python图形界面化编程GUI(七)坦克大战(三)

完善障碍物类

将墙壁存储到列表中,在窗口中添加墙壁,但并未实现障碍物的功能。
在这里插入图片描述

class MainGame():
    # 存储墙壁的列表
    wallList = []
    # 开始游戏
    def startGame(self):
        # 初始化墙壁
        self.createWall()
        while True:
            # 展示墙壁
            self.showWall()
    def showWall(self):
        for wall in MainGame.wallList:
            wall.displayWall()
            
    def createWall(self):
        for i in range(7):
            wall = Wall(i*130, 400)
            MainGame.wallList.append(wall)
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)

墙壁的完善1

实现子弹不能穿越墙壁,墙壁被击中时触发墙壁韧性,韧性设置为3,当墙壁被击中3次时消失。
在这里插入图片描述

class MainGame():
    def showWall(self):
        for wall in MainGame.wallList:
            if wall.live:
                wall.displayWall()
            else:
                MainGame.wallList.remove(wall)
    def showEnemyBullet(self):
        for enemyBullet in MainGame.enemyBulletList:
            # 如果状态是True
            if enemyBullet.live:
                enemyBullet.displayBullet()
                enemyBullet.move()
                # 调用敌方子弹和我方坦克碰撞的方法
                enemyBullet.enemyBullet_hit_myTank()
                enemyBullet.hitWall() # 敌方子弹击中墙壁
            else:
                MainGame.enemyBulletList.remove(enemyBullet)

    def showMyBullet(self):
        for myBullet in MainGame.myBulletList:
            if myBullet.live:
                myBullet.displayBullet()
                myBullet.move()
                # 调用发生碰撞的方法
                myBullet.myBullet_hit_enemyTank()
                myBullet.hitWall() # 我方子弹击中墙壁
            else:
                MainGame.myBulletList.remove(myBullet)
class Bullet(BaseItem):
	# 子弹射击障碍物的方法
    def hitWall(self):
        for wall in MainGame.wallList:
            if pygame.sprite.collide_rect(self, wall):
                self.live = False
                wall.hp -= 1
                if wall.hp <= 0:
                    wall.live = False

墙壁的完善2

解决坦克穿越墙壁的问题,实现坦克不能穿越墙壁,坦克碰到墙壁就不能再移动。
在这里插入图片描述

class MainGame():
	def startGame(self):
		while True:
			# 调用坦克移动的方法
            if MainGame.my_tank and MainGame.my_tank.live:
                if not MainGame.my_tank.stop:
                    MainGame.my_tank.move()
                    MainGame.my_tank.hitWall()
            pygame.display.update()
    # 展示敌方坦克
    def showEnemyTank(self):
        for enemyTank in MainGame.enemyTankList:
            # 直接调用父类的display()
            if enemyTank.live:
                enemyTank.displayTank()
                # 坦克移动
                enemyTank.randMove()
                enemyTank.hitWall()
# 坦克类
class Tank(BaseItem):
    def __init__(self, left, top):
        # 坦克移动的开关,按下移动,松开停止
        self.stop = True  # 默认坦克是不动的状态
        # 添加坦克是否存在的属性
        self.live = True  # 默认坦克是存在的
        # 添加两个之前的位置坐标的属性
        self.oldleft = self.rect.left
        self.oldtop = self.rect.top
    # 移动
    def move(self):
        # 移动后记录原始的坐标
        self.oldleft = self.rect.left
        self.oldtop = self.rect.top
    # 射击
    def shot(self):# 需要对射击的方法进行限制,不然坦克会一直发射子弹
        # 用随机数控制敌方坦克偶尔发射子弹
        num = random.randint(1,100)
        if num < 10:
            return Bullet(self)
        
    def stay(self):
        self.rect.left = self.oldleft
        self.rect.top = self.oldtop

    def hitWall(self):
        for wall in MainGame.walllist:
            if pygame.sprite.collide_rect(self, wall):
                # 将坐标设置为移动之前的坐标,即为坦克出现的地方
                self.stay()

坦克碰撞

双方坦克碰到后不能继续移动,只有转换方向才能再次移动。

  1. 我方坦克碰撞敌方,我方坦克不能移动 stay()
  2. 敌方坦克碰撞我方坦克,敌方坦克不能移动 stay()
    在这里插入图片描述
class MainGame():
    def startGame(self): # 方法
        MainGame.my_tank = Tank(450,400)
        while True:
            if MainGame.my_tank and MainGame.my_tank.live:  # 我方坦克存在且存活的状态下
                if not MainGame.my_tank.stop:
                    # 调用坦克移动的方法,实现按下移动,松开停止
                    MainGame.my_tank.move()
                    MainGame.my_tank.hitWall()
                    MainGame.my_tank.myTank_hit_enemyTank()
    # 展示敌方坦克
    def showEnemyTank(self):
        for enemyTank in MainGame.enemyTankList:
            if enemyTank.live:
                enemyTank.displayTank()
                # 坦克移动
                enemyTank.randMove()
                enemyTank.hitWall()
                # 调用和我方坦克发生碰撞的方法
                if MainGame.my_tank and MainGame.my_tank.live:
                    enemyTank.enemyTank_hit_myTank()
                # 创建并发射子弹
                enemyBullet = enemyTank.shot()
