当前位置:   article > 正文

pygame--坦克大战(三)

pygame--坦克大战(三)

我方坦克发射子弹

添加显示子弹

  1. class Bullet:
  2. '''
  3. 子弹类
  4. '''
  5. def display_bullet(self) -> None:
  6. '''
  7. 显示子弹
  8. '''
  9. MainGame.window.blit(self.image,self.rect)

空格键产生子弹,并将子弹添加到子弹列表中

  1. class MainGame:
  2. '''
  3. 游戏主窗口类
  4. '''
  5. # 游戏主窗口对象
  6. window =None
  7. # 设置我放坦克
  8. my_tank = None
  9. # 存储敌方坦克的列表
  10. enemy_tank_list = []
  11. # 设置敌方坦克的数量
  12. enemy_tank_count = 6
  13. # 存储我方子弹的列表
  14. my_bullet_list = []
  15. def get_event(self) -> None:
  16. '''
  17. 获取事件
  18. '''
  19. # 获取所有事件
  20. event_list = pygame.event.get()
  21. # 遍历事件
  22. for event in event_list:
  23. # 判断是什么事件,然后做出相应的处理
  24. if event.type == pygame.QUIT:
  25. # 点击关闭按钮
  26. self.end_game()
  27. if event.type == pygame.KEYDOWN:
  28. # 按下键盘
  29. if event.key == pygame.K_LEFT:
  30. print('坦克向左移动')
  31. # 修改方向
  32. MainGame.my_tank.direction = 'L'
  33. # 修改坦克移动的状态
  34. MainGame.my_tank.remove = True
  35. elif event.key == pygame.K_RIGHT:
  36. print('坦克向右移动')
  37. # 修改方向
  38. MainGame.my_tank.direction = 'R'
  39. # 修改坦克移动的状态
  40. MainGame.my_tank.remove = True
  41. elif event.key == pygame.K_UP:
  42. print('坦克向上移动')
  43. # 修改方向
  44. MainGame.my_tank.direction = 'U'
  45. # 修改坦克移动的状态
  46. MainGame.my_tank.remove = True
  47. elif event.key == pygame.K_DOWN:
  48. # 修改方向
  49. MainGame.my_tank.direction = 'D'
  50. print('坦克向下移动')
  51. # 修改坦克移动的状态
  52. MainGame.my_tank.remove = True
  53. elif event.key == pygame.K_SPACE:
  54. # 发射子弹
  55. print('发射子弹')
  56. # 创建子弹
  57. m_bullet = Bullet(MainGame.my_tank)
  58. # 将子弹添加到列表中
  59. MainGame.my_bullet_list.append(m_bullet)
  60. if event.type == pygame.KEYUP and event.key in (pygame.K_LEFT,pygame.K_RIGHT,pygame.K_UP,pygame.K_DOWN):
  61. # 修改坦克移动的状态
  62. MainGame.my_tank.remove = False

将子弹添加到窗口

  1. def start_game(self) -> None:
  2. '''
  3. 开始游戏
  4. '''
  5. # 初始化游戏窗口
  6. pygame.display.init()
  7. # 创建一个窗口
  8. MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
  9. # 设置窗口标题
  10. pygame.display.set_caption('坦克大战1.0')
  11. # 创建一个我方 坦克
  12. MainGame.my_tank = MyTank(350,200)
  13. # 创建敌方坦克
  14. self.create_enemy_tank()
  15. # 刷新窗口
  16. while True:
  17. sleep(0.02)
  18. # 给窗口设置填充色
  19. MainGame.window.fill(BG_COLOR)
  20. # 增加提示文字
  21. # 1.要增加文字内容
  22. # num = 6
  23. text = self.get_text_surface(f'敌方坦克剩余数量{MainGame.enemy_tank_count}')
  24. # 2.如何把文字加上
  25. MainGame.window.blit(text,(10,10))
  26. # 增加事件
  27. self.get_event()
  28. # 显示 我方坦克
  29. MainGame.my_tank.display_tank()
  30. # 显示敌方坦克
  31. self.display_enemy_tank()
  32. # 移动坦克
  33. if MainGame.my_tank.remove:
  34. MainGame.my_tank.move()
  35. # 显示我方子弹
  36. self.display_my_bullet()
  37. pygame.display.update()

