位置: IT常识 - 正文

学习 Python 之 Pygame 开发坦克大战(五)(python怎么学)

编辑:rootadmin
学习 Python 之 Pygame 开发坦克大战(五) 学习 Python 之 Pygame 开发坦克大战(五)坦克大战完善地图1. 创建砖墙2. 给砖墙增加子弹击中的碰撞效果3. 给砖墙添加坦克不能通过的碰撞效果4. 添加石墙5. 添加玩家基地6. 最终效果坦克大战完善地图

推荐整理分享学习 Python 之 Pygame 开发坦克大战(五)(python怎么学),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:python语言怎么学,python咋学,python怎样学,python怎么学,python 如何学,python learning,python语言怎么学,python语言怎么学,内容如对您有帮助,希望把文章链接给更多的朋友!

我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材

素材链接:百度网盘 链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz 提取码:tkdz

那我们就继续编写坦克大战吧

1. 创建砖墙

坦克大战中,砖墙是最常见的墙,子弹都可以轻松击穿,下面我们来加入到自己的坦克大战中

创建砖墙类

import pygame.imagefrom ParentObject import ParentObjectclass BrickWall(ParentObject): def __init__(self, x, y): super().__init__() self.image = pygame.image.load('../Image/Wall/BrickWall.png') self.rect = self.image.get_rect() self.rect.left = x self.rect.top = y self.isDestroy = False def draw(self, window): window.blit(self.image, self.rect)

在主类中加入砖墙列表

class MainGame: ... # 砖墙 brickWallList = [] ...

在主类中加入初始化砖墙函数和显示砖墙函数

def drawBrickWall(self, brickWallList): for brickWall in brickWallList: if brickWall.isDestroy: brickWallList.remove(brickWall) else: brickWall.draw(MainGame.window)def initBrickWall(self): for i in range(20): MainGame.brickWallList.append(BrickWall(i * 25, 200))

这里我在y = 200的位置,连续画出20个砖,砖的图片是25x25的,所以为了防止重叠,要间隔25个距离(像素)

在主函数startGame()函数中调用函数

def startGame(self): # 初始化展示模块 pygame.display.init() # 设置窗口大小 size = (SCREEN_WIDTH, SCREEN_HEIGHT) # 初始化窗口 MainGame.window = pygame.display.set_mode(size) # 设置窗口标题 pygame.display.set_caption('Tank Battle') # 初始化我方坦克 MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1) # 播放开始音乐 MainGame.startingSound.play() # 初始化场景 self.initBrickWall() while 1: # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR) # 获取窗口事件 self.getPlayingModeEvent() # 显示物体 self.drawBrickWall(MainGame.brickWallList) # 展示敌方坦克 self.drawEnemyTank() # 显示我方坦克 MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1]) # 我方坦克移动 if not MainGame.playerTank.stop: MainGame.playerTank.move() MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList) # 显示我方坦克子弹 self.drawPlayerBullet(MainGame.playerBulletList) # 展示敌方坦克子弹 self.drawEnemyBullet() # 展示爆炸效果 self.drawExplode() # 更新窗口 pygame.display.update()

运行一下,看看结果 但是墙只是摆设,子弹可以穿过,坦克也可以穿过,下面给墙增加碰撞效果

2. 给砖墙增加子弹击中的碰撞效果

在子弹类中增加函数

def bulletCollideBrickWall(self, brickWallList, explodeList): for brickWall in brickWallList: # 子弹与墙发生碰撞 if pygame.sprite.collide_rect(self, brickWall): self.isDestroy = True brickWall.isDestroy = True # 碰撞出现爆炸效果 explode = Explode(brickWall, 25) explodeList.append(explode) # 出现爆炸播放音效 Sound('../Sound/block.wav').play()

在主函数中调用 修改显示子弹的两个函数

def drawPlayerBullet(self, playerBulletList): # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除 for bullet in playerBulletList: if not bullet.isDestroy: bullet.draw(MainGame.window) bullet.move(MainGame.explodeList) bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList) bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList) else: playerBulletList.remove(bullet)def drawEnemyBullet(self): for bullet in MainGame.enemyTankBulletList: if not bullet.isDestroy: bullet.draw(MainGame.window) bullet.move(MainGame.explodeList) bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList) bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList) else: bullet.source.bulletCount -= 1 MainGame.enemyTankBulletList.remove(bullet)

运行一下看看

