学习 Python 之 Pygame 开发坦克大战

Posted _DiMinisH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习 Python 之 Pygame 开发坦克大战相关的知识,希望对你有一定的参考价值。

学习 Python 之 Pygame 开发坦克大战(三)

继续编写坦克大战

我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材

素材链接:百度网盘
链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz
提取码:tkdz

那我们就继续编写坦克大战吧

1. 实现敌方坦克与我方坦克间的碰撞

由于已经完成了屏幕中出现敌方和我方坦克,现在的问题就是如果我方坦克碰到了敌方坦克,应该是走不动的,即不能穿模

在敌方坦克类和我方坦克类中加入两个属性,用来记录上一次的位置,如果是你用的是继承,那么在父类加入

# 碰撞前的坐标
self.prvX = self.rect.left
self.prvY = self.rect.top

修改我方坦克类move()函数

def move(self):
    if self.accumulation >= 1:
        self.accumulation = 0
        # 记录上一次的位置
        self.prvX = self.rect.left
        self.prvY = self.rect.top
        if self.direction == 'LEFT':
            if self.rect.left > 0:
                self.rect.left -= self.speed
        elif self.direction == 'UP':
            if self.rect.top > 0:
                self.rect.top -= self.speed
        elif self.direction == 'DOWN':
            if self.rect.top < 555:
                self.rect.top += self.speed
        elif self.direction == 'RIGHT':
            if self.rect.left < 855:
                self.rect.left += self.speed
    else:
        self.accumulation += 0.20

修改敌方坦克类move()函数

def move(self):
    """
    新增步数变量, 当坦克移动时, 步数进行减少, 当步数小于等于0的时候, 修改地方坦克的方向
    :return: None
    """
    if self.stop:
        if self.step <= 0:
            self.direction = self.randDirection()
            self.step = 30
        else:
            if self.accumulationMax >= 1:
                self.accumulationMax = 0
                # 记录上一次的位置
                self.prvX = self.rect.left
                self.prvY = self.rect.top
                if self.direction == 'LEFT':
                    if self.rect.left > 0:
                        self.rect.left -= self.speed
                elif self.direction == 'UP':
                    if self.rect.top > 0:
                        self.rect.top -= self.speed
                elif self.direction == 'DOWN':
                    if self.rect.top < 555:
                        self.rect.top += self.speed
                elif self.direction == 'RIGHT':
                    if self.rect.left < 855:
                        self.rect.left += self.speed
                self.step -= 1
            else:
                self.accumulationMax += self.accumulation

加入碰撞检测函数
在两个类中都加入

pygame.sprite.collide_rect()函数用来检测物体碰撞,该物体必须继承pygame.sprite.Sprite类

def collideEnemyTank(self, enemyTankList):
    # 遍历全部敌方坦克,检查有没有碰撞
    for enemyTank in enemyTankList:
        if pygame.sprite.collide_rect(self, enemyTank):
            # 如果碰撞了,就保持原来的位置
            self.rect.left = self.prvX
            self.rect.top = self.prvY
def collidePlayerTank(self, playerTank):
    # 遍历全部敌方坦克,检查有没有碰撞
    if pygame.sprite.collide_rect(self, playerTank):
        # 如果碰撞了,就保持原来的位置
        self.rect.left = self.prvX
        self.rect.top = self.prvY

在坦克移动下面调用该函数

while 1:
    # 设置背景颜色
    MainGame.window.fill(BACKGROUND_COLOR)

    # 获取窗口事件
    self.getPlayingModeEvent()

    # 显示我方坦克
    MainGame.playerTank.draw(MainGame.window)

    # 我方坦克移动
    if not MainGame.playerTank.stop:
        MainGame.playerTank.move()
        MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)

    # 显示我方坦克子弹
    self.drawPlayerBullet(MainGame.playerBulletList)

    # 展示敌方坦克
    self.drawEnemyTank()

    # 展示敌方坦克子弹
    self.drawEnemyBullet()

    # 更新窗口
    pygame.display.update()
# 遍历坦克列表,展示坦克并且移动
for tank in MainGame.enemyTankList:
    # 坦克还有生命值
    if tank.life > 0:
        tank.draw(MainGame.window)
        tank.move()
        tank.collidePlayerTank(MainGame.playerTank)
        bullet = tank.shot()
        if bullet is not None:
            MainGame.enemyTankBulletList.append(bullet)
    # 坦克生命值为0,就从列表中剔除
    else:
        MainGame.enemyTankCurrentCount -= 1
        MainGame.enemyTankList.remove(tank)

完整的我方坦克代码

import pygame as pg
import pygame.image
from ParentObject import ParentObject
from Teach.Bullet import Bullet