我方子弹移动

  1. #子弹的移动方法
  2. def move(self) -> None:
  3. '''
  4. 子弹的移动
  5. '''
  6. # 根据子弹生成的方向来的移动
  7. if self.direction == "L":
  8. # 判断子弹是否超出屏幕
  9. if self.rect.left > 0:
  10. self.rect.left -= self.speed
  11. elif self.direction == "R":
  12. # 判断子弹是否超出屏幕
  13. if self.rect.left + self.rect.width < SCREEN_WIDTH:
  14. self.rect.left += self.speed
  15. elif self.direction == "U":
  16. # 判断子弹是否超出屏幕
  17. if self.rect.top > 0:
  18. self.rect.top -= self.speed
  19. elif self.direction == "D":
  20. # 判断子弹是否超出屏幕
  21. if self.rect.top + self.rect.height < SCREEN_HEIGHT:
  22. self.rect.top += self.speed

修改MainGame类,显示子弹方法

  1. def display_my_bullet(self) -> None:
  2. '''
  3. 显示我方子弹
  4. '''
  5. for my_bullet in MainGame.my_bullet_list:
  6. # 显示我方子弹
  7. my_bullet.display_bullet()
  8. # 移动我方子弹
  9. my_bullet.move()

子弹的消亡与数量控制

修改子弹类,创建live属性,与根据移动位置修改live状态

  1. class Bullet:
  2. '''
  3. 子弹类
  4. '''
  5. def __init__(self,tank) -> None:
  6. # 设置子弹的状态
  7. self.live = True
  8. def move(self) -> None:
  9. '''
  10. 子弹的移动
  11. '''
  12. # 根据子弹生成的方向来的移动
  13. if self.direction == "L":
  14. # 判断子弹是否超出屏幕
  15. if self.rect.left > 0:
  16. self.rect.left -= self.speed
  17. else:
  18. self.live = False
  19. elif self.direction == "R":
  20. # 判断子弹是否超出屏幕
  21. if self.rect.left + self.rect.width < SCREEN_WIDTH:
  22. self.rect.left += self.speed
  23. else:
  24. self.live = False
  25. elif self.direction == "U":
  26. # 判断子弹是否超出屏幕
  27. if self.rect.top > 0:
  28. self.rect.top -= self.speed
  29. else:
  30. self.live = False
  31. elif self.direction == "D":
  32. # 判断子弹是否超出屏幕
  33. if self.rect.top + self.rect.height < SCREEN_HEIGHT:
  34. self.rect.top += self.speed
  35. else:
  36. self.live = False

