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

本文是使用pygsear+pygame作为开发环境,以初级用户角度来分步分阶段学习PYTHON基本概念,并以小游戏开发项目为具体案例,介绍的十分详细。编写风格清新朴实,没有象一般教科书那样枯燥,极其适合初级用户来激发兴趣时使用。

1. StartProgramming-4-4 Tweak

Ok, that is a pretty good start. We have a ball and a paddle and everything basically works.

好的,那是一个非常好的开始。我们有了一个球和一个挡板并且基本上所有的都工作了。

The game is not much fun though. What we need is to shake things up a little bit. Let's see how we can make the game better.

这个游戏并不够有趣。我们需要使事物有一点变化不定。让我们看看如何使游戏更好。

How about each time you hit the ball, it speeds up and goes in a random direction?

每次你击球,它加快速度并向一个随机的方向移动怎么样?

   1 import random
   2 
   3 class Ball(Square):
   4     def hit(self):
   5         vx, vy = self.path.get_velocity()
   6         vx = abs(vx) + 20
   7         vy = random.uniform(-100, 100)
   8         self.path.set_velocity(vx, vy)

That should make things a bit more exciting. Especially after you have hit the ball a few times.

那将使事情有一点刺激。特别是你在很短的时间击球之后。

In fact, if you try it out, it soon becomes impossible to hit the ball. We need to speed the paddle up as the ball goes faster.

事实上,如果你尝试那样做,它不久就会不可能击到球。我们需要加快挡板的速度就像球加速一样。

   1 class Paddle(Rectangle):
   2     def __init__(self):
   3         Rectangle.__init__(self, width=15, height=50)
   4         self.center(x=10)
   5 
   6         self.speed = 100
   7 
   8         self.up_pressed = 0
   9         self.down_pressed = 0
  10 
  11     def hit(self):
  12         self.speed += 4
  13 
  14     def setVel(self):
  15         if self.up_pressed and not self.down_pressed:
  16             self.path.set_velocity(vy=-self.speed)
  17         elif self.down_pressed and not self.up_pressed:
  18             self.path.set_velocity(vy=self.speed)
  19         else:
  20             self.path.set_velocity(vy=0)
  21 
  22 class Pong(Game):
  23     def checkCollisions(self):
  24         if self.ball.collide(self.paddle):
  25             self.ball.hit()
  26             self.paddle.hit()
  27             self.score.addPoints(1)
  28             self.score.updateScore()
  29 
  30         if not self.ball.onscreen(left=10):
  31             self.ball.center()
  32             self.ball.path.set_velocity(vx=150, vy=100)

Finally, to make the game ever so slightly addictive, I want to keep track of the high score so far.

最后,要使游戏每次都那么的吸引人,我想保持继续了解目前为止最高的分数。

   1 class Pong(Game):
   2     def initialize(self):
   3         self.window.border(left=0, top=5, right=5, bottom=5)
   4         self.window.setTitle('Pong!')
   5 
   6         paddle = Paddle()
   7         self.sprites.add(paddle)
   8         ball = Ball()
   9         self.sprites.add(ball)
  10 
  11         self.score = Score()
  12         self.sprites.add(self.score)
  13 
  14         self.events.add(KEYDOWN_Event(key=K_UP, callback=paddle.up))
  15         self.events.add(KEYUP_Event(key=K_UP, callback=paddle.noup))
  16 
  17         self.events.add(KEYDOWN_Event(key=K_DOWN, callback=paddle.down))
  18         self.events.add(KEYUP_Event(key=K_DOWN, callback=paddle.nodown))
  19 
  20         self.paddle = paddle
  21         self.ball = ball
  22 
  23         self.hscore = Score(text='High:', position=(100,70))
  24         self.sprites.add(self.hscore)
  25 
  26     def checkCollisions(self):
  27         if self.ball.collide(self.paddle):
  28             self.ball.hit()
  29             self.paddle.hit()
  30             self.score.addPoints(1)
  31             self.score.updateScore()
  32 
  33         if not self.ball.onscreen(left=10):
  34             self.ball.center()
  35             self.ball.path.set_velocity(vx=150, vy=100)
  36 
  37             high = max(self.score.points, self.hscore.points)
  38             self.hscore.setPoints(high)
  39             self.maxscore.updateScore()
  40             self.score.setPoints(0)
  41             self.score.updateScore()

So, here is the code for our tweaked pong game:

因此,这是我们 tweaked pong 的游戏的代码:

   1 # Pong-1.1.py
   2 import random
   3 
   4 from pygsear.Drawable import Rectangle, Square
   5 from pygsear.Widget import Score
   6 from pygsear.Game import Game
   7 from pygsear.Event import KEYDOWN_Event, KEYUP_Event
   8 
   9 from pygame.locals import K_UP, K_DOWN
  10 
  11 class Paddle(Rectangle):
  12     def __init__(self):
  13         Rectangle.__init__(self, width=15, height=50)
  14         self.center(x=10)
  15 
  16         self.up_pressed = 0
  17         self.down_pressed = 0
  18 
  19         self.speed = 100
  20 
  21     def up(self, ev):
  22          self.up_pressed = 1
  23 
  24     def noup(self, ev):
  25          self.up_pressed = 0
  26 
  27     def down(self, ev):
  28          self.down_pressed = 1
  29 
  30     def nodown(self, ev):
  31          self.down_pressed = 0
  32 
  33     def hit(self):
  34         self.speed += 4
  35 
  36     def setVel(self):
  37         if self.up_pressed and not self.down_pressed:
  38             self.path.set_velocity(vy=-self.speed)
  39         elif self.down_pressed and not self.up_pressed:
  40             self.path.set_velocity(vy=self.speed)
  41         else:
  42             self.path.set_velocity(vy=0)
  43 
  44     def move(self):
  45         self.setVel()
  46         Rectangle.move(self)
  47         self.onscreen(top=-5, bottom=-5, jail=1)
  48 
  49 
  50 class Ball(Square):
  51     def __init__(self):
  52         Square.__init__(self, side=15)
  53         self.center()
  54         self.path.set_velocity(vx=150, vy=100)
  55 
  56     def walls(self):
  57         vx, vy = self.path.get_velocity()
  58         if not self.onscreen(top=-5, bottom=-5, jail=1):
  59             self.path.set_velocity(vy=-vy)
  60         if not self.onscreen(right=-5, jail=1):
  61             self.path.set_velocity(vx=-vx)
  62 
  63     def hit(self):
  64         vx, vy = self.path.get_velocity()
  65         vx = abs(vx) + 20
  66         vy = random.uniform(-100, 100)
  67         self.path.set_velocity(vx=vx, vy=vy)
  68 
  69     def move(self):
  70         self.walls()
  71         Square.move(self)
  72 
  73 
  74 class Pong(Game):
  75     def initialize(self):
  76         self.window.border(left=0, top=5, right=5, bottom=5)
  77         self.window.set_title('Pong!')
  78 
  79         paddle = Paddle()
  80         self.sprites.add(paddle)
  81         ball = Ball()
  82         self.sprites.add(ball)
  83 
  84         self.paddle = paddle
  85         self.ball = ball
  86 
  87         self.events.add(KEYDOWN_Event(key=K_UP, callback=paddle.up))
  88         self.events.add(KEYUP_Event(key=K_UP, callback=paddle.noup))
  89 
  90         self.events.add(KEYDOWN_Event(key=K_DOWN, callback=paddle.down))
  91         self.events.add(KEYUP_Event(key=K_DOWN, callback=paddle.nodown))
  92 
  93         self.score = Score(text='Score:')
  94         self.sprites.add(self.score)
  95 
  96         self.hscore = Score(text='Max:', position=(100, 70))
  97         self.sprites.add(self.hscore)
  98 
  99     def checkCollisions(self):
 100         if self.ball.collide(self.paddle):
 101             self.ball.hit()
 102             self.paddle.hit()
 103             self.score.addPoints(1)
 104             self.score.updateScore()
 105 
 106         if not self.ball.onscreen(left=10):
 107             self.ball.center()
 108             self.ball.path.set_velocity(vx=150, vy=100)
 109 
 110             high = max(self.score.points, self.hscore.points)
 111             self.hscore.set_points(high)
 112             self.hscore.updateScore()
 113             self.score.set_points(0)
 114             self.score.updateScore()
 115 
 116 
 117 if __name__ == '__main__':
 118     game = Pong()
 119     game.mainloop()

There is actually at least one more bug that I know of in this version. See if you can find it. The pong.py in the pygsear examples/ directory has the bug fixed.

实际上这儿还剩下一个错误在我所知道的这个版本中。看看你能否找到它。在pygsear的目录 examples/ 中的 pong.py 已经修复这个错误了。