使用Pygame实现童年游戏《坦克大战》

项目代码详见:https://github.com/xiaozhou-alt/Tank-Domination



一、项目介绍

这是一个基于 PythonPygame 库开发的 2D 坦克大战游戏。游戏包含以下主要功能:

  • 玩家控制坦克移动和射击(方向键移动、空格键射击、Esc 复活吧我的坦克!)
  • 敌方AI坦克随机移动和攻击
  • 多种地图元素:墙壁、铁墙、河水、草丛
  • 爆炸效果和音效
  • 坦克碰撞检测和子弹碰撞检测

二、项目实现

1.文件夹结构

Tank-Domination/
├── tank.py        # 主游戏文件
├── img/           # 游戏资源文件夹
│   ├── *.gif      # 图片资源
│   └── *.wav      # 音效资源
└── demo.gif       # 游戏演示

2.代码实现

代码中使用了大量的 定义和图片贴图,若是读者还在为找不到游戏的图片和音效素材烦恼,那么小周建议可以看一看我的上一篇文章:《超简单!用Pygame实现贪吃蛇游戏!》,其中详细介绍的两个网站 OpenGameArtIconfont

这里我就只针对代码的实现来进行介绍:

1.主逻辑MainGame

class MainGame():
    window = None
    screen_width = 1000
    screen_height = 700
    my_tank = None
    enemytank_list = []
    bullet_list = []
    ebullet_list = []
    explode_list = []
    wall_list = []
    steelwall_list = []
    water_list = []
    grass_list = []

MainGame 类是游戏的核心控制器,负责管理整个游戏流程:

  • window 变量存储游戏主窗口对象
  • screen_widthscreen_height 定义游戏窗口尺寸为1000x700像素
  • my_tank 存储玩家坦克对象,enemytank_list 存储敌方坦克列表
  • bullet_listebullet_list 分别存储玩家和敌方子弹
  • explode_list 管理爆炸效果
  • wall_list 等存储各种地图元素。

2.游戏函数调用

def start_game(self):
    pd.init()
    MainGame.window = pd.set_mode([MainGame.screen_width, MainGame.screen_height])
    pd.set_caption('坦克大战 v1.0')
    self.create_mytank()
    self.create_enemytank()
    self.create_wall()
    self.create_steelwall()
    self.create_water()
    self.create_grass()

start_game方法是游戏的入口点:

  • 首先初始化 pygame 引擎( pd.init() ),然后创建游戏窗口并设置标题
  • create_mytank 创建玩家坦克,create_enemytank 生成敌方坦克等方法(这里函数命名还是非常浅显的,相信读者理解起来并不困难)创建各种地图元素。
  • 这些初始化工作为游戏运行做好准备,确保所有游戏对象在游戏开始前都已正确创建。

3.游戏主循环

while 1:
    time.sleep(0.02)
    MainGame.window.fill(color_black)
    self.get_Event()
    MainGame.window.blit(self.get_TextSurface('剩余敌方坦克%d辆' % len(MainGame.enemytank_list)), (20, 20))
    self.blit_wall()
    self.blit_steelwall()
    self.blit_water()
    self.blit_grass()
    if MainGame.my_tank.live:
        MainGame.my_tank.displayTank()
    self.blit_enemytank()

游戏主循环是游戏运行的核心,每帧执行以下操作:

  • time.sleep(0.02) 控制游戏帧率,使游戏运行更流畅
  • window.fill(color_black) 清空屏幕为黑色
  • get_Event() 处理用户输入
  • blit_TextSurface 显示剩余敌方坦克数量
  • blit_wall 等方法渲染各种地图元素
  • 最后检查玩家坦克是否存活并渲染坦克

这个循环持续运行,直到游戏结束。

4.Tank类与Bullet类

class Tank(BaseItem):
    def __init__(self, left, top):
        self.images = {
            'UP': pygame.image.load(r'img/p1tankU.gif'),
            'DOWN': pygame.image.load(r'img/p1tankD.gif'),
            'LEFT': pygame.image.load(r'img/p1tankL.gif'),
            'RIGHT': pygame.image.load(r'img/p1tankR.gif')
        }
        self.direction = 'UP'
        self.image = self.images[self.direction]
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.speed = 7
        self.stop = True
        self.live = True

Tank 类是坦克的基类,定义了坦克的基本属性和行为:

  • images 字典存储坦克四个方向的图片资源
  • direction 表示当前方向
  • image 是当前显示的图片
  • rect 是坦克的矩形区域用于碰撞检测
  • speed 控制坦克移动速度
  • stop 标志坦克是否停止移动
  • live 表示坦克是否存活

这个基类为我方坦克和敌方坦克提供了共同的基础功能(作为父类,我方和敌方坦克都继承于 Tank 类)

此处选用了游戏较为经典的黄绿坦克配色:

我方坦克:

我方坦克

敌方坦克:

在这里插入图片描述

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()
        if self.direction == 'UP':
            self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
            self.rect.top = tank.rect.top - self.rect.height
        self.speed = 13
        self.live = True

Bullet 类实现了子弹的逻辑:

  • image 加载子弹图片
  • direction 继承自发射坦克的方向

根据方向不同,子弹的初始位置也不同:

  • 向上发射时,子弹位于坦克正上方;其他方向类似
  • speed 控制子弹飞行速度
  • live 标志子弹是否有效(我设定为普通墙壁被子弹击打两次会消失,铁墙不会消失)

这个类处理了子弹的创建、移动和碰撞检测,是游戏战斗系统的核心部分

除了以上的两个类以外,其实游戏中涉及到的普通墙壁、铁墙、草丛、河流、爆炸效果和音乐实现较为简单,留给读者自己解读代码(不过小周也是有注释的哦~(´•ω•̥`) )

5.碰撞逻辑

碰撞作为这个游戏较为重要的逻辑实现,此处格外说明一下:

def tank_hit_walls(self):
    for wall in MainGame.wall_list:
        if pygame.sprite.collide_rect(self, wall):
            self.stay()

def bullet_move(self):
    if self.direction == 'UP':
        if self.rect.top > 0:
            self.rect.top -= self.speed
        else:
            self.live = False

游戏实现了多种碰撞检测:

  • tank_hit_walls 检测坦克与墙壁的碰撞
  • 使用 pygamecollide_rect 方法进行矩形碰撞检测
  • 如果碰撞则调用 stay 方法恢复坦克位置
  • bullet_move 处理子弹移动和边界检测
  • 当子弹到达屏幕边缘时设置 live 为 False 使其消失

6.输入处理

def get_Event(self):
    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:
                MainGame.my_tank.direction = 'LEFT'
                MainGame.my_tank.stop = False
                MainGame.my_tank.move()
            elif event.key == pygame.K_SPACE:
                b = Bullet(MainGame.my_tank)
                if len(MainGame.bullet_list) < 3:
                    MainGame.bullet_list.append(b)

get_Event 方法处理玩家输入:

  • 检测 QUIT 事件(点击关闭按钮)来结束游戏,处理方向键控制坦克移动,空格键发射子弹
  • 方向键改变坦克方向并开始移动,空格键创建新子弹(最多3发)

三、结果展示

基于pygame实现童年游戏《坦克大战》

如果你喜欢我的文章,不妨给小周一个免费的点赞和关注吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值