修改MainGame类,修改显示子弹类,与事件监听

  1. def display_my_bullet(self) -> None:
  2. '''
  3. 显示我方子弹
  4. '''
  5. for my_bullet in MainGame.my_bullet_list:
  6. # 判断子弹是否存活
  7. if my_bullet.live:
  8. # 显示我方子弹
  9. my_bullet.display_bullet()
  10. # 移动我方子弹
  11. my_bullet.move()
  12. else:
  13. # 从列表中移除
  14. MainGame.my_bullet_list.remove(my_bullet)
  15. def get_event(self) -> None:
  16. '''
  17. 获取事件
  18. '''
  19. # 获取所有事件
  20. event_list = pygame.event.get()
  21. # 遍历事件
  22. for event in event_list:
  23. # 判断是什么事件,然后做出相应的处理
  24. if event.type == pygame.QUIT:
  25. # 点击关闭按钮
  26. self.end_game()
  27. if event.type == pygame.KEYDOWN:
  28. # 按下键盘
  29. if event.key == pygame.K_LEFT:
  30. print('坦克向左移动')
  31. # 修改方向
  32. MainGame.my_tank.direction = 'L'
  33. # 修改坦克移动的状态
  34. MainGame.my_tank.remove = True
  35. elif event.key == pygame.K_RIGHT:
  36. print('坦克向右移动')
  37. # 修改方向
  38. MainGame.my_tank.direction = 'R'
  39. # 修改坦克移动的状态
  40. MainGame.my_tank.remove = True
  41. elif event.key == pygame.K_UP:
  42. print('坦克向上移动')
  43. # 修改方向
  44. MainGame.my_tank.direction = 'U'
  45. # 修改坦克移动的状态
  46. MainGame.my_tank.remove = True
  47. elif event.key == pygame.K_DOWN:
  48. # 修改方向
  49. MainGame.my_tank.direction = 'D'
  50. print('坦克向下移动')
  51. # 修改坦克移动的状态
  52. MainGame.my_tank.remove = True
  53. elif event.key == pygame.K_SPACE:
  54. # 判断子弹是否上限
  55. if len(MainGame.my_bullet_list) < 5:
  56. # 发射子弹
  57. print('发射子弹')
  58. # 创建子弹
  59. m_bullet = Bullet(MainGame.my_tank)
  60. # 将子弹添加到列表中
  61. MainGame.my_bullet_list.append(m_bullet)
  62. if event.type == pygame.KEYUP and event.key in (pygame.K_LEFT,pygame.K_RIGHT,pygame.K_UP,pygame.K_DOWN):
  63. # 修改坦克移动的状态
  64. MainGame.my_tank.remove = False

敌方坦克随机发射子弹

实现发射子弹方法

  1. def shot(self):
  2. '''
  3. 敌方坦克的射击
  4. '''
  5. num = random.randint(1,100)
  6. if num < 5:
  7. return Bullet(self)

敌方坦克加入窗口后,发射子弹,并将子弹添加到敌方子弹列表中

  1. #将敌方坦克加入到窗口中
  2. def display_enemy_tank(self) -> None:
  3. '''
  4. 显示敌方坦克
  5. '''
  6. for e_tank in self.enemy_tank_list:
  7. # 显示敌方坦克
  8. e_tank.display_tank()
  9. # 移动敌方坦克
  10. e_tank.rand_move()
  11. # 发射子弹
  12. e_bullet = e_tank.shot()
  13. # 判断是否有子弹
  14. if e_bullet:
  15. # 将子弹增加到列表中
  16. MainGame.enemy_bullet_list.append(e_bullet)

将敌方发射的子弹添加到窗口

  1. def start_game(self) -> None:
  2. '''
  3. 开始游戏
  4. '''
  5. # 初始化游戏窗口
  6. pygame.display.init()
  7. # 创建一个窗口
  8. MainGame.window = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
  9. # 设置窗口标题
  10. pygame.display.set_caption('坦克大战1.0')
  11. # 创建一个我方 坦克
  12. MainGame.my_tank = MyTank(350,200)
  13. # 创建敌方坦克
  14. self.create_enemy_tank()
  15. # 刷新窗口
  16. while True:
  17. sleep(0.02)
  18. # 给窗口设置填充色
  19. MainGame.window.fill(BG_COLOR)
  20. # 增加提示文字
  21. # 1.要增加文字内容
  22. # num = 6
  23. text = self.get_text_surface(f'敌方坦克剩余数量{MainGame.enemy_tank_count}')
  24. # 2.如何把文字加上
  25. MainGame.window.blit(text,(10,10))
  26. # 增加事件
  27. self.get_event()
  28. # 显示 我方坦克
  29. MainGame.my_tank.display_tank()
  30. # 显示敌方坦克
  31. self.display_enemy_tank()
  32. # 移动坦克
  33. if MainGame.my_tank.remove:
  34. MainGame.my_tank.move()
  35. # 显示我方子弹
  36. self.display_my_bullet()
  37. # 显示敌方子弹
  38. self.display_enemy_bullet()
  39. pygame.display.update()

