python3的飞机大战实现

本文详细介绍了使用Python和Pygame库开发飞机大战游戏的过程,包括背景音乐、特效、计分等核心功能的实现,以及游戏界面设计和交互逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       做了个飞机大战的基本实现,有背景音乐,击中敌机特效和音效,计分效果,暂停效果,血量显示效果,具体可以看下面的效果图。

1.主类

"""主文件"""
from tkinter import *
from MyGame.rungame import *
import pygame


def main():
    """main函数"""
    pygame.init()
    bg_music = pygame.mixer.music
    bg_music.load(r'media/interface.mp3')
    bg_music.set_volume(20)
    root = Tk()
    root.title('飞机大战')
    root.resizable(0, 0)
    canvas = Canvas(root, width=359, height=640, cursor='circle', relief=GROOVE)
    canvas.pack(side='left')
    # 加载相关图片
    bg_img = PhotoImage(file=r'image/interface.png')
    begin_button_img = PhotoImage(file='image/begin.png')
    help_button_img = PhotoImage(file='image/help.png')
    about_button_img = PhotoImage(file='image/about.png')
    canvas.create_image(180, 320, image=bg_img)
    # 开始按钮
    canvas.create_window(180, 422, window=Button(root, image=begin_button_img, relief=RIDGE, command=run))
    # 帮助按钮
    canvas.create_window(180, 482, window=Button(root, image=help_button_img, relief=RIDGE))
    # 关于按钮
    canvas.create_window(180, 542, window=Button(root, image=about_button_img, relief=RIDGE))
    if not bg_music.get_busy():
        bg_music.play()

    mainloop()


if __name__ == '__main__':
    main()

2.游戏运行界面类

"""运行函数"""
from pygame.locals import *
from MyGame.plane import *
from MyGame.bullet import *
from MyGame.enemy import *
from MyGame.boss import *
import pygame


def run():
    """主函数"""
    pygame.init()
    bg_size = 900, 515
    pygame.display.set_caption('My_game')
    screen = pygame.display.set_mode(bg_size)
    bg_image = pygame.image.load(r'image/background.png').convert_alpha()
    # 颜色预定义
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    # 爆炸图片
    boom_image = pygame.image.load(r'image/boom.png').convert_alpha()
    # 调用背景音乐
    pygame.mixer.set_num_channels(5)
    bg_music = pygame.mixer.music
    bg_music.load(r'media/bg_music.mp3')
    bg_music.set_volume(10)
    # 设置血量显示
    hp_image = pygame.image.load('image/hp.png')
    # 爆炸声音
    boom_music = pygame.mixer.Sound(r'media/boom.wav')
    boom_music.set_volume(0.2)
    # 添加我方主机
    plane = Plane()
    # 游戏帧率设置
    clock = pygame.time.Clock()
    # 分数图片
    score_image = []
    for i in range(10):
        path = 'image/' + str(i) + '.png'
        number_image = pygame.image.load(path)
        score_image.append(number_image)
    # 生成子弹
    bullet_list = []
    bullet_index = 0
    BULLET_NUM = 6
    for i in range(BULLET_NUM):
        bullet_list.append(Bullet(plane.rect.midtop))
    # 创建敌机
    enemies = pygame.sprite.Group()
    ENEMY_NUM = 10
    for i in range(ENEMY_NUM):
        enemies.add(Enemy(bg_size[0], bg_size[1]))
    # 创建boos敌机
    boss_enemies = pygame.sprite.Group()
    boss = Boss(bg_size[0], bg_size[1])
    boss_enemies.add(boss)
    enemies.add(boss)
    # 创建暂停按钮
    pause_image = pygame.image.load('image/pause.png').convert_alpha()
    # 播放b背景音乐
    if not bg_music.get_busy():
        bg_music.play(-1)
    # 延迟
    delay = 100
    # 设置位置
    score_position = 850
    # 设置暂停
    pause = False
    # 设置是否允许程序
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
        # 设置按键检测
        key_pressed = pygame.key.get_pressed()
        # 判断是否发生暂停
        if key_pressed[K_SPACE]:
            pause = not pause
        # 绘制背景
        screen.blit(bg_image, (0, 0))
        # 如果未暂停
        if not pause:
            # 检测用户键盘操作
            if key_pressed[K_w] or key_pressed[K_UP]:
                plane.moveUp()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                plane.moveDown()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                plane.moveLeft()
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                plane.moveRight()
            position = plane.rect.midtop
            position = (position[0] - 3, position[1])
            # 每过一定时间重置出界子弹
            if not (delay % 6):
                bullet_list[bullet_index].reset(position)
                bullet_index = (bullet_index + 1) % BULLET_NUM
                for each in enemies:
                    if not each.active:
                        each.reset()
                        each.active = True
                        if each in boss_enemies:
                            each.health = 100
            # 对于子弹列表,若存活,便绘制
            for each in bullet_list:
                if each.active:
                    collide_enemies = pygame.sprite.spritecollide(each, enemies, False, pygame.sprite.collide_mask)
                    if collide_enemies:
                        plane.score += 1
                        boom_music.play()
                        screen.blit(boom_image, each.rect)
                        each.active = False
                        for enemy in collide_enemies:
                            if enemy in boss_enemies:
                                enemy.health -= 2
                                if enemy.health == 0:
                                    enemy.active = False
                            else:
                                enemy.active = False
                    else:
                        each.move()
            # 检测我方飞机与敌方碰撞
            collide_plane = pygame.sprite.spritecollide(plane, enemies, False, pygame.sprite.collide_mask)
            if collide_plane:
                for each in collide_plane:
                    if each not in boss_enemies:
                        each.active = False
                    plane.health -= 1
            # 若敌机存活,则移动
            for each in enemies:
                each.move()
            if delay:
                delay -= 1
            else:
                delay = 100
        # 绘制背景,血量,分数和暂停,飞机
        screen.blit(hp_image, (0, 0))
        plane_heath_percent = float(plane.health) / 100
        pygame.draw.line(screen, BLACK, (50, 16),
                         (150, 16), 15)
        if plane_heath_percent > 0.5:
            pygame.draw.line(screen, GREEN, (50, 16),
                             (plane_heath_percent * 100 + 50, 16), 15)
        else:
            pygame.draw.line(screen, RED, (50, 16),
                             (plane_heath_percent * 100 + 50, 16), 15)
        screen.blit(pause_image, (870, 0))
        screen.blit(plane.image, plane.rect)
        # 绘制分数
        score = str(plane.score)
        score = score[::-1]
        for number in score:
            screen.blit(score_image[int(number)], (score_position, 0))
            score_position -= 20
        score_position = 850
        # 若敌机存在则绘制,
        for each in enemies:
            if each.active:
                screen.blit(each.image, each.rect)
                if each in boss_enemies:
                    health_percent = each.health / 100
                    pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 3),
                                     (each.rect.right, each.rect.top - 3), 2)
                    if health_percent > 0.2:
                        pygame.draw.line(screen, GREEN,
                                         (each.rect.left, each.rect.top - 3),
                                         (each.rect.left + health_percent * each.rect.width, each.rect.top - 3), 2)
                    else:
                        pygame.draw.line(screen, RED,
                                         (each.rect.left, each.rect.top - 3),
                                         (each.rect.left + health_percent * each.rect.width, each.rect.top - 3), 2)

        # 对于子弹列表,若存活,便绘制
        for each in bullet_list:
            if each.active:
                screen.blit(each.image, each.rect)
        clock.tick(60)
        pygame.display.flip()
    pygame.quit()

