青少年如何使用 Python 开始游戏开发

From: http://www.oschina.net/translate/beginning-game-programming-for-teens-with-python

这是一篇由教程团队成员Julian Meyer发表的文章,一个12岁的python开发人员。你可以在Google+和Twitter上找到他

你可曾想过如何创建视频游戏吗?它不像你想象的那么复杂!

在本教程中,您将创建一个简单的游戏叫做兔子和獾,在这里作为英雄的兔子要保卫城堡反击进攻的獾群。:O

写这个游戏,你将使用Python。不,我指的并不是一条大蛇!:]

Python是一种计算机编程语言。我们就本教程选择Python,Python是一种易于上手、有趣而且很容易学的语言。

如果你刚接触Python,开始之前先检出这本书 - 深入Python:怎样像计算机科学家一样思考,这将使你提升速度。

然后回到这里,准备开始—— 有一场小兔子和獾之间的战争即将发生。继续阅读将加入战争吧!

Garfielt
Garfielt
翻译于 5个月前

10人顶

顶 翻译的不错哦!

开始: 安装Python

如果你想在Windows电脑上尝试本教程,你需要安装Python,记住要安装2.7.3版本而不是3.3.0!运行完安装程序后,在开始菜单程序文件夹中会有IDLE,运行IDL。

如果你使用Mac,Python已经安装了!只需打开一个终端(/Applications/Utilities/Terminal.app),输入python然后按回车。

注意:如果你从python.org安装Python(如果你想获得PyGame需要这样做),那么你也需要在Mac上进入IDLE。它应该在“Applications/Python 2.7”文件夹内。

Garfielt
Garfielt
翻译于 5个月前

2人顶

顶 翻译的不错哦!

如果操作正确的话,你将会看到类似输出:

1Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43)
2[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
3Type "help", "copyright", "credits" or "license" for more information.
4>>>

注意:如果你想退出Python提示窗(三个尖括号提示:>>>),你可以通过在提示窗里输入exit()或按Ctrl+D。

一旦你在Python提示窗了,测试Python是否正常工作的话输入print 1+1,然后按回车或换行,它将输出2。你已经写了你的第一个Python程序。

现在你知道Python工作正常,为使用Python写游戏你需要安装PyGame。

PyGame是一个使写游戏变简单的Python库,它提供如图像处理、声音回放等你可以很容易添加都游戏中的功能。

到这来下载你系统适合的PyGame,确认你下载的是一个Python2.7版本。

Garfielt
Garfielt
翻译于 5个月前

4人顶

顶 翻译的不错哦!

注意:从上面链接下载的PyGame安装文件不能与Apple的Mac上默认安装的Python一起工作,为使用PyGame你需要从python.org上下载安装Python,或者你可以通过MacPorts安装Python和PyGame。

要检验PyGame安装是否正确的话,打开IDLE或通过终端运行Python,在Python提示符处输入import pygame,如果回车后没有输出的话你安装成功了。

如果,另一方面,输出了下附类似错误,PyGame没有正确安装。

1Python 2.7.2 (default, Jun 20 2012, 16:23:33)
2[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
3Type "help", "copyright", "credits" or "license" for more information.
4>>> import pygame
5Traceback (most recent call last):
6  File "<stdin>", line 1, in <module>
7ImportError: No module named pygame
8>>>
如果你遇到类似的错误,在论坛上发出来我将帮助你让它正常。
Garfielt
Garfielt
翻译于 5个月前

2人顶

顶 翻译的不错哦!

从文件运行Python代码

虽然你可以在Python提示符下运行短的Python代码,但如果你工作在一个大的程序(比如游戏)里,你可能想要将你的代码保存到一个文件,这样你就不必一遍又一遍地键入它了。

有几种方法可以运行Python程序文件。一种方法是使用一个纯文本编辑器,不如记事本(Windows)或TextEdit(Mac)。打开一个新的文本文件,输入你的Python代码(像print 1 + 1)。然后保存它为asXXX.py(XXX可以是任何描述性的文件名称)。

使用Windows的话,通过双击这个文件来运行它。在Mac上,打开终端,输入python,然后拖动你保存的文件到终端窗口并按Enter。

另一种方法是键入代码类到IDLE,也就是你在这个教程中需要做的方式。运行IDLE - 只需在终端输入IDLE。 然后选择文,然后选择File\New Window,会出现一个你可以输入代码的文本编辑器窗口。你可以通过File\Save保存你更改的代码,通过运行Run\Run Module(F5)运行代码。

请注意运行菜单只在你已有一个文件在编辑器窗口打开时有效。

Garfielt
Garfielt
翻译于 5个月前

1人顶

顶 翻译的不错哦!

添加游戏资源

你几乎已经可以开始创建你的游戏了。但没有一些震撼的图像和声音效果的游戏又算什么呢?我已经收集了游戏所需要的所的图形和声音效果并把它们压缩成了一个ZIP存档,你可以在这里下载。

下载文件后,在你的硬盘上创建一个游戏使用的文件夹,将resources文件夹解压到这个文件夹中,这样你的游戏文件夹有了名为resources的子文件夹,各种资源在resources文件夹里面分组显示如下:

Resources

兔子和獾的游戏你已经准备就绪。:]

Garfielt
Garfielt
翻译于 5个月前

4人顶

顶 翻译的不错哦!

第一步:(编写简单的)Hello Bunny(嘿,兔子)

运行IDLE开发环境,向上一节提到的那样,打开一个新的文本编辑窗。在编辑窗键入以下代码:

01# 1 - Import library
02import pygame
03from pygame.locals import *
04  
05# 2 - Initialize the game
06pygame.init()
07width, height = 640, 480
08screen=pygame.display.set_mode((width, height))
09  
10# 3 - Load images
11player = pygame.image.load("resources/images/dude.png")
12  
13# 4 - keep looping through
14while 1:
15    # 5 - clear the screen before drawing it again
16    screen.fill(0)
17    # 6 - draw the screen elements
18    screen.blit(player, (100,100))
19    # 7 - update the screen
20    pygame.display.flip()
21    # 8 - loop through the events
22    for event in pygame.event.get():
23        # check if the event is the X button
24        if event.type==pygame.QUIT:
25            # if it is quit the game
26            pygame.quit()
27            exit(0)
把它保存到你的游戏目录下(即资源子目录)并命名为itgame.py。

让我们逐段分析以上代码:

1. 导入PyGame库。这一步让你在你的程序中使用来自库中的函数。

2. 初始化PyGame并设置显示窗口。

3. 加载你想要给bunny使用的图片。

4. 循环执行以下缩进的代码。

5. 在绘图前,将屏幕填充成黑色。

6. 将之前加载进来的bunny图片以100*100的大小显示在屏幕上。

7. 更新屏幕。

8. 检查任何新事件如果有的话,否则转到退出命令,退出程序。

注意:根据PyGame的文档,你不需要调用pygame.quit()因为解析器关闭时会自动调用它。然而,至少在Mac OS上,这个游戏会在退出时挂起除非pygame.quite被调用。

如果现在运行这段代码(在Idle菜单栏点击 “Run\Run Module"),你应该可以看到一个如下所示的屏幕:

耶,兔子就显示在屏幕上了,并准备做动作!

但是只有一只兔子显示在一个黑漆漆的屏幕上,这个游戏看起来很吓人且很孤单。接下来要做的就是稍微美化一下咯。

jimmyjmh
jimmyjmh
翻译于 5个月前

4人顶

顶 翻译的不错哦!

第二步:添加布景

我们首先给游戏场景添加背景图片,可以通过调用一组screen.blit()来完成背景添加。

在代码的#3 小节,载入角色图像之后添加下面的代码:

1grass = pygame.image.load("resources/images/grass.png")
2castle = pygame.image.load("resources/images/castle.png")
这些代码载入图片然后赋给指定的变量,然后把它们画到屏幕上。但如果你检查草地的图片,你会发现它没有覆盖整个640 x 480的屏幕,所以你必须平铺使草地的图片完全覆盖屏幕。

在#6小节的开始(把兔子画在屏幕上之前),添加以下代码到game.py:

1for x in range(width/grass.get_width()+1):
2    for y in range(height/grass.get_height()+1):
3        screen.blit(grass,(x*100,y*100))
4screen.blit(castle,(0,30))
5screen.blit(castle,(0,135))
6screen.blit(castle,(0,240))
7screen.blit(castle,(0,345 ))
正如你所见,首先把x坐标通过for循环递增,在这个循环中再把y坐标循环递增,并且将草地画在使用循环生成的x、y坐标上。紧接着的一组代码只是将城堡画在屏幕上。

你现在运行这个程序,你会看到像如下的结果:

从现在开始,变得好看点了! :]

gadzllang
gadzllang
翻译于 5个月前

2人顶

顶 翻译的不错哦!

其它翻译版本(1)

第三步:让兔子动起来

下面你需要添加一些真正的游戏元素,比如让兔子响应键盘的按键。

要做到这一点,你需要实现好一个方法记录哪一个键在某一时刻被按下。你可以简单的使用一个数组保存在游戏需要使用的键的按下状态。

添加如下代码到game.py的#2小节结束(在你设了屏幕高和宽度之后):

1keys = [False, False, False, False]
2playerpos=[100,100]

这段代码是非常明了。数组keys按WASD的顺序记录它们的状态。数组的每个元素对应一个键,第一个是W,第二个是A等等。

gadzllang
gadzllang
翻译于 5个月前

1人顶

顶 翻译的不错哦!

其它翻译版本(1)

playerpos变量定义程序开始绘制游戏角色的起始位置。因为这个游戏将移动游戏角色到不同的位置,设置一个储存角色位置的变量,然后便可以简单地将角色绘制到这个位置。

现在你需要修改现有的代码来绘制角色,使用新的playerpos变量,将# 6的程序:

1screen.blit(player, (100,100))
改为:
1screen.blit(player, playerpos)

接下来,基于哪些按键被按下更新键数组,PyGame通过添加event.key事件使检测按键很容易实现。

在# 8检测event.type==pygame.QUIT之后,添加这些代码(如果有块缩进的话使用与pygame.QUIT相同的缩进级):

01if event.type == pygame.KEYDOWN:
02    if event.key==K_w:
03        keys[0]=True
04    elif event.key==K_a:
05        keys[1]=True
06    elif event.key==K_s:
07        keys[2]=True
08    elif event.key==K_d:
09        keys[3]=True
10if event.type == pygame.KEYUP:
11    if event.key==pygame.K_w:
12        keys[0]=False
13    elif event.key==pygame.K_a:
14        keys[1]=False
15    elif event.key==pygame.K_s:
16        keys[2]=False
17    elif event.key==pygame.K_d:
18        keys[3]=False

哇!这里有很多行代码,如果你把它按If语句拆分也不是很复杂的。

Garfielt
Garfielt
翻译于 5个月前

1人顶

顶 翻译的不错哦!

首先你要检测一是否有键被按下或释放,然后你需要检测哪个键被按下或者释放,如果被按下或者释放的键是你要使用的键,根据键值更新相应的键变量。

最后,你需要更新playerpos变量作为键按下的响应,这太简单了。

将下附代码添加到game.py的末尾(使用相同的缩进级,使用和for循环相同的缩进级)

1# 9 - Move player
2if keys[0]:
3    playerpos[1]-=5
4elif keys[2]:
5    playerpos[1]+=5
6if keys[1]:
7    playerpos[0]-=5
8elif keys[3]:
9    playerpos[0]+=5

这段代码只是检查哪个键被按下,然后添加或减去游戏角色的x或y位置(取决于按下的键)来移动游戏角色。

运行这个游戏,你会得到根以前一样的角色。试一下按WASD键,哈哈,起效了!

Garfielt
Garfielt
翻译于 5个月前

2人顶

顶 翻译的不错哦!

第四步: 旋转兔子

是的,你的兔子现在可以随着你的按键移动,但用鼠标来旋转兔子朝向到你选择的方向岂不更酷,所以它不是所有时间都朝向一个方向。使用三角函数来实现,这很简单。

看一下下面的图解:

上图中,如果(5,3)是兔子的位置,(2,4)是当前鼠标的位置,你可以通过对两点间距离的不同应用atan2三角函数获得旋转角度(z)。当然,一旦你知道旋转角,你可以轻松相应地旋转兔子。:]