我方子弹与敌方坦克的碰撞检测

游戏开发中,通常把显示图像的对象叫做精灵Spire,精灵需要有两个属性,image要显示的图像,rect图像要显示在屏幕的位置。

在Pygame框架中,使用pygame. sprite模块中的内置函数可以实现碰撞检测。代码如下:

pygame.sprite.collide_rect(first, second) #返回布尔值

修改坦克类,增加是否存活状态

  1. class Tank:
  2. '''
  3. 坦克类
  4. '''
  5. def __init__(self) -> None:
  6. self.live = True

在子弹类中增加我方子弹碰撞敌方坦克的方法,如果发生碰撞,修改我方子弹及敌方坦克live属性的状态值。

  1. def hit_enemy_tank(self):
  2. for e_tank in MainGame.enemy_tank_list:
  3. # 判断子弹是否击中坦克
  4. if collide_rect(self,e_tank):
  5. # 修改子弹的状态
  6. self.live = False
  7. e_tank.live = False

在我方子弹移动后判断子弹是否与敌方坦克碰撞。

  1. def display_my_bullet(self) -> None:
  2. '''
  3. 显示我方子弹
  4. '''
  5. for my_bullet in MainGame.my_bullet_list:
  6. # 判断子弹是否存活
  7. if my_bullet.live:
  8. # 显示我方子弹
  9. my_bullet.display_bullet()
  10. # 移动我方子弹
  11. my_bullet.move()
  12. # 判断我方子弹是否击中敌方坦克
  13. my_bullet.hit_enemy_tank()
  14. else:
  15. # 从列表中移除
  16. MainGame.my_bullet_list.remove(my_bullet)

修改MainGame类敌方坦克显示逻辑,根据敌方坦克是否存活

  1. def display_enemy_tank(self) -> None:
  2. '''
  3. 显示敌方坦克
  4. '''
  5. for e_tank in self.enemy_tank_list:
  6. # 判断敌方坦克是否存活
  7. if e_tank.live:
  8. # 显示敌方坦克
  9. e_tank.display_tank()
  10. # 移动敌方坦克
  11. e_tank.rand_move()
  12. # 发射子弹
  13. e_bullet = e_tank.shot()
  14. # 判断是否有子弹
  15. if e_bullet:
  16. # 将子弹增加到列表中
  17. MainGame.enemy_bullet_list.append(e_bullet)
  18. else:
  19. # 从列表中移除
  20. self.enemy_tank_list.remove(e_tank)

爆炸效果

添加爆炸效果

初始化爆炸类

  1. def __init__(self,tank:Tank) -> None:
  2. # 加载爆炸效果的图片
  3. self.images = [
  4. pygame.image.load('./img/blast0.gif'),
  5. pygame.image.load('./img/blast1.gif'),
  6. pygame.image.load('./img/blast2.gif'),
  7. pygame.image.load('./img/blast3.gif'),
  8. pygame.image.load('./img/blast4.gif'),
  9. ]
  10. # 设置爆炸效果的位置
  11. self.rect = tank.rect
  12. # 设置爆炸效果的索引
  13. self.step = 0
  14. # 获取需要渲染的图像
  15. self.image = self.images[self.step]
  16. # 设置爆炸的状态
  17. self.live = True

展示爆炸效果。

  1. def display_explode(self) -> None:
  2. '''
  3. 显示爆炸效果
  4. '''
  5. # 判断当前爆照的效果是否播放完毕
  6. if self.step < len(self.images):
  7. # 获取当前爆炸效果的图像
  8. self.image = self.images[self.step]
  9. # 获取下一张爆炸效果的图像的索引
  10. self.step += 1
  11. # 绘制爆炸效果
  12. MainGame.window.blit(self.image,self.rect)
  13. else:
  14. # 初始化爆炸效果的索引
  15. self.step = 0
  16. # 设置爆炸效果的状态,代表爆炸过了
  17. self.live = False

