815 lines
No EOL
20 KiB
JavaScript
815 lines
No EOL
20 KiB
JavaScript
Level = function(levelName) {
|
|
var level = Scene();
|
|
|
|
var camera = {
|
|
x: 0,
|
|
y: 0,
|
|
z: 0,
|
|
angle: 0,
|
|
fwdX: 0,
|
|
fwdY: 0,
|
|
momx: 0,
|
|
momy: 0,
|
|
oldangle: 0
|
|
};
|
|
|
|
level.map = LevelDatabase[levelName];
|
|
level.saveData = Memory.stage(levelName);
|
|
|
|
// Scroll planes
|
|
var background = ScrollPlane(0, 0, 360, 1, level.map.background.width, 0, "bg-" + level.map.background.image, 131);
|
|
var waterBack = ScrollPlane(0, 20, 1, 1, 0, 0, "waterback", 130);
|
|
var waves = [];
|
|
|
|
for (var i = 1024; i > 150; i *= 0.85) {
|
|
waves.push(ScrollPlane(
|
|
i, -3000/i, 40, 250/i, (i)/2, (Math.random()*300-150)/i, "water", Math.round(i/8)
|
|
));
|
|
}
|
|
|
|
// Constant level tint
|
|
var tint;
|
|
if (level.map.tint) {
|
|
tint = new PIXI.Graphics();
|
|
tint.beginFill(level.map.tint.rgb || 0);
|
|
tint.drawRect(0, 0, 8, 8);
|
|
tint.endFill();
|
|
tint.alpha = level.map.tint.a || 0.25;
|
|
tint.blendMode = PIXI.BLEND_MODES[level.map.tint.effect] || PIXI.BLEND_MODES.NORMAL;
|
|
tint.scale.set(500/8, 280/8);
|
|
}
|
|
|
|
// Boss
|
|
var boss;
|
|
|
|
// Wipe in/out graphic
|
|
var wipe = level.wipe = new PIXI.Graphics();
|
|
wipe.beginFill(0x000000);
|
|
wipe.drawPolygon([
|
|
new PIXI.Point(0, 0),
|
|
new PIXI.Point(-10, 28),
|
|
new PIXI.Point(53, 28),
|
|
new PIXI.Point(63, 0)
|
|
]);
|
|
wipe.endFill();
|
|
wipe.scale.set(10, 10);
|
|
|
|
// A set of blocks that entities are contained in.
|
|
// Blocks two grid spaces away (in a square, corners excluded) from the camera
|
|
// are thunk and rendered in a frame.
|
|
var entityGrid = {};
|
|
|
|
function getGridIndex(x, y) {
|
|
return Math.floor(x/600) + Math.floor(y/600)*512;
|
|
// If a map is bigger than 200k pixels one way then you have other problems.
|
|
}
|
|
|
|
var dolphin;
|
|
|
|
level.init = function() {
|
|
level.stage.addChild(background.plane);
|
|
level.stage.addChild(waterBack.plane);
|
|
waves.forEach(function(p) {
|
|
level.stage.addChild(p.plane);
|
|
});
|
|
|
|
var spawn = Memory.getDolphin() || level.map.spawn;
|
|
dolphin = Dolphin(level, spawn.axis, spawn.position, spawn.z);
|
|
if (spawn.momx || spawn.momy) {
|
|
dolphin.momentum.x = spawn.momx;
|
|
dolphin.momentum.y = spawn.momy;
|
|
}
|
|
|
|
placeEntityInGrid(dolphin);
|
|
camera.x = dolphin.position.x;
|
|
camera.y = dolphin.position.y;
|
|
initParaloop();
|
|
|
|
level.map.rocks.forEach(function(rock) {
|
|
if (rock.bossonly && Memory.global.bossClear) {
|
|
return; // Don't spawn this rock any more.
|
|
}
|
|
|
|
var obj = Rock(level, rock.x, rock.y, rock.z, rock.type);
|
|
placeEntityInGrid(obj);
|
|
|
|
if (level.editor) {
|
|
var info = rock;
|
|
|
|
obj.editorremove = function() {
|
|
level.map.rocks.splice(level.map.rocks.indexOf(info), 1);
|
|
obj.position.x = -99999;
|
|
}
|
|
}
|
|
});
|
|
|
|
level.map.keys.forEach(function(key, index) {
|
|
if (level.editor || !level.saveData.keys[index]) {
|
|
placeEntityInGrid(Key(level, key.x, key.y, key.z, index, key.color));
|
|
}
|
|
});
|
|
|
|
level.map.doors.forEach(function(door, index) {
|
|
if (level.editor || !level.saveData.doors[index]) {
|
|
placeEntityInGrid(Door(level, door.x, door.y, door.z, index, door.color));
|
|
}
|
|
});
|
|
|
|
level.map.transitions.forEach(function(trans) {
|
|
var obj = Transition(level, trans.position, trans.bbox, trans.destination);
|
|
placeEntityInGrid(obj);
|
|
|
|
if (level.editor) {
|
|
var info = trans;
|
|
|
|
obj.editorremove = function() {
|
|
level.map.transitions.splice(level.map.rocks.indexOf(info), 1);
|
|
obj.position.x = -99999;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (tint) {
|
|
level.stage.addChild(tint);
|
|
}
|
|
level.stage.addChild(wipe);
|
|
|
|
if (level.map.music && level.map.music != "none" && level.map.music != Music.current
|
|
&& !(level.map.music == "boss" && Memory.global.bossClear)
|
|
) {
|
|
Music.play(level.map.music);
|
|
}
|
|
|
|
// Save crystal.
|
|
if (level.map.save) {
|
|
var crystal = Entity(level, 1000, 1000, -111);
|
|
crystal.addSprite("spr", Renderer.sprite("save"));
|
|
crystal.currentSprite("spr");
|
|
crystal.save = true;
|
|
placeEntityInGrid(crystal);
|
|
}
|
|
|
|
// Rescuee.
|
|
if (RescueDatabase[levelName] && !level.saveData.rescued) {
|
|
var r = Rescuee(level, RescueDatabase[levelName], dolphin);
|
|
placeEntityInGrid(r);
|
|
if (r.bubble) {
|
|
placeEntityInGrid(r.bubble);
|
|
placeEntityInGrid(r.barrier);
|
|
}
|
|
} else if (levelName == "Intro" && Memory.global.bossClear) {
|
|
placeEntityInGrid(Rescuee(level, RescueDatabase.Post, dolphin));
|
|
}
|
|
|
|
// Boss.
|
|
if (level.map.boss && !Memory.global.bossClear) {
|
|
boss = Boss(
|
|
level,
|
|
dolphin.position.x + Math.cos(dolphin.angle) * 250,
|
|
dolphin.position.y + Math.sin(dolphin.angle) * 250,
|
|
dolphin.position.z,
|
|
level.map.boss,
|
|
dolphin
|
|
);
|
|
placeEntityInGrid(boss);
|
|
boss.arms.forEach(function(arm) {
|
|
arm.forEach(function(piece) {
|
|
placeEntityInGrid(piece);
|
|
});
|
|
});
|
|
|
|
var texts = {
|
|
"Boss 1": " THIS IS THE BEGINNING OF YOUR END.",
|
|
"Boss 2": " GIVE UP! YOUR KINGDOM IS MINE.",
|
|
"Boss 3": " ABANDON HOPE.",
|
|
};
|
|
|
|
var t = Renderer.typewriterText(texts[levelName] || "", 60, 220);
|
|
level.stage.addChild(t);
|
|
t.tint = 0xFF0000;
|
|
|
|
window.setTimeout(function() {
|
|
level.stage.removeChild(t);
|
|
}, 8000);
|
|
}
|
|
}
|
|
|
|
var paused = Renderer.text("Pause", 220, 20);
|
|
|
|
level.paused = function() {
|
|
if (Input.pressed("cancel")) {
|
|
level.think = level.unpaused;
|
|
Music.paused(false);
|
|
level.stage.removeChild(paused);
|
|
}
|
|
}
|
|
|
|
level.think = level.unpaused = function() {
|
|
if (Input.pressed("cancel")) {
|
|
level.think = level.paused;
|
|
dolphin.activeSprite.speed(0);
|
|
Music.paused(true);
|
|
level.stage.addChild(paused);
|
|
return;
|
|
}
|
|
|
|
eachEntity(function(entity) {
|
|
if (entity.think) {
|
|
entity.think();
|
|
}
|
|
placeEntityInGrid(entity);
|
|
});
|
|
|
|
doParaloop();
|
|
|
|
cameraThinker();
|
|
|
|
if (level.editor) {
|
|
levelEditor();
|
|
}
|
|
|
|
if (wipe.x < 600) {
|
|
wipe.x += 15;
|
|
|
|
if (wipe.x > -30 && wipe.newlevel) {
|
|
if (Memory.stage() == "Boss 3" && Memory.global.bossClear) {
|
|
Memory.storeDolphin(0, 200, -800, 0, -1);
|
|
Game.setScene(Level("Ending"));
|
|
} else if (Memory.stage() == "Boss 1" && !Memory.global.bossStarted) {
|
|
Memory.global.bossStarted = true;
|
|
Game.setScene(Cutscene("boss"));
|
|
} else if (Memory.stage() == "Intro" && levelName == "Ending") {
|
|
Memory.save();
|
|
Game.setScene(Cutscene("ending"));
|
|
} else {
|
|
Memory.loadStage();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (level.map.save && !level.saved && dolphin.position.z < -30 && dolphin.momentum.y > 0) {
|
|
level.saved = true;
|
|
|
|
if (level.ticCount > 10) {
|
|
Memory.storeDolphin(dolphin.axis.current, dolphin.axis.position,
|
|
dolphin.position.z, dolphin.momentum.x, dolphin.momentum.y);
|
|
Memory.save();
|
|
SFX.play("save");
|
|
|
|
// Special ending.
|
|
if (levelName == "Save 5") {
|
|
Game.setScene(Ending());
|
|
}
|
|
|
|
var text = Renderer.text("Your adventure has been saved.", 140, 200)
|
|
level.stage.addChild(text);
|
|
|
|
var fade = new PIXI.Graphics;
|
|
fade.beginFill(0xFFFFFF);
|
|
fade.drawRect(0, 0, 500, 280);
|
|
fade.endFill();
|
|
|
|
function fadeout() {
|
|
fade.alpha -= 0.01;
|
|
|
|
if (fade.alpha > 0) {
|
|
window.setTimeout(fadeout, 20);
|
|
} else {
|
|
window.setTimeout(function() {
|
|
level.stage.removeChild(text);
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
fadeout();
|
|
|
|
level.stage.addChild(fade);
|
|
}
|
|
}
|
|
}
|
|
|
|
level.moveLevels = function() {
|
|
wipe.x = -630;
|
|
wipe.newlevel = true;
|
|
}
|
|
|
|
function cameraThinker() {
|
|
if (camera.boss) {
|
|
camera.angle = Math.atan2(boss.position.y - camera.y, boss.position.x - camera.x);
|
|
return;
|
|
}
|
|
|
|
// Camera thinker.
|
|
var targetX, targetY;
|
|
|
|
camera.fwdX += (dolphin.momentum.x/30 - camera.fwdX) / 32;
|
|
camera.fwdY += (dolphin.momentum.y*8 - camera.fwdY) / 32;
|
|
|
|
targetX = dolphin.position.x - 250*Math.cos(dolphin.angle);
|
|
targetY = dolphin.position.y - 250*Math.sin(dolphin.angle);
|
|
|
|
camera.x += camera.momx = (targetX - camera.x) / 4;
|
|
camera.y += camera.momy = (targetY - camera.y) / 4;
|
|
camera.z = dolphin.position.z + camera.fwdY;
|
|
camera.angle = Math.atan2(dolphin.position.y - camera.y, dolphin.position.x - camera.x)
|
|
+ camera.fwdX;
|
|
}
|
|
|
|
level.render = function(frames) {
|
|
if (level.think == level.paused) return;
|
|
|
|
eachEntity(function(entity) {
|
|
if (!entity.activeSprite) {
|
|
return;
|
|
}
|
|
|
|
var sprite = entity.activeSprite;
|
|
|
|
sprite.visible = false;
|
|
|
|
// If we're too far vertically, don't bother.
|
|
if (Math.abs(entity.position.z - camera.z) > 700) {
|
|
return;
|
|
}
|
|
|
|
// Start with the angle and distance for the entity.
|
|
var xdist, ydist,
|
|
angle, distance;
|
|
xdist = entity.position.x - camera.x;
|
|
ydist = entity.position.y - camera.y;
|
|
angle = (Math.atan2(ydist, xdist) - camera.angle + Math.PI * 3) % (2 * Math.PI) - Math.PI;
|
|
distance = Math.sqrt(ydist*ydist + xdist*xdist);
|
|
|
|
if (distance > 1024 || distance < 16 || Math.abs(angle) > Math.PI/3) {
|
|
// Not in the viewport.
|
|
return;
|
|
}
|
|
|
|
if ((entity.position.z > 0) != (camera.z > 0)
|
|
&& Math.abs(camera.z) > 120 && distance > 300) {
|
|
// On the wrong side of the water.
|
|
return;
|
|
}
|
|
|
|
// In the viewport.
|
|
sprite.visible = true;
|
|
sprite.alpha = Math.min(4 - (distance/256), 1);
|
|
|
|
distance *= Math.cos(angle);
|
|
|
|
// Get screen position and scale.
|
|
var scrX, scrY, scrScale;
|
|
scrX = (Math.tan(angle) * 250) + 250;
|
|
scrScale = 250/distance;
|
|
scrY = (entity.position.z - camera.z)*scrScale + 150;
|
|
|
|
// Set sprite position.
|
|
sprite.position.set(scrX, scrY);
|
|
sprite.scale.set(scrScale, scrScale);
|
|
|
|
// Use distance to sort.
|
|
sprite.ZINDEX = Math.round(distance/8);
|
|
|
|
var index = level.stage.getChildIndex(sprite);
|
|
try {
|
|
while (index > 0 && (level.stage.getChildAt(index-1).ZINDEX || 0) < sprite.ZINDEX) {
|
|
index--;
|
|
}
|
|
while (level.stage.getChildAt(index+1).ZINDEX > sprite.ZINDEX) {
|
|
index++;
|
|
}
|
|
} catch (e) {}
|
|
level.stage.setChildIndex(sprite, index);
|
|
|
|
// Save cheating.
|
|
if (entity.save) {
|
|
sprite.scale.set(scrScale*2, scrScale*2);
|
|
}
|
|
});
|
|
|
|
// Scroll planes
|
|
var xScroll = Math.sqrt(camera.momx*camera.momx + camera.momy*camera.momy)
|
|
* Math.sin(Math.atan2(camera.momy, camera.momx)-camera.angle);
|
|
|
|
var turn = camera.angle - camera.oldangle;
|
|
camera.oldangle = camera.angle;
|
|
turn = (turn + Math.PI * 3) % (2 * Math.PI) - Math.PI;
|
|
|
|
waves.forEach(function(p) {
|
|
p.plane.tilePosition.x -= (xScroll*p.moveFactor) + (turn*p.turnFactor) - p.driftFactor;
|
|
|
|
p.plane.position.y = 150 - camera.z*p.moveFactor + p.z;
|
|
});
|
|
|
|
waterBack.plane.position.y = Math.max(0, Math.min(150-(camera.z/5), 170-(camera.z*1.5)));
|
|
waterBack.plane.scale.y = 280 - waterBack.plane.position.y;
|
|
|
|
background.plane.position.y = (camera.z/-6)-160;
|
|
background.plane.tilePosition.x = (camera.angle/(-2*Math.PI)) * background.turnFactor;
|
|
|
|
// Keys
|
|
renderKeys();
|
|
}
|
|
|
|
level.end = function() {
|
|
|
|
}
|
|
|
|
level.colliding = function(object, tag, excludes) {
|
|
if (level.editor) { return; }
|
|
excludes = excludes || [];
|
|
var xoffs = object.position.x % 600 > 300 ? 1 : -1;
|
|
var yoffs = object.position.y % 600 > 300 ? 512 : -512;
|
|
var start = getGridIndex(object.position.x, object.position.y);
|
|
|
|
try {
|
|
([start, start+xoffs, start+yoffs, start+xoffs+yoffs]).forEach(function(pos) {
|
|
if (entityGrid[pos]) {
|
|
entityGrid[pos].forEach(function(target) {
|
|
if (!target.bbox || target.bbox.tag != tag) {
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(target.position.x - object.position.x)
|
|
> target.bbox.x + object.bbox.x) {
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(target.position.y - object.position.y)
|
|
> target.bbox.y + object.bbox.y) {
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(target.position.z - object.position.z)
|
|
> target.bbox.z + object.bbox.z) {
|
|
return;
|
|
}
|
|
|
|
if (excludes.indexOf(target) != -1) {
|
|
return;
|
|
}
|
|
|
|
throw target;
|
|
});
|
|
}
|
|
});
|
|
} catch (toucher) {
|
|
return toucher;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function placeEntityInGrid(entity) {
|
|
var grid;
|
|
var gridpos = getGridIndex(entity.position.x, entity.position.y);
|
|
if (entity.gridPosition != gridpos) {
|
|
// Remove from old.
|
|
if (entity.gridPosition !== undefined) {
|
|
grid = entityGrid[entity.gridPosition];
|
|
var pos = grid.indexOf(entity);
|
|
grid.splice(pos, 1);
|
|
}
|
|
|
|
// Add to new.
|
|
grid = (entityGrid[gridpos] || (entityGrid[gridpos] = []));
|
|
entity.gridPosition = gridpos;
|
|
grid.push(entity);
|
|
}
|
|
}
|
|
|
|
function eachEntity(callback) {
|
|
const offsets = [
|
|
-1025, -1024, -1023,
|
|
-514, -513, -512, -511, -510,
|
|
-2, -1, 0, 1, 2,
|
|
510, 511, 512, 513, 514,
|
|
1023, 1024, 1025
|
|
];
|
|
var pos = getGridIndex(camera.x, camera.y);
|
|
|
|
// Build up an array separately so that we can modify the entity arrays during the callback.
|
|
var objs = [];
|
|
offsets.forEach(function(offset) {
|
|
if (entityGrid[pos+offset]) {
|
|
entityGrid[pos+offset].forEach(function(entity) {
|
|
objs.push(entity);
|
|
});
|
|
}
|
|
});
|
|
|
|
objs.forEach(callback);
|
|
}
|
|
|
|
// Paraloop stuff starts here
|
|
var paraloopObjs = [];
|
|
var paraloopLength = 42;
|
|
var paraloopPos = 0;
|
|
|
|
function initParaloop() {
|
|
for (var i = 0; i < paraloopLength; i++) {
|
|
var obj = Entity(level, -99999, -99999, -99999);
|
|
obj.addSprite("spr", Renderer.sprite("loopstar"));
|
|
obj.currentSprite("spr");
|
|
paraloopObjs.push(obj);
|
|
}
|
|
}
|
|
|
|
function doParaloop() {
|
|
if (level.ticCount % 4) {
|
|
return;
|
|
}
|
|
|
|
var obj = paraloopObjs[paraloopPos];
|
|
obj.position.x = dolphin.position.x;
|
|
obj.position.y = dolphin.position.y;
|
|
obj.position.z = dolphin.position.z;
|
|
placeEntityInGrid(obj);
|
|
|
|
var check = paraloopPos;
|
|
do {
|
|
check = (check+1) % paraloopLength;
|
|
|
|
var star = paraloopObjs[check];
|
|
if (
|
|
Math.abs(star.position.x - dolphin.position.x) < 36 &&
|
|
Math.abs(star.position.y - dolphin.position.y) < 36 &&
|
|
Math.abs(star.position.z - dolphin.position.z) < 36
|
|
) {
|
|
checkParaloop(check);
|
|
break;
|
|
}
|
|
} while (check != paraloopPos);
|
|
|
|
paraloopPos++; paraloopPos %= paraloopLength;
|
|
}
|
|
|
|
function checkParaloop(pos) {
|
|
if (level.editor) { return; }
|
|
|
|
var loopLen = (paraloopPos - pos + paraloopLength) % paraloopLength;
|
|
|
|
if (loopLen < 4) {
|
|
return;
|
|
}
|
|
|
|
var origPos = pos;
|
|
var minX, maxX, minY, maxY, minZ, maxZ;
|
|
minX = maxX = paraloopObjs[pos].position.x;
|
|
minY = maxY = paraloopObjs[pos].position.y;
|
|
minZ = maxZ = paraloopObjs[pos].position.z;
|
|
|
|
while (pos != paraloopPos) {
|
|
pos = (pos+1) % paraloopLength;
|
|
var p = paraloopObjs[pos].position;
|
|
|
|
if (minX > p.x) minX = p.x;
|
|
if (maxX < p.x) maxX = p.x;
|
|
if (minY > p.y) minY = p.y;
|
|
if (maxY < p.y) maxY = p.y;
|
|
if (minZ > p.z) minZ = p.z;
|
|
if (maxZ < p.z) maxZ = p.z;
|
|
}
|
|
|
|
// Enforce a minimum loop size.
|
|
if (
|
|
(maxX - minX < 40 ? 1 : 0) +
|
|
(maxY - minY < 40 ? 1 : 0) +
|
|
(maxZ - minZ < 40 ? 1 : 0) > 1
|
|
) {
|
|
return;
|
|
}
|
|
|
|
// Loop again to find the radius.
|
|
var dist = 0, distnum = 0;
|
|
pos = origPos;
|
|
minX = (minX+maxX)/2;
|
|
minY = (minY+maxY)/2;
|
|
minZ = (minZ+maxZ)/2;
|
|
|
|
while (pos != paraloopPos) {
|
|
pos = (pos+1) % paraloopLength;
|
|
var p = paraloopObjs[pos].position;
|
|
|
|
var newDist = (p.x-minX)*(p.x-minX)
|
|
+ (p.y-minY)*(p.y-minY)
|
|
+ (p.z-minZ)*(p.z-minZ);
|
|
|
|
dist += Math.sqrt(newDist);
|
|
distnum++;
|
|
}
|
|
|
|
dist /= distnum;
|
|
|
|
// Enforce a minimum radius of 40 pixels.
|
|
if (dist < 40) {
|
|
return;
|
|
}
|
|
|
|
// Attract and clear out the paraloop.
|
|
paraloopObjs.forEach(function(obj) {
|
|
obj.position.x = -99999;
|
|
obj.position.y = -99999;
|
|
obj.position.z = -99999;
|
|
obj.activeSprite.visible = false;
|
|
});
|
|
attractCollectiblesToDolphin(minX, minY, minZ, dist*dist);
|
|
|
|
// Boss cheating.
|
|
if (levelName == "Boss 3" && Math.abs(minX) < 64 && Math.abs(minY) < 64 && !Memory.global.bossClear) {
|
|
Music.stop();
|
|
|
|
camera.boss = true;
|
|
|
|
Memory.global.bossClear = true;
|
|
|
|
boss.finish();
|
|
}
|
|
}
|
|
|
|
function attractCollectiblesToDolphin(x, y, z, sqdist) {
|
|
sqdist *= 0.7;
|
|
|
|
eachEntity(function(obj) {
|
|
if (!obj.attract) {
|
|
return;
|
|
}
|
|
|
|
var p = obj.position;
|
|
|
|
if (
|
|
(p.x-x)*(p.x-x) +
|
|
(p.y-y)*(p.y-y) +
|
|
(p.z-z)*(p.z-z) < sqdist
|
|
) {
|
|
obj.think = obj.attract;
|
|
obj.attractTarget = dolphin;
|
|
}
|
|
});
|
|
}
|
|
|
|
var keySprites = [];
|
|
function renderKeys() {
|
|
var index;
|
|
|
|
// Remove/reset
|
|
if (keySprites.length > Memory.global.keys.length) {
|
|
keySprites.forEach(function(key) {
|
|
level.stage.removeChild(key);
|
|
});
|
|
keySprites = [];
|
|
}
|
|
|
|
// Add
|
|
for (index = keySprites.length; index < Memory.global.keys.length; index++) {
|
|
var spr = Renderer.sprite("key-" + Memory.global.keys[index]);
|
|
spr.position.set(20 + 15*index, 28);
|
|
keySprites.push(spr);
|
|
level.stage.addChild(spr);
|
|
}
|
|
}
|
|
|
|
level.edit = function() {
|
|
level.editor = true;
|
|
|
|
if (typeof LEVELEDITORBOX == 'undefined') {
|
|
LEVELEDITORBOX = document.createElement('div');
|
|
LEVELEDITORBOX.style.backgroundColor = '#CCC';
|
|
LEVELEDITORBOX.style.minHeight = '100px';
|
|
LEVELEDITORBOX.style.whiteSpace = 'pre-wrap';
|
|
document.body.appendChild(LEVELEDITORBOX);
|
|
}
|
|
|
|
return level;
|
|
}
|
|
|
|
function levelEditor() {
|
|
var color =
|
|
Input.held("redkey") ? "red" :
|
|
Input.held("bluekey") ? "blue" :
|
|
Input.held("greenkey") ? "green" :
|
|
Input.held("yellowkey") ? "yellow" : "white";
|
|
|
|
if (pressOrTurbo("rocksm")) {
|
|
spawnRock("small");
|
|
}
|
|
if (pressOrTurbo("rockmed")) {
|
|
spawnRock("medium");
|
|
}
|
|
if (pressOrTurbo("rocklg")) {
|
|
spawnRock("large");
|
|
}
|
|
if (pressOrTurbo("rockwd")) {
|
|
spawnRock("wide");
|
|
}
|
|
|
|
function spawnRock(size) {
|
|
var info = {
|
|
x: Math.round(dolphin.position.x),
|
|
y: Math.round(dolphin.position.y),
|
|
z: Math.round(dolphin.position.z),
|
|
type: size
|
|
};
|
|
level.map.rocks.push(info);
|
|
var rock = Rock(level, info.x, info.y, info.z, info.type);
|
|
|
|
rock.editorremove = function() {
|
|
level.map.rocks.splice(level.map.rocks.indexOf(info), 1);
|
|
rock.position.x = -99999;
|
|
}
|
|
|
|
placeEntityInGrid(rock);
|
|
}
|
|
|
|
if (Input.pressed("key")) {
|
|
var info = {
|
|
x: Math.round(dolphin.position.x),
|
|
y: Math.round(dolphin.position.y),
|
|
z: Math.round(dolphin.position.z),
|
|
color: color
|
|
};
|
|
|
|
level.map.keys.push(info);
|
|
|
|
placeEntityInGrid(Key(level, info.x, info.y, info.z, level.map.keys.length-1, color));
|
|
}
|
|
|
|
if (Input.pressed("door")) {
|
|
var info = {
|
|
x: Math.round(dolphin.position.x),
|
|
y: Math.round(dolphin.position.y),
|
|
z: Math.round(dolphin.position.z),
|
|
color: color
|
|
};
|
|
|
|
level.map.doors.push(info);
|
|
|
|
placeEntityInGrid(Door(level, info.x, info.y, info.z, level.map.doors.length-1, color));
|
|
}
|
|
|
|
if (Input.pressed("transition")) {
|
|
var trans = {
|
|
position: {
|
|
x: dolphin.position.x,
|
|
y: dolphin.position.y,
|
|
z: dolphin.position.z
|
|
},
|
|
bbox: {x: 32, y: 32, z: 32}, destination: {
|
|
stage: "STAGE",
|
|
axis: 0,
|
|
position: 0,
|
|
z: 0,
|
|
momx: 0,
|
|
momy: 0
|
|
}
|
|
}
|
|
var obj = Transition(level, dolphin.position, trans.bbox, trans.destination);
|
|
placeEntityInGrid(obj);
|
|
|
|
obj.editorremove = function() {
|
|
level.map.transitions.splice(level.map.rocks.indexOf(trans), 1);
|
|
obj.position.x = -99999;
|
|
}
|
|
|
|
level.map.transitions.push(trans);
|
|
}
|
|
|
|
if (Input.held("remove")) {
|
|
eachEntity(function(obj) {
|
|
if (
|
|
obj.editorremove
|
|
&& Math.abs(obj.position.x - dolphin.position.x) < 18
|
|
&& Math.abs(obj.position.y - dolphin.position.y) < 18
|
|
&& Math.abs(obj.position.z - dolphin.position.z) < 18
|
|
) {
|
|
obj.editorremove();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (Input.held("slow")) {
|
|
dolphin.momentum.x = Math.cos(dolphin.activeSprite.rotation)*2;
|
|
dolphin.momentum.y = Math.sin(dolphin.activeSprite.rotation)*2;
|
|
}
|
|
if (Input.held("fast")) {
|
|
dolphin.momentum.x = Math.cos(dolphin.activeSprite.rotation)*8;
|
|
dolphin.momentum.y = Math.sin(dolphin.activeSprite.rotation)*8;
|
|
}
|
|
|
|
if (Input.pressed("export")) {
|
|
level.map.spawn = {
|
|
axis: dolphin.axis.current,
|
|
position: Math.round(dolphin.axis.position),
|
|
z: Math.round(dolphin.position.z)
|
|
};
|
|
|
|
LEVELEDITORBOX.innerText = JSON.stringify(Input.held("redkey") ? level.map.spawn : level.map, null, "\t");
|
|
}
|
|
|
|
function pressOrTurbo(key) {
|
|
return Input.pressed(key) || (Input.held("fast") && Input.held(key) && !(level.ticCount % 4));
|
|
}
|
|
}
|
|
|
|
return level;
|
|
} |