返回

Flutter Flame子弹升级和补给

Android

子弹一直都是空战类游戏中的重要部分,不仅因为它本身是攻击敌人的主要手段,更是因为它有着丰富的玩法:不同的子弹速度、威力和射程,各种各样绚丽的子弹特效,还有许多的子弹道具可以增加游戏乐趣和策略性。例如,子弹升级是很多空战游戏中常见的一个玩法,通过收集一定数量的道具或击败特定的敌人,可以升级子弹的速度、威力和射程,使玩家在面对更强大的敌人时能够更加轻松地取得胜利。此外,在空战游戏中,还经常会出现各种各样的子弹道具,这些道具可以给玩家带来各种各样的增益效果,例如提高子弹的速度、威力或射程,或者让子弹能够穿透敌人的护盾等。这些道具不仅可以帮助玩家更轻松地击败敌人,还能为游戏增添更多的策略性和可玩性。

在上一次,我们已经完成了战机的移动和射击功能,这次我们就来实现子弹的升级和补给功能。首先,我们需要修改一下子弹的Component,在里面添加一个字段来记录子弹的等级,然后在update()方法中根据等级来调整子弹的速度和伤害。另外,我们还需要在游戏场景中添加一个新的道具类,这个道具可以增加子弹的等级,当战机与这个道具碰撞时,子弹的等级就会增加。

class BulletComponent extends PositionComponent with HasGameRef<MyGame> {
  double _speed;
  double _damage;
  int _level;

  BulletComponent({
    @required Vector2 position,
    @required Vector2 size,
    @required double angle,
    @required double speed,
    @required double damage,
    @required int level,
  }) : super(position: position, size: size, angle: angle) {
    this._speed = speed;
    this._damage = damage;
    this._level = level;
  }

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

    position += Vector2(
      cos(angle) * _speed * dt,
      sin(angle) * _speed * dt,
    );

    if (position.x < 0 || position.x > gameRef.size.x) {
      removeFromParent();
    }

    if (position.y < 0 || position.y > gameRef.size.y) {
      removeFromParent();
    }
  }

  void upgrade() {
    _level++;
    _speed *= 1.2;
    _damage *= 1.2;
  }
}
class PowerUpComponent extends PositionComponent with HasGameRef<MyGame> {
  static final String powerUpImage = 'images/powerup.png';

  PowerUpComponent({
    @required Vector2 position,
    @required Vector2 size,
  }) : super(position: position, size: size);

  @override
  void onGameResize(Vector2 newSize) {
    super.onGameResize(newSize);
    position = position.clamp(Vector2.zero(), newSize - size);
  }

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

    position += Vector2(0, 50 * dt);

    if (position.y > gameRef.size.y) {
      removeFromParent();
    }
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);

    canvas.drawImage(gameRef.images[powerUpImage], position, size);
  }

  @override
  bool intersects(Component other) {
    return super.intersects(other) && other is BulletComponent;
  }

  @override
  void onCollision(Component other) {
    super.onCollision(other);

    if (other is BulletComponent) {
      other.upgrade();
      removeFromParent();
    }
  }
}

修改完子弹的Component和添加了新的道具类后,我们还需要在游戏场景中添加这个道具,并修改战机的Component,使其能够与这个道具碰撞。

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  MyGame game = MyGame();
  runApp(game.widget);

  flame.util.addAssetPack(MyGame.assets);
}

class MyGame extends FlameGame {
  static const String spaceshipImage = 'images/spaceship.png';
  static const String bulletImage = 'images/bullet.png';
  static const String powerUpImage = 'images/powerup.png';

  SpriteComponent spaceship;
  List<BulletComponent> bullets = [];
  List<PowerUpComponent> powerUps = [];

  @override
  Future<void> onLoad() async {
    super.onLoad();

    await images.load(spaceshipImage);
    await images.load(bulletImage);
    await images.load(powerUpImage);

    add(spaceship = SpriteComponent(
      sprite: images[spaceshipImage],
      position: Vector2(size.x / 2, size.y / 2),
      size: Vector2(50, 50),
    ));

    add(JoystickComponent(
      knob: CircleComponent(
        radius: 30,
        paint: Paint()..color = Colors.white,
      ),
      background: CircleComponent(
        radius: 40,
        paint: Paint()..color = Colors.grey,
      ),
      margin: EdgeInsets.only(left: 40, bottom: 40),
    ));

    add(ButtonComponent(
      button: CircleComponent(
        radius: 30,
        paint: Paint()..color = Colors.white,
      ),
      onPressed: () {
        bullets.add(BulletComponent(
          position: spaceship.position + Vector2(25, 0),
          size: Vector2(10, 10),
          angle: spaceship.angle,
          speed: 200,
          damage: 10,
          level: 1,
        ));
      },
      margin: EdgeInsets.only(right: 40, bottom: 40),
    ));

    Timer.periodic(Duration(seconds: 1), (timer) {
      powerUps.add(PowerUpComponent(
        position: Vector2.random() * size,
        size: Vector2(20, 20),
      ));
    });
  }

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

    for (BulletComponent bullet in bullets) {
      bullet.update(dt);
    }

    for (PowerUpComponent powerUp in powerUps) {
      powerUp.update(dt);
    }
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);

    for (BulletComponent bullet in bullets) {
      bullet.render(canvas);
    }

    for (PowerUpComponent powerUp in powerUps) {
      powerUp.render(canvas);
    }
  }
}

现在,我们就可以在游戏中看到子弹的升级和补给功能了。当战机与补给道具碰撞时,子弹的等级就会增加,速度和伤害也会随之增加。这将使玩家在面对更强大的敌人时能够更加轻松地取得胜利。