在我方子弹碰撞敌方坦克的方法中,如果检测到碰撞,产生爆炸类,并将爆炸效果添加到爆炸列表。

  1. def hit_enemy_tank(self):
  2. for e_tank in MainGame.enemy_tank_list:
  3. # 判断子弹是否击中坦克
  4. if collide_rect(self,e_tank):
  5. # 爆炸效果
  6. explode = Explode(e_tank)
  7. MainGame.explode_list.append(explode)
  8. # 修改子弹的状态
  9. self.live = False
  10. e_tank.live = False

将爆炸效果添加到窗口。

  1. #新增方法: 展示爆炸效果列表
  2. def display_explode(self) -> None:
  3. '''
  4. 显示爆炸效果
  5. '''
  6. for explode in MainGame.explode_list:
  7. # 判断是否活着
  8. if explode.live:
  9. # 显示爆炸效果
  10. explode.display_explode()
  11. else:
  12. # 从列表中移除
  13. MainGame.explode_list.remove(explode)

敌方子弹与我方坦克碰撞检测

子弹类中,新增敌方子弹与我方坦克的碰撞。如果发生碰撞,修改敌方子弹、我方坦克的状态及产生爆炸效果。

  1. #新增敌方子弹与我方坦克的碰撞方法
  2. def hit_my_tank(self):
  3. # 判断我方坦克是否活着
  4. if MainGame.my_tank and MainGame.my_tank.live:
  5. # 判断字段是否击中我方坦克
  6. if collide_rect(self,MainGame.my_tank):
  7. # 爆炸效果
  8. explode = Explode(MainGame.my_tank)
  9. MainGame.explode_list.append(explode)
  10. # 修改子弹的状态
  11. self.live = False
  12. MainGame.my_tank.live = False

添加敌方子弹到窗口中时候,如果子弹还活着,显示子弹、调用子弹移动并判断敌方子弹是否与我方坦克发生碰撞。

  1. #将敌方子弹加入到窗口中
  2. def display_my_bullet(self) -> None:
  3. '''
  4. 显示我方子弹
  5. '''
  6. for my_bullet in MainGame.my_bullet_list:
  7. # 判断子弹是否存活
  8. if my_bullet.live:
  9. # 显示我方子弹
  10. my_bullet.display_bullet()
  11. # 移动我方子弹
  12. my_bullet.move()
  13. # 判断我方子弹是否击中敌方坦克
  14. my_bullet.hit_enemy_tank()
  15. else:
  16. # 从列表中移除
  17. MainGame.my_bullet_list.remove(my_bullet)

我方坦克无线重生

坦克大战游戏中一般我方坦克有重生的功能,当按下键盘的Esc键时候,让我方坦克重生。重生指的就是重新创建我方坦克。

  1. def create_my_tank(self) -> None:
  2. '''
  3. 创建我方坦克
  4. '''
  5. MainGame.my_tank = MyTank(350,200)
  6. #获取事件
  7. def getEvent(self):
  8. #获取所有事件
  9. eventList= pygame.event.get()
  10. #遍历事件
  11. for event in event_list:
  12. if event.type == pygame.KEYDOWN:
  13. # 如果我方坦克死亡,按下esc键,重新生成我方坦克
  14. if not MainGame.my_tank and event.key == pygame.K_ESCAPE:
  15. print('重新生成我方坦克')
  16. # 按下esc键,重新生成我方坦克
  17. self.create_my_tank()

加载墙壁

初始化墙壁类

  1. class Wall:
  2. '''
  3. 墙壁类
  4. '''
  5. def __init__(self,left,top) -> None:
  6. # 加载图片
  7. self.image = pygame.image.load('./img/steels.gif')
  8. # 获取墙壁的图形
  9. self.rect = self.image.get_rect()
  10. # 设置墙壁的位置
  11. self.rect.left = left
  12. self.rect.top = top
  13. def display_wall(self) -> None:
  14. '''
  15. 显示墙壁
  16. '''
  17. MainGame.window.blit(self.image,self.rect)

