|
|
@ -7,20 +7,22 @@ import 'package:flame/components.dart';
|
|
|
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
|
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
|
|
import 'package:pinball/game/game.dart';
|
|
|
|
import 'package:pinball/game/game.dart';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(erickzanardo): change this to use the layer class
|
|
|
|
|
|
|
|
// that will be introduced on the path PR
|
|
|
|
const _spaceShipBits = 0x0002;
|
|
|
|
const _spaceShipBits = 0x0002;
|
|
|
|
|
|
|
|
const _spaceShipSize = 20.0;
|
|
|
|
|
|
|
|
|
|
|
|
class Spaceship extends Component {
|
|
|
|
/// {@template spaceship_sauce}
|
|
|
|
static const size = 20.0;
|
|
|
|
/// A [BodyComponent] for the base, or the sauce of the spaceship
|
|
|
|
}
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipSauce extends BodyComponent with InitialPosition {
|
|
|
|
class SpaceshipSauce extends BodyComponent {
|
|
|
|
/// {@macro spaceship_sauce}
|
|
|
|
SpaceshipSauce(this.position) : super(priority: 2);
|
|
|
|
SpaceshipSauce() : super(priority: 2);
|
|
|
|
|
|
|
|
|
|
|
|
// TODO change to initial position
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final Vector2 position;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Path for the base sprite
|
|
|
|
static const sauceSpritePath = 'components/spaceship/sauce.png';
|
|
|
|
static const sauceSpritePath = 'components/spaceship/sauce.png';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Path for the upper wall sprite
|
|
|
|
static const upperWallPath = 'components/spaceship/upper.png';
|
|
|
|
static const upperWallPath = 'components/spaceship/upper.png';
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -34,7 +36,7 @@ class SpaceshipSauce extends BodyComponent {
|
|
|
|
await add(
|
|
|
|
await add(
|
|
|
|
SpriteComponent(
|
|
|
|
SpriteComponent(
|
|
|
|
sprite: sprites.first,
|
|
|
|
sprite: sprites.first,
|
|
|
|
size: Vector2.all(Spaceship.size),
|
|
|
|
size: Vector2.all(_spaceShipSize),
|
|
|
|
anchor: Anchor.center,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -42,9 +44,9 @@ class SpaceshipSauce extends BodyComponent {
|
|
|
|
await add(
|
|
|
|
await add(
|
|
|
|
SpriteComponent(
|
|
|
|
SpriteComponent(
|
|
|
|
sprite: sprites.last,
|
|
|
|
sprite: sprites.last,
|
|
|
|
size: Vector2(Spaceship.size + 0.5, Spaceship.size / 2),
|
|
|
|
size: Vector2(_spaceShipSize + 0.5, _spaceShipSize / 2),
|
|
|
|
anchor: Anchor.center,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
position: Vector2(0, -(Spaceship.size / 3.5)),
|
|
|
|
position: Vector2(0, -(_spaceShipSize / 3.5)),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
@ -53,11 +55,11 @@ class SpaceshipSauce extends BodyComponent {
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
|
final circleShape = CircleShape()..radius = Spaceship.size / 2;
|
|
|
|
final circleShape = CircleShape()..radius = _spaceShipSize / 2;
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
..userData = this
|
|
|
|
..userData = this
|
|
|
|
..position = position
|
|
|
|
..position = initialPosition
|
|
|
|
..type = BodyType.static;
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
@ -70,14 +72,15 @@ class SpaceshipSauce extends BodyComponent {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class SpaceshipBridgeTop extends BodyComponent {
|
|
|
|
/// {@spaceship_bridge_top}
|
|
|
|
SpaceshipBridgeTop(
|
|
|
|
/// The bridge of the spaceship (the android head) is divided in two
|
|
|
|
this.position,
|
|
|
|
// [BodyComponent]s, this is the top part of it which contains a single sprite
|
|
|
|
) : super(priority: 6);
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipBridgeTop extends BodyComponent with InitialPosition {
|
|
|
|
// TODO change to initial position
|
|
|
|
/// {@macro spaceship_bridge_top}
|
|
|
|
final Vector2 position;
|
|
|
|
SpaceshipBridgeTop() : super(priority: 6);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Path to the top of this sprite
|
|
|
|
static const spritePath = 'components/spaceship/android-top.png';
|
|
|
|
static const spritePath = 'components/spaceship/android-top.png';
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -89,7 +92,7 @@ class SpaceshipBridgeTop extends BodyComponent {
|
|
|
|
SpriteComponent(
|
|
|
|
SpriteComponent(
|
|
|
|
sprite: sprite,
|
|
|
|
sprite: sprite,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
size: Vector2(Spaceship.size / 2.5 - 1, Spaceship.size / 5),
|
|
|
|
size: Vector2(_spaceShipSize / 2.5 - 1, _spaceShipSize / 5),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -98,54 +101,22 @@ class SpaceshipBridgeTop extends BodyComponent {
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
..userData = this
|
|
|
|
..userData = this
|
|
|
|
..position = position + Vector2(0, 5.5)
|
|
|
|
..position = initialPosition
|
|
|
|
..type = BodyType.static;
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef);
|
|
|
|
return world.createBody(bodyDef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class SpaceshipEntrance extends BodyComponent {
|
|
|
|
/// {@template spaceship_bridge}
|
|
|
|
SpaceshipEntrance(this.position);
|
|
|
|
/// The main part of the [SpaceshipBridge], this [BodyComponent]
|
|
|
|
|
|
|
|
/// provides both the collision and the rotation animation for the bridge.
|
|
|
|
// TODO change to initial position
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipBridge extends BodyComponent with InitialPosition {
|
|
|
|
final Vector2 position;
|
|
|
|
/// {@macro spaceship_bridge}
|
|
|
|
|
|
|
|
SpaceshipBridge() : super(priority: 3);
|
|
|
|
@override
|
|
|
|
|
|
|
|
Body createBody() {
|
|
|
|
|
|
|
|
const r = Spaceship.size / 2;
|
|
|
|
|
|
|
|
final entranceShape = PolygonShape()
|
|
|
|
|
|
|
|
..setAsEdge(
|
|
|
|
|
|
|
|
Vector2(
|
|
|
|
|
|
|
|
r * cos(20 * pi / 180),
|
|
|
|
|
|
|
|
r * sin(20 * pi / 180),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
Vector2(
|
|
|
|
|
|
|
|
r * cos(340 * pi / 180),
|
|
|
|
|
|
|
|
r * sin(340 * pi / 180),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
|
|
|
|
..userData = this
|
|
|
|
|
|
|
|
..position = position
|
|
|
|
|
|
|
|
..angle = 90 * pi / 180
|
|
|
|
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
|
|
|
|
..createFixture(
|
|
|
|
|
|
|
|
FixtureDef(entranceShape)..isSensor = true,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SpaceshipBridge extends BodyComponent {
|
|
|
|
|
|
|
|
SpaceshipBridge(this.position) : super(priority: 3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO change to initial position
|
|
|
|
|
|
|
|
final Vector2 position;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Path to the spaceship bridge
|
|
|
|
static const spritePath = 'components/spaceship/android-bottom.png';
|
|
|
|
static const spritePath = 'components/spaceship/android-bottom.png';
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -163,7 +134,7 @@ class SpaceshipBridge extends BodyComponent {
|
|
|
|
stepTime: 0.2,
|
|
|
|
stepTime: 0.2,
|
|
|
|
textureSize: Vector2(160, 114),
|
|
|
|
textureSize: Vector2(160, 114),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
size: Vector2.all(Spaceship.size / 2.5),
|
|
|
|
size: Vector2.all(_spaceShipSize / 2.5),
|
|
|
|
anchor: Anchor.center,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -171,11 +142,11 @@ class SpaceshipBridge extends BodyComponent {
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
|
final circleShape = CircleShape()..radius = Spaceship.size / 5;
|
|
|
|
final circleShape = CircleShape()..radius = _spaceShipSize / 5;
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
..userData = this
|
|
|
|
..userData = this
|
|
|
|
..position = position
|
|
|
|
..position = initialPosition
|
|
|
|
..type = BodyType.static;
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
@ -188,20 +159,59 @@ class SpaceshipBridge extends BodyComponent {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class SpaceshipHole extends BodyComponent {
|
|
|
|
/// {@template spaceship_entrance}
|
|
|
|
SpaceshipHole(this.position);
|
|
|
|
/// A sensor [BodyComponent] used to detect when the ball enters the
|
|
|
|
|
|
|
|
/// the spaceship area in order to modify its filter data so the ball
|
|
|
|
|
|
|
|
/// can correctly collide only with the Spaceship
|
|
|
|
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipEntrance extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
/// {@macro spaceship_entrance}
|
|
|
|
|
|
|
|
SpaceshipEntrance();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
|
|
Body createBody() {
|
|
|
|
|
|
|
|
const r = _spaceShipSize / 2;
|
|
|
|
|
|
|
|
final entranceShape = PolygonShape()
|
|
|
|
|
|
|
|
..setAsEdge(
|
|
|
|
|
|
|
|
Vector2(
|
|
|
|
|
|
|
|
r * cos(20 * pi / 180),
|
|
|
|
|
|
|
|
r * sin(20 * pi / 180),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
Vector2(
|
|
|
|
|
|
|
|
r * cos(340 * pi / 180),
|
|
|
|
|
|
|
|
r * sin(340 * pi / 180),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
|
|
|
|
..userData = this
|
|
|
|
|
|
|
|
..position = initialPosition
|
|
|
|
|
|
|
|
..angle = 90 * pi / 180
|
|
|
|
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
|
|
|
|
..createFixture(
|
|
|
|
|
|
|
|
FixtureDef(entranceShape)..isSensor = true,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO change to initial position
|
|
|
|
/// {@template spaceship_hole}
|
|
|
|
final Vector2 position;
|
|
|
|
/// A sensor [BodyComponent] responsible for sending the [Ball]
|
|
|
|
|
|
|
|
/// back to the board.
|
|
|
|
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipHole extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
/// {@macro spaceship_hole}
|
|
|
|
|
|
|
|
SpaceshipHole();
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
|
renderBody = false;
|
|
|
|
renderBody = false;
|
|
|
|
final circleShape = CircleShape()..radius = Spaceship.size / 14;
|
|
|
|
final circleShape = CircleShape()..radius = _spaceShipSize / 14;
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
..userData = this
|
|
|
|
..userData = this
|
|
|
|
..position = position
|
|
|
|
..position = initialPosition
|
|
|
|
..type = BodyType.static;
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
@ -214,13 +224,17 @@ class SpaceshipHole extends BodyComponent {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class SpaceshipWall extends BodyComponent {
|
|
|
|
/// {@template spaceship_wall}
|
|
|
|
SpaceshipWall(this.position) : super(priority: 4);
|
|
|
|
/// A [BodyComponent] that provides the collision for the wall
|
|
|
|
|
|
|
|
/// surrounding the spaceship, with a small opening to allow the
|
|
|
|
// TODO change to initial position
|
|
|
|
/// [Ball] to get inside the spaceship sauce.
|
|
|
|
|
|
|
|
/// It also contains the [SpriteComponent] for the lower wall
|
|
|
|
final Vector2 position;
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
|
|
|
class SpaceshipWall extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
/// {@macro spaceship_wall}
|
|
|
|
|
|
|
|
SpaceshipWall() : super(priority: 4);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Sprite path for the lower wall
|
|
|
|
static const lowerWallPath = 'components/spaceship/lower.png';
|
|
|
|
static const lowerWallPath = 'components/spaceship/lower.png';
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -232,9 +246,9 @@ class SpaceshipWall extends BodyComponent {
|
|
|
|
await add(
|
|
|
|
await add(
|
|
|
|
SpriteComponent(
|
|
|
|
SpriteComponent(
|
|
|
|
sprite: sprite,
|
|
|
|
sprite: sprite,
|
|
|
|
size: Vector2(Spaceship.size, (Spaceship.size / 2) + 1),
|
|
|
|
size: Vector2(_spaceShipSize, (_spaceShipSize / 2) + 1),
|
|
|
|
anchor: Anchor.center,
|
|
|
|
anchor: Anchor.center,
|
|
|
|
position: Vector2(-Spaceship.size / 4, 0),
|
|
|
|
position: Vector2(-_spaceShipSize / 4, 0),
|
|
|
|
angle: 90 * pi / 180,
|
|
|
|
angle: 90 * pi / 180,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -244,7 +258,7 @@ class SpaceshipWall extends BodyComponent {
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
|
renderBody = false;
|
|
|
|
renderBody = false;
|
|
|
|
|
|
|
|
|
|
|
|
const r = Spaceship.size / 2;
|
|
|
|
const r = _spaceShipSize / 2;
|
|
|
|
|
|
|
|
|
|
|
|
final wallShape = ChainShape()
|
|
|
|
final wallShape = ChainShape()
|
|
|
|
..createChain(
|
|
|
|
..createChain(
|
|
|
@ -259,7 +273,7 @@ class SpaceshipWall extends BodyComponent {
|
|
|
|
|
|
|
|
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
final bodyDef = BodyDef()
|
|
|
|
..userData = this
|
|
|
|
..userData = this
|
|
|
|
..position = position
|
|
|
|
..position = initialPosition
|
|
|
|
..angle = 90 * pi / 180
|
|
|
|
..angle = 90 * pi / 180
|
|
|
|
..type = BodyType.static;
|
|
|
|
..type = BodyType.static;
|
|
|
|
|
|
|
|
|
|
|
@ -273,6 +287,10 @@ class SpaceshipWall extends BodyComponent {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// [ContactCallback] that handles the contact between the [Ball]
|
|
|
|
|
|
|
|
/// and the [SpaceshipEntrance], it modifies the [Ball] priority
|
|
|
|
|
|
|
|
/// and filter data so it can appear on top of the spaceship and
|
|
|
|
|
|
|
|
/// also only collide with the spaceship
|
|
|
|
class SpaceshipEntranceBallContactCallback
|
|
|
|
class SpaceshipEntranceBallContactCallback
|
|
|
|
extends ContactCallback<SpaceshipEntrance, Ball> {
|
|
|
|
extends ContactCallback<SpaceshipEntrance, Ball> {
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -288,6 +306,9 @@ class SpaceshipEntranceBallContactCallback
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// [ContactCallback] that handles the contact between the [Ball]
|
|
|
|
|
|
|
|
/// and a [SpaceshipHole], it will reset the [Ball] priority and
|
|
|
|
|
|
|
|
/// filter data so it will "be back" on the board
|
|
|
|
class SpaceshipHoleBallContactCallback
|
|
|
|
class SpaceshipHoleBallContactCallback
|
|
|
|
extends ContactCallback<SpaceshipHole, Ball> {
|
|
|
|
extends ContactCallback<SpaceshipHole, Ball> {
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|