Monday, February 9, 2015

Sprites

     Alright, finally we should be getting into some really cool stuff (how many times have I said that?). According to my book, the whole thing we did with the ball isn't very good for making games. Let's all just take a moment to bang our heads against a wall.
     Well, there is a good reason. What if there was an actual background or multiple objects were moving on the screen (two things that you always, always see in a game)? Well, we have to use sprites, and conveniently enough, Pygame has something to help us with that.
     Okay, you're probably asking, "what's a sprite?" People use that term to refer to practically anything in a 2D game (usually animated). Sprites have animations and interact with other objects on the screen. They also have sprite classes, the base class being Sprite (whoa, didn't see that coming). We use it as a template to create our own subclass, and the code to create it looks a little something like this:

class ObjClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location):
          pygame.sprite.Sprite.__init__(self)
          self.image = pygame.image.load(image_file)
          self.rect = self.image.get_rect()
          self.rect.left, self.rect.top = location

     So we basically tell the program we want to create a subclass (ObjClass), then we promise to define itself, the image, and the location. We initialize, or as I like to remember, "set" the self, and then we load the image. After that, we find the size of the image (because no matter the transparency, all pictures are square) and find the location. The location contains 2 items, x and y, so we were able to assign them to two items on the other side, left and top (the order in which they are listed counts!). Oh, and I almost forgot; the two main properties of a sprite is the image itself and the rectangular area around it.
     Now that the subclass has been defined, we should actually use it. I'm thinking of using a different ball image (the old one is just a bit too big), so here's a new one! This image's size is 50x50.


     That's better. I saved it as tinyball.png (but you can always use a different name if you want to). Since we used generic variables, we'll have to define those variables. I guess I'll add a bunch of balls so we'll be using a for loop in the program.
     First, we have to define the image_file.

img_file="tinyball.png"

     Note that img_file is a different variable than the one we used, image_file. This is because we do not directly define the image_file in the def block. Remember, you specify the object in the parenthesis of a def function when you trigger it.
     Speaking of triggering the def, let's specify the location and image with for loops.

for x in range(0, 3):
    for y in range(0, 3):
        pos = [x * 130 + 10, y * 130 + 10]
        ball = ObjClass(img_file, pos)
        screen.blit(ball.image, ball.rect)
        pygame.display.flip()

     X resembles the x axis, and, you guessed it, y resembles the y axis. The x loop triggers the y loop which triggers the other stuff. Don't hurt your head thinking about it. It defines the position by taking the value of x and y's current iterations and doing a little math to them to change the position. We then assign the ObjClass to a variable called ball, in which we also define image_file as img_file and location as pos. It then is blitted onto the screen and the screen flips.
     Remember, it's always a good idea to keep your programs as flexible as possible. There might be better ways to write this, but this was the only solution I found to the bug I encountered. You can try creating a more flexible version of this if you please.
     Anyway, the program will then look like this.


     ...Nine balls? I'm honestly not entirely sure why there are NINE. But, I guess Python's going to do what Python's going to do.
     I'm feeling pretty wasted by this article now. I guess I'll see you when I see you! But before I go...
     Everyone programs a different way. I challenge you to find ways to program that feel the most comfortable, flexible, and/or efficient to you. You'll really have to think about this one!