当前位置:   article > 正文

17 - python——简单的坦克大战(附源码)_python人马大战csdn

python人马大战csdn

基于对面向对象编程的思想完成简单的坦克大战游戏。主要目的锻炼面相对象编程思想
同样的在使用python进行游戏编写时需要安装pygame模块
安装方法:
pycharm安装方式:File --> setting
pygame安装

游戏中的主要对象有:
坦克父类:BaseTank
我方坦克:HeroTank
敌方坦克:EnemyTank
子弹类:Bullet
爆炸类:Explode
墙类:Wall
主进程:MainGame

定义一个精灵类:

# 定义一个精灵类
class BaseItem(Sprite):
    def __init__(self, color, width, height):
        # Call the parent class (Sprite) constructor
       pygame.sprite.Sprite.__init__(self)
  • 1
  • 2
  • 3
  • 4
  • 5

坦克父类:

# 坦克父类
class BaseTank(BaseItem):
    # 定义类属性,所有坦克对象高和宽都是一样
    width = 60
    height = 60

    def __init__(self, left, top):
        self.direction = 'U'  # 坦克的方向默认向上
        # 存放图片的字典
        self.images = {
            'U': pygame.image.load('tank_img/p1tankU.gif'),
            'D': pygame.image.load('tank_img/p1tankD.gif'),
            'L': pygame.image.load('tank_img/p1tankL.gif'),
            'R': pygame.image.load('tank_img/p1tankR.gif')
        }
        self.image = self.images[self.direction]  # 坦克的图片由方向决定
        self.speed = 5  # 坦克的速度
        self.rect = self.image.get_rect()
        # 设置放置的位置
        self.rect.left = left
        self.rect.top = top
        self.stop = True  # 坦克是否停止
        self.live = True  # 决定坦克是否消灭了

        # 保持原来的位置
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top

    # 射击方法
    def shot(self):
        return Bullet(self)

    # 坦克的移动
    def move(self):
        # 保持原来的状态
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top
        # 判断坦克的移动方向
        if self.direction == 'U':
            if self.rect.top > 0:
                self.rect.top -= self.speed
        elif self.direction == 'D':
            if self.rect.top + self.rect.height < WINDOW_HEIGHT:
                self.rect.top += self.speed
        elif self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
        elif self.direction == 'R':
            if self.rect.left+self.rect.height < WINDOW_WIDTH:
                self.rect.left += self.speed
    
    # 加载坦克
    def displayTank(self):
        self.image = self.images[self.direction]
        MainGame.window.blit(self.image, self.rect)
    
    # 撞墙处理
    def hitWall(self):
        for wall in MainGame.wallList:
            if pygame.sprite.collide_rect(wall, self):
                self.stay()
                
    # 处理位置不变
    def stay(self):
        self.rect.left = self.oldLeft
        self.rect.top = self.oldTop
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

我方坦克类():

# 我方坦克
class HeroTank(BaseTank):
    def __init__(self, left, top):
        super().__init__(left, top)
	
	# 我方坦克碰撞敌方坦克
    def myTank_hit_enemyTank(self):
        for enemyTank in MainGame.EnemyTankList:
            if pygame.sprite.collide_rect(enemyTank, self):
                self.stay()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

敌方坦克类():

# 敌方坦克
class EnemyTank(BaseTank):
    def __init__(self, left, top, speed):
        super(EnemyTank, self).__init__(left, top)
        self.images = {
            'U': pygame.image.load('tank_img/enemy1U.gif'),
            'D': pygame.image.load('tank_img/enemy1D.gif'),
            'L': pygame.image.load('tank_img/enemy1L.gif'),
            'R': pygame.image.load('tank_img/enemy1R.gif')
        }

        self.direction = self.RandomDirection()
        self.image = self.images[self.direction]
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.speed = speed
        self.step = 60
        self.enemy_flag = False

    # 坦克出生随机方向
    def RandomDirection(self):
        num = random.randint(1, 4)
        if num == 1:
            return 'U'
        elif num == 2:
            return 'D'
        elif num == 3:
            return 'L'
        else:
            return 'R'
    
    # 坦克随机移动
    def randomMove(self):
        if self.step < 0:
            self.direction = self.RandomDirection()
            self.step = 60
        else:
            self.move()
            self.step -= 1
    
    # 坦克射击
    def shot(self):
        num = random.randint(1, 100)
        if num < 4:
            return Bullet(self)
    
    # 敌方坦克碰撞我方坦克
    def enemyTank_hit_MyTank(self):
        for enemy in MainGame.EnemyTankList:
            if MainGame.my_tank and MainGame.my_tank.live:
                if pygame.sprite.collide_rect(MainGame.my_tank, enemy):
                    self.stay()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

子弹类():