3.plane.py飞机类

import pygame


class Plane(pygame.sprite.Sprite):
    """Plane"""

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(r'image/plane.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = 397, 432
        self.speed = 10
        self.score = 0
        self.health = 100
        self.mask = pygame.mask.from_surface(self.image)

    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 < 515:
            self.rect.top += self.speed
        else:
            self.rect.bottom = 515

    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 < 900:
            self.rect.right += self.speed
        else:
            self.rect.right = 900

4.bullet.py子弹类

import pygame


class Bullet(pygame.sprite.Sprite):
    """Bullet"""

    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(r'image/bullet.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = position
        self.speed = 15
        self.active = True
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        self.rect.bottom -= self.speed
        if self.rect.bottom < 0:
            self.active = False

    def reset(self, position):
        self.rect.left, self.rect.top = position
        self.active = True

5.敌机类

"""enemy"""
import pygame
import random


class Enemy(pygame.sprite.Sprite):
    """enemy"""

    def __init__(self, width, height):
        pygame.sprite.Sprite.__init__(self)
        self.width = width
        self.height = height
        self.image = pygame.image.load(r'image/enemy_plane.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = random.randint(0, self.width - self.rect.width), random.randint(
            -3 * self.height, -2 * self.height)
        self.speed = [0, random.randint(3, 5)]
        self.active = True
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        """move"""
        self.rect = self.rect.move(self.speed)
        if self.rect.top > self.height:
            self.active = False

    def reset(self):
        """reset"""
        self.rect.left, self.rect.top = random.randint(0, self.width - self.rect.width), random.randint(
            -3 * self.height, -2 * self.height)
        self.speed = [0, random.randint(3, 5)]

6.敌机boss类

"""boss"""
import pygame
import random


class Boss(pygame.sprite.Sprite):
    """boss"""

    def __init__(self, width, height):
        pygame.sprite.Sprite.__init__(self)
        self.width = width
        self.height = height
        self.image = pygame.image.load(r'image/tianxie.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = random.randint(0, self.width - self.rect.width), random.randint(
            -6 * self.height, -4 * self.height)
        self.health = 100
        self.speed = [0, 1]
        self.active = True

    def move(self):
        """move"""
        self.rect = self.rect.move(self.speed)
        if self.rect.top > self.height:
            self.active = False

    def reset(self):
        """reset"""
        self.rect.left, self.rect.top = random.randint(0, self.width - self.rect.width), random.randint(
            -6 * self.height, -4 * self.height)

7.效果图

点击开始游戏,进入游戏界面

 

本游戏的全部素材全部通过网上图片处理和下载得到,因为不是专业的,所以美化一般,如果有需要素材的可以联系我。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值