将继承FlameGame的类可变成一个Widget

class Survice extends StatefulWidget {
  const Survice({super.key});

  @override
  State<Survice> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<Survice> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Game'),
      ),
      body: GameWidget(
        game: StickGame(),
      ),
    );
  }
}

class StickGame extends FlameGame with HasDraggables, HasTappables {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Please link device'),
      ),
    );
    body:
    Container(
      width: 100,
      color: Colors.black,
    );
  }

  late Timer timer;
  List<BulletComponent> bullets = [];

  final Paint paint = Paint()..color = const Color.fromARGB(255, 35, 36, 38);
  late TargetComponent target;

  bool isRunning = false;
  double seconds = 0;

  late TextComponent score;
  late TextComponent restartText;

  final Path canvasPath = Path();

  final Random random = Random();

  final Vector2 scorePosition = Vector2(40, 40);

  bool isDrag = false;

  @override
  Future<void>? onLoad() async {
    target =
        TargetComponent(position: Vector2(canvasSize.x / 2, canvasSize.y / 2));
    score =
        TextComponent(position: scorePosition.clone(), text: "0", textSize: 30);
    restartText = TextComponent(
        position: Vector2(canvasSize.x / 2, canvasSize.y / 2),
        text: "START",
        textSize: 50);

    canvasPath.addRect(Rect.fromLTWH(0, 0, canvasSize.x, canvasSize.y));

    timer = Timer(0.1, onTick: () {
      createBullet();
    }, repeat: true);

    return super.onLoad();
  }

  void createBullet() {
    bool isHorizontal = random.nextBool();
    var radius = random.nextInt(10) + 5;
    int x = isHorizontal
        ? random.nextInt(canvasSize.x.toInt())
        : random.nextBool()
            ? radius
            : canvasSize.x.toInt() - radius;
    int y = isHorizontal
        ? random.nextBool()
            ? radius
            : canvasSize.y.toInt() - radius
        : random.nextInt(canvasSize.y.toInt());
    var position = Vector2(x.toDouble(), y.toDouble());
    var angle = atan2(y - target.position.y, x - target.position.x);
    var speed = seconds / 10 + 5;
    bullets.add(BulletComponent(
        position: position,
        angle: angle,
        radius: radius.toDouble(),
        speed: speed));
  }

  void stop() {
    isRunning = false;
    restartText.text = "RESTART";
    score.position
        .setValues(restartText.position.x, restartText.position.y - 80);
    score.text = "Time ${seconds.toInt()} s";
    score.textSize = 35;
  }

  void restart() {
    isRunning = true;
    bullets.clear();
    target.resetPosition();
    score.position.setValues(scorePosition.x + 15, scorePosition.y);
    score.textSize = 25;
    seconds = 0;
  }

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

    canvas.drawPath(canvasPath, paint);

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

    target.render(canvas);

    score.render(canvas);
    if (!isRunning) {
      restartText.render(canvas);
    }
  }

  @override
  void update(double dt) {
    super.update(dt);
    if (isRunning) {
      seconds += dt;
      score.text = "Time ${seconds.toInt()} s";
      timer.update(dt);
      for (var bullet in bullets) {
        if (collisionCheck(bullet)) {
          stop();
          return;
        } else {
          bullet.update(dt);
        }
      }
      checkBullets();
    }
  }

  void checkBullets() {
    var removeBullets = <BulletComponent>[];
    for (var bullet in bullets) {
      if (!canvasPath.contains(bullet.position.toOffset())) {
        removeBullets.add(bullet);
      }
    }
    bullets.removeWhere((element) => removeBullets.contains(element));
  }

  bool collisionCheck(BulletComponent bullet) {
    var tempPath =
        Path.combine(PathOperation.intersect, target.path, bullet.path);
    return tempPath.getBounds().width > 0;
  }

  @override
  void onDragStart(int pointerId, DragStartInfo info) {
    super.onDragStart(pointerId, info);
    if (target.path.contains(info.eventPosition.game.toOffset())) {
      isDrag = true;
    }
  }

  @override
  void onDragUpdate(int pointerId, DragUpdateInfo info) {
    super.onDragUpdate(pointerId, info);
    var eventPosition = info.eventPosition.game;
    if (eventPosition.x < target.radius ||
        eventPosition.x > canvasSize.x - target.radius ||
        eventPosition.y < target.radius ||
        eventPosition.y > canvasSize.y - target.radius) {
      return;
    }

    if (isRunning && isDrag) {
      target.onDragUpdate(pointerId, info);
    }
  }

  @override
  void onDragCancel(int pointerId) {
    super.onDragCancel(pointerId);
    isDrag = false;
  }

  @override
  void onDragEnd(int pointerId, DragEndInfo info) {
    super.onDragEnd(pointerId, info);
    isDrag = false;
  }

  @override
  void onTapUp(int pointerId, TapUpInfo info) {
    super.onTapUp(pointerId, info);
    if (!isRunning &&
        restartText.path.contains(info.eventPosition.game.toOffset())) {
      restart();
    }
  }

  @override
  void onRemove() {
    isRunning = false;
    timer.stop();
    super.onRemove();
  }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值