全面的火焰教程(或如何使用Flutter制作游戏)

介绍

大家好! 我是栾(Luan),欢迎阅读第一个综合性Flame教程。

Flame是极简主义的Flutter游戏引擎,提供了一些模块来制作基于Canvas的游戏。

在本教程中,我们将创建一个非常简单的游戏,盒子会掉落,目标是在盒子撞到屏幕底部之前销毁它们。

您可以自己检查游戏,以了解我们如何安装此APK,或从Play商店安装它。

这将使我们能够涵盖框架提供的所有功能,并演示如何执行最基本的操作:渲染,子画面,音频,文本,动画等。

为什么我们选择这个游戏呢? 除了对框架的探索非常简单而完整之外,一个很好的因素是我们有足够的资源去做!

对于此游戏,我们将使用以下资源:一个板条箱精灵,一个爆炸精灵(带有动画),爆炸声音,“未命中”声音(当未击中盒子时),背景音乐以及一个漂亮的字体呈现分数。

很难在Internet上找到可从市场上买到的优质资源,但是我们在这个很棒的网站上找到了所有内容(字体除外)。 他们真的很棒,绝对值得推荐。

到目前为止,尚不支持Sprite工作表,因此,首先,我们需要将所有资源转换为适当的格式。 另外,我们需要将所有音频转换为MP3(也支持OGG;不支持WAV)。 完成这些后,您可以在此处下载捆绑包,其中包含您需要的所有资源。

还值得一提的是,此处描述的所有内容均作为完整功能的完整版本提交在GitHub上。 如有疑问,您可以随时查看。 另外,该示例是按照以下确切步骤创建的,并以频繁的提交作为快照。 在整个教程中,我将链接将存储库推进到相关阶段的特定提交。 这将使您可以建立检查点并浏览旧代码,以查看所有不清楚的地方。

最后一件事; 您可以在此处查看Flame的完整文档。 如果您有任何疑问,建议,错误,请随时提出问题或与我联系。

除此之外,您还需要安装Flutter和Dart。 如果适合您,您还可以使用IntelliJ IDEA,这是编写代码的好地方。 为了安装这些东西,您可以在这里查阅大量的教程。

基本

所以,现在,我假设您已经准备就绪。 因此,只需运行以下内容并打开它!

另外,请注意,大多数draw方法都使用Paint。 绘画不仅是一种颜色,而且可以是Degradè或其他一些纹理。 通常,您可能想要纯色或直接使用Sprite。 因此,我们只是将绘画内部的颜色设置为Color的实例。

颜色表示单一的ARGB颜色; 用一个可以用十六进制记下的整数创建它,以便于阅读; 它的格式为A(字母,透明度,通常为0xFF),然后依次为R,G和B两位数字。

还有一些命名的颜色; 它虽然在材料包装内。 请注意只导入“颜色”模块,以免意外使用物料包中的其他东西。

现在我们知道了Sprite处理和渲染的基础知识。 让我们继续下一步:爆炸! 没有游戏,什么游戏才是好游戏? 爆炸是另一种野兽,因为它具有动画效果。 只需通过根据当前刻度在渲染器上渲染不同的东西即可完成Flame中的动画。 我们将一个手工计时器添加到生成箱的方式相同,我们将为每个爆炸添加一个lifeTime属性。 而且,爆炸不会继承自SpriteComponent,因为后者只能具有一个Sprite。 我们将扩展超类PositionComponent,并使用Flame.image.load实现渲染。

由于每个爆炸都有很多框架,因此需要以响应方式绘制它们,因此我们将每个框架预加载一次,并保存在Explosion类中的静态变量中; 像这样:

请注意,我们按顺序加载了7个动画帧中的每一个。 然后,在render方法中,我们做出一个简单的逻辑来决定绘制哪个帧:

请注意,如前所述,我们正在使用drawImageRect进行“手工绘制”。 此代码类似于SpriteComponent在后台执行的操作。 还要注意,如果图像不在数组中,则不会绘制任何内容-因此在TIME秒(我们将其设置为0.75或750 ms)之后,不会呈现任何内容。

很好,但是我们不想继续用爆炸爆炸污染我们的爆炸阵列,因此我们还添加了一个destroy()方法,该方法根据生命时间返回是否要销毁爆炸对象。

最后,我们更新游戏,添加爆炸列表,在render方法上进行渲染,然后在update方法上进行更新。 需要对其进行更新以增加其使用寿命。 我们还花时间来重构Game.update方法中以前的内容,即使盒子掉进Crate.update方法中,因为这是Crate的责任。 现在,游戏更新仅委托给其他人。 最后,在更新中,我们需要从列表中删除已破坏的内容。 为此,List提供了一个非常有用的方法removeWhere:

我们已经在输入法上使用了它,以删除数组中被触摸的框。 我们还将在这里制造爆炸。

查看检查点以了解更多详细信息。

检查点: d8c30ad

播放音讯

在下一次提交中,我们最终将播放一些音频! 为此,您需要将文件添加到assets文件夹中,位于assets/audio/ 。 它必须是MP3或OGG文件。 然后,在代码中的任何地方运行:

其中filename.mp3是其中filename.mp3的名称。 在我们的例子中,当我们单击一个框时,我们将播放explosion.mp3声音。

此外,让我们开始授予标点符号。 我们添加一个points变量来保存当前点数。 它从零开始; 每点击一个盒子,我们将获得10分;当盒子落地时,我们将损失20分。

我们现在有义务处理失控的箱子。 基于对Explosion类的操作,我们为Crate添加了destroy方法,该方法将返回它们是否在屏幕外。 这开始成为一种模式! 如果被破坏,我们将从阵列中移除并调整点。

目前,计分有效,但并未在任何地方显示; 那将很快到来。

在下一个检查点,音频将无法正常工作,因为我忘记了添加文件并将它们放在pubspec.yaml 。 在以下提交中完成。

检查点: 43a7570

现在我们想要更多声音! Flame所使用的audioplayers (请注意s)库可让您一次播放多种声音,因为您可能已经注意到如果单击时会发狂,但是现在让我们利用它,通过在播放框时播放错过的声音来发挥我们的优势。击中地面(板条箱的摧毁方法)和背景音乐。

为了循环播放背景音乐,请使用loop方法,该方法的工作原理与之前相同:

在此提交中,我们还修复了在先前提交中错过的板条箱的销毁条件(因为没有办法知道,现在有声音了)。

检查点: f575150

渲染文字

现在我们有了所有想要的音频(背景,音乐,声音效果,MP3,OGG,循环,同时),让我们进入文本渲染。 毕竟,我们需要查看该分数。 “手动”完成此操作的方式是创建一个Paragraph对象并使用Canvas的drawParagraph。 它需要大量的配置,并且是一个相当混乱的API,但是可以这样实现:

检查点: e09221e

这是使用默认字体绘制的,可以使用fontFamily属性指定其他公共系统字体。 不过,可能在您的游戏中,您将需要添加自定义游戏。

因此,我前往1001fonts.com并获得了这款非常漂亮的免费商业Halo字体作为TTF。 再次,只需将文件放置在assets/fonts ,但是现在必须以不同的方式将其导入pubspec.yaml文件中。 没有添加其他资产,而是有一个专用的字体标签,默认情况下会对其进行注释,并提供有关如何添加字体的完整说明。 因此,为其分配一个名称并执行以下操作:

这个额外的抽象层来自Flutter本身,允许您将多个文件添加到相同的字体(以定义粗体,更大的尺寸等)。 现在,回到我们的段落,我们只需将属性fontFamily: 'Halo'TextStyle构造函数中。

运行,您将看到漂亮的Halo字体!

检查点: 3155bda

例如,如果要在同一段落中使用多种样式,则所描述的此方法将为您提供更多控制。 但是,如果您想在这种情况下使用单个样式的简单段落,只需使用Flame.util.text帮助器即可创建它:

该单行替换了之前的4,并公开了最重要的功能。 文本(第一个参数)是必需的,其余所有都是可选的,并且具有合理的默认值。

对于颜色,我们再次使用Colors.white助手,但是如果您想要特定的颜色,我们也可以使用new Color(0xFFFFFFFF)

检查点: 952a9df

在那里,您拥有了! 带有精灵渲染,文本渲染,音频,游戏循环,事件和状态管理的完整游戏。

发布

您的游戏准备发布了吗?

只需按照Flutter教程中的几个简单步骤进行操作即可。

正如您在最后的检查点中所看到的那样,它们都非常简单明了,除了“图标”部分,这可能会引起一些麻烦。 我的建议是制作图标的大版本(512或1024像素),并使用Make App Icon网站生成包含所需内容(iOS和Android)的zip文件。

检查点: 2974f29

还有什么?

你喜欢火焰吗? 如果您有任何建议,错误,问题,功能要求或其他任何内容,请随时与我联系!

想要改善您的游戏并了解更多信息? 如何添加具有Firebase和Google登录功能的服务器? 投放广告怎么样? 如何设置一个主菜单和多个屏幕?

当然,还有很多需要改进的地方–这只是一个示例游戏。 但是它应该已经给出了使用Flutter(有或没有Flame)进行游戏开发的核心概念的基本概念。

希望大家喜欢!