Line data Source code
1 : import 'dart:ui'; 2 : 3 : import 'package:flutter/painting.dart'; 4 : import 'package:meta/meta.dart'; 5 : 6 : import '../extensions/vector2.dart'; 7 : 8 : /// This represents a Component for your game. 9 : /// 10 : /// Components can be bullets flying on the screen, a spaceship or your player's fighter. 11 : /// Anything that either renders or updates can be added to the list on BaseGame. It will deal with calling those methods for you. 12 : /// Components also have other methods that can help you out if you want to override them. 13 : abstract class Component { 14 : /// Whether this component is HUD object or not. 15 : /// 16 : /// HUD objects ignore the BaseGame.camera when rendered (so their position coordinates are considered relative to the device screen). 17 : bool isHud = false; 18 : 19 : bool _isMounted = false; 20 : 21 : /// Whether this component is currently mounted on a game or not 22 4 : bool get isMounted => _isMounted; 23 : 24 : /// If the component has a parent it will be set here 25 : Component? _parent; 26 : 27 0 : Component? get parent => _parent; 28 : 29 : /// Render priority of this component. This allows you to control the order in which your components are rendered. 30 : /// 31 : /// Components are always updated and rendered in the order defined by what this number is when the component is added to the game. 32 : /// The smaller the priority, the sooner your component will be updated/rendered. 33 : /// It can be any integer (negative, zero, or positive). 34 : /// If two components share the same priority, they will probably be drawn in the order they were added. 35 40 : int get priority => _priority; 36 : int _priority; 37 : 38 : /// Whether this component should be removed or not. 39 : /// 40 : /// It will be checked once per component per tick, and if it is true, BaseGame will remove it. 41 : bool shouldRemove = false; 42 : 43 28 : Component({int? priority}) : _priority = priority ?? 0; 44 : 45 : /// This method is called periodically by the game engine to request that your component updates itself. 46 : /// 47 : /// The time [dt] in seconds (with microseconds precision provided by Flutter) since the last update cycle. 48 : /// This time can vary according to hardware capacity, so make sure to update your state considering this. 49 : /// All components on BaseGame are always updated by the same amount. The time each one takes to update adds up to the next update cycle. 50 0 : void update(double dt) {} 51 : 52 : /// Renders this component on the provided Canvas [c]. 53 0 : void render(Canvas c) {} 54 : 55 : /// This is used to render this component and potential children on subclasses 56 : /// of [Component] on the provided Canvas [c]. 57 0 : void renderTree(Canvas c) => render(c); 58 : 59 : /// It receives the new game size. 60 : /// Executed right after the component is attached to a game and right before [onMount] is called 61 23 : void onGameResize(Vector2 gameSize) {} 62 : 63 : /// Remove the component from the game it is added to in the next tick 64 4 : void remove() => shouldRemove = true; 65 : 66 : /// Called when the component has been added and prepared by the game instance. 67 : /// 68 : /// This can be used to make initializations on your component as, when this method is called, 69 : /// things like [onGameResize] are already set and usable. 70 20 : @mustCallSuper 71 : void onMount() { 72 20 : _isMounted = true; 73 : } 74 : 75 : /// Called right before the component is removed from the game 76 5 : @mustCallSuper 77 : void onRemove() { 78 5 : _isMounted = false; 79 : } 80 : 81 : /// Called before the component is added to the BaseGame by the add method. 82 : /// Whenever this returns something, BaseGame will wait for the [Future] to be resolved before adding the component on the list. 83 : /// If `null` is returned, the component is added right away. 84 : /// 85 : /// Has a default implementation which just returns null. 86 : /// 87 : /// This can be overwritten this to add custom logic to the component loading. 88 : /// 89 : /// Example: 90 : /// ```dart 91 : /// @override 92 : /// Future<void> onLoad() async { 93 : /// myImage = await gameRef.load('my_image.png'); 94 : /// } 95 : /// ``` 96 24 : Future<void>? onLoad() => null; 97 : 98 : /// Usually this is not something that the user would want to call since the 99 : /// component list isn't re-ordered when it is called. 100 : /// See BaseGame.changePriority instead. 101 2 : void changePriorityWithoutResorting(int priority) => _priority = priority; 102 : }