美文网首页
Pygame 实现飞机大战

Pygame 实现飞机大战

作者: wjundong | 来源:发表于2020-02-18 22:54 被阅读0次
    #coding=utf-8
    
    import pygame
    from pygame import *
    from pygame.locals import *
    from random import randint
    import sys
    
    SCREEN_WIDTH = 480
    SCREEN_HEIGHT = 640
    
    
    # 材质类
    class Texture():
        def __init__(self):
            texture = pygame.image.load('resources/image/texture.png')
            self.enemy3_down6 = texture.subsurface( 0, 747, 166, 261 )
            self.enemy3_hit = texture.subsurface( 166, 750, 169, 258 )
            self.enemy3_n1 = texture.subsurface( 335, 750, 169, 258 )
            self.enemy3_n2 = texture.subsurface( 504, 750, 169, 258 )
            self.enemy3_down1 = texture.subsurface( 0, 486, 165, 261 )
            self.enemy3_down2 = texture.subsurface( 0, 225, 165, 261 )
            self.enemy3_down5 = texture.subsurface( 673, 748, 166, 260 )
            self.enemy3_down3 = texture.subsurface( 839, 748, 165, 260 )
            self.enemy3_down4 = texture.subsurface( 165, 486, 165, 261 )
            self.hero1 = texture.subsurface( 0, 99, 102, 126)
            self.hero2 = texture.subsurface( 165, 360, 102, 126)
            self.hero_blowup_n1 = texture.subsurface( 165, 234, 102, 126 )
            self.hero_blowup_n2 = texture.subsurface( 330, 624, 102, 126 )
            self.hero_blowup_n3 = texture.subsurface( 330, 498, 102, 126 )
            self.hero_blowup_n4 = texture.subsurface( 432, 624, 102, 126 )
            self.enemy2 = texture.subsurface( 0, 0, 69, 99 )
            self.enemy2_hit = texture.subsurface( 432, 525, 69, 99 )
            self.ufo2 = texture.subsurface( 102, 118, 60, 107 )
            self.enemy2_down1 = texture.subsurface( 534, 655, 69, 95 )
            self.enemy2_down2 = texture.subsurface( 603, 655, 69, 95 )
            self.enemy2_down3 = texture.subsurface( 672, 653, 69, 95 )
            self.enemy2_down4 = texture.subsurface( 741, 653, 69, 95 )
            self.ufo1 = texture.subsurface( 267, 398, 58, 88 )
            self.bomb = texture.subsurface( 810, 691, 63, 57 )
            self.enemy1_down1 = texture.subsurface( 267, 347, 57, 51 )
            self.enemy1_down2 = texture.subsurface( 873, 697, 57, 51 )
            self.enemy1_down3 = texture.subsurface( 267, 296, 57, 51 )
            self.enemy1_down4 = texture.subsurface( 930, 697, 57, 51 )
            self.game_pause_nor = texture.subsurface( 267, 251, 60, 45 )
            self.game_pause_pressed = texture.subsurface( 810, 646, 60, 45 )
            self.enemy1 = texture.subsurface( 534, 612, 57, 43 )
            self.bullet1 = texture.subsurface( 1004, 987, 9, 21 )
            self.bullet2 = texture.subsurface( 69, 78, 9, 21 )
    
    
    class Bullet(pygame.sprite.Sprite):
        def __init__(self, image, initPos):
            super().__init__()
            # 加载资源
            self.image = image
            self.rect = self.image.get_rect()
            # 设置初始位置
            self.rect.x = initPos[0]
            self.rect.y = initPos[1]
            self.speed = 10
    
        def update(self):
            self.rect.y -= self.speed
            if self.rect.bottom < 0:
                self.kill()
    
    
          
    class Enemy1(pygame.sprite.Sprite):
        def __init__(self, texture):
            super().__init__()
            # 加载资源
            self.texture = texture
            self.image = texture.enemy1
            self.rect = self.image.get_rect()
            # 随机生成的位置
            self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
            self.rect.y = randint(0, 30)
            # 飞行速度
            self.speed = 4
            self.downIndex = 0
    
        def finishDownAnimation(self):
            self.downIndex += 1
            if self.downIndex == 4:
                self.image = self.texture.enemy1_down1
            elif self.downIndex == 8:
                self.image = self.texture.enemy1_down2
            elif self.downIndex == 12:
                self.image = self.texture.enemy1_down3
            elif self.downIndex == 16:
                self.image = self.texture.enemy1_down4
            elif self.downIndex == 20:
                self.kill()
                return True
            return False
    
        def update(self):
            self.rect.y += self.speed
            # if self.life < 0:
    
            if self.rect.top > SCREEN_HEIGHT:
                self.kill()
    
    class Enemy1Group():
        def __init__(self, texture):
            # 生成间隔
            self.texture = texture
            self.frameIndex = 0
            self.createSpan = 30
            self.group = pygame.sprite.Group()
        
        def createEnemy(self):
            self.frameIndex += 1
            if self.frameIndex > self.createSpan:
                self.group.add(Enemy1(self.texture))
                self.frameIndex = 0
    
    # 中型敌机   
    class Enemy2(pygame.sprite.Sprite):
        def __init__(self, texture, screen):
            super().__init__()
            # 加载资源
            self.texture = texture
            self.image = texture.enemy2
            self.screen = screen
            self.rect = self.image.get_rect()
            # 随机生成的位置
            self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
            self.rect.y = randint(0, 30)
            # 飞行速度
            self.speed = 2
            
            # 生命值
            self.life = 100
            # 防御值
            self.downIndex = 0
            # 血槽图层
            self.bloodBox = pygame.Surface((self.rect.width, 2))
            
        # 完成被击中动画
        def finishDownAnimation(self):
            self.downIndex += 1
            if self.downIndex == 4:
                self.image = self.texture.enemy2_down1
            elif self.downIndex == 8:
                self.image = self.texture.enemy2_down2
            elif self.downIndex == 12:
                self.image = self.texture.enemy2_down3
            elif self.downIndex == 16:
                self.image = self.texture.enemy2_down4
            elif self.downIndex == 20:
                return True
            return False
    
        # 被击中, 返回是否死亡
        def behit(self, type):
            if self.life > 0:
                if type == 1:
                    self.life -= 30
                elif type == 2:
                    self.life -= 50
                elif type == 3:
                    self.life -= 100
    
        # 绘制血量
        def drawBlood(self):
            self.bloodBox.fill((255, 255, 255, 255))
            pygame.draw.rect(self.bloodBox, [237, 28, 36, 90], [0, 0, int(self.rect.width*(self.life/100)), 2])
            self.screen.blit(self.bloodBox, (self.rect.x, self.rect.y))
    
        def update(self):
            self.drawBlood()
            if self.life <= 0:
                if self.finishDownAnimation():
                    self.kill()
            self.rect.y += self.speed
            # if self.life < 0:
            if self.rect.top > SCREEN_HEIGHT:
                self.kill()
    
    class Enemy2Group():
        def __init__(self, texture):
            # 生成间隔
            self.texture = texture
            self.frameIndex = 0
            self.createSpan = 200
            self.group = pygame.sprite.Group()
        
        def collide(self, bulletGroup):
            for ememy in self.group:
                if pygame.sprite.spritecollide(ememy, bulletGroup, True):
                    if ememy.behit(1):
                        self.kill()
    
        def createEnemy(self, screen):
            self.frameIndex += 1
            if self.frameIndex > self.createSpan:
                self.createSpan = randint(200, 500)
                self.group.add(Enemy2(self.texture, screen))
                self.frameIndex = 0
    
    
    class enemy3Bullet(pygame.sprite.Sprite):
        def __init__(self, image, initPos):
            super().__init__()
            # 加载资源
            self.image = image
            self.rect = self.image.get_rect()
            # 设置初始位置
            self.rect.x = initPos[0]
            self.rect.y = initPos[1]
            self.speed = 1
    
        def update(self):
            x = randint(-1, 1)
            self.rect.y += self.speed
            if self.rect.bottom < 0:
                self.kill()
    
    
    class Enemy3(pygame.sprite.Sprite):
        def __init__(self, texture, screen):
            super().__init__()
            # 加载资源
            self.texture = texture
            self.image = texture.enemy3_n2
            self.screen = screen
            self.rect = self.image.get_rect()
            # 随机生成的位置
            self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
            self.rect.y = 10
            # 飞行速度
            self.speed = 0
            # 生命值
            self.life = 1000
            self.downIndex = 0
            # 血槽图层
            self.bloodBox = pygame.Surface((self.rect.width, 2))
            # 敌人子弹精灵组
            self.bulletGroup = pygame.sprite.Group()
    
        def finishDownAnimation(self):
            self.downIndex += 1
            if self.downIndex == 4:
                self.image = self.texture.enemy3_down1
            elif self.downIndex == 8:
                self.image = self.texture.enemy3_down2
            elif self.downIndex == 12:
                self.image = self.texture.enemy3_down3
            elif self.downIndex == 16:
                self.image = self.texture.enemy3_down4
            elif self.downIndex == 20:
                self.image = self.texture.enemy3_down5
            elif self.downIndex == 25:
                self.image = self.texture.enemy3_down6
            elif self.downIndex == 30:
                return True
            return False
    
        # 被击中, 返回是否死亡
        def behit(self, type):
            if self.life > 0:
                if type == 1:
                    self.life -= 30
                elif type == 2:
                    self.life -= 50
                elif type == 3:
                    self.life -= 100
    
        # 绘制血量
        def drawBlood(self):
            self.bloodBox.fill((255, 255, 255, 255))
            pygame.draw.rect(self.bloodBox, [237, 28, 36, 90], [0, 0, int(self.rect.width*(self.life/1000)), 2])
            self.screen.blit(self.bloodBox, (self.rect.x, self.rect.y))
     
        def update(self):
            self.drawBlood()
            if self.life <= 0:
                if self.finishDownAnimation():
                    self.kill()
            self.rect.y += self.speed
            # if self.life < 0:
            if self.rect.top > SCREEN_HEIGHT:
                self.kill()
    
    class Enemy3Group():
        def __init__(self, texture):
            # 生成间隔
            self.texture = texture
            self.frameIndex = 0
            self.createSpan = 300
            self.group = pygame.sprite.Group()
        
        def collide(self, bulletGroup):
            for ememy in self.group:
                if pygame.sprite.spritecollide(ememy, bulletGroup, True):
                    if ememy.behit(1):
                        self.kill()
    
        def createEnemy(self, screen):
            self.frameIndex += 1
            if self.frameIndex > self.createSpan:
                self.createSpan = randint(500, 1000)
                self.group.add(Enemy3(self.texture, screen))
                self.frameIndex = 0
    
    # 物资类
    class Supply(pygame.sprite.Sprite):
        def __init__(self, texture):
            super().__init__()
            # self.type = randint(0, 3)
            # if self.type == 1:
            self.image = texture.bomb
            self.rect = self.image.get_rect()
            # 随机生成位置
            self.rect.x = randint(0, SCREEN_WIDTH - self.rect.width)
            self.rect.y = 0
            self.speed = 1
            self.moveIndex = 1
            self.direction = 1
    
        def update(self):
            self.moveIndex -= 1
            self.rect.x += self.speed*self.direction
            self.rect.y += self.speed
    
            if self.moveIndex <= 0:
                self.moveIndex = randint(0, 120)
                self.direction = randint(-1, 1)
    
            if self.rect.top > SCREEN_HEIGHT:
                self.kill()
    
    
    class SupplyGroup():
        def __init__(self, texture):
            self.texture = texture
            self.frameIndex = 0
            self.createSpan = 50
            self.group = pygame.sprite.Group()
    
        def createSupply(self, screen):
            self.frameIndex += 1
            if self.frameIndex > self.createSpan:
                self.createSpan = randint(100, 500)
                self.group.add(Supply(self.texture))
                self.frameIndex = 0
    
    
    class Player(pygame.sprite.Sprite):
        def __init__(self, texture, screen):
            super().__init__()
            # 加载资源
            self.screen = screen
            self.texture = texture
            self.image = texture.hero1
            self.rect = self.image.get_rect()
            # 设置初始位置
            self.initpos = [200, 500]
            self.rect.x, self.rect.y = self.initpos 
            # 设置飞机速度
            self.shootSpan = 10 
            self.speed = 6
            # 设置帧数
            self.frameIndex = 0
            self.MAX_FRAME_INDEX = 120
            self.life = 100
            # 由玩家控制的子弹精灵组
            self.bulletGroup = pygame.sprite.Group()
            self.bulletType = 1
            # 血槽图层
            self.bloodBox = pygame.Surface((self.rect.width, 4))
            self.downIndex = 0
    
        
        # 飞机飞行动画
        def flightAnimation(self):
            # 每 30 帧更换一次图片
            if self.frameIndex % 30 == 0:
                if self.image == self.texture.hero1:
                    self.image = self.texture.hero2
                else: 
                    self.image = self.texture.hero1
        # 绘制血量
        def drawBlood(self):
            self.bloodBox.fill((255, 255, 255, 255))
            pygame.draw.rect(self.bloodBox, [0, 128, 64, 90], [0, 0, int(self.rect.width*(self.life/100)), 4])
            self.screen.blit(self.bloodBox, (self.rect.left, self.rect.bottom))
    
        # 飞机移动方法
        def moveUp(self):
            self.rect.y -= self.speed
            if self.rect.top < 0:
                self.rect.top = 0
    
        def moveDown(self):
            self.rect.y += self.speed
            if self.rect.bottom > SCREEN_HEIGHT:
                self.rect.bottom = SCREEN_HEIGHT
    
        def moveLeft(self):
            self.rect.x -= self.speed
            if self.rect.left < 0:
                self.rect.left = 0
    
        def moveRight(self):
            self.rect.x += self.speed
            if self.rect.right > SCREEN_WIDTH:
                self.rect.right = SCREEN_WIDTH
    
        # 射击函数
        def shoot(self):
            if self.frameIndex % self.shootSpan == 0:
                if self.bulletType == 1:
                    self.bulletGroup.add(Bullet(self.texture.bullet1, self.rect.midtop))
                elif self.bulletType == 2:
                    self.bulletGroup.add(Bullet(self.texture.bullet2, self.rect.midtop))
        
        def finishDownAnimation(self):
            self.downIndex += 1
            if self.downIndex == 5:
                self.image = self.texture.hero_blowup_n1
            elif self.downIndex == 10:
                self.image = self.texture.hero_blowup_n2
            elif self.downIndex == 15:
                self.image = self.texture.hero_blowup_n3
            elif self.downIndex == 20:
                self.image = self.texture.hero_blowup_n4
            elif self.downIndex == 25:
                return True
            return False
    
    
        def behit(self):
            if self.life >= 0:
                self.life -= 10
    
        # 碰撞检测
        def collide(self, ememyGroup):
            if pygame.sprite.spritecollide(self, ememyGroup, True):
                self.behit()
    
        # 获取物资检测
        def supplyCollide(self, supplyGroup):
            if pygame.sprite.spritecollide(self, supplyGroup, True):
                supplyType = randint(1, 3)
                if supplyType == 1:
                    self.bulletType = 1
                elif supplyType == 2:
                    self.bulletType = 2
                elif supplyType == 3:
                    self.life += 100 - self.life
    
    
        def update(self):
            self.drawBlood()
            if self.life <= 0:
                if self.finishDownAnimation():
                    self.kill()
    
            self.frameIndex += 1
            if(self.frameIndex > self.MAX_FRAME_INDEX):
                frameIndex = 0
            self.flightAnimation()
            self.shoot()
    
    
    if __name__ == "__main__":
    
        # 初始化窗口
        pygame.init()
        screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
        pygame.display.set_caption('飞机大战')
        colck = pygame.time.Clock()
        
        # 加载背景图片和导入所有材质
        background = pygame.image.load('resources/image/background.png') 
        gameover = pygame.image.load('resources/image/gameover.png') 
        texture = Texture()
        
        # 创建敌人
        enemy1Group = Enemy1Group(texture)
        enemy2Group = Enemy2Group(texture)
        enemy3Group = Enemy3Group(texture)
        # 创建击毁敌人组
        enemy1DownGroup = pygame.sprite.Group()
        enemy2DownGroup = pygame.sprite.Group()
        enemy3DownGroup = pygame.sprite.Group()
    
        # 创建玩家
        player = Player(texture, screen)
        spriteGroup = pygame.sprite.Group()
        spriteGroup.add(player)
    
        # 物资类型
        supplyGroup = SupplyGroup(texture)
    
        yindex = 0
        while True:
    
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                
            # 检测按键按下
            keys = pygame.key.get_pressed()
    
            if(keys[pygame.K_w]):
                player.moveUp()
    
            if(keys[pygame.K_s]):
                player.moveDown()
    
            if(keys[pygame.K_a]):
                player.moveLeft()
    
            if(keys[pygame.K_d]):
                player.moveRight()
            
            # 动态背景
            screen.blit(background, (0, yindex))
            screen.blit(background, (0, yindex - SCREEN_HEIGHT))
            yindex += 10
            if(yindex >= SCREEN_HEIGHT):
                yindex = 0
            
            enemy1DownGroup.add(pygame.sprite.groupcollide(enemy1Group.group, player.bulletGroup, False, True))
            for enemy1Down in enemy1DownGroup:
                # 完成击毁动画再删除
                if enemy1Down.finishDownAnimation() == True:
                    enemy1DownGroup.remove(enemy1Down)
            
            # 碰撞检测
            enemy2Group.collide(player.bulletGroup)
            enemy3Group.collide(player.bulletGroup)
            player.collide(enemy1Group.group)
            player.collide(enemy2Group.group)
            player.supplyCollide(supplyGroup.group)
    
            # 更新玩家状态
            player.bulletGroup.draw(screen)
            player.bulletGroup.update()
            spriteGroup.draw(screen)
            spriteGroup.update()
    
            # 更新敌人状态
            enemy1Group.createEnemy()
            enemy1Group.group.draw(screen)
            enemy1Group.group.update()
            enemy2Group.createEnemy(screen)
            enemy2Group.group.draw(screen)
            enemy2Group.group.update()
            enemy3Group.createEnemy(screen)
            enemy3Group.group.draw(screen)
            enemy3Group.group.update()
    
            # 更新物资状态
            supplyGroup.createSupply(screen)
            supplyGroup.group.draw(screen)
            supplyGroup.group.update()
    
            if player.life <= 0:
                screen.blit(gameover, (0, 0))
            
            # 更新屏幕
            # pygame.display.update()
            pygame.display.flip()
            colck.tick(60)
            
    

    运行效果


    运行效果.PNG
    碰撞爆炸.PNG
    碰撞爆炸.PNG 游戏结束.PNG 运行效果.PNG 空中物资.PNG

    材质资源链接 提取码:e7rh

    相关文章

      网友评论

          本文标题:Pygame 实现飞机大战

          本文链接:https://www.haomeiwen.com/subject/oztofhtx.html