class PlayerTank(ParentObject):
    def __init__(self, x, y, order, amour):
        """

        :param x: 坦克横坐标
        :param y: 坦克纵坐标
        :param order: 玩家坦克序号,1表示一号玩家,2表示二号玩家
        :param amour: 坦克初始护甲
        """
        super().__init__()
        self.images = []
        if order == 1:
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP1.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN1.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT1.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT1.png')
            )
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP2.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN2.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT2.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT2.png')
            )
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP3.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN3.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT3.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT3.png')
            )
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP4.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN4.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT4.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT4.png')
            )
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP5.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN5.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT5.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT5.png')
            )
            self.images.append(
                'UP': pygame.image.load('../Image/Player1/45x45/UP6.png'),
                'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN6.png'),
                'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT6.png'),
                'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT6.png')
            )

        # 生命
        self.life = 3
        # 装甲
        self.armor = amour

        # 方向
        self.direction = 'UP'

        # 根据护甲选择坦克的样子
        self.image: pg.Surface = self.images[max(self.armor - 1, 0)][self.direction]
        self.rect = self.image.get_rect()
        self.rect.left = x
        self.rect.top = y

        # 速度
        self.accumulation: float = 0
        self.speed = 2
        # 移动开关
        self.stop = True
        # 重生
        self.isResurrecting = False
        # 碰撞前的坐标
        self.prvX = self.rect.left
        self.prvY = self.rect.top

        # 等级
        self.level = 1
        # 伤害
        self.damage = 1

    def move(self):
        if self.accumulation >= 1:
            self.accumulation = 0
            # 记录上一次的位置
            self.prvX = self.rect.left
            self.prvY = self.rect.top
            if self.direction == 'LEFT':
                if self.rect.left > 0:
                    self.rect.left -= self.speed
            elif self.direction == 'UP':
                if self.rect.top > 0:
                    self.rect.top -= self.speed
            elif self.direction == 'DOWN':
                if self.rect.top < 555:
                    self.rect.top += self.speed
            elif self.direction == 'RIGHT':
                if self.rect.left < 855:
                    self.rect.left += self.speed
        else:
            self.accumulation += 0.20


    def shot(self):
        return Bullet(self)

    def draw(self, window):
        # 坦克生命中为0,表示已经死亡,不再展示坦克
        if self.life <= 0:
            return
        # 获取展示的对象
        self.image = self.images[max(self.armor - 1, 0)][self.direction]
        # 画出图片
        window.blit(self.image, self.rect)

    def collideEnemyTank(self, enemyTankList):
        # 遍历全部敌方坦克,检查有没有碰撞
        for enemyTank in enemyTankList:
            if pygame.sprite.collide_rect(self, enemyTank):
                # 如果碰撞了,就保持原来的位置
                self.rect.left = self.prvX
                self.rect.top = self.prvY

完整的敌方坦克代码

import random
import pygame
import pygame.image

from ParentObject import ParentObject
from Bullet import Bullet


class EnemyTank(ParentObject):
    def __init__(self, x, y):
        super().__init__()
        types = [(1, 3), (2, 1), (3, 2), (4, 10)]
        # 随机产生一种坦克
        self.type = types[random.randint(0, len(types) - 1)]
        up = []
        down = []
        left = []
        right = []
        for i in range(1, self.type[1] + 1):
            up.append(
                pygame.image.load(
                    '../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank'+ str(self.type[0]) + 'Lv' + str(i) + '(UP).png'
                )
            )
            down.append(
                pygame.image.load(
                    '../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank'+ str(self.type[0]) + 'Lv' + str(i) + '(DOWN).png'
                )
            )
            left.append(
                pygame.image.load(
                    '../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank' + str(self.type[0]) + 'Lv' + str(
                        i) + '(LEFT).png'
                )
            )
            right.append(
                pygame.image.load(
                    '../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank' + str(self.type[0]) + 'Lv' + str(
                        i) + '(RIGHT).png'
                )
            )
        self.images = 
            'UP': up,
            'DOWN': down,
            'LEFT': left,
            'RIGHT': right
        
        # 生命
        self.life = self.type[1]

        # 方向
        self.direction = 'DOWN'
        self.image: pygame.Surface = self.images[self.direction][self.life - 1]
        self.rect = self.image.get_rect()
        self.rect.left = x
        self.rect.top = y

        # 碰撞前的坐标
        self.prvX = self.rect.left
        self.prvY = self.rect.top

        # 速度
        self.accumulationMax: float = 0
        self.accumulation = 0.1

        speed = 0
        maxBulletCount = 0
        damage = 1
        # 每种坦克都有不同的属性
        if self.type[0] == 1:
            speed = 3
            self.level = 1
            maxBulletCount = 1
        elif self.type[0] == 2:
            speed = 5
            self.level = 2
            maxBulletCount = 1
            damage = 3
        elif self.type[0] == 3:
            speed = 7
            self.level = 1
            maxBulletCount = 3
            damage = 2
        elif self.type[0] == 4:
            speed = 6
            self.level = 2
            maxBulletCount = 3
            damage = 1
        self.speed = speed
        # 移动开关
        self.stop = True
        # 开火开关
        self.fire = True
        # 步数
        self.step = 30
        # 伤害
        self.damage = damage
        # 子弹个数
        self.bulletCount = 0
        self.maxBulletCount = maxBulletCount

    def loseLife(self, value = 1):
        self.life -= value

    def move(self):
        """
        新增步数变量, 当坦克移动时, 步数进行减少, 当步数小于等于0的时候, 修改地方坦克的方向
        :return: None
        """
        if self.stop:
            if self.step <= 0:
                self.direction = self.randDirection()
                self.step = 30
            else:
                if self.accumulationMax >= 1:
                    self.accumulationMax = 0
                    # 记录上一次的位置
                    self.prvX = self.rect.left
                    self.prvY = self.rect.top
                    if self.direction == 'LEFT':
                        if self.rect.left > 0:
                            se

以上是关于学习 Python 之 Pygame 开发坦克大战的主要内容,如果未能解决你的问题,请参考以下文章

学习 Python 之 Pygame 开发坦克大战

学习 Python 之 Pygame 开发坦克大战

学习 Python 之 Pygame 开发坦克大战

python之游戏开发-坦克大战

Python游戏开发,pygame模块,Python实现经典90坦克大战游戏

Python游戏开发,pygame模块,Python实现升级版坦克大战小游戏