欢迎,来自IP地址为:18.97.14.80 的朋友
前面教程第一部分已经成了小兔子的正确移动和转向,现在需要给它添加更多的动作以进行游戏的进一步开发。
让小兔子可以射箭
你的小兔子可以正确移动后,现在就可为它增加一些新动作了。给它增加一个射箭的动作如何呢?这个步骤实现起来有一点点复杂,因为你要跟踪每一枝射出去的箭,随时更新、旋转箭的状,并在箭离开游戏屏幕后删除它。
在程序的#2部分初始化参数程序中增加如下必要的变量。
acc=[0,0] arrows=[]
第一个变更跟踪玩家的精准度,第二个变量跟踪所有的箭。精准度变量本质上是射击次数和命中次数的列表,稍后,我们根据这些信息来计算命中率。
在#3程序段加入如下代码以加载箭的图像:
arrow = pygame.image.load (“resources/images/bullet.png”)
当用户单击鼠标时,会触发pygame的MOUSEBUTTONDOWN事件。在#8中增加如下代码以进行事件处理。
position=pygame.mouse.get_pos() acc[1]+=1 arrows.append([math.atan2(position[1]-(playerpos1[1]+32),position[0]-(playerpos1[0]+26)),playerpos1[0]+32,playerpos1[1]+32])
这段代码检测是否有鼠标点击事件,如果点击了,会首先取得鼠标所在的位置,并在命中列表中的射出箭的数值增加1。最后根据鼠标位置来计算箭图片需要的旋转角度值,并将此值增加到前面定义的箭列表中。
将如下代码添加到#6.1后面,用于在屏幕上可以正确显示箭。
# 6.2 - Draw arrows for bullet in arrows: index=0 velx=math.cos(bullet[0])*10 vely=math.sin(bullet[0])*10 bullet[1]+=velx bullet[2]+=vely if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480: arrows.pop(index) index+=1 for projectile in arrows: arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29) screen.blit(arrow1, (projectile[1], projectile[2]))
其中vely和velx值是通过基本的三角函数计算得来,数值10是箭的行进速度。”if”语句是检测”子弹”是否出界,如果有,则删除这支箭。之后的”for”循环是正确的绘制出这些箭并进行正确的旋转。
现在运行程序,点击鼠标,你就可以得到一个会射箭的兔子了,正如图4所示:
图4
拿起武器,对付鼹鼠
当你有城堡和可以移动和射击的英雄,那么,少了什么呢?当然是兔子英雄可以射击的进攻城堡的敌人们。
在这个步骤中,你将随机生成冲向城堡的鼹鼠。随着游戏的进行,将会有更多的鼹鼠产生。现在让我们来看看需要做些什么,首先是将这些敌人加入到一个列表中,更新敌人信息,并将敌人都显示在屏幕上。在#2程序段加入如下内容:
badtimer=100 badtimer1=0 badguys=[[640,100]] healthvalue=194
这里将设置一个计时器(当然你也可以设置为其它值),以保证在鼹鼠消逝一段时间后可以产生新的鼹鼠来充当敌人。当每个badtimer值减到0时会释放一个新的鼹鼠。
在#3程序段最后增加如下代码:
badguyimg1 = pygame.image.load("resources/images/badguy.png") badguyimg=badguyimg1
程序第一行和之前加载图片的代码类似,而第二行是建立一个图片对象的复本,以便给这些鼹鼠敌人添加动画时更加容易。
现在更新代码,以便可以显示敌人。在#6.2程序段后添加如下代码:
# 6.3 – Draw moles if badtimer==0: badguys.append([640, random.randint(50,430)]) badtimer=100-(badtimer1*2) if badtimer1>=35: badtimer1=35 else: badtimer1+=5 index=0 for badguy in badguys: if badguy[0]<-64: badguys.pop(index) badguy[0]-=7 index+=1 for badguy in badguys: screen.blit(badguyimg, badguy)
程序第一行首先检测badtimer值是否为”0″,如果为”0″,则创建一个新的鼹鼠,并根据badtimer运行的次数重新设置badtimer值。第一个”for”循环会更新鼹鼠的x轴位置,并检测鼹鼠否离开屏幕,如果是话就删除它们。
第二个”for”循环将绘制所有的鼹鼠。为了在上面的代码中使用random函数,需要在#1程序段使用如下代码将其引入:
import random
在#4程序段的while语句后添加以下代码来让badtime值在每帧后发生变化:
badtimer-=1
运行程序,现在你会看到自己的程序比较像一个真正的游戏了,你可以让兔子移动、转动和射击,而鼹鼠则试图向它跑去。效果如图5所示:
图5
但是等一下,为什么鼹鼠不能攻击城堡呢。在#6.3程序段index+=1语句前添加以下代码
# 6.3.1 - Attack castle badrect=pygame.Rect(badguyimg.get_rect()) badrect.top=badguy[1] badrect.left=badguy[0] if badrect.left<64: healthvalue -= random.randint(5,20) badguys.pop(index)
如果鼹鼠图片的x数值小于64,说明它已经攻击到城堡了,那么就需要把它删除,并随机扣除5-20之间的血量。
你现在运行程序,会发现一群鼹鼠正在攻击城堡,虽然看不到血量下降,但实际是它们正在扣减你的血量。
射箭杀死鼹鼠
一大群鼹鼠正在攻击你的城堡,现在是时候设置可以射箭来杀死鼹鼠了,这样你就可以保护你的城堡并取得游戏的胜利。
基本上,遍历所有敌人,在每个敌人里再遍历每枝箭,看是否有相撞的,如果有,则删除这枝箭和这个鼹鼠,并增加一个命中的数值在#6.3.1程序段有增加如下代码:
#6.3.2 - Check for collisions index1=0 for bullet in arrows: bullrect=pygame.Rect(arrow.get_rect()) bullrect.left=bullet[1] bullrect.top=bullet[2] if badrect.colliderect(bullrect): acc[0]+=1 badguys.pop(index) arrows.pop(index1)
运行一下程序,你的兔子就可以射箭杀敌了。
给游戏添加血条和计时器
现在你要做的就是给游戏添加一个计分方法,并展示小兔子做的怎么样。实现这个功能最简单的办法就是给游戏添加一下警示显示(Heads-Up Display-HUD),也就是这些城堡健康程度的血条。你同样可以添加一个时钟,用来显示城堡坚持的时间。
在#7程序段之前添加如下代码,用于添加时钟:
# 6.4 - Draw clock font = 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)
下面的代码是用来显示血条的,但在绘制之前,需要在#3程序段将血条的图片加载:
healthbar = pygame.image.load("resources/images/healthbar.png") health = pygame.image.load("resources/images/health.png")
第一个红色的图片用于全部血量也就是生命值,第二个绿色图片用于显示当前血量。将下面的代码添加到#6.4程序段之后,用于显示血条:
# 6.5 - Draw health bar screen.blit(healthbar, (5,5)) for health1 in range(healthvalue): screen.blit(health, (health1+8,8))
第一行代码用于绘制一个全红的生命条,然后,现根据生命值绘制也相应的血量条。如果你现在运行程序,会发现游戏有了计时器和血量条。注意这里的血量图片只有1像素宽,正好配合生命值来显示。
胜利或失败
接下来要做的就是设定一个胜利或失败的场景,让你的游戏更具可玩性。通过相应判断条件来退出主循环,进入显示胜利或失败的循环中,最终显示玩家胜利或失败,并在屏幕加以显示。
在程序代码末尾加入如下代码:
#10 - Win/Lose check if pygame.time.get_ticks()>=90000: running=0 exitcode=1 if healthvalue<=0: running=0 exitcode=0 if acc[1]!=0: accuracy=acc[0]*1.0/acc[1]*100 else: 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().centerx textRect.centery = screen.get_rect().centery+24 screen.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().centerx textRect.centery = screen.get_rect().centery+24 screen.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()
程序第一行”if”语句判断是否到时,第二个判断检测城堡是否被毁坏,第三个判断语句用于计算命中率。#11程序段是根据相应结果显示正确的画面。
注意
此处使用acc[0]*1.0是为了将acc[0]的值转换为浮点型数据,如是不这样写的话,那么除法的结果会返回一个整形数据。
如果你想显示胜利或失败的图片,那就需要在#3程序段将图片加载进来:
gameover = pygame.image.load("resources/images/gameover.png") youwin = pygame.image.load("resources/images/youwin.png")
将程序段#4修改为如下代码,以保证循环正常:
# 4 – keep looping through running = 1 exitcode = 0 while running:
其中running变量用于检测游戏是否结束、exitcode变量用于记录玩家是胜利还是失败。
加入音效
pygame让添加音效变得十分简单,首先,需要在#2程序段初始化音效模块mixer:
pygame.mixer.init()
然后在#3程序段将声音文件加到不同对象上:
# 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)
以上的大部分代码均是加载声音文件和设置声音大小的,但需要注意的是pygame.mixer.music.load行,这个句是用于给游戏设置背景音乐,而下一行则将其设置为循环播放。
注意音效文件的配置,现在要做的就是根据需要播放各种音效。按照代码注释说明给相应动作添加音效,示例如下:
# section 6.3.1 after if badrect. left<64: hit.play() # section 6.3.2 after if badrect. colliderect(bullrect): enemy.play() # section 8, after if event. type==pygame.MOUSEBUTTONDOWN: shoot.play()
要知道,给游戏添加背景音乐和给攻击添加音效后,会让游戏变得更加生动。
还可以做的内容
现在,你刚刚完成了一个简单好玩的游戏,这个游戏有背景音乐、有攻击音效、一只杀敌的小兔子以及不断产生的鼹鼠敢死队。当然,你还可以做的更多,你可以随意修改这款游戏,例如将图片换成自己的作品、增加新的武器以及加入更多的怪物等。
测试游戏
游戏运行前,请确认pygame已经正确安装,双击game.py文件,游戏就会启动,看看各项功能是否正常吧。
One thought on “手把手Python和pygame游戏开发教程(二)”