Garfielt
Garfielt
翻译于 5个月前

4人顶

顶 翻译的不错哦!

如果你对这部分有点困惑,不要担心,你依然可以继续。但这就是你应该在数学课上用功的原因!:]在游戏编程时你会一直使用这个东西。

现在你需要将这个原理应用到你的游戏上,为做到这一点,你可以使用PyGameSurface.rotate(度数)函数, 顺便说一下,记住,Z值是弧度。:[

atan2函数在Python的math库总,所有先在#1结尾处增加:

1import math

然后,将#6最后一行(player.blit这行)替换成下面的代码:

1# 6.1 - Set player position and rotation
2position = pygame.mouse.get_pos()
3angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+26))
4playerrot = pygame.transform.rotate(player, 360-angle*57.29)
5playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)
6screen.blit(playerrot, playerpos1)

让我们梳理一下上面代码的基本流程。首先获取鼠标和游戏角色的位置,然后你对两个位置应用atan2函数,之后,你将atan2返回的弧度转化成度数(将弧度乘以近似57.29或360/2π)。

因为兔子会旋转,它的位置也将会改变。所以现在计算兔子的新位置并把它显示在屏幕。

再次运行这个游戏。如果你只按了“WASD”键,那么这个游戏应该和之前完全一样,但如果你移动你的鼠标兔子也会随之旋转,酷!

Garfielt
Garfielt
翻译于 5个月前

3人顶

顶 翻译的不错哦!

第五步:射击吧,兔子!

现在你的兔子已经可以自由活动了,是时候给它添加更多的动作了。让兔子可以用剑射击敌人怎么样?它可不是只温顺的兔斯基!

这一步稍微有点复杂,因为你必须记录所有射出的剑,更新它们的位置、旋转并且在它们飞出屏幕后删除它们。

首先,在初始化小节(#2小节)的结束添加必要的变量:

1acc=[0,0]
2arrows=[]
第一个变量记录玩家的射击精度,第二个变量记录所有的剑。精度变量acc实际上是一个包含射击数量和命中獾 次数的列表。最后我们可以使用这些信息来计算精度的百分比。
gadzllang
gadzllang
翻译于 5个月前

1人顶

顶 翻译的不错哦!

接下来,在section #3的末尾加载弓箭图像:

1arrow = pygame.image.load("resources/images/bullet.png")
现在当玩家点击鼠标,弓箭就要射出。在section #8的末尾加入以下代码作为新的事件句柄(event handler):
1if event.type==pygame.MOUSEBUTTONDOWN:
2    position=pygame.mouse.get_pos()
3    acc[1]+=1
4    arrows.append([math.atan2(position[1]-(playerpos1[1]+32),position[0]-(playerpos1[0]+26)),playerpos1[0]+32,playerpos1[1]+32])
这些代码检查是否有鼠标点击,如果有它会读取鼠标位置,并根据玩家的旋转和指针的位置计算出弓箭的旋转。这个旋转储存在arrows数组里。

接下来你需要真正在屏幕上画出弓箭了。在section #6.1之后插入以下代码:

01# 6.2 - Draw arrows
02for bullet in arrows:
03    index=0
04    velx=math.cos(bullet[0])*10
05    vely=math.sin(bullet[0])*10
06    bullet[1]+=velx
07    bullet[2]+=vely
08    if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480:
09        arrows.pop(index)
10    index+=1
11    for projectile in arrows:
12        arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29)
13        screen.blit(arrow1, (projectile[1], projectile[2]))

