diff --git a/Features/FlxFSM/source/PlayState.hx b/Features/FlxFSM/source/PlayState.hx index 4a3e2e746..f802ddce5 100644 --- a/Features/FlxFSM/source/PlayState.hx +++ b/Features/FlxFSM/source/PlayState.hx @@ -5,17 +5,24 @@ import flixel.FlxSprite; import flixel.FlxState; import flixel.text.FlxText; import flixel.tile.FlxTilemap; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; import flixel.util.FlxColor; using StringTools; class PlayState extends FlxState { + static inline var BASE_INFO:String = "LEFT & RIGHT to move, UP to jump"; + static inline var GROUND_POUND_INFO:String = "DOWN (in the air) to ground-pound"; + static inline var RESET_INFO:String = "R to Reset\n\nCurrent State: {STATE}"; + var _map:FlxTilemap; var _slime:Slime; - var _powerup:FlxSprite; + var _superJump:FlxSprite; + var _groundPound:FlxSprite; - var _info:String = "LEFT & RIGHT to move, UP to jump\nDOWN (in the air) " + "to ground-pound.\nR to Reset\n\nCurrent State: {STATE}"; + var _info:String = BASE_INFO + "\n" + RESET_INFO; var _txtInfo:FlxText; override public function create():Void @@ -23,8 +30,10 @@ class PlayState extends FlxState bgColor = 0xff661166; super.create(); - _map = new FlxTilemap(); - _map.loadMapFromArray([ + final J = 99; + final G = 100; + final columns = 20; + final data = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, @@ -35,19 +44,35 @@ class PlayState extends FlxState 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 0, 0, J, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - ], 20, 15, "assets/tiles.png", 16, 16); + ]; + + // remove powerups from map, store index so we can place them + final superJumpIndex = data.indexOf(J); + data[superJumpIndex] = 0; + + final groundPoundIndex = data.indexOf(G); + data[groundPoundIndex] = 0; + + final tileSize = 16; + _map = new FlxTilemap(); + _map.loadMapFromArray(data, 20, 15, "assets/tiles.png", tileSize, tileSize); add(_map); _slime = new Slime(192, 128); add(_slime); - _powerup = new FlxSprite(48, 208, "assets/powerup.png"); - add(_powerup); + _superJump = new FlxSprite((superJumpIndex % columns) * tileSize, Std.int(superJumpIndex / columns) * tileSize, "assets/powerup.png"); + add(_superJump); + + _groundPound = new FlxSprite((groundPoundIndex % columns) * tileSize, Std.int(groundPoundIndex / columns) * tileSize, "assets/powerup.png"); + _groundPound.flipY = true; + _groundPound.y += 4; + add(_groundPound); _txtInfo = new FlxText(16, 16, -1, _info); add(_txtInfo); @@ -58,7 +83,19 @@ class PlayState extends FlxState super.update(elapsed); FlxG.collide(_map, _slime); - FlxG.overlap(_slime, _powerup, getPowerup); + + FlxG.overlap(_slime, _superJump, function (_, _) + { + _slime.addSuperJump(); + _superJump.kill(); + }); + + FlxG.overlap(_slime, _groundPound, function (_, _) + { + _slime.addGroundPound(); + _groundPound.kill(); + startGroundPoundInfoTween(); + }); _txtInfo.text = _info.replace("{STATE}", Type.getClassName(_slime.fsm.stateClass)); @@ -67,12 +104,27 @@ class PlayState extends FlxState FlxG.camera.flash(FlxColor.BLACK, .1, FlxG.resetState); } } - - function getPowerup(slime:Slime, particle:FlxSprite):Void + + function startGroundPoundInfoTween() { - slime.fsm.transitions.replace(Slime.Jump, Slime.SuperJump); - slime.fsm.transitions.add(Slime.Jump, Slime.Idle, Slime.Conditions.grounded); - - particle.kill(); + final duration = 2.0; + final flash_period = 0.15 / duration; + final oldColor = _txtInfo.color; + final ease = FlxEase.linear; + FlxTween.num(0, 1, duration, + { + onComplete:function (_) + { + _txtInfo.color = oldColor; + _info = BASE_INFO + "\n" + GROUND_POUND_INFO + "\n" + RESET_INFO; + } + }, + function(n) + { + _txtInfo.color = ((n / flash_period) % 1 > 0.5) ? FlxColor.YELLOW : oldColor; + final chars = Std.int(ease(n) * GROUND_POUND_INFO.length); + _info = BASE_INFO + "\n" + GROUND_POUND_INFO.substr(0, chars) + "\n" + RESET_INFO; + } + ); } } diff --git a/Features/FlxFSM/source/Slime.hx b/Features/FlxFSM/source/Slime.hx index 8d35a22d2..062f811c2 100644 --- a/Features/FlxFSM/source/Slime.hx +++ b/Features/FlxFSM/source/Slime.hx @@ -8,7 +8,7 @@ class Slime extends FlxSprite { public static inline var GRAVITY:Float = 600; - public var fsm:FlxFSM; + public var fsm:FlxFSM; public function new(X:Float = 0, Y:Float = 0) { @@ -28,22 +28,41 @@ class Slime extends FlxSprite acceleration.y = GRAVITY; maxVelocity.set(100, GRAVITY); - fsm = new FlxFSM(this); - fsm.transitions.add(Idle, Jump, Conditions.jump) - .add(Jump, Idle, Conditions.grounded) - .add(Jump, GroundPound, Conditions.groundSlam) - .add(GroundPound, GroundPoundFinish, Conditions.grounded) - .add(GroundPoundFinish, Idle, Conditions.animationFinished) - .start(Idle); + fsm = new FlxFSM(this); + fsm.transitions.add(Idle, Jump, Conditions.jump); + fsm.transitions.add(Jump, Idle, Conditions.grounded); + fsm.transitions.start(Idle); + } + + public function addSuperJump() + { + // remove regular jump now + fsm.transitions.remove(Idle, Jump, Conditions.jump, true); + fsm.transitions.add(Idle, SuperJump, Conditions.jump); + // replace the rest when it's safe + fsm.transitions.replace(Jump, SuperJump, false); + } + + public function addGroundPound() + { + fsm.transitions.add(GroundPound, GroundPoundFinish, Conditions.grounded); + fsm.transitions.add(GroundPoundFinish, Idle, Conditions.animationFinished); + + if (fsm.transitions.hasTransition(Idle, Jump)) + fsm.transitions.add(Jump, GroundPound, Conditions.groundSlam); + + if (fsm.transitions.hasTransition(Idle, SuperJump)) + fsm.transitions.add(SuperJump, GroundPound, Conditions.groundSlam); + } - override public function update(elapsed:Float):Void + override function update(elapsed:Float):Void { fsm.update(elapsed); super.update(elapsed); } - override public function destroy():Void + override function destroy():Void { fsm.destroy(); fsm = null; @@ -74,14 +93,14 @@ class Conditions } } -class Idle extends FlxFSMState +class Idle extends FlxFSMState { - override public function enter(owner:FlxSprite, fsm:FlxFSM):Void + override function enter(owner:Slime, fsm:FlxFSM):Void { owner.animation.play("standing"); } - override public function update(elapsed:Float, owner:FlxSprite, fsm:FlxFSM):Void + override function update(elapsed:Float, owner:Slime, fsm:FlxFSM):Void { owner.acceleration.x = 0; if (FlxG.keys.pressed.LEFT || FlxG.keys.pressed.RIGHT) @@ -98,15 +117,15 @@ class Idle extends FlxFSMState } } -class Jump extends FlxFSMState +class Jump extends FlxFSMState { - override public function enter(owner:FlxSprite, fsm:FlxFSM):Void + override function enter(owner:Slime, fsm:FlxFSM):Void { owner.animation.play("jumping"); owner.velocity.y = -200; } - override public function update(elapsed:Float, owner:FlxSprite, fsm:FlxFSM):Void + override function update(elapsed:Float, owner:Slime, fsm:FlxFSM):Void { owner.acceleration.x = 0; if (FlxG.keys.pressed.LEFT || FlxG.keys.pressed.RIGHT) @@ -118,29 +137,29 @@ class Jump extends FlxFSMState class SuperJump extends Jump { - override public function enter(owner:FlxSprite, fsm:FlxFSM):Void + override function enter(owner:Slime, fsm:FlxFSM):Void { owner.animation.play("jumping"); owner.velocity.y = -300; } } -class GroundPound extends FlxFSMState +class GroundPound extends FlxFSMState { - var _ticks:Float; + var time:Float; - override public function enter(owner:FlxSprite, fsm:FlxFSM):Void + override function enter(owner:Slime, fsm:FlxFSM):Void { owner.animation.play("pound"); owner.velocity.x = 0; owner.acceleration.x = 0; - _ticks = 0; + time = 0; } - override public function update(elapsed:Float, owner:FlxSprite, fsm:FlxFSM):Void + override function update(elapsed:Float, owner:Slime, fsm:FlxFSM):Void { - _ticks++; - if (_ticks < 15) + time += elapsed; + if (time < 0.25) { owner.velocity.y = 0; } @@ -151,9 +170,9 @@ class GroundPound extends FlxFSMState } } -class GroundPoundFinish extends FlxFSMState +class GroundPoundFinish extends FlxFSMState { - override public function enter(owner:FlxSprite, fsm:FlxFSM):Void + override function enter(owner:Slime, fsm:FlxFSM):Void { owner.animation.play("landing"); FlxG.camera.shake(0.025, 0.25);