mirror of https://github.com/flutter/pinball.git
parent
09464347ef
commit
b0e8a3be14
@ -1,5 +1,6 @@
|
||||
export 'anchor.dart';
|
||||
export 'ball.dart';
|
||||
export 'path.dart';
|
||||
export 'plunger.dart';
|
||||
export 'score_points.dart';
|
||||
export 'wall.dart';
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
import 'package:flame/extensions.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maths/maths.dart';
|
||||
|
||||
class Path extends BodyComponent {
|
||||
Path._({
|
||||
Color? color,
|
||||
required Vector2 position,
|
||||
required List<List<Vector2>> paths,
|
||||
}) : _position = position,
|
||||
_paths = paths {
|
||||
if (color != null) {
|
||||
paint = Paint()
|
||||
..color = color
|
||||
..style = PaintingStyle.stroke;
|
||||
}
|
||||
}
|
||||
|
||||
factory Path.straight({
|
||||
Color? color,
|
||||
required Vector2 position,
|
||||
required Vector2 start,
|
||||
required Vector2 end,
|
||||
required double pathWidth,
|
||||
double rotation = 0,
|
||||
bool onlyOneWall = false,
|
||||
}) {
|
||||
final paths = <List<Vector2>>[];
|
||||
final wall1 = [
|
||||
start.clone(),
|
||||
end.clone(),
|
||||
];
|
||||
paths.add(wall1.map((e) => e..rotate(radians(rotation))).toList());
|
||||
|
||||
if (!onlyOneWall) {
|
||||
final wall2 = [
|
||||
start + Vector2(pathWidth, 0),
|
||||
end + Vector2(pathWidth, 0),
|
||||
];
|
||||
paths.add(wall2.map((e) => e..rotate(radians(rotation))).toList());
|
||||
}
|
||||
|
||||
return Path._(
|
||||
color: color,
|
||||
position: position,
|
||||
paths: paths,
|
||||
);
|
||||
}
|
||||
|
||||
factory Path.arc({
|
||||
Color? color,
|
||||
required Vector2 position,
|
||||
required double pathWidth,
|
||||
required double radius,
|
||||
required double angle,
|
||||
double rotation = 0,
|
||||
bool onlyOneWall = false,
|
||||
}) {
|
||||
final paths = <List<Vector2>>[];
|
||||
|
||||
final wall1 = calculateArc(
|
||||
center: position,
|
||||
radius: radius,
|
||||
angle: angle,
|
||||
offsetAngle: rotation,
|
||||
);
|
||||
paths.add(wall1);
|
||||
|
||||
if (!onlyOneWall) {
|
||||
final minRadius = radius - pathWidth;
|
||||
|
||||
final wall2 = calculateArc(
|
||||
center: position,
|
||||
radius: minRadius,
|
||||
angle: angle,
|
||||
offsetAngle: rotation,
|
||||
);
|
||||
paths.add(wall2);
|
||||
}
|
||||
|
||||
return Path._(
|
||||
color: color,
|
||||
position: position,
|
||||
paths: paths,
|
||||
);
|
||||
}
|
||||
|
||||
factory Path.bezierCurve({
|
||||
Color? color,
|
||||
required Vector2 position,
|
||||
required List<Vector2> controlPoints,
|
||||
required double pathWidth,
|
||||
double rotation = 0,
|
||||
bool onlyOneWall = false,
|
||||
}) {
|
||||
final paths = <List<Vector2>>[];
|
||||
|
||||
final wall1 = calculateBezierCurve(controlPoints: controlPoints);
|
||||
paths.add(wall1.map((e) => e..rotate(radians(rotation))).toList());
|
||||
|
||||
var wall2 = <Vector2>[];
|
||||
if (!onlyOneWall) {
|
||||
wall2 = calculateBezierCurve(
|
||||
controlPoints: controlPoints
|
||||
.map((e) => e + Vector2(pathWidth, -pathWidth))
|
||||
.toList(),
|
||||
);
|
||||
paths.add(wall2.map((e) => e..rotate(radians(rotation))).toList());
|
||||
}
|
||||
|
||||
return Path._(
|
||||
color: color,
|
||||
position: position,
|
||||
paths: paths,
|
||||
);
|
||||
}
|
||||
|
||||
final Vector2 _position;
|
||||
final List<List<Vector2>> _paths;
|
||||
|
||||
@override
|
||||
Body createBody() {
|
||||
final bodyDef = BodyDef()
|
||||
..type = BodyType.static
|
||||
..position = _position;
|
||||
|
||||
final body = world.createBody(bodyDef);
|
||||
|
||||
for (final path in _paths) {
|
||||
final chain = ChainShape()
|
||||
..createChain(
|
||||
path.map((e) => gameRef.screenToWorld(e)).toList(),
|
||||
);
|
||||
final fixtureDef = FixtureDef(chain);
|
||||
body.createFixture(fixtureDef);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue