Python实战_坦克大战游戏

1,243 阅读3分钟

1.pycharm游戏引擎安装

340.png

2.需求分析

341.png

342.png

343.png

3.主逻辑

344.png

1.1 开始游戏

(1)借助游戏引擎文档,加载游戏窗口

网址:www.pygame.org/docs/

346.png

347.png 颜色引用文档

349.png

游戏窗口运行结果 348.png

(2)事件处理,关闭游戏窗口,坦克移动方向按键相应

350.png

351.png

事件处理官方文档 352.png

356.png

353.png

354.png

键盘操作,按上下左右键,程序的运行结果(坦克上下左右调头移动) 355.png

1.2 结束游戏

345.png

1.3 敌方坦克剩余数量的文字提示

文字格式,颜色等其实是在画布上完成,只需要把画布贴在游戏窗口上即可

357.png

358.png

359.png

360.png

游戏加载窗口(运行结果) 361.png

1.4 加载我方坦克

方向,图片属性

坦克四个方向,分别代表不同的4张图片,把这些图片按照关键字放在字典中

362.png

363.png

添加图片方法,以及图片参数 364.png

365.png

366.png

367.png

368.png

运行结果(效果图)

369.png

1.5 我方坦克调头并且移动

if event.type == pygame.KEYDOWN:
    #具体是哪一个按键的处理
    if event.key == pygame.K_LEFT:
        print("坦克向左调头,移动")
        #修改坦克方向
        MainGame.TANK_P1.direction = 'L'
        #完成移动操作(调用坦克的移动方法)
        MainGame.TANK_P1.move()
    elif event.key == pygame.K_RIGHT:
        print("坦克向右调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'R'
        # 完成移动操作(调用坦克的移动方法)
        MainGame.TANK_P1.move()
    elif event.key == pygame.K_UP:
        print("坦克向上调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'U'
        # 完成移动操作(调用坦克的移动方法)
        MainGame.TANK_P1.move()
    elif event.key == pygame.K_DOWN:
        print("坦克向下调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'D'
        # 完成移动操作(调用坦克的移动方法)
        MainGame.TANK_P1.move()
#坦克移动方法
def move(self):
    #坦克向左移动,left值减小
    if self.direction == 'L':
        self.rect.left -= self.speed
    # 坦克向右移动,left值增加
    elif self.direction == 'R':
        self.rect.left += self.speed
    # 坦克向上移动,top值减少
    elif self.direction == 'U':
        self.rect.top -= self.speed
    # 坦克向下移动,top值增加
    elif self.direction == 'D':
        self.rect.top += self.speed

向右移动运行结果

372.png

1.6 我方坦克的边界化处理

游戏引擎中默认坦克方向向左时,左上方的点代表坦克

即让坦克不能出游戏窗口

def move(self):
    #坦克向左移动,left值减小
    if self.direction == 'L':
        # left值>0时,left值才减小,即坦克才移动
        if self.rect.left > 0:
            self.rect.left -= self.speed
    # 坦克向右移动,left值增加
    elif self.direction == 'R':
        # left值+坦克长度<窗口长度时,left值才增加,即坦克才移动
        if self.rect.left +self.rect.height < MainGame.SCREEN_WIDTH:
            self.rect.left += self.speed
    # 坦克向上移动,top值减少
    elif self.direction == 'U':
        if self.rect.top > 0:
            self.rect.top -= self.speed
    # 坦克向下移动,top值增加
    elif self.direction == 'D':
        if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT:
            self.rect.top += self.speed

1.7 坦克移动开关

373.png 按下按键,坦克持续移动,松开按键,停止移动,并在移动过程中发射子弹

if event.type == pygame.KEYDOWN:
    #具体是哪一个按键的处理
    if event.key == pygame.K_LEFT:
        print("坦克向左调头,移动")
        #修改坦克方向
        MainGame.TANK_P1.direction = 'L'
        MainGame.TANK_P1.stop = False
    elif event.key == pygame.K_RIGHT:
        print("坦克向右调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'R'
        MainGame.TANK_P1.stop = False
    elif event.key == pygame.K_UP:
        print("坦克向上调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'U'
        MainGame.TANK_P1.stop = False
    elif event.key == pygame.K_DOWN:
        print("坦克向下调头,移动")
        # 修改坦克方向
        MainGame.TANK_P1.direction = 'D'
        MainGame.TANK_P1.stop = False
    elif event.key == pygame.K_SPACE:
        print("坦克发射子弹")
if event.type == pygame.KEYUP:
    #松开的如果是方向键,才更改移动开关状态
    if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
        #修改坦克的移动状态
        MainGame.TANK_P1.stop = True

处理坦克的移动速度

time.sleep(0.02)

2. 加载敌方坦克

2.1 随机生成敌方坦克,并加加载在窗口

374.png

主要代码

class EnemyTank(Tank):
    #敌方坦克继承于坦克
    def __init__(self,left,top,speed):
        self.images = {
            'U': pygame.image.load('img/敌方坦克_U.png'),
            'D': pygame.image.load('img/敌方坦克D.png'),
            'L': pygame.image.load('img/敌方坦克_L.png'),
            'R': pygame.image.load('img/敌方坦克_R.png')
        }
        self.direction = self.randDirection()
        self.image = self.images[self.direction]
        # 坦克所在区域 Rect->
        self.rect = self.image.get_rect()
        # 指定坦克初始化位置 分别距x,y轴的位置
        self.rect.left = left
        self.rect.top = top
        # 新增速度属性
        self.speed = 5
        self.stop = True
    def randDirection(self):
        num = random.randint(1,4)
        if num ==1:
            return 'U'
        elif num ==2:
            return 'D'
        elif num ==3:
            return 'L'
        elif num ==4:
            return 'R'

运行结果

375.png

2.2 敌方坦克的随机移动

376.png 部分代码

def randMove(self):
    if self.step <=0:
        self.direction = self.randDirection()
        self.step = 50
    else:
        self.move()
        self.step -= 1

效果图

377.png

3.子弹类封装

3.1 子弹的位置

self.rect = self.image.get_rect()
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.top
elif self.direction =='D':
    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 == '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

3.2 子弹的移动

380.png

#子弹移动的方法
def bulletMove(self):
    if self.direction == 'U':
        if self.rect.top > 0:
            self.rect.top -=self.speed
        else:
            pass
    elif self.direction == 'D':
        if self.rect.top < MainGame.SCREEN_HEIGHT - self.rect.height:
            self.rect.top += self.speed
        else:
            pass
    elif self.direction == 'L':
        if self.rect.left > 0:
            self.rect.left -= self.speed
    elif self.direction == 'R':
        if self.rect.left < MainGame.SCREEN_WIDTH - self.rect.width:
            self.rect.left += self.speed
        else:
            pass

效果图

378.png

3.2 子弹消亡,控制子弹数量

379.png 重点代码

elif event.key == pygame.K_SPACE:
    print("发射子弹")
    if len(MainGame.Bullet_list) < 3:
        #产生一颗子弹
        m = Bullet(MainGame.TANK_P1)
        #将子弹加入到子弹列表
        MainGame.Bullet_list.append(m)
    else:
        print("子弹数量不足")
    print("当前屏幕中的子弹数量为:%d"%len(MainGame.Bullet_list))

4.敌方发射子弹

#将敌方子弹加入到窗口中
def blitEnemyBullet(self):
    for eBullet in MainGame.Enemy_bullet_list:
        # 如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
        if eBullet.live:
            eBullet.displayBullet()
            # 让子弹移动
            eBullet.bulletMove()
            #调用是否碰撞到墙壁的一个方法
            eBullet.hitWalls()
            if MainGame.TANK_P1 and MainGame.TANK_P1.live:
                eBullet.hitMyTank()
        else:
            MainGame.Enemy_bullet_list.remove(eBullet)

5.墙壁类

class Wall():
    def __init__(self,left,top):
        self.image = pygame.image.load('img/steels.gif')
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        #用来判断墙壁是否应该在窗口中展示
        self.live = True
        #用来记录墙壁的生命值
        self.hp = 3
    #展示墙壁的方法
    def displayWall(self):
        MainGame.window.blit(self.image,self.rect)

6.背景音乐类

class Music():
    def __init__(self,fileName):
        self.fileName = fileName
        #先初始化混合器
        pygame.mixer.init()
        pygame.mixer.music.load(self.fileName)
    #开始播放音乐
    def play(self):
        # pygame.mixer.music.play()
        pass

最终游戏效果

image.png