昨日我們使用 SpriteComponent
建構出整體的遊戲畫面,今日我們研究看看要如何讓 Sprite
動起來。
範例素材圖片使用來自 cocos-creator GitHub
SpriteComponent
繼承自 Component
,提供 update
方法可以讓我們更新 Sprite
的狀態。
@mustCallSuper
void update(double dt) {
children.updateComponentList();
children.forEach((c) => c.update(dt));
}
為了讓我們的怪獸精靈元件能夠跳起來,需要確認目前是往上還是往下的狀態,接著定義跳躍的高度以及速度。
// 向上的狀態
bool _up = true;
// 向下的狀態
bool _down = false;
// 跳躍的高度
final double _jumpHeight = 150;
// 跳躍的速度
final double ySpeed = 300;
// 原始地面的位置
late final double _originY;
在遊戲畫面的定位上是從左上角的 (0, 0)
為起點,我們要呈現跳躍的移動效果,可以在每次 update
的時間通過改變 position
或是 y
的值來達到移動的效果。
@override
void update(double dt) {
super.update(dt);
if (_up) {
y -= dt * ySpeed;
if (y < _originY - _jumpHeight) {
_up = false;
_down = true;
}
}
if (_down) {
y += dt * ySpeed;
if (y > _originY) {
_up = true;
_down = false;
}
}
}
目前的 Moster 會上下跳動了
App 上的遊戲開發通常沒有搭配鍵盤而是使用點擊畫面
的位置或是使用虛擬搖捍
的設置來控制角度的移動,參考官網說明。
首先我們需要在遊戲上 mixin HasDraggableComponents
類別
class StarGame extends FlameGame with HasDraggableComponents {
...
我們使用 JoystickComponent
相關屬性定義 虛擬搖捍
的顯示畫面
final knobPaint = BasicPalette.blue.withAlpha(200).paint();
final backgroundPaint = BasicPalette.blue.withAlpha(100).paint();
final joystick = JoystickComponent(
knob: Circle(radius: 15).toComponent(paint: knobPaint),
background: Circle(radius: 50).toComponent(paint: backgroundPaint),
margin: const EdgeInsets.only(left: 30, bottom: 40),
);
add(joystick);
在畫面上應該就會出現 虛擬搖捍
的介面。
接著將 joystick
當作參數配置給 Moster
class Moster extends SpriteComponent with Hitbox, Collidable {
...
final JoystickComponent joystick;
final moster = Moster(this, joystick);
joystick
提供三種參數可以供設定
direction
:搖捍目前對應的方向。這個讓我想到KOF遊戲的招式表 XD。intensity
:從旋鈕中心至半徑邊緣的百分比[0.0, 1.0]
delta
:從旋鈕中心至半徑對應向量值velocity
:從 delta
與 knobRadius
計算出 relativeDelta
,用來表示加速度的參數。 /// The percentage, presented as a [Vector2], and direction that the knob is
/// currently pulled from its base position to a edge of the joystick.
Vector2 get relativeDelta => delta / knobRadius;
向量
:指一個同時具有大小和方向,且滿足平行四邊形法則的幾何對象。[維基百科]
在 Moster
的 update
加入下面程式碼:
@override
void update(double dt) {
...
// joystick
if (!joystick.delta.isZero()) {
x += joystick.relativeDelta[0] * xSpeed * dt;
}
// 邊界
if (x < 32) {
x = 32;
}
if (x > _game.screenWidth - 32) {
x = _game.screenWidth - 32;
}
}