使用pygame编写游戏(1)

1. 介绍

      游戏是编程应用较多的地方。即使是写一个最简单的游戏,你要熟悉UI制作,数学,物理学,甚至人工智能。这是一个练习编程的非常有趣的方式。

      如果你是(或者不是)python语言的粉丝,你对游戏很感兴趣,那么pygame是一个非常棒的游戏编程库,你需要仔细的来学习它。它可以运行在所有的主流平台上,提供简单的工具函数就能处理复杂的图像处理,比如图像的移动、声音等。

      网上有很多pygame的入门教程,但它们很多都是讲基本的。甚至Pygame book也属于介绍性级别的。为了更进一步提高对pygame的掌握,我决定写一个我自己的教程,希望能为使用pygame的人提供更进一步的合理学习。

     本教程明确鼓励你去改进代码,并强烈推荐做一下后面的练习题,这些练习题可以让你对学到内容有更好的认知。

2. 写在前面

      基于以上说的,这个教程并不适合初学者。如果你刚开始学习pygame,你可以看一下这些教程,推荐看这些基本的介绍教程

      在这里,我认为你具备以下知识:

      1. Python(你可能不是它的高级用户,但也完全不是一个初学者)。

      2. 数学和物理学的基本知识(向量,正方形,运动定律,概率等等)。我会解释所有非常见的知识点,但我不会教你怎么增加向量,等等。

      3. 对pygame的认知。比如,你已经学习过我之前提到的介绍性的pygame教程。、

      还有要说的是,我之关注2D游戏,3D游戏会是更高层次更复杂,我会提出一个不是很完整的3D游戏样本。

3. 让我们开始吧

     在这个部分,我们完整写一个游戏样例:模拟爬虫,一些生物在屏幕上移动,从墙上弹回来,时不时的改变方向。

http://eli.thegreenplace.net/wp-content/uploads/2008/12/creeps_screenshot_1.png

    虽然这称不上是一个游戏,但这是我们实现更多不同想法的好的起点。I’ll leave myself the luxury of postponing the decision of which game it will eventually be, for now.

4. 代码

    第一部分完整的代码包,包括需要的图片,可以在这里下载。我建议你下载下来并运行它。一遍看教程,一遍看代码将会对你非常有好处。我在python2.5.2,pygame1.8.1上测试过了,也可能会在其它版本上运行比较好。

5. pygame的文档

    pygame的API文档很全。这里有pygame全部模块,类,常量,函数的列表,我建议对你不熟悉的类或者方法,多去查找这个文档。

6. 爬虫

好吧,我先明确以下该部分的目标:

  • 我们想让爬虫能在屏幕上移动
  • 爬虫的总数是可以轻易的配置的
  • 爬虫碰到墙后能反弹
  • 为让游戏更有趣,爬虫需要表现出半随机的动作

那么爬虫是什么?

爬虫是一张图片,在pygame的驱动下,能够移动或者旋转。由于图片的制作超出我的能力,我只让爬虫能够向左右上下移动,而45度方向移动无法实现。

爬虫的图片包含在下载包中的小的.png文件中。

http://eli.thegreenplace.net/wp-content/uploads/2008/12/pinkcreep.png
http://eli.thegreenplace.net/wp-content/uploads/2008/12/bluecreep.png
http://eli.thegreenplace.net/wp-content/uploads/2008/12/graycreep.png

注意到所有的爬虫图片头部方向都是一致的。

爬虫是怎么移动的?

如果你确定读过一个基本的pygame教程(没有吗?),你会知道移动其实是一种幻觉。电脑屏幕上没真正移动的东西。其实,程序会对一系列图片以比人眼睛快的多的速度进行移位。每秒30次或更多次刷新,会让图片看上去更加平滑。为了实现周期性的刷屏,游戏有一个"game loop"

7. 游戏循环

和GUI程序一样,每个游戏都有一个“主循环”。在pygame中,使用了一个简单的循环,如下:

# The main game loop
#
while True:
    # Limit frame speed to 50 FPS
    #
    time_passed = clock.tick(50)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit_game()

    # Redraw the background
    screen.fill(BG_COLOR)

    # Update and redraw all creeps
    for creep in creeps:
        creep.update(time_passed)
        creep.blitme()

    pygame.display.flip()

就如我说的,这是一个基本的python循环--直到用户点击关闭窗口后,会给出退出消息,响应pygame.QUIT处理退出。

循环执行频度如何?这要取决于对clock.tick的调用。clock是pygame.time.Clock的对象,在此之前已经创建。调用tick的意思是:在下一个1/50秒到来前主循环休眠。在实际生活中,这限制了游戏的速度为50FPS,这是有好处的。一方面,我们可以让游戏更加平滑真实,另一方面,可以使游戏不能占用太多cpu资源。你可以尝试修改这个值,比如,当此值小于10,那么这个程序将会是什么样呢?我们看练习1和3.

现在是时候去看看关于tick的文档了。

每次循环都会重绘背景颜色,并且所有的爬虫会更新绘制。最终,整个屏幕会使用flip进行刷新(你应该看看它的文档了)。

8. 在循环之前

 

现在让我们看看在主循环之前都做了那些事情:ow let’s see what comes before the main loop:

# Game parameters
SCREEN_WIDTH, SCREEN_HEIGHT = 400, 400
BG_COLOR = 150, 150, 80
CREEP_FILENAMES = [
    'bluecreep.png',
    'pinkcreep.png',
    'graycreep.png']
N_CREEPS = 20

pygame.init()
screen = pygame.display.set_mode(
            (SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)
clock = pygame.time.Clock()

# Create N_CREEPS random creeps.
creeps = []
for i in range(N_CREEPS):
    creeps.append(Creep(screen,
                        choice(CREEP_FILENAMES),
                        (   randint(0, SCREEN_WIDTH),
                            randint(0, SCREEN_HEIGHT)),
                        (   choice([-1, 1]),
                            choice([-1, 1])),
                        0.1))

开始的几行都是可以自说明的,我认为你已经了解如何初始化pygame,并且创建display对象。但是爬虫对象的创建呢?

爬虫是一系列爬虫对象的集合,这是整个游戏的心脏和灵魂。下面是爬虫类的声明和其构造函数的定义。

class Creep(Sprite):
    """ A creep sprite that bounces off walls and changes its
        direction from time to time.
    """
    def __init__(
            self, screen, img_filename, init_position,
            init_direction, speed):
        """ Create a new Creep.

            screen:
                The screen on which the creep lives (must be a
                pygame Surface object, such as pygame.display)

            img_filaneme:
                Image file for the creep.

            init_position:
                A vec2d or a pair specifying the initial position
                of the creep on the screen.

            init_direction:
                A vec2d or a pair specifying the initial direction
                of the creep. Must have an angle that is a
                multiple of 45 degres.

            speed:
                Creep speed, in pixels/millisecond (px/ms)
        """

构造函数的参数有详细的说明文档,你可以看到它们在爬虫被创建时如何匹配的。


creeps.append(Creep(screen,
                    choice(CREEP_FILENAMES),
                    (   randint(0, SCREEN_WIDTH),
                        randint(0, SCREEN_HEIGHT)),
                    (   choice([-1, 1]),
                        choice([-1, 1])),
                    0.1))

首先,我们传递screen surface给爬虫类。爬虫将使用它判读如何从墙上反弹回来,如何去绘制自己。

其次,爬虫可以从图片列表中任意选择一个(choice是一个标准的python模块),它有一个屏幕随机位置,随机的方向,移动速度被设定为0.1像素/每毫秒,或者说100个像素/秒。

英文原地址 http://eli.thegreenplace.net/2008/12/13/writing-a-game-in-python-with-pygame-part-i/

Posted by imouse 2011年10月22日 02:38