可以看到墙可以被打掉了

3. 给砖墙添加坦克不能通过的碰撞效果

在敌方坦克类中加入函数,在我方坦克类中加入函数 collideBrickWall()

def collideBrickWall(self, brickWallList): for brickWall in brickWallList: if pygame.sprite.collide_rect(self, brickWall): self.rect.left = self.prvX self.rect.top = self.prvY

在主类中调用 在while循环中调用

while 1: # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR) # 获取窗口事件 self.getPlayingModeEvent() # 显示物体 self.drawBrickWall(MainGame.brickWallList) # 展示敌方坦克 self.drawEnemyTank() # 显示我方坦克 MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1]) # 我方坦克移动 if not MainGame.playerTank.stop: MainGame.playerTank.move() MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList) # 不能撞墙 MainGame.playerTank.collideBrickWall(MainGame.brickWallList)

在主类的drawEnemyTank()中调用

def drawEnemyTank(self): ... for tank in MainGame.enemyTankList: # 坦克还有生命值 if tank.life > 0: tank.draw(MainGame.window) tank.move() tank.collidePlayerTank(MainGame.playerTank) tank.collideEnemyTank(MainGame.enemyTankList) # 不能撞墙 tank.collideBrickWall(MainGame.brickWallList) bullet = tank.shot() if bullet is not None: MainGame.enemyTankBulletList.append(bullet) # 坦克生命值为0,就从列表中剔除 else: MainGame.enemyTankCurrentCount -= 1 MainGame.enemyTankList.remove(tank)

运行一下,看看效果 确实是不能穿过了 那就完成啦,接下来就是添加其他的物体了 添加的过程跟添加砖墙是一样的

4. 添加石墙

创建石墙类

import pygame.imagefrom ParentObject import ParentObjectclass StoneWall(ParentObject): def __init__(self, x, y): super().__init__() self.image = pygame.image.load('../Image/Wall/StoneWall.png') self.rect = self.image.get_rect() self.rect.left = x self.rect.top = y self.isDestroy = False def draw(self, window): window.blit(self.image, self.rect)

在主类中加入石墙列表 在主类中加入显示石墙函数

def initStoneWall(self): for i in range(20): MainGame.stoneWallList.append(StoneWall(i * 25, 400))def drawStoneWall(self, stoneWallList): for stoneWall in stoneWallList: if stoneWall.isDestroy: stoneWallList.remove(stoneWall) else: stoneWall.draw(MainGame.window)学习 Python 之 Pygame 开发坦克大战(五)(python怎么学)

给石墙添加坦克不能通过的碰撞效果 在敌方坦克类中加入函数,在我方坦克类中加入函数 collideStoneWall()

def collideStoneWall(self, stoneWallList): for stoneWall in stoneWallList: if pygame.sprite.collide_rect(self, stoneWall): self.rect.left = self.prvX self.rect.top = self.prvY

在主类中调用函数

接下来是给子弹添加打击石墙的效果

def bulletCollideStoneWall(self, stoneWallList, explodeList): for stoneWall in stoneWallList: if pygame.sprite.collide_rect(self, stoneWall): # 判断坦克的等级,大于等于2时,可以打穿石墙 if self.source.level >= 2: stoneWall.isDestroy = True self.isDestroy = True explode = Explode(stoneWall, 25) explodeList.append(explode) Sound('../Sound/block.wav').play()

在主类中调用函数

主类的完整代码

