Simplify BaseGame interactions

This commit is contained in:
Lukas Klingsbo
2020-11-14 14:34:39 +01:00
parent 64068ebad9
commit 0135f93493
4 changed files with 27 additions and 28 deletions

View File

@ -12,6 +12,7 @@
- Effects duration and test suite for basic effects - Effects duration and test suite for basic effects
- Pause and resume for effects - Pause and resume for effects
- Fix position bug in parallax effect - Fix position bug in parallax effect
- Simplification of BaseGame. Removal of addLater (add is now addLater) and rename markForRemoval.
## 1.0.0-rc1 ## 1.0.0-rc1
- Move all box2d related code and examples to the flame_box2d repo - Move all box2d related code and examples to the flame_box2d repo

View File

@ -73,12 +73,12 @@ class MyGame extends BaseGame with DoubleTapDetector, TapDetector {
components.forEach((c) { components.forEach((c) {
if (c is PositionComponent && c.toRect().overlaps(touchArea)) { if (c is PositionComponent && c.toRect().overlaps(touchArea)) {
handled = true; handled = true;
markToRemove(c); remove(c);
} }
}); });
if (!handled) { if (!handled) {
addLater(Square() add(Square()
..x = touchArea.left ..x = touchArea.left
..y = touchArea.top); ..y = touchArea.top);
} }

View File

@ -193,7 +193,7 @@ abstract class PositionComponent extends Component {
void addChild(Game gameRef, Component c) { void addChild(Game gameRef, Component c) {
if (gameRef is BaseGame) { if (gameRef is BaseGame) {
gameRef.preAdd(c); gameRef.prepare(c);
} }
_children.add(c); _children.add(c);
} }

View File

@ -16,12 +16,13 @@ import 'game.dart';
/// This is a more complete and opinionated implementation of Game. /// This is a more complete and opinionated implementation of Game.
/// ///
/// It still needs to be subclasses to add your game logic, but the [update], [render] and [resize] methods have default implementations. /// BaseGame should be extended to add your game logic.
/// [update], [render] and [onResize] methods have default implementations.
/// This is the recommended structure to use for most games. /// This is the recommended structure to use for most games.
/// It is based on the Component system. /// It is based on the Component system.
class BaseGame extends Game with FPSCounter { class BaseGame extends Game with FPSCounter {
/// The list of components to be updated and rendered by the base game. /// The list of components to be updated and rendered by the base game.
OrderedSet<Component> components = final OrderedSet<Component> components =
OrderedSet(Comparing.on((c) => c.priority())); OrderedSet(Comparing.on((c) => c.priority()));
/// Components added by the [addLater] method /// Components added by the [addLater] method
@ -31,17 +32,15 @@ class BaseGame extends Game with FPSCounter {
final List<Component> _removeLater = []; final List<Component> _removeLater = [];
/// Current game viewport size, updated every resize via the [resize] method hook /// Current game viewport size, updated every resize via the [resize] method hook
Vector2 size; final Vector2 size = Vector2.zero();
set size(Vector2 size) => this.size.setFrom(size);
/// Camera position; every non-HUD component is translated so that the camera position is the top-left corner of the screen. /// Camera position; every non-HUD component is translated so that the camera position is the top-left corner of the screen.
Vector2 camera = Vector2.zero(); Vector2 camera = Vector2.zero();
/// This method is called for every component added, both via [add] and [addLater] methods. /// Does preparation on a component before any update or render method is called on it
///
/// You can use this to setup your mixins, pre-calculate stuff on every component, or anything you desire.
/// By default, this calls the first time resize for every component, so don't forget to call super.preAdd when overriding.
@mustCallSuper @mustCallSuper
void preAdd(Component c) { void prepare(Component c) {
if (c is Tapable) { if (c is Tapable) {
assert( assert(
this is HasTapableComponents, this is HasTapableComponents,
@ -61,32 +60,30 @@ class BaseGame extends Game with FPSCounter {
if (size != null) { if (size != null) {
c.onGameResize(size); c.onGameResize(size);
} }
c.onMount();
} }
/// Adds a new component to the components list. /// Prepares and registers a component to be added on the next game tick
///
/// Also calls [preAdd], witch in turn sets the current size on the component (because the resize hook won't be called until a new resize happens).
void add(Component c) { void add(Component c) {
preAdd(c); prepare(c);
components.add(c);
}
/// Registers a component to be added on the components on the next tick.
///
/// Use this to add components in places where a concurrent issue with the update method might happen.
/// Also calls [preAdd] for the component added, immediately.
void addLater(Component c) {
preAdd(c);
_addLater.add(c); _addLater.add(c);
} }
/// Prepares and registers a list of components to be added on the next game tick
void addAll(Iterable<Component> components) {
components.forEach(prepare);
_addLater.addAll(components);
}
/// Marks a component to be removed from the components list on the next game loop cycle /// Marks a component to be removed from the components list on the next game loop cycle
void markToRemove(Component c) { void remove(Component c) {
_removeLater.add(c); _removeLater.add(c);
} }
/// Marks a list of components to be removed from the components list on the next game loop cycle
void removeAll(Iterable<Component> components) {
_removeLater.addAll(components);
}
/// This implementation of render basically calls [renderComponent] for every component, making sure the canvas is reset for each one. /// This implementation of render basically calls [renderComponent] for every component, making sure the canvas is reset for each one.
/// ///
/// You can override it further to add more custom behaviour. /// You can override it further to add more custom behaviour.
@ -126,6 +123,7 @@ class BaseGame extends Game with FPSCounter {
_removeLater.clear(); _removeLater.clear();
components.addAll(_addLater); components.addAll(_addLater);
_addLater.forEach((component) => component.onMount());
_addLater.clear(); _addLater.clear();
components.forEach((c) => c.update(t)); components.forEach((c) => c.update(t));
@ -139,7 +137,7 @@ class BaseGame extends Game with FPSCounter {
@override @override
@mustCallSuper @mustCallSuper
void onResize(Vector2 size) { void onResize(Vector2 size) {
this.size = size; this.size.setFrom(size);
components.forEach((c) => c.onGameResize(size)); components.forEach((c) => c.onGameResize(size));
} }