Pygame mouse click detection on moving sprites - python

I'm making a "duck hunt" game in pygame. I have everything working, my sprites move and respawn when needed, cursor is a crosshair with sound when clicked etc. The issue I'm having is trying to add points when the mouse is click on a duck. Any idea how I would do this? Posted all of the code, its a bit of a mess until I get thank working, check the main loop specifically. Thanks.
import pygame
import random
import duck_code
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
DUCK_BACK = (59, 202, 255)
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
# -- Methods
def __init__(self, x, y, filename):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(BLACK)
self.image = pygame.image.load(filename).convert()
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# -- Attributes
# Set speed vector
self.change_x = 0
self.change_y = 0
def changespeed(self, x, y):
""" Change the speed of the player"""
self.change_x += x
self.change_y += y
def update(self):
""" Find a new position for the player"""
self.rect.x += self.change_x
self.rect.y += self.change_y
# boarders for walls, reset player, play bump sound
if self.rect.x in range(1060, 1085):
self.rect.x -= 25
if self.rect.x in range(-5, 0):
self.rect.x += 25
if self.rect.y in range(-5, 0):
self.rect.y += 25
if self.rect.y in range(480, 505):
self.rect.y -= 25
# Initialize Pygame
# Loading sounds
pygame.init()
game_background = pygame.image.load("game_background.jpg")
duck_hit = pygame.mixer.Sound("duck_hit.wav")
player_click = pygame.mixer.Sound("shot_gun.ogg")
# Set the height and width of the screen
screen_width = 1280
screen_height = 1024
screen = pygame.display.set_mode([screen_width, screen_height])
# Starting score and font settings
font = pygame.font.Font(None, 36)
score = 0
# This is a list of every sprite.
all_sprites_list = pygame.sprite.Group()
duck_list = pygame.sprite.Group()
duck_hit_list = pygame.sprite.Group()
"""DUCKS"""
for i in range(5):
# This represents a block
ducks = duck_code.Duck("duck1.png")
ducks.rect.x = random.randrange(screen_width)
ducks.rect.y = random.randrange(50, 350)
# Add the block to the list of objects
duck_list.add(ducks)
all_sprites_list.add(ducks)
"""PLAYER"""
player_image = pygame.image.load("crosshair.png")
player_image.set_colorkey(WHITE)
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
score = 0
# Hide the mouse cursor
pygame.mouse.set_visible(0)
# -------- Main Program Loop -----------
while not done:
mouse = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
blocks_hit_list = pygame.sprite.spritecollide(mouse, duck_list, True)
score += 100
print(score)
player_click.play()
# --- Game logic should go here
# --- Screen-clearing code goes here
# Here, we clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
# If you want a background image, replace this clear with blit'ing the
# background image.
screen.blit(game_background, [0, 0])
player_position = pygame.mouse.get_pos()
x = player_position[0]
y = player_position[1]
screen.blit(player_image, [x, y])
pos = pygame.mouse.get_pos()
pressed1, pressed2, pressed3 = pygame.mouse.get_pressed()
# Check if the rect collided with the mouse pos
# and if the left mouse button was pressed.
all_sprites_list.draw(screen)
duck_list.update()
# Showing scoreboard
text = font.render("Score: " + str(score), True, WHITE)
screen.blit(text, [10, 10])
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(60)
pygame.quit()

pygame.sprite.spritecollide only works with a sprite as the first argument and a sprite group as the second argument. To check if the mouse collides with a duck, you can iterate over the duck_list with a for loop and call the collidepoint method of the current duck's rect:
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
for duck in duck_list:
if duck.rect.collidepoint(event.pos): # event.pos is the mouse position.
score += 100

Related

Make enemy go backward