import pygameimport sysfrom PlayerTank import PlayerTankfrom EnemyTank import EnemyTankfrom Sound import Soundfrom BrickWall import BrickWallfrom StoneWall import StoneWallSCREEN_WIDTH = 1100SCREEN_HEIGHT = 600BACKGROUND_COLOR = pygame.Color(0, 0, 0)FONT_COLOR = (255, 255, 255)PLAYER_TANK_POSITION = (325, 550)class MainGame: # 窗口Surface对象 window = None # 玩家坦克 playerTank = None # 玩家子弹 playerBulletList = [] playerBulletNumber = 3 # 敌人坦克 enemyTankList = [] enemyTankTotalCount = 5 # 用来给玩家展示坦克的数量 enemyTankCurrentCount = 5 # 敌人坦克子弹 enemyTankBulletList = [] # 爆炸列表 explodeList = [] # 坦克移动音效 playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume() # 游戏开始音效 startingSound = Sound('../Sound/intro.wav') # 砖墙 brickWallList = [] # 石墙 stoneWallList = [] def __init__(self): pass def startGame(self): # 初始化展示模块 pygame.display.init() # 设置窗口大小 size = (SCREEN_WIDTH, SCREEN_HEIGHT) # 初始化窗口 MainGame.window = pygame.display.set_mode(size) # 设置窗口标题 pygame.display.set_caption('Tank Battle') # 初始化我方坦克 MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1) # 播放开始音乐 MainGame.startingSound.play() # 初始化场景 self.initBrickWall() self.initStoneWall() while 1: # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR) # 获取窗口事件 self.getPlayingModeEvent() # 显示物体 self.drawBrickWall(MainGame.brickWallList) self.drawStoneWall(MainGame.stoneWallList) # 展示敌方坦克 self.drawEnemyTank() # 显示我方坦克 MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1]) # 我方坦克移动 if not MainGame.playerTank.stop: MainGame.playerTank.move() MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList) MainGame.playerTank.collideBrickWall(MainGame.brickWallList) MainGame.playerTank.collideStoneWall(MainGame.stoneWallList) # 显示我方坦克子弹 self.drawPlayerBullet(MainGame.playerBulletList) # 展示敌方坦克子弹 self.drawEnemyBullet() # 展示爆炸效果 self.drawExplode() # 更新窗口 pygame.display.update() def getPlayingModeEvent(self): # 获取所有事件 eventList = pygame.event.get() for event in eventList: if event.type == pygame.QUIT: sys.exit() """ stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动 如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动 """ if event.type == pygame.KEYDOWN: MainGame.playerTankMoveSound.play(-1) if event.key == pygame.K_w: MainGame.playerTank.direction = 'UP' MainGame.playerTank.stop = False elif event.key == pygame.K_s: MainGame.playerTank.direction = 'DOWN' MainGame.playerTank.stop = False elif event.key == pygame.K_a: MainGame.playerTank.direction = 'LEFT' MainGame.playerTank.stop = False elif event.key == pygame.K_d: MainGame.playerTank.direction = 'RIGHT' MainGame.playerTank.stop = False elif event.key == pygame.K_j: # 判断子弹数量是否超过指定的个数 if len(MainGame.playerBulletList) < MainGame.playerBulletNumber: bullet = MainGame.playerTank.shot() MainGame.playerBulletList.append(bullet) # 添加音效 Sound('../Sound/shoot.wav').play(0) if event.type == pygame.KEYUP: MainGame.playerTankMoveSound.stop() if event.key == pygame.K_w: MainGame.playerTank.stop = True elif event.key == pygame.K_s: MainGame.playerTank.stop = True elif event.key == pygame.K_a: MainGame.playerTank.stop = True elif event.key == pygame.K_d: MainGame.playerTank.stop = True def drawPlayerBullet(self, playerBulletList): # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除 for bullet in playerBulletList: if not bullet.isDestroy: bullet.draw(MainGame.window) bullet.move(MainGame.explodeList) bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList) bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList) bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList) else: playerBulletList.remove(bullet) def drawEnemyTank(self): # 如果当前坦克为0,那么就该重新生成坦克 if len(MainGame.enemyTankList) == 0: # 一次性产生三个,如果剩余坦克数量超过三,那只能产生三个 n = min(3, MainGame.enemyTankTotalCount) # 如果最小是0,就说明敌人坦克没有了,那么就赢了 if n == 0: print('赢了') return # 没有赢的话,就产生n个坦克 self.initEnemyTank(n) # 总个数减去产生的个数 MainGame.enemyTankTotalCount -= n # 遍历坦克列表,展示坦克并且移动 for tank in MainGame.enemyTankList: # 坦克还有生命值 if tank.life > 0: tank.draw(MainGame.window) tank.move() tank.collidePlayerTank(MainGame.playerTank) tank.collideEnemyTank(MainGame.enemyTankList) tank.collideBrickWall(MainGame.brickWallList) tank.collideStoneWall(MainGame.stoneWallList) bullet = tank.shot() if bullet is not None: MainGame.enemyTankBulletList.append(bullet) # 坦克生命值为0,就从列表中剔除 else: MainGame.enemyTankCurrentCount -= 1 MainGame.enemyTankList.remove(tank) def initEnemyTank(self, number): y = 0 position = [0, 425, 850] index = 0 for i in range(number): x = position[index] enemyTank = EnemyTank(x, y) MainGame.enemyTankList.append(enemyTank) index += 1 def drawEnemyBullet(self): for bullet in MainGame.enemyTankBulletList: if not bullet.isDestroy: bullet.draw(MainGame.window) bullet.move(MainGame.explodeList) bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList) bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList) bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList) else: bullet.source.bulletCount -= 1 MainGame.enemyTankBulletList.remove(bullet) def drawExplode(self): for e in MainGame.explodeList: if e.isDestroy: MainGame.explodeList.remove(e) else: e.draw(MainGame.window) def drawBrickWall(self, brickWallList): for brickWall in brickWallList: if brickWall.isDestroy: brickWallList.remove(brickWall) else: brickWall.draw(MainGame.window) def initBrickWall(self): for i in range(20): MainGame.brickWallList.append(BrickWall(i * 25, 200)) def initStoneWall(self): for i in range(20): MainGame.stoneWallList.append(StoneWall(i * 25, 400)) def drawStoneWall(self, stoneWallList): for stoneWall in stoneWallList: if stoneWall.isDestroy: stoneWallList.remove(stoneWall) else: stoneWall.draw(MainGame.window)if __name__ == '__main__': MainGame().startGame()5. 添加玩家基地

