Skip to content

Commit

Permalink
Use FSM on Cheese
Browse files Browse the repository at this point in the history
  • Loading branch information
5u4 committed Jan 5, 2021
1 parent 5e2da8c commit 975eba9
Showing 1 changed file with 110 additions and 122 deletions.
232 changes: 110 additions & 122 deletions source/enemies/Cheese.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,23 @@ package enemies;
import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.addons.util.FlxFSM;
import flixel.math.FlxMath;
import flixel.math.FlxPoint;
import flixel.math.FlxVector;
import flixel.system.FlxSound;
import flixel.util.FlxTimer;
import modules.Entity;
import modules.brains.statemachine.State;
import modules.brains.statemachine.StateMachine;

class Cheese extends Enemy
{
var target:Entity;
var brain = new StateMachine();
var margin = 240.0;
var flyTo:FlxPoint = new FlxPoint();
var getBullet:() -> FlxSprite;
var attackPattern = Math.random();
var aimCooldown = 0.3;
var _aimCooldown = 0.0;
var fireCooldown = 0.8;
var _fireCooldown = 0.0;
var charged = false;
var shootSound:FlxSound;
public var tick = 0.5;
public var target:Entity;
public var getBullet:() -> FlxSprite;
public var flyTo:FlxPoint = new FlxPoint();
public var shootSound:FlxSound;
public var attackPattern = Math.random();

var fsm:FlxFSM<Cheese>;

public function new(target:Entity, getBullet:() -> FlxSprite)
{
Expand All @@ -35,13 +29,17 @@ class Cheese extends Enemy
this.getBullet = getBullet;
grav.grav = 0.0;

brain.states.push(MakeChangeLocationState());
brain.states.push(MakeChargeState());
brain.states.push(MakeFireState());
brain.states.push(MakeAimState());

shootSound = FlxG.sound.load(#if html5 AssetPaths.cheese_shoot__mp3 #else AssetPaths.cheese_shoot__wav #end);
shootSound.volume = Reg.sfxVolume;

fsm = new FlxFSM<Cheese>(this);
fsm.transitions.add(Idle, Charge, c -> c.tick <= 0)
.add(Charge, FireAround, c -> c.tick <= 0 && attackPattern > 0.5)
.add(Charge, FireAim, c -> c.tick <= 0 && attackPattern <= 0.5)
.add(FireAround, ChangeLocation, c -> c.tick <= 0)
.add(FireAim, ChangeLocation, c -> c.tick <= 0)
.add(ChangeLocation, Idle, c -> new FlxVector(c.x, c.y).distanceTo(c.flyTo) < 30)
.start(Idle);
}

override function render()
Expand All @@ -53,29 +51,72 @@ class Cheese extends Enemy
animation.add("idle", [0, 1, 2], 6, true);
animation.add("charge", [3, 4, 5], 3, false);
animation.add("attack", [6, 7], 6, true);
animation.finishCallback = (name:String) ->
{
if (name == "charge")
charged = true;
}
}

override function update(elapsed:Float)
{
brain.update(elapsed);
tick -= elapsed;
fsm.update(elapsed);
super.update(elapsed);
}

function fireCircular(amount:Int)
override function destroy()
{
fsm.destroy();
fsm = null;
super.destroy();
}
}

class Idle extends FlxFSMState<Cheese>
{
override function enter(owner:Cheese, fsm:FlxFSM<Cheese>)
{
owner.tick = 0.5;
owner.animation.play("idle");
}
}

class Charge extends FlxFSMState<Cheese>
{
override function enter(owner:Cheese, fsm:FlxFSM<Cheese>)
{
owner.tick = 0.5;
owner.attackPattern = Math.random();
owner.animation.play("charge");
}
}

class FireAround extends FlxFSMState<Cheese>
{
var cd = 0.8;
var _cd = 0.0;

override function enter(owner:Cheese, fsm:FlxFSM<Cheese>)
{
var center = getMidpoint();
var targetCenter = target.getMidpoint();
owner.tick = 3;
owner.animation.play("attack");
}

override function update(elapsed:Float, owner:Cheese, fsm:FlxFSM<Cheese>)
{
_cd -= elapsed;
if (_cd > 0)
return;
fire(owner, 10);
_cd = cd;
}

function fire(owner:Cheese, amount:Int)
{
var center = owner.getMidpoint();
var targetCenter = owner.target.getMidpoint();
var v = new FlxVector(targetCenter.x - center.x, targetCenter.y - center.y).normalize();
var speed = 100.0;
var deg = 360.0 / amount;
for (_ in 0...amount)
{
var bullet = getBullet();
var bullet = owner.getBullet();
if (bullet == null)
return;
bullet.reset(center.x - bullet.width / 2, center.y - bullet.height / 2);
Expand All @@ -85,116 +126,63 @@ class Cheese extends Enemy
bullet.angle = v.angleBetween(new FlxVector()) + 90;
v.rotateByDegrees(deg);
}
shootSound.play(true);
owner.shootSound.play(true);
}
}

function fireDirectly()
class FireAim extends FlxFSMState<Cheese>
{
var cd = 0.3;
var _cd = 0.0;

override function enter(owner:Cheese, fsm:FlxFSM<Cheese>)
{
var bullet = getBullet();
if (bullet == null)
owner.tick = 3;
owner.animation.play("attack");
}

override function update(elapsed:Float, owner:Cheese, fsm:FlxFSM<Cheese>)
{
_cd -= elapsed;
if (_cd > 0)
return;
fire(owner);
_cd = cd;
}

var center = getMidpoint();
var targetCenter = target.getMidpoint();
function fire(owner:Cheese)
{
var bullet = owner.getBullet();
if (bullet == null)
return;
var center = owner.getMidpoint();
var targetCenter = owner.target.getMidpoint();
var v = new FlxVector(targetCenter.x - center.x, targetCenter.y + 75 - center.y).normalize();
var speed = 400.0;

bullet.reset(center.x - bullet.width / 2, center.y - bullet.height / 2);
bullet.velocity.x = speed * v.x;
bullet.velocity.y = speed * v.y;
bullet.animation.play("fire", true);
bullet.angle = v.angleBetween(new FlxVector()) + 90;
shootSound.play(true);
}

function MakeChangeLocationState()
{
var state = new State();
var timer = new FlxTimer();
timer.start(3.0);
state.shouldEnable = () -> timer.finished;
state.enable = () ->
{
animation.play("idle");
flyTo.x = x > FlxG.width / 2 ? margin : FlxG.width - margin - width;
flyTo.y = Math.random() * 480.0 + 64.0;
};
state.handle = elapsed ->
{
x = FlxMath.lerp(x, flyTo.x, elapsed * 0.7);
y = FlxMath.lerp(y, flyTo.y, elapsed * 0.7);
facing = x < FlxG.width / 2 ? FlxObject.RIGHT : FlxObject.LEFT;
};
state.shouldDisable = () -> new FlxVector(x, y).distanceTo(flyTo) < 30;
state.disable = () ->
{
attackPattern = Math.random();
timer.start(3.0);
}
return state;
owner.shootSound.play(true);
}
}

function MakeChargeState()
{
var state = new State();
var timer = new FlxTimer();
timer.start(0);
state.shouldEnable = () -> timer.finished && !charged;
state.enable = () ->
{
animation.play("charge");
timer.start(1);
}
return state;
}
class ChangeLocation extends FlxFSMState<Cheese>
{
var margin = 240.0;

function MakeFireState()
override function enter(owner:Cheese, fsm:FlxFSM<Cheese>)
{
var state = new State();
var timer = new FlxTimer();
timer.start(0);
state.shouldEnable = () -> charged && attackPattern >= 0.5;
state.enable = () ->
{
animation.play("attack");
timer.start(3);
}
state.handle = elapsed ->
{
_fireCooldown -= elapsed;
if (_fireCooldown > 0)
return;
fireCircular(10);
_fireCooldown = fireCooldown;
}
state.shouldDisable = () -> timer.finished;
state.disable = () -> charged = false;

return state;
owner.animation.play("idle");
owner.flyTo.x = owner.x > FlxG.width / 2 ? margin : FlxG.width - margin - owner.width;
owner.flyTo.y = Math.random() * 480.0 + 64.0;
}

function MakeAimState()
override function update(elapsed:Float, owner:Cheese, fsm:FlxFSM<Cheese>)
{
var state = new State();
var timer = new FlxTimer();
timer.start(0);
state.shouldEnable = () -> charged && attackPattern < 0.5;
state.enable = () ->
{
animation.play("attack");
timer.start(3);
}
state.handle = elapsed ->
{
_aimCooldown -= elapsed;
if (_aimCooldown > 0)
return;
fireDirectly();
_aimCooldown = aimCooldown;
}
state.shouldDisable = () -> timer.finished;
state.disable = () -> charged = false;

return state;
owner.x = FlxMath.lerp(owner.x, owner.flyTo.x, elapsed * 0.7);
owner.y = FlxMath.lerp(owner.y, owner.flyTo.y, elapsed * 0.7);
owner.facing = owner.x < FlxG.width / 2 ? FlxObject.RIGHT : FlxObject.LEFT;
}
}

0 comments on commit 975eba9

Please sign in to comment.