I am making a space invaders game where the enemy hits the left or right side of the screen it will go down. However, I am struggling to figure out how to do the same thing but in reverse. So when it hits the end of the screen it will move left/right. Here is the code for the enemy.
import pygame
import random
# Initialize Pygame
pygame.init()
# Creates the screen for pygame
screen = pygame.display.set_mode((1000, 800))
#Enemy1
enemy1image = pygame.image.load('Enemy1.png')
enemy1image = pygame.transform.scale(enemy1image, (80, 80))
#Make it appear in a random cordinate
enemy1X = random.randint (0,1000)
enemy1y = random.randint(40,300)
enemy1X_change = 3
enemy1Y_change = 30
enemy1y_change_reverse = -30
def enemy1(x,y):
#Draws Enemy1 on screen
screen.blit(enemy1image,(x,y))
#Enemy1 Movement/boundaries
enemy1X += enemy1X_change
enemy1(enemy1X, enemy1y)
#Every time the enemy hits the boundary, it moves down
if enemy1X <= 0:
enemy1X_change = 4
enemy1y += enemy1Y_change
elif enemy1X >= 917:
enemy1X_change = -4
enemy1y += enemy1Y_change
It is difficult to answer what is specifically wrong with your code without a Minimal, Reproducible Example. Your concept appears valid, when you hit the boundary, change direction, move down and increase speed.
Here is an example that creates sprites that exhibit space-invader style movement. It it a little more effort to create sprites, but they make handling multiple game entities much easier.
import pygame
import random
screen = pygame.display.set_mode((800, 800))
pygame.init()
sprite_list = pygame.sprite.Group()
class Block(pygame.sprite.Sprite):
"""A block that moves like a space invader"""
def __init__(self, size, pos):
pygame.sprite.Sprite.__init__(self)
self.size = size
self.image = pygame.Surface([size[0], size[1]])
self.image.fill(pygame.color.Color("blueviolet"))
self.rect = self.image.get_rect()
self.rect.x = pos[0]
self.rect.y = pos[1]
self.speedx = random.randint(-5, 5) # note: includes zero
self.speedy = size[1] # this only changes on edge collission
def update(self):
"""move across the screen, skip down a row when at the edge"""
width, height = screen.get_size()
if not 0 < self.rect.x < (width - self.size[0]):
self.speedx *= -1 # reverse direction
self.rect.y += self.speedy
self.rect.x += self.speedx
if self.rect.y > (height - self.size[1]):
self.kill()
# Create some random blocks in random positions
for _ in range(5):
invader = Block(
(random.randint(80, 100), random.randint(80, 100)), # size
(random.randint(0, 800), random.randint(0, 800)), # position
)
sprite_list.add(invader)
run = True
clock = pygame.time.Clock()
while run:
## Handle Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.MOUSEBUTTONUP:
# create block on mouse click
invader = Block((random.randint(80, 100), random.randint(80, 100)), event.pos)
sprite_list.add(invader)
## Clear background
screen.fill("white")
## Update Sprites
sprite_list.update()
## Draw Sprites
sprite_list.draw(screen)
## Update Screen
pygame.display.update()
clock.tick(60) # limit to 60 FPS
pygame.quit()

Pygame returns an error when you click a sprite with another sprite that isn't listed