运用基本的三角函数可以计算出vely和velx。10是弓箭的速度。if语句检查弓箭是否飞出边界,如果是则删除该弓箭。第二个for语句循环过arrows数组并画出相应旋转的弓箭。

试试运行程序。你应该有一只兔兔在你点击鼠标时发射弓箭了。(。☉౪ ⊙。)

AUA
AUA
翻译于 5个月前

1人顶

顶 翻译的不错哦!

第六步:拿起武器!獾!

好的,你有了一个城堡和可以移动和射击的英雄。但少了什么东西呢?攻击城堡的敌人!


(炸掉你的城堡!)

在这个步骤中,你将创建几只随机生成并跑向城堡的獾。随着游戏的进展会有越来越多的獾。所以,让我们做一个列表看看需要做那些工作。

1、把坏家伙们添加到一个数组列表;

2、每帧每帧的更新这个数组并检查他们是否都出现在屏幕上;

3、显示这些坏家伙。

很容易,是吧:]

首先,把下面这段代码添加到section #2后面:

1badtimer=100
2badtimer1=0
3badguys=[[640,100]]
4healthvalue=194
上面这段代码设置了一个计时器(以及其他一些值)以便每过一段时间在游戏中增加一只新的獾。你每帧每帧的减少 badtimer直到0, 然后就生成一个新的獾。
HouGary
HouGary
翻译于 5个月前

1人顶

顶 翻译的不错哦!

现在把下面这段代码添加到section #3后面:

1badguyimg1 = pygame.image.load("resources/images/badguy.png")
2badguyimg=badguyimg1

上面代码的第一行类似于前面所有的图片加载代码。第二行代码设置了一个图片副本以便于这个坏家伙能更容易动起来。

下一步,你必须更新并且显示这个坏家伙。把下面代码添加到section #6.2之后

01# 6.3 - Draw badgers
02if badtimer==0:
03    badguys.append([640, random.randint(50,430)])
04    badtimer=100-(badtimer1*2)
05    if badtimer1>=35:
06        badtimer1=35
07    else:
08        badtimer1+=5
09index=0
10for badguy in badguys:
11    if badguy[0]<-64:
12        badguys.pop(index)
13    badguy[0]-=7
14    index+=1
15for badguy in badguys:
16    screen.blit(badguyimg, badguy)

仔细的看下这段代码,:] 第一行检查badtimer是否为0,以badtimer至今为止已经运行的次数为基础,创建一个新的獾并再次设置badtimer。第一个for循环更新獾的X坐标,并检查是否在屏幕上。如果不再屏幕上就删除掉。第二个佛如循环绘制所有獾。

HouGary
HouGary
翻译于 5个月前

1人顶

顶 翻译的不错哦!

为了在上述代码中使用随机函数,我们必须引入 random 库:

1import random
最后,在 while 语句后面添加下面一行代码用来让 badtimer 值减1:
1badtimer-=1

再次运行游戏来测试上述代码,现在你将看到真正的游戏,你可以发射、移动、转向,而且獾也尝试跑向你。

但等等,为什么不是獾炸毁这座城堡吗?马上搞定!

红薯
红薯
翻译于 5个月前

1人顶

顶 翻译的不错哦!

在#6.3小节中每一个循环前的 index += 1 之前添加如下代码:

1# 6.3.1 - Attack castle
2badrect=pygame.Rect(badguyimg.get_rect())
3badrect.top=badguy[1]
4badrect.left=badguy[0]
5if badrect.left<64:
6    healthvalue -= random.randint(5,20)
7    badguys.pop(index)
8# 6.3.3 - Next bad guy

这段代码非常简单,如果獾的x坐标值小于64,则删除这家伙然后随机递减5到20点的城堡的生命值。(在后面你可以显示生命值到屏幕上)

现在你构建并运行程序,你将看到一堆獾攻击城堡后消失。虽然你不能看到但獾确实降低了城堡的生命值。


gadzllang
gadzllang
翻译于 5个月前

0人顶

顶 翻译的不错哦!

第七步:獾与箭的碰撞

现在獾可以攻击你的城堡但你的箭却对它们没有任何效果!兔子该如何保护自己的家园?

是时候让箭可以杀死獾,你才可以保护你的城堡赢得游戏!首先,你必须循环检查每个坏蛋,在检查时以需要循环检查所有的箭是不是和獾碰撞了。如果箭碰到了獾则删除箭和獾,并且递增命中值。

在#6.3.1小节后添加如下代码:

01#6.3.2 - Check for collisions
02index1=0
03for bullet in arrows:
04    bullrect=pygame.Rect(arrow.get_rect())
05    bullrect.left=bullet[1]
06    bullrect.top=bullet[2]
07    if badrect.colliderect(bullrect):
08        acc[0]+=1
09        badguys.pop(index)
10        arrows.pop(index1)
11    index1+=1

这段代码里有一个值得注意的地方,if语句后是PyGame内建的检查两个矩形是否相交的函数。其他语句只是按上面解释运行。

如果你现在运行程序,你会发现已经可以射击并杀死獾了。

gadzllang
gadzllang
翻译于 5个月前

0人顶

顶 翻译的不错哦!

第八步:添加生命值和时钟显示

游戏现在进展良好,有攻击者和守卫者。现在你还需要一种方式显示分数,看看这些兔子干得怎么样。

最简单的方式是添加一个HUD(平视显示器)显示当前城堡的健康状况。也可以添加一个时钟显示城堡被保护了多久。

