位置: 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 安装)

  • 两处取得工资的成语
  • 非税收入票据能否税前扣除
  • 核定征收的计算方法有哪些
  • 报关单汇率按出口日期还是申报日期
  • 利息支出可以抵扣吗
  • 收银设备如何入账的
  • 工商登记执照号码怎么查询
  • 购货方要求退货合理吗
  • 作为一个财务 月末要做什么
  • 按年征收的基金有哪些
  • 公司土地转让另外公司
  • 承包工程会计账务处理流程
  • 银行卡收到养老金是什么意思
  • 交通费汇算清缴怎么做账
  • 企业给员工的异地安家费交个税吗?
  • 会计凭证的概念及分类
  • 一般纳税人取得3%专票可以抵扣吗
  • 购销合同印花税优惠政策
  • 增值税进项和销项税的计算方法
  • 内销征税是什么意思
  • 服装发票怎么进项抵扣
  • 转籍车辆是什么意思
  • 税收滞纳金变化
  • 营业外收入政府补贴要交税吗
  • mac菜单键怎么设置出来的
  • 电脑打字不显示文字选项
  • 怎么做年终结算工资
  • 查补以前年度税款账务处理
  • 发票已开不符合收入确认条件账务处理怎么做?
  • 税务机关义务包括
  • nginx静态文件服务器
  • php删除数据
  • 增值税发票超额后税率
  • 悬崖雕塑
  • 图片转base64格式返回给前端,前端如何展示?
  • php 集成环境
  • 深拷贝的实现方式
  • echarts api文档
  • 结转材料成本差异所需科目
  • 事业单位体检费标准是多少
  • mysql数据库命名 可以用-吗
  • 啤酒的消费税
  • 非营利组织注册
  • 个人劳务报酬的个税
  • 计提坏账准备资产总额会减少吗
  • 实缴税额怎么算
  • 母公司溢价收购子公司
  • 固定资产当月入账当月计提吗
  • 小规模纳税人减按1%账务处理
  • 为什么出口退税是贷方
  • 外资企业对应的企业是什么
  • 什么是委托加工原材料
  • 财政总预算会计的主体是
  • 新成立的公司哪个地方能查到
  • 工资代扣工会会费协议
  • 公司的钱如何提出来
  • 一般纳税人开错税率严重吗
  • SSB(SQLservice Service Broker) 入门实例介绍
  • 动态创建表
  • win10创建家庭
  • linux ls常用命令
  • winxp不能正常启动
  • javascript 语言精粹(修订版)
  • 学习计划
  • javascript字体属性
  • nginx日志按天切割
  • css兼容浏览器
  • android:testonly="true"
  • Javascript字符串奇数位替换
  • Android自定义系统服务框架
  • socks5代理怎么用
  • 油票增值税专用发票几个点开
  • 纳税人识别号是几位数
  • 如何下载个人所得税A表
  • 公司0申报怎么申报视频
  • 发票怎样上传?
  • 土地买卖谈判开场陈述
  • 浙江省如何自助缴纳社保
  • 应聘保险公司需要了解什么
  • 怎么下载国家税务局网上办税
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设