"""
子弹的消亡
子弹的数量控制,避免内存溢出
"""
import pygame
from time import sleep
import random
# 设置通用属性
BG_COLOR = pygame.Color(0, 0, 0)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
TEXT_COLOR = pygame.Color(255, 0, 0)
class Tank:
"""
坦克类
"""
def display_tank(self) -> None:
"""
显示坦克
"""
# 获取最新坦克的朝向位置图片
self.image = self.images.get(self.direction)
MainGame.window.blit(self.image, self.rect)
def move(self) -> None:
"""
坦克的移动
"""
if self.direction == "L":
if self.rect.left > 0:
# 修改坦克的位置 按原距离 +-操作
self.rect.left = self.rect.left - self.speed
elif self.direction == "R":
if self.rect.left + self.rect.width < SCREEN_WIDTH:
self.rect.left = self.rect.left + self.speed
elif self.direction == "U":
if self.rect.top > 0:
self.rect.top = self.rect.top - self.speed
elif self.direction == "D":
if self.rect.top + self.rect.width < SCREEN_HEIGHT:
self.rect.top = self.rect.top + self.speed
def shot(self) -> None:
"""
坦克的射击
"""
pass
class MyTank(Tank):
"""
我方坦克类
"""
def __init__(self, left: int, top: int) -> None:
# 设置我方坦克的图片资源
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 = "U"
# 获取图片信息
self.image = self.images.get(self.direction)
# 获取图片的矩形
self.rect = self.image.get_rect()
# 设置我方坦克位置
self.rect.left = left
self.rect.top = top
# 设置移动速度
self.speed = 10
# 设置移动开关
self.remove = False
class EnemyTank(Tank):
"""
敌方坦克类
"""
def __init__(self, left, top, speed) -> None:
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.rand_direction()
# 获取图片信息
self.image = self.images.get(self.direction)
# 获取图片的矩形
self.rect = self.image.get_rect()
# 设置敌方坦克位置
self.rect.left = left
self.rect.top = top
# 设置移动速度
self.speed = speed
# 设置移动的步长
self.step = 20
def rand_direction(self) -> str:
"""
生成随机方向
"""
chice = random.randint(1, 4)
if chice == 1:
return "U"
elif chice == 2:
return "D"
elif chice == 3:
return "L"
elif chice == 4:
return "R"
def rand_move(self):
# 随机移动
if self.step <= 0:
# 如果小于0,更换方向
self.direction = self.rand_direction()
# 修改步长
self.step = 20
else:
self.move()
self.step -= 1
def shot(self):
"""
敌方坦克的射击
"""
num = random.randint(1, 100)
if num < 3:
return Bullet(self)
class Bullet:
"""
子弹类
"""
def __init__(self, tank) -> None:
# 加载图片
self.image = pygame.image.load("img\enemymissile.gif")
# 获取子弹的反向
self.direction = tank.direction
# 获取子弹图形
self.rect = self.image.get_rect()
# 设置子弹的位置
if self.direction == "L":
self.rect.left = tank.rect.left - self.rect.width
self.rect.top = tank.rect.top + tank.rect.height / 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.height / 2 - self.rect.width / 2
elif 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
# 设置子弹的速度
self.speed = 10
# 设置子弹的状态
self.live = True
def display_bullet(self) -> None:
"""
显示子弹
"""
MainGame.window.blit(self.image, self.rect)
def move(self) -> None:
"""
子弹的移动
"""
# 根据子弹生成的方向来移动
if 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 < SCREEN_WIDTH - self.rect.width:
self.rect.left += self.speed
else:
self.live = False
elif 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 < SCREEN_HEIGHT - self.rect.height:
self.rect.top += self.speed
else:
self.live = False
class Wall:
"""
墙壁类
"""
def __init__(self) -> None:
pass
def display_wall(self) -> None:
"""
显示墙壁
"""
pass
class Explode:
"""
爆炸类
"""
def __init__(self) -> None:
pass
def display_explode(self) -> None:
"""
显示爆炸效果
"""
pass
class Music:
"""
音效类
"""
def __init__(self) -> None:
pass
def play_music(self) -> None:
"""
播放音效
"""
pass
class MainGame:
"""
游戏主窗口类
"""
# 游戏主窗口对象
window = None
# 设置我方坦克
my_tank = None
# 存储敌方坦克的列表
enemy_tank_list = []
# 设置敌方的坦克数量
enemy_tank_count = 6
# 存储我方子弹的列表
my_bullet_list = []
# 存储敌方坦克的列表
enemy_bullet_list = []
def __init__(self) -> None:
pass
def start_game(self) -> None:
"""
开始游戏
"""
# 初始化游戏窗口
pygame.display.init()
# 创建一个窗口
MainGame.window = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
# 设置窗口标题
pygame.display.set_caption("坦克大战1.0")
# 创建一个我方坦克
MainGame.my_tank = MyTank(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 1.25)
# 创建敌方坦克
self.create_enemy_tank()
# 刷新窗口
while True:
sleep(0.02)
# 给窗口设置填充色
MainGame.window.fill(BG_COLOR)
# 增加提示文字
# 1.要增加文字内容
# num = 6
text = self.get_text_surface(f"敌方坦克剩余数量{MainGame.enemy_tank_count}")
# 2.如何把文字加上
MainGame.window.blit(text, (10, 10))
# 增加事件
self.get_event()
# 显示我方坦克
MainGame.my_tank.display_tank()
# 显示敌方坦克
self.display_enemy_tank()
# 显示敌方子弹
self.display_enemy_bullet()
# 移动坦克
if MainGame.my_tank.remove:
MainGame.my_tank.move()
# 显示我方子弹
self.display_my_bullet()
pygame.display.update()
def display_my_bullet(self) -> None:
"""
显示我方子弹
"""
for my_bullet in MainGame.my_bullet_list:
# 判断子弹是否存活
if my_bullet.live:
# 显示我方子弹
my_bullet.display_bullet()
# 移动我方子弹
my_bullet.move()
else:
# 从列表中移除
MainGame.my_bullet_list.remove(my_bullet)
def create_enemy_tank(self) -> None:
"""
创建敌方坦克
"""
self.enemy_top = 100
self.enemy_speed = 4
for i in range(self.enemy_tank_count):
# 生成坦克的位置
left = random.randint(0, 600)
# 创建坦克位置
e_tank = EnemyTank(left, self.enemy_top, self.enemy_speed)
# 将敌方坦克添加到列表中
self.enemy_tank_list.append(e_tank)
def display_enemy_tank(self) -> None:
"""
显示敌方坦克
"""
for e_tank in self.enemy_tank_list:
# 显示敌方坦克
e_tank.display_tank()
# 移动敌方坦克
e_tank.rand_move()
# 发射子弹
e_bullet = e_tank.shot()
# 判断是否有子弹
if e_bullet:
# 将子弹增加到列表中
MainGame.enemy_bullet_list.append(e_bullet)
def display_enemy_bullet(self) -> None:
"""
显示敌方子弹
"""
for e_bullet in MainGame.enemy_bullet_list:
# 显示子弹
if e_bullet.live:
# 如果子弹存活,显示子弹
e_bullet.display_bullet()
e_bullet.move()
else:
# 如果子弹不存活,从列表中移除
MainGame.enemy_bullet_list.remove(e_bullet)
def get_text_surface(self, text: str) -> None:
"""
获取文字的图片
"""
pygame.font.init()
# 获取可以使用的字体
# print(pygame.font.get_fonts())
# 创建字体
font = pygame.font.SysFont("kaiti", 18)
# 绘制文字信息
text_surface = font.render(text, True, TEXT_COLOR)
# 将绘制的文字信息返回
return text_surface
def get_event(self) -> None:
"""
获取事件
"""
# 获取所有事件
event_list = pygame.event.get()
# 遍历事件
for event in event_list:
# 判断事件,作出相应的处理
if event.type == pygame.QUIT:
# 关闭按钮
self.end_game()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("左")
# 修改方向
MainGame.my_tank.direction = "L"
# 修改坦克的移动的状态为 TRUE
MainGame.my_tank.remove = True
elif event.key == pygame.K_RIGHT:
print("右")
MainGame.my_tank.direction = "R"
MainGame.my_tank.remove = True
elif event.key == pygame.K_UP:
print("上")
MainGame.my_tank.direction = "U"
MainGame.my_tank.remove = True
elif event.key == pygame.K_DOWN:
print("下")
MainGame.my_tank.direction = "D"
MainGame.my_tank.remove = True
elif event.key == pygame.K_SPACE:
# 判断子弹是否上限
if len(MainGame.my_bullet_list) < 5:
# 发射子弹
print("发射子弹")
# 创建子弹
my_bullet = Bullet(MainGame.my_tank)
# 将子弹添加到列表中
MainGame.my_bullet_list.append(my_bullet)
if event.type == pygame.KEYUP and event.key in (
pygame.K_LEFT,
pygame.K_RIGHT,
pygame.K_UP,
pygame.K_DOWN,
):
# 修改坦克状态
MainGame.my_tank.remove = False
def end_game(self) -> None:
"""
结束游戏
"""
print("谢谢使用")
exit()
if __name__ == "__main__":
# 调用MainGame类中的start_game方法,开始游戏
MainGame().start_game()

在这里我不是很理解 e_bullet怎么可以调用 Bullet类的 显示方法和移动方法
我自己理解就是e_bullet的对象是 EnemyTank 继承Tank的方法, 但是这里用e_bullet调用display_bullet()和move() ,没发现e_bullet关联了 Bullet这个类