首先添加时钟,在#7小节前添加如下代码:

1# 6.4 - Draw clock
2font = pygame.font.Font(None, 24)
3survivedtext = font.render(str((90000-pygame.time.get_ticks())/60000)+":"+str((90000-pygame.time.get_ticks())/1000%60).zfill(2), True, (0,0,0))
4textRect = survivedtext.get_rect()
5textRect.topright=[635,5]
6screen.blit(survivedtext, textRect)

上面代码简单的使用PyGame默认字体创建字体并设置尺寸为24。然后使用字体渲染时间到表面上。之后广西被定位并绘制到屏幕上。

gadzllang
gadzllang
翻译于 5个月前

0人顶

顶 翻译的不错哦!

下一步添加生命条。在绘制生命条之前你需要载入它的背景图。添加如下代码到#3小节结束:

1healthbar = pygame.image.load("resources/images/healthbar.png")
2health = pygame.image.load("resources/images/health.png")
第一个是红色图用来铺满生命条。第二个绿色图显示当前生命值。

现在添加如下代码到#6.4节(你上一步添加的)之后来将生命条画到屏幕上:

1# 6.5 - Draw health bar
2screen.blit(healthbar, (5,5))
3for health1 in range(healthvalue):
4    screen.blit(health, (health1+8,8))
上面的代码首先画出全红色的生命条,然后根据城堡的剩余的生命绘制绿色生命条。

现在你构建并运行程序,你可以看到时钟和生命条。

gadzllang
gadzllang
翻译于 5个月前

0人顶

顶 翻译的不错哦!

第九步:判断输赢

这是什么?如果你玩得足够久,即使你的命令值降到了0,游戏还是继续!不仅仅如此,你也还可以继续射击獾。这应该行不通的,但现在就是这样。你需要添加某种赢/输形式的场景让这个游戏值得玩。

所以我们现在添加输赢条件和各自的画面。你可以退出主游戏循环并进入输赢界面的循环。在输赢循环中,你可以检查用户是输了还是赢了,并显示相应的界面。

下面是一个判断输赢的基本方法:

如果超过了时间(90000毫秒或90秒):

  • 停止运行游戏
  • 设置游戏的结果为赢了

如果城堡被摧毁了:

  • 停止运行游戏
  • 设置游戏结果为输了

计算准确度的方法。

注:使用acc[0]*1.0 只是将acc[0]转换成float浮点类型,如果你不这么转换,则除法操作将返回一个整数值比如1或2而不是1.5。

gadzllang
gadzllang
翻译于 5个月前

0人顶

顶 翻译的不错哦!

将下面的代码加到game.py末尾:

01    #10 - Win/Lose check
02    if pygame.time.get_ticks()>=90000:
03        running=0
04        exitcode=1
05    if healthvalue<=0:
06        running=0
07        exitcode=0
08    if acc[1]!=0:
09        accuracy=acc[0]*1.0/acc[1]*100
10    else:
11        accuracy=0
12# 11 - Win/lose display       
13if exitcode==0:
14    pygame.font.init()
15    font = pygame.font.Font(None, 24)
16    text = font.render("Accuracy: "+str(accuracy)+"%", True, (255,0,0))
17    textRect = text.get_rect()
18    textRect.centerx = screen.get_rect().centerx
19    textRect.centery = screen.get_rect().centery+24
20    screen.blit(gameover, (0,0))
21    screen.blit(text, textRect)
22else:
23    pygame.font.init()
24    font = pygame.font.Font(None, 24)
25    text = font.render("Accuracy: "+str(accuracy)+"%", True, (0,255,0))
26    textRect = text.get_rect()
27    textRect.centerx = screen.get_rect().centerx
28    textRect.centery = screen.get_rect().centery+24
29    screen.blit(youwin, (0,0))
30    screen.blit(text, textRect)
31while 1:
32    for event in pygame.event.get():
33        if event.type == pygame.QUIT:
34            pygame.quit()
35            exit(0)
36    pygame.display.flip()

这是截至目前最长的代码块,但不是最复杂的。

第一个if语句检查是否到时间,第二个检查城堡是否被摧毁,第三个计算你的准确率。之后,一个快速的if语句检查你是胜利还是失败了,并显示正确的图像。

当然,如果你想显示胜利与失败的屏幕图像,那么这些图像必须先被加载。将下面的代码添加到# 3结束的地方:

1gameover = pygame.image.load("resources/images/gameover.png")
2youwin = pygame.image.load("resources/images/youwin.png")

另一点,更改#4处:

1# 4 - keep looping through
2while 1:
3    badtimer-=1
更改为:
1# 4 - keep looping through
2running = 1
3exitcode = 0
4while running:
5    badtimer-=1

running变量跟踪游戏是否结束,exitcode变量跟踪玩家是赢了还是输了。

再次运行游戏,现在你可以尝试胜利或死亡!酷!:]

Garfielt
Garfielt
翻译于 5个月前

1人顶

顶 翻译的不错哦!

第10步: 免费的音乐和声音效果!

这个游戏看起来相当棒,可是有声音吗?是不是太安静了点呢?增加一点点音效会让整个游戏的感觉变得更棒。

PyGame 加载并播放声音的方法非常简单。首先你需要初始化混音器,代码如下:

1pygame.mixer.init()
然后加载要播放的声音,并设置音量大小:
01# 3.1 - Load audio
02hit = pygame.mixer.Sound("resources/audio/explode.wav")
03enemy = pygame.mixer.Sound("resources/audio/enemy.wav")
04shoot = pygame.mixer.Sound("resources/audio/shoot.wav")
05hit.set_volume(0.05)
06enemy.set_volume(0.05)
07shoot.set_volume(0.05)
08pygame.mixer.music.load('resources/audio/moonlight.wav')
09pygame.mixer.music.play(-1, 0.0)
10pygame.mixer.music.set_volume(0.25)
红薯
红薯
翻译于 5个月前

7人顶

顶 翻译的不错哦!

最上代码中大多数是简单加载音频文件和配置的音频音量,但要注意pygame.mixer.music.load这一行——这一行加载游戏的背景音乐,下一行设置背景音乐一直重复。

注意音频配置。:] 现在,你所需要做的就是按需要播放各种声音效果。像下面每段注释代码那样做:

1# section 6.3.1 after if badrect.left<64:
2hit.play()
3# section 6.3.2 after if badrect.colliderect(bullrect):
4enemy.play()
5# section 8, after if event.type==pygame.MOUSEBUTTONDOWN:
6shoot.play()

多次运行游戏,你会发现你现在有碰撞的背景音乐和射击的声音效果,游戏让人感觉更逼真了!:]

Garfielt
Garfielt
翻译于 5个月前

1人顶

顶 翻译的不错哦!

从哪里开始?

你应该为自己感到自豪:你刚刚创建完成一个有趣的游戏,里面充满了音乐,音效,一个杀手兔子,神风特攻队獾和更多东西。我告诉你你可以做到!:]

你可以在这里下载最终的游戏源代码。

这时,在游戏中随意拓展你的创造力!也许可以试着换成与你自己的绘画风格,或添加不同的武器或不同类型的怪物到游戏中!

在完成这个教程中你有问题或评论吗? 如果有,请加入我们论坛的讨论中! 我很期待你的来信。

===================完整代码如下:

# 1
import pygame, math, random
from pygame.locals import *# 2
pygame.init()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
keys = [False, False, False, False]
playerpos = [100, 100]
acc = [0, 0]
arrows = []badtimer = 100
badtimer1 = 0
badguys = [[640, 100]]
healthvalue = 194# 3
pygame.mixer.init()
player = pygame.image.load("resources/images/dude.png")
grass = pygame.image.load("resources/images/grass.png")
castle = pygame.image.load("resources/images/castle.png")
arrow = pygame.image.load("resources/images/bullet.png")
badguyimg1 = pygame.image.load("resources/images/badguy.png")
badguyimg = badguyimg1
healthbar = pygame.image.load("resources/images/healthbar.png")
health = pygame.image.load("resources/images/health.png")
gameover = pygame.image.load("resources/images/gameover.png")
youwin = pygame.image.load("resources/images/youwin.png")# 3.1 - Load audio
hit = pygame.mixer.Sound("resources/audio/explode.wav")
enemy = pygame.mixer.Sound("resources/audio/enemy.wav")
shoot = pygame.mixer.Sound("resources/audio/shoot.wav")
hit.set_volume(0.05)
enemy.set_volume(0.05)
shoot.set_volume(0.05)
pygame.mixer.music.load("resources/audio/moonlight.wav")
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)# 4 - keep looping through
running = 1
exitcode = 0
while running:badtimer -= 1# 5screen.fill(0)# 6for x in range(width/grass.get_width()+1):for y in range(height/grass.get_height()+1):screen.blit(grass, (x * 100, y * 100))screen.blit(castle, (0, 30))screen.blit(castle, (0, 135))screen.blit(castle, (0, 240))screen.blit(castle, (0, 345))# 6.1position = pygame.mouse.get_pos()angle = math.atan2(position[1] - (playerpos[1] + 32), position[0] - (playerpos[0] + 26))playerrot = pygame.transform.rotate(player, 360 - angle * 57.29)playerpos1 = (playerpos[0] - playerrot.get_rect().width / 2, playerpos[1] - playerrot.get_rect().height / 2)screen.blit(playerrot, playerpos1)# 6.2 - Draw arrowsfor bullet in arrows:index = 0velx = math.cos(bullet[0]) * 10vely = math.sin(bullet[0]) * 10bullet[1] += velxbullet[2] += velyif bullet[1] < -64 or bullet[1] > 640 or bullet[2] < -64 or bullet[2] > 480:arrows.pop(index)index += 1for projectile in arrows:arrow1 = pygame.transform.rotate(arrow, 360 - projectile[0] * 57.29)screen.blit(arrow1, (projectile[1], projectile[2]))# 6.3 - Draw badgersif badtimer == 0:badguys.append([640, random.randint(50, 430)])badtimer = 100 - (badtimer1 * 2)if badtimer1 >= 35:badtimer1 = 35else:badtimer1 += 5index = 0for badguy in badguys:if badguy[0] < -64:badguys.pop(index)badguy[0] -= 7# 6.3.1 - Attack castlebadrect = pygame.Rect(badguyimg.get_rect())badrect.top = badguy[1]badrect.left = badguy[0]if badrect.left < 64:hit.play()healthvalue -= random.randint(5, 20)badguys.pop(index)# 6.3.2 - Check for collisionsindex1 = 0for bullet in arrows:bullrect = pygame.Rect(arrow.get_rect())bullrect.left = bullet[1]bullrect.top = bullet[2]if badrect.colliderect(bullrect):enemy.play()acc[0] += 1badguys.pop(index)arrows.pop(index1)index1 += 1index += 1for badguy in badguys:screen.blit(badguyimg, badguy)# 6.4 - Draw clockfont = pygame.font.Font(None, 24)survivedtext = font.render(str((90000 - pygame.time.get_ticks()) / 60000) + ": " + str((90000 - pygame.time.get_ticks()) / 1000 % 60).zfill(2), True, (0, 0, 0))textRect = survivedtext.get_rect()textRect.topright = [635, 5]screen.blit(survivedtext, textRect)# 6.5 - Draw health barscreen.blit(healthbar, (5, 5))for health1 in range(healthvalue):screen.blit(health, (health1 + 8, 8))# 7pygame.display.flip()# 8for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit(0)if event.type == pygame.KEYDOWN:if event.key == K_w:keys[0] = Trueelif event.key == K_a:keys[1] = Trueelif event.key == K_s:keys[2] = Trueelif event.key == K_d:keys[3] = Trueif event.type == pygame.KEYUP:if event.key == K_w:keys[0] = Falseelif event.key == K_a:keys[1] = Falseelif event.key == K_s:keys[2] = Falseelif event.key == K_d:keys[3] = Falseif event.type == pygame.MOUSEBUTTONDOWN:shoot.play()position = pygame.mouse.get_pos()acc[1] += 1arrows.append([math.atan2(position[1] - (playerpos1[1] + 32), position[0] - (playerpos1[0] + 26)), playerpos1[0] + 32, playerpos1[1] + 32])# 9if keys[0]:playerpos[1] -= 5elif keys[2]:playerpos[1] += 5if keys[1]:playerpos[0] -= 5elif keys[3]:playerpos[0] += 5# 10 - Win/Lose Checkif pygame.time.get_ticks() >= 90000:running = 0exitcode = 1if healthvalue <= 0:running = 0exitcode = 0if acc[1] != 0:accuracy = acc[0] * 1.0 / acc[1] * 100else:accuracy = 0# 11 - Win/Lose display
if exitcode == 0:pygame.font.init()font = pygame.font.Font(None, 24)text = font.render("Accuracy: " + str(accuracy) + "%", True, (255, 0, 0))textRect = text.get_rect()textRect.centerx = screen.get_rect().centerxtextRect.centery = screen.get_rect().centery + 24screen.blit(gameover, (0, 0))screen.blit(text, textRect)
else:pygame.font.init()font = pygame.font.Font(None, 24)text = font.render("Accuracy: " + str(accuracy) + "%", True, (0, 255, 0))textRect = text.get_rect()textRect.centerx = screen.get_rect().centerxtextRect.centery = screen.get_rect().centery + 24screen.blit(youwin, (0, 0))screen.blit(text, textRect)while 1:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit(0)pygame.display.flip()


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3中的混入(mixins)

