Flutter之Flame初体验

914 阅读2分钟

你有没有想过在Flutter中构建游戏,但是,因为从头开始构建游戏所需的工作量而望而却步?

ezgif.com-gif-maker.gif

如果您同意,请查看Flame,这是一个构建在Flutter之上的游戏引擎。

image.png

开箱即用,它带有构建游戏所需的核心构建块,例如游戏循环、对象组件系统、碰撞检测等等。

image.png

所有这些系统也是模块化的,因此您可以挑选游戏所需的部分。

image.png

首先,创刊一个扩展FlameGame的游戏类

class MyGame extends FlameGame {

}

Flame会让您重写还很多方法来实现您的游戏逻辑,但您会特别熟悉onLoadupdate

class MyGame extendss FlameGame {
    @override
    Future<void> onLoad() async {...}
    
    @override
    void update(double dt) {...}
}

onLoad允许您加载您的Flame组件

@override
Future<void> onLoad() async {
    character = MyCharacter(...);
    add(character);
}

image.png

update,Flame在游戏循环的每一轮调用一次,允许您让您的组件有机会对游戏中发生的所有其他事情做出反应。Flame在增量是时间参数中传递此方法,它告诉您自上一个更新周期以来已经过去了多少时间。这对于计算物体的位置之类的东西很方便。

@override
void update(double dt) {
    distanceTraveled = dt * characterVelocity;
    
    position += distanceTraveled;
}

ezgif.com-gif-maker (1).gif

您可以简单地通过覆盖Flame游戏中的onLoadupdate来实现大多数事情,但有时,您会希望创建单独的游戏组件以加载到游戏中。

这些组件还具有您可以覆盖的onLoadupdate方法。 例如,当您可以通过扩展sprite组件创建自己的角色类时,您将在onLoad中加载自定义sprite资产,并覆盖其update方法以控制角色的定位。

class MyCharacter extendss SpriteComponent {
    @override
    onLoad() async {
        sprite = await gameRef.loadSprite('dash.png');
    }
    
    @override
    void update(double dt) {
        jumpHeight = dt * jumpVelocity;
        
        position += jumpHeight;
    }
}

ezgif.com-gif-maker (2).gif

要增加功能,请添加一些混音。HasGameRef将使您能够访问您的Flame游戏,以便您可以引用Flame游戏实例以及任何关联的状态。

class MyCharacter extends SpriteComponent with HasGameRef<MyGame> {
    bool isInBound() {
        gameWidth = gameRef.size.x;
        gameHeight = gameRef.size.y;
        
        // Check if char iss within bounds of game window
    }
}

ezgif.com-gif-maker (3).gif

对于碰撞检测,使用CollisionCallbacks mixin,将碰撞框添加到您的对象。覆盖onCollision方法去实现。

classs MyCharacter extends SpriteComponent with CollisionCallbacks {
    ShapeHitbox hitbox;
    
    @override
    onLoad() async {
        sprite = await gameRef.loadSprite('dash.png');
        add(hitbox);
    }
    
    @override
    onCollisionStart(intersectionPoints, other) {
        if (other is Empty) {
            gameOver();
            return;
        }
    }
}

也许KeyboardHandler mixin可以处理按键。

class MyCharacter extends SpriteComponent with KeyboardHandler {
    @override
    KeyEventResult onKeyEvent(event, keysPressed) {
        
        if (event is RawKeyDownEvent) {
            print('Key has been pressed!');
        }
        
        return super.onKeyEvent(event, keysPressed);
    }
}

ezgif.com-gif-maker (4).gif

一旦你的游戏被编码,将他传递给一个Flame小部件,它现在可以去任何接受小部件的地方。 ``` class MyGame extends StatelessWidget { Widget build(BuildContext context) { return GameWidget(game: MyGame()); } } ```

ezgif.com-gif-maker (5).gif

有关Flame和所有其他软件包的更多信息,pub.dev

原文翻译自视频:视频地址