diff --git a/.DS_Store b/.DS_Store
index 9275525..6fc3f54 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/index.html b/index.html
index 7c463e8..31f687d 100644
--- a/index.html
+++ b/index.html
@@ -95,7 +95,8 @@
diff --git a/js/bullet.js b/js/bullet.js
index 77cf0c5..db996d6 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -5453,7 +5453,7 @@ const b = {
} else {
const bodyCollisions = Matter.Query.collides(this, body)
if (bodyCollisions.length) {
- if (!bodyCollisions[0].bodyA.isComposite) {
+ if (!bodyCollisions[0].bodyA.isNonStick) {
onCollide(this)
this.stuckTo = bodyCollisions[0].bodyA
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
diff --git a/js/level.js b/js/level.js
index 0674ce3..010c795 100644
--- a/js/level.js
+++ b/js/level.js
@@ -8,8 +8,12 @@ const level = {
onLevel: -1,
levelsCleared: 0,
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], //intro, gauntlet, final are added in at the start and end of level order
- trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "dhotGun", "superBall", "matterWave", "missile"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"],
+ trainingLevels: [
+ "walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect",
+ "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile",
+ "stack", "mine", "grenades", "harpoon"
+ ],
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
@@ -30,7 +34,7 @@ const level = {
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.tech[297].frequency = 100
- // level.deflect();
+ // level.harpoon();
if (simulation.isTraining) { level.walk(); } else { level.intro(); }
// level.testing(); //not in rotation, used for testing
@@ -63,7 +67,7 @@ const level = {
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
// lore.techCount = 3
// simulation.isCheating = false //true;
- // localSettings.loreCount = 3; //this sets what conversation is heard
+ // localSettings.loreCount = 1; //this sets what conversation is heard
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
// level.null()
@@ -136,1121 +140,12 @@ const level = {
},
trainingText(say) {
simulation.lastLogTime = 0; //clear previous messages
- simulation.makeTextLog(`
supervised.learning(${(Date.now()/1000).toFixed(0)} s):
${say}`, Infinity)
+ simulation.isTextLogOpen = true
+ simulation.makeTextLog(`
supervised.learning(${(Date.now()/1000).toFixed(0)} s):
${say}`, Infinity)
+ simulation.isTextLogOpen = false
// lore.trainer.text("Wow. Just a platform.")
},
trainingBackgroundColor: "#e1e1e1",
- walk() { //learn to walk
-
- var img = new Image(); // Create new img element
- img.src = 'myImage.png'; // Set source path
-
-
- m.addHealth(Infinity)
- document.getElementById("health").style.display = "none" //hide your health bar
- document.getElementById("health-bg").style.display = "none"
-
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- simulation.lastLogTime = 0; //clear previous messages
- let instruction = 0
- level.trainingText(`move
↔ with
${input.key.left.replace('Key', '').replace('Digit', '')} and
${input.key.right.replace('Key', '').replace('Digit', '')}`)
-
- level.custom = () => {
- if (instruction === 0 && input.right) {
- instruction++
- level.trainingText(`
move ↔ with ${input.key.left.replace('Key', '').replace('Digit', '')} and ${input.key.right.replace('Key', '').replace('Digit', '')}
-
exit through the blue door`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 0, 3500, 1800); //floor
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
- spawn.mapRect(700, -8, 50, 25);
- spawn.mapRect(725, -16, 75, 25);
- spawn.mapRect(1375, -16, 50, 50);
- spawn.mapRect(1400, -8, 50, 25);
- spawn.mapRect(750, -24, 650, 100);
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- crouch() { //learn to crouch
- m.addHealth(Infinity)
- level.setPosToSpawn(75, -100); //normal spawn
- spawn.mapRect(25, -60, 100, 20); //small platform for player
- spawn.mapRect(0, -50, 150, 25); //stairs
- spawn.mapRect(-25, -40, 200, 25);
- spawn.mapRect(-50, -30, 250, 25);
- spawn.mapRect(-75, -20, 300, 25);
- spawn.mapRect(-100, -10, 350, 25);
- spawn.mapRect(-150, -50, 175, 75);
-
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- let instruction = 0
- level.trainingText(`press
${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
- level.custom = () => {
- if (instruction === 0 && input.down) {
- instruction++
- level.trainingText(`
press ${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1625, -350, 375, 350)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1625, -350, 375, 350)
- //dark
- ctx.fillStyle = "rgba(0,0,0,0.2)"
- ctx.fillRect(500, -100, 1125, 175);
- };
-
- // spawn.mapRect(1025, -675, 300, 623); //crouch wall
- // spawn.mapRect(625, -650, 1025, 550);
- spawn.mapRect(500, -650, 1125, 550);
- spawn.mapRect(-200, -650, 875, 300);
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- },
- jump() { //learn to jump
- m.addHealth(Infinity)
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- let instruction = 0
- level.trainingText(`hold down
${input.key.up.replace('Key', '').replace('Digit', '')} longer to jump higher`)
-
- level.custom = () => {
- if (instruction === 0 && m.pos.x > 300) {
- instruction++
- level.trainingText(`
hold down ${input.key.up.replace('Key', '').replace('Digit', '')} longer to jump higher`)
- }
- m.health = 1 //can't die
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //dark
- ctx.fillStyle = "rgba(0,0,0,0.2)"
- ctx.fillRect(1000, 0, 450, 1800)
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(275, -350, 200, 375);
- spawn.mapRect(-250, 0, 1250, 1800); //floor
- spawn.mapRect(1450, 0, 1075, 1800); //floor
- spawn.mapRect(-250, -2800, 1250, 2200); //roof
- spawn.mapRect(1450, -2800, 1075, 2200); //roof
- spawn.mapVertex(375, 0, "150 0 -150 0 -100 -50 100 -50"); //base
-
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
-
- //roof steps
- spawn.mapRect(1000, -650, 25, 25);
- spawn.mapRect(1000, -675, 50, 25);
- spawn.mapRect(1000, -700, 75, 25);
- spawn.mapRect(1000, -725, 100, 25);
- spawn.mapRect(1425, -650, 25, 25);
- spawn.mapRect(1400, -675, 50, 25);
- spawn.mapRect(1375, -700, 75, 25);
- spawn.mapRect(1350, -725, 100, 25);
- spawn.mapRect(1325, -750, 150, 25);
- spawn.mapRect(1300, -775, 150, 25);
- spawn.mapRect(1000, -750, 125, 25);
- spawn.mapRect(1275, -2800, 200, 2025);
- spawn.mapRect(975, -2800, 200, 2025);
- spawn.mapRect(1000, -775, 150, 25);
- },
- hold() { //put block on button to open door
- m.addHealth(Infinity)
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- spawn.bodyRect(1025, -75, 50, 50); //block to go on button
- const buttonDoor = level.button(500, 0)
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
-
- let instruction = 0
- level.trainingText(`activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse`)
-
- level.custom = () => {
- if (instruction === 0 && input.field) {
- instruction++
- level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouserelease your
field on a
block to pick it up`)
- } else if (instruction === 1 && m.isHolding) {
- instruction++
- level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
release your field on a block to pick it updrop the
block on the red button to open the door`)
- } else if (instruction === 2 && !buttonDoor.isUp && Vector.magnitudeSquared(Vector.sub(body[0].position, buttonDoor.min)) < 10000) {
- instruction++
- level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
release your field on a block to pick it up
drop the block on the red button to open the door`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- buttonDoor.query();
- buttonDoor.draw();
- if (buttonDoor.isUp) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- throw () { //throw a block on button to open door
- m.addHealth(Infinity)
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- spawn.bodyRect(1025, -75, 50, 50); //block to go on button
- const buttonDoor = level.button(1635, -400)
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
-
- // activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse
- let instruction = 0
- level.trainingText(`pick up the
block with your
field`)
-
- level.custom = () => {
- if (instruction === 0 && m.isHolding) {
- instruction++
- level.trainingText(`
pick up the block with your field
-
hold your
field down to charge up then release to throw a
block`)
- } else if (instruction === 1 && m.throwCharge > 2) {
- instruction++
- level.trainingText(`
pick up the block with your field
-
hold your field down to charge up then release to throw a block
-
throw the
block onto the button`)
- // the
block at the button
- } else if (instruction === 2 && !buttonDoor.isUp && Vector.magnitudeSquared(Vector.sub(body[0].position, buttonDoor.min)) < 10000) {
- instruction++
- level.trainingText(`
pick up the block with your field
-
hold your field down to charge up then release to throw a block
-
throw the block onto the button`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- buttonDoor.query();
- buttonDoor.draw();
- if (buttonDoor.isUp) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- // spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1790, -600, 250, 225); //button left wall
- spawn.mapRect(1625, -400, 400, 50);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- throwAt() { //throw a block at mob to open door
- m.addHealth(Infinity)
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
-
- let instruction = 0
- level.trainingText(`throw the
block at the
mobs to open the door`)
-
- level.custom = () => {
- if (instruction === 0 && !mob.length) {
- instruction++
- level.trainingText(`
throw the block at the mobs to open the door`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (mob.length > 0) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- // spawn.mapRect(1600, -1200, 500, 850); //exit roof
- // spawn.mapRect(1790, -600, 250, 225); //button left wall
- // spawn.mapRect(1625, -400, 400, 50);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- spawn.mapRect(1600, -600, 425, 250);
-
- spawn.bodyRect(1025, -75, 50, 50); //block to go on button
- spawn.starter(425, -350, 35)
- spawn.starter(800, -350, 44)
- },
- fire() { //throw a block at mob to open door
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = 15;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- const door = level.door(1612.5, -125, 25, 190, 185, 3)
- const buttonDoor = level.button(400, 0)
-
- let instruction = 0
- level.trainingText(`use your
field to pick up the gun power up`)
-
- level.custom = () => {
- if (instruction === 0 && simulation.isChoosing) {
- instruction++
- level.trainingText(`
use your field to pick up the gun power up
-
choose a
gun`)
- } else if (instruction === 1 && !simulation.isChoosing) {
- instruction++
- level.trainingText(`
use your field to pick up the gun power up
-
choose a gun
-
use the
left mouse button to shoot the
mobs`)
- } else if (instruction === 2 && mob.length === 0) {
- instruction++
- level.trainingText(`
use your field to pick up the gun power up
-
choose a gun
-
use the left mouse button to shoot the mobs
-
drop a
block on the red button to open the door`)
- } else if (instruction === 3 && !door.isClosing) {
- instruction++
- level.trainingText(`
use your field to pick up the gun power up
-
choose a gun
-
use the left mouse button to shoot the mobs
-
put a block on the red button to open the door`)
- }
- //spawn ammo if you run out
- if (!powerUp.length && b.inventory.length && b.guns[b.activeGun].ammo === 0) powerUps.directSpawn(1300, -2000, "ammo", false);
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -350, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- buttonDoor.query();
- buttonDoor.draw();
- if (buttonDoor.isUp) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -350, 400, 400)
- //ammo tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.4)"
- ctx.fillRect(1250, -2800, 100, 2200)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
- spawn.mapRect(1350, -2800, 675, 2200);
-
- //ceiling steps
- spawn.mapRect(725, -588, 50, 25);
- spawn.mapRect(725, -600, 75, 25);
- spawn.mapRect(750, -612, 75, 25);
- spawn.mapRect(-275, -650, 1025, 87);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
-
- spawn.mapRect(1600, -600, 425, 300);
- spawn.mapRect(1600, -400, 50, 275);
-
- powerUps.directSpawn(1300, -1500, "gun", false);
- spawn.starter(900, -300, 35)
- spawn.starter(1400, -400, 44)
- },
- deflect() { //learn to jump
- m.addHealth(Infinity)
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- let instruction = 0
- // activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse
- level.trainingText(`use your
field to
deflect the
mobs`)
-
- level.custom = () => {
- if (instruction === 0 && m.pos.x > 1350) {
- instruction++
- level.trainingText(`
use your field to deflect the mobs`)
- }
- //teleport to start if hit
- if (m.immuneCycle > m.cycle) {
- m.energy = m.maxEnergy
- Matter.Body.setPosition(player, { x: 60, y: -50 })
- }
- //spawn bullets
- if (!(simulation.cycle % 5)) {
- spawn.sniperBullet(660 + 580 * Math.random(), -2000, 10, 4);
- const who = mob[mob.length - 1]
- Matter.Body.setVelocity(who, { x: 0, y: 8 });
- who.timeLeft = 300
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //dark
- ctx.fillStyle = "rgba(0,0,0,0.05)"
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //center falling bullets
- ctx.fillStyle = "rgba(255,0,255,0.013)" //pink?
- ctx.fillRect(650, -2800, 600, 2800)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
-
- spawn.mapRect(-250, 0, 3000, 1800); //floor
- spawn.mapRect(-250, -2800, 900, 2200); //roof
- spawn.mapRect(1250, -2800, 1275, 2200); //roof
- spawn.mapVertex(950, 0, "400 0 -400 0 -300 -50 300 -50"); //base
-
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
-
- //spawn bullets on load to avoid rush
- for (let i = 0; i < 32; i++) {
- spawn.sniperBullet(660 + 580 * Math.random(), -2000 + 40 * i, 10, 4);
- const who = mob[mob.length - 1]
- Matter.Body.setVelocity(who, { x: 0, y: 8 });
- who.timeLeft = 300
- }
- },
- heal() { //learn to heal
- m.addHealth(Infinity)
- m.health = 0;
- m.addHealth(0.25)
- document.getElementById("health").style.display = "inline" //show your health bar
- document.getElementById("health-bg").style.display = "inline"
-
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
- let instruction = 0
- level.trainingText(`your
health is displayed in the top left corner
-
use your
field to pick up
until your
health is full`)
-
- level.custom = () => {
- if (instruction === 0 && m.health === 1) {
- instruction++
- level.trainingText(`
use your field to pick up until your health is full`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (m.health !== 1) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 0, 3500, 1800); //floor
-
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- spawn.mapRect(700, -8, 50, 25);
- spawn.mapRect(725, -16, 75, 25);
- spawn.mapRect(1375, -16, 50, 50);
- spawn.mapRect(1400, -8, 50, 25);
- spawn.mapRect(750, -24, 650, 100);
- powerUps.directSpawn(875, -40, "heal", false, null, 15);
- powerUps.directSpawn(1075, -50, "heal", false, null, 25);
- powerUps.directSpawn(1275, -65, "heal", false, null, 35);
-
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- nailGun() { //throw a block on button to open door
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
- b.giveGuns("nail gun")
- b.guns[b.activeGun].ammo = 0
- simulation.updateGunHUD();
-
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- let instruction = 0
- level.trainingText(`use your
field to pick up
for your
nail gun`)
-
- level.custom = () => {
- if (instruction === 0 && b.inventory.length && b.guns[b.activeGun].ammo > 0) {
- instruction++
- level.trainingText(`
use your field to pick up for your nail gun
-
use the
left mouse button to shoot the
mobs`)
- } else if (instruction === 1 && mob.length === 0) {
- instruction++
- level.trainingText(`
use your field to pick up for your nail gun
-
use the left mouse button to shoot the mobs`)
- }
- //spawn ammo if you run out
- let isAmmo = false
- for (let i = 0; i < powerUp.length; i++) {
- if (powerUp[i].name === 'ammo') isAmmo = true
- }
- if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
- powerUps.directSpawn(1300, -2000, "ammo", false);
- powerUps.directSpawn(1301, -2200, "ammo", false);
- }
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (mob.length > 0) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //ammo tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.4)"
- ctx.fillRect(1250, -2800, 100, 2200)
- };
-
- if (m.health < 1) {
- powerUps.directSpawn(1298, -3500, "heal", false, 23);
- powerUps.directSpawn(1305, -3000, "heal", false, 35);
- }
- for (let i = 0; i < 2; i++) {
- spawn.spinner(1300 + i, -3000 - 200 * i, 25 + 5 * i)
- Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 62 });
- }
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
- spawn.mapRect(1350, -2800, 675, 2200);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- // spawn.mapRect(1600, -1200, 500, 850); //exit roof
- // spawn.mapRect(1790, -600, 250, 225); //button left wall
- // spawn.mapRect(1625, -400, 400, 50);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- spawn.mapRect(1600, -600, 425, 250);
- },
- shotGun() { //throw a block on button to open door
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
- b.giveGuns("shotgun")
- // b.guns[b.activeGun].ammo = 0
- // simulation.updateGunHUD();
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- let instruction = 0
- level.trainingText(`use your
shotgun to clear the room of mobs`)
-
- level.custom = () => {
- if (instruction === 0 && mob.length === 0) {
- instruction++
- level.trainingText(`
use your shotgun to clear the room of mobs`)
- }
- //spawn ammo if you run out
- let isAmmo = false
- for (let i = 0; i < powerUp.length; i++) {
- if (powerUp[i].name === 'ammo') isAmmo = true
- }
- if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
- powerUps.directSpawn(1300, -2000, "ammo", false);
- powerUps.directSpawn(1301, -2200, "ammo", false);
- }
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (mob.length > 0) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //ammo tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.4)"
- ctx.fillRect(1250, -2800, 100, 2200)
- };
-
- if (m.health < 1) {
- powerUps.directSpawn(1298, -3500, "heal", false, 23);
- powerUps.directSpawn(1305, -3000, "heal", false, 35);
- }
- for (let i = 0; i < 3; i++) {
- spawn.hopper(1300 + i, -3000 - 2000 * i, 25 + 5 * i)
- // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
- }
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
- spawn.mapRect(1350, -2800, 675, 2200);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- spawn.mapRect(1600, -600, 425, 250);
- },
- superBall() { //throw a block on button to open door
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
- b.giveGuns("super balls")
- // b.guns[b.activeGun].ammo = 0
- // simulation.updateGunHUD();
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- let instruction = 0
- level.trainingText(`use
super balls to clear the room of mobs`)
-
- level.custom = () => {
- if (instruction === 0 && mob.length === 0) {
- instruction++
- level.trainingText(`
use super balls to clear the room of mobs`)
- }
- //spawn ammo if you run out
- let isAmmo = false
- for (let i = 0; i < powerUp.length; i++) {
- if (powerUp[i].name === 'ammo') isAmmo = true
- }
- if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
- powerUps.directSpawn(1300, -2000, "ammo", false);
- powerUps.directSpawn(1301, -2200, "ammo", false);
- }
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (mob.length > 0) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //ammo tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.2)"
- // ctx.fillRect(1225, -2800, 125, 2450)
- ctx.fillRect(-150, -2800, 1500, 2450);
- };
-
- if (m.health < 1) {
- powerUps.directSpawn(1298, -3500, "heal", false, 23);
- powerUps.directSpawn(1305, -3000, "heal", false, 35);
- }
- for (let i = 0; i < 6; i++) {
- spawn.spawner(i * 230, -800)
- // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
- }
- spawn.mapVertex(510, -430, "725 0 725 80 -650 80 -650 -80 650 -80"); //upper room with mobs
- spawn.mapRect(-225, -2800, 1450, 2000);
- spawn.mapRect(1350, -2800, 675, 2450);
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- matterWave() { //throw a block on button to open door
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
- b.giveGuns("matter wave")
- // b.guns[b.activeGun].ammo = 0
- // simulation.updateGunHUD();
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- let instruction = 0
- level.trainingText(`use
matter wave to clear the room of mobs`)
-
- level.custom = () => {
- if (instruction === 0 && mob.length === 0) {
- instruction++
- level.trainingText(`
use matter wave to clear the room of mobs`)
- }
- //spawn ammo if you run out
- let isAmmo = false
- for (let i = 0; i < powerUp.length; i++) {
- if (powerUp[i].name === 'ammo') isAmmo = true
- }
- if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
- powerUps.directSpawn(1300, -2000, "ammo", false);
- powerUps.directSpawn(1301, -2200, "ammo", false);
- }
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- if (mob.length > 0) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //ammo tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.2)"
- // ctx.fillRect(1225, -2800, 125, 2450)
- ctx.fillRect(-150, -2800, 1500, 2450);
- };
-
- if (m.health < 1) {
- powerUps.directSpawn(1298, -3500, "heal", false, 23);
- powerUps.directSpawn(1305, -3000, "heal", false, 35);
- }
- for (let i = 0; i < 6; i++) {
- spawn.springer(i * 200, -800)
- // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
- }
- spawn.springer(1825, -330, 20);
-
- spawn.mapRect(1125, -850, 100, 500); //upper room with mobs
- spawn.mapRect(-225, -450, 1450, 100);
- spawn.mapRect(-225, -2800, 1450, 2000);
- spawn.mapRect(1350, -2800, 675, 2450);
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
- missile() { //throw a block on button to open door
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 30); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
- b.giveGuns("missiles")
- // b.guns[b.activeGun].ammo = 0
- // simulation.updateGunHUD();
- const buttonDoor = level.button(2500, 50)
- const door = level.door(1612.5, -175, 25, 190, 185, 3)
- let instruction = 0
- level.trainingText(`use
missiles to drop a
block on the button`)
-
- level.custom = () => {
- if (instruction === 0 && mob.length === 0) {
- instruction++
- level.trainingText(`
use missiles to drop a block on the button`)
- }
- //spawn ammo if you run out
- let isAmmo = false
- for (let i = 0; i < powerUp.length; i++) {
- if (powerUp[i].name === 'ammo') isAmmo = true
- }
- if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
- powerUps.directSpawn(1300, -2000, "ammo", false);
- powerUps.directSpawn(1301, -2200, "ammo", false);
- }
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- buttonDoor.query();
- buttonDoor.draw();
- if (buttonDoor.isUp) {
- door.isClosing = true
- } else {
- door.isClosing = false
- }
- door.openClose();
- door.draw();
-
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- //tunnel shadow
- ctx.fillStyle = "rgba(0,0,0,0.4)"
- ctx.fillRect(1250, -2800, 100, 2200)
- ctx.fillRect(1550, 25, 475, 25);
- };
- if (m.health < 1) {
- powerUps.directSpawn(1298, -3500, "heal", false, 23);
- powerUps.directSpawn(1305, -3000, "heal", false, 35);
- }
- for (let i = 0; i < 10; i++) {
- spawn.springer(2100 + i * 100, -250)
- // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
- }
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- // spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(3050, -2800, 1550, 4600);
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
- spawn.mapRect(1350, -2800, 675, 2200);
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- // spawn.mapRect(1350, 0, 675, 30);
- spawn.mapRect(1550, 0, 475, 35);
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- spawn.mapRect(1600, -600, 425, 250);
-
- spawn.mapRect(1975, -600, 50, 625);
- spawn.mapRect(2025, -2800, 1075, 2450);
-
-
- },
- trainingTemplate() { //learn to crouch
- m.addHealth(Infinity)
- document.getElementById("health").style.display = "none" //hide your health bar
- document.getElementById("health-bg").style.display = "none"
-
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
-
- let instruction = 0
- level.trainingText(`press
${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
-
- level.custom = () => {
- if (instruction === 0 && input.down) {
- instruction++
-
- level.trainingText(`
press ${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
- }
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
- spawn.mapRect(-250, 50, 3500, 1750); //floor
- spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(1575, 0, 500, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- spawn.mapRect(725, 12, 50, 25);
- spawn.mapRect(725, 25, 75, 25);
- spawn.mapRect(750, 38, 75, 25);
- spawn.mapRect(1525, 25, 75, 50);
- spawn.mapRect(1500, 38, 50, 25);
- spawn.mapRect(1550, 12, 50, 25);
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
- spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
- },
custom() {},
customTopLayer() {},
setDifficulty() {
@@ -1685,13 +580,13 @@ const level = {
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
density: density,
isNotHoldable: true,
- isComposite: true
+ isNonStick: true
});
const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, {
angle: Math.PI / 2,
density: density,
isNotHoldable: true,
- isComposite: true
+ isNonStick: true
});
rotor = Body.create({ //combine rotor1 and rotor2
parts: [rotor1, rotor2],
@@ -1858,6 +753,72 @@ const level = {
}
}
},
+ vanish(x, y, width, height, hide = { x: 0, y: 100 }) {
+ x = x + width / 2
+ y = y + height / 2
+ const block = body[body.length] = Bodies.rectangle(x, y, width, height, {
+ collisionFilter: {
+ category: cat.map,
+ mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ },
+ isNoSetCollision: true,
+ inertia: Infinity, //prevents rotation
+ isNotHoldable: true,
+ isNonStick: true, //this keep sporangium from sticking
+ isTouched: false,
+ fadeTime: 30,
+ fadeCount: 30,
+ isThere: true,
+ returnTime: 180,
+ returnCount: 0,
+ query() {
+ if (this.isThere) {
+ if (this.isTouched) {
+ if (!m.isBodiesAsleep) this.fadeCount--
+ if (this.fadeCount < 1) {
+ Matter.Body.setPosition(this, hide)
+ this.isThere = false
+ this.isTouched = false
+ this.collisionFilter.mask = 0 //cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ this.returnCount = this.returnTime
+ }
+ } else if (Matter.Query.collides(this, [player]).length) { // || (Matter.Query.collides(this, body).length)) {
+ this.isTouched = true
+ this.fadeCount = this.fadeTime;
+ }
+ } else {
+ if (!m.isBodiesAsleep) {
+ this.returnCount--
+ if (this.returnCount < 1) {
+ Matter.Body.setPosition(this, { x: x, y: y })
+ if (Matter.Query.collides(this, [player]).length) { //|| (Matter.Query.collides(this, body).length)) {
+ Matter.Body.setPosition(this, hide)
+ this.returnCount = 15
+ } else {
+ this.isThere = true
+ this.collisionFilter.mask = cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ this.fadeCount = this.fadeTime
+ }
+ }
+ }
+ }
+ ctx.beginPath();
+ const v = this.vertices;
+ ctx.moveTo(v[0].x, v[0].y);
+ for (let i = 1; i < v.length; ++i) ctx.lineTo(v[i].x, v[i].y);
+ ctx.lineTo(v[0].x, v[0].y);
+ const color = 220 * (1 - this.fadeCount / this.fadeTime)
+ ctx.fillStyle = `rgb(${color},220, 200)`
+ // ctx.fillStyle = `rgba(0,220,200,${this.fadeCount/this.fadeTime+0.05})`
+ ctx.fill();
+ // ctx.strokeStyle = `#bff`
+ // ctx.stroke();
+ },
+ });
+ Matter.Body.setStatic(block, true); //make static
+ Composite.add(engine.world, block); //add to world
+ return block
+ },
door(x, y, width, height, distance, speed = 1) {
x = x + width / 2
y = y + height / 2
@@ -3419,8 +2380,17 @@ const level = {
level.customTopLayer = () => {
button.query();
button.draw();
+ vanish1.query();
+ vanish2.query();
+ vanish3.query();
+ vanish4.query();
+ vanish5.query();
};
-
+ const vanish1 = level.vanish(1400, -200, 200, 50) //x, y, width, height, hide = { x: 0, y: 0 } //hide should just be somewhere behind the map so the player can't see it
+ const vanish2 = level.vanish(1825, -150, 150, 150) //x, y, width, height, hide = { x: 0, y: 0 } //hide should just be somewhere behind the map so the player can't see it
+ const vanish3 = level.vanish(1975, -150, 150, 150) //x, y, width, height, hide = { x: 0, y: 0 } //hide should just be somewhere behind the map so the player can't see it
+ const vanish4 = level.vanish(1825, -300, 150, 150) //x, y, width, height, hide = { x: 0, y: 0 } //hide should just be somewhere behind the map so the player can't see it
+ const vanish5 = level.vanish(1975, -300, 150, 150) //x, y, width, height, hide = { x: 0, y: 0 } //hide should just be somewhere behind the map so the player can't see it
level.setPosToSpawn(0, -450); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = 6500;
@@ -3473,7 +2443,7 @@ const level = {
spawn.mapRect(4850, -275, 50, 175);
//???
- level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
+ level.difficultyIncrease(1) //30 is near max on hard //60 is near max on why
m.addHealth(Infinity)
// spawn.starter(1900, -500, 200) //big boy
@@ -3494,7 +2464,7 @@ const level = {
// spawn.launcherBoss(3200, -500)
// spawn.blockBoss(1700, -500)
// spawn.blinkBoss(3200, -500)
- spawn.mantisBoss(1700, -500)
+ // spawn.mantisBoss(1700, -500)
// spawn.tetherBoss(1700, -500) //go to actual level?
// spawn.revolutionBoss(1900, -500)
// spawn.bomberBoss(1400, -500)
@@ -5135,9 +4105,9 @@ const level = {
}
} else if (!elevator1.isOn) {
elevator1.isOn = true
- elevator1.isUp = true
+ elevator1.isUp = false
elevator1.removeConstraint();
- elevator1.frictionAir = 0.01 //elevator.isUp ? 0.01 : 0.2
+ elevator1.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
}
if (elevator1.isOn) {
elevator1.move();
@@ -5158,9 +4128,9 @@ const level = {
}
} else if (!elevator2.isOn) {
elevator2.isOn = true
- elevator2.isUp = true
+ elevator2.isUp = false
elevator2.removeConstraint();
- elevator2.frictionAir = 0.01 //elevator.isUp ? 0.01 : 0.2
+ elevator2.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
}
if (elevator2.isOn) {
@@ -5337,9 +4307,9 @@ const level = {
}
} else if (!elevator1.isOn) {
elevator1.isOn = true
- elevator1.isUp = true
+ elevator1.isUp = false
elevator1.removeConstraint();
- elevator1.frictionAir = 0.01 //elevator.isUp ? 0.01 : 0.2
+ elevator1.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
}
if (elevator1.isOn) {
elevator1.move();
@@ -5359,9 +4329,9 @@ const level = {
}
} else if (!elevator2.isOn) {
elevator2.isOn = true
- elevator2.isUp = true
+ elevator2.isUp = false
elevator2.removeConstraint();
- elevator2.frictionAir = 0.01 //elevator.isUp ? 0.01 : 0.2
+ elevator2.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
}
if (elevator2.isOn) {
@@ -9309,4 +8279,1454 @@ const level = {
initialSpawn == true;
}
},
+ // ********************************************************************************************************
+ // ********************************************************************************************************
+ // ***************************************** training levels **********************************************
+ // ********************************************************************************************************
+ // ********************************************************************************************************
+ walk() { //learn to walk
+ m.addHealth(Infinity)
+ document.getElementById("health").style.display = "none" //hide your health bar
+ document.getElementById("health-bg").style.display = "none"
+
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ simulation.lastLogTime = 0; //clear previous messages
+ let instruction = 0
+ level.trainingText(`move
↔ with
${input.key.left.replace('Key', '').replace('Digit', '')} and
${input.key.right.replace('Key', '').replace('Digit', '')}`)
+
+ level.custom = () => {
+ if (instruction === 0 && input.right) {
+ instruction++
+ level.trainingText(`
move ↔ with ${input.key.left.replace('Key', '').replace('Digit', '')} and ${input.key.right.replace('Key', '').replace('Digit', '')}
+
exit through the blue door`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+ spawn.mapRect(700, -8, 50, 25);
+ spawn.mapRect(725, -16, 75, 25);
+ spawn.mapRect(1375, -16, 50, 50);
+ spawn.mapRect(1400, -8, 50, 25);
+ spawn.mapRect(750, -24, 650, 100);
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ crouch() { //learn to crouch
+ m.addHealth(Infinity)
+ level.setPosToSpawn(75, -100); //normal spawn
+ spawn.mapRect(25, -60, 100, 20); //small platform for player
+ spawn.mapRect(0, -50, 150, 25); //stairs
+ spawn.mapRect(-25, -40, 200, 25);
+ spawn.mapRect(-50, -30, 250, 25);
+ spawn.mapRect(-75, -20, 300, 25);
+ spawn.mapRect(-100, -10, 350, 25);
+ spawn.mapRect(-150, -50, 175, 75);
+
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ let instruction = 0
+ level.trainingText(`press
${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
+ level.custom = () => {
+ if (instruction === 0 && input.down) {
+ instruction++
+ level.trainingText(`
press ${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1625, -350, 375, 350)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1625, -350, 375, 350)
+ //dark
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ ctx.fillRect(500, -100, 1125, 175);
+ };
+
+ // spawn.mapRect(1025, -675, 300, 623); //crouch wall
+ // spawn.mapRect(625, -650, 1025, 550);
+ spawn.mapRect(500, -650, 1125, 550);
+ spawn.mapRect(-200, -650, 875, 300);
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ },
+ jump() { //learn to jump
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ let instruction = 0
+ level.trainingText(`hold down
${input.key.up.replace('Key', '').replace('Digit', '')} longer to jump higher`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.pos.x > 300) {
+ instruction++
+ level.trainingText(`
hold down ${input.key.up.replace('Key', '').replace('Digit', '')} longer to jump higher`)
+ }
+ m.health = 1 //can't die
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //dark
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ ctx.fillRect(1000, 0, 450, 1800)
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(275, -350, 200, 375);
+ spawn.mapRect(-250, 0, 1250, 1800); //floor
+ spawn.mapRect(1450, 0, 1075, 1800); //floor
+ spawn.mapRect(-250, -2800, 1250, 2200); //roof
+ spawn.mapRect(1450, -2800, 1075, 2200); //roof
+ spawn.mapVertex(375, 0, "150 0 -150 0 -100 -50 100 -50"); //base
+
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+
+ //roof steps
+ spawn.mapRect(1000, -650, 25, 25);
+ spawn.mapRect(1000, -675, 50, 25);
+ spawn.mapRect(1000, -700, 75, 25);
+ spawn.mapRect(1000, -725, 100, 25);
+ spawn.mapRect(1425, -650, 25, 25);
+ spawn.mapRect(1400, -675, 50, 25);
+ spawn.mapRect(1375, -700, 75, 25);
+ spawn.mapRect(1350, -725, 100, 25);
+ spawn.mapRect(1325, -750, 150, 25);
+ spawn.mapRect(1300, -775, 150, 25);
+ spawn.mapRect(1000, -750, 125, 25);
+ spawn.mapRect(1275, -2800, 200, 2025);
+ spawn.mapRect(975, -2800, 200, 2025);
+ spawn.mapRect(1000, -775, 150, 25);
+ },
+ hold() { //put block on button to open door
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ spawn.bodyRect(1025, -75, 50, 50); //block to go on button
+ const buttonDoor = level.button(500, 0)
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+
+ let instruction = 0
+ level.trainingText(`activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse`)
+
+ level.custom = () => {
+ if (instruction === 0 && input.field) {
+ instruction++
+ level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouserelease your
field on a
block to pick it up`)
+ } else if (instruction === 1 && m.isHolding) {
+ instruction++
+ level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
release your field on a block to pick it updrop the
block on the red button to open the door`)
+ } else if (instruction === 2 && !buttonDoor.isUp && Vector.magnitudeSquared(Vector.sub(body[0].position, buttonDoor.min)) < 10000) {
+ instruction++
+ level.trainingText(`
activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
release your field on a block to pick it up
drop the block on the red button to open the door`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ throw () { //throw a block on button to open door
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ spawn.bodyRect(1025, -75, 50, 50); //block to go on button
+ const buttonDoor = level.button(1635, -400)
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+
+ // activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse
+ let instruction = 0
+ level.trainingText(`pick up the
block with your
field`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.isHolding) {
+ instruction++
+ level.trainingText(`
pick up the block with your field
+
hold your
field down to charge up then release to throw a
block`)
+ } else if (instruction === 1 && m.throwCharge > 2) {
+ instruction++
+ level.trainingText(`
pick up the block with your field
+
hold your field down to charge up then release to throw a block
+
throw the
block onto the button`)
+ // the
block at the button
+ } else if (instruction === 2 && !buttonDoor.isUp && Vector.magnitudeSquared(Vector.sub(body[0].position, buttonDoor.min)) < 10000) {
+ instruction++
+ level.trainingText(`
pick up the block with your field
+
hold your field down to charge up then release to throw a block
+
throw the block onto the button`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ // spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1790, -600, 250, 225); //button left wall
+ spawn.mapRect(1625, -400, 400, 50);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ throwAt() { //throw a block at mob to open door
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+
+ let instruction = 0
+ level.trainingText(`throw the
block at the
mobs to open the door`)
+
+ level.custom = () => {
+ if (instruction === 0 && !mob.length) {
+ instruction++
+ level.trainingText(`
throw the block at the mobs to open the door`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ // spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ // spawn.mapRect(1790, -600, 250, 225); //button left wall
+ // spawn.mapRect(1625, -400, 400, 50);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+
+ spawn.bodyRect(1025, -75, 50, 50); //block to go on button
+ spawn.starter(425, -350, 35)
+ spawn.starter(800, -350, 44)
+ },
+ fire() { //throw a block at mob to open door
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = 15;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ const door = level.door(1612.5, -125, 25, 190, 185, 3)
+ const buttonDoor = level.button(400, 0)
+
+ let instruction = 0
+ level.trainingText(`use your
field to pick up the gun power up`)
+
+ level.custom = () => {
+ if (instruction === 0 && simulation.isChoosing) {
+ instruction++
+ level.trainingText(`
use your field to pick up the gun power up
+
choose a
gun`)
+ } else if (instruction === 1 && !simulation.isChoosing) {
+ instruction++
+ level.trainingText(`
use your field to pick up the gun power up
+
choose a gun
+
use the
left mouse button to shoot the
mobs`)
+ } else if (instruction === 2 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use your field to pick up the gun power up
+
choose a gun
+
use the left mouse button to shoot the mobs
+
drop a
block on the red button to open the door`)
+ } else if (instruction === 3 && !door.isClosing) {
+ instruction++
+ level.trainingText(`
use your field to pick up the gun power up
+
choose a gun
+
use the left mouse button to shoot the mobs
+
put a block on the red button to open the door`)
+ }
+ //spawn ammo if you run out
+ if (!powerUp.length && b.inventory.length && b.guns[b.activeGun].ammo === 0) powerUps.directSpawn(1300, -2000, "ammo", false);
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -350, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -350, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ //ceiling steps
+ spawn.mapRect(725, -588, 50, 25);
+ spawn.mapRect(725, -600, 75, 25);
+ spawn.mapRect(750, -612, 75, 25);
+ spawn.mapRect(-275, -650, 1025, 87);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+
+ spawn.mapRect(1600, -600, 425, 300);
+ spawn.mapRect(1600, -400, 50, 275);
+
+ powerUps.directSpawn(1300, -1500, "gun", false);
+ spawn.starter(900, -300, 35)
+ spawn.starter(1400, -400, 44)
+ },
+ deflect() { //learn to jump
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ let instruction = 0
+ // activate your
field with
${input.key.field.replace('Key', '').replace('Digit', '')} or
right mouse
+ level.trainingText(`use your
field to
deflect the
mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.pos.x > 1350) {
+ instruction++
+ level.trainingText(`
use your field to deflect the mobs`)
+ }
+ //teleport to start if hit
+ if (m.immuneCycle > m.cycle) {
+ m.energy = m.maxEnergy
+ Matter.Body.setPosition(player, { x: 60, y: -50 })
+ }
+ //spawn bullets
+ if (!(simulation.cycle % 5)) {
+ spawn.sniperBullet(660 + 580 * Math.random(), -2000, 10, 4);
+ const who = mob[mob.length - 1]
+ Matter.Body.setVelocity(who, { x: 0, y: 8 });
+ who.timeLeft = 300
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //dark
+ ctx.fillStyle = "rgba(0,0,0,0.05)"
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //center falling bullets
+ ctx.fillStyle = "rgba(255,0,255,0.013)" //pink?
+ ctx.fillRect(650, -2800, 600, 2800)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+
+ spawn.mapRect(-250, 0, 3000, 1800); //floor
+ spawn.mapRect(-250, -2800, 900, 2200); //roof
+ spawn.mapRect(1250, -2800, 1275, 2200); //roof
+ spawn.mapVertex(950, 0, "400 0 -400 0 -300 -50 300 -50"); //base
+
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+
+ //spawn bullets on load to avoid rush
+ for (let i = 0; i < 32; i++) {
+ spawn.sniperBullet(660 + 580 * Math.random(), -2000 + 40 * i, 10, 4);
+ const who = mob[mob.length - 1]
+ Matter.Body.setVelocity(who, { x: 0, y: 8 });
+ who.timeLeft = 300
+ }
+ },
+ heal() { //learn to heal
+ m.addHealth(Infinity)
+ m.health = 0;
+ m.addHealth(0.25)
+ document.getElementById("health").style.display = "inline" //show your health bar
+ document.getElementById("health-bg").style.display = "inline"
+
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ let instruction = 0
+ level.trainingText(`your
health is displayed in the top left corner
+
use your
field to pick up
until your
health is full`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.health === 1) {
+ instruction++
+ level.trainingText(`
use your field to pick up until your health is full`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (m.health !== 1) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+ spawn.mapRect(700, -8, 50, 25);
+ spawn.mapRect(725, -16, 75, 25);
+ spawn.mapRect(1375, -16, 50, 50);
+ spawn.mapRect(1400, -8, 50, 25);
+ spawn.mapRect(750, -24, 650, 100);
+ powerUps.directSpawn(875, -40, "heal", false, null, 15);
+ powerUps.directSpawn(1075, -50, "heal", false, null, 25);
+ powerUps.directSpawn(1275, -65, "heal", false, null, 35);
+
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ nailGun() {
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("nail gun")
+ b.guns[b.activeGun].ammo = 0
+ simulation.updateGunHUD();
+
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use your
field to pick up
for your
nail gun`)
+
+ level.custom = () => {
+ if (instruction === 0 && b.inventory.length && b.guns[b.activeGun].ammo > 0) {
+ instruction++
+ level.trainingText(`
use your field to pick up for your nail gun
+
use the
left mouse button to shoot the
mobs`)
+ } else if (instruction === 1 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use your field to pick up for your nail gun
+
use the left mouse button to shoot the mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 2; i++) {
+ spawn.spinner(1300 + i, -3000 - 200 * i, 25 + 5 * i)
+ Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 62 });
+ }
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ // spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ // spawn.mapRect(1790, -600, 250, 225); //button left wall
+ // spawn.mapRect(1625, -400, 400, 50);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+ },
+ shotGun() {
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("shotgun")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use your
shotgun to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use your shotgun to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 3; i++) {
+ spawn.hopper(1300 + i, -3000 - 2000 * i, 25 + 5 * i)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+ },
+ superBall() {
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("super balls")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use
super balls to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use super balls to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ // ctx.fillRect(1225, -2800, 125, 2450)
+ ctx.fillRect(-150, -2800, 1500, 2450);
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 6; i++) {
+ spawn.spawner(i * 230, -800)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.mapVertex(510, -430, "725 0 725 80 -650 80 -650 -80 650 -80"); //upper room with mobs
+ spawn.mapRect(-225, -2800, 1450, 2000);
+ spawn.mapRect(1350, -2800, 675, 2450);
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ matterWave() { //fire matter wave through the map to kill mosb
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("matter wave")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use
matter wave to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use matter wave to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ // ctx.fillRect(1225, -2800, 125, 2450)
+ ctx.fillRect(-150, -2800, 1500, 2450);
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 6; i++) {
+ spawn.springer(i * 200, -800)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.springer(1825, -330, 20);
+
+ spawn.mapRect(1175, -850, 50, 500); //upper room with mobs
+ spawn.mapRect(-225, -400, 1450, 50);
+ spawn.mapRect(-225, -2800, 1450, 2000);
+ spawn.mapRect(1350, -2800, 675, 2450);
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ missile() { //fire a missile to kill mobs and trigger button
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 30); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("missiles")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const buttonDoor = level.button(2500, 50)
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use
missiles to drop a
block on the button`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`
use missiles to drop a block on the button`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ ctx.fillRect(1550, 25, 475, 25);
+ };
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 10; i++) {
+ spawn.springer(2100 + i * 100, -250)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ // spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(3050, -2800, 1550, 4600);
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ // spawn.mapRect(1350, 0, 675, 30);
+ spawn.mapRect(1550, 0, 475, 35);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+
+ spawn.mapRect(1975, -600, 50, 625);
+ spawn.mapRect(2025, -2800, 1075, 2450);
+ },
+ stack() { //stack blocks to get to exit
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -685;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ let instruction = 0
+ level.trainingText(`use your
field to stack the
blocks`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.pos.x > 1635) {
+ instruction++
+ level.trainingText(`
use your field to stack the blocks`)
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -1050, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -1050, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(250, -2800, 200, 1800)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(298, -3500, "heal", false, 23);
+ powerUps.directSpawn(305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 15; i++) {
+ spawn.bodyRect(280, -2000 - 500 * i, 30 + 80 * Math.random(), 30 + 80 * Math.random());
+ }
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+ spawn.mapRect(1600, -650, 450, 775);
+ spawn.mapRect(-150, -2800, 400, 1800); //roof with tunnel for ammo
+ spawn.mapRect(450, -2800, 1675, 1800);
+ spawn.mapVertex(1300, 0, "400 0 -500 0 -300 -125 400 -125"); //base
+ },
+ mine() { //kill mobs and tack their bodies
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(300, -50); //normal spawn
+ spawn.mapRect(250, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -685;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("mine")
+
+ let instruction = 0
+ level.trainingText(`press the red
button to spawn a
mob`)
+ const button = level.button(-100, -200)
+ button.isUp = true
+ spawn.mapRect(-150, -200, 240, 425);
+
+ level.custom = () => {
+ if (instruction === 0 && !button.isUp) {
+ instruction++
+ level.trainingText(`
press the red button to spawn a mobturn the
mobs into
blocks`)
+ } else if (instruction === 1 && body.length > 2) {
+ instruction++
+ level.trainingText(`
press the red button to spawn a mob
turn the mobs into blocksuse your
field to stack the
blocks`)
+ } else if (instruction === 2 && m.pos.x > 1635) {
+ instruction++
+ level.trainingText(`
press the red button to spawn a mob
turn the mobs into blocks
use your field to stack the blocks`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -1050, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ button.query();
+ button.draw();
+ if (!button.isUp) {
+ if (button.isReady) {
+ button.isReady = false
+ spawn.exploder(335, -1700)
+ Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 20 });
+ ctx.fillStyle = "rgba(255,0,0,0.9)"
+ ctx.fillRect(550, -2800, 200, 1800)
+ }
+ } else {
+ button.isReady = true
+ }
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -1050, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(550, -2800, 200, 1800)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(298, -3500, "heal", false, 23);
+ powerUps.directSpawn(305, -3000, "heal", false, 35);
+ }
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+ spawn.mapRect(1600, -650, 450, 775);
+ spawn.mapRect(-150, -2800, 700, 1800); //roof with tunnel for ammo
+ spawn.mapRect(750, -2800, 1675, 1800);
+ spawn.mapVertex(1300, 0, "400 0 -600 0 -300 -125 400 -125"); //base
+ },
+ grenades() { //jump at the top of the elevator's path to go extra high
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(0, -50); //normal spawn
+ spawn.mapRect(-50, -10, 100, 20); //small platform for player
+ level.exit.x = 1900;
+ level.exit.y = -2835;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("grenades")
+
+ const elevator1 = level.elevator(550, -100, 180, 25, -840, 0.003, { up: 0.05, down: 0.2 }) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
+ elevator1.addConstraint();
+ const toggle1 = level.toggle(275, 0) //(x,y,isOn,isLockOn = true/false)
+
+ const elevator2 = level.elevator(1400, -950, 180, 25, -2400, 0.0025) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
+ elevator2.addConstraint();
+ const button2 = level.button(1000, -850)
+
+ let instruction = 0
+ level.trainingText(`flip the
switch to turn on the
elevator`)
+ level.custom = () => {
+ if (instruction === 0 && elevator1.isOn) {
+ instruction++
+ level.trainingText(`
flip the switch to turn on the elevator
+
put a
block on the
button to active the
elevator`)
+ } else if (instruction === 1 && elevator2.isOn) {
+ instruction++
+ level.trainingText(`
flip the switch to turn on the elevator
put a block on the button to active the elevator
+
hold
jump before the
elevator's apex to reach the
exit`)
+ } else if (instruction === 2 && m.pos.x > 1635) {
+ instruction++
+ level.trainingText(`
flip the switch to turn on the elevator
put a block on the button to active the elevator
hold jump before the elevator's apex to reach the exit`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1725, -3100, 375, 300);
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ toggle1.query();
+ if (!toggle1.isOn) {
+ if (elevator1.isOn) {
+ elevator1.isOn = false
+ elevator1.frictionAir = 0.2
+ elevator1.addConstraint();
+ }
+ } else if (!elevator1.isOn) {
+ elevator1.isOn = true
+ elevator1.isUp = false
+ elevator1.removeConstraint();
+ elevator1.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
+ }
+ if (elevator1.isOn) {
+ elevator1.move();
+ ctx.fillStyle = "#444"
+ } else {
+ ctx.fillStyle = "#aaa"
+ }
+ ctx.fillRect(640, -825, 1, 745)
+
+ button2.query();
+ button2.draw();
+ if (button2.isUp) {
+ if (elevator2.isOn) {
+ elevator2.isOn = false
+ elevator2.frictionAir = 0.2
+ elevator2.addConstraint();
+ }
+ } else if (!elevator2.isOn) {
+ elevator2.isOn = true
+ elevator2.isUp = false
+ elevator2.removeConstraint();
+ elevator2.frictionAir = 0.2 //elevator.isUp ? 0.01 : 0.2
+ }
+ if (elevator2.isOn) {
+ elevator2.move();
+ ctx.fillStyle = "#444"
+ } else {
+ ctx.fillStyle = "#aaa"
+ }
+ ctx.fillRect(1490, -2300, 1, 1375)
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1725, -3100, 375, 300);
+ //shadows
+ ctx.fillStyle = "rgba(0,0,0,0.05)"
+ ctx.fillRect(-150, -250, 300, 250);
+ let grd = ctx.createLinearGradient(0, -150, 0, -2300);
+ grd.addColorStop(0, "rgba(0,0,0,0.35)");
+ grd.addColorStop(1, "rgba(0,0,0,0)");
+ ctx.fillStyle = grd //"rgba(0,0,100,0.01)"
+ ctx.fillRect(-200, -2300, 1825, 2300);
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(298, -3500, "heal", false, 23);
+ powerUps.directSpawn(305, -3000, "heal", false, 35);
+ }
+ spawn.mapRect(-2750, -4800, 2600, 6600); //left wall
+ spawn.mapRect(1600, -2800, 3000, 4600); //right wall
+ spawn.mapRect(-150, -4800, 300, 4550);
+ spawn.mapRect(2125, -4775, 2475, 2050);
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+ spawn.mapRect(750, -850, 950, 950);
+ spawn.mapRect(125, -275, 25, 100);
+ spawn.mapRect(2100, -3150, 50, 350);
+ spawn.mapRect(1725, -3150, 50, 175);
+ spawn.mapRect(1725, -3150, 425, 50);
+
+ spawn.nodeGroup(1200, -1500, "grenadier", 7);
+ },
+ harpoon() { //jump at the top of the elevator's path to go extra high
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(0, -50); //normal spawn
+ spawn.mapRect(-50, -10, 100, 20); //small platform for player
+ level.exit.x = 1900;
+ level.exit.y = -2835;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("harpoon")
+
+
+ let instruction = 0
+ level.trainingText(`climb up to the exit`)
+ level.custom = () => {
+ if (instruction === 0 && m.pos.x > 1635) {
+ instruction++
+ level.trainingText(`
climb up to the exit`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1725, -3100, 375, 300);
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1725, -3100, 375, 300);
+ //shadows
+ ctx.fillStyle = "rgba(0,90,100,0.05)"
+ ctx.fillRect(-150, -250, 300, 250);
+ let grd = ctx.createLinearGradient(0, -150, 0, -2300);
+ grd.addColorStop(0, "rgba(0,90,100,0.35)");
+ grd.addColorStop(1, "rgba(0,90,100,0)");
+ ctx.fillStyle = grd //"rgba(0,0,100,0.01)"
+ ctx.fillRect(-200, -2300, 1825, 2300);
+ vanish1.query();
+ vanish2.query();
+ vanish3.query();
+ vanish4.query();
+ vanish5.query();
+ vanish6.query();
+ vanish7.query();
+ vanish8.query();
+ vanish9.query();
+ vanish10.query();
+ vanish11.query();
+ vanish12.query();
+ };
+ const vanish1 = level.vanish(175, -325, 175, 25); //x, y, width, height, hide = { x: 0, y: 100 } //hide should just be somewhere behind the map so the player can't see it
+ const vanish2 = level.vanish(525, -625, 175, 25);
+ const vanish3 = level.vanish(1125, -1125, 175, 25);
+ const vanish4 = level.vanish(1500, -1450, 100, 25);
+ const vanish5 = level.vanish(1125, -1675, 175, 25);
+ const vanish6 = level.vanish(750, -1950, 175, 25);
+ const vanish7 = level.vanish(550, -1950, 175, 25);
+ const vanish8 = level.vanish(350, -1950, 175, 25);
+ const vanish9 = level.vanish(150, -1950, 175, 25);
+ const vanish10 = level.vanish(325, -2300, 200, 25);
+ const vanish11 = level.vanish(725, -2550, 100, 25);
+ const vanish12 = level.vanish(1125, -2700, 150, 25);
+
+ if (m.health < 1) {
+ powerUps.directSpawn(298, -3500, "heal", false, 23);
+ powerUps.directSpawn(305, -3000, "heal", false, 35);
+ }
+ spawn.mapRect(-2750, -4800, 2600, 6600); //left wall
+ spawn.mapRect(1600, -2800, 3000, 4600); //right wall
+ spawn.mapRect(-150, -4800, 300, 4550);
+ spawn.mapRect(2125, -4775, 2475, 2050);
+ spawn.mapRect(-250, 0, 3500, 1800); //floor
+ spawn.mapRect(750, -850, 950, 950);
+ spawn.mapRect(125, -275, 25, 100);
+ spawn.mapRect(2100, -3150, 50, 350);
+ spawn.mapRect(1725, -3150, 50, 175);
+ spawn.mapRect(1725, -3150, 425, 50);
+
+ spawn.grower(250, -375);
+ spawn.grower(1000, -900)
+ spawn.grower(1475, -925);
+ spawn.grower(275, -2000);
+ spawn.grower(650, -2000);
+ spawn.grower(1475, -975);
+ spawn.grower(1575, -1525);
+ spawn.grower(1700, -2850);
+ },
+ trainingTemplate() { //learn to crouch
+ m.addHealth(Infinity)
+ document.getElementById("health").style.display = "none" //hide your health bar
+ document.getElementById("health-bg").style.display = "none"
+
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+
+ let instruction = 0
+ level.trainingText(`press
${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
+
+ level.custom = () => {
+ if (instruction === 0 && input.down) {
+ instruction++
+
+ level.trainingText(`
press ${input.key.down.replace('Key', '').replace('Digit', '')} to crouch`)
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-250, -2800, 3500, 2200); //roof
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
};
\ No newline at end of file
diff --git a/js/simulation.js b/js/simulation.js
index 8799432..d2b8bb0 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -593,6 +593,7 @@ const simulation = {
}, 1000);
},
startGame(isBuildRun = false, isTrainingRun = false) {
+ simulation.isTextLogOpen = true
simulation.clearMap()
if (!isBuildRun) { //if a build run logic flow returns to "experiment-button").addEventListener
document.body.style.cursor = "none";
diff --git a/js/spawn.js b/js/spawn.js
index 35ce949..2cd38f9 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1146,14 +1146,14 @@ const spawn = {
powerUps.spawnRandomPowerUp(this.position.x, this.position.y) // manual power up spawn to avoid spawning too many tech with "symbiosis"
}
}
- me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.23 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
//required setup for invulnerable
me.isInvulnerable = false
me.invulnerabilityCountDown = 0
me.do = function() {
if (this.isInvulnerable) {
if (this.invulnerabilityCountDown > 0) {
- this.invulnerabilityCountDown--
+ if (!m.isBodiesAsleep) this.invulnerabilityCountDown--
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
@@ -1234,7 +1234,7 @@ const spawn = {
me.do = function() {
if (this.isInvulnerable) {
if (this.invulnerabilityCountDown > 0) {
- this.invulnerabilityCountDown--
+ if (!m.isBodiesAsleep) this.invulnerabilityCountDown--
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
@@ -1982,7 +1982,7 @@ const spawn = {
ctx.strokeStyle = "rgba(255,255,255,0.7)";
ctx.stroke();
} else if (this.invulnerabilityCountDown > 0) {
- this.invulnerabilityCountDown--
+ if (!m.isBodiesAsleep) this.invulnerabilityCountDown--
} else {
this.isInvulnerable = true
if (this.damageReduction) this.startingDamageReduction = this.damageReduction
@@ -3401,7 +3401,7 @@ const spawn = {
}
if (this.isInvulnerable) {
if (this.invulnerabilityCountDown > 0) {
- this.invulnerabilityCountDown--
+ if (!m.isBodiesAsleep) this.invulnerabilityCountDown--
//graphics //draw a super shield?
ctx.beginPath();
let vertices = this.vertices;
diff --git a/js/tech.js b/js/tech.js
index a7e9b67..3f2fc7b 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -4498,7 +4498,7 @@ const tech = {
},
{
name: "MIRV",
- description: "fire
+1 missile,
grenade, and
super balldecrease
explosion radius up to
10%",
+ description: "fire
+1 missile and
grenadedecrease
explosion radius up to
10%",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -8834,7 +8834,7 @@ const tech = {
},
{
name: "black hole cluster",
- description: `
spawn nearby
black holes`,
+ description: `spawn
30 nearby
black holes`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -8847,7 +8847,7 @@ const tech = {
const unit = { x: 1, y: 0 }
for (let i = 0; i < 30; i++) {
const where = Vector.add(m.pos, Vector.mult(Vector.rotate(unit, Math.random() * 2 * Math.PI), 2000 + 1200 * Math.random()))
- spawn.sucker(where.x, where.y, 200)
+ spawn.sucker(where.x, where.y, 140)
const who = mob[mob.length - 1]
who.locatePlayer()
// who.damageReduction = 0.2
diff --git a/todo.txt b/todo.txt
index 2a9338e..8d8cb68 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,14 +1,19 @@
******************************************************** NEXT PATCH **************************************************
-tech: super duper - fire +0-2 extra super balls
- super balls no longer part of MIRV
+new training levels "stack", "mine", "grenades", "harpoon"
-bug fix for plasma extruder interaction with doors that collide with power ups
-mantisBoss moves slower, can be damaged for longer time, has less total life, has a smaller punch range
+new map element vanish goes away after you touch it, returns in 3 seconds
+bug fixes
******************************************************** TODO ********************************************************
-merge various multi bullet tech under one name
+shrink crumble width as it fades out
+ player moves through a grid of stacked crumble blocks
+
+boss that gives nearby mobs invulnerability
+ boss is only mildly aggressive
+ repulsed by player upto a point
+ attracted to mobs
training
save training level progress as local variable
@@ -18,34 +23,17 @@ training
uses the lore voice/text code?
replace all mob clear triggers with button triggers?
tutorial rooms:
- done walk forwards and backwards
- done crouch through tunnel
- done jump over wall and gap
- look around with your mouse
- done pick up a block an drop onto a button to open door
- done fire block at button to open door
- done fire block at mob to open door
+ look around with your mouse?
easier deflecting level, with 1-2 attacking mobs
- done use field to deflect bullets
- done pick up heal power ups with field to open door
- done use a gun to kill a mob and use it's block body to activate a button to open a door
gun rooms: (different mobs type in each room)
different mobs in each room
- how to introduce shields?
+ how to introduce mob shields?
"hopper" "slasher" "shooter "grenadier" "striker" "laser" "stabber" "springer" "pulsar" "launcher" "launcherOne" "exploder" "sneaker" "sucker" "sniper" "spinner" "grower" "beamer" "focuser" "spawner" "ghoster"
- done nailgun - start with no ammo collect ammo and shoot at mobs
- done shotgun - some simple close range combat
- done superball - use 1 ammo to take out several mobs
- done matter wave - kill a mob inside a map element
- done missiles - take out mobs that are around corner and have them drop on a button
- grenades - use 1 ammo to take out a ring of mob`s
spores - use 1 ammo to take out several mobs at once, you have to block with your shield until the mobs die
drones - use mouse to bring drones around a couple corners
foam - slow boss mob, and run away
harpoon - kill one close mob, pick up ammo that is out of reach, first at several far away mobs with crouch
or just some hard melee combat
- mine - built kill zone, get mobs to follow into mine kill zone
- maybe a boss mob?
laser - reflect off walls to hit mobs
field rooms:
standing wave - bullets come from every direction
@@ -58,24 +46,21 @@ training
pilot wave - toss blocks at mobs
worm hole - teleport past lasers
puzzle/platforming rooms:
- stack blocks to get to high ground
- also make a harder version of stacking blocks
- portal rooms
- jump at the top of a elevator to jump high
- use the double constrained platforms
+ use the double constrained platforms
combat rooms:
- kill so many mobs that the mob bodies pile up and you can get over a wall by jumping on them
boss gauntlet, spawn with nothing but a few power ups and fight 10 bosses
use no gun, just bots to kil stuff
-JUNK tech disable level exit for 5 minutes
- level.disableExit = true
- setTimeout( () => {level.disableExit = false;}, 5*60000);
-
balance time dilation with bose einstein (you can freeze everything and take no damage)
code is still there, need to balance
balance with energy drain?
+overflowing energy does harm?
+ or just reduces harm reduction?
+
+make a line of constained mobs move like a snake
+ apply forces with directions determined by time and position on the snake
+
tech: basic research - heal power ups spawn as research power ups instead, and using research heals you (needs to be pretty low, like 3% health)
tech: maintenance - heals no longer spawn, but using research heals you 100%