坦克大战是玩家坦克在保护自己基地的同时消灭敌方坦克,当玩家坦克生命值为0或者基地爆炸时,游戏失败,下面来添加玩家的基地

创建基地类

import pygame.imagefrom ParentObject import ParentObjectclass Home(ParentObject): def __init__(self, x, y): super().__init__() self.image = pygame.image.load('../Image/Home/Home.png') self.rect = self.image.get_rect() self.rect.left = x self.rect.top = y self.isDestroy = False def draw(self, window): window.blit(self.image, self.rect)

为基地添加碰撞效果,在两个坦克类中加入下面的函数

def collideHome(self, home): if pygame.sprite.collide_rect(self, home): self.rect.left = self.prvX self.rect.top = self.prvY

在主函数创建基地变量,并初始化和调用上面的函数

之后给基地加入子弹击中效果

def bulletCollidePlayerHome(self, home, explodeList): if pygame.sprite.collide_rect(self, home): self.isDestroy = True explode = Explode(home, 50) explodeList.append(explode) Sound('../Sound/buh.wav').play() return True else: return False

返回值用来判断是否结束游戏 在主类中设置一个变量记录是否游戏结束

def __init__(self):# 初始化 MainGame.home = Home(425, 550) # 记录是否输了 self.isDefeated = False

在循环中检查

while 1:... # 检查是否输了 if self.isDefeated: self.defeated() break ...def defeated(self): # 失败了坦克不能移动了 MainGame.playerTankMoveSound.stop() # 播放失败音乐 Sound('../Sound/gameOver.wav').play() print('游戏结束') self.isDefeated = True

游戏结束后要改变窗口中的内容,显示你输了,所以要用break跳出

这里需要使用到在窗口显示文字,编写一个函数

def drawText(self, text, x, y, fontSize, window): # 初始化字体 pygame.font.init() font = pygame.font.SysFont('georgia', fontSize) # 加载文字并设置颜色 fontColor = pygame.Color(255, 255, 255) fontObject = font.render(text, True, fontColor) # 展示文字 window.blit(fontObject, (x, y))

记得在主函数中调用

while 1: # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR) # 获取窗口事件 self.getPlayingModeEvent() # 显示物体 self.drawBrickWall(MainGame.brickWallList) self.drawStoneWall(MainGame.stoneWallList) MainGame.home.draw(MainGame.window) # 展示敌方坦克 self.drawEnemyTank() # 显示我方坦克 MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1]) # 我方坦克移动 if not MainGame.playerTank.stop: MainGame.playerTank.move() MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList) MainGame.playerTank.collideBrickWall(MainGame.brickWallList) MainGame.playerTank.collideStoneWall(MainGame.stoneWallList) MainGame.playerTank.collideHome(MainGame.home) # 显示我方坦克子弹 self.drawPlayerBullet(MainGame.playerBulletList) # 展示敌方坦克子弹 self.drawEnemyBullet() # 展示爆炸效果 self.drawExplode() # 检查是否输了 if self.isDefeated: self.defeated() break # 更新窗口 pygame.display.update()# 设置背景颜色MainGame.window.fill(BACKGROUND_COLOR)# 显示字体self.drawText('Defeated', 200, 200, 50, MainGame.window)# 更新窗口pygame.display.update()

