Zaid Saeed
Zaid Saeed

Reputation: 199

How to create multiple sprites which are similar?

Let me show you the code which may help make this question make more sense.

import pygame, classes, random
pygame.init()

screen = pygame.display.set_mode((640, 480))

def game():
    pygame.display.set_caption("GOLOGO")

    laser = classes.Laser(screen)
    player = classes.Player(laser, screen)
    bad = classes.BadGuy(screen, 320, 0)
    bad1 = classes.BadGuy(screen, 260, 0)
    bad2 = classes.BadGuy(screen, 200, 0)
    bad3 = classes.BadGuy(screen, 140, 0)
    bad4 = classes.BadGuy(screen, 80, 0)
    bad5 = classes.BadGuy(screen, 20, 0)
    bad6 = classes.BadGuy(screen, 380, 0)
    bad7 = classes.BadGuy(screen, 440, 0)
    bad8 = classes.BadGuy(screen, 440, 60)
    bad9 = classes.BadGuy(screen, 320, 60)
    bad10 = classes.BadGuy(screen, 260, 60)
    bad11 = classes.BadGuy(screen, 200, 60)
    bad12 = classes.BadGuy(screen, 140, 60)
    bad13 = classes.BadGuy(screen, 80, 60)
    bad14 = classes.BadGuy(screen, 20, 60)
    bad15 = classes.BadGuy(screen, 380, 60)
    space = classes.Space(screen)
    scoreboard = classes.Scoreboard()

    allSprites = pygame.sprite.OrderedUpdates(space, laser, player)
    badSprites = pygame.sprite.Group(bad, bad1, bad2, bad3, bad4, \
        bad5, bad6, bad7, bad8, bad9, bad10, bad11, bad12, \
        bad13, bad14, bad15)
    scoreSprite = pygame.sprite.Group(scoreboard)

As you can see, there are a lot of BadGuy sprites. They are just in different locations. I don't mind continuing to do this method, but I was hoping that there would be a much easier way to do this. I am probably going to add a bunch more of them while increasing the size of the screen. I am using python 3 and pygame

Upvotes: 3

Views: 505

Answers (2)

aIKid
aIKid

Reputation: 28302

You can store the value in a list:

coordinates = [(320, 0), (260, 0), (200, 0), ...]

And loop through them as you create it. You can put the instances in a dictionary:

badGuys = {}
for i, v in enumerate(coordinates):
    badGuys["bad%d"%i] = classes.BadGuy(screen, *v) 

Hope this helps!

Upvotes: 1

steveha
steveha

Reputation: 76745

This is a classic case where a list will help.

For example:

bad_guys = []
bad_guys.append(classes.BadGuy(screen, 320, 0))
bad_guys.append(classes.BadGuy(screen, 260, 0))
bad_guys.append(classes.BadGuy(screen, 200, 0))
# ... and so on ...

Now you can refer to a specific bad guy with indexing:

bad_guys[0] # looks up the first bad guy, the one at (320, 0)

But notice that we have a lot of repetition here. We are always using the BadGuy class to make a bad guy, and we always pass screen as an argument.

We can pull out just those coordinate values, make a list of them, and then loop to make the bad guys:

coords = [
    (320, 0), (260, 0), (200, 0), (140, 0), (80, 0), (20, 0), (380, 0), (440, 0),
    (440, 0), (320, 0), (260, 0), (200, 0), (140, 0), (80, 0), (20, 0), (380, 0),
]

bad_guys = []
for x, y in coords:
    bad_guys.append(classes.BadGuy(screen, x, y))

The list of coordinates we have to just build, but now the list of bad guys can be built by a for loop.

But Python provides a short-cut we can use to build the bad_guys list. We can use a "list comprehension" to build the list of bad guys without an explicit for loop:

coords = [
    (320, 0), (260, 0), (200, 0), (140, 0), (80, 0), (20, 0), (380, 0), (440, 0),
    (440, 0), (320, 0), (260, 0), (200, 0), (140, 0), (80, 0), (20, 0), (380, 0),
]

bad_guys = [classes.BadGuy(screen, x, y) for x, y in coords]

That handles creating a list of bad guys.

Now that we have the list, we can need to call pygame.sprite.Group() with all the bad guys. We could do it by hand:

badSprites = pygame.sprite.Group(bad_guys[0], bad_guys[1], ... and so on ...)

but there is a much better way. In Python we can use the * operator to "paste" the values from a list or tuple:

badSprites = pygame.sprite.Group(*bad_guys)

Now it doesn't matter how many bad guys are in the bad_guys list; however many there are, they will be passed in as the arguments to pygame.sprite.Group().

EDIT: changed the code to store values as coordinates (both x and y). I wasn't sure what the "bad guy numbers" were but I am pretty sure that @alKid is correct and they are coordinates. Currently all the y values are 0 but that could change, so store both x and y values.

Upvotes: 1

Related Questions