Fix several renderer interpolation bugs
This commit is contained in:
parent
69a344595c
commit
0c774d343e
35
js/game.js
35
js/game.js
@ -37,20 +37,18 @@ export class Tile {
|
|||||||
|
|
||||||
// Gives the effective position of an actor in motion, given smooth scrolling
|
// Gives the effective position of an actor in motion, given smooth scrolling
|
||||||
visual_position(tic_offset = 0, interpolate_backwards_by = 0) {
|
visual_position(tic_offset = 0, interpolate_backwards_by = 0) {
|
||||||
let x = this.cell.x;
|
|
||||||
let y = this.cell.y;
|
|
||||||
if (! this.previous_cell || this.movement_speed === null) {
|
if (! this.previous_cell || this.movement_speed === null) {
|
||||||
return [x, y];
|
return [this.cell.x, this.cell.y];
|
||||||
}
|
|
||||||
else {
|
|
||||||
// For a movement speed of N, the cooldown is set to N during the tic an actor starts
|
|
||||||
// moving, and we interpolate it from there to N - 1 over the course of the duration
|
|
||||||
let p = this.movement_progress(tic_offset, interpolate_backwards_by);
|
|
||||||
return [
|
|
||||||
(1 - p) * this.previous_cell.x + p * x,
|
|
||||||
(1 - p) * this.previous_cell.y + p * y,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cell = this.destination_cell ?? this.cell;
|
||||||
|
// For a movement speed of N, the cooldown is set to N during the tic an actor starts
|
||||||
|
// moving, and we interpolate it from there to N - 1 over the course of the duration
|
||||||
|
let p = this.movement_progress(tic_offset, interpolate_backwards_by);
|
||||||
|
return [
|
||||||
|
(1 - p) * this.previous_cell.x + p * cell.x,
|
||||||
|
(1 - p) * this.previous_cell.y + p * cell.y,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO don't love that the arg order is different here vs tile type, but also don't love that
|
// TODO don't love that the arg order is different here vs tile type, but also don't love that
|
||||||
@ -931,6 +929,10 @@ export class Level extends LevelInterface {
|
|||||||
// 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;
|
||||||
|
// This is a renderer prop and only exists between two loops
|
||||||
|
if (actor.destination_cell) {
|
||||||
|
this._set_tile_prop(actor, 'destination_cell', null);
|
||||||
|
}
|
||||||
|
|
||||||
if (! actor.cell)
|
if (! actor.cell)
|
||||||
continue;
|
continue;
|
||||||
@ -1690,6 +1692,10 @@ export class Level extends LevelInterface {
|
|||||||
let teleporter = actor.just_stepped_on_teleporter;
|
let teleporter = actor.just_stepped_on_teleporter;
|
||||||
delete actor.just_stepped_on_teleporter;
|
delete actor.just_stepped_on_teleporter;
|
||||||
|
|
||||||
|
// We're about to abruptly move the actor, and the renderer needs to know to interpolate its
|
||||||
|
// movement towards the teleporter it just stepped on, not the teleporter it's moved to
|
||||||
|
this._set_tile_prop(actor, 'destination_cell', actor.cell);
|
||||||
|
|
||||||
if (teleporter.type.name === 'teleport_red' && ! teleporter.is_active) {
|
if (teleporter.type.name === 'teleport_red' && ! teleporter.is_active) {
|
||||||
// Curious special-case red teleporter behavior: if you pass through a wired but
|
// Curious special-case red teleporter behavior: if you pass through a wired but
|
||||||
// inactive one, you keep sliding indefinitely. Players can override out of it, but
|
// inactive one, you keep sliding indefinitely. Players can override out of it, but
|
||||||
@ -2352,6 +2358,11 @@ export class Level extends LevelInterface {
|
|||||||
this._set_tile_prop(tile, 'previous_cell', null);
|
this._set_tile_prop(tile, 'previous_cell', null);
|
||||||
this._set_tile_prop(tile, 'movement_speed', tile.type.ttl);
|
this._set_tile_prop(tile, 'movement_speed', tile.type.ttl);
|
||||||
this._set_tile_prop(tile, 'movement_cooldown', tile.type.ttl);
|
this._set_tile_prop(tile, 'movement_cooldown', tile.type.ttl);
|
||||||
|
// This is effectively a completely new object, so remove double cooldown prevention;
|
||||||
|
// this cooldown MUST happen, because the renderer can't handle cooldown == speed
|
||||||
|
if (tile.last_extra_cooldown_tic) {
|
||||||
|
this._set_tile_prop(tile, 'last_extra_cooldown_tic', null);
|
||||||
|
}
|
||||||
this._do_extra_cooldown(tile);
|
this._do_extra_cooldown(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2777,36 +2777,38 @@ const TILE_TYPES = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
// New VFX (not in CC2, so they don't block to avoid altering gameplay)
|
// New VFX (not in CC2, so they don't block to avoid altering gameplay)
|
||||||
// TODO would like these to play faster but the first frame is often skipped due to other bugs
|
// Note that these need to NOT have a duration that's an even number of tics, or the last frame
|
||||||
|
// will be skipped when playing at 20fps; the cooldown will be 3, then decremented to 0, and the
|
||||||
|
// tile will immediately be removed!
|
||||||
player1_exit: {
|
player1_exit: {
|
||||||
layer: LAYERS.vfx,
|
layer: LAYERS.vfx,
|
||||||
is_actor: true,
|
is_actor: true,
|
||||||
collision_mask: 0,
|
collision_mask: 0,
|
||||||
ttl: 8 * 3,
|
ttl: 8 * 3 + 1,
|
||||||
},
|
},
|
||||||
player2_exit: {
|
player2_exit: {
|
||||||
layer: LAYERS.vfx,
|
layer: LAYERS.vfx,
|
||||||
is_actor: true,
|
is_actor: true,
|
||||||
collision_mask: 0,
|
collision_mask: 0,
|
||||||
ttl: 8 * 3,
|
ttl: 8 * 3 + 1,
|
||||||
},
|
},
|
||||||
teleport_flash: {
|
teleport_flash: {
|
||||||
layer: LAYERS.vfx,
|
layer: LAYERS.vfx,
|
||||||
is_actor: true,
|
is_actor: true,
|
||||||
collision_mask: 0,
|
collision_mask: 0,
|
||||||
ttl: 8 * 3,
|
ttl: 8 * 3 + 1,
|
||||||
},
|
},
|
||||||
transmogrify_flash: {
|
transmogrify_flash: {
|
||||||
layer: LAYERS.vfx,
|
layer: LAYERS.vfx,
|
||||||
is_actor: true,
|
is_actor: true,
|
||||||
collision_mask: 0,
|
collision_mask: 0,
|
||||||
ttl: 4 * 3,
|
ttl: 4 * 3 + 1,
|
||||||
},
|
},
|
||||||
puff: {
|
puff: {
|
||||||
layer: LAYERS.vfx,
|
layer: LAYERS.vfx,
|
||||||
is_actor: true,
|
is_actor: true,
|
||||||
collision_mask: 0,
|
collision_mask: 0,
|
||||||
ttl: 4 * 3,
|
ttl: 4 * 3 + 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Invalid tiles that appear in some CCL levels because community level
|
// Invalid tiles that appear in some CCL levels because community level
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user