本文主要介绍Vue3中的混入&#xff08;mixins&#xff09;。 目录 一、在普通写法中使用混入&#xff1a;二、在setup写法中使用混入&#xff1a; 混入是Vue中一种用于在组件中共享可复用功能的特性。在Vue 3中&#xff0c;混入的使用方式有所改变。 一、在普通写法中使用混入…

RTSP协议

From: http://www.cnblogs.com/Jimmly/archive/2009/07/27/1531999.html RTSP是由Real network 和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。 实时流协议&#xff08;RTSP&#xff09;建立并控制一个或几个时间同步的连续流媒体&#xff0c;如音频和…

CSS3 动画 思维导图

思维导图在新窗口打开浏览 转载于:https://www.cnblogs.com/weaming/p/5193044.html

python+PyQT+Eric安装配置

From: http://www.cnblogs.com/lhj588/archive/2011/10/03/2198472.html 一、大纲内容&#xff1a; 1、预备PC环境&#xff1a; 2、预备安装程序: 2、1、下载Python3.2 2、2、下载PyQt4 2、3、下载Eric5 3、安装配置步骤&#xff1a; 3、1、安装Pyhon3.2 3、2、安装PyQt4 3、3、…

ffmpeg解码流程 turorial5详解

From: http://www.360doc.com/content/11/1117/09/8050095_165108638.shtml FFMPEG解码流程 1. 注册所有容器格式和CODEC:av_register_all() 2. 打开文件:av_open_input_file() 3. 从文件中提取流信息:av_find_stream_info() 4. 穷举所有的流&#xff0c;查找其中种类为CODE…

Windows phone7 开发-Zune software is not launched 【转】

刚学习Windows Phone7开发&#xff0c;遇到这个配置错误&#xff0c;在此记录一下。 错误提示&#xff1a;Zune软件未安装 Zune software is not installed. Install the latest version of Zune software. 遇到这个问题&#xff0c;尝试根据提示&#xff0c;按图索骥&#xf…

让您变的更智慧 秘笈145条(上)

钱多钱少&#xff0c;常有就好&#xff01;人老人少&#xff0c;健康就好&#xff01;家贫家富&#xff0c;和睦就好。生活其实很简单&#xff0c;过了今天就是明天&#xff0c;重要的每个今天和明天都要智慧快乐得活着。 1. 精神失常的疯子不可怕&#xff0c;可怕的是精神正常…

