Reputation: 193
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.
Upvotes: 2
Views: 684
Reputation: 4007
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
.update()
method and .image
and.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 :)
Upvotes: 1