I'm just making a title screen for a future project, and when I run it the "PLAY" and "QUIT" buttons work fine enough but when you click the surrounding background or the title image, the game freezes up and returns the error, "AttributeError: 'list' object has no attribute 'sprites'" I tried adding a blank audio file seperate from the "if play == 0:" in case it was just confused when it had nothing to do, but the problem stayed.
import pygame
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255,255,0)
score = 0
play = 0
class Sprite(pygame.sprite.Sprite):
def __init__(self,filename):
super().__init__()
self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
class Player(Sprite):
def update(self):
""" Method called when updating a sprite. """
# Get the current mouse position. This returns the position
# as a list of two numbers.
pos = pygame.mouse.get_pos()
# Now see how the mouse position is different from the current
# player position. (How far did we move?)
diff_x = self.rect.x - pos[0]
diff_y = self.rect.y - pos[1]
# Loop through each block that we are carrying and adjust
# it by the amount we moved.
# Now wet the player object to the mouse location
self.rect.x = pos[0]
self.rect.y = pos[1]
class Block(pygame.sprite.Sprite):
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 750
screen_height = 500
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("LARP")
# This is a list of 'sprites.' Each block in the program is
# added to this list. The list is managed by a class called 'Group.'
block_list = pygame.sprite.Group()
quit_block = pygame.sprite.Group()
start_block = pygame.sprite.Group()
title_image = pygame.image.load("title.png").convert_alpha()
quit_image = pygame.image.load("quit.png").convert_alpha()
logo_image = pygame.image.load("logo.png").convert_alpha()
player_image = pygame.image.load("player.png").convert_alpha()
background_image = pygame.image.load("title_screen.png").convert_alpha()
bomp = pygame.mixer.Sound("bump.wav")
# This is a list of every sprite.
# All blocks and the player block as well.
player_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
#for i in range(50):
#This represents a block
#block = Block(BLACK, 20, 15)
#Set a random location for the block
#block.rect.x = random.randrange(screen_width)
#block.rect.y = random.randrange(screen_height)
#Add the block to the list of objects
#block_list.add(block)
#all_sprites_list.add(block)
title = Sprite("title.png")
title.rect.x = 340
title.rect.y = 230
all_sprites_list.add(title)
start_block.add(title)
quitg = Sprite("quit.png")
quitg.rect.x = 340
quitg.rect.y = 350
all_sprites_list.add(quitg)
quit_block.add(quitg)
logo = Sprite("logo.png")
logo.rect.y = 90
logo.rect.x = 310
all_sprites_list.add(logo)
block_list.add(logo)
player = Player("player.png")
player_list.add(player)
all_sprites_list.add(player)
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# Hide the mouse cursor
pygame.mouse.set_visible(False)
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
# When the mouse button is pressed, see if we are in contact with
# other sprites:
if play == 0:
start_block = pygame.sprite.spritecollide(player, start_block, True)
if len(start_block) >= 1:
play += 1
quit_block = pygame.sprite.spritecollide(player, quit_block, True)
if len(quit_block) >= 1:
done = True
#print(score)
#blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
#if len(blocks_hit_list) >= 1:
#score +=1
# Set the list of blocks we are in contact with as the list of
# blocks being carried.
#player.carry_block_list = blocks_hit_list
elif event.type == pygame.MOUSEBUTTONUP:
# When we let up on the mouse, set the list of blocks we are
# carrying as empty.
player.carry_block_list = []
all_sprites_list.update()
# Clear the screen
screen.fill(WHITE)
# Draw all the spites
if play == 0:
screen.blit(background_image, [0,0])
all_sprites_list.draw(screen)
screen.blit(player_image, [player.rect.x, player.rect.y])
# Limit to 60 frames per second
clock.tick(60)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit()
start_block and quit_block are pygame.sprite.Group(). However, pygame.sprite.spritecollide(). Therefore an instruction like:
start_block = pygame.sprite.spritecollide(player, start_block, True)
makes no sense because the group start_block is overwritten with the list start_block
Change the name of the variable the gets the return value. e.g.:
start_block_hit = pygame.sprite.spritecollide(player, start_block, False)
Note, you don't need to store the return values at all. The doKill argument must be False, otherwise your button will be destroyed when you click it:
if pygame.sprite.spritecollide(player, start_block, False):
play += 1
if pygame.sprite.spritecollide(player, quit_block, False):
done = True

My game keeps calling a method for the wrong sprite

When i try to run the game the code tries to run a method for the wrong sprite. I think the line "player.handle_keys()" is the problem as when i run it, it says that it can't find a "handle_keys()" method for the "meteor" class. I haven't got a line to run a "meteor.handle_keys()" as this class should not have this method.
Here is the code:
import pygame
import random
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
bg = pygame.image.load("bg1.png")
class space_ship(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
# Create an image of the space_ship1, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
self.rect = self.image.get_rect()
#draw image
self.image = pygame.image.load("player1.gif").convert()
# Draw the ellipse
#pygame.draw.ellipse(self.image, color, [0, 0, width, height])
# x and y coordinates
self.x = 500
self.y = 450
def handle_keys(self):
""" Handles Keys """
key = pygame.key.get_pressed()
dist = 5 # distance moved in 1 frame
if key[pygame.K_RIGHT]: # right key
self.x += dist # move right
elif key[pygame.K_LEFT]: # left key
self.x -= dist # move left
def draw(self, surface):
""" Draw on surface """
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
class asteroid(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
# Create an image of the space_ship1, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
self.rect = self.image.get_rect()
# Draw the ellipse
#pygame.draw.ellipse(self.image, color, [0, 0, width, height])
self.image = pygame.image.load("ast1.gif").convert()
# x and y coordinates
self.x = random.randint(50,950)
self.y = 10
def draw(self, surface):
""" Draw on surface """
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
def fall(self):
dist = 5
self.y +=dist
if self.y > 600:
self.x = random.randint(50,950)
self.y = random.randint(-2000, -10)
def respawn(self):
self.y = -10
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 1000
screen_height = 600
screen = pygame.display.set_mode([screen_width, screen_height])
# This is a list of 'sprites.' Each sprite in the program is
# added to this list.
# The list is managed by a class called 'Group.'
asteroid_list = pygame.sprite.Group()
# This is a list of every sprite.
# All asteroids and the player as well.
all_sprites_list = pygame.sprite.Group()
player = space_ship(RED, 20, 15)
all_sprites_list.add(player)
asteroid_1 = asteroid(BLACK, 40, 40)
asteroid_list.add(asteroid_1)
all_sprites_list.add(asteroid_1)
asteroid_2 = asteroid(BLACK, 40, 40)
asteroid_list.add(asteroid_2)
all_sprites_list.add(asteroid_2)
asteroid_3 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_3)
all_sprites_list.add(asteroid_3)
asteroid_4 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_4)
all_sprites_list.add(asteroid_4)
asteroid_5 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_5)
all_sprites_list.add(asteroid_5)
asteroid_6 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_6)
all_sprites_list.add(asteroid_6)
asteroid_7 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_7)
all_sprites_list.add(asteroid_7)
asteroid_8 = asteroid(BLACK,40, 40)
asteroid_list.add(asteroid_8)
all_sprites_list.add(asteroid_list)
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
score = 0
# ----------------- Main Program Loop --------------------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#Call upon function
player.handle_keys()
# Clear the screen
screen.fill(WHITE)
#INSIDE OF THE GAME LOOP
screen.blit(bg, (0, 0))
# See if the player space_ship1 has collided with anything.
blocks_hit_list = pygame.sprite.spritecollide(player, asteroid_list, True)
# Check the list of collisions.
for player in blocks_hit_list:
score +=1
print(score)
# Draw all the spites
player.draw(screen)
asteroid_1.draw(screen)
asteroid_1.fall()
asteroid_2.draw(screen)
asteroid_2.fall()
asteroid_3.draw(screen)
asteroid_3.fall()
asteroid_4.draw(screen)
asteroid_4.fall()
asteroid_5.draw(screen)
asteroid_5.fall()
asteroid_6.draw(screen)
asteroid_6.fall()
asteroid_7.draw(screen)
asteroid_7.fall()
asteroid_8.draw(screen)
asteroid_8.fall()
#all_sprites_list.draw(screen)
# Limit to 60 frames per second
clock.tick(60)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit()
You are overriding player in your for loop
# Check the list of collisions.
for player in blocks_hit_list:
score +=1
print(score)
change it to something else and all will be good
# Check the list of collisions.
for something_else in blocks_hit_list:
score +=1
print(score)
Enjoy