Bootstrap(七):CSS--图片

1.基本样式 主要四个样式类&#xff1a; 设置布局 .img-responsive : 可以让图片支持响应式布局&#xff0c;从而让图片在其父元素中更好的缩放&#xff1b; 设置形状 .img-rounded &#xff1a; 设置图片为圆角&#xff1b; 设置形状 .img-circle &#xff1a; 设置图片为圆形…

【WiFi密码破解详细图文教程】ZOL仅此一份 详细介绍从CDlinux U盘启动到设置扫描破解

From: http://softbbs.zol.com.cn/1/32_7991.html 每天都能看到有不少网友在回复论坛之前发布的一篇破解WiFi密码的帖子&#xff0c;并伴随各种疑问。今天流云就为大家准备一篇实战型的文章吧&#xff0c;详细图文从思维CDlinux U盘启动到中文设置&#xff0c;如何进行路由SSID…

【EWSA无线路由密码破解工具 中文特别版下载】含教程及字典(弱口令生日特殊符号等)

From: http://softbbs.zol.com.cn/1/32_8011.html Elcomsoft Wireless Security Auditor简称EWSA,是一款极为强悍的路由密码破解工具&#xff0c;支持CPU、GPU调用破解&#xff0c;速度比但CPU破解厉害很多&#xff0c;加上此次分享的EWSA字典下载&#xff0c;可以帮助大家更好…

RESTful API 设计指南 (转)

RESTful API 设计指南 2016-02-23 ImportNew(点击上方公号&#xff0c;可快速关注) 作者&#xff1a;阮一峰 链接&#xff1a;http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序&#xff0c;分为前端和后端两个部分。当前的发展趋势&#xff0c;就是前端设…

模式——工程化实现及扩展(设计模式Java 版)

--模式——工程化实现及扩展&#xff08;设计模式Java 版&#xff09;王翔&#xff0c;孙逊著ISBN 978-7-121-15638-02012年4月出版定价&#xff1a;59.00元16开416页内 容 简 介设计模式不是一门适合空谈的技术&#xff0c;它来自于开发人员的工程实践又服务于工程实践。本书并…

由Qt中qApp想到的(这是单例模式么???)

From: http://blog.csdn.net/qq575787460/article/details/7880972 学Qt时&#xff0c;发现只要包含头文件QApplication或者QCoreapplication&#xff0c;就用使用qApp&#xff0c;指向一个当前实例。 查看源码发现qApp是个宏&#xff1a; QApplication中&#xff1a;#define q…

bootstrap基础学习十篇

bootstrap字体图标&#xff08;Glyphicons&#xff09; a.什么是字体图标 字体图标是在 Web 项目中使用的图标字体。虽然&#xff0c;Glyphicons Halflings 需要商业许可&#xff0c;但是您可以通过基于项目的 Bootstrap 来免费使用这些图标。 b.bootstrap自带字体图标文件结构…

Python 用hashlib求中文字符串的MD5值

From&#xff1a; http://blog.csdn.net/haungrui/article/details/6959340 使用过hashlib库的朋友想必都遇到过以下的错误吧&#xff1a;“Unicode-objects must be encoded before hashing”&#xff0c;意思是在进行md5哈希运算前&#xff0c;需要对数据进行编码。而且在不…

JS中的Replace方法

最近查一个bug&#xff0c;原因是JS中的Replace方法造成的&#xff0c;当将一个字符串中有处需要替换时&#xff0c;一般会用到JS中的Replace方法&#xff0c;Replace方法的第一个参数如果是传的字符串&#xff0c;只会替换第一处。代码如下&#xff1a; var str "0CEA65…

VMware 9 安装 Mac OS X 10.8 Mountain Lion 图文全程

From: http://unmi.cc/vmware9-install-mac-os-x-mountain-lion/#comment-8684 本教程是在 VMware 9 下安装当前最新版的 Mac OS X Mountain Lion 苹果系统。曾在 VirtualBox/VMware 下安装过 Mac OS Lion 系统&#xff0c;但安装后是无法升级到 Mountain Lion 的&#xff0c;所…

初识Vulkan

Vulkan是Khronos组织制定的“下一代”开放的图形显示API&#xff0c;是与DirectX12可以匹敌的GPU API标准。Vulkan是基于AMD的Mantle API演化而来&#xff0c;目前Vulkan 1.0标准已经完成并正式发布。上一代的OpenGL|ES并不会被遗弃&#xff0c;还会继续发展&#xff0c;很有可…

java_IO流之 NIO

NIO 定义 即新IO&#xff0c;在JDK1.4的java.nio.*包中引入&#xff0c;其目的在于提高速度。 在Java1.4之前的I/O系统中&#xff0c;提供的都是面向流的I/O系统&#xff0c;系统一次一个字节地处理数据&#xff0c;一个输入流产生一个字节的数据&#xff0c;一个输出流消费一个…

“我的电脑”右键“管理”打不开,提示“该文件没有与之关联的程序来执行该操作“

From: http://bbs.kafan.cn/thread-1240058-1-1.html 如图&#xff1a; 右键单击桌面上的“我的电脑”&#xff0c;再点“管理”就弹出这个对话框了。 【该文件没有与之关联的程序来执行该操作。请安装一个程序&#xff0c;或者&#xff0c;如果已安装程序&#xff0c;请在“…