mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-31 00:48:47 +08:00
* Introduce updateTree * Update tests * Fix update for game-in-game situations * Add dartdoc to updateTree
110 lines
2.7 KiB
Dart
110 lines
2.7 KiB
Dart
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
|
|
@mustCallSuper
|
|
void update(double 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<Ball, Ball> {
|
|
@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<Ball, WhiteBall> {
|
|
@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<Ball, Wall> {
|
|
@override
|
|
void begin(Ball ball, Wall wall, Contact contact) {
|
|
wall.paint = ball.paint;
|
|
}
|
|
|
|
@override
|
|
void end(Ball ball, Wall wall, Contact contact) {}
|
|
}
|