import 'package:flame/palette.dart'; import 'package:flame_forge2d/body_component.dart'; import 'package:flame_forge2d/contact_callbacks.dart'; import 'package:flutter/material.dart'; import 'package:forge2d/forge2d.dart'; import 'boundaries.dart'; class Ball extends BodyComponent { late Paint originalPaint; bool giveNudge = false; final double radius; final Vector2 _position; double _timeSinceNudge = 0.0; static const double _minNudgeRest = 2.0; final Paint _blue = BasicPalette.blue.paint(); Ball(this._position, {this.radius = 2}) { originalPaint = randomPaint(); paint = originalPaint; } Paint randomPaint() => PaintExtension.random(withAlpha: 0.9, base: 100); @override Body createBody() { final shape = CircleShape(); shape.radius = radius; final fixtureDef = FixtureDef(shape) ..restitution = 0.8 ..density = 1.0 ..friction = 0.4; final bodyDef = BodyDef() // To be able to determine object in collision ..userData = this ..angularDamping = 0.8 ..position = _position ..type = BodyType.dynamic; return world.createBody(bodyDef)..createFixture(fixtureDef); } @override void renderCircle(Canvas c, Offset center, double radius) { super.renderCircle(c, center, radius); final lineRotation = Offset(0, radius); c.drawLine(center, center + lineRotation, _blue); } @override void update(double dt) { super.update(dt); _timeSinceNudge += dt; if (giveNudge) { giveNudge = false; if (_timeSinceNudge > _minNudgeRest) { body.applyLinearImpulse(Vector2(0, 1000)); _timeSinceNudge = 0.0; } } } } class WhiteBall extends Ball { WhiteBall(Vector2 position) : super(position) { originalPaint = BasicPalette.white.paint(); paint = originalPaint; } } class BallContactCallback extends ContactCallback { @override void begin(Ball ball1, Ball ball2, Contact contact) { if (ball1 is WhiteBall || ball2 is WhiteBall) { return; } if (ball1.paint != ball1.originalPaint) { ball1.paint = ball2.paint; } else { ball2.paint = ball1.paint; } } @override void end(Ball ball1, Ball ball2, Contact contact) {} } class WhiteBallContactCallback extends ContactCallback { @override void begin(Ball ball, WhiteBall whiteBall, Contact contact) { ball.giveNudge = true; } @override void end(Ball ball, WhiteBall whiteBall, Contact contact) {} } class BallWallContactCallback extends ContactCallback { @override void begin(Ball ball, Wall wall, Contact contact) { wall.paint = ball.paint; } @override void end(Ball ball, Wall wall, Contact contact) {} }