I just edited below to simplify, and update my problems status.
I have made a simple enemy class called 'Wolf'. Before I pulled this text out into a new file, my main file ran with no errors.
IF I TRY TO IMPORT ONLY WOLF:
from Enemy Import Wolf
I get the following:
ImportError: cannot import name 'Wolf' from 'Enemy'
Below are all of my files.
When I run my main program, the game runs but crashes when I close it and gives me an error.
Enemy.py
import pygame
import random
import Colors
class Wolf(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
Main_Game_File.py
import pygame
import random
import Colors
import Player
import Enemy
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode([screen_width, screen_height])
#SPRITE LIST CREATIONS
wolf_list = pygame.sprite.Group()
poison_wolf_list = pygame.sprite.Group()
# This is a list of every sprite.
# All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
for i in range(50):
# This represents a single block
wolf = Wolf(Colors.GREEN, 20, 15)
# Set a random location for the block
wolf.rect.x = random.randrange(screen_width)
wolf.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
wolf_list.add(wolf)
all_sprites_list.add(wolf)
for i in range(50):
# This represents a single block
wolf = Wolf(Colors.RED, 20, 15)
# Set a random location for the block
wolf.rect.x = random.randrange(screen_width)
wolf.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
poison_wolf_list.add(wolf)
all_sprites_list.add(wolf)
#Since this will repeat 50 times, you will create 50 red blocks
#This adds all 50 blocks to the bad_block_list, and the all_sprites_list.
# Create a RED player block
player = Player.Player(100, 100)
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()
score = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the speed based on the key pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player.changespeed(-3, 0)
elif event.key == pygame.K_d:
player.changespeed(3, 0)
elif event.key == pygame.K_w:
player.changespeed(0, -3)
elif event.key == pygame.K_s:
player.changespeed(0, 3)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.changespeed(3, 0)
elif event.key == pygame.K_d:
player.changespeed(-3, 0)
elif event.key == pygame.K_w:
player.changespeed(0, 3)
elif event.key == pygame.K_s:
player.changespeed(0, -3)
# Clear the screen
screen.fill(Colors.WHITE)
# Game Logic
all_sprites_list.update()
# See if the player block has collided with anything.
wolf_list = pygame.sprite.spritecollide(player, wolf_list, True)
poison_wolf_list = pygame.sprite.spritecollide(player, poison_wolf_list, True)
# Check the list of collisions.
for block in wolf_list:
score += 1
print(score)
for block in poison_wolf_list:
score -= 1
print(score)
# Draw all the spites
all_sprites_list.draw(screen)
# 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()
Player.py
import pygame
import random
import Colors
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
# -- Methods
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(Colors.BLUE)
# 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
Colors
# Colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 225, 0)
BLUE = ( 0, 0, 225)
In Main_Game_File.py lines 91/92, you're overwriting the Groups with lists.
Use Enemy.Wolf for the imports and change those lines.
wolf_list_2 = pygame.sprite.spritecollide(player, wolf_list, True)
poison_wolf_list_2 = pygame.sprite.spritecollide(player, poison_wolf_list, True)
# Check the list of collisions.
for block in wolf_list_2:
score += 1
print(score)
for block in poison_wolf_list_2:
score -= 1
print(score)
# Draw all the spites
all_sprites_list.draw(screen)
You simply need to prefix it with the module import name.
import Enemy
# [...]
mr_wolf = Enemy.Wolf(Colors.GREEN, 20, 15) # <-- HERE
Or use the import * notation:
from Enemy import * # <-- HERE
# [...]
mr_wolf = Wolf(Colors.GREEN, 20, 15) # (no change)
How modules are imported changes the naming scope.
Or of course, you can import only Wolf from Enemy too:
from Enemy import Wolf # <-- HERE
# [...]
mr_wolf = Wolf(Colors.GREEN, 20, 15) # (no change)
EDIT: Example files:
Enemy.py ~
import pygame
class Wolf(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
def __str__( self ):
return "Wolf at (%d,%d) size %dx%d" % ( self.rect.x, self.rect.y, self.rect.width, self.rect.height )
main.py ~
import Enemy
YELLOW = ( 255, 255, 0 )
mr_wolf = Enemy.Wolf( YELLOW, 10, 10)
print( str( mr_wolf ) )
Which gives:
# python3 ./main.py
pygame 1.9.4.post1
Hello from the pygame community. https://www.pygame.org/contribute.html
Wolf at (0,0) size 10x10
Related
I am trying to use pygame.KEYDOWN so that when I press the key represented by pygame.K_q the block that the player has collided with can be dragged (pick up) to where the player moves as it is done using pygame.MOUSEBUTTONDOWN in this tutorial.
But pressing the q key to drag the block does not work...
This need of mine arose when trying to implement this functionality in another larger code. So I decided to get this other tutorial2 to set up my MWE. I looked to see if anyone had already asked about it but I just found relative but not exact questions that used a very different or very large code structure and I still haven't figured out why I can't get my MWE code to work. This should be a simple question and someone may have already posted this question, so if so let me know where there is a question already posted that clarifies my question.
My MWE:
import pygame
import random
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
class Block(pygame.sprite.Sprite):
"""
This class represents the block to be picked up.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# 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()
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
carry_block_list = []
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(RED)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
diff_x = self.rect.x - 4
diff_y = self.rect.y - 4
# Loop through each block that we are carrying and adjust
# it by the amount we moved.
for block in self.carry_block_list:
block.rect.x -= diff_x
block.rect.y -= diff_y
print("something")
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
# Set the title of the window
pygame.display.set_caption('Move Sprite With Keyboard')
# Create the player paddle object
player = Player(50, 50)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)
block_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)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
print("pick up")
# When the mouse button is pressed, see if we are in contact with
# other sprites:
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, False)
# Set the list of blocks we are in contact with as the list of
# blocks being carried.
player.carry_block_list = blocks_hit_list
if event.key == pygame.K_l:
print("let go")
# When we let up on the mouse, set the list of blocks we are
# carrying as empty.
player.carry_block_list = []
if event.key == pygame.K_LEFT:
player.rect.x -= player.rect.width
elif event.key == pygame.K_RIGHT:
player.rect.x += player.rect.width
elif event.key == pygame.K_UP:
player.rect.y -= player.rect.height
elif event.key == pygame.K_DOWN:
player.rect.y += player.rect.height
# -- Draw everything
# Clear screen
screen.fill(WHITE)
# Draw sprites
all_sprites_list.draw(screen)
# Flip screen
pygame.display.flip()
# Pause
clock.tick(40)
pygame.quit()
You move blocks in Player.update() but you never execute it
First I tried to execute this function in every loop but finally I changed this function to run only when players is moved
def update(self, diff_x, diff_y):
# Loop through each block that we are carrying and adjust
# it by the amount we moved.
for block in self.carry_block_list:
block.rect.x += diff_x
block.rect.y += diff_y
and
if event.key == pygame.K_LEFT:
player.rect.x -= player.rect.width
player.update(-player.rect.width, 0)
elif event.key == pygame.K_RIGHT:
player.rect.x += player.rect.width
player.update(player.rect.width, 0)
elif event.key == pygame.K_UP:
player.rect.y -= player.rect.height
player.update(0, -player.rect.height)
elif event.key == pygame.K_DOWN:
player.rect.y += player.rect.height
player.update(0, player.rect.height)
Full code:
import pygame
import random
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
class Block(pygame.sprite.Sprite):
"""
This class represents the block to be picked up.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# 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()
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
carry_block_list = []
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(RED)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self, diff_x, diff_y):
# Loop through each block that we are carrying and adjust
# it by the amount we moved.
for block in self.carry_block_list:
block.rect.x += diff_x
block.rect.y += diff_y
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
# Set the title of the window
pygame.display.set_caption('Move Sprite With Keyboard')
# Create the player paddle object
player = Player(50, 50)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)
block_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)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
# When the mouse button is pressed, see if we are in contact with
# other sprites:
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, False)
# Set the list of blocks we are in contact with as the list of
# blocks being carried.
player.carry_block_list = blocks_hit_list
if event.key == pygame.K_l:
# When we let up on the mouse, set the list of blocks we are
# carrying as empty.
player.carry_block_list = []
if event.key == pygame.K_LEFT:
player.rect.x -= player.rect.width
player.update(-player.rect.width, 0)
elif event.key == pygame.K_RIGHT:
player.rect.x += player.rect.width
player.update(player.rect.width, 0)
elif event.key == pygame.K_UP:
player.rect.y -= player.rect.height
player.update(0, -player.rect.height)
elif event.key == pygame.K_DOWN:
player.rect.y += player.rect.height
player.update(0, player.rect.height)
# -- Draw everything
# Clear screen
screen.fill(WHITE)
# Draw sprites
all_sprites_list.draw(screen)
# Flip screen
pygame.display.flip()
# Pause
clock.tick(40)
pygame.quit()
I am having troubles with an assignment for school and my teacher doesn't know enough about coding to help me.
The link to the assignment is here:
http://programarcadegames.com/index.php?lang=en&chapter=lab_sprite_moving
I got to step 6 on the assignment where it wants me to make the green blocks move but I cant seem to figure out how to make the update method work (I called it update_good in my code).
When I try the run the code it comea up with the error AttributeError: 'Group' object has no attribute 'update_good'
Here is my code
import pygame
import random
import block_library
import good_block_library
A_Block = block_library.Block
A_Good_Block = good_block_library.good_block
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
# -- Methods
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(BLUE)
# 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
# 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])
bump_sound = pygame.mixer.Sound("bump.wav")
good_sound = pygame.mixer.Sound("good_block.wav")
bad_sound = pygame.mixer.Sound("bad_block.wav")
# 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.'
good_block_list = pygame.sprite.Group()
bad_block_list = pygame.sprite.Group()
# This is a list of every sprite.
# All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
for i in range(50):
# This represents a block
A_Good_Block = A_Block(GREEN, 20, 15)
# Set a random location for the block
A_Good_Block.rect.x = random.randrange(screen_width)
A_Good_Block.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
good_block_list.add(A_Good_Block)
all_sprites_list.add(A_Good_Block)
for i in range(50):
# This represents a block
bad_block = A_Block(RED, 20, 15)
# Set a random location for the block
bad_block.rect.x = random.randrange(screen_width)
bad_block.rect.y = random.randrange(screen_height)
# Add the block to the list of objects
bad_block_list.add(bad_block)
all_sprites_list.add(bad_block)
# Create a player block
player = Player(10, 15)
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()
score = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.changespeed(-3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, -3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, 3)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.changespeed(3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(-3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, 3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, -3)
# Clear the screen
screen.fill(WHITE)
#!!!! this is where the problem occurs v
good_block_list.update_good()
all_sprites_list.update()
# See if the player block has collided with anything.
blocks_hit_list = pygame.sprite.spritecollide(player, good_block_list, True)
blocks_hit_list2 = pygame.sprite.spritecollide(player, bad_block_list, True)
# Check the list of collisions.
for block in blocks_hit_list:
score += 1
good_sound.play()
for block in blocks_hit_list2:
score-= 1
bad_sound.play()
font = pygame.font.SysFont('Calibri', 25, True, False)
text = font.render("Score: " + str(score), True, BLACK)
screen.blit(text, [30, 350])
# Draw all the spites
all_sprites_list.draw(screen)
if player.rect.y == 0 or player.rect.y == 399:
bump_sound.play()
if player.rect.x == 1 or player.rect.x == 700:
bump_sound.play()
# update the screen
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(60)
pygame.quit()
Below is the program I import that contains the good_block class and the update_good function. I think the problem might be in here
def main():
pass
if __name__ == '__main__':
main()
import pygame
import block_library
import random
GREEN = (0, 255, 0)
screen_width = 700
screen_height = 400
A_Block = block_library.Block
change_x = random.randint(-3,3)
change_y = random.randint(-3,3)
good_block_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
class good_block(A_Block):
def changespeed(self, x, y):
""" Change the speed of the player"""
self.change_x += x
self.change_y += y
def update_good(self):
self.rect.x += self.change_x
self.rect.y += self.change_y
Below is the library has the class that A_good_block is inherited from
import pygame
import random
class Block(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# 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()
self.change_x = random.randint(-3,3)
self.change_y = random.randint(-3,3)
Please help
The problem is that you don't fully understand what you're code is doing.
The reason why the code all_sprites_list.update() works is because that method is actually defined for that object. You have a pygame Group object which has it's own methods that you can read about here: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Group.
What you'll find is that the update() method is there but there isn't any update_good() method. The docs say that the update() method calls the update() method off every Sprite contained in it.
So it seems simple, just change update_good() to update() and then call the update() method of the Group and it will work.
I am working through the programarcadegames labs using python and pygame and I am stuck. When I am running this code, I am doing something wrong when I am initializing the block and player classes. The player class is supposed to be its own class and not an instance of Block class.
When I run this program, I am getting this error:
'Block' object has no attribute 'changespeed'
import pygame
import random
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
class Block(pygame.sprite.Sprite):
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# 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()
class Player (pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
def __init__(self,x,y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# -- methods
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(BLACK)
# 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
# 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])
# 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()
# This is a list of every sprite.
# All blocks and the player block as well.
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)
# Create a RED player block
player = Block(BLUE, 20, 15)
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()
score = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the speed based on the key pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.changespeed(-3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, -3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, 3)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.changespeed(3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(-3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, 3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, -3)
# Clear the screen
screen.fill(WHITE)
# Get the current mouse position. This returns the position
# as a list of two numbers.
#pos = pygame.mouse.get_pos()
# Fetch the x and y out of the list,
# just like we'd fetch letters out of a string.
# Set the player object to the mouse location
#player.rect.x = pos[0]
#player.rect.y = pos[1]
# See if the player block has collided with anything.
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
# Check the list of collisions.
for block in blocks_hit_list:
score += 1
print(score)
# This calls update on all the sprites
all_sprites_list.update()
# Draw all the spites
all_sprites_list.draw(screen)
# 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()
Here's the problem: player = Block(BLUE, 20, 15). The player is a Block instance not a Player instance and blocks have got no changespeed method.
I am currently working on a square collecting game in which the User/Player will be a blue square that can only collect squares that are smaller than the player's square. These are represented by color, if the square is smaller than the player than it is green, if it is bigger it will be red.
I have run into a problem where I can not figure out how to INCREASE THE SIZE of the Player when the player collides with the green squares. I have tried a number of different things that don't seem to work and would appreciate some different options to try and accomplish this task.
Here is the code that I am currently using:
import pygame
import random
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
class Block(pygame.sprite.Sprite):
"""
This class represents the ball.
It derives from the "Sprite" class in Pygame.
"""
def __init__(self, color, width, height):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# 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()
class Player(pygame.sprite.Sprite):
""" The class is the player-controlled sprite. """
# -- Methods
def __init__(self, x, y):
"""Constructor function"""
# Call the parent's constructor
super().__init__()
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(BLUE)
# 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"""
# move left or right
self.rect.x += self.change_x
if self.rect.x <= 0:
self.rect.x = 1
wall_sound.play()
if self.rect.x >= 680:
self.rect.x = 679
wall_sound.play()
# move up or down
self.rect.y += self.change_y
if self.rect.y <= 0:
self.rect.y = 1
wall_sound.play()
if self.rect.y >= 385:
self.rect.y = 384
wall_sound.play()
# 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])
# 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()
# This is a list of every sprite.
# All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
# Create a BLUE player block
p_width = 30
p_height = 25
p_size = (p_width, p_height)
player = Player(p_width, p_height)
all_sprites_list.add(player)
# BLOCK LIST
for i in range(50):
width = random.randrange(20, 50)
height = width - 5
b_size = (width, height)
if b_size <= p_size:
color = GREEN
if b_size > p_size:
color = RED
# This represents a block
block = Block(color, width, height)
# Set a random location for the block
block.rect.x = random.randrange(screen_width - width)
block.rect.y = random.randrange(screen_height - height)
# Add the block to the list of objects
block_list.add(block)
all_sprites_list.add(block)
# Loop until the user clicks the close button.
done = False
# Pygame sound effects
collect_good = pygame.mixer.Sound("SnowWalk.ogg")
collect_bad = pygame.mixer.Sound("icebreaks.ogg")
wall_sound = pygame.mixer.Sound("evillaugh.ogg")
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
font = pygame.font.Font(None, 25)
score = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the speed based on the key pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.changespeed(-3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(3, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, -3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, 3)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.changespeed(3, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(-3, 0)
eli
# See if the player block has collided with anything.
#good
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
# Check the list of collisions.
#good
for block in blocks_hit_list:
score += 1
collect_good.play()
if score <= -1:
done = True
# Draw all the spites
all_sprites_list.draw(screen)
text = font.render("Score: " + str(score), True, BLACK)
screen.blit(text, [20, 300])
# 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()f event.key == pygame.K_UP:
player.changespeed(0, 3)
elif event.key == pygame.K_DOWN:
player.changespeed(0, -3)
# This calls update on all the sprites
all_sprites_list.update()
# Clear the screen
screen.fill(WHITE)
# See if the player block has collided with anything.
#good
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
# Check the list of collisions.
#good
for block in blocks_hit_list:
score += 1
collect_good.play()
if score <= -1:
done = True
# Draw all the spites
all_sprites_list.draw(screen)
text = font.render("Score: " + str(score), True, BLACK)
screen.blit(text, [20, 300])
# 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()
Make the player constructor take the width and height as well as the x and y. In the collision check, increase these and create a new image for the player with the new increased x and y values. Don't forget to reset the player rect at the same time as well.
Also, you are passing the width and height in and using them as x and y not width and height.
this is my game right now but for some reason i keep getting a
PYTHON GAME.py", line 319, in <module>
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
File "C:\Python33\lib\site-packages\pygame\sprite.py", line 1515, in spritecollide
if spritecollide(s.rect):
AttributeError: 'Rocket' object has no attribute 'rect'
error. I have no idea why and ive tried alot of stuff to get it to work.
This stupid thing keeps saying i have to much code so i wrote this sentance to take up room
import pygame
import random
"""
Global constants
"""
# Colors
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
BLUE = ( 0, 0, 255)
BLACK = [ 0, 0, 0]
WHITE = [255, 255, 255]
black = [ 0,0,0]
white=[255,255,255]
green = ( 0, 255, 0)
red = ( 255, 0, 0)
BLUE = ( 0, 0, 255)
lightblue= ( 0, 255, 255)
brown =( 97, 66, 12)
yellow =(232,232,74)
grey=(148,148,148)
purple=(124,102,196)
yellow2 =(252,252,0)
yellow3 =(252,252,0)
red2=(255,0,0)
brown2 =(51,32,5)
orange = (255,119,0)
a=random.randrange(0,255,1)
b=random.randrange(0,255,1)
c=random.randrange(0,255,1)
#color=(a,b,c)
score=0
x=50
#game_sound = pygame.mixer.Sound("nunu_nights.wav")
# Screen dimensions
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 700
# This class represents the bar at the bottom that the player controls
class Player(pygame.sprite.Sprite):
""" This class represents the bar at the bottom that the player controls. """
# Set speed vector
change_x = 0
change_y = 0
walls = None
# Constructor function
def __init__(self, x, y):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill(WHITE)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def changespeed(self, x, y):
""" Change the speed of the player. """
self.change_x += x
self.change_y += y
def update(self):
""" Update the player position. """
# Move left/right
self.rect.x += self.change_x
# Did this update cause us to hit a wall?
block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
# If we are moving right, set our right side to the left side of the item we hit
if self.change_x > 0:
self.rect.right = block.rect.left
else:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
# Move up/down
self.rect.y += self.change_y
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
class Wall(pygame.sprite.Sprite):
""" Wall the player can run into. """
def __init__(self, x, y, width, height):
""" Constructor for the wall that the player can run into. """
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Make a black wall, of the size specified in the parameters
self.image = pygame.Surface([width, height])
self.image.fill(BLACK)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
class Rocket(pygame.sprite.Sprite):
""" Rocket Class. """
x=0
y=0
change_x=0
change_y=0
size=10
color=[255, 0, 0]
def move(self):
self.x+=self.change_x
self.y+=self.change_y
def draw(self,screen):
pygame.draw.circle(screen,self.color,[self.x,self.y], self.size)
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
# Set the title of the window
pygame.display.set_caption('ROCKETS EVERYWHERE!!')
all_sprite_list = pygame.sprite.Group()
# Create an empty array
rocket_list = []
# Loop 50 times and add a rocket in a random x,y position
for i in range(100):
x = random.randrange(0, 1000)
y = random.randrange(0, 700)
rocket_list.append([x, y])
rect_x = 50
rect_y = 50
# Speed and direction of rectangle
rect_change_x = 5
rect_change_y = 5
# This is a font we use to draw text on the screen (size 36)
font = pygame.font.Font(None, 36)
# List to hold all the sprites
all_sprite_list = pygame.sprite.Group()
# Make the walls. (x_pos, y_pos, width, height)
wall_list = pygame.sprite.Group()
wall = Wall(0, 0, 10, 800)
wall_list.add(wall)
all_sprite_list.add(wall)
wall = Wall(10, 0, 1000, 10)
wall_list.add(wall)
all_sprite_list.add(wall)
wall = Wall(990, 0, 10, 800)
wall_list.add(wall)
all_sprite_list.add(wall)
wall = Wall(0, 690, 1000, 10)
wall_list.add(wall)
all_sprite_list.add(wall)
block_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
# Create the player object
player = Player(500, 600)
player.walls = wall_list
for i in range(50):
enemyRocket1 = Rocket()
enemyRocket1.change_x=2
enemyRocket1.change_y=2
enemyRocket1.color=[a,b,c]
enemyRocket1.x=random.randrange(0,1000,1)
enemyRocket1.y=random.randrange(0,700,1)
block_list.add(enemyRocket1)
all_sprites_list.add(enemyRocket1)
'''
enemyRocket2 = Rocket()
enemyRocket2.x=50
enemyRocket2.y=0
enemyRocket2.change_x=0
enemyRocket2.change_y=10
enemyRocket2.color=[a,b,c]
'''
all_sprite_list.add(player)
clock = pygame.time.Clock()
display_instructions = True
instruction_page = 1
done= False
# -------- Instruction Page Loop -----------
while done==False and display_instructions:
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
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 3:
display_instructions = False
# Set the screen background
screen.fill(black)
if instruction_page == 1:
# Draw instructions, page 1
# This could also load an image created in another program.
# That could be both easier and more flexible.
#random.play()
#screen.blit(title_intro, [0,0])
text=font.render("ROCKETS EVERYWHERE!!", True, white)
screen.blit(text, [10, 10])
text=font.render("Click mouse to see the instructions", True, white)
screen.blit(text, [10, 40])
if instruction_page == 2:
# Draw instructions, page 2
text=font.render("The objective of the game is to dodge rockets", True, white)
screen.blit(text, [10, 10])
text=font.render("Use the Arrow keys to move around the screen", True, white)
screen.blit(text, [10, 40])
# Limit to 20 frames per second
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
#------------------------
#MAIN PROGRAM LOOP
#------------------------
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the speed based on the key pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.changespeed(-14, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(14, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, -7)
elif event.key == pygame.K_DOWN:
player.changespeed(0, 7)
# Reset speed when key goes up
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.changespeed(14, 0)
elif event.key == pygame.K_RIGHT:
player.changespeed(-14, 0)
elif event.key == pygame.K_UP:
player.changespeed(0, 7)
elif event.key == pygame.K_DOWN:
player.changespeed(0, -7)
all_sprite_list.update()
player.update()
screen.fill(BLACK)
all_sprite_list.draw(screen)
#The score
text=font.render("Score="+str(score), True, white)
screen.blit(text, [10, 10])
a=random.randrange(0,255,1)
b=random.randrange(0,255,1)
c=random.randrange(0,255,1)
color=(a,b,c)
enemyRocket1.move()
enemyRocket1.draw(screen)
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
# Check the list of collisions.
for block in blocks_hit_list:
score+=99999999999
if score>x:
x+=100
for i in range(len(rocket_list)):
# Draw the rocket
pygame.draw.circle(screen, WHITE, rocket_list[i], 2)
# Move the rocket down one pixel
rocket_list[i][1] += 10
# If the rocket has moved off the bottom of the screen
if rocket_list[i][1] > 700:
# Reset it just above the top
y = random.randrange(-50, -10)
rocket_list[i][1] = y
# Give it a new x position
x = random.randrange(0, 1000)
rocket_list[i][0] = x
score+=1
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
clock.tick(40)
pygame.quit ()
As the error message suggests, you are trying to access the attribute rect of a Rocket.
Looking at your Rocket class, Rocket objects indeed have no such attribute.