PyGame collision working but sprite being reset - motion not continuing.

Having trouble with my PyGame experimental game - I'm learning how to work with sprites.
I have been trying to code 'collision' detection between sprites (ball and paddle) and have managed to get the collision detection working but my ball sprite seems to reset its position instead of carrying on. Could anyone take a look and see where my error is?
Here is my code:
import pygame
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
#variables, constants, functions
x = 1
y = 1
x_vel = 10
y_vel = 10
bat_x = 1
bat_y = 1
bat_x_vel = 0
bat_y_vel = 0
score = 0
class Ball(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# Call the parent class (Sprite) constructor
super().__init__()
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
# Draw the ellipse
pygame.draw.ellipse(self.image, (255,0,0), [0,0,width,height], 10)
# Fetch the rectangle object that has the dimensions of the image
# image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
# Instance variables that control the edges of where we bounce
self.left_boundary = 0
self.right_boundary = 0
self.top_boundary = 0
self.bottom_boundary = 0
# Instance variables for our current speed and direction
self.vel_x = 5
self.vel_y = 5
def update(self):
""" Called each frame. """
self.rect.x += self.vel_x
self.rect.y += self.vel_y
if self.rect.right >= self.right_boundary or self.rect.left <= self.left_boundary:
self.vel_x *= -1
if self.rect.bottom >= self.bottom_boundary or self.rect.top <= self.top_boundary:
self.vel_y *= -1
class Paddle(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# Call the parent class (Sprite) constructor
super().__init__()
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
# Draw the rectangle
pygame.draw.rect(self.image, (0, 255, 0), [0, 0, width, height], 0)
# Fetch the rectangle object that has the dimensions of the image
# image.
# Update the position of this object by setting the values
# of rect.x and rect.y
self.rect = self.image.get_rect()
# Instance variables for our current speed and direction
self.x_vel = 0
self.y_vel = 0
def update(self):
# Get the current mouse position. This returns the position
# as a list of two numbers.
self.rect.x = self.rect.x + self.x_vel
self.rect.y = self.rect.y + self.y_vel
#initialise ball and paddle
paddle = Paddle(20, 100)
ball = Ball(100,100)
# This is a list of every sprite.
# All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(ball)
all_sprites_list.add(paddle)
ball_sprites_list = pygame.sprite.Group()
ball_sprites_list.add(ball)
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode((screen_width, screen_height))
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# Loop until the user clicks the close button.
done = False
# -------- Main Program Loop -----------
while not done:
# --- Events code goes here (mouse clicks, key hits etc)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
paddle.y_vel = -3
if event.key == pygame.K_DOWN:
paddle.y_vel = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
paddle.y_vel = 0
if event.key == pygame.K_DOWN:
paddle.y_vel = 0
# --- Game logic should go here
# Calls update() method on every sprite in the list
all_sprites_list.update()
# collision check
ball_hit_list = pygame.sprite.spritecollide(paddle, ball_sprites_list, False)
# Check the list of collisions.
for ball in ball_hit_list:
score +=1
print(score)
# --- Clear the screen
screen.fill((255,255,255))
# --- Draw all the objects
all_sprites_list.draw(screen)
# render text
myfont = pygame.font.SysFont("monospace", 15)
label = myfont.render(str(score), 1, (0,0,0))
screen.blit(label, (100, 100))
# --- Update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
pygame.quit()
Sorry,
Have found the error.
Didn't set the boundaries of the window properly.
# Instance variables that control the edges of where we bounce
self.left_boundary = 0
self.right_boundary = 700
self.top_boundary = 0
self.bottom_boundary = 400

Collision Detection With 'jump/not smooth'' movement

My problem with the code is that I created a sprite that is able to move a tile each time when an arrow key is pressed, the problem is when the sprite moves onto a tile that has a wall on it, it still goes onto the tile instead of staying on the tile that it is on. I can't seem to get the right collision detection code.
import pygame
import random
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
red = ( 255, 0, 0)
GREEN = ( 0, 255, 0)
wall = ( 66, 66, 66)
# This class represents the ball
# It derives from the "Sprite" class in Pygame
class Main(pygame.sprite.Sprite):
walls = None
def __init__(self, filename):
# Calls the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Creates the 'block' that will contain the image
self.image = pygame.image.load(filename).convert()
# Set background colour so its transparent
self.image.set_colorkey(black)
# Sets parameters so you can adjust the x and y values
self.rect = self.image.get_rect()
def update (self,):
# Moving left or right
self.rect.x += self.change_y
# Did something collide into wall ?
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for wall in wall_hit_list:
# If we are moving right, set our right side to the left side of the item we hit
if self.change_y > 0:
self.rect.right = wall.rect.left
else:
# Otherwise if we are moving left, do the opposite
self.rect.left = wall.rect.right
# Move up/down
self.rect.y += self.change_x
# Check and see if we hit anything
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for wall in wall_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_x > 0:
self.rect.bottom = wall.rect.top
else:
self.rect.top = wall.rect.bottom
class Wall(pygame.sprite.Sprite):
# Wall that the player can run into.
def __init__(self, filename):
# Constructor
pygame.sprite.Sprite.__init__(self)
# Make a wall
self.image = pygame.image.load(filename).convert()
# Sets parameters so you adjust the x and y values
self.rect = self.image.get_rect()
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
# List of all the sprites
all_sprites_list = pygame.sprite.Group ()
# List of the main sprite ( squirtle )
main_sprite = pygame.sprite.Group ()
# List of Walls
wall_list = pygame.sprite.Group ()
wall = Wall("wall2.png",)
wall.rect.x = 100
wall.rect.y = 150
wall_list.add(wall)
all_sprites_list.add(wall)
# Sets player to the class 'Main' which thanks to the parameter, is squirtle
Hero = Main ("Character.png")
player = Main ("Character.png")
# Spawns squirtle in a random position
Hero.rect.x = 4
Hero.rect.y = 1
# Adds squirtle to the lists that we made
main_sprite.add(Hero)
all_sprites_list.add(Hero)
#Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while done == False:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
Hero.rect.x -= 50
elif event.key == pygame.K_RIGHT:
Hero.rect.x += 50
elif event.key == pygame.K_UP:
Hero.rect.y -= 50
elif event.key == pygame.K_DOWN:
Hero.rect.y += 50
# Clear the screen
screen.fill(white)
# Drawing Code
y_offset = 0
x_offset = 0
while x_offset < 750:
pygame.draw.line(screen,GREEN, [0+x_offset,0], [0+x_offset,500],1)
x_offset = x_offset + 50
while y_offset < 550:
pygame.draw.line(screen, GREEN, [0,0+y_offset], [700,0+y_offset],1)
y_offset = y_offset + 50
# Draw all the sprites
all_sprites_list.draw(screen)
pygame.display.flip ()
clock.tick (60)
pygame.quit ()`
First of all, you never call the update method of your sprites, so your collision check is never performed.
If you would call it, it would fail, because you try to read self.change_y, which you never set.
If you would, it would still fail, because you try to check the collision against the sprites in self.walls, but you never set it thus self.walls is always None.

Categories