学习 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 开发坦克大战的主要内容,如果未能解决你的问题,请参考以下文章