组件 Component

该类表示屏幕上的单个对象,可以是一个浮动的矩形,也可以是一个旋转的精灵。

基本的抽象类包含常见的updaterender函数等待我们去实现。

其中一个有用的实现PositionComponent提供了诸如x , y , width , heightangle 的实用属性,还有实用的函数,比如distance(距离)和angleBetween(弧度)等。

用的最多的Component实现类应该是能构建精灵的SpriteComponent

import 'dart:ui';

import 'package:flame/components/component.dart';
import 'package:flame/game.dart';
import 'package:flame/sprite.dart';

class MyGame extends BaseGame {
  SpriteComponent player;

  MyGame() {
    Sprite sprite = Sprite('player.png');
    const size = 128.0;

    // 指定精灵组件的宽度,高度和精灵
    player = SpriteComponent.fromSprite(size, size, sprite);

    // 指定在屏幕上的坐标
    player.x = 20; // 若不指定,默认为0
    player.y = 30; // 若不指定,默认为0
    player.angle = 0; // 若不指定,默认为0
  }

  
  void render(Canvas canvas) {
    // 仅当图片加载完成,x,y和宽高不为0时才会进行渲染
    player.render(canvas);
  }
}

组件方向

你的项目中,当你希望旋转某组件时,你可以通过使用 renderFlipXrenderFlipY 轻松在render(Canvas c)的过程中实现此效果。

该方法允许在所有的PositionComponent中使用,并且在 SpriteComponentAnimationComponent 中相当实用!

比如,只需设置component.renderFlipX = true ,就可以实现水平翻转渲染。是不是非常简单?

其他函数

每个组件都有其他的一些函数,你可以选择实现它们。这些函数可供BaseGame类进行使用。如果你不想使用BaseGame,你可以在自己的游戏循环中自由实现。

resize

每次屏幕尺寸发生变更时,都会调用其 resize 函数。通过add添加的组件会在最开始调用它一次。

由于屏幕尺寸会发生变更,你需要在此提交对组件的变更,比如:x,y坐标,组件的宽高或其他修改。

你可以在该函数内对变量们进行初始化,因为只有在它们赋值完成后,精灵才会渲染。

destroy

希望销毁一个对象?你只需要实现 destory 并返回true值,就可以警告BaseGame,你的对象已被标记为待销毁。并且在下次update前将其删除。之后,它就不会被渲染或者更新了。

isHUD

可以实现isHUD函数并返回true(默认为false),这样会使BaseGame忽略该元素的摄像头。

onMount

重写 onMount函数以运行组件的初始化代码。调用此函数时,BaseGame确保已解决所有将更改此组件行为的混合包。

onDestroy

你可以重写 onDestroy ,以在组件删除前运行某些代码。(比如敌人在死亡之前会有倒地动画)

其他实现

这里也有一些其他的实现:

  • AnimationComponent接收一个Animation对象,并渲染一个循环动画的Sprite。(点击此处查看有关动画的说明)
  • SvgComponent接收Svg对象并在游戏中渲染SVG图片。
  • ParallaxComponent可以渲染出具有视差效果的背景。
  • Box2DComponent包含了物理引擎(使用了Dart的Box2D组件)。

动画组件 AnimationComponent

该组件使用了Animation的实例,来表示一个具有运行单个循环动画精灵的组件。

看一下一个简单的,3帧动画的效果:

List<Sprite> sprites = [0, 1, 2].map((i) => new Sprite('player_${i}.png')).toList();
this.player = AnimationComponent(64.0, 64.0, new Animation.spriteList(sprites, stepTime: 0.01));

如果你有一个精灵清单,则可以使用sequenced的构造函数,该构造函数与Animation类提供的构造函数相同(点击此处查看更多详细说明):

this.player = AnimationComponent.sequenced(64.0, 64.0, 'player.png', 2);

如果你并未使用BaseGame, 别忘了即使是静态的也要更新此组件,因为需要勾选动画对象才能移动框架。

Svg组件 SvgComponent

该组件使用Svg类实例,作为组件在游戏中渲染Svg图像:

Svg svg = Svg('android.svg');
SvgComponent android = SvgComponent.fromSvg(100, 100, svg);
android.x = 100;
android.y = 100;

Flare动画组件 FlareComponent

该组件包含FlareAnimation的实例,它接收Flare动画文件名、该文件要使用的动画以及渲染动画的宽度及高度。

final fileName = "assets/Bob_Minion.flr";
final animation = "Wave";
final width = 306;
final height = 228;

FlareComponent flareAnimation = FlareComponent(fileName, animation, width, height);
flareAnimation.x = 50;
flareAnimation.y = 240;
add(flareAnimation);

你可以使用updateAnimation函数来变更当前播放的动画。

聚合组件 Composed component

一个可以使你将多个Component进行组合的 mixin. 通过层次结构来对可视组件进行分组相当实用。实现后,其包含的组件集合中的每个项目都将以相同的条件进行更新和渲染。

