Pygame游戏引擎的安装
- doc窗口直接使用pip安装
win +r —>cmd—>输入:pip install pygame(unintall是卸载)


- 下载whl文件进行安装
进入官网,点击PyPI
- 输入
pygame

- 选择
pygame

- 选择Download files

- 选择自己对应的版本



- 下载后进行安装

进入下载的文件目录,输入命令安装
#导入pygame模块import pygame,time,randomimport pygame.sprite#设置常量方便修改SCREEN_WIDTH=700 #定义窗口的宽度SCREEN_HEIGHT=500#定义窗口的高度#背景填充色Bg_color=pygame.Color(0,0,0)#右上角字体颜色TEXT_color=pygame.Color(255,255,255)#定义一个基类,继承精灵类,精灵类可实现碰撞复杂的算法class BaseItem(pygame.sprite.Sprite):def __init__(self,color,width,height):pygame.sprite.Sprite.__init__(self)#主游戏类class MainGame():window = None # 类对象my_tank =None #定义坦克类变量#存储敌方坦克列表enemyTankList = []#定义敌方坦克数量enemyTankCount=5#存储我方子弹的列表myBulletList =[]#存储敌方子弹的列表enemyBulletList = []#存储爆炸效果的列表explodeList = []#存储墙壁的列表wallList =[]def __init__(self):pass#开始游戏def startGame(self):#加载主窗口#初始化窗口pygame.display.init()#设置窗口的大小及显示MainGame.window = pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])#初始化我方坦克,设置初始的位置(距离左上角默认)#MainGame.my_tank=Tank(350,250)self.createMytank()#初始化敌方坦克,并将敌方坦克添加到列表中self.createEnemyTank()#初始化墙壁self.createWall()#设置窗口标题pygame.display.set_caption("坦克大战")# 使窗口一直显示的内容while True:#给窗口设置填充色MainGame.window.fill(Bg_color)#调用获取事件(包括按键坦克移动)方法self.getEvent()#右上角文字调用到主窗口window中MainGame.window.blit(self.getTextSurface("敌方坦克剩余数量%d"%len(MainGame.enemyTankList)),(10,10))#调用坦克显示#添加我方坦克是否存活if MainGame.my_tank and MainGame.my_tank.live:MainGame.my_tank.dispalyTank()else:#删除我方坦克del MainGame.my_tankMainGame.my_tank =None#循环遍历敌方坦克的列表,展示敌方坦克self.blitEnemyTank()#循环遍历我方坦克子弹self.blitMyBullet()#循环遍历敌方子弹列表,展示敌方子弹self.blitEnemyBullet()#循环遍历爆炸列表,展示爆炸效果self.blitExplode()#循环遍历墙壁的显示,展示墙壁self.blitWall()#使坦克移动的慢一点(添加睡眠)time.sleep(0.02)#如果坦克的开关开启时,才可移动(限制一直移动)if MainGame.my_tank and MainGame.my_tank.live:if not MainGame.my_tank.stop:#调用移动move(在while中可以一直移动,实现按键按下去不松走动)MainGame.my_tank.move()#检测我方坦克是否与墙壁反生碰撞MainGame.my_tank.hitWall()#检测我方坦克是否与敌方坦克发生碰撞MainGame.my_tank.myTank_hit_enemyTank()# 更新部分软件界面显示,只能放在后面pygame.display.update()#无限重生,定义我方坦克出生的方法def createMytank(self):MainGame.my_tank =MyTank(SCREEN_WIDTH-(SCREEN_WIDTH/2),310)#创建Musci对象misic = Music("img/sound.wav")#播放音乐misic.play()#循环遍历墙壁的显示,展示墙壁def blitWall(self):for wall in MainGame.wallList:#判断墙壁是否存活if wall.live:# 调用墙壁的显示方法wall.dispalyWall()else:#从墙壁列表移除MainGame.wallList.remove(wall)#初始化墙壁def createWall(self):for i in range(6):wall=Wall(i*130,(SCREEN_HEIGHT/2))#将墙壁添加到列表中MainGame.wallList.append(wall)#初始化敌方坦克,并将敌方坦克添加到列表中def createEnemyTank(self):top=SCREEN_HEIGHT-400#循序生成敌方坦克for i in range(MainGame.enemyTankCount):left = random.randint(0,SCREEN_WIDTH-100)speed = random.randint(1,4)enemy=EnemyTank(left,top,speed)MainGame.enemyTankList.append(enemy)#循环并展示爆炸效果def blitExplode(self):for explode in MainGame.explodeList:#判断是否活着if explode.live:#展示explode.displayExplode()else:#在爆炸列表中移除MainGame.explodeList.remove(explode)#循环遍历敌方坦克的列表,展示敌方坦克def blitEnemyTank(self):for enemyTank in MainGame.enemyTankList:# 添加判断敌方坦克是否活着,没有if敌方坦克就一直活着,不能实现爆炸效果if enemyTank.live:enemyTank.dispalyTank()# enemyTank.move()enemyTank.randMove()#调用检测是否与墙壁碰撞enemyTank.hitWall()#检测敌方坦克是否与我方坦克反生碰撞if MainGame.my_tank and MainGame.my_tank.live:enemyTank.enemyTank_hit_myTank()#敌方子弹发射子弹enmyBullet = enemyTank.shot()##判断敌方子弹是否为None,如果不为None,则添加到敌方子弹列表中if enmyBullet:#将敌方子弹存储到敌方子弹列表中MainGame.enemyBulletList.append(enmyBullet)# 不活着,从敌方坦克列表移除else:MainGame.enemyTankList.remove(enemyTank)#循环遍历我方子弹存储列表def blitMyBullet(self):for myBullet in MainGame.myBulletList:#判断当前子弹是否是活着的状态,如果是则进行显示,否则在列表中删除if myBullet.live:myBullet.displayBullet()#调用子弹移动方法myBullet.move()#调用检测我方子弹是否与敌方坦克发生碰撞myBullet.myBullet_hit_enemyTank()#检测我方子弹是否与墙壁碰撞myBullet.hitWall()#否则在列表中删除else:MainGame.myBulletList.remove(myBullet)# 循环遍历敌方子弹列表,展示敌方子弹def blitEnemyBullet(self):for enemyBullet in MainGame.enemyBulletList:if enemyBullet.live:#判断敌方子弹是否存活enemyBullet.displayBullet()enemyBullet.move()#调用敌方子弹与我方坦克的碰撞的方法enemyBullet.enemyBullet_hit_myTank()#检测敌方子弹是否与墙壁碰撞enemyBullet.hitWall()else:MainGame.enemyBulletList.remove(enemyBullet)#结束游戏def endGame(self):print("谢谢使用")exit()#设置左上角文字显示的方法def getTextSurface(self,text):#text为设置坦克数量# 设置字体#初始化pygame.font.init()#获取字体Font对象font = pygame.font.SysFont('youyuan',18)#在控制台查看所有字体名称#print(pygame.font.get_fonts())#绘制文字信息(文本,抗锯齿,颜色,背景-无)textSurface=font.render(text,True,TEXT_color)return textSurface#获取事件(定义按下键盘显示什么的事件)def getEvent(self):#获取所有事件evenList = pygame.event.get()#遍历事件for event in evenList:#判断按下的键是关闭还是键盘按下# 如果按的键是退出,则关闭窗口if event.type == pygame.QUIT:self.endGame()#设置上下左右键(当键盘是按下去的时候)if event.type == pygame.KEYDOWN:#当坦克不存在,死亡时,按下的esc键可复活if not MainGame.my_tank:#判断按下的是esc,if event.key == pygame.K_ESCAPE:#让坦克重生,即调用坦克重生的方法self.createMytank()if MainGame.my_tank and MainGame.my_tank.live:# 判断是否为上下左右键if event.key == pygame.K_LEFT:# 按下键调用移动方法MainGame.my_tank.direction = 'L'# MainGame.my_tank.move()#在event.type == pygame.KEYDOWN中,只能按一下走一下# 修改坦克的开关状态(优化上面,使stop改为false)MainGame.my_tank.stop = Falseprint("按左键,坦克向左移动")elif event.key == pygame.K_RIGHT:# 按下键调用移动方法MainGame.my_tank.direction = 'R'# MainGame.my_tank.move()#在event.type == pygame.KEYDOWN中,只能按一下走一下# 修改坦克的开关状态(优化上面,使stop改为false)MainGame.my_tank.stop = Falseprint("按右键,坦克向右移动")elif event.key == pygame.K_UP:# 按下键调用移动方法MainGame.my_tank.direction = 'U'# MainGame.my_tank.move()#在event.type == pygame.KEYDOWN中,只能按一下走一下# 修改坦克的开关状态(优化上面,使stop改为false)MainGame.my_tank.stop = Falseprint("按上键,坦克向上移动")elif event.key == pygame.K_DOWN:# 按下键调用移动方法MainGame.my_tank.direction = 'D'# MainGame.my_tank.move()#在event.type == pygame.KEYDOWN中,只能按一下走一下# 修改坦克的开关状态(优化上面可一直按按键走动,使stop改为false)MainGame.my_tank.stop = Falseprint("按下键,坦克向下移动")# 补充一个空格键,可以发射子弹elif event.key == pygame.K_SPACE:print("发射子弹")# 如果我方子弹列表列表的大小,小于等于3时,才可以创建if len(MainGame.myBulletList) < 3:# 创建我方坦克发射子弹myBullet = Bullet(MainGame.my_tank)MainGame.myBulletList.append(myBullet)#添加我方坦克发射子弹添加音效music = Music("img/jiu.wav")music.play()#当键盘是松开的时候(修改坦克的关状态,使坦克停止)if event.type == pygame.KEYUP:#判断松开的键是上、下、左、右的时候才停止移动if event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:if MainGame.my_tank and MainGame.my_tank.live:MainGame.my_tank.stop = True#坦克类class Tank(BaseItem):#添加坦克def __init__(self,left,top):#距离左边left,距离上边topself.images={'U':pygame.image.load('img/p1tankU.gif'),'D':pygame.image.load('img/p1tankD.gif'),'L':pygame.image.load('img/p1tankL.gif'),'R':pygame.image.load('img/p1tankR.gif')}#设置默认方向self.direction='U'#根据当前图片的方向来获取图片,返回的是surfaceself.image=self.images[self.direction]#获取区域self.rect=self.image.get_rect()#设置区域的left和topself.rect.left=leftself.rect.top=top#速度决移动的快慢self.speed=5#坦克移动的开关self.stop = True#在坦克类中添加live属性#是否活着self.live = True#新增属性原来坐标self.oldLeft = self.rect.leftself.oldTop =self.rect.top#定义移动方法;限制可移动的范围def move(self):#移动后记录原始的坐标self.oldLeft = self.rect.leftself.oldTop = self.rect.top#判读坦克的移动方向if self.direction =='L':if self.rect.left>0:self.rect.left -= self.speedelif self.direction =='R':if self.rect.left+self.rect.height<SCREEN_WIDTH:self.rect.left += self.speedelif self.direction == 'U':if self.rect.top > 0:self.rect.top -= self.speedelif self.direction == 'D':if self.rect.top+self.rect.height<SCREEN_HEIGHT:self.rect.top += self.speed#射击def shot(self):return Bullet(self)#def stay(self):self.rect.left=self.oldLeftself.rect.top=self.oldTop#检测坦克是否与墙壁反生碰撞def hitWall(self):for wall in MainGame.wallList:if pygame.sprite.collide_rect(self,wall):#将坐标设置为移动之前的坐标self.stay()#展示坦克的方法def dispalyTank(self):#获取坦克图片对象self.image=self.images[self.direction]#获取元组(即四个方向的坦克)#调用blit方法:将一个图像绘制到另一个图像上MainGame.window.blit(self.image,self.rect)#我方坦克class MyTank(Tank):def __init__(self,left,top):super(MyTank,self).__init__(left,top)#检测我方坦克与敌方坦克反生碰撞def myTank_hit_enemyTank(self):#循环遍历敌方坦克列表for enemyTank in MainGame.enemyTankList:if pygame.sprite.collide_rect(self,enemyTank):self.stay()#敌方坦克class EnemyTank(Tank):def __init__(self,left,top,speed):#调用父类初始化方法super(EnemyTank,self).__init__(left,top)#加载敌方坦克图片(上下左右四个方向)self.images = {'U': pygame.image.load('img/p2tankU.gif'),'D': pygame.image.load('img/p2tankD.gif'),'L': pygame.image.load('img/p2tankL.gif'),'R': pygame.image.load('img/p2tankR.gif')}#方向,随机生成敌方坦克方向self.direction = self.randDirection()#根据方向获取图片self.image =self.images[self.direction]#区域self.rect =self.image.get_rect()#对left和top进行赋值self.rect.left = leftself.rect.top = top#速度self.speed=speed#移动开关self.flag = True#新增一个变量步数stepself.step =60#敌方坦克与我方坦克是否发生碰撞def enemyTank_hit_myTank(self):if pygame.sprite.collide_rect(self,MainGame.my_tank):self.stay()#随机生成敌方坦克方向def randDirection(self):num = random.randint(1,4)if num == 1:return 'U'elif num==2:return 'D'elif num==3:return 'L'elif num==4:return 'R'#随机移动敌方坦克的方法def randMove(self):if self.step <= 0:# 修改方向self.direction=self.randDirection()#让步数复位self.step =random.randint(50,70)else:self.move()#让步数递减self.step -= 1#因为敌方坦克发射子弹频率块,重新定义shot方法def shot(self):# 随机生成100以内的数num =random.randint(7,100)if num <10:return Bullet(self)#子弹class Bullet(BaseItem):def __init__(self,tank):#加载图片self.image = pygame.image.load('img/Bullet.gif')#坦克方向决定子弹方向self.direction = tank.direction#获取区域self.rect =self.image.get_rect()#子弹的left个top与方向有关if self.direction == 'U':self.rect.left=tank.rect.left+tank.rect.width/2 -self.rect.width/2self.rect.top=tank.rect.top-self.rect.heightelif self.direction == 'D':self.rect.left = tank.rect.left+tank.rect.width-self.rect.width/2self.rect.top = tank.rect.top+self.rect.heightelif self.direction == 'L':self.rect.left = tank.rect.left-self.rect.width/2-self.rect.width/2self.rect.top = tank.rect.top+tank.rect.width/2-self.rect.width/2elif self.direction == 'R':self.rect.left = tank.rect.left+tank.rect.widthself.rect.top = tank.rect.top+tank.rect.width/2-self.rect.width/2self.speed=6#子弹的状态,是否碰到墙壁,如果碰到墙壁,修此状态self.live = True#移动def move(self):#如果子弹向上发射if self.direction=='U':#如果向上的距离大于0,则子弹向上发射(子弹与坦克的方向一致),否则子弹消失if self.rect.top>0:self.rect.top -=self.speedelse:self.live = Falseelif self.direction == 'R':if self.rect.left+self.rect.width<SCREEN_WIDTH:self.rect.left+=self.speedelse:self.live = Falseelif self.direction == 'D':if self.rect.top+self.rect.height<SCREEN_HEIGHT:self.rect.top += self.speedelse:self.live = Falseelif self.direction == 'L':if self.rect.left>0:self.rect.left -=self.speedelse:self.live = False#子弹是否碰撞墙壁def hitWall(self):#循环遍历墙壁列表for wall in MainGame.wallList:if pygame.sprite.collide_rect(self,wall):#让子弹消失,修改子弹的生存状态self.live = False#墙壁的生命值减小wall.hp -=1if wall.hp<=0:#修改墙板的生存状态wall.live = False#展示子弹def displayBullet(self):# 将图片surface加载到窗口MainGame.window.blit(self.image,self.rect)#我方子弹与敌方坦克的碰撞def myBullet_hit_enemyTank(self):#循环遍历敌方坦克列表,判断是否发生碰撞for enemTank in MainGame.enemyTankList:if pygame.sprite.collide_rect(enemTank,self):#修改敌方坦克和我方子弹的状态enemTank.live = Falseself.live = False#创建爆炸对象explod = Explode(enemTank)#将爆炸对象添加到爆炸列表中MainGame.explodeList.append(explod)#敌方子弹与我方坦克的碰撞def enemyBullet_hit_myTank(self):if MainGame.my_tank and MainGame.my_tank.live:if pygame.sprite.collide_rect(MainGame.my_tank, self):# 产生爆炸对象explode = Explode(MainGame.my_tank)# 将爆炸对象添加到爆炸列表中MainGame.explodeList.append(explode)# 修改敌方子弹与我方坦克的状态self.live = FalseMainGame.my_tank.live = False#墙壁class Wall():def __init__(self,left,top):#加载墙壁图片self.image = pygame.image.load('img/w.gif')#获取墙壁的区域self.rect =self.image.get_rect()#设置位置left、topself.rect.left=leftself.rect.top=top#是否活着self.live =True#设置墙壁生命值self.hp=5#展示墙壁的方法def dispalyWall(self):MainGame.window.blit(self.image,self.rect)#爆炸class Explode():def __init__(self,tank):#爆炸的位置由当前子弹打中的坦克位置决定self.rect = tank.rectself.images = [pygame.image.load('img/b1.gif'),pygame.image.load('img/b2.gif'),pygame.image.load('img/b3.gif'),pygame.image.load('img/b4.gif'),pygame.image.load('img/b5.gif'),]self.step=0self.image=self.images[self.step]#是否活着self.live =True#展示爆炸效果def displayExplode(self):if self.step<len(self.images):#根据索引获取爆炸对象self.image=self.images[self.step]self.step +=1# 添加到主窗口MainGame.window.blit(self.image,self.rect)else:#修改活着的状态self.live=Falseself.step=0#音效class Music():def __init__(self,filename):self.filename = filename#初始化音乐混合器pygame.mixer.init()#加载音乐pygame.mixer.music.load(self.filename)#播放音乐def play(self):pygame.mixer.music.play()if __name__ == "__main__":MainGame().startGame()#MainGame().getTextSurface(),调用即可在控制台,看到可使用的字体
