diff --git a/index.html b/index.html index b86a359..1251708 100644 --- a/index.html +++ b/index.html @@ -95,8 +95,7 @@ settings - combat - difficulty: + combat difficulty: easy normal diff --git a/js/bullets.js b/js/bullets.js index 89b765b..3e482c8 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -1679,21 +1679,16 @@ const b = { }, { name: "laser", //14 - description: "emit a beam of collimated coherent lightdrains energy instead of ammunition", + description: "drain energy to emit a beam of coherent lightwhen crouched, initiate a fusion explosion", ammo: 0, ammoPack: Infinity, have: false, isStarterGun: true, fire() { - const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets - const damage = 0.05 - if (mech.fieldMeter < FIELD_DRAIN) { - mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy - } else { - mech.fieldMeter -= mech.fieldRegen + FIELD_DRAIN + if (mech.crouch) { //crouch fire mode + //calculate laser collision let best; - const color = "#f00"; - const range = 3000; + let range = 3000 const path = [{ x: mech.pos.x + 20 * Math.cos(mech.angle), y: mech.pos.y + 20 * Math.sin(mech.angle) @@ -1743,54 +1738,153 @@ const b = { } } }; - const checkForCollisions = function () { - best = { - x: null, - y: null, - dist2: Infinity, - who: null, - v1: null, - v2: null - }; - vertexCollision(path[path.length - 2], path[path.length - 1], mob); - vertexCollision(path[path.length - 2], path[path.length - 1], map); - vertexCollision(path[path.length - 2], path[path.length - 1], body); - }; - const laserHitMob = function (dmg) { - if (best.who.alive) { - dmg *= b.dmgScale * damage; - best.who.damage(dmg); - best.who.locatePlayer(); - //draw mob damage circle - ctx.fillStyle = color; - ctx.beginPath(); - ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); - ctx.fill(); - } - }; - const reflection = function () { - // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector - const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2))); - const d = Vector.sub(path[path.length - 1], path[path.length - 2]); - const nn = Vector.mult(n, 2 * Vector.dot(d, n)); - const r = Vector.normalise(Vector.sub(d, nn)); - path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]); + //check for collisions + best = { + x: null, + y: null, + dist2: Infinity, + who: null, + v1: null, + v2: null }; - //beam before reflection - checkForCollisions(); - if (best.dist2 != Infinity) { - //if hitting something + vertexCollision(path[0], path[1], mob); + vertexCollision(path[0], path[1], map); + vertexCollision(path[0], path[1], body); + if (best.dist2 != Infinity) { //if hitting something path[path.length - 1] = { x: best.x, y: best.y }; - laserHitMob(1); + } - //1st reflection beam - reflection(); - //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body - let who = best.who; + //use energy to explode + const energy = mech.fieldMeter * 0.25 + mech.fieldMeter -= energy + if (best.who) b.explosion(path[1], 1200 * energy) + mech.fireCDcycle = mech.cycle + Math.floor(65 * b.modFireRate); // cool down + + //draw laser beam + ctx.beginPath(); + ctx.moveTo(path[0].x, path[0].y); + ctx.lineTo(path[1].x, path[1].y); + ctx.strokeStyle = "rgba(255,0,0,0.13)" + ctx.lineWidth = 60 * energy / 0.2 + ctx.stroke(); + ctx.strokeStyle = "rgba(255,0,0,0.2)" + ctx.lineWidth = 18 + ctx.stroke(); + ctx.strokeStyle = "#f00"; + ctx.lineWidth = 4 + ctx.stroke(); + + //draw little dots along the laser path + const sub = Vector.sub(path[1], path[0]) + const mag = Vector.magnitude(sub) + for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) { + const dist = Math.random() + game.drawList.push({ + x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5), + y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5), + radius: 1 + 4 * Math.random(), + color: "rgba(255,0,0,0.5)", + time: Math.floor(2 + 33 * Math.random() * Math.random()) + }); + } + } else { //normal fire mode + const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets + const damage = 0.045 + if (mech.fieldMeter < FIELD_DRAIN) { + mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy + } else { + mech.fieldMeter -= mech.fieldRegen + FIELD_DRAIN + let best; + const color = "#f00"; + const range = 3000; + const path = [{ + x: mech.pos.x + 20 * Math.cos(mech.angle), + y: mech.pos.y + 20 * Math.sin(mech.angle) + }, + { + x: mech.pos.x + range * Math.cos(mech.angle), + y: mech.pos.y + range * Math.sin(mech.angle) + } + ]; + const vertexCollision = function (v1, v1End, domain) { + for (let i = 0; i < domain.length; ++i) { + let vertices = domain[i].vertices; + const len = vertices.length - 1; + for (let j = 0; j < len; j++) { + results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[j], + v2: vertices[j + 1] + }; + } + } + } + results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[0], + v2: vertices[len] + }; + } + } + } + }; + const checkForCollisions = function () { + best = { + x: null, + y: null, + dist2: Infinity, + who: null, + v1: null, + v2: null + }; + vertexCollision(path[path.length - 2], path[path.length - 1], mob); + vertexCollision(path[path.length - 2], path[path.length - 1], map); + vertexCollision(path[path.length - 2], path[path.length - 1], body); + }; + const laserHitMob = function (dmg) { + if (best.who.alive) { + dmg *= b.dmgScale * damage; + best.who.damage(dmg); + best.who.locatePlayer(); + //draw mob damage circle + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); + ctx.fill(); + } + }; + + const reflection = function () { + // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector + const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2))); + const d = Vector.sub(path[path.length - 1], path[path.length - 2]); + const nn = Vector.mult(n, 2 * Vector.dot(d, n)); + const r = Vector.normalise(Vector.sub(d, nn)); + path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]); + }; + //beam before reflection checkForCollisions(); if (best.dist2 != Infinity) { //if hitting something @@ -1798,22 +1892,24 @@ const b = { x: best.x, y: best.y }; - laserHitMob(0.8); + laserHitMob(1); - //2nd reflection beam + //1st reflection beam + reflection(); //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body - if (who !== best.who) { - reflection(); - checkForCollisions(); - if (best.dist2 != Infinity) { - //if hitting something - path[path.length - 1] = { - x: best.x, - y: best.y - }; - laserHitMob(0.63); - + let who = best.who; + checkForCollisions(); + if (best.dist2 != Infinity) { + //if hitting something + path[path.length - 1] = { + x: best.x, + y: best.y + }; + laserHitMob(0.8); + //2nd reflection beam + //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body + if (who !== best.who) { reflection(); checkForCollisions(); if (best.dist2 != Infinity) { @@ -1822,147 +1918,330 @@ const b = { x: best.x, y: best.y }; - laserHitMob(0.5); + laserHitMob(0.63); + + + reflection(); + checkForCollisions(); + if (best.dist2 != Infinity) { + //if hitting something + path[path.length - 1] = { + x: best.x, + y: best.y + }; + laserHitMob(0.5); + } } } } } - } - ctx.fillStyle = color; - ctx.strokeStyle = color; - ctx.lineWidth = 2; - ctx.lineDashOffset = 300 * Math.random() - // ctx.setLineDash([200 * Math.random(), 250 * Math.random()]); + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = 2; + ctx.lineDashOffset = 300 * Math.random() + // ctx.setLineDash([200 * Math.random(), 250 * Math.random()]); - ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]); - for (let i = 1, len = path.length; i < len; ++i) { - ctx.beginPath(); - ctx.moveTo(path[i - 1].x, path[i - 1].y); - ctx.lineTo(path[i].x, path[i].y); - ctx.stroke(); - ctx.globalAlpha *= 0.65; //reflections are less intense - // ctx.globalAlpha -= 0.1; //reflections are less intense + ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]); + for (let i = 1, len = path.length; i < len; ++i) { + ctx.beginPath(); + ctx.moveTo(path[i - 1].x, path[i - 1].y); + ctx.lineTo(path[i].x, path[i].y); + ctx.stroke(); + ctx.globalAlpha *= 0.65; //reflections are less intense + // ctx.globalAlpha -= 0.1; //reflections are less intense + } + ctx.setLineDash([0, 0]); + ctx.globalAlpha = 1; } - ctx.setLineDash([0, 0]); - ctx.globalAlpha = 1; } } }, - { - name: "pulse", //15 - description: "power a laser that initiates a fusion explosioneach pulse drains 25% of your current energy", - ammo: 0, - ammoPack: Infinity, - have: false, - isStarterGun: true, - fire() { - //calculate laser collision - let best; - let range = 3000 - const path = [{ - x: mech.pos.x + 20 * Math.cos(mech.angle), - y: mech.pos.y + 20 * Math.sin(mech.angle) - }, - { - x: mech.pos.x + range * Math.cos(mech.angle), - y: mech.pos.y + range * Math.sin(mech.angle) - } - ]; - const vertexCollision = function (v1, v1End, domain) { - for (let i = 0; i < domain.length; ++i) { - let vertices = domain[i].vertices; - const len = vertices.length - 1; - for (let j = 0; j < len; j++) { - results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); - if (results.onLine1 && results.onLine2) { - const dx = v1.x - results.x; - const dy = v1.y - results.y; - const dist2 = dx * dx + dy * dy; - if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { - best = { - x: results.x, - y: results.y, - dist2: dist2, - who: domain[i], - v1: vertices[j], - v2: vertices[j + 1] - }; - } - } - } - results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); - if (results.onLine1 && results.onLine2) { - const dx = v1.x - results.x; - const dy = v1.y - results.y; - const dist2 = dx * dx + dy * dy; - if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { - best = { - x: results.x, - y: results.y, - dist2: dist2, - who: domain[i], - v1: vertices[0], - v2: vertices[len] - }; - } - } - } - }; + // { + // name: "laser", //14 + // description: "emit a beam of collimated coherent lightdrains energy instead of ammunition", + // ammo: 0, + // ammoPack: Infinity, + // have: false, + // isStarterGun: true, + // fire() { + // const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets + // const damage = 0.05 + // if (mech.fieldMeter < FIELD_DRAIN) { + // mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy + // } else { + // mech.fieldMeter -= mech.fieldRegen + FIELD_DRAIN + // let best; + // const color = "#f00"; + // const range = 3000; + // const path = [{ + // x: mech.pos.x + 20 * Math.cos(mech.angle), + // y: mech.pos.y + 20 * Math.sin(mech.angle) + // }, + // { + // x: mech.pos.x + range * Math.cos(mech.angle), + // y: mech.pos.y + range * Math.sin(mech.angle) + // } + // ]; + // const vertexCollision = function (v1, v1End, domain) { + // for (let i = 0; i < domain.length; ++i) { + // let vertices = domain[i].vertices; + // const len = vertices.length - 1; + // for (let j = 0; j < len; j++) { + // results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[j], + // v2: vertices[j + 1] + // }; + // } + // } + // } + // results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[0], + // v2: vertices[len] + // }; + // } + // } + // } + // }; + // const checkForCollisions = function () { + // best = { + // x: null, + // y: null, + // dist2: Infinity, + // who: null, + // v1: null, + // v2: null + // }; + // vertexCollision(path[path.length - 2], path[path.length - 1], mob); + // vertexCollision(path[path.length - 2], path[path.length - 1], map); + // vertexCollision(path[path.length - 2], path[path.length - 1], body); + // }; + // const laserHitMob = function (dmg) { + // if (best.who.alive) { + // dmg *= b.dmgScale * damage; + // best.who.damage(dmg); + // best.who.locatePlayer(); + // //draw mob damage circle + // ctx.fillStyle = color; + // ctx.beginPath(); + // ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); + // ctx.fill(); + // } + // }; - //check for collisions - best = { - x: null, - y: null, - dist2: Infinity, - who: null, - v1: null, - v2: null - }; - vertexCollision(path[0], path[1], mob); - vertexCollision(path[0], path[1], map); - vertexCollision(path[0], path[1], body); - if (best.dist2 != Infinity) { //if hitting something - path[path.length - 1] = { - x: best.x, - y: best.y - }; - } + // const reflection = function () { + // // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector + // const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2))); + // const d = Vector.sub(path[path.length - 1], path[path.length - 2]); + // const nn = Vector.mult(n, 2 * Vector.dot(d, n)); + // const r = Vector.normalise(Vector.sub(d, nn)); + // path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]); + // }; + // //beam before reflection + // checkForCollisions(); + // if (best.dist2 != Infinity) { + // //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // laserHitMob(1); - //use energy to explode - const energy = mech.fieldMeter * 0.25 - mech.fieldMeter -= energy - if (best.who) b.explosion(path[1], 1300 * energy) - mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down + // //1st reflection beam + // reflection(); + // //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body + // let who = best.who; + // checkForCollisions(); + // if (best.dist2 != Infinity) { + // //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // laserHitMob(0.8); - //draw laser beam - ctx.beginPath(); - ctx.moveTo(path[0].x, path[0].y); - ctx.lineTo(path[1].x, path[1].y); - ctx.strokeStyle = "rgba(255,0,0,0.13)" - ctx.lineWidth = 60 * energy / 0.2 - ctx.stroke(); - ctx.strokeStyle = "rgba(255,0,0,0.2)" - ctx.lineWidth = 18 - ctx.stroke(); - ctx.strokeStyle = "#f00"; - ctx.lineWidth = 4 - ctx.stroke(); + // //2nd reflection beam + // //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body + // if (who !== best.who) { + // reflection(); + // checkForCollisions(); + // if (best.dist2 != Infinity) { + // //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // laserHitMob(0.63); - //draw little dots along the laser path - const sub = Vector.sub(path[1], path[0]) - const mag = Vector.magnitude(sub) - for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) { - const dist = Math.random() - game.drawList.push({ - x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5), - y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5), - radius: 1 + 4 * Math.random(), - color: "rgba(255,0,0,0.5)", - time: Math.floor(2 + 33 * Math.random() * Math.random()) - }); - } - } - }, + + // reflection(); + // checkForCollisions(); + // if (best.dist2 != Infinity) { + // //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // laserHitMob(0.5); + // } + // } + // } + // } + // } + // ctx.fillStyle = color; + // ctx.strokeStyle = color; + // ctx.lineWidth = 2; + // ctx.lineDashOffset = 300 * Math.random() + // // ctx.setLineDash([200 * Math.random(), 250 * Math.random()]); + + // ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]); + // for (let i = 1, len = path.length; i < len; ++i) { + // ctx.beginPath(); + // ctx.moveTo(path[i - 1].x, path[i - 1].y); + // ctx.lineTo(path[i].x, path[i].y); + // ctx.stroke(); + // ctx.globalAlpha *= 0.65; //reflections are less intense + // // ctx.globalAlpha -= 0.1; //reflections are less intense + // } + // ctx.setLineDash([0, 0]); + // ctx.globalAlpha = 1; + // } + // } + // }, + // { + // name: "pulse", //15 + // description: "power a laser that initiates a fusion explosioneach pulse drains 25% of your current energy", + // ammo: 0, + // ammoPack: Infinity, + // have: false, + // isStarterGun: true, + // fire() { + // //calculate laser collision + // let best; + // let range = 3000 + // const path = [{ + // x: mech.pos.x + 20 * Math.cos(mech.angle), + // y: mech.pos.y + 20 * Math.sin(mech.angle) + // }, + // { + // x: mech.pos.x + range * Math.cos(mech.angle), + // y: mech.pos.y + range * Math.sin(mech.angle) + // } + // ]; + // const vertexCollision = function (v1, v1End, domain) { + // for (let i = 0; i < domain.length; ++i) { + // let vertices = domain[i].vertices; + // const len = vertices.length - 1; + // for (let j = 0; j < len; j++) { + // results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[j], + // v2: vertices[j + 1] + // }; + // } + // } + // } + // results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[0], + // v2: vertices[len] + // }; + // } + // } + // } + // }; + + // //check for collisions + // best = { + // x: null, + // y: null, + // dist2: Infinity, + // who: null, + // v1: null, + // v2: null + // }; + // vertexCollision(path[0], path[1], mob); + // vertexCollision(path[0], path[1], map); + // vertexCollision(path[0], path[1], body); + // if (best.dist2 != Infinity) { //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // } + + // //use energy to explode + // const energy = mech.fieldMeter * 0.25 + // mech.fieldMeter -= energy + // if (best.who) b.explosion(path[1], 1300 * energy) + // mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down + + // //draw laser beam + // ctx.beginPath(); + // ctx.moveTo(path[0].x, path[0].y); + // ctx.lineTo(path[1].x, path[1].y); + // ctx.strokeStyle = "rgba(255,0,0,0.13)" + // ctx.lineWidth = 60 * energy / 0.2 + // ctx.stroke(); + // ctx.strokeStyle = "rgba(255,0,0,0.2)" + // ctx.lineWidth = 18 + // ctx.stroke(); + // ctx.strokeStyle = "#f00"; + // ctx.lineWidth = 4 + // ctx.stroke(); + + // //draw little dots along the laser path + // const sub = Vector.sub(path[1], path[0]) + // const mag = Vector.magnitude(sub) + // for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) { + // const dist = Math.random() + // game.drawList.push({ + // x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5), + // y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5), + // radius: 1 + 4 * Math.random(), + // color: "rgba(255,0,0,0.5)", + // time: Math.floor(2 + 33 * Math.random() * Math.random()) + // }); + // } + // } + // }, { name: "foam", //16 description: "spray bubbly foam that sticks to enemiesdoes damage over time and slows movement", diff --git a/js/game.js b/js/game.js index 508b82e..defe576 100644 --- a/js/game.js +++ b/js/game.js @@ -64,12 +64,8 @@ const game = { x: 0, y: 0 }, - levelsCleared: 0, + g: 0.001, - dmgScale: null, //set in levels.setDifficulty - accelScale: null, //set in levels.setDifficulty - CDScale: null, //set in levels.setDifficulty - lookFreqScale: null, //set in levels.setDifficulty onTitlePage: true, paused: false, testing: false, //testing mode: shows wireframe and some variables @@ -82,8 +78,14 @@ const game = { delta: 1000 / 60, //speed of game engine //looks like it has to be 16 to match player input buttonCD: 0, isBodyDamage: true, + levelsCleared: 0, difficultyMode: null, - difficulty: 0, + difficulty: 1, + dmgScale: null, //set in levels.setDifficulty + healScale: 1, + accelScale: null, //set in levels.setDifficulty + CDScale: null, //set in levels.setDifficulty + lookFreqScale: null, //set in levels.setDifficulty isDraftMode: false, // dropFPS(cap = 40, time = 15) { // game.fpsCap = cap @@ -462,7 +464,7 @@ const game = { game.makeGunHUD(); mech.drop(); mech.holdingTarget = null - mech.addHealth(1); + mech.addHealth(Infinity); mech.alive = true; level.onLevel = 0; level.levelsCleared = 0; diff --git a/js/index.js b/js/index.js index 94aa588..f4924c0 100644 --- a/js/index.js +++ b/js/index.js @@ -2,15 +2,23 @@ /* TODO: ******************************************* ***************************************************** -new game loop structure: game loop is an object with named methods - when looping each method is called in order like an array - allows me to dynamically add and remove functions to the game +make draft mode default and add in negative mods + +field: catch mobs in your field and make them into guardian bullets + +negative mod effect ideas + -max health + -fire rate + -slow life decay mod: if you fire when out of ammo you gain 1 ammo pack at the cost of 10% max health 20% of your current health -mod: increase range of shield block +Boss mob: triangle that fires three lasers + +mob: has 2 or 3 shields that can regenerate over time + could be just a boss gun: Spirit Bomb (singularity) use charge up like rail gun @@ -143,7 +151,7 @@ const build = { level.isBuildRun = true; for (let i = 0; i < build.list.length; i++) { if (build.list[i].type === "field") { - mech.fieldUpgrades[build.list[i].index].effect(); + mech.setField(build.list[i].index) } else if (build.list[i].type === "gun") { b.giveGuns(build.list[i].index) } else if (build.list[i].type === "mod") { diff --git a/js/level.js b/js/level.js index 5e0cc8d..f8a40ae 100644 --- a/js/level.js +++ b/js/level.js @@ -42,22 +42,26 @@ const level = { // if (level.isBuildRun) num++ for (let i = 0; i < num; i++) { game.difficulty++ - game.dmgScale += 0.15; //damage done by mobs increases each level + game.dmgScale += 0.1; //damage done by mobs increases each level b.dmgScale *= 0.94; //damage done by player decreases each level game.accelScale *= 1.03 //mob acceleration increases each level game.lookFreqScale *= 0.97 //mob cycles between looks decreases each level game.CDScale *= 0.97 //mob CD time decreases each level } + game.healScale = 1 / (1 + game.difficulty * 0.05) }, difficultyDecrease(num = 1) { //used in easy mode for game.reset() for (let i = 0; i < num; i++) { - game.dmgScale -= 0.15; //damage done by mobs increases each level + game.difficulty-- + game.dmgScale -= 0.1; //damage done by mobs increases each level if (game.dmgScale < 0.1) game.dmgScale = 0.1; b.dmgScale /= 0.94; //damage done by player decreases each level game.accelScale /= 1.03 //mob acceleration increases each level game.lookFreqScale /= 0.97 //mob cycles between looks decreases each level game.CDScale /= 0.97 //mob CD time decreases each level } + if (game.difficulty < 1) game.difficulty = 1; + game.healScale = 1 / (1 + game.difficulty * 0.05) }, //****************************************************************************************************************** //****************************************************************************************************************** diff --git a/js/player.js b/js/player.js index fb9a7a3..069787b 100644 --- a/js/player.js +++ b/js/player.js @@ -433,7 +433,7 @@ const mech = { } }, addHealth(heal) { - mech.health += heal; + mech.health += heal * game.healScale; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; mech.displayHealth(); }, diff --git a/js/powerups.js b/js/powerups.js index b556e74..a85b6f6 100644 --- a/js/powerups.js +++ b/js/powerups.js @@ -40,7 +40,6 @@ const powerUps = { }, effect() { let heal = ((this.size / 40) ** 2) - heal /= (0.95 + game.difficulty * 0.01) heal = Math.min(mech.maxHealth - mech.health, heal) if (b.isModRecursiveHealing) heal *= 2 mech.addHealth(heal); @@ -290,10 +289,10 @@ const powerUps = { if (mech.fieldMode === 0) { powerUps.spawn(x, y, "field") if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field") - } else if (Math.random() < 0.5) { + } else if (Math.random() < 0.55) { powerUps.spawn(x, y, "mod") if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod") - } else if (Math.random() < 0.3) { + } else if (Math.random() < 0.2) { powerUps.spawn(x, y, "gun") if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun") } else if (Math.random() < 0.1) {