# 子弹类
class Bullet(BaseItem):
    def __init__(self, tank):
        self.image = pygame.image.load('tank_img/tankmissile.gif')
        self.direction = tank.direction
        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.height
        elif self.direction == 'D':
            self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
            self.rect.top = tank.rect.top + tank.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.height / 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.height / 2 - self.rect.width / 2

        # 子弹的速度
        self.speed = 6
        # 子弹状态
        self.live = True
    
    # 加载子弹
    def displayBullet(self):
        MainGame.window.blit(self.image, self.rect)
    
    # 子弹的移动
    def move(self):
        if self.direction == 'U':
            if self.rect.top > 0:
                self.rect.top -= self.speed
            else:
                self.live = False
        elif self.direction == 'R':
            if self.rect.left + self.rect.width < WINDOW_WIDTH:
                self.rect.left += self.speed
            else:
                self.live = False
        elif self.direction == 'D':
            if self.rect.top + self.rect.height < WINDOW_HEIGHT:
                self.rect.top += self.speed
            else:
                self.live = False
        elif self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
            else:
                self.live = False
    
    # 我方子弹击中敌方坦克
    def myBullet_hit_enemy(self):
        for enemytank in MainGame.EnemyTankList:
            if pygame.sprite.collide_rect(enemytank, self):
                enemytank.live = False
                self.live = False

                # 创建爆炸对象
                explode = Explode(enemytank)
                MainGame.explodeList.append(explode)
    
    # 敌方坦克击中我方坦克
    def enemyBullet_hit_myTank(self):
        if MainGame.my_tank and MainGame.my_tank.live:
            if pygame.sprite.collide_rect(MainGame.my_tank, self):
                MainGame.my_tank.live = False
                self.live = False

                # 创建爆炸对象
                explode = Explode(MainGame.my_tank)
                MainGame.explodeList.append(explode)
    
    # 射击墙壁
    def wall_bullet(self):
        for wall in MainGame.wallList:
            if pygame.sprite.collide_rect(wall, self):
                wall.hg -= 1
                self.live = False
                if wall.hg <= 0:
                    wall.live = False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

墙壁类():

# 墙壁类
class Wall:
    def __init__(self, left, top):
        self.image = pygame.image.load('tank_img/steels.gif')
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.live = True
        self.hg = 100000000000000
        
	# 加载墙壁
    def displayWall(self):
        if self.live:
            MainGame.window.blit(self.image, self.rect)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

爆炸类:

# 爆炸类
class Explode:
    def __init__(self, tank):
        # 爆炸的位置由坦克决定
        self.rect = tank.rect
        self.images = [
            pygame.image.load('tank_img/blast0.gif'),
            pygame.image.load('tank_img/blast1.gif'),
            pygame.image.load('tank_img/blast2.gif'),
            pygame.image.load('tank_img/blast3.gif'),
            pygame.image.load('tank_img/blast4.gif'),
            pygame.image.load('tank_img/blast5.gif'),
            pygame.image.load('tank_img/blast6.gif'),
            pygame.image.load('tank_img/blast7.gif')
        ]
        self.step = 0
        self.image = self.images[self.step]
        self.live = True
    
    # 加载爆炸类
    def displayExplode(self):
        if self.step < len(self.images):
            self.image = self.images[self.step]
            self.step += 1
            MainGame.window.blit(self.image, self.rect)
        else:
            self.live = False
            self.step = 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

主进程():

