Switch JavaScript engine to goja

* Switch from otto to goja for JavaScript engine.
* goja supports many ES6 syntax features like arrow functions,
  const/let, for-of with more coming soon.
* Same great features as otto, more modern environment for doodads!
master
Noah 2022-01-16 20:09:27 -08:00
parent ca9ad6e3a8
commit c1a87e03e6
29 changed files with 188 additions and 295 deletions

View File

@ -1,43 +0,0 @@
// Azulian (Red)
// DEPRECATED: they both share azulian.js now.
function main() {
var playerSpeed = 4;
var gravity = 4;
var Vx = Vy = 0;
var direction = "right";
Self.SetHitbox(0, 0, 32, 32)
Self.SetMobile(true);
Self.SetInventory(true);
Self.SetGravity(true);
Self.AddAnimation("walk-left", 100, ["red-wl1", "red-wl2", "red-wl3", "red-wl4"]);
Self.AddAnimation("walk-right", 100, ["red-wr1", "red-wr2", "red-wr3", "red-wr4"]);
// Sample our X position every few frames and detect if we've hit a solid wall.
var sampleTick = 0;
var sampleRate = 5;
var lastSampledX = 0;
setInterval(function () {
if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X;
var delta = Math.abs(curX - lastSampledX);
if (delta < 5) {
direction = direction === "right" ? "left" : "right";
}
lastSampledX = curX;
}
sampleTick++;
// TODO: Vector() requires floats, pain in the butt for JS,
// the JS API should be friendlier and custom...
var Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1));
Self.SetVelocity(Vector(Vx, 0.0));
if (!Self.IsAnimating()) {
Self.PlayAnimation("walk-" + direction, null);
}
}, 100);
}

View File

