Skip to content

Commit

Permalink
Merge pull request #131 from omenking/FSM
Browse files Browse the repository at this point in the history
First iteration FSM. Works exactly as before, with combo glitch fixed…
  • Loading branch information
omenking authored Dec 3, 2017
2 parents d843102 + 008423d commit bbf3dc4
Showing 1 changed file with 153 additions and 107 deletions.
260 changes: 153 additions & 107 deletions app/src/renderer/components/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ module.exports = function(game){

get state() {return this.attr_state }
set state(val) { this.attr_state = val }

get state_timer() { return this.attr_state_timer }
set state_timer(val) { this.attr_state_timer = val }

get chain() {return this.attr_chain }
set chain(val) { this.attr_chain = val }
Expand All @@ -71,7 +74,7 @@ module.exports = function(game){
get right2(){ return _f.out_of_bounds(this.x+2,this.y) ? blank : this.playfield.stack(this.x+2,this.y) }
get under2(){ return _f.out_of_bounds(this.x,this.y+2) ? blank : this.playfield.stack(this.x ,this.y+2)}
get above2(){ return _f.out_of_bounds(this.x,this.y-2) ? blank : this.playfield.stack(this.x ,this.y-2)}

/** */
constructor() {
this.bauble_chain = new ComponentBaubleChain()
Expand Down Expand Up @@ -126,6 +129,133 @@ module.exports = function(game){

/** */
create(playfield, x, y){
/************************************************
* STATE MACHINE
************************************************/
this.state_enter = new Map();
this.state_execute = new Map();
this.state_exit = new Map();

// SWAP_L State
this.state_enter.set(SWAP_L, function(panel){});
this.state_execute.set(SWAP_L, function(panel){ if (panel.counter <= 0) { panel.change_state(SWAPPING_L); }});
this.state_exit.set(SWAP_L, function(panel){});

// SWAP_R State
this.state_enter.set(SWAP_R, function(panel){});
this.state_execute.set(SWAP_R, function(panel){ if (panel.counter <= 0){ panel.change_state(SWAPPING_R); } });
this.state_exit.set(SWAP_R, function(panel){});

// SWAPPING_L State
this.state_enter.set(SWAPPING_L, function(panel){
const i1 = panel.kind;
const i2 = panel.right.kind;
panel.kind = i2;
panel.right.kind = i1;
panel.counter = TIME_SWAP;
});
this.state_execute.set(SWAPPING_L, function(panel){ if (panel.counter <= 0) { panel.state = STATIC; /*TODO: use FSM here*/ }});
this.state_exit.set(SWAPPING_L, function(panel){});

// SWAPPING_R State
this.state_enter.set(SWAPPING_R, function(panel){ panel.counter = TIME_SWAP; });
this.state_execute.set(SWAPPING_R, function(panel){ if (panel.counter <= 0) { panel.state = STATIC; /*TODO: use FSM here*/ }});
this.state_exit.set(SWAPPING_R, function(panel){});

// STATIC state
this.state_enter.set(STATIC, function(panel){});
this.state_execute.set(STATIC, function(panel){
if ((panel.under.empty && !panel.empty) || panel.under.state === HANG) {
panel.change_state(HANG);
} else if (panel.danger && panel.counter === 0) {
// we add 1 otherwise we will miss out on one frame
// since counter can never really hit zero and render
panel.chain = 0
panel.counter = FRAME_DANGER.length+1
} else {
panel.chain = 0
}
});
this.state_exit.set(STATIC, function(panel){});

// HANG State
this.state_enter.set(HANG, function(panel){ panel.counter = 0; });
this.state_execute.set(HANG, function(panel){ if (panel.counter <= 0) { panel.change_state(FALL); }});
this.state_exit.set(HANG, function(panel){});

// FALL State
this.state_enter.set(FALL, function(panel){});
this.state_execute.set(FALL, function(panel){
if (panel.counter > 0) { return }
if (panel.under.empty) {
panel.under.kind = panel.kind
panel.under.state = panel.state
panel.under.counter = panel.counter
panel.under.chain = panel.chain

panel.kind = null
panel.state = STATIC
panel.counter = 0
panel.chain = 0
} else {
panel.change_state(LAND);
}
//} else if (this.under.state === CLEAR) {
//this.state = STATIC
//} else {
//this.state = this.under.state
//this.counter = this.under.counter
//this.chain = this.under.chain
//}
//this.state = LAND
//this.counter = FRAME_LAND.length
});
this.state_exit.set(FALL, function(panel){});

// CLEAR State
this.state_enter.set(CLEAR, function(panel){
panel.chain += 1
panel.playfield.clearing.push(panel)
panel.group = panel.playfield.stage.tick;
});
this.state_execute.set(CLEAR, function(panel){
if (panel.counter > 0) {
const [xi,xlen] = panel.clear_index
panel.clear_i = xi
panel.clear_len = xlen

const time_max = TIME_CLEAR + (TIME_POP*panel.clear_len) + TIME_FALL
panel.time_pop = TIME_CLEAR + (TIME_POP*panel.clear_i)
panel.time_cur = time_max - panel.counter

if (panel.time_cur === panel.time_pop) {
panel.particles.forEach((particle) => {
particle.counter = TIME_PARTICLE;
});

panel.clear_i < 6 ? game.sound.play("sfx_pop" + panel.clear_i) : game.sound.play("sfx_pop5");
}
} else {
if (panel.above && !panel.above.hidden && panel.above.state === STATIC) {
panel.above.chain += 1
}

panel.change_state(STATIC);
}
});
this.state_exit.set(CLEAR, function(panel){
panel.kind = null
panel.counter = 0
panel.chain = 0
panel.group = null
});

// LAND State
this.state_enter.set(LAND, function(panel){ panel.counter = FRAME_LAND.length });
this.state_execute.set(LAND, function(panel){ if (panel.counter <= 0) { panel.change_state(STATIC); } });
this.state_exit.set(LAND, function(panel){});


this.playfield = playfield
this.counter = 0
this.i = null
Expand Down Expand Up @@ -183,7 +313,7 @@ module.exports = function(game){
/** */
get clearable() { return this.swappable && this.under.support && !this.hidden }
/** */
get comboable() { return this.clearable || (this.state === CLEAR && this.playfield.clearing.indexOf(this))}
get comboable() { return this.clearable || (this.state === CLEAR && this.playfield.clearing.indexOf(this) && this.state_timer === 0)}
/** */
get empty() { return this.state === STATIC && this.hidden }
/** */
Expand Down Expand Up @@ -224,14 +354,25 @@ module.exports = function(game){
break;
}
}


/**
* exit old state, enter new state, reset state_timer
*/
change_state(state){
this.state_timer = 0;

this.state_exit.get(this.state)(this);
this.state = state;
this.state_enter.get(this.state)(this);
}

/**
* `update(i)` handles the states and its transition to other states.
* A panel's state will usually change when the panel's `counter`
* reaches zero.
*
*/

update(){
this.particles.forEach(particle => particle.update());

Expand All @@ -240,107 +381,15 @@ module.exports = function(game){
} else {
if (this.newline){ return; }
if (this.counter > 0) { this.counter--}
switch (this.state) {
case SWAP_L:
if (this.counter > 0) { return }
const i1 = this.kind
const i2 = this.right.kind
this.kind = i2
this.right.kind = i1

this.state = SWAPPING_L
this.counter = TIME_SWAP
break
case SWAP_R:
if (this.counter > 0) { return }
this.state = SWAPPING_R
this.counter = TIME_SWAP
break
case SWAPPING_L:
if (this.counter > 0) { return }
this.state = STATIC
break
case SWAPPING_R:
if (this.counter > 0) { return }
this.state = STATIC
break
case STATIC:
if ((this.under.empty && !this.empty) || this.under.state === HANG) {
this.state = HANG
this.counter = 0
} else if (this.danger && this.counter === 0) {
// we add 1 otherwise we will miss out on one frame
// since counter can never really hit zero and render
this.chain = 0
this.counter = FRAME_DANGER.length+1
} else {
this.chain = 0
}
break;
case HANG:
if (this.counter > 0) { return }
this.state = FALL
break;
case FALL:
if (this.counter > 0) { return }
if (this.under.empty) {
this.under.kind = this.kind
this.under.state = this.state
this.under.counter = this.counter
this.under.chain = this.chain

this.kind = null
this.state = STATIC
this.counter = 0
this.chain = 0
} else {
this.state = LAND
this.counter = FRAME_LAND.length
}
//} else if (this.under.state === CLEAR) {
//this.state = STATIC
//} else {
//this.state = this.under.state
//this.counter = this.under.counter
//this.chain = this.under.chain
//}
//this.state = LAND
//this.counter = FRAME_LAND.length
break;
case CLEAR:
if (this.counter > 0) {
const [xi,xlen] = this.clear_index
this.clear_i = xi
this.clear_len = xlen

const time_max = TIME_CLEAR + (TIME_POP*this.clear_len) + TIME_FALL
this.time_pop = TIME_CLEAR + (TIME_POP* this.clear_i)
this.time_cur = time_max - this.counter

if (this.time_cur === this.time_pop) {
this.particles.forEach(particle => particle.counter = TIME_PARTICLE);

this.clear_i < 4 ? game.sounds.pop(this.clear_i) : game.sounds.pop(3);
}
} else {
if (this.above && !this.above.hidden && this.above.state === STATIC) {
this.above.chain += 1
}
this.state = STATIC
this.kind = null
this.counter = 0
this.chain = 0
this.group = null
}
break;
case LAND:
if (this.counter > 0) { return }
this.state = STATIC
break;
default:
throw(new Error('unknown panel state'))
}

this.state_execute.get(this.state)(this);
}

this.particles.forEach((particle) => {
particle.update();
});

++this.state_timer;
}

/**
Expand Down Expand Up @@ -444,10 +493,7 @@ module.exports = function(game){
*/
clear() {
if (this.state === CLEAR) { return }
this.state = CLEAR
this.chain += 1
this.playfield.clearing.push(this)
this.group = this.playfield.stage.tick;
this.change_state(CLEAR);
}
/**
* Checks above and under and then left and right from the current panel.
Expand Down

0 comments on commit bbf3dc4

Please sign in to comment.