spaceify
This commit is contained in:
parent
e9d542f438
commit
be5cc7f97f
146
js/game.js
146
js/game.js
@ -329,12 +329,12 @@ export class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player_awaiting_input() {
|
player_awaiting_input() {
|
||||||
return this.player.movement_cooldown === 0 && (this.player.slide_mode === null || (this.player.slide_mode === 'force' && this.player.last_move_was_force))
|
return this.player.movement_cooldown === 0 && (this.player.slide_mode === null || (this.player.slide_mode === 'force' && this.player.last_move_was_force))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the game state forwards by one tic
|
// Move the game state forwards by one tic
|
||||||
// split into two parts for turn-based mode: first part is the consequences of the previous tick, second part depends on the player's input
|
// split into two parts for turn-based mode: first part is the consequences of the previous tick, second part depends on the player's input
|
||||||
advance_tic(p1_primary_direction, p1_secondary_direction, pass) {
|
advance_tic(p1_primary_direction, p1_secondary_direction, pass) {
|
||||||
if (this.state !== 'playing') {
|
if (this.state !== 'playing') {
|
||||||
console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
||||||
@ -342,18 +342,18 @@ export class Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
this._advance_tic_part1(p1_primary_direction, p1_secondary_direction);
|
this._advance_tic_part1(p1_primary_direction, p1_secondary_direction);
|
||||||
}
|
}
|
||||||
else if (pass == 2)
|
else if (pass == 2)
|
||||||
{
|
{
|
||||||
this._advance_tic_part2(p1_primary_direction, p1_secondary_direction);
|
this._advance_tic_part2(p1_primary_direction, p1_secondary_direction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
console.warn(`What pass is this?`);
|
console.warn(`What pass is this?`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (e instanceof GameEnded) {
|
if (e instanceof GameEnded) {
|
||||||
@ -388,68 +388,68 @@ export class Level {
|
|||||||
// arrival as its own mini pass, for one reason: if the player dies (which will end the game
|
// arrival as its own mini pass, for one reason: if the player dies (which will end the game
|
||||||
// immediately), we still want every time's animation to finish, or it'll look like some
|
// immediately), we still want every time's animation to finish, or it'll look like some
|
||||||
// objects move backwards when the death screen appears!
|
// objects move backwards when the death screen appears!
|
||||||
let cell_steppers = [];
|
let cell_steppers = [];
|
||||||
for (let actor of this.actors) {
|
for (let actor of this.actors) {
|
||||||
// Actors with no cell were destroyed
|
// Actors with no cell were destroyed
|
||||||
if (! actor.cell)
|
if (! actor.cell)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Clear any old decisions ASAP. Note that this prop is only used internally within a
|
// Clear any old decisions ASAP. Note that this prop is only used internally within a
|
||||||
// single tic, so it doesn't need to be undoable
|
// single tic, so it doesn't need to be undoable
|
||||||
actor.decision = null;
|
actor.decision = null;
|
||||||
|
|
||||||
// Decrement the cooldown here, but don't check it quite yet,
|
// Decrement the cooldown here, but don't check it quite yet,
|
||||||
// because stepping on cells in the next block might reset it
|
// because stepping on cells in the next block might reset it
|
||||||
if (actor.movement_cooldown > 0) {
|
if (actor.movement_cooldown > 0) {
|
||||||
this._set_prop(actor, 'movement_cooldown', actor.movement_cooldown - 1);
|
this._set_prop(actor, 'movement_cooldown', actor.movement_cooldown - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.animation_speed) {
|
if (actor.animation_speed) {
|
||||||
// Deal with movement animation
|
// Deal with movement animation
|
||||||
this._set_prop(actor, 'animation_progress', actor.animation_progress + 1);
|
this._set_prop(actor, 'animation_progress', actor.animation_progress + 1);
|
||||||
if (actor.animation_progress >= actor.animation_speed) {
|
if (actor.animation_progress >= actor.animation_speed) {
|
||||||
if (actor.type.ttl) {
|
if (actor.type.ttl) {
|
||||||
// This is purely an animation so it disappears once it's played
|
// This is purely an animation so it disappears once it's played
|
||||||
this.remove_tile(actor);
|
this.remove_tile(actor);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this._set_prop(actor, 'previous_cell', null);
|
this._set_prop(actor, 'previous_cell', null);
|
||||||
this._set_prop(actor, 'animation_progress', null);
|
this._set_prop(actor, 'animation_progress', null);
|
||||||
this._set_prop(actor, 'animation_speed', null);
|
this._set_prop(actor, 'animation_speed', null);
|
||||||
if (! this.compat.tiles_react_instantly) {
|
if (! this.compat.tiles_react_instantly) {
|
||||||
// We need to track the actor AND the cell explicitly, because it's possible
|
// We need to track the actor AND the cell explicitly, because it's possible
|
||||||
// that one actor's step will cause another actor to start another move, and
|
// that one actor's step will cause another actor to start another move, and
|
||||||
// then they'd end up stepping on the new cell they're moving to instead of
|
// then they'd end up stepping on the new cell they're moving to instead of
|
||||||
// the one they just landed on!
|
// the one they just landed on!
|
||||||
cell_steppers.push([actor, actor.cell]);
|
cell_steppers.push([actor, actor.cell]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let [actor, cell] of cell_steppers) {
|
for (let [actor, cell] of cell_steppers) {
|
||||||
this.step_on_cell(actor, cell);
|
this.step_on_cell(actor, cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only reset the player's is_pushing between movement, so it lasts for the whole push
|
// Only reset the player's is_pushing between movement, so it lasts for the whole push
|
||||||
if (this.player.movement_cooldown <= 0) {
|
if (this.player.movement_cooldown <= 0) {
|
||||||
this.player.is_pushing = false;
|
this.player.is_pushing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass: actors decide their upcoming movement simultaneously
|
// Second pass: actors decide their upcoming movement simultaneously
|
||||||
// (we'll do the player's decision in part 2!)
|
// (we'll do the player's decision in part 2!)
|
||||||
for (let actor of this.actors) {
|
for (let actor of this.actors) {
|
||||||
if (actor != this.player)
|
if (actor != this.player)
|
||||||
{
|
{
|
||||||
this.actor_decision(actor, p1_primary_direction);
|
this.actor_decision(actor, p1_primary_direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_advance_tic_part2(p1_primary_direction, p1_secondary_direction) {
|
_advance_tic_part2(p1_primary_direction, p1_secondary_direction) {
|
||||||
//player now makes a decision based on input
|
//player now makes a decision based on input
|
||||||
this.actor_decision(this.player, p1_primary_direction);
|
this.actor_decision(this.player, p1_primary_direction);
|
||||||
|
|
||||||
// Third pass: everyone actually moves
|
// Third pass: everyone actually moves
|
||||||
for (let actor of this.actors) {
|
for (let actor of this.actors) {
|
||||||
if (! actor.cell)
|
if (! actor.cell)
|
||||||
|
|||||||
104
js/main.js
104
js/main.js
@ -428,7 +428,7 @@ class Player extends PrimaryView {
|
|||||||
while (this.level.undo_stack.length > 0 &&
|
while (this.level.undo_stack.length > 0 &&
|
||||||
! (moved && this.level.player.slide_mode === null))
|
! (moved && this.level.player.slide_mode === null))
|
||||||
{
|
{
|
||||||
this.undo();
|
this.undo();
|
||||||
if (player_cell !== this.level.player.cell) {
|
if (player_cell !== this.level.player.cell) {
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
@ -509,7 +509,7 @@ class Player extends PrimaryView {
|
|||||||
this.previous_input = new Set; // actions that were held last tic
|
this.previous_input = new Set; // actions that were held last tic
|
||||||
this.previous_action = null; // last direction we were moving, if any
|
this.previous_action = null; // last direction we were moving, if any
|
||||||
this.current_keys = new Set; // keys that are currently held
|
this.current_keys = new Set; // keys that are currently held
|
||||||
this.current_keys_new = new Set; //for keys that have only been held a frame
|
this.current_keys_new = new Set; //for keys that have only been held a frame
|
||||||
// TODO this could all probably be more rigorous but it's fine for now
|
// TODO this could all probably be more rigorous but it's fine for now
|
||||||
key_target.addEventListener('keydown', ev => {
|
key_target.addEventListener('keydown', ev => {
|
||||||
if (ev.key === 'p' || ev.key === 'Pause') {
|
if (ev.key === 'p' || ev.key === 'Pause') {
|
||||||
@ -550,7 +550,7 @@ class Player extends PrimaryView {
|
|||||||
|
|
||||||
if (this.key_mapping[ev.key]) {
|
if (this.key_mapping[ev.key]) {
|
||||||
this.current_keys.add(ev.key);
|
this.current_keys.add(ev.key);
|
||||||
this.current_keys_new.add(ev.key);
|
this.current_keys_new.add(ev.key);
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
@ -656,7 +656,7 @@ class Player extends PrimaryView {
|
|||||||
_clear_state() {
|
_clear_state() {
|
||||||
this.set_state('waiting');
|
this.set_state('waiting');
|
||||||
|
|
||||||
this.waiting_for_input = false;
|
this.waiting_for_input = false;
|
||||||
this.tic_offset = 0;
|
this.tic_offset = 0;
|
||||||
this.last_advance = 0;
|
this.last_advance = 0;
|
||||||
this.demo_faucet = null;
|
this.demo_faucet = null;
|
||||||
@ -701,15 +701,15 @@ class Player extends PrimaryView {
|
|||||||
for (let key of this.current_keys) {
|
for (let key of this.current_keys) {
|
||||||
input.add(this.key_mapping[key]);
|
input.add(this.key_mapping[key]);
|
||||||
}
|
}
|
||||||
for (let key of this.current_keys_new) {
|
for (let key of this.current_keys_new) {
|
||||||
input.add(this.key_mapping[key]);
|
input.add(this.key_mapping[key]);
|
||||||
}
|
}
|
||||||
this.current_keys_new = new Set;
|
this.current_keys_new = new Set;
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waiting_for_input = false;
|
waiting_for_input = false;
|
||||||
|
|
||||||
advance_by(tics) {
|
advance_by(tics) {
|
||||||
for (let i = 0; i < tics; i++) {
|
for (let i = 0; i < tics; i++) {
|
||||||
@ -773,43 +773,43 @@ class Player extends PrimaryView {
|
|||||||
this.previous_input = input;
|
this.previous_input = input;
|
||||||
|
|
||||||
this.sfx_player.advance_tic();
|
this.sfx_player.advance_tic();
|
||||||
|
|
||||||
var primary_dir = this.primary_action ? ACTION_DIRECTIONS[this.primary_action] : null;
|
var primary_dir = this.primary_action ? ACTION_DIRECTIONS[this.primary_action] : null;
|
||||||
var secondary_dir = this.secondary_action ? ACTION_DIRECTIONS[this.secondary_action] : null;
|
var secondary_dir = this.secondary_action ? ACTION_DIRECTIONS[this.secondary_action] : null;
|
||||||
|
|
||||||
//turn based logic
|
//turn based logic
|
||||||
//first, handle a part 2 we just got input for
|
//first, handle a part 2 we just got input for
|
||||||
if (this.waiting_for_input)
|
if (this.waiting_for_input)
|
||||||
{
|
{
|
||||||
if (!this.turn_based || primary_dir != null || input.has('wait'))
|
if (!this.turn_based || primary_dir != null || input.has('wait'))
|
||||||
{
|
{
|
||||||
this.waiting_for_input = false;
|
this.waiting_for_input = false;
|
||||||
this.level.advance_tic(
|
this.level.advance_tic(
|
||||||
primary_dir,
|
primary_dir,
|
||||||
secondary_dir,
|
secondary_dir,
|
||||||
2);
|
2);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //TODO: or `if (!this.waiting_for_input)` to be snappier
|
else //TODO: or `if (!this.waiting_for_input)` to be snappier
|
||||||
{
|
{
|
||||||
this.level.advance_tic(
|
this.level.advance_tic(
|
||||||
primary_dir,
|
primary_dir,
|
||||||
secondary_dir,
|
secondary_dir,
|
||||||
1);
|
1);
|
||||||
//then if we should wait for input, the player needs input and we don't have input, we set waiting_for_input, else we run part 2
|
//then if we should wait for input, the player needs input and we don't have input, we set waiting_for_input, else we run part 2
|
||||||
if (this.turn_based && this.level.player_awaiting_input() && !(primary_dir != null || input.has('wait')))
|
if (this.turn_based && this.level.player_awaiting_input() && !(primary_dir != null || input.has('wait')))
|
||||||
{
|
{
|
||||||
this.waiting_for_input = true;
|
this.waiting_for_input = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.level.advance_tic(
|
this.level.advance_tic(
|
||||||
primary_dir,
|
primary_dir,
|
||||||
secondary_dir,
|
secondary_dir,
|
||||||
2);
|
2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.level.state !== 'playing') {
|
if (this.level.state !== 'playing') {
|
||||||
// We either won or lost!
|
// We either won or lost!
|
||||||
@ -843,7 +843,7 @@ class Player extends PrimaryView {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Rewind by undoing one tic every tic
|
// Rewind by undoing one tic every tic
|
||||||
this.undo();
|
this.undo();
|
||||||
this.update_ui();
|
this.update_ui();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,11 +862,11 @@ class Player extends PrimaryView {
|
|||||||
this._advance_handle = window.setTimeout(this._advance_bound, dt);
|
this._advance_handle = window.setTimeout(this._advance_bound, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
undo() {
|
undo() {
|
||||||
//if we were waiting for input and undo, well, now we're not
|
//if we were waiting for input and undo, well, now we're not
|
||||||
this.waiting_for_input = false;
|
this.waiting_for_input = false;
|
||||||
this.level.undo();
|
this.level.undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redraws every frame, unless the game isn't running
|
// Redraws every frame, unless the game isn't running
|
||||||
redraw() {
|
redraw() {
|
||||||
@ -901,7 +901,7 @@ class Player extends PrimaryView {
|
|||||||
|
|
||||||
// Actually redraw. Used to force drawing outside of normal play
|
// Actually redraw. Used to force drawing outside of normal play
|
||||||
_redraw() {
|
_redraw() {
|
||||||
this.renderer.waiting_for_input = this.waiting_for_input;
|
this.renderer.waiting_for_input = this.waiting_for_input;
|
||||||
this.renderer.draw(this.tic_offset);
|
this.renderer.draw(this.tic_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,8 +51,8 @@ export class CanvasRenderer {
|
|||||||
sx * tw, sy * th, w * tw, h * th,
|
sx * tw, sy * th, w * tw, h * th,
|
||||||
dx * tw, dy * th, w * tw, h * th);
|
dx * tw, dy * th, w * tw, h * th);
|
||||||
}
|
}
|
||||||
|
|
||||||
waiting_for_input = false;
|
waiting_for_input = false;
|
||||||
|
|
||||||
draw(tic_offset = 0) {
|
draw(tic_offset = 0) {
|
||||||
if (! this.level) {
|
if (! this.level) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user