Python Programming for the Absolute Beginner, 3rd Edition
If you watch the Falling Pizza program run for any length of time, you may notice that once the pizza hits the ground, it keeps going. In fact, it keeps falling, appearing to go below the graphics window and out of sight.
Whenever you set a sprite in motion, you need to create a mechanism to deal with the graphics window's boundaries. That is, you need to tell your class what to do when one of its objects reaches the edge of the screen. You have a few choices. A moving sprite could simply stop when it reaches the edge of the screen. It could die in, say, a fiery explosion. It could bounce, like a giant rubber ball. It could even wrap around the screen so that just as it disappears off one edge, it reappears on the opposite. What seems to make the most sense for a falling pizza? Bouncing of course.
The Bouncing Pizza Program
When I say that a sprite "bounces" off the edges of the graphics window, I mean that when it reaches a screen boundary, it should reverse the velocity component that was moving it toward that boundary. So, if the bouncing pizza sprite reaches the top or bottom screen edge, it should reverse its dy attribute. When it reaches the sides of the screen, it should reverse its dx. Figure 11.12 illustrates the Bouncing Pizza program.
To create the Bouncing Pizza program, I modify the Falling Pizza program by adding one method to the Pizza class.
Writing the moved() Method
I need to add just a single method to the Pizza class to turn a falling pizza into a bouncing one. Every time the graphics window is updated by a Screen object's mainloop() method, a Games_Object's moved() method is automatically invoked. So, by creating a moved() method in Pizza, I get the perfect place to put code to handle screen boundary checking.
def moved(self): """ Reverse a velocity component if edge of screen reached. """ dx, dy = self.get_velocity() if self.get_right() > SCREEN_WIDTH or self.get_left() < 0: self.set_velocity(-dx, dy) if self.get_bottom() > SCREEN_HEIGHT or self.get_top() < 0: self.set_velocity(dx, -dy)
First, I retrieve the current velocity of the Pizza object by invoking its get_velocity() method, which returns the values of an object's dx and dy attributes. Next, I check to see if the sprite is about to go beyond the screen limits in any direction. If so, I reverse the responsible velocity by invoking the object's set_velocity() method, which takes two arguments and sets an object's dx and dy attributes.
If the x-coordinate of the sprite's right edge is greater than the screen width, then the pizza is about to go off the right edge into oblivion. If the x-coordinate of the sprite's left edge is less than 0, then the pizza is headed off the screen to the left. In either case, I simply reverse dx, the pizza's horizontal velocity.
If the y-coordinate of the sprite's bottom edge is greater than the screen height, then the pizza is about to fall through the bottom of the screen. If the y-coordinate of the sprite's top edge is less than 0, then the pizza is about to float through the top of the screen. In either case, I reverse dy, the pizza's vertical velocity.
Creating the Bouncing Pizza Object
I don't need to do anything else to the program for this bouncing behavior to work. But to make things more interesting, I give the sprite some velocity in the x direction, so that it will bounce all over the screen. I pass dx a value of 1 when I create the sprite, like so:
Pizza(screen = my_screen, x = SCREEN_WIDTH/2, y = SCREEN_HEIGHT/2, image = pizza_image, dx = 1, dy =1)
And that's it. I now have a bouncing pizza!
Категории