这里提供将两个可视组件进行组合的示例代码:

class GameOverPanel extends PositionComponent with Resizable, ComposedComponent {
  bool visible = false;

  GameOverText gameOverText;
  GameOverButton gameOverButton;

  GameOverPanel(Image spriteImage) : super() {
    gameOverText = GameOverText(spriteImage); // GameOverText is a Component
    gameOverButton = GameOverButton(spriteImage); // GameOverRestart is a SpriteComponent

    components..add(gameOverText)..add(gameOverButton);
  }

  
  void render(Canvas canvas) {
    if (visible) {
      super.render(canvas);
    } // If not, neither of its `components` will be rendered
  }
}

视差组件 ParallaxComponent

该组件可通过在彼此的上方绘制多个透明图像(每个图像会有较小的错位)来渲染好看的背景。

当你观察地平线并移动时,较近的对象似乎比远处的对象移动的更快。

该组件模拟了这种效果,使背景更加逼真,并且有了远近的视觉效果。

像这样创建它:

final images = [
    ParallaxImage("mountains.jpg"),
    ParallaxImage("forest.jpg"),
    ParallaxImage("city.jpg"),
];
this.bg = ParallaxComponent(images);

这样将会创建一个静态的背景。

如果要移动它,则必须设置可选参数baseSpeedlayerDelta。例如,如果要沿X轴移动背景图并使图片更远,可以这样做:

this.bg = ParallaxComponent(images, baseSpeed: Offset(50, 0), layerDelta: Offset(20, 0));

你可以随时设置baseSpeed和layerDelta。比如角色跳跃或者游戏加速时:

this.bg.baseSpeed = Offset(100, 0);
this.bg.layerDelta = Offset(40, 0);

默认情况下,图像将会对齐到左下角,沿X轴重复并按比例缩放,以使图像覆盖屏幕的高度。如果要修改此算法,比如你的游戏前进方向不为横向,则可以为每个ParallaxImage设置repeatalignment以及fill参数。

比如:

final images = [
    ParallaxImage("stars.jpg", repeat: ImageRepeat.repeat, alignment: Alignment.center, fill: LayerFill.width),
    ParallaxImage("planets.jpg", repeat: ImageRepeat.repeatY, alignment: Alignment.bottomLeft, fill: LayerFill.none),
    ParallaxImage("dust.jpg", repeat: ImageRepeat.repeatX, alignment: Alignment.topRight, fill: LayerFill.height),
];
this.bg = ParallaxComponent(images, baseSpeed: Offset(50, 0), layerDelta: Offset(20, 0));
  • 在此DEMO中,star图片将会在两个轴上重复绘制,居中对齐并缩放以填充与屏幕同宽。
  • planets图片将会在Y轴上重复,并与屏幕的左下角对齐,但不会缩放。
  • dust图片将会在X轴上重复,与右上角对齐并缩放以填充与屏幕同高。

根据需要完成参数设置后,将 ParallaxComponent 作为组件进行渲染。

和AnimationComponent类似,即使你的视差是静态的,也必须在此组件上调用update,以使它运行其动画。同样,记得要把资源文件添加在pubspec.yaml中。

你可以点击此处 查看parallax的例子

物理组件 Box2DComponent

Flame基本集成了Flutter实现的Box2D

box2d世界的整个概念都会映射到Box2DComponent组件。每个Body都是一个BodyComponent,并且直接添加至Box2DComponent,而不是game的list。

因此,你可以在game list中包含HUD和其他与物理无关的组件,还可以按需添加任意数量的Box2DComponent(通常是一个Box2DComponent),然后将物理实体添加到Components实例中。组件更新后,它将使用box2d物理引擎正确update每个child。

你可以在@feroult制作的 WIP 游戏中看到box2d用法的更加完整的示例(虽然该示例使用的是0.6.x版本的Flame,但是Box2D相关的API并未更改)。

你可以在此 查看Box2D的更多内容。

平铺组件 TiledComponent

目前我们有Tiled组件的基本实现。该API通过使用Tiled 库来解析地图文件并渲染可见图层。

你可以点此 查看使用该API的示例。

9格平铺组件 Nine Tile Box Component

Nine Tile Box 是使用网格精灵绘制的矩形。

网格精灵是一个3x3网格,有9个区块,分别代表4个角、4个边和中间。

角以相同的尺寸绘制,侧面在侧方向拉伸,中间部分向两边扩展。

使用此功能,您可以获得一个可以扩展到任何尺寸的矩形。当你制作面板、对话框时非常实用。

查看nine_tile_box示例项目来学习如何使用它。

特效 Effects

Flame提供了一组可应用于特定类型的组件的特效,这些特效可为组件的某些属性(比如位置和尺寸)设置动画。你可以 点击此处 查看这些效果

点此 查看运行效果的例子。

Flame中文站 all right reserved,powered by Gitbook最后修改: 2020-08-18 18:57:12

results matching ""

    No results matching ""