# 游戏类
class MainGame:
    # 类属性
    window = None
    my_tank = None

    # 敌方坦克初始化
    EnemyTankList = []
    EnemyTankCount = 5

    # 存储我方子弹列表
    myBulleList = []
    # 存储敌方子弹的列表
    EnemyBulletList = []

    # 创建爆炸对象列表
    explodeList = []

    # 创建墙壁列表
    wallList = []

    # 游戏开始方法
    def start_game(self):
        # 初始化展示模块
        pygame.display.init()
        # 调用创建窗口的方法
        self.creat_window()
        # 设置游戏窗口标题
        pygame.display.set_caption('坦克大战')
        # 初始化我方坦克
        self.createMyTank()
        # 初始化敌方坦克
        self.creatEnemyTank()
        # 初始化墙壁
        self.creatWall()

        # 程序持续进行
        while True:
            # 更改背景颜色
            MainGame.window.fill(COLOR_GREEN)
            # 背景音乐

            # 获取事件
            self.getEvent()
            # 调用我方坦克进行显示
            if MainGame.my_tank and MainGame.my_tank.live:
                MainGame.my_tank.displayTank()
                if not MainGame.my_tank.stop:
                    MainGame.my_tank.move()
                    MainGame.my_tank.hitWall()
                    MainGame.my_tank.myTank_hit_enemyTank()
            else:
                del MainGame.my_tank
                MainGame.my_tank = None
            # 加载我方子弹
            self.biltMyBullet()
            # 显示敌方坦克
            self.biltEnemyTank()
            # 显示敌方子弹
            self.biltEnemyBullet()
            # 显示墙壁
            self.blitWall()
            # 显示爆炸效果
            self.blitExplode()

            self.put_more_enemytank()

            # 窗口持续刷新
            pygame.display.update()
            time.sleep(0.02)

    # 重复添加敌方坦克
    def put_more_enemytank(self):
        while len(MainGame.EnemyTankList) < 5:
            self.more()

    # 创建游戏窗口方法:
    def creat_window(self):
        if not MainGame.window:
            # 创建窗口
            MainGame.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        return MainGame.window

    # 创建我方坦克
    def createMyTank(self):
        MainGame.my_tank = HeroTank((WINDOW_WIDTH - HeroTank.width)/2, WINDOW_HEIGHT - HeroTank.height)
        music = Music('tank_img/start.wav')
        music.play()

    # 创建墙壁
    def creatWall(self):
        for i in range(60, WINDOW_WIDTH, 60):
            top = WINDOW_WIDTH // 3
            left = i
            wall = Wall(left, top)
            MainGame.wallList.append(wall)

    # 显示墙壁
    def blitWall(self):
        for b in MainGame.wallList:
            if b.live:
                b.displayWall()
            else:
                MainGame.wallList.remove(b)

    # 加载我方子弹
    def biltMyBullet(self):
        for bullet in MainGame.myBulleList:
            if bullet.live:
                bullet.displayBullet()
                bullet.move()
                bullet.myBullet_hit_enemy()
                bullet.wall_bullet()
            else:
                MainGame.myBulleList.remove(bullet)

    # 后续坦克的添加
    def more(self):
        top = 0
        for i in range(5 - len(MainGame.EnemyTankList)):
            left = random.randint(0, 750)
            speed = random.randint(1, 4)
            enemy = EnemyTank(left, top, speed)
            MainGame.EnemyTankList.append(enemy)

    # 创建敌方坦克
    def creatEnemyTank(self):
        top = 0
        for i in range(MainGame.EnemyTankCount):
            left = random.randint(0, 750)
            speed = random.randint(1, 4)
            enemy = EnemyTank(left, top, speed)
            MainGame.EnemyTankList.append(enemy)

    # 循环遍历显示敌方坦克
    def biltEnemyTank(self):
        for enemytank in MainGame.EnemyTankList:
            if enemytank.live:
                enemytank.displayTank()
                EnemyBullet = enemytank.shot()
                enemytank.randomMove()
                enemytank.hitWall()
                enemytank.enemyTank_hit_MyTank()

                # 存储敌方子弹
                if EnemyBullet:
                    MainGame.EnemyBulletList.append(EnemyBullet)
            else:
                MainGame.EnemyTankList.remove(enemytank)
                MainGame.EnemyTankCount -= 1

    # 加载敌方子弹
    def biltEnemyBullet(self):
        for bullet in MainGame.EnemyBulletList:
            if bullet.live:
                bullet.displayBullet()
                bullet.move()
                bullet.enemyBullet_hit_myTank()
                bullet.wall_bullet()

            else:
                MainGame.EnemyBulletList.remove(bullet)

    # 加载爆炸效果
    def blitExplode(self):
        for explode in MainGame.explodeList:
            if explode.live:
                explode.displayExplode()
            else:
                MainGame.explodeList.remove(explode)

    # 获取游戏中的所有事件
    def getEvent(self):
        # 获取游戏中的事件列表
        even_list = pygame.event.get()
        for e in even_list:
            # 点击窗口的叉号实现游戏结束
            if e.type == pygame.QUIT:
                sys.exit()

            # 通过上下左右键控制坦克的移动
            if e.type == pygame.KEYDOWN:
                if MainGame.my_tank and MainGame.my_tank.live:
                    if e.key == pygame.K_DOWN or e.key == pygame.K_s:
                        MainGame.my_tank.direction = 'D'
                        MainGame.my_tank.stop = False
                        print("按下向下的键,向下移动")
                    elif e.key == pygame.K_UP or e.key == pygame.K_w:
                        MainGame.my_tank.direction = 'U'
                        MainGame.my_tank.stop = False
                        print("按下向上的键,向上移动")
                    elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
                        MainGame.my_tank.direction = 'L'
                        MainGame.my_tank.stop = False
                        print("按下向左的键,向左移动")
                    elif e.key == pygame.K_RIGHT or e.key == pygame.K_d:
                        MainGame.my_tank.direction = 'R'
                        MainGame.my_tank.stop = False
                        print("按下向右的键,向右移动")

                    elif e.key == pygame.K_SPACE:
                        print('发射子弹')
                        # 创建我方子弹
                        if len(MainGame.myBulleList) < 10:
                            mybullet = Bullet(MainGame.my_tank)
                            MainGame.myBulleList.append(mybullet)

                            # 射击音效
                            Shot_music = Music('tank_img/fire.wav')
                            Shot_music.play()

            elif e.type == pygame.KEYUP:
                if e.key == pygame.K_UP or e.key == pygame.K_DOWN or e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT \
                        or e.key == pygame.K_w or e.key == pygame.K_s or e.key == pygame.K_a or e.key == pygame.K_d:
                    if MainGame.my_tank and MainGame.my_tank.live:
                        MainGame.my_tank.stop = True
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216

程序运行结果:

运行结果
源码:百度盘: 坦克大战:https://pan.baidu.com/s/1ZOLIba7SpZk-WUvhKJlPig
提取码:q87l

(QwQ)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/573055
推荐阅读
相关标签
  

闽ICP备14008679号