Life is short,you need Python——Python实现坦克大战(五)
皮卡丘比特:Life is short,you need Python——Python实现坦克大战(五)zhuanlan.zhihu.com四.项目开始
24.实现双方坦克的互相碰撞检测
- 1.我方坦克主动碰撞到敌方坦克(我方坦克停下来stay())
- 2.敌方坦克主动碰撞到我方坦克(敌方坦克停下来stay())
import pygame, time, random, os
_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0) # 窗口颜色
COLOR_BLUE = pygame.Color(3, 117, 190) # 窗口左上角文字颜色
class MainGame:
"""主游戏类"""
window = None # 游戏主窗口
SCREEN_WIDTH = 800 # 窗口的宽度
SCREEN_HEIGHT = 500 # 窗口的高度
TANK_P1 = None # 我方坦克
EnemyTank_list = [] # 存储敌方坦克的数量
EnemyTank_count = 5 # 要创建的敌方坦克数量
Bullet_list = [] # 存储我方子弹的列表
Eneny_bullet_list = [] # 存储敌方坦克的列表
Explode_list = [] # 存储爆炸效果的列表
Wall_list = [] # 存储墙壁的列表
def startGame(self):
"""开始游戏"""
_display.init() # 初始化窗口
# 创建窗口并加载窗口(借鉴官方文档)
MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])
self.creatMyTank() # 创建我方坦克
self.creatEnemyTank() # 创建敌方坦克
self.creatWalls() # 创建墙壁群
_display.set_caption("坦克大战v1.23") # 设置游戏的标题
# 让窗口持续刷新
while True:
MainGame.window.fill(COLOR_BLACK) # 给窗口完成一个填充颜色
self.getEvent() # 在循环中持续完成事件的获取
# 在窗口新增“坦克大战”小画布
MainGame.window.blit(pygame.image.load('img/标题.jpg'), (0, 0))
# 将绘制文字的小画布粘贴到窗口中
MainGame.window.blit(self.getTextSurface("剩余敌方坦克{}辆".format(len(MainGame.EnemyTank_list))), (600, 10))
# 调用展示墙壁的方法
self.blitWalls()
if MainGame.TANK_P1 and MainGame.TANK_P1.live:
# 将我方坦克加入到窗口中
MainGame.TANK_P1.displayTank()
else:
del MainGame.TANK_P1
MainGame.TANK_P1 = None
# 循环展示敌方坦克
self.blitEnemyTank()
# 根据坦克的开关状态调用坦克的移动方法
if MainGame.TANK_P1 and not MainGame.TANK_P1.stop:
MainGame.TANK_P1.move()
# 调用坦克碰撞墙壁的方法
MainGame.TANK_P1.hitWalls()
# 调用我方坦克与敌方坦克碰撞的方法
MainGame.TANK_P1.hitEnemyTank()
# 调用渲染我方子弹列表的方法
self.blitBullet()
# 调用渲染敌方子弹列表的方法
self.blitEnemyBullet()
# 调用展示爆炸效果的方法
self.displayExplodes()
time.sleep(0.02)
_display.update() # 窗口的刷新
def creatMyTank(self):
"""创建我方坦克"""
MainGame.TANK_P1 = MyTank(MainGame.SCREEN_WIDTH // 2, MainGame.SCREEN_HEIGHT - 70)
def creatEnemyTank(self):
"""创建敌方坦克"""
top = 100
for i in range(MainGame.EnemyTank_count):
left = random.randint(1, 7) # 每次都随机生成一个left值
speed = random.randint(2, 4)
eTank = EnemyTank(left * 100, top, speed)
MainGame.EnemyTank_list.append(eTank)
def creatWalls(self):
"""创建墙壁"""
for i in range(1, 10):
wall = Wall(100 * i, 260)
MainGame.Wall_list.append(wall)
def blitWalls(self):
"""将墙壁加入到窗口中"""
for wall in MainGame.Wall_list:
if wall.live:
wall.displayWall()
else:
MainGame.Wall_list.remove(wall)
def blitEnemyTank(self):
"""将敌方坦克加入到窗口中"""
for eTank in MainGame.EnemyTank_list:
if eTank.live:
eTank.displayTank()
eTank.randMove() # 敌方坦克移动的随机方法
eTank.hitWalls() # 调用敌方坦克与墙壁的碰撞方法
eTank.hitMyTank() # 调用敌方坦克与我方坦克碰撞的方法
eBullet = eTank.shot() # 调用敌方坦克的射击
if eBullet: # 如果子弹为None,不加入到列表中
MainGame.Eneny_bullet_list.append(eBullet) # 将子弹存储到敌方子弹列表中
else:
MainGame.EnemyTank_list.remove(eTank)
def blitBullet(self):
"""将我方子弹加入到窗口中"""
for bullet in MainGame.Bullet_list:
# 如果子弹还活着,绘制出来,否则,直接从列表中删除子弹
if bullet.live:
bullet.displayBullet()
# 让子弹移动
bullet.bulletMove()
# 调用我方子弹与敌方坦克碰撞的方法
bullet.hitEnemyTank()
# 调用判断我方子弹是否碰撞到墙壁的方法
bullet.hitWalls()
else:
MainGame.Bullet_list.remove(bullet)
def blitEnemyBullet(self):
"""将敌方子弹加入到窗口中"""
for eBullet in MainGame.Eneny_bullet_list:
# 如果子弹还活着,绘制出来,否则,直接从列表中删除子弹
if eBullet.live:
eBullet.displayBullet()
# 让子弹移动
eBullet.bulletMove()
# 调用判断敌方子弹是否碰撞到墙壁的方法
eBullet.hitWalls()
if MainGame.TANK_P1 and MainGame.TANK_P1.live:
eBullet.hitMyTank() # 调用敌方子弹与我方坦克碰撞的方法
else:
MainGame.Eneny_bullet_list.remove(eBullet)
def displayExplodes(self):
"""展示爆炸效果列表"""
for explode in MainGame.Explode_list:
if explode.live:
explode.displayExplode()
else:
MainGame.Explode_list.remove(explode)
def getEvent(self):
"""获取程序运行期间所有的鼠标和键盘事件"""
eventList = pygame.event.get() # 获取所有的事件
# 对事件进行判断处理(1.点击鼠标关闭按钮 2.按下键盘上的某个按键)
for event in eventList:
# 判断event.type是否为QUIT,如果是,直接调用程序结束方法
if event.type == pygame.QUIT:
self.endGame()
# 判断事件是否为键盘按键操作,如果是,继续判断按键是哪一个按键,并进行对应的处理
if event.type == pygame.KEYDOWN:
# 点击ESC按键让我方坦克重生
if event.key == pygame.K_ESCAPE and not MainGame.TANK_P1:
# 调用创建我方坦克的方法
self.creatMyTank()
if MainGame.TANK_P1 and MainGame.TANK_P1.live:
# 具体是哪个按键的处理
if event.key == pygame.K_LEFT:
print("坦克向左调头,移动")
# 修改坦克方向
MainGame.TANK_P1.direction = 'L'
MainGame.TANK_P1.stop = False
# 完成移动操作(调用坦克的移动方法)
# MainGame.TANK_P1.move()
elif event.key == pygame.K_RIGHT:
print("坦克向右调头,移动")
# 修改坦克方向
MainGame.TANK_P1.direction = 'R'
MainGame.TANK_P1.stop = False
# 完成移动操作(调用坦克的移动方法)
# MainGame.TANK_P1.move()
elif event.key == pygame.K_UP:
print("坦克向上调头,移动")
# 修改坦克方向
MainGame.TANK_P1.direction = 'U'
MainGame.TANK_P1.stop = False
# 完成移动操作(调用坦克的移动方法)
# MainGame.TANK_P1.move()
elif event.key == pygame.K_DOWN:
print("坦克向下调头,移动")
# 修改坦克方向
MainGame.TANK_P1.direction = 'D'
MainGame.TANK_P1.stop = False
# 完成移动操作(调用坦克的移动方法)
# MainGame.TANK_P1.move()
elif event.key == pygame.K_SPACE:
print("发射子弹")
if len(MainGame.Bullet_list) < 3: