【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本

简介: 【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本

【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本

背景

之前卓伊凡在AE特效制作处博文已经完整介绍了本款游戏的素材开发,本文开始把素材利用起来放进去,本游戏命名为鹰击长空,Eagles strike across the sky,简称名字ESAS!自从卓伊凡找到了人生的方向,每天就是不停的工作学习工作学习,拒接一切享乐,这就是道,感谢各位看官,涨粉也是对卓伊凡的鼓励。

章节内容03

【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe

内容概要

·规划游戏项目目录
·打包为可玩的exe-练习python打包为可执行exe

开源源代码下载地址

https://gitee.com/youyacao/esas

游戏运行包

https://youyacao.lanzouq.com/i60sA2lht5mh

完善飞机大战小游戏-换上制作的特效序列png图片-加入boss机

规划目录结构

常规用python开发游戏我们需要建立以下这样的目录

my_game_project/
├── assets/               // 游戏资源文件(图像、音效、字体等)
│   ├── images/
│   │   ├── player.png
│   │   ├── enemy.png
│   │   └── background.jpg
│   ├── sounds/
│   │   ├── background.mp3
│   │   └── hit.wav
│   └── fonts/
│       ├── main.ttf
│       └── secondary.ttf
├── config/               // 配置文件
│   └── settings.py
├── data/                 // 数据文件(如保存文件)
│   └── scores.json
├── docs/                 // 文档
│   └── README.md
├── src/                  // 源代码
│   ├── __init__.py
│   ├── main.py          // 主程序入口
│   ├── game.py          // 游戏主逻辑
│   ├── player.py        // 玩家类
│   ├── enemy.py         // 敌人类
│   ├── settings.py      // 游戏设置
│   └── utils.py         // 辅助函数
├── tests/                // 单元测试
│   ├── __init__.py
│   ├── test_game.py
│   ├── test_player.py
│   └── test_enemy.py
└── requirements.txt      // 项目依赖

目录结构解释:

  • assets/:存放游戏资源文件,包括图像、音效和字体等。
  • config/:存放配置文件,如游戏设置和参数。
  • data/:存放数据文件,如保存文件、分数记录等。
  • docs/:存放项目文档,如 README 文件。
  • src/:存放源代码,包括游戏主逻辑、玩家类、敌人类、游戏设置和辅助函数等。
  • tests/:存放单元测试文件,用于测试游戏的各个模块。
  • requirements.txt:记录项目依赖的库和版本信息。

目前我们就开始把已有资源进行归类,由于此前我们都是用的一个文件 显然就是不合理的,根据目前已有资源和内容我们应该规划为:

planegame/
├── main.py                # 主程序入口
├── assets/
│   ├── png/
│   │   ├── boss00.png     # BOSS 动画帧
│   │   ├── ...
│   │   ├── player_100.png # 玩家动画帧
│   │   ├── ...
│   │   ├── enemy_10.png   # 敌人动画帧
│   │   ├── ...
│   │   ├── bullet0.png    # 子弹动画帧
│   │   ├── ...
│   │   ├── explosion00.png # 爆炸动画帧
│   │   ├── ...
│   └── sounds/
│       ├── bullet.wav     # 子弹发射音效
│       ├── boss.wav       # BOSS 出现背景音乐
│       └── ...
├── src/
│   ├── __init__.py        # 使 src 成为一个包
│   ├── game.py            # 游戏逻辑代码
│   ├── sprites.py         # 精灵类定义
│   └── utils.py           # 辅助函数和常量
└── README.md              # 项目说明文档

资源文件夹改为assets ,对应代码中也修改,

建立 main.py # 主程序入口 文件,并且内容如下:

import pygame
from src.game import Game
def main():
    pygame.init()
    game = Game()
    game.run()
    pygame.quit()
if __name__ == "__main__":
    main()

新建src目录,下面新建game.py,写入游戏的主逻辑

import pygame
from src.sprites import Player, Enemy, Bullet, Boss, Explosion
import random
import os
import sys
class Game:
    def __init__(self):
        self.screen_width = 720
        self.screen_height = 1280
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
        pygame.display.set_caption("鹰击长空-Eagles strike across the sky-优雅草央千澈")
        self.clock = pygame.time.Clock()
        self.running = True
        self.all_sprites = pygame.sprite.Group()
        self.all_enemies = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.player = Player()
        self.all_sprites.add(self.player)
        self.all_sprites.add(self.bullets)
        self.boss_spawned = False
        self.boss_spawn_time = 10000  # 10秒后生成BOSS
        self.load_sounds()
    def load_sounds(self):
        self.bullet_sound = pygame.mixer.Sound(os.path.join("assets", "sounds", "bullet.wav"))
    def run(self):
        while self.running:
            self.events()
            self.update()
            self.draw()
            self.clock.tick(60)
    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    self.player.shoot()
    def update(self):
        self.all_sprites.update()
        self.all_enemies.update()
        # 生成敌人
        if random.randint(1, 100) < 5:
            enemy = Enemy()
            self.all_enemies.add(enemy)
            self.all_sprites.add(enemy)
        # 检测碰撞
        hits = pygame.sprite.groupcollide(self.all_enemies, self.bullets, True, True)
        for hit in hits:
            explosion = Explosion(hit.rect.center)
            self.all_sprites.add(explosion)
        # 检测 BOSS 是否生成
        if not self.boss_spawned and pygame.time.get_ticks() > self.boss_spawn_time:
            boss = Boss()
            self.all_sprites.add(boss)
            self.all_enemies.add(boss)
            self.boss_spawned = True
            pygame.mixer.music.load(os.path.join("assets", "sounds", "boss.wav"))
            pygame.mixer.music.play(-1)
    def draw(self):
        self.screen.fill((0, 0, 0))
        self.all_sprites.draw(self.screen)
        pygame.display.flip()

下一步,新建sprites.py 文件夹 定义游戏中的所有精灵类,如 Player, Enemy, Bullet, Boss, Explosion均放在此处,

对了有人不知道什么是精灵类,

扩展知识

在游戏开发中,“精灵类”(Sprite)是指游戏中的可视对象,通常用于表示角色、物品、背景等。精灵类的主要职责是管理和渲染这些可视对象,并处理它们的属性和行为。它是2D游戏开发中的一个重要概念。以下是关于精灵类的一些详细介绍:

精灵类的属性

  • 图像:精灵通常由一幅或多幅图像组成,用于在屏幕上显示。
  • 位置:精灵在屏幕上的坐标位置(x, y)。
  • 大小:精灵的宽度和高度。
  • 速度:精灵的移动速度和方向。
  • 动画帧:如果精灵是动画的,可以包含多个帧来创建动画效果。

精灵类的行为

  • 移动:根据速度和方向更新位置。
  • 绘制:在游戏的每一帧中将精灵绘制到屏幕上。
  • 碰撞检测:检测与其他精灵或环境的碰撞。
  • 动画更新:如果是动画精灵,根据时间或事件更新动画帧。

把精灵类代码归纳到本文件:

import pygame
import random
import os
class Boss(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.frames = [pygame.image.load(os.path.join("assets", "png", f"boss{i:02d}.png")).convert_alpha() for i in range(10)]
        self.frame = 0
        self.image = self.frames[self.frame]
        self.rect = self.image.get_rect(center=(360, -100))
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 100
        self.health = 100
        self.move_direction = 1
        self.move_speed = 2
        self.shoot_delay = 1000
        self.last_shot = pygame.time.get_ticks()
    def update(self):
        self.rect.y += 2
        if self.rect.top > 0:
            self.rect.x += self.move_speed * self.move_direction
            if self.rect.right > 720 or self.rect.left < 0:
                self.move_direction *= -1
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame = (self.frame + 1) % len(self.frames)
            self.image = self.frames[self.frame]
        if now - self.last_shot > self.shoot_delay:
            self.last_shot = now
            self.shoot()
    def shoot(self):
        bullet = Bullet(self.rect.centerx, self.rect.bottom)
        self.bullets.add(bullet)
class Player(pygame.sprite.Sprite):
    # 类似于 Boss 类的定义
    pass
class Bullet(pygame.sprite.Sprite):
    # 类似于 Boss 类的定义
    pass
class Enemy(pygame.sprite.Sprite):
    # 类似于 Boss 类的定义
    pass
class Explosion(pygame.sprite.Sprite):
    # 类似于 Boss 类的定义
    pass

新建辅助函数文件utils.py

import pygame
import os
def load_image(filename):
    return pygame.image.load(os.path.join("assets", "png", filename)).convert_alpha()
def load_sound(filename):
    return pygame.mixer.Sound(os.path.join("assets", "sounds", filename))

整理完毕 运行

报错,

这个错误表明 Python 无法找到 src 模块。这通常是由于 Python 解释器无法正确识别 src 目录为一个包。以下是一些可能的解决方案:

确保 src 目录包含 init.py 文件:

init.py 文件可以是空的,但它的存在告诉 Python 这个目录是一个包。
确保 src 目录下有一个 init.py 文件。

也就是说我必须建立 init.py 文件,哪怕为空,ok建立好了再次运行

继续报错,这个是因为 Player 对象没有 image 属性。在 Pygame 中,pygame.sprite.Sprite 类要求每个精灵对象必须有一个 image 属性,因为 draw 方法会使用这个属性来绘制精灵。

让我们检查 Player 类的定义,确保它正确地设置了 image 属性。

修改game.py

# src/game.py
import pygame
from src.sprites import Player, Enemy, Bullet, Boss, Explosion
import random
import os
import sys
# 加载图像
player_frames = []
for i in range(12):  # 假设有12帧,从player_100.png到player_111.png
    frame = pygame.image.load(os.path.join("assets", "png", f"player_{100 + i:03d}.png")).convert_alpha()
    frame = pygame.transform.scale(frame, (150, 150))  # 调整为150x150像素
    player_frames.append(frame)
class Game:
    def __init__(self):
        self.screen_width = 720
        self.screen_height = 1280
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
        pygame.display.set_caption("鹰击长空-Eagles strike across the sky-优雅草央千澈")
        self.clock = pygame.time.Clock()
        self.running = True
        self.all_sprites = pygame.sprite.Group()
        self.all_enemies = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.player = Player()
        self.all_sprites.add(self.player)
        self.all_sprites.add(self.bullets)
        self.boss_spawned = False
        self.boss_spawn_time = 10000  # 10秒后生成BOSS
        self.load_sounds()
    def load_sounds(self):
        self.bullet_sound = pygame.mixer.Sound(os.path.join("assets", "sounds", "bullet.wav"))
    def run(self):
        while self.running:
            self.events()
            self.update()
            self.draw()
            self.clock.tick(60)
    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    self.player.shoot()
    def update(self):
        self.all_sprites.update()
        self.all_enemies.update()
        # 生成敌人
        if random.randint(1, 100) < 5:
            enemy = Enemy()
            self.all_enemies.add(enemy)
            self.all_sprites.add(enemy)
        # 检测碰撞
        hits = pygame.sprite.groupcollide(self.all_enemies, self.bullets, True, True)
        for hit in hits:
            explosion = Explosion(hit.rect.center)
            self.all_sprites.add(explosion)
        # 检测 BOSS 是否生成
        if not self.boss_spawned and pygame.time.get_ticks() > self.boss_spawn_time:
            boss = Boss()
            self.all_sprites.add(boss)
            self.all_enemies.add(boss)
            self.boss_spawned = True
            pygame.mixer.music.load(os.path.join("assets", "sounds", "boss.wav"))
            pygame.mixer.music.play(-1)
    def draw(self):
        self.screen.fill((0, 0, 0))
        self.all_sprites.draw(self.screen)
        pygame.display.flip()

然后几经折腾,基本上就是 类没有初始化之类的问题,或者 Enemy 类的 init 方法中,enemy_frames 未被定义。同样地,boss_frames 和 bullet_frames 也会遇到类似的问题,经过了 1个小时的处理,终于好了

处理好了以后可以正常运行了终于,成功了,

由于文章篇幅问题,我们开始进行打包工作,python 游戏 项目 如何 直接打包为可执行exe

要将一个 Python 游戏项目打包为可执行的 EXE 文件,可以使用 PyInstaller 这个工具:

安装 PyInstaller

首先,你需要安装 PyInstaller。你可以通过 pip 来安装:

pip install pyinstaller

安装成功

项目主文件是 main.py

使用 PyInstaller 打包项目

进入你的项目目录,然后运行以下命令:

pyinstaller --onefile main.py

直接执行,在卓伊凡的目录下,

这个命令将生成一个单独的 EXE 文件。--onefile 选项表示将所有内容打包到一个文件中,ok 现在分享蓝奏云

直接成功 15993 INFO: Copying bootloader EXE to G:\clone\esas\dist\main.exe
15995 INFO: Copying icon to EXE

想必通过此文,也知道python项目如何打包exe了吧

相关文章
|
15天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
阿里云与企业共筑容器供应链安全
171332 12
|
17天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
随着云计算和DevOps的兴起,容器技术和自动化在软件开发中扮演着愈发重要的角色,但也带来了新的安全挑战。阿里云针对这些挑战,组织了一场关于云上安全的深度访谈,邀请了内部专家穆寰、匡大虎和黄竹刚,深入探讨了容器安全与软件供应链安全的关系,分析了当前的安全隐患及应对策略,并介绍了阿里云提供的安全解决方案,包括容器镜像服务ACR、容器服务ACK、网格服务ASM等,旨在帮助企业构建涵盖整个软件开发生命周期的安全防护体系。通过加强基础设施安全性、技术创新以及倡导协同安全理念,阿里云致力于与客户共同建设更加安全可靠的软件供应链环境。
150295 32
|
25天前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
201962 14
对话 | ECS如何构筑企业上云的第一道安全防线
|
3天前
|
机器学习/深度学习 自然语言处理 PyTorch
深入剖析Transformer架构中的多头注意力机制
多头注意力机制(Multi-Head Attention)是Transformer模型中的核心组件,通过并行运行多个独立的注意力机制,捕捉输入序列中不同子空间的语义关联。每个“头”独立处理Query、Key和Value矩阵,经过缩放点积注意力运算后,所有头的输出被拼接并通过线性层融合,最终生成更全面的表示。多头注意力不仅增强了模型对复杂依赖关系的理解,还在自然语言处理任务如机器翻译和阅读理解中表现出色。通过多头自注意力机制,模型在同一序列内部进行多角度的注意力计算,进一步提升了表达能力和泛化性能。
|
7天前
|
存储 人工智能 安全
对话|无影如何助力企业构建办公安全防护体系
阿里云无影助力企业构建办公安全防护体系
1253 8
|
9天前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
8天前
|
人工智能 自然语言处理 程序员
通义灵码2.0全新升级,AI程序员全面开放使用
通义灵码2.0来了,成为全球首个同时上线JetBrains和VSCode的AI 程序员产品!立即下载更新最新插件使用。
1314 24
|
8天前
|
消息中间件 人工智能 运维
1月更文特别场——寻找用云高手,分享云&AI实践
我们寻找你,用云高手,欢迎分享你的真知灼见!
618 25
1月更文特别场——寻找用云高手,分享云&AI实践
|
7天前
|
机器学习/深度学习 人工智能 自然语言处理
|
13天前
|
人工智能 自然语言处理 API
阿里云百炼xWaytoAGI共学课DAY1 - 必须了解的企业级AI应用开发知识点
本课程旨在介绍阿里云百炼大模型平台的核心功能和应用场景,帮助开发者和技术小白快速上手,体验AI的强大能力,并探索企业级AI应用开发的可能性。