时间:2023-01-02 09:21:44 | 栏目:Python代码 | 点击:次
本文实例为大家分享了python实现简单的飞机大战的具体代码,供大家参考,具体内容如下
这几天闲来没事干,就想起来好长时间没做过游戏了,于是就想做一个游戏练练手,为了起到一个练习的目的就使用了自己不是太熟练的python这门语言来编写,代码都有备注,大家可以直接看代码,这个代码我是在python3.1的环境下写的,大家需要可以直接下载我这里的资源,图片和代码打包到了一起的,因为是第一次使用python做游戏,有什么不足的地方望大佬斧正。
首先我们分析飞机大战这个游戏属于一个平面的2d游戏,那这个游戏的所有都是建立在x,y的基础上进行的运算,为了加快我们的开发工作,秉承时间就是金钱的原则,我们采用的是python 的 pygame第三方库来实现的。
言归正传!!!
仔细分析飞机大战我们不难发现,这个游戏的背景实际上就是一张图片一直循环滚动所造成的一种视觉上的效果,那布满我们一个场景并且让他无缝连接实际上我们只需要两张图片滚动,然后当第二张图片滚动完,再让他从第一张图片开始滚动如此循环便可以给用户视觉上一种无缝滚动的效果。
我们分析飞机的行为可以发现,不管是我方的飞机还是敌人的飞机都是有几种他们共有的动作。
1,运动,敌我双方都是在一直的运动。
2,发射子弹,双方都是在发射子弹,但具体的数量和速度我们可以通过类的属性来进行修改。
3,死亡,敌人和我们自身都会死亡,死亡会触发一个爆炸的动画,敌人死亡加分,我方死亡游戏结束。
为了节省时间此处的子弹都只会走直线,封装到自己的类方法里面,后期可以修改轨迹。
话不多说,直接上代码,每个重要的代码都是有注释。大家可以自己观看。
main.py
# -*- coding: UTF-8 -*- # animation.py # 导入需要的模块 import pygame, sys from pygame.locals import * import airplane import random class Game: def __init__(self): # 初始化pygame pygame.init() #初始化字体文件 pygame.font.init() #初始化游戏分数 self.mark=0 # 设置帧率(屏幕每秒刷新的次数) self.FPS = 60 # 获得pygame的时钟 self.fpsClock = pygame.time.Clock() # 设置窗口大小 self.screen = pygame.display.set_mode((500, 800), 0, 32) # 设置标题 pygame.display.set_caption('飞机大战') # 定义颜色 self.WHITE = (255, 255, 255) #用于存放爆炸图片 self.boom=[pygame.image.load("boom_1.gif") ,pygame.image.load("boom_2.gif") ,pygame.image.load("boom_3.gif") ,pygame.image.load("boom_4.gif") ,pygame.image.load("boom_5.gif") ,pygame.image.load("boom_6.gif") , pygame.image.load("boom_7.gif") , pygame.image.load("boom_8.gif") , pygame.image.load("boom_9.gif")] # 加载一张背景图片 self.img = pygame.image.load('bg.jpg') #加载开始游戏按钮 self.startGameImage=pygame.image.load('start.png') # 初始化背景图片的位置 self.imgx = 0 self.imgy = 0 # 全局的时间变量 self.time = 0; #敌人子弹的图片数据 self.allEnemyButtlueImg=[pygame.image.load('buttle3.png')] # 存放所有敌人图片数据的一个列表 self.allEnemyImg = [pygame.image.load('em1.png'), pygame.image.load('em2.png')] # 存放所有敌人变量的一个列表 self.allEnemy = []; #是否开始了游戏 开始游戏状态为0 死亡状态为1 为开始为2 self.isStart=2 #最后一个爆炸动画 self.lastTime=0 #开始执行动画 self.run() def initGame(self): # 创建一个自己角色 self.myself = airplane.airplane(self.screen, 30, pygame.image.load('airplane.png'), 250, 800, pygame.image.load('buttle.png'), 0, 120, 79, self.boom) self.isStart=0 def run(self): # 程序主循环 while True: # 每次都要重新绘制背景白色 self.screen.fill(self.WHITE) # 背景的循环滚动 self.imgy += 2 if self.imgy == 854: self.imgy = 0 # 背景的绘制,绘制两张图片实现循环滚动的效果 self.screen.blit(self.img, (self.imgx, self.imgy)) self.screen.blit(self.img, (self.imgx, self.imgy - 854)) #如果游戏isstart为flase则游戏不会继续刷新 if self.isStart==0: self.startGame(); elif self.isStart == 1: self.clearAll(); else: self.showstartGame() for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type==MOUSEBUTTONDOWN: x, y = pygame.mouse.get_pos() if(x>170 and x<170+161and y>300 and y<300+43): self.isStart=0 self.initGame(); # 刷新屏幕 pygame.display.update() # 设置pygame时钟的间隔时间 self.fpsClock.tick(self.FPS) def showMark(self): a = pygame.font.SysFont('幼圆', 50) text = a.render(str(self.mark),True,(255,0,0)) b=len(str(self.mark)) self.screen.blit(text, [500-b*30,10]) def showstartGame(self): self.screen.blit(self.startGameImage,(170,300)) def addMark(self,m): self.mark+=m; def clearMark(self): self.mark=0; def startGame(self): # 获取鼠标位置点 x, y = pygame.mouse.get_pos() # 飞机的运行函数 self.myself.run(x, y); # 所有子弹每一帧的位置 for item in self.myself.allbullet: if item.y <= 0: # 当子弹行驶出地图边界之后移除列表中的当前元素并且销毁对象 self.myself.allbullet.remove(item) del item else: # 如果没有行驶出边界范围则继续行驶 item.advance() for enemy in self.allEnemy: try: # 判断我方子弹是否与敌人相撞,并且相撞的时候敌人还活着 if ( item.x > enemy.x and item.x < enemy.x + enemy.width and item.y >= enemy.y and item.y < enemy.y + enemy.height and enemy.isDeath == 0): self.myself.allbullet.remove(item) del item enemy.death() self.addMark(enemy.myselfMark) except: continue; self.showMark() # 发射子弹的函数具体的射速由对象内部决定 self.myself.attack(); # 外部计算时间的一个变量没time % FPS == 0 时为1秒钟 self.time += 1 if self.time==self.lastTime: self.isStart=1 # 飞机随机生成时间 if self.time % (self.FPS * 2) == 0: # 每过一秒钟新生成一架飞机,添加到allEnemy这个列表之中,y从0开始 x在窗口大小随机生成 self.allEnemy.append( airplane.airplane(self.screen, 15, self.allEnemyImg[random.randint(0, 1)], random.randint(0, 500 - 179), -134, self.allEnemyButtlueImg[0], 1, 179, 134, self.boom)) # 循环执行该列表,敌人飞机的运动轨迹 for item in self.allEnemy: # 飞机超出下边界后去除 if item.y > 800 + item.height: self.allEnemy.remove(item) del item # 飞机死亡并且存在子弹数为0后去除 elif item.isDeath == 1 and len(item.allbullet) == 0: self.allEnemy.remove(item) del item # 否则飞机继续运行 else: item.ai() item.attack() for i in item.allbullet: if i.y <= -96 or i.y >= 896: # 当子弹行驶出地图边界之后移除列表中的当前元素并且销毁对象 item.allbullet.remove(i) del i else: # 如果没有行驶出边界范围则继续行驶 if ( i.x > self.myself.x and i.x < self.myself.x + self.myself.width and i.y >= self.myself.y and i.y < self.myself.y + self.myself.height and self.myself.isDeath == 0): self.myself.death() self.lastTime=self.time+50; i.advance() def clearAll(self): self.mark=0 for i in self.allEnemy: for j in i.allbullet: del j; del i; for j in self.myself.allbullet: del j del self.myself # 存放所有敌人变量的一个列表 self.allEnemy = []; # 是否开始了游戏 self.isStart = 2 self.lastTime=0 game=Game()
airplane.py
#飞机子弹的图片路径 self.bullet=bullet; #飞机的类型,0代表自己,1代表敌人 self.type=type; #飞机的宽度 self.width=w; #飞机的高度 self.height=h; #存放子弹的数组 self.allbullet=[]; #用于判断子弹多长时间发射一次和fps相关 self.time=0; #当前这个飞机的速度 self.speedx=1; self.speedy=1; # 攻击速度,值越小攻击越快最小为1 self.advancespeed = advancespeed; #每个飞机自己携带的分数,目前随机 self.myselfMark=random.randint(1,3) #运动轨迹 self.runType=random.randint(0, 3) #是否死亡 1表示死亡 0表示活着 self.isDeath=0 #爆炸图片播放那一张 self.showboomTime=0 #爆炸数据 self.boom=boom #开始攻击 self.attack(); def death(self): #死亡状态 self.isDeath=1; def showboom(self): #显示boom的动画 if self.showboomTime==len(self.boom)-1: return ; if self.time%5==0: self.showboomTime+=1; self.screen.blit(self.boom[self.showboomTime], (self.x, self.y)) def run(self,x,y): if self.isDeath==1: self.showboom(); return 1; self.x = x - self.width / 2; self.y = y - self.height / 2; self.screen.blit(self.img, (self.x, self.y)) def attack(self): #飞机发射子弹的函数 if self.time%self.advancespeed==0 and self.isDeath==0: self.allbullet.append(bullet(self.screen,self.bullet,self.x-self.width/2,self.y,self.width,self.height,128,128,self.type)) self.time+=1 def ai(self): if self.isDeath==1: self.showboom(); return #这里分为四种的运动轨迹随机决定 if self.type==1: if self.runType==0: self.y+=self.speedy*2; elif self.runType==1: self.y+=self.speedy; if self.x<=0-self.width/2 or self.x>=500-self.width/2: self.speedx=0-self.speedx self.x+=self.speedx elif self.runType==2: self.y += self.speedy; if self.x<=0-self.width/2 or self.x>=500-self.width/2: self.speedx = 0 - self.speedx self.x -= self.speedx elif self.runType==3: self.y += self.speedy; if self.x<=0-self.width/2 or self.x>=500-self.width/2: self.speedx = 0 - self.speedx self.speedy=0-self.speedy self.x -= self.speedx self.screen.blit(self.img, (self.x, self.y)) self.attack() def __del__(self): return class bullet: def __init__(self,screen,img,x,y,airplanex,airplaney,w,h,type): #游戏场景传参 self.screen=screen; #子弹的图片的路径 self.img=img; if type==0: # 子弹的y坐标 self.y=y-airplaney; # 子弹的x坐标 self.x = x + airplanex / 2; else: self.y=y+airplaney-20; self.x = x+airplanex/2+w/2-12; #子弹图片的宽度 self.width=w #子弹图片的高度 self.height=h #子弹需要一直往前飞 self.run() #子子弹是谁的 self.type = type if self.type==0: self.speed=5 else: self.speed=3 def advance(self): if self.type==0: self.y-=self.speed; else: self.y+=self.speed; self.run(); def run(self): self.screen.blit(self.img, (self.x, self.y)) def __del__(self): return
给大家看看游戏运行的效果
一个简单的开始按钮,死亡后又返回这个界面
上方有一个简洁明了的计分板,游戏结束归零
敌人有四种运动,随机产生!!!