Skip to content

Commit

Permalink
feat: adding character base class (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtome authored Nov 29, 2023
1 parent a8a27b4 commit 802a735
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 34 deletions.
2 changes: 1 addition & 1 deletion examples/standard_platformer/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class ExamplePlatformerLeapGame extends LeapGame
);

player = Player();
world.add(player = Player());
world.add(player!);
camera.follow(player!);

if (!FlameAudio.bgm.isPlaying) {
Expand Down
6 changes: 3 additions & 3 deletions examples/standard_platformer/lib/player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:leap_standard_platformer/info_text.dart';
import 'package:leap_standard_platformer/main.dart';

class Player extends JumperCharacter<ExamplePlatformerLeapGame> {
Player({super.health = initialHealth}) {
Player({super.health = initialHealth}) : super(removeOnDeath: false) {
solidTags.add(CommonTags.ground);
}

Expand Down Expand Up @@ -113,7 +113,7 @@ class Player extends JumperCharacter<ExamplePlatformerLeapGame> {
}

final ladderCollision =
collisionInfo.allCollisions?.whereType<Ladder>().firstOrNull;
collisionInfo.allCollisions.whereType<Ladder>().firstOrNull;
final onLadderStatus = getStatus<OnLadderStatus>();
if (_input.justPressed &&
_input.isPressedCenter &&
Expand Down Expand Up @@ -240,7 +240,7 @@ class Player extends JumperCharacter<ExamplePlatformerLeapGame> {
velocity.y = -minJumpImpulse;
}

for (final other in collisionInfo.allCollisions ?? const []) {
for (final other in collisionInfo.allCollisions) {
if (other is Coin) {
other.removeFromParent();
coins++;
Expand Down
2 changes: 1 addition & 1 deletion examples/standard_platformer/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ packages:
path: "../../packages/leap"
relative: true
source: path
version: "0.3.1"
version: "0.4.0"
material_color_utilities:
dependency: transitive
description:
Expand Down
5 changes: 3 additions & 2 deletions packages/leap/lib/src/characters/jumper_character.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:flame/components.dart';
import 'package:leap/src/characters/jumper_behavior.dart';
import 'package:leap/src/entities/entities.dart';
import 'package:leap/src/entities/character.dart';
import 'package:leap/src/leap_game.dart';

class JumperCharacter<TGame extends LeapGame> extends PhysicalEntity<TGame> {
class JumperCharacter<TGame extends LeapGame> extends Character<TGame> {
JumperCharacter({
super.health = 10,
super.removeOnDeath,
}) : super(behaviors: [JumperBehavior()]);

/// When true the character is facing left, otherwise right.
Expand Down
61 changes: 61 additions & 0 deletions packages/leap/lib/src/entities/character.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:flutter/foundation.dart';
import 'package:leap/leap.dart';

/// A type of [PhysicalEntity] which is typically used as the base class
/// for players, enemies, etc.
/// Characters have health, and usually a removed on death.
///
// TODO(kurtome): add sprite animation and state helpers.
class Character<T extends LeapGame> extends PhysicalEntity<T> {
Character({
this.health = 1,
this.removeOnDeath = true,
super.static,
super.behaviors,
super.priority,
super.position,
super.size,
}) : super() {
_wasAlive = isAlive;
}

/// The health of this character, when positive this is "alive".
int health;

/// Indicates if this should [remove] itself on death.
bool removeOnDeath;

/// Whether or not this is "alive" (or not destroyed) in the game
bool get isAlive => health > 0;

/// Whether or not this is "dead" (or destroyed) in the game.
bool get isDead => !isAlive;

bool _wasAlive = true;

/// Indicates that this was alive on the previous [update] loop
bool get wasAlive => _wasAlive;

/// Called when this entity dies, typically due to health dropping below one.
///
/// This will be invoked after this has been marked for removal
/// (if [removeOnDeath] is true) but before [onRemove].
/// Entities can be removed without dying.
@mustCallSuper
void onDeath() {}

@override
@mustCallSuper
void update(double dt) {
super.update(dt);

if (isDead && wasAlive) {
if (removeOnDeath) {
removeFromParent();
}
onDeath();
}

_wasAlive = isAlive;
}
}
3 changes: 1 addition & 2 deletions packages/leap/lib/src/entities/ladder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ class OnLadderStatus<T extends LeapGame> extends StatusComponent

final parentEntity = parent! as PhysicalEntity;

if (!(parentEntity.collisionInfo.allCollisions?.contains(ladder) ??
false)) {
if (!parentEntity.collisionInfo.allCollisions.contains(ladder)) {
// No longer on the ladder
removeFromParent();
parentEntity.velocity.y = 0;
Expand Down
11 changes: 0 additions & 11 deletions packages/leap/lib/src/entities/physical_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ abstract class PhysicalEntity<TGame extends LeapGame> extends PositionedEntity
/// Multiplier on standard gravity, see [LeapWorld].
double gravityRate = 1;

/// When health reaches 0, [isDead] will be true.
/// This needs to be used by child classes to have any effect.
int health;

PhysicalEntity({
this.health = 10,
this.static = false,
Iterable<Behavior<PhysicalEntity>>? behaviors,
super.priority,
Expand Down Expand Up @@ -121,12 +116,6 @@ abstract class PhysicalEntity<TGame extends LeapGame> extends PositionedEntity
/// Tile size (width and height) in pixels
double get tileSize => game.tileSize;

/// Whether or not this is "alive" (or not destroyed) in the game
bool get isAlive => health > 0;

/// Whether or not this is "dead" (or destroyed) in the game.
bool get isDead => !isAlive;

/// Leftmost point.
double get left {
return x;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class CollisionDetectionBehavior extends PhysicalBehavior {
!collisionInfo.onSlope) {
// Moving down.
_calculateSolidHits((c) {
return c.bottom >= bottom &&
return c.bottom > bottom &&
c.isSolidFromTop &&
// For one-way platforms from underneath, make sure this is
// currently above it so this doesn't pop up on top of it
Expand Down Expand Up @@ -292,7 +292,7 @@ class CollisionDetectionBehavior extends PhysicalBehavior {

_proxyHitboxForPotentialHits(dt);
for (final other in world.physicals) {
if (intersectsOther(_hitboxProxy, other)) {
if (!other.isRemoving && intersectsOther(_hitboxProxy, other)) {
_potentialHits.add(other);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class CollisionInfo {

set upCollision(PhysicalEntity? c) {
if (_upCollision != null) {
allCollisions?.remove(c);
_allCollisions?.remove(c);
}
if (c != null) {
addCollision(c);
Expand All @@ -45,7 +45,7 @@ class CollisionInfo {

set downCollision(PhysicalEntity? c) {
if (_downCollision != null) {
allCollisions?.remove(c);
_allCollisions?.remove(c);
}
if (c != null) {
addCollision(c);
Expand All @@ -58,7 +58,7 @@ class CollisionInfo {

set leftCollision(PhysicalEntity? c) {
if (_leftCollision != null) {
allCollisions?.remove(c);
_allCollisions?.remove(c);
}
if (c != null) {
addCollision(c);
Expand All @@ -71,7 +71,7 @@ class CollisionInfo {

set rightCollision(PhysicalEntity? c) {
if (_rightCollision != null) {
allCollisions?.remove(c);
_allCollisions?.remove(c);
}
if (c != null) {
addCollision(c);
Expand All @@ -80,11 +80,13 @@ class CollisionInfo {
}

/// Non-solid collisions.
List<PhysicalEntity>? allCollisions;
List<PhysicalEntity>? _allCollisions;

List<PhysicalEntity> get allCollisions => _allCollisions ?? const [];

void addCollision(PhysicalEntity collision) {
allCollisions ??= [];
allCollisions!.add(collision);
_allCollisions ??= [];
_allCollisions!.add(collision);
}

/// Is currently colliding on top
Expand Down Expand Up @@ -115,7 +117,8 @@ class CollisionInfo {
downCollision = null;
leftCollision = null;
rightCollision = null;
allCollisions = null;

_allCollisions = null;
}

void copyFrom(CollisionInfo other) {
Expand All @@ -124,10 +127,10 @@ class CollisionInfo {
_leftCollision = other.leftCollision;
_rightCollision = other.rightCollision;

allCollisions?.clear();
if (other.allCollisions != null) {
allCollisions ??= [];
allCollisions!.addAll(other.allCollisions!);
_allCollisions?.clear();
if (other.allCollisions.isNotEmpty) {
_allCollisions ??= [];
_allCollisions!.addAll(other.allCollisions);
}
}
}

0 comments on commit 802a735

Please sign in to comment.