@ -5,7 +5,7 @@ var playerSpeed = 12,
lastDirection = "right";
function setupAnimations(color) {
var left = color === 'blue' ? 'blu-wl' : 'red-wl',
let left = color === 'blue' ? 'blu-wl' : 'red-wl',
right = color === 'blue' ? 'blu-wr' : 'red-wr',
leftFrames = [left + '1', left + '2', left + '3', left + '4'],
rightFrames = [right + '1', right + '2', right + '3', right + '4'];
@ -15,7 +15,7 @@ function setupAnimations(color) {
}
function main() {
var color = Self.GetTag("color");
const color = Self.GetTag("color");
playerSpeed = color === 'blue' ? 2 : 4;
Self.SetMobile(true);
@ -32,14 +32,14 @@ function main() {
// when it meets resistance.
// Sample our X position every few frames and detect if we've hit a solid wall.
var sampleTick = 0;
var sampleRate = 5;
var lastSampledX = 0;
let sampleTick = 0;
let sampleRate = 5;
let lastSampledX = 0;
setInterval(function () {
setInterval(() => {
if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X;
var delta = Math.abs(curX - lastSampledX);
let curX = Self.Position().X;
let delta = Math.abs(curX - lastSampledX);
if (delta < 5) {
direction = direction === "right" ? "left" : "right";
}
@ -47,7 +47,7 @@ function main() {
}
sampleTick++;
var Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1));
let Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1));
Self.SetVelocity(Vector(Vx, 0.0));
// If we changed directions, stop animating now so we can
@ -66,7 +66,7 @@ function main() {
function playerControls() {
// Note: player speed is controlled by the engine.
Events.OnKeypress(function (ev) {
Events.OnKeypress((ev) => {
if (ev.Right) {
if (!Self.IsAnimating()) {
Self.PlayAnimation("walk-right", null);

View File

@ -1,17 +1,17 @@
// Bird
function main() {
var speed = 4;
var Vx = Vy = 0;
var altitude = Self.Position().Y; // original height in the level
let speed = 4,
Vx = Vy = 0,
altitude = Self.Position().Y; // original height in the level
var direction = "left",
let direction = "left",
lastDirection = "left";
var states = {
let states = {
flying: 0,
diving: 1,
};
var state = states.flying;
let state = states.flying;
Self.SetMobile(true);
Self.SetGravity(false);
@ -24,22 +24,22 @@ function main() {
return player();
}
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) {
return false;
}
});
// Sample our X position every few frames and detect if we've hit a solid wall.
var sampleTick = 0;
var sampleRate = 2;
var lastSampledX = 0;
var lastSampledY = 0;
let sampleTick = 0,
sampleRate = 2,
lastSampledX = 0,
lastSampledY = 0;
setInterval(function () {
setInterval(() => {
if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X;
var delta = Math.abs(curX - lastSampledX);
let curX = Self.Position().X;
let delta = Math.abs(curX - lastSampledX);
if (delta < 5) {
direction = direction === "right" ? "left" : "right";
}
@ -48,15 +48,15 @@ function main() {
sampleTick++;
// If we are not flying at our original altitude, correct for that.
var curV = Self.Position();
var Vy = 0.0;
let curV = Self.Position();
let Vy = 0.0;
if (curV.Y != altitude) {
Vy = curV.Y < altitude ? 1 : -1;
}
// TODO: Vector() requires floats, pain in the butt for JS,
// the JS API should be friendlier and custom...
var Vx = parseFloat(speed * (direction === "left" ? -1 : 1));
let Vx = parseFloat(speed * (direction === "left" ? -1 : 1));
Self.SetVelocity(Vector(Vx, Vy));
// If we changed directions, stop animating now so we can
@ -76,7 +76,7 @@ function main() {
// If under control of the player character.
function player() {
Self.SetInventory(true);
Events.OnKeypress(function (ev) {
Events.OnKeypress((ev) => {
Vx = 0;
Vy = 0;
@ -103,4 +103,4 @@ function player() {
Self.SetVelocity(Vector(Vx, Vy));
})
}
}

View File

@ -1,20 +1,21 @@
// Pushable Box.
var speed = 4;
var size = 75;
const speed = 4,
size = 75;
function main() {
Self.SetMobile(true);
Self.SetGravity(true);
Self.SetHitbox(0, 0, size, size);
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
// Ignore events from neighboring Boxes.
if (e.Actor.Actor.Filename === "box.doodad") {
return false;
}
if (e.Actor.IsMobile() && e.InHitbox) {
var overlap = e.Overlap;
let overlap = e.Overlap;
if (overlap.Y === 0 && !(overlap.X === 0 && overlap.W < 5) && !(overlap.X === size)) {
// Standing on top, ignore.
@ -39,8 +40,8 @@ function main() {
});
// When we receive power, we reset to our original position.
var origPoint = Self.Position();
Message.Subscribe("power", function (powered) {
let origPoint = Self.Position();
Message.Subscribe("power", (powered) => {
Self.MoveTo(origPoint);
Self.SetVelocity(Vector(0, 0));
});
@ -52,8 +53,8 @@ function main() {
function animate() {
Self.AddAnimation("animate", 100, [0, 1, 2, 3, 2, 1]);
var running = false;
setInterval(function () {
let running = false;
setInterval(() => {
if (!running) {
running = true;
Self.PlayAnimation("animate", function () {
@ -61,4 +62,4 @@ function animate() {
})
}
}, 100);
}
}

View File

@ -1,10 +1,10 @@
const playerSpeed = 12;
let Vx = Vy = 0,
animating = false,
animStart = animEnd = 0;
function main() {
var playerSpeed = 12;
var Vx = Vy = 0;
var animating = false;
var animStart = animEnd = 0;
Self.SetMobile(true);
Self.SetInventory(true);
Self.SetGravity(true);
@ -13,13 +13,13 @@ function main() {
Self.AddAnimation("walk-right", 200, ["stand-right", "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]);
// If the player suddenly changes direction, reset the animation state to quickly switch over.
var lastVelocity = Vector(0, 0);
let lastVelocity = Vector(0, 0);
Events.OnKeypress(function (ev) {
Events.OnKeypress((ev) => {
Vx = 0;
Vy = 0;
var curVelocity = Self.GetVelocity();
let curVelocity = Self.GetVelocity();
if ((lastVelocity.X < 0 && curVelocity.X > 0) ||
(lastVelocity.X > 0 && curVelocity.X < 0)) {
Self.StopAnimation();
@ -40,7 +40,5 @@ function main() {
Self.StopAnimation();
animating = false;
}
// Self.SetVelocity(Point(Vx, Vy));
})
}

View File

@ -1,18 +1,18 @@
function main() {
var timer = 0;
var pressed = false;
let timer = 0;
let pressed = false;
// Has a linked Sticky Button been pressed permanently down?
var stickyDown = false;
Message.Subscribe("sticky:down", function (down) {
let stickyDown = false;
Message.Subscribe("sticky:down", (down) => {
stickyDown = down;
Self.ShowLayer(stickyDown ? 1 : 0);
});
// Track who all is colliding with us.
var colliders = {};
let colliders = {};
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}
@ -46,7 +46,7 @@ function main() {
Self.ShowLayer(1);
});
Events.OnLeave(function (e) {
Events.OnLeave((e) => {
delete colliders[e.Actor.ID()];
if (Object.keys(colliders).length === 0 && !stickyDown) {

View File

@ -1,8 +1,8 @@
function main() {
var pressed = false;
let pressed = false;
// When a sticky button receives power, it pops back up.
Message.Subscribe("power", function (powered) {
Message.Subscribe("power", (powered) => {
if (powered && pressed) {
Self.ShowLayer(0);
pressed = false;
@ -12,7 +12,7 @@ function main() {
}
})
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}

View File

@ -6,19 +6,16 @@ function main() {
Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]);
// Recover time for the floor to respawn.
var recover = 5000;
let recover = 5000;
// States of the floor.
var stateSolid = 0;
var stateShaking = 1;
var stateFalling = 2;
var stateFallen = 3;
var state = stateSolid;
let stateSolid = 0;
let stateShaking = 1;
let stateFalling = 2;
let stateFallen = 3;
let state = stateSolid;
// Started the animation?
var startedAnimation = false;
Events.OnCollide(function(e) {
Events.OnCollide((e) => {
// If the floor is falling, the player passes right thru.
if (state === stateFalling || state === stateFallen) {
@ -40,15 +37,15 @@ function main() {
// Begin the animation sequence if we're in the solid state.
if (state === stateSolid) {
state = stateShaking;
Self.PlayAnimation("shake", function() {
Self.PlayAnimation("shake", () => {
state = stateFalling;
Self.PlayAnimation("fall", function() {
Self.PlayAnimation("fall", () => {
Sound.Play("crumbly-break.wav")
state = stateFallen;
Self.ShowLayerNamed("fallen");
// Recover after a while.
setTimeout(function() {
setTimeout(() => {
Self.ShowLayer(0);
state = stateSolid;
}, recover);

View File

@ -1,9 +1,11 @@
function main() {
var color = Self.GetTag("color");
var keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad";
// Colored Locked Doors.
const color = Self.GetTag("color"),
keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad";
function main() {
// Layers in the doodad image.
var layer = {
let layer = {
closed: 0,
unlocked: 1,
right: 2,
@ -11,13 +13,13 @@ function main() {
};
// Variables that change in event handler.
var unlocked = false; // Key has been used to unlock the door (one time).
var opened = false; // If door is currently showing its opened state.
var enterSide = 0; // Side of player entering the door, -1 or 1, left or right.
let unlocked = false; // Key has been used to unlock the door (one time).
let opened = false; // If door is currently showing its opened state.
let enterSide = 0; // Side of player entering the door, -1 or 1, left or right.
Self.SetHitbox(34, 0, 13, 76);
Events.OnCollide(function(e) {
Events.OnCollide((e) => {
// Record the side that this actor has touched us, in case the door
// needs to open.
if (enterSide === 0) {
@ -37,7 +39,7 @@ function main() {
}
// Do they have our key?
var hasKey = e.Actor.HasItem(keyname) >= 0;
let hasKey = e.Actor.HasItem(keyname) >= 0;
if (!hasKey) {
// Door is locked.
return false;
@ -55,7 +57,7 @@ function main() {
}
}
});
Events.OnLeave(function(e) {
Events.OnLeave((e) => {
Self.ShowLayer(unlocked ? layer.unlocked : layer.closed);
// Sound.Play("door-close.wav")

View File

@ -1,6 +1,8 @@
var animating = false;
var opened = false;
var powerState = false;
// Electric Door
let animating = false;
let opened = false;
let powerState = false;
// Function to handle the door opening or closing.
function setPoweredState(powered) {
@ -13,14 +15,14 @@ function setPoweredState(powered) {
animating = true;
Sound.Play("electric-door.wav")
Self.PlayAnimation("open", function () {
Self.PlayAnimation("open", () => {
opened = true;
animating = false;
});
} else {
animating = true;
Sound.Play("electric-door.wav")
Self.PlayAnimation("close", function () {
Self.PlayAnimation("close", () => {
opened = false;
animating = false;
})
@ -31,7 +33,6 @@ function main() {
Self.AddAnimation("open", 100, [0, 1, 2, 3]);
Self.AddAnimation("close", 100, [3, 2, 1, 0]);
Self.SetHitbox(0, 0, 34, 76);
// A linked Switch that activates the door will send the Toggle signal
@ -39,13 +40,13 @@ function main() {
// state on this signal, and ignore the very next Power signal. Ordinary
// power sources like Buttons will work as normal, as they emit only a power
// signal.
var ignoreNextPower = false;
Message.Subscribe("switch:toggle", function (powered) {
let ignoreNextPower = false;
Message.Subscribe("switch:toggle", (powered) => {
ignoreNextPower = true;
setPoweredState(!powerState);
})
Message.Subscribe("power", function (powered) {
Message.Subscribe("power", (powered) => {
if (ignoreNextPower) {
ignoreNextPower = false;
return;
@ -54,7 +55,7 @@ function main() {
setPoweredState(powered);
});
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (e.InHitbox) {
if (!opened) {
return false;

View File

@ -1,8 +1,10 @@
function main() {
var color = Self.GetTag("color");
var quantity = color === "small" ? 1 : 0;
// Colored Keys and Small Key
Events.OnCollide(function (e) {
const color = Self.GetTag("color"),
quantity = color === "small" ? 1 : 0;
function main() {
Events.OnCollide((e) => {
if (e.Settled) {
if (e.Actor.HasInventory()) {
// If we don't have a quantity, and the actor already has

View File

@ -1,27 +0,0 @@
// DEPRECATED: old locked door script. Superceded by colored-door.js.
function main() {
Self.AddAnimation("open", 0, [1]);
var unlocked = false;
var color = Self.GetTag("color");
Self.SetHitbox(16, 0, 32, 64);
Events.OnCollide(function(e) {
if (unlocked) {
return;
}
if (e.InHitbox) {
var data = e.Actor.GetData("key:" + color);
if (data === "") {
// Door is locked.
return false;
}
if (e.Settled) {
unlocked = true;
Self.PlayAnimation("open", null);
}
}
});
}

View File

@ -8,9 +8,9 @@ function main() {
Self.SetGravity(true);
// Monitor our Y position to tell if we've been falling.
var lastPoint = Self.Position();
setInterval(function () {
var nowAt = Self.Position();
let lastPoint = Self.Position();
setInterval(() => {
let nowAt = Self.Position();
if (nowAt.Y > lastPoint.Y) {
falling = true;
} else {
@ -19,7 +19,7 @@ function main() {
lastPoint = nowAt;
}, 100);
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}
@ -43,8 +43,8 @@ function main() {
});
// When we receive power, we reset to our original position.
var origPoint = Self.Position();
Message.Subscribe("power", function (powered) {
let origPoint = Self.Position();
Message.Subscribe("power", (powered) => {
Self.MoveTo(origPoint);
Self.SetVelocity(Vector(0, 0));
});

View File

@ -7,11 +7,11 @@ function main() {
// Checkpoints broadcast to all of their peers so they all
// know which one is the most recently activated.
Message.Subscribe("broadcast:checkpoint", function (currentID) {
Message.Subscribe("broadcast:checkpoint", (currentID) => {
setActive(false);
});
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}
@ -35,4 +35,4 @@ function setActive(v) {
isCurrentCheckpoint = v;
Self.ShowLayerNamed(v ? "checkpoint-active" : "checkpoint-inactive");
}
}

View File

@ -2,7 +2,7 @@
function main() {
Self.SetHitbox(22 + 16, 16, 75 - 16, 86);
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}

View File

@ -4,8 +4,7 @@ function main() {
// Linking a doodad to the Start Flag sets the
// player character. Destroy the original doodads.
var links = Self.GetLinks();
for (var i = 0; i < links.length; i++) {
links[i].Destroy();
for (var link of Self.GetLinks()) {
link.Destroy();
}
}

View File

@ -3,9 +3,9 @@ function main() {
Self.SetHitbox(0, 0, 42, 42);
// Blue block is ON by default.
var state = true;
let state = true;
Message.Subscribe("broadcast:state-change", function(newState) {
Message.Subscribe("broadcast:state-change", (newState) => {
state = !newState;
// Layer 0: ON
@ -13,7 +13,7 @@ function main() {
Self.ShowLayer(state ? 0 : 1);
});
Events.OnCollide(function(e) {
Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) {
if (state) {
return false;

View File

@ -3,9 +3,9 @@ function main() {
Self.SetHitbox(0, 0, 42, 42);
// Orange block is OFF by default.
var state = false;
let state = false;
Message.Subscribe("broadcast:state-change", function(newState) {
Message.Subscribe("broadcast:state-change", (newState) => {
state = newState;
// Layer 0: OFF
@ -13,7 +13,7 @@ function main() {
Self.ShowLayer(state ? 1 : 0);
});
Events.OnCollide(function(e) {
Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) {
if (state) {
return false;

View File

@ -1,23 +1,23 @@
// State Block Control Button
// Button is "OFF" by default.
var state = false;
let state = false;
function main() {
Self.SetHitbox(0, 0, 42, 42);
// When the button is activated, don't keep toggling state until we're not
// being touched again.
var colliding = false;
let colliding = false;
// If we receive a state change event from a DIFFERENT on/off button, update
// ourself to match the state received.
Message.Subscribe("broadcast:state-change", function(value) {
Message.Subscribe("broadcast:state-change", (value) => {
state = value;
showSprite();
});
Events.OnCollide(function(e) {
Events.OnCollide((e) => {
if (colliding) {
return false;
}
@ -40,7 +40,7 @@ function main() {
return false;
});
Events.OnLeave(function(e) {
Events.OnLeave((e) => {
colliding = false;
})
}

View File

@ -8,11 +8,11 @@ function main() {
// Checkpoints broadcast to all of their peers so they all
// know which one is the most recently activated.
Message.Subscribe("broadcast:checkpoint", function (currentID) {
Message.Subscribe("broadcast:checkpoint", (currentID) => {
setActive(false);
});
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (isCurrentCheckpoint || !e.Settled) {
return;
}
@ -35,4 +35,4 @@ function setActive(v) {
}
isCurrentCheckpoint = v;
}
}

View File

@ -2,7 +2,7 @@
function main() {
Self.Hide();
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}

View File

@ -2,7 +2,7 @@
function main() {
Self.Hide();
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled) {
return;
}

View File

@ -15,7 +15,7 @@ function main() {
);
}
Message.Subscribe("broadcast:ready", function () {
Message.Subscribe("broadcast:ready", () => {
Message.Publish("switch:toggle", true);
Message.Publish("power", true);
});

View File

@ -4,7 +4,7 @@
function main() {
Self.Hide();
var active = true,
let active = true,
timeout = 250,
ms = Self.GetTag("ms");
@ -12,7 +12,7 @@ function main() {
timeout = parseInt(ms);
}
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!active || !e.Settled) {
return;
}
@ -25,7 +25,7 @@ function main() {
if (e.InHitbox) {
// Grab hold of the player.
e.Actor.Freeze();
setTimeout(function () {
setTimeout(() => {
e.Actor.Unfreeze();
}, timeout);
@ -34,7 +34,7 @@ function main() {
});
// Reset the trap if powered by a button.
Message.Subscribe("power", function (powered) {
Message.Subscribe("power", (powered) => {
active = true;
});
}

View File

@ -4,15 +4,15 @@ function main() {
// 0: Off
// 1: On
var state = false;
var collide = false;
let state = false;
let collide = false;
Message.Subscribe("power", function (powered) {
Message.Subscribe("power", (powered) => {
state = powered;
showState(state);
});
Events.OnCollide(function (e) {
Events.OnCollide((e) => {
if (!e.Settled || !e.Actor.IsMobile()) {
return;
}
@ -21,7 +21,6 @@ function main() {
Sound.Play("button-down.wav")
state = !state;
var nonce = Math.random() * 2147483647;
Message.Publish("switch:toggle", state);
Message.Publish("power", state);
showState(state);
@ -30,7 +29,7 @@ function main() {
}
});
Events.OnLeave(function (e) {
Events.OnLeave((e) => {
collide = false;
});
}

View File

@ -21,8 +21,8 @@ function main() {
// Common "steal" power between playable and A.I. thieves.
function stealable() {
// Steals your items.
Events.OnCollide(function (e) {
var victim = e.Actor;
Events.OnCollide((e) => {
let victim = e.Actor;
if (!e.Settled) {
return;
}
@ -33,17 +33,17 @@ function stealable() {
}
// Steal inventory
var stolen = 0;
let stolen = 0;
if (victim.HasInventory()) {
var myInventory = Self.Inventory(),
let myInventory = Self.Inventory(),
theirInventory = victim.Inventory();
for (var key in theirInventory) {
for (let key in theirInventory) {
if (!theirInventory.hasOwnProperty(key)) {
continue;
}
var value = theirInventory[key];
let value = theirInventory[key];
if (value > 0 || myInventory[key] === undefined) {
victim.RemoveItem(key, value);
Self.AddItem(key, value);
@ -68,7 +68,7 @@ function stealable() {
// when it encounters and obstacle.
function ai() {
// Walks back and forth.
var Vx = Vy = 0.0,
let Vx = Vy = 0.0,
playerSpeed = 4,
direction = "right",
lastDirection = "right",
@ -76,9 +76,9 @@ function ai() {
sampleTick = 0,
sampleRate = 2;
setInterval(function () {
setInterval(() => {
if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X,
let curX = Self.Position().X,
delta = Math.abs(curX - lastSampledX);
if (delta < 5) {
direction = direction === "right" ? "left" : "right";
@ -106,7 +106,7 @@ function ai() {
// If under control of the player character.
function playable() {
Events.OnKeypress(function (ev) {
Events.OnKeypress((ev) => {
Vx = 0;
Vy = 0;
@ -127,4 +127,4 @@ function playable() {
// Self.SetVelocity(Point(Vx, Vy));
})
}
}

View File

@ -1,36 +0,0 @@
function main() {
var timer = 0;
Self.SetHitbox(0, 0, 72, 6);
var animationSpeed = 100;
var opened = false;
Self.AddAnimation("open", animationSpeed, ["down1", "down2", "down3", "down4"]);
Self.AddAnimation("close", animationSpeed, ["down4", "down3", "down2", "down1"]);
Events.OnCollide( function(e) {
if (opened) {
return;
}
// Is the actor colliding our solid part?
if (e.InHitbox) {
// Touching the top or the bottom?
if (e.Overlap.Y > 0) {
return false; // solid wall when touched from below
} else {
opened = true;
Self.PlayAnimation("open", function() {
});
}
}
});
Events.OnLeave(function() {
if (opened) {
Self.PlayAnimation("close", function() {
opened = false;
});
}
})
}

View File

@ -1,12 +1,12 @@
// Trapdoors.
// What direction is the trapdoor facing?
const direction = Self.GetTag("direction");
function main() {
// What direction is the trapdoor facing?
var direction = Self.GetTag("direction");
var timer = 0;
// Set our hitbox based on our orientation.
var thickness = 10;
var doodadSize = 86;
let thickness = 10;
let doodadSize = 86;
if (direction === "left") {
Self.SetHitbox(48, 0, doodadSize, doodadSize);
} else if (direction === "right") {
@ -17,12 +17,12 @@ function main() {
Self.SetHitbox(0, 0, doodadSize, thickness);
}
var animationSpeed = 100;
var opened = false;
let animationSpeed = 100;
let opened = false;
// Register our animations.
var frames = [];
for (var i = 1; i <= 4; i++) {
let frames = [];
for (let i = 1; i <= 4; i++) {
frames.push(direction + i);
}
@ -30,7 +30,7 @@ function main() {
frames.reverse();
Self.AddAnimation("close", animationSpeed, frames);
Events.OnCollide( function(e) {
Events.OnCollide((e) => {
if (opened) {
return;
}
@ -78,9 +78,9 @@ function main() {
}
});
Events.OnLeave(function() {
Events.OnLeave(() => {
if (opened) {
Self.PlayAnimation("close", function() {
Self.PlayAnimation("close", () => {
opened = false;
});
}

View File

@ -1,16 +1,17 @@
// Warp Doors
const color = Self.GetTag("color"),
isStateDoor = color === 'blue' || color === 'orange';
// State in case we're a blue warp door.
let state = color === 'blue',
animating = false,
collide = false;
function main() {
// Are we a blue or orange door? Regular warp door will be 'none'
var color = Self.GetTag("color");
var isStateDoor = color === 'blue' || color === 'orange';
var state = color === 'blue'; // Blue door is ON by default.
var animating = false;
var collide = false;
// Declare animations and sprite names.
var animSpeed = 100;
var spriteDefault, spriteDisabled; // the latter for state doors.
let animSpeed = 100;
let spriteDefault, spriteDisabled; // the latter for state doors.
if (color === 'blue') {
Self.AddAnimation("open", animSpeed, ["blue-2", "blue-3", "blue-4"]);
Self.AddAnimation("close", animSpeed, ["blue-4", "blue-3", "blue-2", "blue-1"]);
@ -33,17 +34,17 @@ function main() {
}
// Find our linked Warp Door.
var links = Self.GetLinks()
var linkedDoor = null;
for (var i = 0; i < links.length; i++) {
if (links[i].Title.indexOf("Warp Door") > -1) {
linkedDoor = links[i];
let linkedDoor = null;
for (let link of Self.GetLinks()) {
if (link.Title.indexOf("Warp Door") > -1) {
linkedDoor = link;
break;
}
}
// Subscribe to the global state-change if we are a state door.
if (isStateDoor) {
Message.Subscribe("broadcast:state-change", function(newState) {
Message.Subscribe("broadcast:state-change", (newState) => {
state = color === 'blue' ? !newState : newState;
// Activate or deactivate the door.
@ -52,12 +53,11 @@ function main() {
}
// For player groundedness work-around
var playerLastY = []; // last sampling of Y values
var lastUsed = time.Now();
let playerLastY = []; // last sampling of Y values
// The player Uses the door.
var flashedCooldown = false; // "Locked Door" flashed message.
Events.OnUse(function(e) {
let flashedCooldown = false; // "Locked Door" flashed message.
Events.OnUse((e) => {
if (animating) {
return;
}
@ -86,7 +86,7 @@ function main() {
// Work-around: if two Boxes are stacked atop each other the player can
// get stuck if he jumps on top. He may not be Grounded but isn't changing
// effective Y position and a warp door may work as a good way out.
var yValue = e.Actor.Position().Y;
let yValue = e.Actor.Position().Y;
// Collect a sampling of last few Y values. If the player Y position
// is constant the last handful of frames, treat them as if they're
@ -100,8 +100,8 @@ function main() {
playerLastY.pop();
// Hasn't moved?
var isGrounded = true;
for (var i = 0; i < playerLastY.length; i++) {
let isGrounded = true;
for (let i = 0; i < playerLastY.length; i++) {
if (yValue !== playerLastY[i]) {
isGrounded = false;
break;
@ -120,9 +120,9 @@ function main() {
// Play the open and close animation.
animating = true;
Self.PlayAnimation("open", function() {
Self.PlayAnimation("open", () => {
e.Actor.Hide()
Self.PlayAnimation("close", function() {
Self.PlayAnimation("close", () => {
Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault);
animating = false;
@ -139,12 +139,12 @@ function main() {
});
// Respond to incoming warp events.
Message.Subscribe("warp-door:incoming", function(player) {
Message.Subscribe("warp-door:incoming", (player) => {
animating = true;
player.Unfreeze();
Self.PlayAnimation("open", function() {
Self.PlayAnimation("open", () => {
player.Show();
Self.PlayAnimation("close", function() {
Self.PlayAnimation("close", () => {
animating = false;
// If the receiving door was a State Door, fix its state.