|
|
@ -8,10 +8,6 @@ import 'package:flame_forge2d/flame_forge2d.dart';
|
|
|
|
import 'package:pinball/flame/blueprint.dart';
|
|
|
|
import 'package:pinball/flame/blueprint.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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A [Blueprint] which creates the spaceship feature.
|
|
|
|
/// A [Blueprint] which creates the spaceship feature.
|
|
|
|
class Spaceship extends Forge2DBlueprint {
|
|
|
|
class Spaceship extends Forge2DBlueprint {
|
|
|
|
/// Total size of the spaceship
|
|
|
|
/// Total size of the spaceship
|
|
|
@ -19,7 +15,7 @@ class Spaceship extends Forge2DBlueprint {
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
void build() {
|
|
|
|
void build() {
|
|
|
|
final position = Vector2(20, -24);
|
|
|
|
final position = Vector2(30, -50);
|
|
|
|
|
|
|
|
|
|
|
|
addAllContactCallback([
|
|
|
|
addAllContactCallback([
|
|
|
|
SpaceshipHoleBallContactCallback(),
|
|
|
|
SpaceshipHoleBallContactCallback(),
|
|
|
@ -41,9 +37,11 @@ class Spaceship extends Forge2DBlueprint {
|
|
|
|
/// {@template spaceship_saucer}
|
|
|
|
/// {@template spaceship_saucer}
|
|
|
|
/// A [BodyComponent] for the base, or the saucer of the spaceship
|
|
|
|
/// A [BodyComponent] for the base, or the saucer of the spaceship
|
|
|
|
/// {@endtemplate}
|
|
|
|
/// {@endtemplate}
|
|
|
|
class SpaceshipSaucer extends BodyComponent with InitialPosition {
|
|
|
|
class SpaceshipSaucer extends BodyComponent with InitialPosition, Layered {
|
|
|
|
/// {@macro spaceship_saucer}
|
|
|
|
/// {@macro spaceship_saucer}
|
|
|
|
SpaceshipSaucer() : super(priority: 2);
|
|
|
|
SpaceshipSaucer() : super(priority: 2) {
|
|
|
|
|
|
|
|
layer = Layer.spaceship;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Path for the base sprite
|
|
|
|
/// Path for the base sprite
|
|
|
|
static const saucerSpritePath = 'components/spaceship/saucer.png';
|
|
|
|
static const saucerSpritePath = 'components/spaceship/saucer.png';
|
|
|
@ -90,10 +88,7 @@ class SpaceshipSaucer extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
..createFixture(
|
|
|
|
..createFixture(
|
|
|
|
FixtureDef(circleShape)
|
|
|
|
FixtureDef(circleShape)..isSensor = true,
|
|
|
|
..isSensor = true
|
|
|
|
|
|
|
|
..filter.maskBits = _spaceShipBits
|
|
|
|
|
|
|
|
..filter.categoryBits = _spaceShipBits,
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -138,9 +133,11 @@ class SpaceshipBridgeTop extends BodyComponent with InitialPosition {
|
|
|
|
/// The main part of the [SpaceshipBridge], this [BodyComponent]
|
|
|
|
/// The main part of the [SpaceshipBridge], this [BodyComponent]
|
|
|
|
/// provides both the collision and the rotation animation for the bridge.
|
|
|
|
/// provides both the collision and the rotation animation for the bridge.
|
|
|
|
/// {@endtemplate}
|
|
|
|
/// {@endtemplate}
|
|
|
|
class SpaceshipBridge extends BodyComponent with InitialPosition {
|
|
|
|
class SpaceshipBridge extends BodyComponent with InitialPosition, Layered {
|
|
|
|
/// {@macro spaceship_bridge}
|
|
|
|
/// {@macro spaceship_bridge}
|
|
|
|
SpaceshipBridge() : super(priority: 3);
|
|
|
|
SpaceshipBridge() : super(priority: 3) {
|
|
|
|
|
|
|
|
layer = Layer.spaceship;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Path to the spaceship bridge
|
|
|
|
/// Path to the spaceship bridge
|
|
|
|
static const spritePath = 'components/spaceship/android-bottom.png';
|
|
|
|
static const spritePath = 'components/spaceship/android-bottom.png';
|
|
|
@ -177,10 +174,7 @@ class SpaceshipBridge extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
..createFixture(
|
|
|
|
..createFixture(
|
|
|
|
FixtureDef(circleShape)
|
|
|
|
FixtureDef(circleShape)..restitution = 0.4,
|
|
|
|
..restitution = 0.4
|
|
|
|
|
|
|
|
..filter.maskBits = _spaceShipBits
|
|
|
|
|
|
|
|
..filter.categoryBits = _spaceShipBits,
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -190,34 +184,29 @@ class SpaceshipBridge extends BodyComponent with InitialPosition {
|
|
|
|
/// the spaceship area in order to modify its filter data so the ball
|
|
|
|
/// the spaceship area in order to modify its filter data so the ball
|
|
|
|
/// can correctly collide only with the Spaceship
|
|
|
|
/// can correctly collide only with the Spaceship
|
|
|
|
/// {@endtemplate}
|
|
|
|
/// {@endtemplate}
|
|
|
|
// TODO(erickzanardo): Use RampOpening once provided.
|
|
|
|
class SpaceshipEntrance extends RampOpening {
|
|
|
|
class SpaceshipEntrance extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
/// {@macro spaceship_entrance}
|
|
|
|
/// {@macro spaceship_entrance}
|
|
|
|
SpaceshipEntrance();
|
|
|
|
SpaceshipEntrance()
|
|
|
|
|
|
|
|
: super(
|
|
|
|
|
|
|
|
pathwayLayer: Layer.spaceship,
|
|
|
|
|
|
|
|
orientation: RampOrientation.up,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
layer = Layer.spaceship;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Body createBody() {
|
|
|
|
Shape get shape {
|
|
|
|
final entranceShape = PolygonShape()
|
|
|
|
const radius = Spaceship.radius * 2;
|
|
|
|
|
|
|
|
return PolygonShape()
|
|
|
|
..setAsEdge(
|
|
|
|
..setAsEdge(
|
|
|
|
Vector2(
|
|
|
|
Vector2(
|
|
|
|
Spaceship.radius * cos(20 * pi / 180),
|
|
|
|
radius * cos(20 * pi / 180),
|
|
|
|
Spaceship.radius * sin(20 * pi / 180),
|
|
|
|
radius * sin(20 * pi / 180),
|
|
|
|
),
|
|
|
|
)..rotate(90 * pi / 180),
|
|
|
|
Vector2(
|
|
|
|
Vector2(
|
|
|
|
Spaceship.radius * cos(340 * pi / 180),
|
|
|
|
radius * cos(340 * pi / 180),
|
|
|
|
Spaceship.radius * sin(340 * pi / 180),
|
|
|
|
radius * sin(340 * pi / 180),
|
|
|
|
),
|
|
|
|
)..rotate(90 * 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,
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -226,9 +215,11 @@ class SpaceshipEntrance extends BodyComponent with InitialPosition {
|
|
|
|
/// A sensor [BodyComponent] responsible for sending the [Ball]
|
|
|
|
/// A sensor [BodyComponent] responsible for sending the [Ball]
|
|
|
|
/// back to the board.
|
|
|
|
/// back to the board.
|
|
|
|
/// {@endtemplate}
|
|
|
|
/// {@endtemplate}
|
|
|
|
class SpaceshipHole extends BodyComponent with InitialPosition {
|
|
|
|
class SpaceshipHole extends BodyComponent with InitialPosition, Layered {
|
|
|
|
/// {@macro spaceship_hole}
|
|
|
|
/// {@macro spaceship_hole}
|
|
|
|
SpaceshipHole();
|
|
|
|
SpaceshipHole() {
|
|
|
|
|
|
|
|
layer = Layer.spaceship;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Body createBody() {
|
|
|
|
Body createBody() {
|
|
|
@ -242,10 +233,7 @@ class SpaceshipHole extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
..createFixture(
|
|
|
|
..createFixture(
|
|
|
|
FixtureDef(circleShape)
|
|
|
|
FixtureDef(circleShape)..isSensor = true,
|
|
|
|
..isSensor = true
|
|
|
|
|
|
|
|
..filter.maskBits = _spaceShipBits
|
|
|
|
|
|
|
|
..filter.categoryBits = _spaceShipBits,
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -256,9 +244,11 @@ class SpaceshipHole extends BodyComponent with InitialPosition {
|
|
|
|
/// [Ball] to get inside the spaceship saucer.
|
|
|
|
/// [Ball] to get inside the spaceship saucer.
|
|
|
|
/// It also contains the [SpriteComponent] for the lower wall
|
|
|
|
/// It also contains the [SpriteComponent] for the lower wall
|
|
|
|
/// {@endtemplate}
|
|
|
|
/// {@endtemplate}
|
|
|
|
class SpaceshipWall extends BodyComponent with InitialPosition {
|
|
|
|
class SpaceshipWall extends BodyComponent with InitialPosition, Layered {
|
|
|
|
/// {@macro spaceship_wall}
|
|
|
|
/// {@macro spaceship_wall}
|
|
|
|
SpaceshipWall() : super(priority: 4);
|
|
|
|
SpaceshipWall() : super(priority: 4) {
|
|
|
|
|
|
|
|
layer = Layer.spaceship;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sprite path for the lower wall
|
|
|
|
/// Sprite path for the lower wall
|
|
|
|
static const lowerWallPath = 'components/spaceship/lower.png';
|
|
|
|
static const lowerWallPath = 'components/spaceship/lower.png';
|
|
|
@ -303,10 +293,7 @@ class SpaceshipWall extends BodyComponent with InitialPosition {
|
|
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
return world.createBody(bodyDef)
|
|
|
|
..createFixture(
|
|
|
|
..createFixture(
|
|
|
|
FixtureDef(wallShape)
|
|
|
|
FixtureDef(wallShape)..restitution = 1,
|
|
|
|
..restitution = 1
|
|
|
|
|
|
|
|
..filter.maskBits = _spaceShipBits
|
|
|
|
|
|
|
|
..filter.categoryBits = _spaceShipBits,
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -316,19 +303,14 @@ class SpaceshipWall extends BodyComponent with InitialPosition {
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// It modifies the [Ball] priority and filter data so it can appear on top of
|
|
|
|
/// It modifies the [Ball] priority and filter data so it can appear on top of
|
|
|
|
/// the spaceship and also only collide with the spaceship.
|
|
|
|
/// the spaceship and also only collide with the spaceship.
|
|
|
|
// TODO(alestiago): modify once Layer is implemented in Spaceship.
|
|
|
|
|
|
|
|
class SpaceshipEntranceBallContactCallback
|
|
|
|
class SpaceshipEntranceBallContactCallback
|
|
|
|
extends ContactCallback<SpaceshipEntrance, Ball> {
|
|
|
|
extends ContactCallback<SpaceshipEntrance, Ball> {
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
void begin(SpaceshipEntrance entrance, Ball ball, _) {
|
|
|
|
void begin(SpaceshipEntrance entrance, Ball ball, _) {
|
|
|
|
ball
|
|
|
|
ball
|
|
|
|
..priority = 3
|
|
|
|
..priority = 3
|
|
|
|
..gameRef.reorderChildren();
|
|
|
|
..gameRef.reorderChildren()
|
|
|
|
|
|
|
|
..layer = Layer.spaceship;
|
|
|
|
for (final fixture in ball.body.fixtures) {
|
|
|
|
|
|
|
|
fixture.filterData.categoryBits = _spaceShipBits;
|
|
|
|
|
|
|
|
fixture.filterData.maskBits = _spaceShipBits;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -337,18 +319,13 @@ class SpaceshipEntranceBallContactCallback
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// It resets the [Ball] priority and filter data so it will "be back" on the
|
|
|
|
/// It resets the [Ball] priority and filter data so it will "be back" on the
|
|
|
|
/// board.
|
|
|
|
/// board.
|
|
|
|
// TODO(alestiago): modify once Layer is implemented in Spaceship.
|
|
|
|
|
|
|
|
class SpaceshipHoleBallContactCallback
|
|
|
|
class SpaceshipHoleBallContactCallback
|
|
|
|
extends ContactCallback<SpaceshipHole, Ball> {
|
|
|
|
extends ContactCallback<SpaceshipHole, Ball> {
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
void begin(SpaceshipHole hole, Ball ball, _) {
|
|
|
|
void begin(SpaceshipHole hole, Ball ball, _) {
|
|
|
|
ball
|
|
|
|
ball
|
|
|
|
..priority = 1
|
|
|
|
..priority = 1
|
|
|
|
..gameRef.reorderChildren();
|
|
|
|
..gameRef.reorderChildren()
|
|
|
|
|
|
|
|
..layer = Layer.board;
|
|
|
|
for (final fixture in ball.body.fixtures) {
|
|
|
|
|
|
|
|
fixture.filterData.categoryBits = 0xFFFF;
|
|
|
|
|
|
|
|
fixture.filterData.maskBits = 0x0001;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|