I am trying to have sprites randomly appear on the screen with out using OOP principles
this code is from a ants demo for AI
if randint(1, 10) == 1:
leaf = Leaf(world, leaf_image)
leaf.location = Vector2(randint(0, w), randint(0, h))
world.add_entity(leaf)
world.process(time_passed)
world.render(screen)
pygame.display.update()
Question:
How do I get Sprites on the screen randomly?
I know to blit them
but how without using Object-Oriented
this is the only part my code is missing a way for sprites to randomly appear
this the code to the antstate.py where im getting the code:
http://www.mediafire.com/?5tjswcyl9xt5huj
A sprite is an object. So you need to use some OOP to work with a sprite. Here's an example:
# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://cs.simpson.edu/?q=python_pygame_examples
import pygame
import random
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
# This class represents the ball
# It derives from the "Sprite" class in Pygame
class Block(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block,
# and its x and y position
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# 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=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 'RenderPlain.'
block_list = pygame.sprite.RenderPlain()
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)
Related
I have an image of a vertical line, and want to create two of them. I want them to randomly spread apart and close the gap (while maintaining a minimum and maximum distance - I'm waiting to fix this first), while moving along the x-axis. The y coords don't move.
There are many examples of creating more complex sprites and games using pygame, but I can't find one simple enough to pinpoint what I'm supposed to do, so any help is appreciated. This code is based off of a simple example found here.
This is the very basic code that I have so far.
class Squeeze(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.img_load()
def update(self):
self.rect.x += random.randint(-1, 1)
if self.rect.x >= 1920:
self.rect.x += -1
if self.rect.x <= 0:
self.rect.x += 1
def img_load(self):
self.image = pygame.Surface([SCREEN_WIDTH, SCREEN_HEIGHT])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
pygame.init()
SCREEN_WIDTH = 1920
SCREEN_HEIGHT = 1080
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
FPS = 60
wall = pygame.image.load('wall.png')
wall_list = pygame.sprite.Group()
BLACK = (0, 0, 0)
for i in range(2):
wall = Squeeze()
wall.rect.x = random.randrange(SCREEN_WIDTH)
wall.rect.y = random.randrange(SCREEN_HEIGHT)
wall_list.add(wall)
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
wall_list.update()
wall_list.draw(screen)
clock.tick(60)
pygame.display.flip()
pygame.quit()
I'm confused about the pygame.sprite.Group() deal. How do I get the two images to load and operate on them separately? Any other advice is appreciated as well.
Basically a "sprite" is a visible game object in your game. Pygames pygame.sprite.Sprite class is known as the "base class" for all these objects.
Every time when creating the Squeeze class, you derive form Pygames build-in sprite base class:
class Squeeze(pygame.sprite.Sprite):
def __init__(self):
...
Each object (or instance) of the pygame.sprite.Sprite class holds
an .update() method and
an .image and
an .rect attribute.
As the documentation states, "* ... derived classes will want to override the Sprite.update() and assign a Sprite.image and Sprite.rect attributes.*"
You did this by calling the your img_load() method in the __init__() method of your Squeeze class.
The problem is now that your .rect is assigned to the same size as your screen (self.image = pygame.Surface([SCREEN_WIDTH, SCREEN_HEIGHT])) and the .image attribute has the same color as your display screen, so you canĀ“t see it.
Try to modify your img_load() method to
def img_load(self, img):
self.image = img
self.rect = self.image.get_rect()
As you can see, the modified img_load() method needs an image object -- which is passed to the img argument. So you also need to change your __init__() method:
def __init__(self, img):
pygame.sprite.Sprite.__init__(self)
self.img_load(img)
When now instantiating (e.g. creating an object of a class) a Squeeze object, you need to pass an image (in our case wall_img) to the constructor:
#... main programm
wall_img = pygame.image.load('wall.png') #load an image
wall_list = pygame.sprite.Group() #create a sprite group
BLACK = (0, 0, 0)
for i in range(2):
wall = Squeeze(wall_img) #create a sprite
wall.rect.x = random.randrange(SCREEN_WIDTH)
wall.rect.y = random.randrange(SCREEN_HEIGHT)
wall_list.add(wall) #add the sprite to the sprite group
The second build-in class you use is the pygame.sprite.Group class -- a container, which can hold and manage (modify) sprites it contains.
Calling the .update() method of a sprite group instance, Pygame automatically calls the update() methods of all sprites in this group. This means you can control a sprites behavior by implementing its update() method, as you did:
#update method of the Squeeze class
def update(self):
#any logic which changes sprite
self.rect.x += random.randint(-1, 1)
if self.rect.x >= 1920:
self.rect.x += -1
if self.rect.x <= 0:
self.rect.x += 1
By calling
wall_list.draw(screen)
your spites will be blitted onto the screen surface using the .image attribute for the source surface, and .rect for the position.
If you now wont to have different images you just need to pass other images (or surfaces) to the Squeeze constructor:
#... main programm
wall_imgs = [pygame.image.load('wall.png'),
pygame.image.load('other_wall.png')] #load images in list
wall_list = pygame.sprite.Group() #create a sprite group
BLACK = (0, 0, 0)
for i in range(2):
wall = Squeeze(wall_imgs[i]) #create a sprite
wall.rect.x = random.randrange(SCREEN_WIDTH)
wall.rect.y = random.randrange(SCREEN_HEIGHT)
wall_list.add(wall) #add the sprite to the sprite group
I hope this helps you a little bit :)
I have this classic example of a pygame program:
import pygame
import random
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
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
pygame.sprite.Sprite.__init__(self)
# 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 = 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(100):
# 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(RED, 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
# 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)
# Draw all the spites
for block in all_sprites_list:
if block.rect.y + 1 > screen_height:
block.rect.y = 0
block.rect.y = block.rect.y + 1
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(120)
pygame.quit()
Well, I notice that when I move the mouse, the rest of the blocks are moving slower(like freezing for a fraction of the second) but when it is in one place everything is moving smooth. The player sprite is in the list of all sprites and there is no calculation of the position of the player - only getting mouse's coordinates. And in my opinion there shouldn't be difference between getting (100,100) all the time and getting something else for coordinates of the mouse.
Could someone please explain why motion of the mouse (player's sprite) affects the rest of the sprites?
Thanks!
The problem is probably that you've been running Python for too long a while without restarting, and a fair bit of data has accumulated in memory without being deallocated during previous runs. As noted in the comments, rebooting will usually solve it.
I have an image in pygame with multiple instances of the image called in a for loop. is there a way I could move each instance of the image independently without moving the others with the code as is? or will I have to load separate instances of the image individually?
def pawn(self):
y_pos = 100
self.image = pygame.transform.scale(pygame.image.load('pawn.png'), (100,100))
for x_pos in range(0,8,1):
pieceNum = x_pos
screen.blit(self.image, (x_pos*100, y_pos))
I recommend to use pygame.sprite.Sprite and pygame.sprite.Group:
Create a class derived from pygame.sprite.Sprite:
class MySprite(pygame.sprite.Sprite):
def __init__(self, image, pos_x, pos_y):
super().__init__()
self.image = image
self.rect = self.image.get_rect()
self.rect.topleft = (pos_x, pos_y)
Load the image
image = pygame.transform.scale(pygame.image.load('pawn.png'), (100,100))
Create a list of sprites
imageList = [MySprite(image, x_pos*100, 100) for x_pos in range(0,8,1)]
and create a sprite group:
group = pygame.sprite.Group(imageList)
The sprites of a group can be drawn by .draw (screen is the surface created by pygame.display.set_mode()):
group.draw(screen)
The position of the sprite can be changed by changing the position of the .rect property (see pygame.Rect).
e.g.
imageList[0].rect = imageList[0].rect.move(move_x, move_y)
Of course, the movement can be done in a method of class MySprite:
e.g.
class MySprite(pygame.sprite.Sprite):
# [...]
def move(self, move_x, move_y):
self.rect = self.rect.move(move_x, move_y)
imageList[1].move(0, 100)
I'm learning Object Orientated Python and understand the main principals of classes and creating objects from classes however I need something explained Re: the pygame code below. I'm struggling to get my head around what's happening when sprite lists are being created and the two lines of code under the code which creates the ball object (allsprites.add etc). In other words what are sprites and why are lists of them created? Why isn't the ball object just created from the class on its own? Why does it need to be added to a sprite list?? What's going on? Any explanation would be greatly appreciated.
"""
Sample Breakout Game
Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
"""
# --- Import libraries used for this program
import math
import pygame
# Define some colors
black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
# Size of break-out blocks
block_width = 23
block_height = 15
class Block(pygame.sprite.Sprite):
"""This class represents each block that will get knocked out by the ball
It derives from the "Sprite" class in Pygame """
def __init__(self, color, x, y):
""" Constructor. Pass in the color of the block,
and its x and y position. """
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create the image of the block of appropriate size
# The width and height are sent as a list for the first parameter.
self.image = pygame.Surface([block_width, block_height])
# Fill the image with the appropriate color
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
self.rect = self.image.get_rect()
# Move the top left of the rectangle to x,y.
# This is where our block will appear..
self.rect.x = x
self.rect.y = y
class Ball(pygame.sprite.Sprite):
""" This class represents the ball
It derives from the "Sprite" class in Pygame """
# Speed in pixels per cycle
speed = 10.0
# Floating point representation of where the ball is
x = 0.0
y = 180.0
# Direction of ball (in degrees)
direction = 200
width = 10
height = 10
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create the image of the ball
self.image = pygame.Surface([self.width, self.height])
# Color the ball
self.image.fill(white)
# Get a rectangle object that shows where our image is
self.rect = self.image.get_rect()
# Get attributes for the height/width of the screen
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()
def bounce(self, diff):
""" This function will bounce the ball
off a horizontal surface (not a vertical one) """
self.direction = (180 - self.direction) % 360
self.direction -= diff
def update(self):
""" Update the position of the ball. """
# Sine and Cosine work in degrees, so we have to convert them
direction_radians = math.radians(self.direction)
# Change the position (x and y) according to the speed and direction
self.x += self.speed * math.sin(direction_radians)
self.y -= self.speed * math.cos(direction_radians)
# Move the image to where our x and y are
self.rect.x = self.x
self.rect.y = self.y
# Do we bounce off the top of the screen?
if self.y <= 0:
self.bounce(0)
self.y = 1
# Do we bounce off the left of the screen?
if self.x <= 0:
self.direction = (360 - self.direction) % 360
self.x = 1
# Do we bounce of the right side of the screen?
if self.x > self.screenwidth - self.width:
self.direction = (360 - self.direction) % 360
self.x = self.screenwidth - self.width - 1
# Did we fall off the bottom edge of the screen?
if self.y > 600:
return True
else:
return False
class Player(pygame.sprite.Sprite):
""" This class represents the bar at the bottom that the player controls. """
def __init__(self):
""" Constructor for Player. """
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
self.width = 75
self.height = 15
self.image = pygame.Surface([self.width, self.height])
self.image.fill((white))
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()
self.rect.x = 0
self.rect.y = self.screenheight-self.height
def update(self):
""" Update the player position. """
# Get where the mouse is
pos = pygame.mouse.get_pos()
# Set the left side of the player bar to the mouse position
self.rect.x = pos[0]
# Make sure we don't push the player paddle
# off the right side of the screen
if self.rect.x > self.screenwidth - self.width:
self.rect.x = self.screenwidth - self.width
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])
# Set the title of the window
pygame.display.set_caption('Breakout')
# Enable this to make the mouse disappear when over our window
pygame.mouse.set_visible(0)
# This is a font we use to draw text on the screen (size 36)
font = pygame.font.Font(None, 36)
# Create a surface we can draw on
background = pygame.Surface(screen.get_size())
# Create sprite lists
blocks = pygame.sprite.Group()
balls = pygame.sprite.Group()
allsprites = pygame.sprite.Group()
# Create the player paddle object
player = Player()
allsprites.add(player)
# Create the ball
ball = Ball()
allsprites.add(ball)
balls.add(ball)
# The top of the block (y position)
top = 80
# Number of blocks to create
blockcount = 32
# --- Create blocks
# Five rows of blocks
for row in range(5):
# 32 columns of blocks
for column in range(0, blockcount):
# Create a block (color,x,y)
block = Block(blue, column * (block_width + 2) + 1, top)
blocks.add(block)
allsprites.add(block)
# Move the top of the next row down
top += block_height + 2
# Clock to limit speed
clock = pygame.time.Clock()
# Is the game over?
game_over = False
# Exit the program?
exit_program = False
# Main program loop
while exit_program != True:
# Limit to 30 fps
clock.tick(30)
# Clear the screen
screen.fill(black)
# Process the events in the game
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_program = True
# Update the ball and player position as long
# as the game is not over.
if not game_over:
# Update the player and ball positions
player.update()
game_over = ball.update()
# If we are done, print game over
if game_over:
text = font.render("Game Over", True, white)
textpos = text.get_rect(centerx=background.get_width()/2)
textpos.top = 300
screen.blit(text, textpos)
# See if the ball hits the player paddle
if pygame.sprite.spritecollide(player, balls, False):
# The 'diff' lets you try to bounce the ball left or right
# depending where on the paddle you hit it
diff = (player.rect.x + player.width/2) - (ball.rect.x+ball.width/2)
# Set the ball's y position in case
# we hit the ball on the edge of the paddle
ball.rect.y = screen.get_height() - player.rect.height - ball.rect.height - 1
ball.bounce(diff)
# Check for collisions between the ball and the blocks
deadblocks = pygame.sprite.spritecollide(ball, blocks, True)
# If we actually hit a block, bounce the ball
if len(deadblocks) > 0:
ball.bounce(0)
# Game ends if all the blocks are gone
if len(blocks) == 0:
game_over = True
# Draw Everything
allsprites.draw(screen)
# Flip the screen and show what we've drawn
pygame.display.flip()
pygame.quit()
You don't need to add the balls and blocks to sprite lists - it's just a matter of convenience. You could manually check each ball for a collision, but it's easier to just tell pygame to check them all for you
# See if the ball hits the player paddle
if pygame.sprite.spritecollide(player, balls, False):
# The 'diff' lets you try to bounce the ball left or right
# depending where on the paddle you hit it
diff = (player.rect.x + player.width/2) - (ball.rect.x+ball.width/2)
# Set the ball's y position in case
# we hit the ball on the edge of the paddle
ball.rect.y = screen.get_height() - player.rect.height - ball.rect.height - 1
ball.bounce(diff)
You could draw each thing to the screen separately on each frame, but it's easier just to tell pygame to do it for you:
# Draw Everything
allsprites.draw(screen)
Things can be in more than one list as required, for example a ball is added to the balls list so that you can easily check for collisions, but also added to the allsprites list so that you can easily draw everything on the screen
# Create the ball
ball = Ball()
allsprites.add(ball)
balls.add(ball)
Edit:
An important distinction is that allsprites is actually a sprite.Group. It has a list of sprites inside it, but it also has other methods like draw.
To address your question of "what is a Sprite", it's simply a thing that gets drawn on screen. pygame methods like sprite.Group.draw expect a list of things with certain attributes - such as update. The easiest way to make sure that you provide all of those attributes with the right names is to subclass Sprite, however this is also a (strongly recommended) convenience thing - for instance, this is from the pygame source code:
While it is possible to design sprite and group classes that don't
derive from the Sprite and AbstractGroup classes below, it is strongly
recommended that you extend those when you add a Sprite or Group
class.
So what specifically does subclassing Sprite get you? Let's take a look at the source. Here's how to find the source code for a python module:
>>> import pygame.sprite
>>> pygame.sprite.__file__
'c:\\Python27\\lib\\site-packages\\pygame\\sprite.py'
>>>
Every python module has a __file__ attribute that tells you where the source is located (well not quite every). If you open it up in your editor, and scroll down, you see the class definition for Sprite:
class Sprite(object):
"""simple base class for visible game objects
pygame.sprite.Sprite(*groups): return Sprite
The base class for visible game objects. Derived classes will want to
override the Sprite.update() and assign a Sprite.image and
Sprite.rect attributes. The initializer can accept any number of
Group instances to be added to.
When subclassing the Sprite, be sure to call the base initializer before
adding the Sprite to Groups.
"""
def __init__(self, *groups):
self.__g = {} # The groups the sprite is in
if groups: self.add(groups)
def add(self, *groups):
"""add the sprite to groups
Sprite.add(*groups): return None
Any number of Group instances can be passed as arguments. The
Sprite will be added to the Groups it is not already a member of.
"""
has = self.__g.__contains__
for group in groups:
if hasattr(group, '_spritegroup'):
if not has(group):
group.add_internal(self)
self.add_internal(group)
else: self.add(*group)
def remove(self, *groups):
"""remove the sprite from groups
Sprite.remove(*groups): return None
Any number of Group instances can be passed as arguments. The Sprite will
be removed from the Groups it is currently a member of.
"""
has = self.__g.__contains__
for group in groups:
if hasattr(group, '_spritegroup'):
if has(group):
group.remove_internal(self)
self.remove_internal(group)
else: self.remove(*group)
def add_internal(self, group):
self.__g[group] = 0
def remove_internal(self, group):
del self.__g[group]
def update(self, *args):
"""method to control sprite behavior
Sprite.update(*args):
The default implementation of this method does nothing; it's just a
convenient "hook" that you can override. This method is called by
Group.update() with whatever arguments you give it.
There is no need to use this method if not using the convenience
method by the same name in the Group class.
"""
pass
def kill(self):
"""remove the Sprite from all Groups
Sprite.kill(): return None
The Sprite is removed from all the Groups that contain it. This won't
change anything about the state of the Sprite. It is possible to continue
to use the Sprite after this method has been called, including adding it
to Groups.
"""
for c in self.__g.keys():
c.remove_internal(self)
self.__g.clear()
def groups(self):
"""list of Groups that contain this Sprite
Sprite.groups(): return group_list
Return a list of all the Groups that contain this Sprite.
"""
return self.__g.keys()
def alive(self):
"""does the sprite belong to any groups
Sprite.alive(): return bool
Returns True when the Sprite belongs to one or more Groups.
"""
return (len(self.__g) != 0)
def __repr__(self):
return "<%s sprite(in %d groups)>" % (self.__class__.__name__, len(self.__g))
So in summary, you don't have to subclass Sprite - you could just provide all of these methods on your own - but it's easier if you do ;)
the background of my game is being weird. it doesn't work and the sprites show up, then it works but on top of the sprites!
import pygame
import random
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
lives = 10
# Call this function so the Pygame library can initialize itself
pygame.init()
screen = pygame.display.set_mode([700, 600])
clock = pygame.time.Clock()
# Set positions of graphics
background_position = [0,0]
# Make mouse invisible
pygame.mouse.set_visible(False)
pygame.font.init()
font= pygame.font.Font(None, 50)
# This class represents the ball
# It derives from the "Sprite" class in Pygame
class Background(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block,
# and its x and y position
def __init__(self, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block.
# This could also be an image loaded from the disk.
self.image = pygame.image.load("Grass2.fw.png").convert()
# 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()
# Reset position to the right of the screen, at an x location.
# Called by update() or the main program loop if there is a collision.
def reset_pos(self):
self.rect.y =(0)
self.rect.x =(0)
# Called each frame
def update(self):
# Move block left some pixels
self.rect.x -= 1
# If block is too far left, reset to right of screen.
if self.rect.x < -700:
self.reset_pos()
class Block(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block,
# and its x and y position
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# 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.image.load("Enemy small.fw.png").convert()
self.image.set_colorkey(white)
# 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()
# Reset position to the top of the screen, at a random x location.
# Called by update() or the main program loop if there is a collision.
def reset_pos(self):
self.rect.y = random.randrange(0, 600)
self.rect.x = random.randrange(700, 800)
# Called each frame
def update(self):
# Move block right one pixel
self.rect.x -= 1
# If block is too far left, reset to top of screen.
if self.rect.x < -100:
self.reset_pos()
class Player(Block):
def __init__(self, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block.
# This could also be an image loaded from the disk.
self.image = pygame.image.load("ship.fw.png").convert()
self.image.set_colorkey(white)
# 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()
def update(self):
# 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
self.rect.x=pos[0]
self.rect.y=pos[1]
# Initialize Pygame
pygame.init()
# Set the height and width of the screen
screen_width=700
screen_height=600
screen=pygame.display.set_mode([screen_width,screen_height])
pygame.display.set_caption('Razazone')
clock.tick(70)
#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()
background_list = pygame.sprite.Group()
# This represents a background
background = Background(20,15)
# Set a location for the block
background.rect.x = (screen_width)
background.rect.y = (screen_height)
background_list.add(background)
# Add the block to the list of objects
all_sprites_list.add(background)
for i in range(1):
# 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 = Player(350, 300)
all_sprites_list.add(player)
done=False
I know there is something wrong about the order of my updates but I can't figure out exactly what I need to do to fix the problem.
# -------- 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#
# Calls update() method on every sprite in the list
all_sprites_list.update()
# See if the player block has collided with anything.
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, False)
# Check the list of collisions.
for block in blocks_hit_list:
lives -=1
print (lives)
# Reset block to the top of the screen to fall again.
block.reset_pos()
# Reset block to the right of the screen to fall again.
#background.reset_pos()
if lives<=1:
lives=1
screen.fill(black)
background.update()
background_list.draw(screen)
# Draw all the spites
all_sprites_list.draw(screen)
lives_text=font.render("%d lives" % lives, True, white)
screen.blit(lives_text, [100,100])
#background.update()
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit()
You add background to background_list and all_sprite_list and then you draw background_list and all_sprite_list so your background is drawn twice.
Remove all_sprites_list.add(background)