上篇写的动画示例其实算不上一个游戏,顶多算是利用pygame进行的图形操作,今天着手实现一个小游戏:传说哥大战剧毒术士。名字很玄乎,其实就是最简单的一个射击游戏。好了废话不多说,先上截图吧:
一、初始化程序和定义变量
importpygameimportmathimportrandom#1 - Initialize the gamepygame.init()#PRepare the variableswidth, height = 640, 480screen=pygame.display.set_mode((width, height))
playerpos=[100,100]
speed_x=5speed_y=5speed_bullet=10speed_shit=3shot=0
alive=True
bullet=[]
shit=[]green=[0,255,0]#2 - Load imagesplayer = pygame.image.load("1.bmp")
badguy= pygame.image.load("2.bmp")
backgroud= pygame.image.load("3.bmp")
bullet_bmp=pygame.image.load("4.bmp")
shit_bmp=pygame.image.load("5.bmp")
player.set_colorkey([0,0,0])
badguy.set_colorkey([0,0,0])
shit_bmp.set_colorkey([255,255,255])
第一部分声明的变量中主要是传说哥的移动速度,子弹的数据,剧毒术士喷出的便便速度等。第二部分预载入图片资源:角色,背景图等。注意设置set_colorkey进行透明色处理(书上有介绍)。
二、响应事件处理相关
1#4 - clear the screen before drawing it again2screen.fill(0)3#5 - draw the backgroud4forxinrange(width/backgroud.get_width()+1):5foryinrange(height/backgroud.get_height()+1):6screen.blit(backgroud,(x*90,y*65))7#6 - loop through the events8foreventinpygame.event.get():9#check if the event is the X button10ifevent.type==pygame.QUIT:11#if it is quit the game12pygame.quit()13exit(0)14ifevent.type==pygame.KEYDOWN:15ifevent.key ==pygame.K_w:16playerpos[1]-=speed_y17elifevent.key ==pygame.K_s:18playerpos[1]+=speed_y19elifevent.key ==pygame.K_a:20playerpos[0]-=speed_x21elifevent.key ==pygame.K_d:22playerpos[0]+=speed_x23position =pygame.mouse.get_pos()24angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+32))25playerrot = pygame.transform.rotate(player, 360-angle*57.29)26playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)27ifevent.type==pygame.MOUSEBUTTONDOWN:28position=pygame.mouse.get_pos()29bullet.append([math.atan2(position[1]-(playerpos1[1]+32),30position[0]-(playerpos1[0]+32)),playerpos1[0]+32,playerpos1[1]+32])
这一部分首先将加载进的背景图片利用blit函数贴到窗口里。随后进入事件循环:这里主要是两种事件:WSAD控制人物运动,鼠标点击射出子弹,由于是用鼠标控制射击方向,因此需要获取图片的新位置,简单的数学知识,偏转角计算如下图,这块的处理具体参照一篇不错的文章http://bbs.chinaunix.net/thread-4094150-1-2.html,这个小东东借鉴了里面很多知识。
三、处理对战逻辑
1#7 - process fight2screen.blit(playerrot, playerpos1)3foroneshotinbullet:4index=05velx=math.cos(oneshot[0])*speed_bullet6vely=math.sin(oneshot[0])*speed_bullet7oneshot[1]+=velx8oneshot[2]+=vely9ifoneshot[1]<-64oroneshot[1]>640oroneshot[2]<-64oroneshot[2]>480:10bullet.pop(index)11index+=112foreachoneinbullet:13pos_x=int(eachone[1])14pos_y=int(eachone[2])15pos=[pos_x,pos_y]16bullet_bmp_new=pygame.transform.rotate(bullet_bmp,360-eachone[0]*57.29)17screen.blit(bullet_bmp_new,pos)18pygame.display.flip()19foroneshotinbullet:20ifoneshot[1]<badguy_pos[0]+57andoneshot[1]>badguy_pos[0]and\21oneshot[2]<badguy_pos[1]+70andoneshot[2]>badguy_pos[1]:22shot+=123alive=False24
break25ifshot<5andalive==False:26badguy_x=random.randrange(0,640-57)27badguy_y=random.randrange(0,480-70)28badguy_pos=[badguy_x,badguy_y]29alive=True30ifalive ==True:31screen.blit(badguy, badguy_pos)32else:33pygame.quit()34exit(0)35iflen(shit)<2:36shit.append([math.atan2(playerpos1[1]-(badguy_pos[1]+32),37playerpos1[0]-(badguy_pos[0]+32)),badguy_pos[0]+32,badguy_pos[1]+32])38foroneshitinshit:39index=040velx=math.cos(oneshit[0])*speed_shit41vely=math.sin(oneshit[0])*speed_shit42oneshit[1]+=velx43oneshit[2]+=vely44ifoneshit[1]<-64oroneshit[1]>640oroneshit[2]<-64oroneshit[2]>480:45shit.pop(index)46index+=147foreachshitinshit:48pos_x=int(eachshit[1])49pos_y=int(eachshit[2])50pos=[pos_x,pos_y]51shit_bmp_new=pygame.transform.rotate(shit_bmp,360-eachshit[0]*57.29)52screen.blit(shit_bmp_new,pos)53pygame.display.flip()54foroneshitinshit:55ifoneshit[1]<playerpos1[0]+66andoneshit[1]>playerpos1[0]and\56oneshit[2]<playerpos1[1]+66andoneshit[2]>playerpos1[1]:57pygame.quit()58exit(0)59pygame.display.flip()
每次点击一次鼠标,子弹发射,保存到列表中,但是当子弹离开屏幕需要删除掉改子弹,同时记得由第二部分保存的偏转角计算子弹的偏转。剧毒喷出的大便处理类似,也要由传说哥的位置计算出偏转角利用设定的速度甩向我们的主人公火枪哥。
这里的输赢判定为火枪打死5个剧毒即获取胜利,扔出的便便有一次砸到我们的主人公,游戏失败即结束,不管胜利还是失败,游戏均退出处理。
以上便是整个游戏的大体逻辑,可以看出利用python 100行左右的代码即可以实现一个最简单的人机对战,不过代码写的比较乱得说,也没有用函数编程和面向对象的东西。另外提一下写游戏这块效率性能确实不敢恭维(明显的迟钝)。。不管怎么样,利用pygame实现小游戏还是比较方便的。
这个小游戏写的确实虽然简单和幼稚,不过花了半天时间就能从零搞起来,确实有所收获。有时间的话可以进一步增加敌方的难度和可玩性,先这样吧。
附下代码吧:
1importpygame2importmath3importrandom45#1 - Initialize the game6pygame.init()7#prepare the variables8width, height = 640, 4809screen=pygame.display.set_mode((width, height))10playerpos=[100,100]11speed_x=512speed_y=513speed_bullet=1014speed_shit=315shot=016alive=True17bullet=[]18shit=[]19badguy_x=random.randrange(0,640)20badguy_y=random.randrange(0,480)21badguy_pos=[badguy_x,badguy_y]22green=[0,255,0]23#2 - Load images24player = pygame.image.load("1.bmp")25badguy = pygame.image.load("2.bmp")26backgroud= pygame.image.load("3.bmp")27bullet_bmp=pygame.image.load("4.bmp")28shit_bmp=pygame.image.load("5.bmp")29player.set_colorkey([0,0,0])30badguy.set_colorkey([0,0,0])31shit_bmp.set_colorkey([255,255,255])32#3 - main loop33while1:34#4 - clear the screen before drawing it again35screen.fill(0)36#5 - draw the backgroud37forxinrange(width/backgroud.get_width()+1):38foryinrange(height/backgroud.get_height()+1):39screen.blit(backgroud,(x*90,y*65))404142#6 - loop through the events43foreventinpygame.event.get():44#check if the event is the X button45ifevent.type==pygame.QUIT:46#if it is quit the game47pygame.quit()48exit(0)49ifevent.type==pygame.KEYDOWN:50ifevent.key ==pygame.K_w:51playerpos[1]-=speed_y52elifevent.key ==pygame.K_s:53playerpos[1]+=speed_y54elifevent.key ==pygame.K_a:55playerpos[0]-=speed_x56elifevent.key ==pygame.K_d:57playerpos[0]+=speed_x58position =pygame.mouse.get_pos()59angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+32))60playerrot = pygame.transform.rotate(player, 360-angle*57.29)61playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)62ifevent.type==pygame.MOUSEBUTTONDOWN:63position=pygame.mouse.get_pos()64bullet.append([math.atan2(position[1]-(playerpos1[1]+32),65position[0]-(playerpos1[0]+32)),playerpos1[0]+32,playerpos1[1]+32])66#7 - process fight67screen.blit(playerrot, playerpos1)68foroneshotinbullet:69index=070velx=math.cos(oneshot[0])*speed_bullet71vely=math.sin(oneshot[0])*speed_bullet72oneshot[1]+=velx73oneshot[2]+=vely74ifoneshot[1]<-64oroneshot[1]>640oroneshot[2]<-64oroneshot[2]>480:75bullet.pop(index)76index+=177foreachoneinbullet:78pos_x=int(eachone[1])79pos_y=int(eachone[2])80pos=[pos_x,pos_y]81bullet_bmp_new=pygame.transform.rotate(bullet_bmp,360-eachone[0]*57.29)82screen.blit(bullet_bmp_new,pos)83pygame.display.flip()84foroneshotinbullet:85ifoneshot[1]<badguy_pos[0]+57andoneshot[1]>badguy_pos[0]and\86oneshot[2]<badguy_pos[1]+70andoneshot[2]>badguy_pos[1]:87shot+=188alive=False89
break90ifshot<5andalive==False:91badguy_x=random.randrange(0,640-57)92badguy_y=random.randrange(0,480-70)93badguy_pos=[badguy_x,badguy_y]94alive=True95ifalive ==True:96screen.blit(badguy, badguy_pos)97else:98pygame.quit()99exit(0)100iflen(shit)<2:101shit.append([math.atan2(playerpos1[1]-(badguy_pos[1]+32),102playerpos1[0]-(badguy_pos[0]+32)),badguy_pos[0]+32,badguy_pos[1]+32])103foroneshitinshit:104index=0105velx=math.cos(oneshit[0])*speed_shit106vely=math.sin(oneshit[0])*speed_shit107oneshit[1]+=velx108oneshit[2]+=vely109ifoneshit[1]<-64oroneshit[1]>640oroneshit[2]<-64oroneshit[2]>480:110shit.pop(index)111index+=1112foreachshitinshit:113pos_x=int(eachshit[1])114pos_y=int(eachshit[2])115pos=[pos_x,pos_y]116shit_bmp_new=pygame.transform.rotate(shit_bmp,360-eachshit[0]*57.29)117screen.blit(shit_bmp_new,pos)118pygame.display.flip()119foroneshitinshit:120ifoneshit[1]<playerpos1[0]+66andoneshit[1]>playerpos1[0]and\121oneshit[2]<playerpos1[1]+66andoneshit[2]>playerpos1[1]:122pygame.quit()123exit(0)124pygame.display.flip()
View Code