# 坦克类
class Tank(BaseItem):
    def myTank_hit_enemyTank(self):
        for enemyTank in MainGame.enemyTankList:
            if pygame.sprite.collide_rect(self, enemyTank):
                self.stay()
class MyTank(Tank):
    def __init__(self, left, top):
        super().__init__(left, top)

class EnemyTank(Tank):
    def enemyTank_hit_myTank(self):
        if pygame.sprite.collide_rect(self, MainGame.my_tank):
            self.stay()

也可以初始化MyTank,把碰撞方法放到MyTank里

class MainGame():
    def startGame(self): # 方法
            self.creatMyTank()
            MainGame.my_tank = MyTank(450,400)
class MyTank(Tank):
    def __init__(self, left, top):
        super().__init__(left, top)
    def myTank_hit_enemyTank(self):
        for enemyTank in MainGame.enemyTankList:
            if pygame.sprite.collide_rect(self, enemyTank):
                self.stay()

音效类的补充

完善开场音效,我方坦克发射子弹的音效以及爆炸音效。

class MainGame():
    def startGame(self): # 方法
            # 初始化我方坦克
        self.creatMyTank()
        MainGame.my_tank = MyTank(450,400)
    def creatMyTank(self):
        MainGame.my_tank = Tank(450, 500)
        music = Music('img/start.wav')
        music.play()
    # 显示爆炸的方法
    def showExplode(self):
        for explode in MainGame.explodeList:
            if explode.live:
                explode.displayExplode()
                music = Music('img/fire.wav')
                music.play()
            else:
                MainGame.explodeList.remove(explode)
    # 获取事件
    def getEvent(self):
        # 获取所有的事件
        eventList = pygame.event.get() # 获取的是事件列表,并不是唯一的事件,比如上下左右
        # 遍历出每一个事件
        for event in eventList:
            # 判断按下的是关闭键还是键盘
            if event.type == pygame.QUIT:
                self.endGame()  # 执行退出操作
            # 判断方向键,如果按下的类型是键盘
            elif event.type == pygame.KEYDOWN:
                # 如果没有坦克,如果按下的是ESC键,就调用创建坦克的命令
                if not MainGame.my_tank:
                    if event.key == pygame.K_ESCAPE:
                        self.creatMyTank()
                if MainGame.my_tank and MainGame.my_tank.live:
                    # 左
                    if event.key == pygame.K_LEFT:
                        # 切换方向
                        MainGame.my_tank.direction = 'L'
                        # 更改移动开关
                        MainGame.my_tank.stop = False # 按下按键的时候,解除停止的状态
                        # MainGame.my_tank.move()  # 实现坦克按下移动,松开停止,要把单个方向的移动禁用掉
                        print('按下左键,向左移动')
                    # 右
                    elif event.key == pygame.K_RIGHT:
                        MainGame.my_tank.direction = 'R'
                        # 更改移动开关
                        MainGame.my_tank.stop = False  # 按下按键的时候,解除停止的状态
                        # MainGame.my_tank.move()
                        print('按下右键,向右移动')
                    # 上
                    elif event.key == pygame.K_UP:
                        MainGame.my_tank.direction = 'U'
                        # 更改移动开关
                        MainGame.my_tank.stop = False  # 按下按键的时候,解除停止的状态
                        # MainGame.my_tank.move()
                        print('按下上键,向上移动')
                    # 下
                    elif event.key == pygame.K_DOWN:
                        MainGame.my_tank.direction = 'D'
                        # 更改移动开关
                        MainGame.my_tank.stop = False  # 按下按键的时候,解除停止的状态
                        # MainGame.my_tank.move()
                        print('按下下键,向下移动')
                    # 用空格发射子弹,此时发射子弹和坦克移动是冲突的,松开空格相当于松开键盘,坦克就停止了,不能实现边走边发射子弹
                    # 如果实现边移动边发射子弹的逻辑,就要把松开方向键进行判断
                    elif event.key == pygame.K_SPACE:
                        print('发射子弹')
                        # 如果当前子弹列表长度不大于3,才进行子弹的创建
                        if len(MainGame.myBulletList) < 3:
                            # 我方坦克发射子弹
                            myBullet = Bullet(MainGame.my_tank)
                            MainGame.myBulletList.append(myBullet)
                            music = Music('img/hit.wav')
                            music.play()                     
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值