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: "吸泡泡",
));
}
flutter 吸泡泡游戏
于 2024-08-23 16:36:54 首次发布