给玩家提示敌人坦克数量

到这里,坦克大战的基本功能就实现了,接下来就是添加其他的场景物体和坦克样子了

6. 最终效果

主界面,这里直接放了一张图片上去,图片在素材里,上面的坦克是自己画上去的,w和s键可以上下移动坦克,选择对应的模式 选择关卡,这里使用用了四张图片,左右箭头,上面的标题和start文字,这些都是图片,按下黄色箭头可以选择关卡,使用的鼠标事件

游戏界面

其中加入了奖励功能

地图制作可以使用excel读取信息,下面是第一关的地图

坦克大战代码

链接:https://pan.baidu.com/s/1qFV-0hi0cgZS1Hnvx6mK6Q?pwd=90tk 提取码:90tk

本文链接地址:https://www.jiuchutong.com/zhishi/295690.html 转载请保留说明!

上一篇:vue3 + ts: layout布局(vue3+ts+vite)

下一篇:Termux安装完整版Linux(Ubuntu)详细步骤(termux 安装)

  • 自行研发的无形资产不确认递延所得税
  • 税控盘的功能特点是
  • 什么是税收滞纳金请举例说明
  • 税务局报税怎么操作流程
  • 信用减值损失是什么类科目
  • 公司名称变更在哪个网站
  • 开发票税前税后
  • 年底向员工客户发放、赠送实物的怎么缴个税
  • 增值税发票密码忘记了怎么办
  • 金融企业税务稽查案例分析
  • 4s店的赠品
  • 文化传媒公司取名字不带文化
  • 预付房租发票未到分录
  • 假的手撕票已经入账了怎么办?
  • 银行缴纳印花税贷款方面哪些可以减免
  • 个人缴纳物业费怎么开发票
  • 2018水利基金税率是多少?怎么算
  • 国税发200931号文件解读
  • 土地投资入股需要什么资料
  • 专用发票可以抵扣吗
  • 固定资产残值清零怎么处理
  • 苹果电脑安装中国银行控件用不了
  • 让别公司开发票,不打款公账,可以不
  • 挖机所有权需要办理什么手续吗
  • 筹建期间内发生的开办费属于什么费用
  • php函数返回值类型
  • 马齿苋的功效与作用的功能与主治与用量
  • 无形资产的账务处理候文江视频
  • 土建工程付款方式比例
  • 没有抵扣联可以作废吗
  • 如何补办二手车牌照
  • webssh github
  • php sql 教程
  • 微信开发获取位置
  • vue使用计算属性
  • 股东投资款怎么存入公司
  • 生产企业出口转内销增值税申报表怎么填
  • 学电脑哪个网站比较好
  • 学电脑的网站
  • Python可变数据类型和不可变数据类型
  • 股东转股怎么办理
  • 从农业生产者购进农产品
  • 所得税预缴申报表资产总额怎么填
  • 什么情况下提供个人征信
  • 账务核对的主要内容
  • 推迟确认收入的分析
  • 销售收入打折后怎么做账
  • 民办非企业单位免税
  • 税控盘费用进什么科目
  • 技术服务费如何赋码
  • 开办费计入期间费用明细表
  • 代开专票作废税已经交了如何做分录?
  • 应付利息怎么记账
  • windows server2008 64位没有安装音频怎么办?
  • ubuntuone
  • debian更新软件
  • windows无法安装所需的文件,请确保所需的所有文件可用
  • 2021年win10累积更新
  • win8系统怎么设置桌面图标
  • win8桌面右键无法使用
  • ie11forwindows10
  • xp系统桌面图标不见了,点什么都没用?
  • linux磁盘空间不足怎么清理
  • win8怎么打开系统设置
  • linux文件中添加内容
  • cocos2dx视频教程
  • 创建自己的app外卖平台
  • bootstrap 多级菜单
  • jquery crud
  • 远程批量管理windows
  • js的变量
  • 税务局着装规定文件
  • 国家税务12366电子税务局重庆
  • 天津电子税务局ca证书
  • 贵州省地方税务局历任纪检组长马平
  • 纳税人有什么影响
  • 买车险代收车船税多少钱
  • 物流公司怎么申请TIR
  • 普宁市离揭阳市有多远
  • 何为标兵称号
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设