创建墙壁

  1. def create_wall(self) -> None:
  2. '''
  3. 创建墙壁
  4. '''
  5. top = 200
  6. for i in range(6):
  7. # 创建墙壁
  8. wall = Wall(i*128,top)
  9. # 添加到墙壁列表中
  10. MainGame.wall_list.append(wall)

墙壁加入到窗口

  1. def display_wall(self) -> None:
  2. '''
  3. 显示墙壁
  4. '''
  5. for wall in MainGame.wall_list:
  6. # 显示墙壁
  7. wall.display_wall()

子弹不能穿墙

子弹不能穿墙指子弹碰到墙壁后消失。因此,子弹类中新增方法,子弹与墙壁的碰撞,如果子弹与墙壁碰撞,修改子弹的状态。另外还需要将墙壁的生命值减少,如果墙壁的生命值小于等于零时候修改墙壁的状态。

  1. #新增子弹与墙壁的碰撞
  2. def hit_wall(self):
  3. '''
  4. 碰撞墙壁
  5. '''
  6. for wall in MainGame.wall_list:
  7. # 判断是否碰撞
  8. if collide_rect(self,wall):
  9. # 修改子弹的状态
  10. self.live = False

设置我方与敌方坦克子弹移动时,增加碰撞检测

  1. def display_enemy_bullet(self) -> None:
  2. '''
  3. 显示敌方子弹
  4. '''
  5. for e_bullet in MainGame.enemy_bullet_list:
  6. # 显示子弹
  7. if e_bullet.live:
  8. # 如果子弹存活,显示子弹
  9. e_bullet.display_bullet()
  10. e_bullet.move()
  11. # 判断是否击中我方坦克
  12. e_bullet.hit_my_tank()
  13. # 判断是否击中墙壁
  14. e_bullet.hit_wall()
  15. else:
  16. # 如果子弹不存活,从列表中移除
  17. MainGame.enemy_bullet_list.remove(e_bullet)
  18. def display_my_bullet(self) -> None:
  19. '''
  20. 显示我方子弹
  21. '''
  22. for my_bullet in MainGame.my_bullet_list:
  23. # 判断子弹是否存活
  24. if my_bullet.live:
  25. # 显示我方子弹
  26. my_bullet.display_bullet()
  27. # 移动我方子弹
  28. my_bullet.move()
  29. # 判断我方子弹是否击中敌方坦克
  30. my_bullet.hit_enemy_tank()
  31. # 判断我方子弹是否击中墙壁
  32. my_bullet.hit_wall()
  33. else:
  34. # 从列表中移除
  35. MainGame.my_bullet_list.remove(my_bullet)

设置墙壁耐久

设置墙壁生命值与存活状态

  1. class Wall:
  2. '''
  3. 墙壁类
  4. '''
  5. def __init__(self,left,top) -> None:
  6. # 加载图片
  7. self.image = pygame.image.load('./img/steels.gif')
  8. # 获取墙壁的图形
  9. self.rect = self.image.get_rect()
  10. # 设置墙壁的位置
  11. self.rect.left = left
  12. self.rect.top = top
  13. # 设置墙壁的生命值
  14. self.hp = 3
  15. # 设置墙壁的状态
  16. self.live = True

修改子弹碰撞墙壁逻辑

  1. class Bullet:
  2. '''
  3. 子弹类
  4. '''
  5. def hit_wall(self):
  6. '''
  7. 碰撞墙壁
  8. '''
  9. for wall in MainGame.wall_list:
  10. # 判断是否碰撞
  11. if collide_rect(self,wall):
  12. # 修改子弹的状态
  13. self.live = False
  14. # 修改墙壁的生命值
  15. wall.hp -= 1
  16. # 判断墙壁是否依然显示
  17. if wall.hp <= 0:
  18. wall.live = False

