starting level:
@@ -207,7 +244,63 @@ const build = {
document.getElementById("field-0").classList.add("build-field-selected");
document.getElementById("build-grid").style.display = "grid"
},
+ shareURL() {
+ // Create a fake textarea
+ const textAreaEle = document.createElement('textarea');
+ // Reset styles
+ textAreaEle.style.border = '0';
+ textAreaEle.style.padding = '0';
+ textAreaEle.style.margin = '0';
+
+ // Set the absolute position
+ // User won't see the element
+ textAreaEle.style.position = 'absolute';
+ textAreaEle.style.left = '-9999px';
+ textAreaEle.style.top = `0px`;
+
+ // Set the value
+ textAreaEle.value = build.generateURL();
+
+ // Append the textarea to body
+ document.body.appendChild(textAreaEle);
+
+ // Focus and select the text
+ textAreaEle.focus();
+ textAreaEle.select();
+
+ // Execute the "copy" command
+ try {
+ document.execCommand('copy');
+ } catch (err) {
+ // Unable to copy
+ } finally {
+ // Remove the textarea
+ document.body.removeChild(textAreaEle);
+ }
+ alert('n-gon build URL copied to clip board.\nPaste it into your browser address bar.')
+ },
+ generateURL() {
+ let url = "https://landgreen.github.io/sidescroller/index.html?"
+ let count = 0;
+ for (let i = 0; i < b.guns.length; i++) {
+ if (b.guns[i].have) {
+ url += `&gun${count}=${encodeURIComponent(b.guns[i].name.trim())}`
+ count++
+ }
+ }
+ count = 0;
+ for (let i = 0; i < b.mods.length; i++) {
+ for (let j = 0; j < b.mods[i].count; j++) {
+ url += `&mod${count}=${encodeURIComponent(b.mods[i].name.trim())}`
+ count++
+ }
+ }
+ url += `&field=${encodeURIComponent(mech.fieldUpgrades[mech.fieldMode].name.trim())}`
+ url += `&difficulty=${game.difficultyMode}`
+ console.log(url)
+ return url
+ },
startBuildRun() {
build.isCustomSelection = false;
b.modOnHealthChange()
diff --git a/js/level.js b/js/level.js
index a039f51..eb41ed6 100644
--- a/js/level.js
+++ b/js/level.js
@@ -15,13 +15,14 @@ const level = {
if (level.levelsCleared === 0) {
// level.difficultyIncrease(9)
// b.giveGuns("vacuum bomb")
- // mech.setField("time dilation field")
+ // mech.setField("phase decoherence field")
// mech.energy = 0.1;
- // b.giveMod("ground state");
+ // b.giveMod("negative feedback");
// b.giveMod("photovoltaics");
+ onLoadPowerUps();
- // level.intro(); //starting level
- level.testingMap();
+ level.intro(); //starting level
+ // level.testing();
// level.stronghold()
// level.bosses();
// level.satellite();
@@ -75,8 +76,7 @@ const level = {
if (game.difficulty < 1) game.difficulty = 0;
game.healScale = 1 / (1 + game.difficulty * 0.09)
},
- difficultyText() {
- let mode = document.getElementById("difficulty-select").value
+ difficultyText(mode = document.getElementById("difficulty-select").value) {
if (mode === "0") {
return "easy"
} else if (mode === "1") {
@@ -97,7 +97,7 @@ const level = {
//******************************************************************************************************************
//******************************************************************************************************************
- testingMap() {
+ testing() {
// level.difficultyIncrease(9) //level 7 on normal, level 4 on hard, level 1.2 on why?
spawn.setSpawnList();
level.defaultZoom = 1500
@@ -137,14 +137,15 @@ const level = {
spawn.mapRect(2500, -1200, 200, 750); //right wall
blockDoor(2585, -210)
spawn.mapRect(2500, -200, 200, 300); //right wall
- spawn.mapRect(4500, -1200, 200, 750); //right wall
- blockDoor(4585, -210)
- spawn.mapRect(4500, -200, 200, 300); //right wall
+ spawn.mapRect(4500, -1200, 200, 650); //right wall
+ blockDoor(4585, -310)
+ spawn.mapRect(4500, -300, 200, 400); //right wall
spawn.mapRect(6400, -1200, 400, 750); //right wall
spawn.mapRect(6400, -200, 400, 300); //right wall
spawn.mapRect(6700, -1800, 800, 2600); //right wall
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
spawn.timeSkipBoss(2900, -500)
+ spawn.randomMob(3200, -500)
},
bosses() {
@@ -193,23 +194,16 @@ const level = {
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
powerUps.spawnStartingPowerUps(600, -800);
- function blockDoor(x, y, blockSize = 58) {
- spawn.mapRect(x, y - 290, 40, 60); // door lip
- spawn.mapRect(x, y, 40, 50); // door lip
- for (let i = 0; i < 4; ++i) {
- spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
- }
- }
- blockDoor(710, -710);
+ spawn.blockDoor(710, -710);
spawn[spawn.pickList[0]](1500, -200, 150 + Math.random() * 30);
spawn.mapRect(2500, -1200, 200, 750); //right wall
- blockDoor(2585, -210)
+ spawn.blockDoor(2585, -210)
spawn.mapRect(2500, -200, 200, 300); //right wall
spawn.nodeBoss(3500, -200, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
spawn.mapRect(4500, -1200, 200, 750); //right wall
- blockDoor(4585, -210)
+ spawn.blockDoor(4585, -210)
spawn.mapRect(4500, -200, 200, 300); //right wall
spawn.lineBoss(5000, -200, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
diff --git a/js/player.js b/js/player.js
index ac06994..730bf9f 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1584,7 +1584,7 @@ const mech = {
zeroG(powerUp, this.fieldDrawRadius);
zeroG(body, this.fieldDrawRadius);
}
- if (mech.energy < 0) {
+ if (mech.energy < 0.001) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
@@ -1761,57 +1761,66 @@ const mech = {
mech.grabPowerUp();
mech.lookForPickUp();
- const DRAIN = 0.0001 + 0.00017 * player.speed
+ const DRAIN = 0.00004 + 0.00009 * player.speed
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
- if (mech.energy < 0) {
+ if (mech.energy < 0.001) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
+
+
mech.isStealth = true //isStealth disables most uses of foundPlayer()
player.collisionFilter.mask = cat.map
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, mech.fieldRange, 0, 2 * Math.PI);
- ctx.globalCompositeOperation = "destination-in"; //in or atop
- ctx.fillStyle = `rgba(255,255,255,${mech.energy*0.5})`;
- ctx.fill();
- ctx.globalCompositeOperation = "source-over";
- ctx.strokeStyle = "#000"
- ctx.lineWidth = 2;
- ctx.stroke();
+ if (!game.isTimeSkipping) {
+ // game.timeSkip(1)
+ const drawRadius = 125
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, drawRadius, 0, 2 * Math.PI);
+ ctx.fillStyle = `rgba(255,255,255,${mech.energy*0.5})`;
+ ctx.globalCompositeOperation = "destination-in"; //in or atop
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+ ctx.strokeStyle = "#000"
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, drawRadius, 0, 2 * Math.PI);
+ ctx.clip();
- let inPlayer = Matter.Query.region(mob, player.bounds)
- if (inPlayer.length > 0) {
- for (let i = 0; i < inPlayer.length; i++) {
- if (inPlayer[i].shield) {
- mech.energy -= 0.005; //shields drain player energy
- //draw outline of shield
- ctx.fillStyle = `rgba(0, 204, 255,0.6)`
- ctx.fill()
- } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) {
- inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
- mech.energy -= 0.002;
-
- //draw outline of mob in a few random locations to show blurriness
- const vertices = inPlayer[i].vertices;
- const off = 30
- for (let k = 0; k < 3; k++) {
- const xOff = off * (Math.random() - 0.5)
- const yOff = off * (Math.random() - 0.5)
- ctx.beginPath();
- ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
- for (let j = 1, len = vertices.length; j < len; ++j) {
- ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
- }
- ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
- // ctx.strokeStyle = "#000"
- // ctx.lineWidth = 1
- // ctx.stroke()
- ctx.fillStyle = "rgba(0,0,0,0.3)"
+ let inPlayer = Matter.Query.region(mob, player.bounds)
+ if (inPlayer.length > 0) {
+ for (let i = 0; i < inPlayer.length; i++) {
+ if (inPlayer[i].shield) {
+ mech.energy -= 0.005; //shields drain player energy
+ //draw outline of shield
+ ctx.fillStyle = `rgba(0, 204, 255,0.6)`
ctx.fill()
+ } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) {
+ inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
+ mech.energy -= 0.002;
+
+ //draw outline of mob in a few random locations to show blurriness
+ const vertices = inPlayer[i].vertices;
+ const off = 30
+ for (let k = 0; k < 3; k++) {
+ const xOff = off * (Math.random() - 0.5)
+ const yOff = off * (Math.random() - 0.5)
+ ctx.beginPath();
+ ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
+ for (let j = 1, len = vertices.length; j < len; ++j) {
+ ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
+ }
+ ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
+ // ctx.strokeStyle = "#000"
+ // ctx.lineWidth = 1
+ // ctx.stroke()
+ ctx.fillStyle = "rgba(0,0,0,0.3)"
+ ctx.fill()
+ }
+ break;
}
- break;
}
}
}
diff --git a/js/spawn.js b/js/spawn.js
index d011008..455ae5e 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -641,52 +641,68 @@ const spawn = {
let me = mob[mob.length - 1];
// me.stroke = "transparent"; //used for drawSneaker
me.timeSkipLastCycle = 0
- me.eventHorizon = 1600; //required for black hole
+ me.eventHorizon = 1300; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 1000) * (me.eventHorizon + 1000); //vision limit is event horizon
- me.accelMag = 0.0001 * game.accelScale;
+ me.accelMag = 0.00013 * game.accelScale;
// me.collisionFilter.mask = cat.player | cat.bullet
// me.frictionAir = 0.005;
// me.memory = 1600;
- Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.018); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () {
//applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
me.do = function () {
//keep it slow, to stop issues from explosion knock backs
- this.seePlayerByDistOrLOS();
+ this.seePlayerCheck();
+ this.attraction()
+ if (!game.isTimeSkipping) {
+ const compress = 3
+ if (this.timeSkipLastCycle < game.cycle - compress &&
+ Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
+ this.timeSkipLastCycle = game.cycle
+ game.timeSkip(compress)
- if (this.seePlayer.recall) {
- //accelerate towards the player
- const forceMag = this.accelMag * this.mass;
- const dx = this.seePlayer.position.x - this.position.x
- const dy = this.seePlayer.position.y - this.position.y
- const mag = Math.sqrt(dx * dx + dy * dy)
- this.force.x += forceMag * dx / mag;
- this.force.y += forceMag * dy / mag;
-
- if (!game.isTimeSkipping) {
this.fill = `rgba(0,0,0,${0.1+0.1*Math.random()})`
- const compress = 3
- if (this.timeSkipLastCycle < game.cycle - compress &&
- Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
- this.timeSkipLastCycle = game.cycle
- game.timeSkip(compress)
+ this.stroke = "#000"
+ this.isShielded = false;
+ this.dropPowerUp = true;
+ ctx.beginPath();
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
+ ctx.fillStyle = `rgba(255,255,255,${mech.energy*0.5})`;
+ ctx.globalCompositeOperation = "destination-in"; //in or atop
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+ ctx.beginPath();
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
+ ctx.clip();
- ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
- ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
- ctx.fill();
- ctx.strokeStyle = "#000";
- ctx.stroke();
- } else {
- ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
- ctx.fillStyle = this.fill;
- ctx.fill();
- }
+ // ctx.beginPath();
+ // ctx.arc(this.position.x, this.position.y, 9999, 0, 2 * Math.PI);
+ // ctx.fillStyle = "#000";
+ // ctx.fill();
+ // ctx.strokeStyle = "#000";
+ // ctx.stroke();
+
+ // ctx.beginPath();
+ // ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
+ // ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
+ // ctx.fill();
+ // ctx.strokeStyle = "#000";
+ // ctx.stroke();
+ } else {
+ this.isShielded = true;
+ this.dropPowerUp = false;
+ this.seePlayer.recall = false
+ this.fill = "transparent"
+ this.stroke = "transparent"
+ ctx.beginPath();
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
+ ctx.fillStyle = `rgba(0,0,0,${0.1*Math.random()})`;
+ ctx.fill();
}
}
+
this.checkStatus();
}
},
@@ -1857,6 +1873,13 @@ const spawn = {
color: "#f0f0f3"
});
},
+ blockDoor(x, y, blockSize = 58) {
+ spawn.mapRect(x, y - 290, 40, 60); // door lip
+ spawn.mapRect(x, y, 40, 50); // door lip
+ for (let i = 0; i < 4; ++i) {
+ spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
+ }
+ },
debris(x, y, width, number = Math.floor(2 + Math.random() * 9)) {
for (let i = 0; i < number; ++i) {
if (Math.random() < 0.15) {
diff --git a/todo.txt b/todo.txt
index cec10ef..e48cba6 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,6 +2,9 @@ mod - electromagnetic pulse - vacuum bomb removes shields and does 20% extra dam
************** TODO - n-gon **************
+
+mod - spores with no target hang out about player
+
mod - status effects last 1 second longer
cryonics : a mod that increases the freezing time of mobs.
wait until you have more status effects written