refactor: changed Elevated mixin to Priority extension

pull/83/head
RuiAlonso 4 years ago
parent 6946a09e07
commit b2741a3461

@ -7,8 +7,7 @@ import 'package:pinball/gen/assets.gen.dart';
/// A solid, [BodyType.dynamic] sphere that rolls and bounces along the
/// [PinballGame].
/// {@endtemplate}
class Ball extends BodyComponent<PinballGame>
with InitialPosition, Layered, Elevated {
class Ball extends BodyComponent<PinballGame> with InitialPosition, Layered {
/// {@macro ball}
Ball() {
// TODO(ruimiguel): while developing Ball can be launched by clicking mouse,

@ -3,7 +3,6 @@ export 'baseboard.dart';
export 'board.dart';
export 'board_side.dart';
export 'bonus_word.dart';
export 'elevation.dart';
export 'flipper.dart';
export 'initial_position.dart';
export 'jetpack_ramp.dart';
@ -13,6 +12,7 @@ export 'launcher_ramp.dart';
export 'layer.dart';
export 'pathway.dart';
export 'plunger.dart';
export 'priority.dart';
export 'ramp_opening.dart';
export 'round_bumper.dart';
export 'score_points.dart';

@ -1,71 +0,0 @@
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart';
/// {@template elevated}
/// Modifies priority of the [BodyComponent] to specify in which z-index level
/// [BodyComponent] is.
/// {@endtemplate}
mixin Elevated<T extends Forge2DGame> on BodyComponent<T> {
int _elevation = Elevation.board.order;
/// {@macro elevated}
int get elevation => _elevation;
set elevation(int value) {
_elevation = value;
if (!isLoaded) {
// TODO(ruimiguel): Use loaded.whenComplete once provided.
mounted.whenComplete(_applyElevation);
} else {
_applyElevation();
}
}
void _applyElevation() {
priority = elevation;
reorderChildren();
}
}
/// The [Elevation]s a [BodyComponent] can be in.
///
/// Each [Elevation] is associated with a different board level from ground, to
/// define several z-index heights.
///
/// Usually used with [Elevated].
enum Elevation {
/// The ground level.
board,
/// Level for Jetpack group elements.
jetpack,
/// Level for Spaceship group elements.
spaceship,
/// Level for SpaceshipExitRail.
spaceshipExitRail,
}
/// {@template elevation_order}
/// Specifies the order of each [Elevation].
///
/// Used by [Elevated] to specify what is the priority of [BodyComponent].
/// {@endtemplate}
@visibleForTesting
extension ElevationOrder on Elevation {
/// {@macro elevation_order}
int get order {
switch (this) {
case Elevation.board:
return 1;
case Elevation.jetpack:
return 2;
case Elevation.spaceship:
return 3;
case Elevation.spaceshipExitRail:
return 2;
}
}
}

@ -0,0 +1,32 @@
// TODO(ruimiguel): move file to appropiate location.
import 'dart:math' as math;
import 'package:flame/components.dart';
/// Helper methods to change the [priority] of a [Component].
extension ComponentPriorityX on Component {
static const _lowestPriority = 0;
/// Changes the priority to the lowest possible.
void sendToBack() {
if (priority != _lowestPriority) {
priority = _lowestPriority;
reorderChildren();
}
}
/// Decreases the priority to be lower than another [Component].
void showBehindOf(Component other) {
if (priority >= other.priority) {
priority = math.max(other.priority - 1, _lowestPriority);
reorderChildren();
}
}
/// Increases the priority to be higher than another [Component].
void showInFrontOf(Component other) {
if (priority <= other.priority) {
priority = other.priority + 1;
reorderChildren();
}
}
}

@ -1,4 +1,4 @@
// ignore_for_file: avoid_renaming_method_parameters
// ignore_for_file: avoid_renaming_method_parameters, avoid_function_literals_in_foreach_calls
import 'dart:async';
import 'dart:math';
@ -26,14 +26,28 @@ class Spaceship extends Forge2DBlueprint {
SpaceshipEntranceBallContactCallback(),
]);
addAll([
SpaceshipSaucer()..initialPosition = position,
const ballPriorityWhenOnSpaceship = 3;
final rendersBehindBall = [
SpaceshipEntrance()..initialPosition = position,
SpaceshipSaucer()..initialPosition = position,
]..forEach(
(component) => component.priority = ballPriorityWhenOnSpaceship - 1,
);
final rendersInFrontOfBall = [
SpaceshipBridge()..initialPosition = position,
SpaceshipBridgeTop()..initialPosition = position + Vector2(0, 5.5),
SpaceshipWall()..initialPosition = position,
]..forEach(
(component) => component.priority = ballPriorityWhenOnSpaceship + 1,
);
addAll([
...rendersBehindBall,
...rendersInFrontOfBall,
SpaceshipHole()..initialPosition = position - Vector2(5, 4),
SpaceshipHole()..initialPosition = position - Vector2(-5, 4),
SpaceshipWall()..initialPosition = position,
]);
}
}
@ -41,12 +55,10 @@ class Spaceship extends Forge2DBlueprint {
/// {@template spaceship_saucer}
/// A [BodyComponent] for the base, or the saucer of the spaceship
/// {@endtemplate}
class SpaceshipSaucer extends BodyComponent
with InitialPosition, Layered, Elevated {
class SpaceshipSaucer extends BodyComponent with InitialPosition, Layered {
/// {@macro spaceship_saucer}
SpaceshipSaucer() {
layer = Layer.spaceship;
elevation = Elevation.spaceship.order - 1;
}
@override
@ -97,11 +109,9 @@ class SpaceshipSaucer extends BodyComponent
/// The bridge of the spaceship (the android head) is divided in two
// [BodyComponent]s, this is the top part of it which contains a single sprite
/// {@endtemplate}
class SpaceshipBridgeTop extends BodyComponent with InitialPosition, Elevated {
class SpaceshipBridgeTop extends BodyComponent with InitialPosition {
/// {@macro spaceship_bridge_top}
SpaceshipBridgeTop() {
elevation = Elevation.spaceship.order * 2;
}
SpaceshipBridgeTop();
@override
Future<void> onLoad() async {
@ -134,12 +144,10 @@ class SpaceshipBridgeTop extends BodyComponent with InitialPosition, Elevated {
/// The main part of the [SpaceshipBridge], this [BodyComponent]
/// provides both the collision and the rotation animation for the bridge.
/// {@endtemplate}
class SpaceshipBridge extends BodyComponent
with InitialPosition, Layered, Elevated {
class SpaceshipBridge extends BodyComponent with InitialPosition, Layered {
/// {@macro spaceship_bridge}
SpaceshipBridge() {
layer = Layer.spaceship;
elevation = Elevation.spaceship.order;
}
@override
@ -246,12 +254,10 @@ class SpaceshipHole extends BodyComponent with InitialPosition, Layered {
/// [Ball] to get inside the spaceship saucer.
/// It also contains the [SpriteComponent] for the lower wall
/// {@endtemplate}
class SpaceshipWall extends BodyComponent
with InitialPosition, Layered, Elevated {
class SpaceshipWall extends BodyComponent with InitialPosition, Layered {
/// {@macro spaceship_wall}
SpaceshipWall() : super(priority: 4) {
SpaceshipWall() {
layer = Layer.spaceship;
elevation = Elevation.spaceship.order + 1;
}
@override
@ -311,8 +317,8 @@ class SpaceshipEntranceBallContactCallback
@override
void begin(SpaceshipEntrance entrance, Ball ball, _) {
ball
..elevation = Elevation.spaceship.order
..layer = Layer.spaceship;
..layer = Layer.spaceship
..showInFrontOf(entrance);
}
}
@ -326,7 +332,7 @@ class SpaceshipHoleBallContactCallback
@override
void begin(SpaceshipHole hole, Ball ball, _) {
ball
..elevation = Elevation.board.order
..layer = Layer.board;
..layer = Layer.board
..sendToBack();
}
}

@ -2,10 +2,10 @@
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/components/elevation.dart';
import 'package:pinball/game/components/priority.dart';
import 'package:pinball/game/game.dart';
class TestBodyComponent extends BodyComponent with Elevated {
class TestBodyComponent extends BodyComponent {
@override
Body createBody() {
final fixtureDef = FixtureDef(CircleShape());
@ -16,7 +16,7 @@ class TestBodyComponent extends BodyComponent with Elevated {
void main() {
final flameTester = FlameTester(Forge2DGame.new);
group('Elevated', () {
group('ComponentPriorityX', () {
test('correctly sets and gets', () {
final component = TestBodyComponent()
..elevation = Elevation.spaceship.order;
Loading…
Cancel
Save