版本16和17间的区别
于2006-09-03 19:01:38修订的的版本16
大小: 9304
编辑: czk
备注:
于2006-09-03 19:05:44修订的的版本17
大小: 11103
编辑: czk
备注:
删除的内容标记成这样。 加入的内容标记成这样。
行号 143: 行号 143:

= 结合在一起 =
把前面所讲的各个部分结合在一起,我们可以构成一个完整pygame程序:
{{{#!python
# INTIALISATION
import pygame, math, sys
from pygame.locals import *
screen = pygame.display.set_mode((1024, 768))
car = pygame.image.load('car.png')
clock = pygame.time.Clock()
k_up = k_down = k_left = k_right = 0
speed = direction = 0
position = (100, 100)
TURN_SPEED = 5
ACCELERATION = 2
MAX_FORWARD_SPEED = 10
MAX_REVERSE_SPEED = ­5
BLACK = (0,0,0)
while 1:
    # USER INPUT
    clock.tick(30)
    for event in pygame.event.get():
        if not hasattr(event, 'key'): continue
        down = event.type == KEYDOWN # key down or up?
        if event.key == K_RIGHT: k_right = down * ­5
        elif event.key == K_LEFT: k_left = down * 5
        elif event.key == K_UP: k_up = down * 2
        elif event.key == K_DOWN: k_down = down * ­2
        elif event.key == K_ESCAPE: sys.exit(0) # quit the game
    screen.fill(BLACK)
    # SIMULATION
    # .. new speed and direction based on acceleration and turn
    speed += (k_up + k_down)
    if speed > MAX_FORWARD_SPEED: speed = MAX_FORWARD_SPEED
    if speed < MAX_REVERSE_SPEED: speed = MAX_REVERSE_SPEED
    direction += (k_right + k_left)
    # .. new position based on current position, speed and direction
    x, y = position
    rad = direction * math.pi / 180
    x += ­speed*math.sin(rad)
    y += ­speed*math.cos(rad)
    position = (x, y)
    # RENDERING
    # .. rotate the car image for direction
    rotated = pygame.transform.rotate(car, direction)
    # .. position the car on screen
    rect = rotated.get_rect()
    rect.center = position
    # .. render the car to screen
    screen.blit(rotated, rect)
    pygame.display.flip()
}}}

TableOfContents

概述

1. 介绍

pygame是主要构筑在SDL库基础上的一组Python模块的集合,它使我们能够用Python语言来创建功能完整的游戏和多媒体程序。pygame是高度括平台可移植的,在任何SDL支持的平台上都可以运行(几乎可以在任何平台和操作系统上运行)。

pygame是自由、免费的,以GNU LGPL 2.1协议发布,完整的协议可以在 http://www.gnu.org/copyleft/lesser.html 找到。这协议基本上就让你可以在你的任何项目中使用pygame。你可以用它来创建开源、自由、免费、共享或者商业游戏。但是如果你要增加和改变pygame本身的功能,你必须以一种LGPL兼容的协议来发布这种修改。

而examples子目录中的程序属于公共域软件。

2. 安装

pygame安装的简单方法是下载对应于你的系统的二进制pygame安装包。二进制安装包通常包括了依赖信息。从 http://www.pygame.org/download.shtml 可以找到你的系统和python版本对应的pygame安装包。

从源代码安装pygame也是相当自动的过程。主要的工作就是要安装pygame所依赖的软件包。一旦它所依赖的东西就绪,那么只要简单的运行setup.py就可以完成pygame的自动配置、编译和安装。

pygame非常强的依赖于SDL和Pygame。同时它也连接或者嵌入了几个其他的小程序库。font模块依赖于SDL_tff(它又依赖于freetype),mixer和mixer.music模块依赖于SDL_mixer,imag模块依赖于SDL_image(它又依赖于libjpeg和libpng),transform模块为了rotozoom函数而内嵌了SDL_rotozoom,surfarray模块需要python的Numeric包来提供多维数组。

http://www.pygame.org/install.html 有更多关于安装的信息。

3. 文档

作为起步,pygame有很多tutorial和介绍文章(在 http://www.pygame.org/wiki/tutorials 可以找到)。然后在examples目录中,有很多可以运行的小程序,可以从这些程序的代码开始动手。

而完整的pygame参考手册在 http://www.pygame.org/docs/index.html 可以找到。

如果需要帮助,可以在IRC的pygame频道找到可以提供帮助的人:irc.freenode.net 6667 #pygame

pygame维护了一个活跃的邮件列表。你可以发信到pygame-users@seul.org来发信到邮件列表发送特定内容的信到majordomo@seul.org可以实现一些特别功能,比如订阅、取消订阅和获取帮助可以分别用如下内容(写在信的内容而不是标题中)的信件实现:

  • subscribe pygame-users
  • unsubscribe pygame-users
  • help

4. 参考资料

起步

1. 初始化

pygame的import和初始化是非常简单的。首先我们必须先导入(import)pygame这个包。

   1 import pygame
   2 from pygame.locals import *

第一行是必须的,它导入了pygame包中所有可用的模块。第二行是可选的,它把一些常量和函数放在global名字空间中。

必需注意的是,有些pygame模块是可选的,比如font模块。当你import pygame时,pygame会检查font模块是否存在。如果font模块存在,那么它会自动被导入为pygame.font。如果它不存在,pygame.font会被设置成None。

在用pygame前,必须先初始化。一般只要一句话就可以完成:

   1 pygame.init()

执行这个语句,它会试着去初始化所有的pygame模块。并不是所有的模块都是需要初始化的,这个语句会自动去初始化那些需要初始化的模块。你也可以手动的去初始化各个模块,比如说要单独初始化font模块可以这样做:

   1 pygame.font.init()

注意,如果执行pygame.init()初始化有错误,它不会给出异常。如果手动初始化单个模块,错误会导致抛出异常。任何必须初始化的模块都包含一个get_init()函数,来判断这个模块是否已经被初始化。

可以对任何模块多次调用init()函数而不会出错。

已经初始化的模块通常会有一个quit()函数来完成清理工作。没有必要显式的调用这个函数,因为pygame会在python退出的时候自动清理所有已经初始化的模块。

2. surface和screen

pygame最重要的部分就是surface。我们可以把surface看作是一张白纸。你可以对surface作很多操作,比如在surface上画线、用某种颜色填充surface上的部分区域、把图片拷贝到surface上去,把图片从surface上复制下来、设置或者读取surface上某个点的颜色。一个surface可以是任何大小,一个游戏可以有任意多surface。其中有一个surface是特别的,就是用pygame.display.set_mode()创建的display surface。它代表了screen屏幕,对它的任何操作会出现在用户的屏幕上。一个游戏只能有一个这样的surface,这是SDL的限制。

怎样创建surface?刚才提到,用pygame.display.set_mode()可以创建特殊的display surface。此外,还可以用image.load()创建一个包含图片的surface,还可以用font.render()创建一个包含文字的surface。你甚至可以用Surface()创建一个不包含任何东西的surface。

surface的大部分方法都不重要,只要学习其中的blit(), fill(), set_at()和get_at()就够用了。

display surface的初始化操作是这样的:

   1 screen = pygame.display.set_mode((1024, 768))
   2 screen = pygame.display.set_mode((1024, 768), pygame.FULLSCREEN)

你可以用set_mode把原来窗口的游戏变成全屏。其它的俄显式模式(可以用|连接)有

  • DOUBLEBUF
    • 对于平滑的动画所必须
  • OPENGL
    • 让你可以用PyOpenGL,但是不能用pygame的绘图函数

还有一个可选的depth参数,用来控制颜色显示的深度。一般情况下不用指定这个参数,只要用默认值就可以了。

如果使用DOUBLEBUF,你需要用flip函数来把绘制的内容显示到屏幕上。

>>> pygame.display.flip()

3. 画图

接下来,我们在屏幕上画一幅图像。我们通过最重要的画图原语BLIT(BLock Image Transfer)来实现,它可以把图像从一个地方(比如源图像)拷贝到另一个地方(比如屏幕上的某个位置)。

>>> car = pygame.image.load('car.png')
>>> screen.blit(car, (50, 100))
>>> pygame.display.flip()

这时,图片car.png中的内容会显示在屏幕上,图片的左上角在屏幕上的坐标是(50, 100)。屏幕坐标的X轴从作往右的,Y轴是从上往下的。然后我们可以用如下语句来旋转图片:

>>> rotated = pygame.transform.rotate(car, 45)
>>> screen.blit(car, (50, 100))
>>> pygame.display.flip()

要让屏幕上的任何东西动起来,需要一个这样的过程:画一个场景,然后把它擦掉,然后再画一幅稍微不同的场景,然后再擦掉……如此反复。比如:

   1 for i in range(100):
   2     screen.fill((0, 0, 0))
   3     screen.blit(car, (i, 0))

注意:这里我们把整个屏幕清楚然后重新绘制不是很好的方法。最好是只把屏幕上变化的部分擦掉重画,其它部分不变。Sprite模块可以帮助我们做这个事情。

4. 获取输入

pygame有多种方法获得用户的输入事件,最常见的方法有:

   1 pygame.event.wait()
   2 pygame.event.poll()
   3 pygame.event.get()

wait函数会阻塞游戏的执行直到有用户事件发生。这对于游戏不是很有用,因为我们希望在等待输入的同时还要产生动画。poll函数会查看是否有事件等待处理,并返回等待处理的一个事件,如果没有事件它就返回NOEVENT。get函数和poll类似,只是它会返回所有在等待处理的事件,没有事件它会返回空列表。

这里还要提一下非常重要的时间控制,如果没有它你的游戏会在计算机上能跑多快就跑多快,这往往不是我们希望的。时间控制很容易:

   1 clock = pygame.time.Clock()
   2 FRAMES_PER_SECOND = 30
   3 deltat = clock.tick(FRAMES_PER_SECOND)

tick函数会暂停一定的时间,使得上次调用tick的时间到此次调用tick的时间满1/30秒。这样有效的限制了调用tick的次数只有每秒30次。两次tick调用之间的实际时间差由tick函数返回(以毫秒为单位),在比较慢的计算机上,可能不能达到每秒30次。

非常重要的是每秒30帧的速度也决定了游戏响应用户输入的速度,因为它只在每次画图的时候检查用户的输入。以慢于每秒30次的速度检测输入会使用户觉得明显的延时。以每秒30次的帧速显示是因为30帧以上的速度对于人眼是没有用的。如果你的游戏是动作型的,那么你可能要把帧速提高一倍,这样使用户觉得他们的输入能够被更快地得到响应。

结合在一起

把前面所讲的各个部分结合在一起,我们可以构成一个完整pygame程序:

   1 # INTIALISATION
   2 import pygame, math, sys
   3 from pygame.locals import *
   4 screen = pygame.display.set_mode((1024, 768))
   5 car = pygame.image.load('car.png')
   6 clock = pygame.time.Clock()
   7 k_up = k_down = k_left = k_right = 0
   8 speed = direction = 0
   9 position = (100, 100)
  10 TURN_SPEED = 5
  11 ACCELERATION = 2
  12 MAX_FORWARD_SPEED = 10
  13 MAX_REVERSE_SPEED = ­5
  14 BLACK = (0,0,0)
  15 while 1:
  16     # USER INPUT
  17     clock.tick(30)
  18     for event in pygame.event.get():
  19         if not hasattr(event, 'key'): continue
  20         down = event.type == KEYDOWN     # key down or up?
  21         if event.key == K_RIGHT: k_right = down * ­5
  22         elif event.key == K_LEFT: k_left = down * 5
  23         elif event.key == K_UP: k_up = down * 2
  24         elif event.key == K_DOWN: k_down = down * ­2
  25         elif event.key == K_ESCAPE: sys.exit(0)     # quit the game
  26     screen.fill(BLACK)
  27     # SIMULATION
  28     # .. new speed and direction based on acceleration and turn
  29     speed += (k_up + k_down)
  30     if speed > MAX_FORWARD_SPEED: speed = MAX_FORWARD_SPEED
  31     if speed < MAX_REVERSE_SPEED: speed = MAX_REVERSE_SPEED
  32     direction += (k_right + k_left)
  33     # .. new position based on current position, speed and direction
  34     x, y = position
  35     rad = direction * math.pi / 180
  36     x += ­speed*math.sin(rad)
  37     y += ­speed*math.cos(rad)
  38     position = (x, y)
  39     # RENDERING
  40     # .. rotate the car image for direction
  41     rotated = pygame.transform.rotate(car, direction)
  42     # .. position the car on screen
  43     rect = rotated.get_rect()
  44     rect.center = position
  45     # .. render the car to screen
  46     screen.blit(rotated, rect)
  47     pygame.display.flip()

End

Pygame起步 (2010-01-29 16:48:28由s235-200编辑)

ch3n2k.com | Copyright (c) 2004-2020 czk.