修改显示墙壁逻辑

  1. def display_wall(self) -> None:
  2. '''
  3. 显示墙壁
  4. '''
  5. for wall in MainGame.wall_list:
  6. if wall.live:
  7. # 显示墙壁
  8. wall.display_wall()
  9. else:
  10. # 从列表中移除
  11. MainGame.wall_list.remove(wall)

坦克不能穿墙功能

坦克不能穿墙指坦克一旦碰到墙壁则不能再移动,也就是需要修改坦克的坐标为移动之前的。因此在坦克类中新增属性oldLeft、oldTop记录移动之前的坐标,新增stay()、hitWalls()方法。

  1. class Tank:
  2. '''
  3. 坦克类
  4. '''
  5. def __init__(self) -> None:
  6. self.live = True
  7. # 记录坦克原来的位置
  8. self.old_left = 0
  9. self.old_top = 0
  10. def move(self) -> None:
  11. '''
  12. 坦克的移动
  13. '''
  14. # 记录坦克原来的位置,为了方便还原碰撞后的位置
  15. self.old_left = self.rect.left
  16. self.old_top = self.rect.top
  17. if self.direction == "L":
  18. # 判断坦克的位置是否已左边界
  19. if self.rect.left > 0:
  20. # 修改坦克的位置 离左边的距离 - 操作
  21. self.rect.left = self.rect.left - self.speed
  22. elif self.direction == "R":
  23. # 判断坦克的位置是否已右边界
  24. if self.rect.left + self.rect.width < SCREEN_WIDTH:
  25. # 修改坦克的位置 离左边的距离 + 操作
  26. self.rect.left = self.rect.left + self.speed
  27. elif self.direction == "U":
  28. # 判断坦克的位置是否已上边界
  29. if self.rect.top > 0:
  30. # 修改坦克的位置 离上边的距离 - 操作
  31. self.rect.top = self.rect.top - self.speed
  32. elif self.direction == "D":
  33. # 判断坦克的位置是否已下边界
  34. if self.rect.top + self.rect.height < SCREEN_HEIGHT:
  35. # 修改坦克的位置 离上边的距离 + 操作
  36. self.rect.top = self.rect.top + self.speed
  37. def tank_hit_wall(self) -> None:
  38. '''
  39. 坦克和墙壁的碰撞
  40. '''
  41. for wall in MainGame.wall_list:
  42. # 检测当前坦克是否能和墙壁发生碰撞
  43. if pygame.sprite.collide_rect(self,wall):
  44. # 将位置还原到碰撞前的位置
  45. self.rect.left = self.old_left
  46. self.rect.top = self.old_top

坦克移动时,检测是否碰撞

  1. def display_enemy_tank(self) -> None:
  2. '''
  3. 显示敌方坦克
  4. '''
  5. for e_tank in self.enemy_tank_list:
  6. # 判断敌方坦克是否存活
  7. if e_tank.live:
  8. # 显示敌方坦克
  9. e_tank.display_tank()
  10. # 移动敌方坦克
  11. e_tank.rand_move()
  12. # 判断是否与墙壁发生碰撞
  13. e_tank.tank_hit_wall()
  14. # 发射子弹
  15. e_bullet = e_tank.shot()
  16. # 判断是否有子弹
  17. if e_bullet:
  18. # 将子弹增加到列表中
  19. MainGame.enemy_bullet_list.append(e_bullet)
  20. else:
  21. # 从列表中移除
  22. self.enemy_tank_list.remove(e_tank)
  1. # 判断我方坦克是否死亡
  2. if MainGame.my_tank and MainGame.my_tank.live:
  3. # 移动坦克
  4. if MainGame.my_tank.remove:
  5. MainGame.my_tank.move()
  6. # 检测我方坦克是否与墙壁发生碰撞
  7. MainGame.my_tank.tank_hit_wall()

