flutter 吸泡泡游戏

import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Bubble {
  Offset position;
  Color color;
  double size;
  Bubble(this.position, this.color, this.size);
  double distance(Bubble other) {
    return sqrt(pow(position.dx - other.position.dx, 2) + pow(position.dy - other.position.dy, 2));
  }
}

class GamePainter extends CustomPainter {
  List<Bubble> bubbles = [];
  GamePainter(this.bubbles);
  @override
  void paint(Canvas canvas, Size size) {
    for (int i = 0; i < bubbles.length; i++) {
      Paint paint = Paint();
      paint.color = bubbles[i].color;
      paint.style = PaintingStyle.fill;
      paint.strokeWidth = 2;
      paint.strokeCap = StrokeCap.round;
      canvas.drawCircle(bubbles[i].position, bubbles[i].size, paint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

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

  @override
  BubbleGameState createState() => BubbleGameState();
}

class BubbleGameState extends State<BubbleGame>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _animation;
  List<Bubble> bubbles = [];
  Bubble player =Bubble(const Offset(200, 200), Colors.blue.withOpacity(0.3), 20);
  late Offset newPosition;
  late Offset oldPosition;
  @override
  void initState() {
    _controller = AnimationController(duration: const Duration(seconds:1), vsync: this);
    super.initState();
    generateBubble();
  }

  void generateBubble() {
    bubbles.clear();
    player = Bubble(const Offset(200, 200), Colors.blue.withOpacity(0.3), 10);
    for (int i = 0; i < 40; i++) {
      Random r = Random.secure();
      double size = r.nextDouble() * 30;
      Color color = size < player.size
          ? Colors.yellow.withOpacity(0.3)
          : Colors.pink.withOpacity(0.3);

      Bubble newBubble = Bubble(
          Offset(
              r.nextDouble() * 400 + i / 4.00, r.nextDouble() * 400 + i / 4.00),
          color,
          size);
      bubbles.add(newBubble);
    }
  }

  void animation(clickPosition) {
    if (_controller.isAnimating || _controller.isCompleted) {
      _controller.reset();
    }
    oldPosition = player.position;
    newPosition = clickPosition;
    _animation = Tween<Offset>(begin: oldPosition, end: newPosition)
        .animate(_controller);
    _animation.addListener(() {
      if (_controller.isAnimating) {
        setState(() {
          player.position = oldPosition * (1 - _controller.value) +  newPosition * _controller.value;
          checkDistance();
        });
      }
    });
    _controller.forward();
  }

  checkDistance() {
    for (int i = 0; i < bubbles.length; i++) {
      if (bubbles[i].size > player.size) {
        bubbles[i].color = Colors.pink.withOpacity(0.3);
        if (bubbles[i].distance(player) < player.size + bubbles[i].size) {
          if (player.size > 1) {
            reSizeBubbles(player, bubbles[i]);
          } else {
            if (kDebugMode) {
              print("输了");
            }

            generateBubble();
          }
        }
      } else {
        bubbles[i].color = Colors.yellow.withOpacity(0.3);
        if (bubbles[i].distance(player) < bubbles[i].size + player.size) {
          if (bubbles[i].size > 1) {
            reSizeBubbles(bubbles[i], player);
          } else {
            bubbles.removeAt(i);
            if (bubbles.isEmpty) {
              if (kDebugMode) {
                print("赢了");
              }
              generateBubble();
            }
          }
        }
      }
    }
  }

  void reSizeBubbles(Bubble small, Bubble big) {
    double s1 = (small.size * 2 - 1) * 0.8;
    double s2 = big.size * big.size;
    double newSize = sqrt((s2 + s1));
    small.size--;
    big.size = newSize;
  }

  @override
  Widget build(BuildContext context) {
    List<Bubble> all = [...bubbles, player];
    return Scaffold(
        floatingActionButton: ElevatedButton(
            onPressed: () {
              setState(() {
                generateBubble();
              });
            },
            child: const Text("重新开始")),
        body: Container(
          color: Colors.green,
          child: InkWell(
            onTapDown: (details) {
              animation(details.localPosition);
            },
            child: Center(
              child: CustomPaint(
                size: const Size(double.infinity, double.infinity),
                willChange: true,
                painter: GamePainter(all),
              ),
            ),
          ),
        ));
  }
}

main() {
  runApp(const MaterialApp(
    debugShowCheckedModeBanner: false,
    home: BubbleGame(),
    title: "吸泡泡",
  ));
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值