精华内容
下载资源
问答
  • Python游戏飞机大战源代码,单机游戏。结课项目,功能全面,游戏有趣,压缩包涵盖所有阶段的源代码,轻松学习,内容充实。
  • python开发飞机大战游戏,有背景音乐,背景图。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 小猿圈python讲师今天就为你重现飞机大战游戏的原型,让你回忆一下小时候的。首先飞机大战(Python)代码分为两个python文件,工具类和主类,需要安装pygame模块,能完美运行,如图所示:完整代码如下:1.工具类...

    现在游戏产业的多种多样,从最早的坦克大战、超级玛丽到现在的英雄联盟、刺激战场等等数不胜数,你还记得最早的飞机大战吗?小猿圈python讲师今天就为你重现飞机大战游戏的原型,让你回忆一下小时候的。

    首先飞机大战(Python)代码分为两个python文件,工具类和主类,需要安装pygame模块,能完美运行,如图所示:

    完整代码如下:

    1.工具类plane_sprites.py

    import random

    import pygame

    # 屏幕大小的常量

    SCREEN_RECT = pygame.Rect(0, 0, 480, 700)

    # 刷新的帧率

    FRAME_PER_SEC = 60

    # 创建敌机的定时器常量

    CREATE_ENEMY_EVENT = pygame.USEREVENT

    # 英雄发射子弹事件

    HERO_FIRE_EVENT = pygame.USEREVENT + 1

    class GameSprite(pygame.sprite.Sprite):

    """飞机大战游戏精灵"""

    def __init__(self, image_name, speed=1):

    super().__init__()# 调用父类的初始化方法

    self.image = pygame.image.load(image_name)# 定义对象的属性

    self.rect = self.image.get_rect()

    self.speed = speed

    def update(self):

    # 在屏幕的垂直方向上移动

    self.rect.y += self.speed

    class Background(GameSprite):

    """游戏背景精灵"""

    def __init__(self, is_alt=False):

    super().__init__("C:/Users/Administrator/Desktop/background.png")# 1. 调用父类方法实现精灵的创建(image/rect/speed)

    if is_alt:# 2. 判断是否是交替图像,如果是,需要设置初始位置

    self.rect.y = -self.rect.height

    def update(self):

    super().update()# 1. 调用父类的方法实现

    if self.rect.y >= SCREEN_RECT.height:# 2. 判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方

    self.rect.y = -self.rect.height

    class Enemy(GameSprite):

    """敌机精灵"""

    def __init__(self):

    super().__init__("C:/Users/Administrator/Desktop/enemy1.png")# 1. 调用父类方法,创建敌机精灵,同时指定敌机图片

    self.speed = random.randint(1, 3)# 2. 指定敌机的初始随机速度 1 ~ 3

    self.rect.bottom = 0# 3. 指定敌机的初始随机位置

    max_x = SCREEN_RECT.width - self.rect.width

    self.rect.x = random.randint(0, max_x)

    def update(self):

    super().update()# 1. 调用父类方法,保持垂直方向的飞行

    # 2. 判断是否飞出屏幕,如果是,需要从精灵组删除敌机

    if self.rect.y >= SCREEN_RECT.height:

    self.kill()

    # print("飞出屏幕,需要从精灵组删除...")

    # kill方法可以将精灵从所有精灵组中移出,精灵就会被自动销毁

    def __del__(self):

    # print("敌机挂了 %s" % self.rect)

    pass

    class Hero(GameSprite):

    """英雄精灵"""

    def __init__(self):

    super().__init__("C:/Users/Administrator/Desktop/me1.png", 0)

    self.rect.centerx = SCREEN_RECT.centerx

    self.rect.bottom = SCREEN_RECT.bottom - 120

    self.bullets = pygame.sprite.Group()

    def update(self):

    self.rect.x += self.speed

    if self.rect.x < 0:

    self.rect.x = 0

    elif self.rect.right > SCREEN_RECT.right:

    self.rect.right = SCREEN_RECT.right

    def fire(self):

    print("发射子弹...")

    for i in (0, 1, 2):

    bullet = Bullet()

    bullet.rect.bottom = self.rect.y - i * 20

    bullet.rect.centerx = self.rect.centerx

    self.bullets.add(bullet)

    class Bullet(GameSprite):

    """子弹精灵"""

    def __init__(self):

    super().__init__("C:/Users/Administrator/Desktop/bullet1.png", -2)

    def update(self):

    super().update()

    if self.rect.bottom < 0:

    self.kill()

    def __del__(self):

    print("子弹被销毁...")

    2.主类plane_main.py

    import pygame

    from plane_sprites import *

    class PlaneGame(object):

    """飞机大战主游戏"""

    def __init__(self):

    print("游戏初始化")

    self.screen = pygame.display.set_mode(SCREEN_RECT.size)

    self.clock = pygame.time.Clock()

    self.__create_sprites()

    pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)

    pygame.time.set_timer(HERO_FIRE_EVENT, 500)

    def __create_sprites(self):

    bg1 = Background()

    bg2 = Background(True)

    self.back_group = pygame.sprite.Group(bg1, bg2)

    self.enemy_group = pygame.sprite.Group()

    self.hero = Hero()

    self.hero_group = pygame.sprite.Group(self.hero)

    def start_game(self):

    print("游戏开始...")

    while True:

    self.clock.tick(FRAME_PER_SEC)

    self.__event_handler()

    self.__check_collide()

    self.__update_sprites()

    pygame.display.update()

    def __event_handler(self):

    for event in pygame.event.get():

    if event.type == pygame.QUIT:

    PlaneGame.__game_over()

    elif event.type == CREATE_ENEMY_EVENT:

    # print("敌机出场...")

    # 创建敌机精灵

    enemy = Enemy()

    self.enemy_group.add(enemy)

    elif event.type == HERO_FIRE_EVENT:

    self.hero.fire()

    # elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:

    # print("向右移动...")

    keys_pressed = pygame.key.get_pressed()

    if keys_pressed[pygame.K_RIGHT]:

    self.hero.speed = 2

    elif keys_pressed[pygame.K_LEFT]:

    self.hero.speed = -2

    else:

    self.hero.speed = 0

    def __check_collide(self):

    for event in pygame.event.get():

    if event.type == pygame.QUIT:

    PlaneGame.__game_over()

    elif event.type == CREATE_ENEMY_EVENT:

    enemy = Enemy()

    self.enemy_group.add(enemy)

    elif event.type == HERO_FIRE_EVENT:

    self.hero.fire()

    keys_pressed = pygame.key.get_pressed()

    if keys_pressed[pygame.K_RIGHT]:

    self.hero.speed = 2

    elif keys_pressed[pygame.K_LEFT]:

    self.hero.speed = -2

    else:

    self.hero.speed = 0

    def __check_collide(self):

    pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)

    enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)

    if len(enemies) > 0:

    self.hero.kill()

    PlaneGame.__game_over()

    def __update_sprites(self):

    self.back_group.update()

    self.back_group.draw(self.screen)

    self.enemy_group.update()

    self.enemy_group.draw(self.screen)

    self.hero_group.update()

    self.hero_group.draw(self.screen)

    self.hero.bullets.update()

    self.hero.bullets.draw(self.screen)

    @staticmethod

    def __game_over():

    print("游戏结束")

    pygame.quit()

    exit()

    if __name__ == '__main__':

    game = PlaneGame()

    game.start_game()

    上面就是飞机大战的代码了,还在等什么快去装环境运行一下去吧,如果遇到问题可以找小猿圈python讲师去解答,如果你想学习python开发,小猿圈还是很不错的,有需要的可以直接去看看的。

    展开全文
  • Python代码实现飞机大战

    万次阅读 多人点赞 2020-06-19 11:40:37
    文章目录经典飞机大战一.游戏设定二.我方飞机三.敌方飞机四.发射子弹五.发放补给包六.主模块 经典飞机大战 源代码以及素材资料(图片,音频)可从下面的github中下载: 飞机大战源代码以及素材资料github项目地址链接...

    参考资料

    • 《零基础入门学习python》

    源代码以及素材资料(图片,音频)可从下面的github中下载:

    —————————————————————————————————————————————————————

    经典飞机大战

    不知道大家有没有打过飞机,喜不喜欢打飞机。当我第一次接触这个东西的时候,我的内心是被震撼到的。第一次接触打飞机的时候作者本人是身心愉悦的,因为周边的朋友都在打飞机, 每次都会下意识彼此较量一下,看谁打得更好。打飞机也是需要有一定的技巧的,熟练的朋友一把能打上半个小时,生疏的则三五分钟就败下阵来。

    一.游戏设定

    游戏界面如下图所示
    游戏的基本设定:

    • 敌方共有大中小3款飞机,分为高中低三种速度;
    • 子弹的射程并非全屏,而大概是屏幕长度的80%;
    • 消灭小飞机需要1发子弹,中飞机需要8发,大飞机需要20发子弹;
    • 每消灭一架小飞机得1000分,中飞机6000分,大飞机10000分;
    • 每隔30秒有一个随机的道具补给,分为两种道具,全屏炸弹和双倍子弹;
    • 全屏炸弹最多只能存放3枚,双倍子弹可以维持18秒钟的效果;
    • 游戏将根据分数来逐步提高难度,难度的提高表现为飞机数量的增多以及速度的加快。

    另外还对游戏做了一些改进,比如为中飞机和大飞机增加了血槽的显示,这样玩家可以直观地知道敌机快被消灭了没有;我方有三次机会,每次被敌人消灭,新诞生的飞机会有3秒钟的安全期;游戏结束后会显示历史最高分数。

    这个游戏加上基本的注释代码量在800行左右,代码看上去比较多,多打代码少动脑。所以大家不要怕,越是多的代码,逻辑就越容易看得清楚,就越好学习。好,那让我们从无到有,从简单到复杂来一起打造这个游戏吧!

    二.我方飞机

    首先创建一个myplane. py模块来定义我方飞机:

    import pygame
    
    class MyPlane(pygame.sprite.Sprite):
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
    
            self.image1 = pygame.image.load("images/me1.png").convert_alpha()
            self.image2 = pygame.image.load("images/me2.png").convert_alpha()
            self.destroy_images = []
            self.destroy_images.extend([\
                pygame.image.load("images/me_destroy_1.png").convert_alpha(), \
                pygame.image.load("images/me_destroy_2.png").convert_alpha(), \
                pygame.image.load("images/me_destroy_3.png").convert_alpha(), \
                pygame.image.load("images/me_destroy_4.png").convert_alpha() \
                ])
            self.rect = self.image1.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.rect.left, self.rect.top = \
                            (self.width - self.rect.width) // 2, \
                            self.height - self.rect.height - 60
            self.speed = 10
            self.active = True
            self.invincible = False
            self.mask = pygame.mask.from_surface(self.image1)
    
        # 分别定义moveUp()、moveDown()、moveLeft()和moveRight()控制我方飞机上、下、左、右移动:
    
        def moveUp(self):
            if self.rect.top > 0:
                self.rect.top -= self.speed
            else:
                self.rect.top = 0
    
        def moveDown(self):
            if self.rect.bottom < self.height - 60:
                self.rect.top += self.speed
            else:
                self.rect.bottom = self.height - 60
    
        def moveLeft(self):
            if self.rect.left > 0:
                self.rect.left -= self.speed
            else:
                self.rect.left = 0
    
        def moveRight(self):
            if self.rect.right < self.width:
                self.rect.left += self.speed
            else:
                self.rect.right = self.width
    
        def reset(self):
            self.rect.left, self.rect.top = \
                            (self.width - self.rect.width) // 2, \
                            self.height - self.rect.height - 60
            self.active = True
            self.invincible = True
    
    

    三.敌方飞机

    既然英雄已经有了,那现在就是需要创造敌人的时候。敌机分为小、中、大三个尺寸,它们的速度依次是快、中、慢,在游戏界面的上方位置创造位置随机的敌机,可以让它们不在同一排出现。将敌机的定义写在enemy. py模块中:

    import pygame
    from random import *
    
    
    class SmallEnemy(pygame.sprite.Sprite):
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/enemy1.png").convert_alpha()
            self.destroy_images = []
            self.destroy_images.extend([ \
                pygame.image.load("images/enemy1_down1.png").convert_alpha(), \
                pygame.image.load("images/enemy1_down2.png").convert_alpha(), \
                pygame.image.load("images/enemy1_down3.png").convert_alpha(), \
                pygame.image.load("images/enemy1_down4.png").convert_alpha() \
                ])
            self.rect = self.image.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.speed = 2
            self.active = True
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-5 * self.height, 0)
            self.mask = pygame.mask.from_surface(self.image)
        
        def move(self):
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.reset()
        
        def reset(self):
            self.active = True
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-5 * self.height, 0)
    
    
    class MidEnemy(pygame.sprite.Sprite):
        energy = 8
        
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/enemy2.png").convert_alpha()
            self.image_hit = pygame.image.load("images/enemy2_hit.png").convert_alpha()
            self.destroy_images = []
            self.destroy_images.extend([ \
                pygame.image.load("images/enemy2_down1.png").convert_alpha(), \
                pygame.image.load("images/enemy2_down2.png").convert_alpha(), \
                pygame.image.load("images/enemy2_down3.png").convert_alpha(), \
                pygame.image.load("images/enemy2_down4.png").convert_alpha() \
                ])
            self.rect = self.image.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.speed = 1
            self.active = True
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-10 * self.height, -self.height)
            self.mask = pygame.mask.from_surface(self.image)
            self.energy = MidEnemy.energy
            self.hit = False
        
        def move(self):
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.reset()
        
        def reset(self):
            self.active = True
            self.energy = MidEnemy.energy
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-10 * self.height, -self.height)
    
    
    class BigEnemy(pygame.sprite.Sprite):
        energy = 20
        
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
            
            self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()
            self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()
            self.image_hit = pygame.image.load("images/enemy3_hit.png").convert_alpha()
            self.destroy_images = []
            self.destroy_images.extend([ \
                pygame.image.load("images/enemy3_down1.png").convert_alpha(), \
                pygame.image.load("images/enemy3_down2.png").convert_alpha(), \
                pygame.image.load("images/enemy3_down3.png").convert_alpha(), \
                pygame.image.load("images/enemy3_down4.png").convert_alpha(), \
                pygame.image.load("images/enemy3_down5.png").convert_alpha(), \
                pygame.image.load("images/enemy3_down6.png").convert_alpha() \
                ])
            self.rect = self.image1.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.speed = 1
            self.active = True
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-15 * self.height, -5 * self.height)
            self.mask = pygame.mask.from_surface(self.image1)
            self.energy = BigEnemy.energy
            self.hit = False
        
        def move(self):
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.reset()
        
        def reset(self):
            self.active = True
            self.energy = BigEnemy.energy
            self.rect.left, self.rect.top = \
                randint(0, self.width - self.rect.width), \
                randint(-15 * self.height, -5 * self.height)
    
    

    四.发射子弹

    现在的情况是我方飞机处于落后挨打的状态,敌强我弱,所以应该拿起武器进行反击! 接下来定义子弹,子弹分为两种: 一种是普通子弹一次只发射一颗; 另一种是补给发放的超级子弹一次可以发射两颗。

    我们将子弹定义为独立的模块bullet.py:

    import pygame
    
    
    class Bullet1(pygame.sprite.Sprite):
        def __init__(self, position):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/bullet1.png").convert_alpha()
            self.rect = self.image.get_rect()
            self.rect.left, self.rect.top = position
            self.speed = 12
            self.active = False
            self.mask = pygame.mask.from_surface(self.image)
        
        def move(self):
            self.rect.top -= self.speed
            
            if self.rect.top < 0:
                self.active = False
        
        def reset(self, position):
            self.rect.left, self.rect.top = position
            self.active = True
    
    
    class Bullet2(pygame.sprite.Sprite):
        def __init__(self, position):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/bullet2.png").convert_alpha()
            self.rect = self.image.get_rect()
            self.rect.left, self.rect.top = position
            self.speed = 14
            self.active = False
            self.mask = pygame.mask.from_surface(self.image)
        
        def move(self):
            self.rect.top -= self.speed
            
            if self.rect.top < 0:
                self.active = False
        
        def reset(self, position):
            self.rect.left, self.rect.top = position
            self.active = True
    
    

    五.发放补给包

    游戏设计每30秒随机发放一个补给包,可 能是超级子弹,也可能是全屏炸弹。补给包有自己的图像和运动轨迹,不妨单独为其定义一个模块supply.py:

    import pygame
    from random import *
    
    
    class Bullet_Supply(pygame.sprite.Sprite):
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/bullet_supply.png").convert_alpha()
            self.rect = self.image.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.rect.left, self.rect.bottom = \
                randint(0, self.width - self.rect.width), -100
            self.speed = 5
            self.active = False
            self.mask = pygame.mask.from_surface(self.image)
        
        def move(self):
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.active = False
        
        def reset(self):
            self.active = True
            self.rect.left, self.rect.bottom = \
                randint(0, self.width - self.rect.width), -100
    
    
    class Bomb_Supply(pygame.sprite.Sprite):
        def __init__(self, bg_size):
            pygame.sprite.Sprite.__init__(self)
            
            self.image = pygame.image.load("images/bomb_supply.png").convert_alpha()
            self.rect = self.image.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.rect.left, self.rect.bottom = \
                randint(0, self.width - self.rect.width), -100
            self.speed = 5
            self.active = False
            self.mask = pygame.mask.from_surface(self.image)
        
        def move(self):
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.active = False
        
        def reset(self):
            self.active = True
            self.rect.left, self.rect.bottom = \
                randint(0, self.width - self.rect.width), -100
    

    六.主模块

    所有的模块都到齐了,接下来就该实现我们的主模块了

    
    # main.py
    import pygame
    import sys
    import traceback
    import myplane
    import enemy
    import bullet
    import supply
    
    from pygame.locals import *
    from random import *
    
    pygame.init()
    pygame.mixer.init()
    
    bg_size = width, height = 480, 700
    screen = pygame.display.set_mode(bg_size)
    pygame.display.set_caption("飞机大战 -- FishC Demo")
    
    background = pygame.image.load("images/background.png").convert()
    
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    
    # 载入游戏音乐
    pygame.mixer.music.load("sound/game_music.ogg")
    pygame.mixer.music.set_volume(0.2)
    bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
    bullet_sound.set_volume(0.2)
    bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
    bomb_sound.set_volume(0.2)
    supply_sound = pygame.mixer.Sound("sound/supply.wav")
    supply_sound.set_volume(0.2)
    get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
    get_bomb_sound.set_volume(0.2)
    get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
    get_bullet_sound.set_volume(0.2)
    upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
    upgrade_sound.set_volume(0.2)
    enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
    enemy3_fly_sound.set_volume(0.2)
    enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
    enemy1_down_sound.set_volume(0.2)
    enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
    enemy2_down_sound.set_volume(0.2)
    enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
    enemy3_down_sound.set_volume(0.5)
    me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
    me_down_sound.set_volume(0.2)
    
    
    def add_small_enemies(group1, group2, num):
        for i in range(num):
            e1 = enemy.SmallEnemy(bg_size)
            group1.add(e1)
            group2.add(e1)
    
    
    def add_mid_enemies(group1, group2, num):
        for i in range(num):
            e2 = enemy.MidEnemy(bg_size)
            group1.add(e2)
            group2.add(e2)
    
    
    def add_big_enemies(group1, group2, num):
        for i in range(num):
            e3 = enemy.BigEnemy(bg_size)
            group1.add(e3)
            group2.add(e3)
    
    
    def inc_speed(target, inc):
        for each in target:
            each.speed += inc
    
    
    def main():
        pygame.mixer.music.play(-1)
        
        # 生成我方飞机
        me = myplane.MyPlane(bg_size)
        
        enemies = pygame.sprite.Group()
        
        # 生成敌方小型飞机
        small_enemies = pygame.sprite.Group()
        add_small_enemies(small_enemies, enemies, 15)
        
        # 生成敌方中型飞机
        mid_enemies = pygame.sprite.Group()
        add_mid_enemies(mid_enemies, enemies, 4)
        
        # 生成敌方大型飞机
        big_enemies = pygame.sprite.Group()
        add_big_enemies(big_enemies, enemies, 2)
        
        # 生成普通子弹
        bullet1 = []
        bullet1_index = 0
        BULLET1_NUM = 4
        for i in range(BULLET1_NUM):
            bullet1.append(bullet.Bullet1(me.rect.midtop))
        
        # 生成超级子弹
        bullet2 = []
        bullet2_index = 0
        BULLET2_NUM = 8
        for i in range(BULLET2_NUM // 2):
            bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))
            bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))
        
        clock = pygame.time.Clock()
        
        # 中弹图片索引
        e1_destroy_index = 0
        e2_destroy_index = 0
        e3_destroy_index = 0
        me_destroy_index = 0
        
        # 统计得分
        score = 0
        score_font = pygame.font.Font("font/font.ttf", 36)
        
        # 标志是否暂停游戏
        paused = False
        pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()
        pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()
        resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()
        resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()
        paused_rect = pause_nor_image.get_rect()
        paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
        paused_image = pause_nor_image
        
        # 设置难度级别
        level = 1
        
        # 全屏炸弹
        bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
        bomb_rect = bomb_image.get_rect()
        bomb_font = pygame.font.Font("font/font.ttf", 48)
        bomb_num = 3
        
        # 每30秒发放一个补给包
        bullet_supply = supply.Bullet_Supply(bg_size)
        bomb_supply = supply.Bomb_Supply(bg_size)
        SUPPLY_TIME = USEREVENT
        pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
        
        # 超级子弹定时器
        DOUBLE_BULLET_TIME = USEREVENT + 1
        
        # 标志是否使用超级子弹
        is_double_bullet = False
        
        # 解除我方无敌状态定时器
        INVINCIBLE_TIME = USEREVENT + 2
        
        # 生命数量
        life_image = pygame.image.load("images/life.png").convert_alpha()
        life_rect = life_image.get_rect()
        life_num = 3
        
        # 用于阻止重复打开记录文件
        recorded = False
        
        # 游戏结束画面
        gameover_font = pygame.font.Font("font/font.TTF", 48)
        again_image = pygame.image.load("images/again.png").convert_alpha()
        again_rect = again_image.get_rect()
        gameover_image = pygame.image.load("images/gameover.png").convert_alpha()
        gameover_rect = gameover_image.get_rect()
        
        # 用于切换图片
        switch_image = True
        
        # 用于延迟
        delay = 100
        
        running = True
        
        while running:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                
                elif event.type == MOUSEBUTTONDOWN:
                    if event.button == 1 and paused_rect.collidepoint(event.pos):
                        paused = not paused
                        if paused:
                            pygame.time.set_timer(SUPPLY_TIME, 0)
                            pygame.mixer.music.pause()
                            pygame.mixer.pause()
                        else:
                            pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
                            pygame.mixer.music.unpause()
                            pygame.mixer.unpause()
                
                elif event.type == MOUSEMOTION:
                    if paused_rect.collidepoint(event.pos):
                        if paused:
                            paused_image = resume_pressed_image
                        else:
                            paused_image = pause_pressed_image
                    else:
                        if paused:
                            paused_image = resume_nor_image
                        else:
                            paused_image = pause_nor_image
                
                elif event.type == KEYDOWN:
                    if event.key == K_SPACE:
                        if bomb_num:
                            bomb_num -= 1
                            bomb_sound.play()
                            for each in enemies:
                                if each.rect.bottom > 0:
                                    each.active = False
                
                elif event.type == SUPPLY_TIME:
                    supply_sound.play()
                    if choice([True, False]):
                        bomb_supply.reset()
                    else:
                        bullet_supply.reset()
                
                elif event.type == DOUBLE_BULLET_TIME:
                    is_double_bullet = False
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)
                
                elif event.type == INVINCIBLE_TIME:
                    me.invincible = False
                    pygame.time.set_timer(INVINCIBLE_TIME, 0)
            
            # 根据用户的得分增加难度
            if level == 1 and score > 50000:
                level = 2
                upgrade_sound.play()
                # 增加3架小型敌机、2架中型敌机和1架大型敌机
                add_small_enemies(small_enemies, enemies, 3)
                add_mid_enemies(mid_enemies, enemies, 2)
                add_big_enemies(big_enemies, enemies, 1)
                # 提升小型敌机的速度
                inc_speed(small_enemies, 1)
            elif level == 2 and score > 300000:
                level = 3
                upgrade_sound.play()
                # 增加5架小型敌机、3架中型敌机和2架大型敌机
                add_small_enemies(small_enemies, enemies, 5)
                add_mid_enemies(mid_enemies, enemies, 3)
                add_big_enemies(big_enemies, enemies, 2)
                # 提升小型敌机的速度
                inc_speed(small_enemies, 1)
                inc_speed(mid_enemies, 1)
            elif level == 3 and score > 600000:
                level = 4
                upgrade_sound.play()
                # 增加5架小型敌机、3架中型敌机和2架大型敌机
                add_small_enemies(small_enemies, enemies, 5)
                add_mid_enemies(mid_enemies, enemies, 3)
                add_big_enemies(big_enemies, enemies, 2)
                # 提升小型敌机的速度
                inc_speed(small_enemies, 1)
                inc_speed(mid_enemies, 1)
            elif level == 4 and score > 1000000:
                level = 5
                upgrade_sound.play()
                # 增加5架小型敌机、3架中型敌机和2架大型敌机
                add_small_enemies(small_enemies, enemies, 5)
                add_mid_enemies(mid_enemies, enemies, 3)
                add_big_enemies(big_enemies, enemies, 2)
                # 提升小型敌机的速度
                inc_speed(small_enemies, 1)
                inc_speed(mid_enemies, 1)
            
            screen.blit(background, (0, 0))
            
            if life_num and not paused:
                # 检测用户的键盘操作
                key_pressed = pygame.key.get_pressed()
                
                if key_pressed[K_w] or key_pressed[K_UP]:
                    me.moveUp()
                if key_pressed[K_s] or key_pressed[K_DOWN]:
                    me.moveDown()
                if key_pressed[K_a] or key_pressed[K_LEFT]:
                    me.moveLeft()
                if key_pressed[K_d] or key_pressed[K_RIGHT]:
                    me.moveRight()
                
                # 绘制全屏炸弹补给并检测是否获得
                if bomb_supply.active:
                    bomb_supply.move()
                    screen.blit(bomb_supply.image, bomb_supply.rect)
                    if pygame.sprite.collide_mask(bomb_supply, me):
                        get_bomb_sound.play()
                        if bomb_num < 3:
                            bomb_num += 1
                        bomb_supply.active = False
                
                # 绘制超级子弹补给并检测是否获得
                if bullet_supply.active:
                    bullet_supply.move()
                    screen.blit(bullet_supply.image, bullet_supply.rect)
                    if pygame.sprite.collide_mask(bullet_supply, me):
                        get_bullet_sound.play()
                        is_double_bullet = True
                        pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
                        bullet_supply.active = False
                
                # 发射子弹
                if not (delay % 10):
                    bullet_sound.play()
                    if is_double_bullet:
                        bullets = bullet2
                        bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery))
                        bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery))
                        bullet2_index = (bullet2_index + 2) % BULLET2_NUM
                    else:
                        bullets = bullet1
                        bullets[bullet1_index].reset(me.rect.midtop)
                        bullet1_index = (bullet1_index + 1) % BULLET1_NUM
                
                # 检测子弹是否击中敌机
                for b in bullets:
                    if b.active:
                        b.move()
                        screen.blit(b.image, b.rect)
                        enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)
                        if enemy_hit:
                            b.active = False
                            for e in enemy_hit:
                                if e in mid_enemies or e in big_enemies:
                                    e.hit = True
                                    e.energy -= 1
                                    if e.energy == 0:
                                        e.active = False
                                else:
                                    e.active = False
                
                # 绘制大型敌机
                for each in big_enemies:
                    if each.active:
                        each.move()
                        if each.hit:
                            screen.blit(each.image_hit, each.rect)
                            each.hit = False
                        else:
                            if switch_image:
                                screen.blit(each.image1, each.rect)
                            else:
                                screen.blit(each.image2, each.rect)
                        
                        # 绘制血槽
                        pygame.draw.line(screen, BLACK, \
                                         (each.rect.left, each.rect.top - 5), \
                                         (each.rect.right, each.rect.top - 5), \
                                         2)
                        # 当生命大于20%显示绿色,否则显示红色
                        energy_remain = each.energy / enemy.BigEnemy.energy
                        if energy_remain > 0.2:
                            energy_color = GREEN
                        else:
                            energy_color = RED
                        pygame.draw.line(screen, energy_color, \
                                         (each.rect.left, each.rect.top - 5), \
                                         (each.rect.left + each.rect.width * energy_remain, \
                                          each.rect.top - 5), 2)
                        
                        # 即将出现在画面中,播放音效
                        if each.rect.bottom == -50:
                            enemy3_fly_sound.play(-1)
                    else:
                        # 毁灭
                        if not (delay % 3):
                            if e3_destroy_index == 0:
                                enemy3_down_sound.play()
                            screen.blit(each.destroy_images[e3_destroy_index], each.rect)
                            e3_destroy_index = (e3_destroy_index + 1) % 6
                            if e3_destroy_index == 0:
                                enemy3_fly_sound.stop()
                                score += 10000
                                each.reset()
                
                # 绘制中型敌机:
                for each in mid_enemies:
                    if each.active:
                        each.move()
                        
                        if each.hit:
                            screen.blit(each.image_hit, each.rect)
                            each.hit = False
                        else:
                            screen.blit(each.image, each.rect)
                        
                        # 绘制血槽
                        pygame.draw.line(screen, BLACK, \
                                         (each.rect.left, each.rect.top - 5), \
                                         (each.rect.right, each.rect.top - 5), \
                                         2)
                        # 当生命大于20%显示绿色,否则显示红色
                        energy_remain = each.energy / enemy.MidEnemy.energy
                        if energy_remain > 0.2:
                            energy_color = GREEN
                        else:
                            energy_color = RED
                        pygame.draw.line(screen, energy_color, \
                                         (each.rect.left, each.rect.top - 5), \
                                         (each.rect.left + each.rect.width * energy_remain, \
                                          each.rect.top - 5), 2)
                    else:
                        # 毁灭
                        if not (delay % 3):
                            if e2_destroy_index == 0:
                                enemy2_down_sound.play()
                            screen.blit(each.destroy_images[e2_destroy_index], each.rect)
                            e2_destroy_index = (e2_destroy_index + 1) % 4
                            if e2_destroy_index == 0:
                                score += 6000
                                each.reset()
                
                # 绘制小型敌机:
                for each in small_enemies:
                    if each.active:
                        each.move()
                        screen.blit(each.image, each.rect)
                    else:
                        # 毁灭
                        if not (delay % 3):
                            if e1_destroy_index == 0:
                                enemy1_down_sound.play()
                            screen.blit(each.destroy_images[e1_destroy_index], each.rect)
                            e1_destroy_index = (e1_destroy_index + 1) % 4
                            if e1_destroy_index == 0:
                                score += 1000
                                each.reset()
                
                # 检测我方飞机是否被撞
                enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
                if enemies_down and not me.invincible:
                    me.active = False
                    for e in enemies_down:
                        e.active = False
                
                # 绘制我方飞机
                if me.active:
                    if switch_image:
                        screen.blit(me.image1, me.rect)
                    else:
                        screen.blit(me.image2, me.rect)
                else:
                    # 毁灭
                    if not (delay % 3):
                        if me_destroy_index == 0:
                            me_down_sound.play()
                        screen.blit(me.destroy_images[me_destroy_index], me.rect)
                        me_destroy_index = (me_destroy_index + 1) % 4
                        if me_destroy_index == 0:
                            life_num -= 1
                            me.reset()
                            pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)
                
                # 绘制全屏炸弹数量
                bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE)
                text_rect = bomb_text.get_rect()
                screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
                screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))
                
                # 绘制剩余生命数量
                if life_num:
                    for i in range(life_num):
                        screen.blit(life_image, \
                                    (width - 10 - (i + 1) * life_rect.width, \
                                     height - 10 - life_rect.height))
                
                # 绘制得分
                score_text = score_font.render("Score : %s" % str(score), True, WHITE)
                screen.blit(score_text, (10, 5))
            
            # 绘制游戏结束画面
            elif life_num == 0:
                # 背景音乐停止
                pygame.mixer.music.stop()
                
                # 停止全部音效
                pygame.mixer.stop()
                
                # 停止发放补给
                pygame.time.set_timer(SUPPLY_TIME, 0)
                
                if not recorded:
                    recorded = True
                    # 读取历史最高得分
                    with open("record.txt", "r") as f:
                        record_score = int(f.read())
                    
                    # 如果玩家得分高于历史最高得分,则存档
                    if score > record_score:
                        with open("record.txt", "w") as f:
                            f.write(str(score))
                
                # 绘制结束画面
                record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))
                screen.blit(record_score_text, (50, 50))
                
                gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
                gameover_text1_rect = gameover_text1.get_rect()
                gameover_text1_rect.left, gameover_text1_rect.top = \
                    (width - gameover_text1_rect.width) // 2, height // 3
                screen.blit(gameover_text1, gameover_text1_rect)
                
                gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))
                gameover_text2_rect = gameover_text2.get_rect()
                gameover_text2_rect.left, gameover_text2_rect.top = \
                    (width - gameover_text2_rect.width) // 2, \
                    gameover_text1_rect.bottom + 10
                screen.blit(gameover_text2, gameover_text2_rect)
                
                again_rect.left, again_rect.top = \
                    (width - again_rect.width) // 2, \
                    gameover_text2_rect.bottom + 50
                screen.blit(again_image, again_rect)
                
                gameover_rect.left, gameover_rect.top = \
                    (width - again_rect.width) // 2, \
                    again_rect.bottom + 10
                screen.blit(gameover_image, gameover_rect)
                
                # 检测用户的鼠标操作
                # 如果用户按下鼠标左键
                if pygame.mouse.get_pressed()[0]:
                    # 获取鼠标坐标
                    pos = pygame.mouse.get_pos()
                    # 如果用户点击“重新开始”
                    if again_rect.left < pos[0] < again_rect.right and \
                            again_rect.top < pos[1] < again_rect.bottom:
                        # 调用main函数,重新开始游戏
                        main()
                    # 如果用户点击“结束游戏”
                    elif gameover_rect.left < pos[0] < gameover_rect.right and \
                            gameover_rect.top < pos[1] < gameover_rect.bottom:
                        # 退出游戏
                        pygame.quit()
                        sys.exit()
                        
                        # 绘制暂停按钮
            screen.blit(paused_image, paused_rect)
            
            # 切换图片
            if not (delay % 5):
                switch_image = not switch_image
            
            delay -= 1
            if not delay:
                delay = 100
            
            pygame.display.flip()
            clock.tick(60)
    
    
    if __name__ == "__main__":
        try:
            main()
        except SystemExit:
            pass
        except:
            traceback.print_exc()
            pygame.quit()
            input()
    
    

    切记: 所有的模块应该放在同一个文件夹下

    最后运行我们的主模块就大功告成了!

    下面是运行结果:

    展开全文
  • python游戏飞机大战

    2020-09-13 19:29:16
    飞机大战,代码+音效+图片,很全,自己配置好环境,可以直接运行的那种。适合新手学习python开发游戏
  • 采用python开发飞机大战源码,摈除了复杂的逻辑,简单易学,非常适合初学者。开发一个小游戏,能够提高程序开发兴趣,python入门利器,。
  • 往期回顾 Python实现“小兔子和Bun”游戏 ...今日周六给大家安利一波用Python制作一个简易版的类"飞机大战"游戏,让我们愉快地开始吧~ 效果 开发工具 **Python版本:**3.6.4 相关模块: pygame模块; 以及一些P

    往期回顾

    Python实现“小兔子和Bun”游戏

    Python实现八音符小游戏

    Python实现拼图小游戏

    Python实现滑雪小游戏

    Python实现经典90坦克大战

    Python实现FlappyBird的小游戏

    Python实恐龙跳一跳小游戏现

    Python实现塔防小游戏

    Python实现接水果和金币小游戏

    前言

    今日周六给大家安利一波用Python制作一个简易版的类"飞机大战"游戏,让我们愉快地开始吧~

    效果

    image.png

    开发工具

    **Python版本:**3.6.4

    相关模块:

    pygame模块;

    以及一些Python自带的模块。

    环境搭建

    安装Python并添加到环境变量,pip安装需要的相关模块即可。

    原理简介

    游戏规则简介:

    游戏模式包括单人模式和双人模式。

    单人模式中,玩家通过↑↓←→控制飞船行动,J键发射炮弹;双人模式中,玩家一通过↑↓←→控制飞船行动,J键发射炮弹,玩家二通过wsad控制飞船行动,空格键发射炮弹。每击碎一个小行星(或者说陨石),玩家得分加一,若所有玩家均被小行星击中,则游戏结束。

    逐步实现:

    Step1:定义精灵类

    首先,我们定义一下游戏中涉及到碰撞检测的三个精灵类,也就是小行星(陨石)类:

    图片

    子弹类:

    图片

    飞船类:

    图片

    子弹发射后,只需要一直向前飞就行了,小行星和子弹类似,产生后,只需要一直向前飞,然后顺便旋转一下就行了,飞船类则需要拥有发射子弹的能力以及被小行星击中后爆炸的"能力"。

    Step2:实现游戏主循环

    先初始化:

    图片

    然后就可以进入游戏主循环了,主循环包括按键检测并根据检测结果行动飞船:

    图片

    向下移动背景图实现飞船向上移动的效果:

    image.png

    画子弹、飞船和小行星,并进行必要的碰撞检测等操作:

    图片

    Step3:制作简易的游戏开始和结束界面

    游戏开始界面:

    图片

    游戏结束界面:

    图片

    Step4:整合游戏开始、游戏进行和游戏结束界面

    图片

    文章到这里就结束了,感谢你的观看,Python24个小游戏系列,下篇文章分享俄罗斯方块小游戏

    为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。

    干货主要有:

    ① 2000多本Python电子书(主流和经典的书籍应该都有了)

    ② Python标准库资料(最全中文版)

    ③ 项目源码(四五十个有趣且经典的练手项目及源码)

    ④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

    ⑤ Python学习路线图(告别不入流的学习)

    ⑥ 两天的Python爬虫训练营直播权限

    All done~点个收藏支持下~详见个人简介或者私信获取完整源代码。。

    展开全文
  • Python开发飞机大战游戏源代码,由于非常简单所以不是很难学的。直接阅读代码
  • 基于python Pygame的飞机大战游戏开发 文章目录基于python Pygame的飞机大战游戏开发**一、项目介绍****1.1 简介****1.2 所用到的知识点****1.3 开发验环境****1.2 代码获取****二、开发准备****三、项目代码解析**...

    基于python Pygame的飞机大战游戏开发

    一、项目介绍

    1.1 简介

    基于python 的pygame库函数,开发了一个飞机大战的游戏,具体实现的功能,通过按键控制飞机实现上下左右的移动,游戏效果如下:

    image-20210605144207172

    1.2 所用到的知识点

    1. Pygame图形
    2. Pygame动画
    3. Pygame文字
    4. Pygame音频
    5. Pygame事件

    1.3 开发验环境

    1. Python 3.7
    2. Windows10 vscode

    1.2 代码获取

    本项目所用到的代码和相关资源文件已经长传至本人github,下载链接:ISOEhy/AircraftWars: 基于python pygame的飞机大战游戏 (github.com)

    二、开发准备

    本次课程主要利用Pygame模块来进行开发,首先打开cmd终端,并使用 pip 命令来安装Pygame

    pip install pygame
    

    安装完成之后进入Python的交互界面,输入以下命令查看是否成功安装。

    import pygame
    

    若无异常,如下图所示,则说明安装成功。

    image-20210605142837986

    三、项目代码解析

    3.1 HelloWorld

    首先开始我们第一个HelloWorld程序:

    # -*- coding: UTF-8 -*-
    # helloworld.py
     
    # 导入所需的模块
    import pygame, sys
    # 导入所有pygame.locals里的变量(比如下面大写的QUIT变量)
    from pygame.locals import *
     
     
    # 初始化pygame
    pygame.init()
     
    # 设置窗口的大小,单位为像素
    screen = pygame.display.set_mode((500, 400))
     
    # 设置窗口标题
    pygame.display.set_caption('Hello World')
     
    # 程序主循环
    while True:
     
      # 获取事件
      for event in pygame.event.get():
        # 判断事件是否为退出事件
        if event.type == QUIT:
          # 退出pygame
          pygame.quit()
          # 退出系统
          sys.exit()
     
      # 绘制屏幕内容
      pygame.display.update()
    

    效果图如下:

    image-20210605143142521

    这里解释一下上面程序的运行方式

    一个游戏循环(也可以称为主循环)就做下面这三件事:

    1. 处理事件
    2. 更新游戏状态
    3. 绘制游戏状态到屏幕上

    3.2 飞机类

    定义飞机类,初始化属性。加载飞机图片,并获取飞机的坐标,将飞机放置在合适的位置上。飞机这个类有几个方法,首先就是上下左右移动,通过key_control 方法实现按键控制它的移动和子弹的发射,update方法更新飞机的位置,display方法将飞机显示在屏幕上。

    要想实现通过按键控制游戏,就要用到pygame中的事件,Pygame里常用的事件如下表:

    事件 产生途径 参数
    QUIT 用户按下关闭按钮 none
    ACTIVEEVENT Pygame被激活或者隐藏 gain, state
    KEYDOWN 键盘被按下 unicode, key, mod
    KEYUP 键盘被放开 key, mod
    MOUSEMOTION 鼠标移动 pos, rel, buttons
    MOUSEBUTTONDOWN 鼠标按下 pos, button
    MOUSEBUTTONUP 鼠标放开 pos, button
    VIDEORESIZE Pygame窗口缩放 size, w, h

    代码如下:

    class HeroPlane(pygame.sprite.Sprite):
        # 存放所有飞机的子弹的组
        bullets = pygame.sprite.Group()
    
        def __init__(self, screen):
            # 这个精灵的初始化方法 必须调用
            pygame.sprite.Sprite.__init__(self)
            # 图片
            self.image = pygame.image.load('./feiji/hero1.png')
            # 根据图片image获取矩形的对象
            self.rect = self.image.get_rect()  # rect属性:矩形
            self.rect.topleft = [Manager.bg_size[0] / 2 - 100 / 2, 600]  # 矩形左上角坐
            # 窗口
            self.screen = screen
            self.screen_rect = screen.get_rect()
            # Start each new ship at the bottom center of the screen.
            self.rect.centerx = self.screen_rect.centerx
            self.rect.bottom = self.screen_rect.bottom
    
            # Store a decimal value for the ship's center.
            self.centerx = float(self.rect.centerx)
            self.centery = float(self.rect.centery)
            # 速度
            self.speed = 15
            # pygame.sprite.Group()生成一个放精灵的对象 类似一个列表
            self.bullets = pygame.sprite.Group()
    
        def key_control(self):
            """
            按键的监听 用来改变飞机坐标
            """
            # 监听键盘事件  键盘一直按下
            key_pressed = pygame.key.get_pressed()  # 注意这种方式是能够检测到连续按下的,比之前的版本要新
    
            # 改变飞机坐标
            if (key_pressed[K_w] or key_pressed[K_UP])and self.rect.top> self.screen_rect.top:#判断飞机是否处于屏幕范围内
                self.rect.top -= self.speed
            if (key_pressed[K_s] or key_pressed[K_DOWN]) and self.rect.bottom <self.screen_rect.bottom:
                self.rect.bottom += self.speed
                print(self.rect.bottom,self.screen_rect.bottom)
            if (key_pressed[K_a] or key_pressed[K_LEFT])and  self.rect.left > 0:
                self.rect.left -= self.speed
            if (key_pressed[K_d] or key_pressed[K_RIGHT]) and self.rect.right < self.screen_rect.right:
                self.rect.right += self.speed
            if key_pressed[K_SPACE]:
                # 按下空格键 发射一枚子弹 把飞机的坐标传入子弹
                bullet = Bullet(self.screen, self.rect.left, self.rect.top)
                # 把子弹放到列表里
                self.bullets.add(bullet)
                # 存放所有飞机的子弹的组
                HeroPlane.bullets.add(bullet)
    
        # 调用飞机的更新方法,更新飞机的位置
        def update(self):
            self.key_control()
            self.display()
    
        def display(self):
            """显示飞机到窗口"""
            self.screen.blit(self.image, self.rect)
            # 更新子弹坐标
            self.bullets.update()
    
            # 把所有的子弹全部添加到屏幕
            self.bullets.draw(self.screen)
    
        @classmethod
        def clear_bullets(cls):
            # 清空子弹
            cls.bullets.empty()
    

    飞机还有一个属性,就是子弹,我们可以将子弹也定义为一个类,包含了子弹的图片,子弹的位置,超出区域或者碰撞后消失。

    # 子弹类
    # 属性  坐标 速度 图片
    class Bullet(pygame.sprite.Sprite):
    
        def __init__(self, screen, x, y):
            pygame.sprite.Sprite.__init__(self)
            # 图片
            self.image = pygame.image.load('./feiji/bullet.png')
            self.rect = self.image.get_rect()  # rect属性:矩形
            self.rect.topleft = [x + 100 / 2 - 22 / 2, y - 25]  # 矩形左上角坐
            # 窗口
            self.screen = screen
            # 速度
            self.speed = 20
    
        def update(self):
            # 修改子弹坐标
            self.rect.top -= self.speed
            # 如果子弹移出屏幕上方,则销毁子弹对象
            if self.rect.top < -22:
                # 超出界面 干掉自己
                self.kill()
    

    3.3 定义敌方飞机类

    敌方飞机和我方飞机本质是一样的,属性和方法类似,不同的是,敌方飞机是自动移动和自动开火的。敌机随机从屏幕左上方或右上方出现,在碰到左方的墙壁或者右边的墙壁后反向移动。同时,通过random模块实现自动开火,具体实现方法是,随机生成1-20的数,如果这个随机数为8就发射子弹,可以通过更改随机数范围降低游戏难度。

    class EnemyPlane(pygame.sprite.Sprite):
        """敌方飞机"""
        # 敌方所有子弹  类属性
        enemy_bullets = pygame.sprite.Group()
    
        def __init__(self, screen):
            pygame.sprite.Sprite.__init__(self)
            # 5.创建一个飞机的图片
            self.image = pygame.image.load('./feiji/enemy0.png')  # 51*39
            self.rect = self.image.get_rect()
            x = random.randrange(1, Manager.bg_size[0], 50)
            self.rect.topleft = [x, 0]
    
            # 飞机的速度
            self.speed = 10
    
            # 记录当前的窗口对象
            self.screen = screen
            # 装子弹的列表
            self.bullets = pygame.sprite.Group()
            # 飞机左右飞的方向 一开始向右
            self.direction = 'right'
    
        def display(self):
            """显示飞机到窗口"""
            self.screen.blit(self.image, self.rect)
            # 所有子弹更新坐标
            self.bullets.update()
            # 所有子弹贴到屏幕
            self.bullets.draw(self.screen)
    
        def update(self):
            self.auto_move()
            self.auto_fire()
            self.display()
    
        def auto_move(self):
            # 一开始 飞机在左上角 向右移动
            if self.direction == 'right':
                self.rect.right += self.speed
            elif self.direction == 'left':
                self.rect.right -= self.speed
    
            if self.rect.right > Manager.bg_size[0] - 51:
                # 如果移动到最右侧 把方向改成左
                self.direction = 'left'
            elif self.rect.right < 0:
                # 如果移动到最右左侧 把方向改成右
                self.direction = 'right'
    
            self.rect.bottom += self.speed
    
        def auto_fire(self):
            # 获取一个随机数
            random_num = random.randint(1, 20)
            # 降低概率发射子弹  当前是1/20的概率
            if random_num == 8:
                """自动开火 创建子弹对象 添加到列表里"""
                bullet = EnemyBullet(self.screen, self.rect.left, self.rect.top)
                self.bullets.add(bullet)
                # 把子弹添加到类属性的子弹组里
                EnemyPlane.enemy_bullets.add(bullet)
    
        @classmethod
        def clear_bullets(cls):
            # 清空子弹  empty是精灵组提供的方法 用来清空精灵组
            cls.enemy_bullets.empty()
    
    
    # 敌方子弹类
    # 属性  坐标 速度 图片
    class EnemyBullet(pygame.sprite.Sprite):
    
        def __init__(self, screen, x, y):
            pygame.sprite.Sprite.__init__(self)
            # 坐标
            # 图片
            self.image = pygame.image.load('./feiji/bullet1.png')  # 9*21
            self.rect = self.image.get_rect()  # rect属性:矩形
            self.rect.topleft = [x + 50 / 2 - 8 / 2, y + 39]  # 矩形左上角坐
            # 窗口
            self.screen = screen
            # 速度
            self.speed = 15
    
        def update(self):
            # 修改子弹坐标
            self.rect.bottom += self.speed
            # 如果子弹移出屏幕上方,则销毁子弹对象
            if self.rect.top > Manager.bg_size[1]:
                self.kill()
    

    3.4 爆炸类-中弹或者是碰撞动画

    由于人类眼睛的特殊生理结构,当所看画面的帧率高于24的时候,就会认为是连贯的,此现象称之为 视觉暂留 。

    帧率(Frame rate)是用于测量显示帧数的量度,所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)一般来说30fps是可以接受的,但是将性能提升至60fps则可以明显提升交互感和逼真感,但是一般来说超过75fps一般就不容易察觉到有明显的流畅度提升了。在我们原有坐标系的基础上添加偏移量,再重新绘制,依次一张一张的循环绘制下去,就会得到我们想要的物体移动的效果。

    Pygame实现动画主要用到的方法:

    pygame.image.load(filename)加载一张图片

    pygame.Surface.blit(source, dest, area=None, special_flags = 0)将图片绘制到屏幕相应坐标上(后面两个参数默认,可以不传)

    pygame.time.Clock()获得pygame的时钟

    pygame.time.Clock.tick(FPS)设置pygame时钟的间隔时间

    以下为示例代码:

    class Bomb(object):
        # 初始化爆炸
        def __init__(self, screen, type):
            self.screen = screen
            if type == 'enemy':
                # 加载爆炸资源
                self.mImages = [
                    pygame.image.load("./feiji/enemy0_down" + str(v) + ".png") for v in range(1, 5)]
            else:
                # 加载爆炸资源
                self.mImages = [pygame.image.load(
                    "./feiji/hero_destroy" + str(v) + ".png") for v in range(1, 4)]
    
            self.mImages += self.mImages
    
            # 设置当前爆炸播放索引
            self.mIndex = 0
            # 爆炸位置
            self.mPos = [0, 0]
            # 是否可见
            self.mVisible = False
    
        # 设置位置
        def action(self, rect):
            # 触发爆炸方法draw
            # 爆炸的坐标
            self.mPos[0] = rect.left
            self.mPos[1] = rect.top
            # 打开爆炸的开关
            self.mVisible = True
    
        # 绘制爆炸
        def draw(self):
            if not self.mVisible:
                return
            self.screen.blit(self.mImages[self.mIndex], (self.mPos[0], self.mPos[1]))
            self.mIndex += 1
            if self.mIndex >= len(self.mImages):
                # 如果下标已经到最后 代表爆炸结束
                # 下标重置 mVisible重置
                self.mIndex = 0
                self.mVisible = False
    

    3.5 动态游戏背景

    游戏背景可以使得游戏更加吸引研究,而动态背景则让游戏更加生动,要实现背景的移动,可以通过两张图片拼接的方式,两张图片是特殊处理的,实现平滑过渡,在游戏开始后自动变换图片的位置就能达到游戏背景移动的效果。

    # 地图
    class GameBackground(object):
        # 初始化地图
        def __init__(self, screen):
            self.mImage1 = pygame.image.load("./feiji/img_bg_level_2.jpg")
            self.mImage2 = pygame.image.load("./feiji/img_bg_level_2.jpg")
            # 窗口
            self.screen = screen
            # 辅助移动地图
            self.y1 = 0
            self.y2 = -Manager.bg_size[1]  # -768
    
        # 移动地图
    
        def move(self):
            self.y1 += 2
            self.y2 += 2
            if self.y1 >= Manager.bg_size[1]:
                self.y1 = 0
            if self.y2 >= 0:
                self.y2 = -Manager.bg_size[1]
    
        # 绘制地图
        def draw(self):
            self.screen.blit(self.mImage1, (0, self.y1))
            self.screen.blit(self.mImage2, (0, self.y2))
    

    3.6 绘制文字

    为了显示分数,那么我们就得在屏幕上绘制文字,Pygame提供了很方便的方法使用.ttf字体文件,这样我们就能很轻易的将文字绘制在屏幕上了。常用到的方法:

    pygame.font.Font(filename, size)

    filename:字体文件的文件名;

    size:字体的高height,单位为像素;

    pygame.font.Font.render(text, antialias, color, background=None)

    text:要显示的文字;

    antialias: 是否抗锯齿;

    color:字体颜色;

    background:背景颜色(可选参数);

    .get_rect()

    获得一个对象的rect,以便于设置其坐标位置

    以下为示例代码:

        # 绘制文字  rgb 红绿蓝 0 - 255
        # 参1要绘制的文字 参2 x轴坐标 参3y轴坐标 参4文字大小 参5 文字颜色 参6 背景颜色
        def drawText(self, text, x, y, textHeight=30, fontColor=(255, 255, 255), backgroudColor=None):
    
            # 通过字体文件获得字体对象  参数1 字体文件 参数2 字体大小
            font_obj = pygame.font.Font('./feiji/baddf.ttf', textHeight)
            # 1文字  2是否抗锯齿 3文字颜色 4背景颜色
            text_obj = font_obj.render(text, True, fontColor, backgroudColor)  # 配置要显示的文字
            # 获得要显示的对象的rect
            text_rect = text_obj.get_rect()
            # 设置显示对象的坐标
            text_rect.topleft = (x, y)
            # 绘制字 到指定区域  参1是文字对象 参2 矩形对象
            self.screen.blit(text_obj, text_rect)
    

    3.7 播放音频

    在Pygame里播放音频有两个方法,一个用来播放特效声音,一个用来播放背景音乐:

    pygame.mixer.Sound(filename) :该方法返回一个Sound对象,调用它的.play( )方法,即可播放较短的音频文件(比如玩家受到伤害、收集到金币等);

    pygame.mixer.music.load(filename):该方法用来加载背景音乐,之后调用pygame.mixer.music.play( )方法就可以播放背景音乐(Pygame只允许加载一个背景音乐在同一个时刻)

    以下为示例代码:

    class GameSound(object):
        def __init__(self):
            pygame.mixer.init()  # 音乐模块初始化
            pygame.mixer.music.load("./feiji/bg2.ogg")
            pygame.mixer.music.set_volume(0.5)  # 声音大小 一半
    
            self.__bomb = pygame.mixer.Sound("./feiji/bomb.wav")
    
        def playBackgroundMusic(self):
            pygame.mixer.music.play(-1)  # 开始播放背景音乐
    
        def playBombSound(self):
            pygame.mixer.Sound.play(self.__bomb)  # 爆炸音乐
    

    3.8 飞机大战的主函数

    在主函数中,是实现整个游戏的骨架,上面的各个类都将在这里面调用

    class Manager(object):
        bg_size = (512, 768)
        # 创建敌机定时器的id
        create_enemy_id = 10
        # 游戏结束 倒计时的id
        game_over_id = 11
        # 游戏是否结束
        is_game_over = False
        # 倒计时时间
        over_time = 3
    
        def __init__(self):
            pygame.init()
            # 1创建一个窗口 Manager.bg_size 是宽高
            self.screen = pygame.display.set_mode(Manager.bg_size, 0, 32)
            pygame.display.set_caption("飞机大战")
            # 2创建一个背景图片
            #play_button = Button(self.screen, "Play")
            self.background = pygame.image.load('./feiji/background.png')
            self.map = GameBackground(self.screen)
            self.score = 0
            # 初始化一个装玩家精灵的group
            self.players = pygame.sprite.Group()
            # 初始化一个装敌机精灵的group
            self.enemys = pygame.sprite.Group()
    
            # 初始化一个玩家爆炸的对象
            self.player_bomb = Bomb(self.screen, 'player')
            # 初始化一个敌机爆炸的对象
            self.enemy_bomb = Bomb(self.screen, 'enemy')
            # 初始化一个声音播放的对象
            self.sound = GameSound()
    
        def exit(self):
            print('退出')
            # 执行pygame退出
            pygame.quit()
            # python程序的退出
            exit()
    
        def show_over_text(self):
            # 游戏结束 倒计时后重新开始
            self.drawText('gameover %d' % Manager.over_time, 100, Manager.bg_size[1] / 2,
                          textHeight=50, fontColor=[255, 0, 0])
    
        def game_over_timer(self):
            self.show_over_text()
            # 倒计时-1
            Manager.over_time -= 1
            if Manager.over_time == 0:
                # 参数2改为0 定时间停止
                pygame.time.set_timer(Manager.game_over_id, 0)
                # 倒计时后重新开始
                Manager.over_time = 3
                Manager.is_game_over = False
                self.start_game()
    
        def start_game(self):
            # 重新开始游戏 有些类属性要清空
            EnemyPlane.clear_bullets()
            HeroPlane.clear_bullets()
            manager = Manager()
            manager.main()
    
        def new_player(self):
            # 创建一个飞机的对象 添加到玩家的组
            player = HeroPlane(self.screen)
            self.players.add(player)
    
        def new_enemy(self):
            # 创建一个飞机的对象 添加到敌机的组
            enemy = EnemyPlane(self.screen)
            self.enemys.add(enemy)
    
        # 绘制文字  rgb 红绿蓝 0 - 255
        # 参1要绘制的文字 参2 x轴坐标 参3y轴坐标 参4文字大小 参5 文字颜色 参6 背景颜色
        def drawText(self, text, x, y, textHeight=30, fontColor=(255, 255, 255), backgroudColor=None):
    
            # 通过字体文件获得字体对象  参数1 字体文件 参数2 字体大小
            font_obj = pygame.font.Font('./feiji/baddf.ttf', textHeight)
            # 1文字  2是否抗锯齿 3文字颜色 4背景颜色
            text_obj = font_obj.render(text, True, fontColor, backgroudColor)  # 配置要显示的文字
            # 获得要显示的对象的rect
            text_rect = text_obj.get_rect()
            # 设置显示对象的坐标
            text_rect.topleft = (x, y)
            # 绘制字 到指定区域  参1是文字对象 参2 矩形对象
            self.screen.blit(text_obj, text_rect)
    
        def main(self):
            
            # 播放背景音乐
            self.sound.playBackgroundMusic()
            # 创建一个玩家
            self.new_player()
            # 开启创建敌机的定时器
            pygame.time.set_timer(Manager.create_enemy_id, 1000)
            while True:
                # 把背景图片贴到窗口里  可以盖住上一次的飞机
                # self.screen.blit(self.background, (0, 0))
    
                # 移动地图
                self.map.move()
                # 把地图画到窗口上
                self.map.draw()
    
                # 绘制文字
                self.drawText('Score:%d'%self.score, 0, 0)
                if Manager.is_game_over:
                    # 判断游戏结束才显示结束文字
                    self.show_over_text()
    
                # 获取事件 这样pygame才能正常响应  pygame.event.get()得到的是一个事件列表
                for event in pygame.event.get():
                    # 判断事件类型如果是 点击pygame窗口的×号
                    if event.type == QUIT:
                        self.exit()
                    elif event.type == Manager.create_enemy_id:
                        # 创建一个敌机
                        self.new_enemy()
                    # 定时器触发的事件
                    elif event.type == Manager.game_over_id:
                        self.game_over_timer()
                #  调用爆炸的爆炸
                self.player_bomb.draw()
                self.enemy_bomb.draw()
    
                if self.players.sprites():
                    # 判断一个精灵和一个精灵组之间的碰撞 返回被碰撞的敌方飞机
                    # 玩家飞机和敌方子弹 参数一是玩家飞机 参数二是敌方所有飞机的所有的子弹
                    isover = pygame.sprite.spritecollide(self.players.sprites()[0], EnemyPlane.enemy_bullets, True)
                    if isover:
                        Manager.is_game_over = True  # 标识游戏结束
                        # pygame提供的定时器服务 参数一是标识定时器的唯一的id 参数2是间隔时间 毫秒
                        pygame.time.set_timer(Manager.game_over_id, 1000)  # 开启游戏倒计时
                        print('中弹')
                        self.player_bomb.action(self.players.sprites()[0].rect)
                        # 把玩家飞机 从精灵组移除
                        self.players.remove(self.players.sprites()[0])
                        # 爆炸的声音
                        self.sound.playBombSound()
    
                    # 判断碰撞 只能判断两个精灵组之间的碰撞
                    iscollide = pygame.sprite.groupcollide(self.players, self.enemys, True, True)
    
                    if iscollide:
                        Manager.is_game_over = True  # 标识游戏结束
                        pygame.time.set_timer(Manager.game_over_id, 1000)  # 开启游戏倒计时
                        # [(x, (y))]
                        items = list(iscollide.items())[0]
                        print(items)  # (x, (y,))
                        x = items[0]
                        y = items[1][0]
                        # print(x.speed, y.speed)
                        # 玩家爆炸图片
                        self.player_bomb.action(x.rect)
                        # 敌机爆炸图片
                        self.enemy_bomb.action(y.rect)
                        # 爆炸的声音
                        self.sound.playBombSound()
    
                    # 玩家所有子弹和所有敌机的碰撞
                    is_enemy = pygame.sprite.groupcollide(HeroPlane.bullets, self.enemys, True, True)
                    if is_enemy:
                        items = list(is_enemy.items())[0]
                        self.score+=100
                        y = items[1][0]
                        # # 敌机爆炸图片
                        self.enemy_bomb.action(y.rect)
                        # # 爆炸的声音
                        self.sound.playBombSound()
    
                # 玩家飞机和子弹的显示
                self.players.update()
                # 敌机和子弹的显示
                self.enemys.update()
    
                # 4刷新显示窗口内容
                pygame.display.update()
                # 取一个合适的值 循环时停一下  单位是秒 减少cpu的消耗
                time.sleep(0.03)
    
    
    if __name__ == '__main__':
        manager = Manager()
        manager.main()
    
    
    展开全文
  • 1.引言1.1 项目背景python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、...为了加深对python的了解,决定用python开发一个飞机大战游戏1.2 实现功能用python实现一个飞机大战游戏,实...
  • importpygamefrom pygame.locals import *importtimeimportrandom#创建飞机的基类classBasePlane(object):def __init__(self, screen, x, y, image):self.x=xself.y=yself.screen=screenself.image=pygame.image....
  • Python游戏开发-飞机大战想要代码文件,可以加我微信:nickchen121#!/usr/bin/env python# coding: utf-8import pygameimport timeimport randomfrom pygame.locals import *class Base(object):def __init__(self...
  • 本文实例讲述了python飞机大战pygame游戏框架搭建操作。分享给大家供大家参考,具体如下:目标明确主程序职责实现主程序类准备游戏精灵组01. 明确主程序职责回顾 快速入门案例,一个游戏主程序的 职责 可以分为两个...
  • 基于Python飞机大战游戏杨铠【期刊名称】《电脑迷》【年(卷),期】2017(000)021【摘要】我们每天都享受到科技带来的好处,了解计算机编程对每个人来说十分重要,学习Python可作为一种了解计算机编程的方法.Python是一...
  • 一个使用pyxel引擎开发飞机大战游戏
  • Python游戏-飞机大战

    2018-12-09 18:45:11
    Python游戏-飞机大战,改编自:https://www.cnblogs.com/wuzhanpeng/category/655359.html 在原来的基础上添加以下几点: 1)背景音乐 2)实时分数和最高分的显示 3)暂停和继续操作 4)重来操作
  • 本资源为基于Python开发游戏飞机大战。已打包好,直接可以运行。
  • python3开发,使用 pygame开发飞机大战 游戏源码python3开发,使用 pygame开发飞机大战 游戏源码
  • 下面小编用python实现一个小游戏-飞机大战,使用的python文件有两个,下面逐步进行讲解。工具/原料笔记本电脑(以Windows 7为例);PyCharm软件。方法/步骤1首先安装本次程序需要依赖的python库:pygame,可以使用...
  • python飞机大战游戏

    2021-05-22 21:58:52
    1.使用python开发飞机大战游戏 2.游戏开始点击进入,开始战斗 3.发射子弹打击敌方不同的战机,我方也有不同战机 4.游戏分为三个关卡 5.当玩家操纵的战机被敌方的子弹击中时,玩家的战机损失生命值,生命值损失完...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,031
精华内容 812
关键字:

python游戏开发飞机大战

python 订阅