Python pygame 坦克大战
import pygame, time, random from pygame.sprite import Sprite SCREEN_WIDTH = 750
SCREEN_HEIGHT= 500 BG_COLOR = pygame.Color(0, 0, 0) # 背景颜色 TEXT_COLOR = pygame.
Color(206, 217, 231) # 字体颜色 # 新建精灵类 class BaseItem(Sprite): pass class MainGame:
window= None myTank = None enemyCount = 5 enemyList = [] # 定义我方子弹发射列表
myBulletList= [] # 敌方坦克发射的子弹列表 enemyBulletList = [] # 定义存储爆炸效果类列表 explodeList =
[] # 定义墙壁列表 wallList = [] # 初始化方法 def __init__(self) -> None: pass # 创建敌方坦克 def
createEnemy(self): top = 100 for i in range(MainGame.enemyCount): left = random.
randint(0, 600) speed = random.randint(1, 4) enemyTank = EnemtTank(left, top,
speed) # 添加到列表 MainGame.enemyList.append(enemyTank) # 加载敌方坦克 def
displayEnemyTank(self): for enemyTank in MainGame.enemyList: # 判断敌方坦克是否存活 if
enemyTank.live: enemyTank.displayTank() # 调用move进行移动 enemyTank.rankMove() #
调用检测敌方坦克是否与墙壁发生碰撞 enemyTank.tank_hit_wall() # 初始化敌方坦克发射的子弹 enemyBullet =
enemyTank.shot() # 调用检测敌方坦克是否与墙壁发生碰撞 if MainGame.myTank and MainGame.myTank.live
: enemyTank.enemyTank_hit_myTank() if enemyBullet: MainGame.enemyBulletList.
append(enemyBullet) # 判断子弹是否有值 if enemyBullet: MainGame.enemyBulletList.append(
enemyBullet) else: # 当敌方坦克已经死亡,将坦克从敌方坦克列表移除 MainGame.enemyList.remove(enemyTank)
# 显示我方坦克发射的子弹 def displayMyBullet(self): for myBullet in MainGame.myBulletList:
if myBullet.live: myBullet.displayBullet() # 调用子弹的移动方法 myBullet.move() #
调用子弹是否与敌方坦克碰撞 myBullet.myBullet_hit_enemyTank() # 调用我方子弹是否与墙壁碰撞 myBullet.
bullet_hit_wall() else: # 从子弹列表中删除子弹 MainGame.myBulletList.remove(myBullet) #
显示敌方子弹发射 def displayEnemyBullet(self): for enemyBullet in MainGame.
enemyBulletList: if enemyBullet.live: enemyBullet.displayBullet() # 调用子弹移动
enemyBullet.move() # 调用敌方子弹和我我方坦克碰撞检测 enemyBullet.enemyBullet_hit_myTank() #
调用敌方子弹是否与墙壁碰撞 enemyBullet.bullet_hit_wall() else: MainGame.enemyBulletList.
remove(enemyBullet) # 循环遍历爆炸效果列表来展示爆炸效果 def displayExplodeList(self): for
explodein MainGame.explodeList: if explode.live: # 展示 explode.displayExplode()
else: # 从爆炸效果中移除 MainGame.explodeList.remove(explode) # 创建我方坦克 def createMyTank(
self): MainGame.myTank = MyTank(350, 300) # 添加音效 music = Music(
"../坦克大战/img/start.wav") # 播放 music.playMusic() # 创建墙壁 def createWall(self): top
= 220 for i in range(6): # 初始化墙壁 wall = Wall(i * 130, top) # 添加到墙壁列表 MainGame.
wallList.append(wall) # 加载墙壁 def displayWallList(self): # 循环遍历墙壁列表 for wall in
MainGame.wallList: if wall.live: wall.displayWall() else: MainGame.wallList.
remove(wall) # 开始游戏 def startGame(self): pygame.display.init() # 设置窗口大小 MainGame
.window = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 设置窗口标题 pygame
.display.set_caption("坦克大战1.00") # 初始化我方坦克 self.createMyTank() # 调用创建敌方坦克 self.
createEnemy() # 创建墙壁 self.createWall() while True: # 让窗口一直存在不消失 time.sleep(0.01)
# 给窗口设置填充色 MainGame.window.fill(BG_COLOR) # 添加文字信息提示 textSurface = self.
getTextSurface(" Remaining number of enemy tanks is %d " % len(MainGame.
enemyList)) # 主窗口显示文字信息 MainGame.window.blit(textSurface, (10, 10)) # 添加事件监听
self.getEvent() # 调用坦克的显示方法 if MainGame.myTank and MainGame.myTank.live:
MainGame.myTank.displayTank() else: # 删除我方坦克 del MainGame.myTank MainGame.myTank
= None # 调用坦克移动的方法 if MainGame.myTank and MainGame.myTank.live: if not MainGame.
myTank.stop: MainGame.myTank.move() # 调用检测敌方坦克是否与墙壁发生碰撞 MainGame.myTank.
tank_hit_wall() # 调用检测我方坦克是否与敌方坦克发生碰撞 MainGame.myTank.myTank_hit_enemyTank() #
加载敌方坦克 self.displayEnemyTank() # 加载我方坦克发射的子弹 self.displayMyBullet() #
加载敌方坦克发射的子弹 self.displayEnemyBullet() # 加载爆炸效果 self.displayExplodeList() # 加载墙壁
self.displayWallList() pygame.display.update() # 添加文字信息提示 def getTextSurface(
self, text): # 初始化字体模块 pygame.font.init() # 获取字体对象 font = pygame.font.SysFont(
'consolas', 18) # 绘制文字信息 textSurface = font.render(text, True, TEXT_COLOR) #
添加事件监听 self.getEvent() return textSurface # print(pygame.font.get_fonts()) #
看看字体有哪些 # 添加事件监听 def getEvent(self): # 获取所有的事件 eventList = pygame.event.get() #
遍历事件 for event in eventList: # 判断按下是否是关闭按钮 if event.type == pygame.QUIT: self.
endGame() # 判断是否是键盘事件 if event.type == pygame.KEYDOWN: if not MainGame.myTank:
# 判断键盘按下的是esc if event.key == pygame.K_ESCAPE: # 调用创建我方坦克的方法 self.createMyTank()
# 调用创建墙壁的方法 # self.createWall() if MainGame.myTank and MainGame.myTank.live: if
event.key == pygame.K_LEFT: print("按下左键,坦克向左移动") MainGame.myTank.direction = 'L'
# 修改坦克移动的方法 MainGame.myTank.stop = False elif event.key == pygame.K_RIGHT: print
("按下右键,坦克向右移动") # 调用坦克移动方法 MainGame.myTank.direction = 'R' # 修改坦克移动的方法 MainGame.
myTank.stop = False elif event.key == pygame.K_UP: print("按下上键,坦克向上移动") #
调用坦克移动方法 MainGame.myTank.direction = 'U' # 修改坦克移动的方法 MainGame.myTank.stop =
False elif event.key == pygame.K_DOWN: print("按下下键,坦克向下移动") # 调用坦克移动方法 MainGame.
myTank.direction = 'D' # 修改坦克移动的方法 MainGame.myTank.stop = False elif event.key
== pygame.K_SPACE: print('发射子弹') # 限制子弹数量 #子弹列表的数量如果小于3,可以初始化子弹 if len(MainGame.
myBulletList) <= 3: myBullet = Bullet(MainGame.myTank) MainGame.myBulletList.
append(myBullet) # 添加音效 music = Music('../坦克大战/img/fire.wav') music.playMusic()
# 判断是否是键盘是否松开 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or
event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame
.K_UP: if MainGame.myTank and MainGame.myTank.live: MainGame.myTank.stop = True
# 结束游戏 def endGame(self): print("谢谢使用,欢迎下次使用") exit() class Tank(BaseItem): def
__init__(self, left, top): # 保存加载图片 self.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 = 'R' # 根据坦克方向,加载图片 self.
image= self.images.get(self.direction) # 根据图片获取图片所在的矩形区域 self.rect = self.image.
get_rect() # 设置区域的left和top self.rect.left = left self.rect.top = top # 速度 self.
speed= 5 # 坦克移动的开关 self.stop = True # 坦克生成状态 self.live = True # 移动之前的位置 self.
oldleft= self.rect.left self.oldtop = self.rect.top # 展示坦克 def displayTank(self)
: self.image = self.images.get(self.direction) MainGame.window.blit(self.image,
self.rect) # 移动坦克 def move(self): # 记录移动之前的位置 self.oldleft = self.rect.left self
.oldtop = self.rect.top # 判断坦克方向移动 if self.direction == 'L': if self.rect.left >
0: self.rect.left -= self.speed elif self.direction == 'R': if self.rect.left +
self.rect.height < SCREEN_WIDTH: self.rect.left += self.speed elif self.
direction== 'U': if self.rect.top > 0: self.rect.top -= self.speed elif self.
direction== 'D': if self.rect.top + self.rect.height < SCREEN_HEIGHT: self.rect.
top+= self.speed # 射击 def shot(self): pass # 设置坦克位置为移动之前的位置 def stay(self): self
.rect.left = self.oldleft self.rect.top = self.oldtop # 检测坦克是否与墙壁发生碰撞 def
tank_hit_wall(self): # 循环遍历墙壁列表 for wall in MainGame.wallList: if pygame.sprite.
collide_rect(self, wall): # 设置坦克的坐标为移动之前的位置 self.stay() # 我方坦克 class MyTank(Tank
): # 初始化方法 def __init__(self, left, top) -> None: # 调用父类的初始方法 super(MyTank, self
).__init__(left, top) # 检测我方坦克是否与敌方坦克发生碰撞 def myTank_hit_enemyTank(self): #
循环遍历敌方坦克列表 for enemyTank in MainGame.enemyList: if pygame.sprite.collide_rect(
self, enemyTank): self.stay() # 地方坦克 class EnemtTank(Tank): def __init__(self,
left, top, speed): super(EnemtTank, self).__init__(left, top) self.images = {
'U': pygame.image.load("../坦克大战/img/enemy1U.gif"), 'D': pygame.image.load(
"../坦克大战/img/enemy1D.gif"), 'L': pygame.image.load("../坦克大战/img/enemy1L.gif"),
'R': pygame.image.load("../坦克大战/img/enemy1R.gif"), } # 设置敌方坦克的方向 self.direction
= self.randDirection() # 根据方向获取图片 self.image = self.images.get(self.direction)
# 获取矩形区域 self.rect = self.image.get_rect() # 设置left 和top self.rect.left = left
self.rect.top = top self.speed = speed self.step = 30 # self.live = True #
随机生成的方向 def randDirection(self): num = int(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 rankMove(self): if self.step <= 0: # 修改坦克移动方向 self.direction =
self.randDirection() # 让步数复位 self.step = 30 else: self.move() # 步数递减 self.step
-= 1 def shot(self): # 随机生成一个100以内的数字 num = random.randint(0, 100) if num < 19:
return Bullet(self) # 检测敌方坦克是否与我方坦克发生碰撞 def enemyTank_hit_myTank(self): if
pygame.sprite.collide_rect(self, MainGame.myTank): self.stay() # 子弹类 class
Bullet(BaseItem): def __init__(self, tank): # 加载图片 self.image = pygame.image.
load("../坦克大战/img/enemymissile.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 / 2
self.rect.top = tank.rect.top - self.rect.height elif self.direction == 'D':
self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2 self
.rect.top = tank.rect.top + tank.rect.height elif self.direction == 'L': self.
rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2 self.rect
.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2 elif self.
direction== 'R': self.rect.left = tank.rect.left + tank.rect.width self.rect.top
= tank.rect.top + tank.rect.width / 2 - self.rect.width / 2 # 子弹的速度 self.speed =
6 # 判断子弹是否存活 self.live = True # 显示子弹 def displayBullet(self): MainGame.window.
blit(self.image, self.rect) # 子弹移动 def move(self): if self.direction == 'U': if
self.rect.top > 0: self.rect.top -= self.speed else: # 碰到墙壁 self.live = False
elif self.direction == 'D': if self.rect.top + self.rect.height < SCREEN_HEIGHT:
self.rect.top += self.speed else: self.live = False elif self.direction == 'L':
if self.rect.left > 0: self.rect.left -= self.speed else: self.live = False elif
self.direction == 'R': if self.rect.left + self.rect.width < SCREEN_WIDTH: self
.rect.left += self.speed else: self.live = False # 我方子弹和敌方坦克碰撞检测 def
myBullet_hit_enemyTank(self): # 遍历敌方坦克列表 for enemyTank in MainGame.enemyList: if
pygame.sprite.collide_rect(self, enemyTank): # 修改敌方坦克和我方子弹生成状态 enemyTank.live =
False self.live = False # 初始化爆炸效果类 explode = Explode(enemyTank) #
添加爆炸效果类到爆炸效果列表中 MainGame.explodeList.append(explode) def enemyBullet_hit_myTank(
self): if MainGame.myTank and MainGame.myTank.live: if pygame.sprite.
collide_rect(self, MainGame.myTank): # 产生爆炸效果 explode = Explode(MainGame.myTank)
# 将爆炸效果添加到爆炸效果列表 MainGame.explodeList.append(explode) # 修改敌方子弹与我方坦克的生存状态 self.
live= False MainGame.myTank.live = False # 检测子弹是否与墙壁发生碰撞 def bullet_hit_wall(
self): # 循环遍历墙壁列表 for wall in MainGame.wallList: if pygame.sprite.collide_rect(
self, wall): # 设置子弹生存状态修改 self.live = False # 让墙壁的生命值减减 wall.hp -= 1 #
判断墙壁生命值是否小于等于0 if wall.hp <= 0: # 设置墙壁的生存状态 wall.live = False # 墙壁类 class Wall()
: def __init__(self, left, top): # 加载墙壁图片 self.image = pygame.image.load(
'../坦克大战/代码/img/steels.gif') # 根据图片获取区域 self.rect = self.image.get_rect() #
设置left top self.rect.left = left self.rect.top = top # 生存状态 self.live = True #
生命值 self.hp = 3 # 展示墙壁方法 def displayWall(self): MainGame.window.blit(self.image,
self.rect) # 爆炸效果 class Explode(): def __init__(self, tank): # 爆炸位置为当前击中坦克的位置
self.rect = tank.rect self.images = [ pygame.image.load("../坦克大战/img/blast0.gif"
), pygame.image.load("../坦克大战/img/blast1.gif"), pygame.image.load(
"../坦克大战/img/blast2.gif"), pygame.image.load("../坦克大战/img/blast3.gif"), pygame.
image.load("../坦克大战/img/blast4.gif"), ] self.step = 0 self.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 = False
self.step = 0 # 音效类 class Music(): def __init__(self, filename) -> None: self.
filename= filename # 初始化混合器 pygame.mixer.init() # 加载音乐 pygame.mixer.music.load(
self.filename) # 播放音乐 def playMusic(self): pygame.mixer.music.play() if __name__
== '__main__': # 调用主类的startGame MainGame().startGame()

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信