双方坦克之间的碰撞检测

如果我方坦克碰撞到敌方坦克,则我方坦克再不能继续移动。同理如果敌方坦克碰撞到我方坦克也不能继续移动。

在坦克类中新增坦克与坦克碰撞的检测方法

  1. class Tank:
  2. def tank_collide_tank(self,tank):
  3. '''
  4. 检测2个坦克是否碰撞
  5. '''
  6. # 判断是否都存活
  7. if self.live and tank.live:
  8. if pygame.sprite.collide_rect(self,tank):
  9. # 将位置还原到碰撞前的位置
  10. self.rect.left = self.old_left
  11. self.rect.top = self.old_top

我方坦克移动后,调用是否与敌方坦克发生碰撞。

  1. #根据坦克的开关状态调用坦克的移动方法
  2. if MainGame.TANK_P1 and not MainGame.TANK_P1.stop:
  3. MainGame.TANK_P1.move()
  4. #调用碰撞墙壁的方法
  5. MainGame.TANK_P1.hitWalls()
  6. MainGame.TANK_P1.hitEnemyTank()

在敌方坦克类中,新增敌方坦克碰撞我方坦克的方法。

  1. def hitMyTank(self):
  2. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  3. if pygame.sprite.collide_rect(self, MainGame.TANK_P1):
  4. # 让敌方坦克停下来 stay()
  5. self.stay()

敌方坦克添加到窗口时候,调用是否与我方坦克碰撞。

  1. #将敌方坦克加入到窗口中
  2. def blitEnemyTank(self):
  3. for eTank in MainGame.EnemyTank_list:
  4. if eTank.live:
  5. eTank.displayTank()
  6. # 坦克移动的方法
  7. eTank.randMove()
  8. #调用敌方坦克与墙壁的碰撞方法
  9. eTank.hitWalls()
  10. #敌方坦克是否撞到我方坦克
  11. eTank.hitMyTank()
  12. # 调用敌方坦克的射击
  13. eBullet = eTank.shot()
  14. # 如果子弹为None。不加入到列表
  15. if eBullet:
  16. # 将子弹存储敌方子弹列表
  17. MainGame.Enemy_bullet_list.append(eBullet)
  18. else:
  19. MainGame.EnemyTank_list.remove(eTank)

音效处理

music是pygame中控制流音频的pygame模块,音乐模块与pygame.mixer紧密相连, pygame.mixer是一个用来处理声音的模块,其含义为“混音器”。游戏中对声音的处理一般包括制造声音和播放声音两部分。

初始化混合器

pygame.mixer.init()

加载一个播放音乐的文件

pygame.mixer.music.load()

开始播放音乐流

pygame.mixer.music.play()

初始化音效类

  1. class Music():
  2. def __init__(self,fileName):
  3. self.fileName = fileName
  4. #先初始化混合器
  5. pygame.mixer.init()
  6. pygame.mixer.music.load(self.fileName)
  7. #开始播放音乐
  8. def play(self):
  9. pygame.mixer.music.play()

创建坦克时,添加音效。

  1. #创建我方坦克的方法
  2. def creatMyTank(self):
  3. # 创建我方坦克
  4. MainGame.TANK_P1 = MyTank(400, 300)
  5. #创建音乐对象
  6. music = Music('img/start.wav')
  7. #调用播放音乐方法
  8. music.play()

我方坦克发射子弹时,添加音效。

  1. elif event.key == pygame.K_SPACE:
  2. print("发射子弹")
  3. if len(MainGame.Bullet_list) < 3:
  4. # 产生一颗子弹
  5. m = Bullet(MainGame.TANK_P1)
  6. # 将子弹加入到子弹列表
  7. MainGame.Bullet_list.append(m)
  8. music = Music('img/fire.wav')
  9. music.play()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/443332
推荐阅读
相关标签
  

闽ICP备14008679号