為了找回一點信心,救回專案,先試著做做看小遊戲吧。
參考Flame的官網,發現他在頁面的最底下有一些Tutorials。
我們可以照著這些說明試著將範例實作出來~
(網址:https://docs.flame-engine.org/main/tutorials/platformer/platformer.html#ember-quest-game-tutorial)
flutter:
assets:
- assets/images/
void main() {
runApp(
const GameWidget<你的遊戲(FlameGame類)>.controlled(
gameFactory: 你的遊戲(FlameGame類).new,
),
);
}
要注意那個「controlled」很重要!不是這樣導入你的角色根本不會動!(之前有提過直接將FlameGame包個GameWidget的方式「GameWidget(game:FlameGame())」,在這裡會導致角色控制項失效。)
4. 然後在你的遊戲畫面裡,先將剛剛有的圖檔先全部載入。同時還有我們的遊戲視角。
5. 開始要創造我們的主角Ember了~
class EmberPlayer extends SpriteAnimationComponent ///精靈Component
with HasGameRef<你的遊戲> {
EmberPlayer({
required super.position,
}) : super(size: Vector2.all(64), anchor: Anchor.center);
@override
void onLoad() {
animation = SpriteAnimation.fromFrameData(
game.images.fromCache('ember.png'),
SpriteAnimationData.sequenced(
amount: 4, ///將圖切成4等份
textureSize: Vector2.all(16), ///每等份大小(也就是說,看你的精靈圖一格是多大)
stepTime: 0.12, ///播放速度
),
);
}
}
class EmberQuestGame extends FlameGame
with HasCollisionDetection, HasKeyboardHandlerComponents {
@override
bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
horizontalDirection = 0;
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyA) ||
keysPressed.contains(LogicalKeyboardKey.arrowLeft))
? -1
: 0;
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyD) ||
keysPressed.contains(LogicalKeyboardKey.arrowRight))
? 1
: 0;
return true;
}
@override
void update(double dt) {
velocity.x = horizontalDirection * moveSpeed;
game.objectSpeed = 0;
// Prevent ember from going backwards at screen edge.
if (position.x - 36 <= 0 && horizontalDirection < 0) {
velocity.x = 0;
}
// Prevent ember from going beyond half screen.
if (position.x + 64 >= game.size.x / 2 && horizontalDirection > 0) {
velocity.x = 0;
game.objectSpeed = -moveSpeed;
}
// Apply basic gravity.
velocity.y += gravity;
// Determine if ember has jumped.
if (hasJumped) {
if (isOnGround) {
velocity.y = -jumpSpeed;
isOnGround = false;
}
hasJumped = false;
}
// Prevent ember from jumping to crazy fast.
velocity.y = velocity.y.clamp(-jumpSpeed, terminalVelocity);
// Adjust ember position.
position += velocity * dt;
// Flip ember if needed.
if (horizontalDirection < 0 && scale.x > 0) {
flipHorizontally();
} else if (horizontalDirection > 0 && scale.x < 0) {
flipHorizontally();
}
super.update(dt);
}
但我們將來比較可能會是手遊,所以我會想試著加搖捍(在遊戲那個class裡):
final knobPaint = BasicPalette.blue.withAlpha(200).paint();
final backgroundPaint = BasicPalette.blue.withAlpha(100).paint();
joystick = JoystickComponent(
knob: CircleComponent(radius: 25, paint: knobPaint),
background: CircleComponent(radius: 60, paint: backgroundPaint),
margin: const EdgeInsets.only(left: 40, bottom: 40),
);
@override
void update(double dt) {
super.update(dt);
if (!joystick.delta.isZero()) {
Vector2 ds = joystick.relativeDelta * _ember.moveSpeed * dt;
_ember.move(ds);
}
}
在ember裡也要加入move的方法去接收joystick傳給他的vector。
參考資料:
Flame官方文件
【Flutter&Flame 游戏 - 贰】操纵杆与角色移动