[Notas de desenvolvimento para guerras de aeronaves baseadas em Flutter&Flame] Gerador de aeronaves inimigas

prefácio

Dando continuidade ao conteúdo anterior, este artigo registra principalmente o conteúdo básico da criação e geraçãoFlame de aeronaves inimigas com base na realização de guerra de aeronaves .

O autor incluiu esta série de artigos nas seguintes colunas, e os alunos interessados ​​podem ler:

Notas de desenvolvimento para guerras de aeronaves baseadas em Flutter&Flame

Construção do inimigo

Crie uma Enemy1herança de classe SpriteAnimationComponent, a mesma da Playerclasse anterior, mas este é o Componente que representa a aeronave inimiga .

class Enemy1 extends SpriteAnimationComponent {
  Enemy1({required Vector2 initPosition, required Vector2 size})
      : super(position: initPosition, size: size);

  @override
  Future<void> onLoad() async {
    List<Sprite> sprites = [];
    sprites.add(await Sprite.load('enemy/enemy1.png'));
    final spriteAnimation = SpriteAnimation.spriteList(sprites, stepTime: 0.15, loop: false);
    animation = spriteAnimation;

    add(RectangleHitbox()..debugMode = true);
  }

ps: Continue a usá-lo aqui SpriteAnimationComponent, mas há apenas um quadro . onLoadPor fim, adicionamos um à camada Game 敌机Component, primeiro assumimos que a posição do avião inimigo está em (50,50) e o tamanho é 50 * 50 . Claro, há também o artigo anterior Player.

// class Game
@override
Future<void> onLoad() async {
  final ParallaxComponent parallax = await loadParallaxComponent(
      [ParallaxImageData('background.png')]);
  add(parallax);

  final player = Player(
      initPosition: Vector2(size.x / 2, size.y * 0.75),
      size: Vector2(75, 100));
  add(player);

  final enemy = Enemy1(initPosition: Vector2(50, 50), size: Vector2(50, 50));
  add(enemy);
}

movimento automático

Na batalha de aeronaves, o inimigo se moverá automaticamente da parte superior da tela para a parte inferior da tela até sair da interface. Aqui nós simplesmente usamos Flamea atualização da tela para atualizar a posição do Componente inimigo .

// class Enemy1
@override
void update(double dt) {
  super.update(dt);
  Vector2 ds = Vector2(0, 1) * 100 * dt;
  position.add(ds);
  if (position.y > gameRef.size.y) {
    removeFromParent();
  }
}

Cada Componentum tem um updatecallback, se o callback print dtpuder ser encontrado, ele está basicamente à 16.66sesquerda e à direita, ou seja, ele 1sserá chamado de volta 60次. Isso corresponde à taxa de atualização 60fps. Com base nisso, você pode calcular a distância do deslocamento da aeronave inimiga em cada quadro e, em seguida, atualizá-la position.

  • 计算位移:这里运用小学的知识:s = v * t。即速度乘以时间,速度这里先简单定义100。由于是带方向的位移这里还需要转换成Vector2类型Vector2(0, 1)表示向y轴正方向移动。ps:Flame中坐标系y轴向下,所以往下为正方向,这个跟移动端界面的坐标类似。
  • 边界问题:若位移后position超过可显示范围,视为移出屏幕,此时需要将敌机Component父Component中移除。这里利用gameRef获取到最上层的Game对象,它的size即为游戏可显示范围

自动生成器

实际场景中,敌机应该是随机在屏幕上方生成,然后再进行自动移动的。所以这里就需要一个生成器(亦或者是管理器,因为也不止一个种类的敌机)。

所以这里需要新建一个Component专门用作生成器。

class EnemyCreator extends PositionComponent with HasGameRef {
  late Timer _createTimer;
  final Random _random = Random();

  @override
  Future<void> onLoad() async {
    _createTimer = Timer(1, onTick: _createEnemy, repeat: true);
  }

  @override
  void onMount() {
    super.onMount();
    _createTimer.start();
  }

  @override
  void update(double dt) {
    super.update(dt);
    _createTimer.update(dt);
  }

  @override
  void onRemove() {
    super.onRemove();
    _createTimer.stop();
  }

  void _createEnemy() {
    final width = gameRef.size.x;
    double x = _random.nextDouble() * width;
    final Vector2 size = Vector2(50, 50);
    if (width - x < 50) {
      x = width - 50;
    }
    final enemy1 = Enemy1(initPosition: Vector2(x, -size.y), size: size);
    add(enemy1);
  }
}

创建类EnemyCreator用于敌机生成

  • 继承自PositionComponent。其实上述的SpriteAnimationComponent也是继承于它。默认的position为(0,0),size为0 * 0。所以可以理解为这是一个不在Component树中绘制出来的Component
  • Use o Timertempo para criar um avião inimigo, o tempo é 1s. Método de disparo temporizado _createEnemy. Pode-se ver no código que Timertambém depende do updateretorno de chamada. ps: O tempoonMount quando o componente é montado na árvore de componentes e vice-versa .onRemove
  • _createEnemyO método usará a largura do jogo para calcular uma coordenada x aleatória e, em seguida, definirá a coordenada y na -size.yposição para obter o efeito de que a aeronave inimiga se mova da parte superior da tela para a parte inferior .
  • Após adicionar a Component树, 敌机Componenta lógica de movimento automático anterior será executada para sair da tela de cima para baixo.

おすすめ

転載: juejin.im/post/7117185613795131400