• Immutable Page
• Info
• Attachments

（首页）开始编程之旅 翻译自Lee Harr的Start Programming

## 1. StartProgramming-4-3 Game

In the simplest case, every Drawable object is a rectangle.

Even when the image that you see is not just a rectangle, the sprite is considered to be the rectangle which would cover the entire image. pygsear defines two different colors you can use for transparency, or it can use the transparency created by an image program like GIMP.

A collision is when two of these rectangles overlap.

Notice here that even though the images themselves do not touch, these two sprites are colliding. In most cases this will not be a problem, since sprites tend to be small and move relatively fast.

In Pong the only collision we are worried about is between the Paddle and the Ball.

```   1 class Ball(Square):
2     def hit(self):
3         vx, vy = self.path.get_velocity()
4         vx = abs(vx)
5         self.path.set_velocity(vx=vx)
6
7 class Pong(Game):
8     def initialize(self):
11         ball = Ball()
13
16
19
21         self.ball = ball
22
23     def checkCollisions(self):
25             self.ball.hit()
```

Each time through the mainloop() loop, the Game will call checkCollisions()

Our checkCollisions() will check to see if the Ball has hit the Paddle and if so, it will call the hit() for the Ball.

Important: Notice how we need to modify the initialize() method to keep a handle on the Ball and the Paddle. If the Game did not hold on to those, it would have no way of checking the collisions.

Once we know there has been a collision, we know the Ball should end up moving to the right, and so that is all hit() does. It makes sure vx is positive, using the absolute value function.

The only thing left is to check for the Ball exiting the screen to the left, and to show the score.

```   1 from pygsear.Drawable import Score
2
3 class Pong(Game):
4     def initialize(self):
5         self.window.border(left=0, top=5, right=5, bottom=5)
6         self.window.setTitle('Pong!')
7
10         ball = Ball()
12
13         self.score = Score()
15
18
21
23         self.ball = ball
24
25     def checkCollisions(self):
27             self.ball.hit()
30
31         if not self.ball.onscreen(left=10):
32             self.ball.center()
33             self.ball.path.set_velocity(vx=150, vy=100)
```

Actually, while I was in there, I also set a title for the window and added a border around the screen.

That border might make it a bit more clear why all of the onscreen() calls were checking for the ball to be 5 pixels from the edge.

Here is the full source for the game. You can click on the link to download the file:

```   1 # Pong-1.0.py
2 from pygsear.Drawable import Rectangle, Square
3 from pygsear.Widget import Score
4 from pygsear.Game import Game
5 from pygsear.Event import KEYDOWN_Event, KEYUP_Event
6
7 from pygame.locals import K_UP, K_DOWN
8
10     def __init__(self):
11         Rectangle.__init__(self, width=15, height=50)
12         self.center(x=10)
13
14         self.up_pressed = 0
15         self.down_pressed = 0
16
17     def up(self, ev):
18          self.up_pressed = 1
19
20     def noup(self, ev):
21          self.up_pressed = 0
22
23     def down(self, ev):
24          self.down_pressed = 1
25
26     def nodown(self, ev):
27          self.down_pressed = 0
28
29     def setVel(self):
30         if self.up_pressed and not self.down_pressed:
31             self.path.set_velocity(vy=-100)
32         elif self.down_pressed and not self.up_pressed:
33             self.path.set_velocity(vy=100)
34         else:
35             self.path.set_velocity(vy=0)
36
37     def move(self):
38         self.setVel()
39         Rectangle.move(self)
40         self.onscreen(top=-5, bottom=-5, jail=1)
41
42
43 class Ball(Square):
44     def __init__(self):
45         Square.__init__(self, side=15)
46         self.center()
47         self.path.set_velocity(vx=150, vy=100)
48
49     def walls(self):
50         vx, vy = self.path.get_velocity()
51         if not self.onscreen(top=-5, bottom=-5, jail=1):
52             self.path.set_velocity(vy=-vy)
53         if not self.onscreen(right=-5, jail=1):
54             self.path.set_velocity(vx=-vx)
55
56     def hit(self):
57         vx, vy = self.path.get_velocity()
58         vx = abs(vx)
59         self.path.set_velocity(vx=vx)
60
61     def move(self):
62         self.walls()
63         Square.move(self)
64
65
66 class Pong(Game):
67     def initialize(self):
68         self.window.border(left=0, top=5, right=5, bottom=5)
69         self.window.set_title('Pong!')
70
73         ball = Ball()
75
76         self.score = Score()
78
81
84
86         self.ball = ball
87
88     def checkCollisions(self):
90             self.ball.hit()
93
94         if not self.ball.onscreen(left=10):
95             self.ball.center()
96             self.ball.path.set_velocity(vx=150, vy=100)
97
98
99 if __name__ == '__main__':
100     game = Pong()
101     game.mainloop()
```
• getACL = 0.002s