laser and pulse combined, heal effect difficulty balance, custom mode bug fix

This commit is contained in:
landgreen
2019-12-30 06:44:20 -08:00
parent 624553186c
commit 45b87e8c72
7 changed files with 502 additions and 211 deletions

View File

@@ -95,8 +95,7 @@
<details> <details>
<summary>settings</summary> <summary>settings</summary>
<div style="line-height: 150%;" id="details-div"> <div style="line-height: 150%;" id="details-div">
<label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed">combat <label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">combat difficulty:</label>
difficulty:</label>
<select name="difficulty-select" id="difficulty-select"> <select name="difficulty-select" id="difficulty-select">
<option value="0">easy</option> <option value="0">easy</option>
<option value="1" selected>normal</option> <option value="1" selected>normal</option>

View File

@@ -1679,21 +1679,16 @@ const b = {
}, },
{ {
name: "laser", //14 name: "laser", //14
description: "emit a beam of collimated coherent <strong>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition", description: "drain <strong class='color-f'>energy</strong> to emit a beam of coherent <strong>light</strong><br>when crouched, initiate a fusion <strong class='color-e'>explosion</strong>",
ammo: 0, ammo: 0,
ammoPack: Infinity, ammoPack: Infinity,
have: false, have: false,
isStarterGun: true, isStarterGun: true,
fire() { fire() {
const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets if (mech.crouch) { //crouch fire mode
const damage = 0.05 //calculate laser collision
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; let best;
const color = "#f00"; let range = 3000
const range = 3000;
const path = [{ const path = [{
x: mech.pos.x + 20 * Math.cos(mech.angle), x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(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 () { //check for collisions
// https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector best = {
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2))); x: null,
const d = Vector.sub(path[path.length - 1], path[path.length - 2]); y: null,
const nn = Vector.mult(n, 2 * Vector.dot(d, n)); dist2: Infinity,
const r = Vector.normalise(Vector.sub(d, nn)); who: null,
path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]); v1: null,
v2: null
}; };
//beam before reflection vertexCollision(path[0], path[1], mob);
checkForCollisions(); vertexCollision(path[0], path[1], map);
if (best.dist2 != Infinity) { vertexCollision(path[0], path[1], body);
//if hitting something if (best.dist2 != Infinity) { //if hitting something
path[path.length - 1] = { path[path.length - 1] = {
x: best.x, x: best.x,
y: best.y y: best.y
}; };
laserHitMob(1); }
//1st reflection beam //use energy to explode
reflection(); const energy = mech.fieldMeter * 0.25
//ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body mech.fieldMeter -= energy
let who = best.who; 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(); checkForCollisions();
if (best.dist2 != Infinity) { if (best.dist2 != Infinity) {
//if hitting something //if hitting something
@@ -1798,22 +1892,24 @@ const b = {
x: best.x, x: best.x,
y: best.y 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 //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body
if (who !== best.who) { let who = best.who;
reflection(); checkForCollisions();
checkForCollisions(); if (best.dist2 != Infinity) {
if (best.dist2 != Infinity) { //if hitting something
//if hitting something path[path.length - 1] = {
path[path.length - 1] = { x: best.x,
x: best.x, y: best.y
y: best.y };
}; laserHitMob(0.8);
laserHitMob(0.63);
//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(); reflection();
checkForCollisions(); checkForCollisions();
if (best.dist2 != Infinity) { if (best.dist2 != Infinity) {
@@ -1822,147 +1918,330 @@ const b = {
x: best.x, x: best.x,
y: best.y 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.fillStyle = color; ctx.strokeStyle = color;
ctx.strokeStyle = color; ctx.lineWidth = 2;
ctx.lineWidth = 2; ctx.lineDashOffset = 300 * Math.random()
ctx.lineDashOffset = 300 * Math.random() // ctx.setLineDash([200 * Math.random(), 250 * Math.random()]);
// ctx.setLineDash([200 * Math.random(), 250 * Math.random()]);
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]); ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
for (let i = 1, len = path.length; i < len; ++i) { for (let i = 1, len = path.length; i < len; ++i) {
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(path[i - 1].x, path[i - 1].y); ctx.moveTo(path[i - 1].x, path[i - 1].y);
ctx.lineTo(path[i].x, path[i].y); ctx.lineTo(path[i].x, path[i].y);
ctx.stroke(); ctx.stroke();
ctx.globalAlpha *= 0.65; //reflections are less intense ctx.globalAlpha *= 0.65; //reflections are less intense
// ctx.globalAlpha -= 0.1; //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 // name: "laser", //14
description: "power a <strong>laser</strong> that initiates a fusion <strong class='color-e'>explosion</strong><br>each pulse drains 25% of your current <strong class='color-f'>energy</strong>", // description: "emit a beam of collimated coherent <strong>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
ammo: 0, // ammo: 0,
ammoPack: Infinity, // ammoPack: Infinity,
have: false, // have: false,
isStarterGun: true, // isStarterGun: true,
fire() { // fire() {
//calculate laser collision // const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets
let best; // const damage = 0.05
let range = 3000 // if (mech.fieldMeter < FIELD_DRAIN) {
const path = [{ // mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy
x: mech.pos.x + 20 * Math.cos(mech.angle), // } else {
y: mech.pos.y + 20 * Math.sin(mech.angle) // mech.fieldMeter -= mech.fieldRegen + FIELD_DRAIN
}, // let best;
{ // const color = "#f00";
x: mech.pos.x + range * Math.cos(mech.angle), // const range = 3000;
y: mech.pos.y + range * Math.sin(mech.angle) // const path = [{
} // x: mech.pos.x + 20 * Math.cos(mech.angle),
]; // y: mech.pos.y + 20 * Math.sin(mech.angle)
const vertexCollision = function (v1, v1End, domain) { // },
for (let i = 0; i < domain.length; ++i) { // {
let vertices = domain[i].vertices; // x: mech.pos.x + range * Math.cos(mech.angle),
const len = vertices.length - 1; // y: mech.pos.y + range * Math.sin(mech.angle)
for (let j = 0; j < len; j++) { // }
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); // ];
if (results.onLine1 && results.onLine2) { // const vertexCollision = function (v1, v1End, domain) {
const dx = v1.x - results.x; // for (let i = 0; i < domain.length; ++i) {
const dy = v1.y - results.y; // let vertices = domain[i].vertices;
const dist2 = dx * dx + dy * dy; // const len = vertices.length - 1;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { // for (let j = 0; j < len; j++) {
best = { // results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
x: results.x, // if (results.onLine1 && results.onLine2) {
y: results.y, // const dx = v1.x - results.x;
dist2: dist2, // const dy = v1.y - results.y;
who: domain[i], // const dist2 = dx * dx + dy * dy;
v1: vertices[j], // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
v2: vertices[j + 1] // best = {
}; // x: results.x,
} // y: results.y,
} // dist2: dist2,
} // who: domain[i],
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); // v1: vertices[j],
if (results.onLine1 && results.onLine2) { // v2: vertices[j + 1]
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 = { // results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
x: results.x, // if (results.onLine1 && results.onLine2) {
y: results.y, // const dx = v1.x - results.x;
dist2: dist2, // const dy = v1.y - results.y;
who: domain[i], // const dist2 = dx * dx + dy * dy;
v1: vertices[0], // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
v2: vertices[len] // 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 // const reflection = function () {
best = { // // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
x: null, // const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
y: null, // const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
dist2: Infinity, // const nn = Vector.mult(n, 2 * Vector.dot(d, n));
who: null, // const r = Vector.normalise(Vector.sub(d, nn));
v1: null, // path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]);
v2: null // };
}; // //beam before reflection
vertexCollision(path[0], path[1], mob); // checkForCollisions();
vertexCollision(path[0], path[1], map); // if (best.dist2 != Infinity) {
vertexCollision(path[0], path[1], body); // //if hitting something
if (best.dist2 != Infinity) { //if hitting something // path[path.length - 1] = {
path[path.length - 1] = { // x: best.x,
x: best.x, // y: best.y
y: best.y // };
}; // laserHitMob(1);
}
//use energy to explode // //1st reflection beam
const energy = mech.fieldMeter * 0.25 // reflection();
mech.fieldMeter -= energy // //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body
if (best.who) b.explosion(path[1], 1300 * energy) // let who = best.who;
mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down // checkForCollisions();
// if (best.dist2 != Infinity) {
// //if hitting something
// path[path.length - 1] = {
// x: best.x,
// y: best.y
// };
// laserHitMob(0.8);
//draw laser beam // //2nd reflection beam
ctx.beginPath(); // //ugly bug fix: this stops the reflection on a bug where the beam gets trapped inside a body
ctx.moveTo(path[0].x, path[0].y); // if (who !== best.who) {
ctx.lineTo(path[1].x, path[1].y); // reflection();
ctx.strokeStyle = "rgba(255,0,0,0.13)" // checkForCollisions();
ctx.lineWidth = 60 * energy / 0.2 // if (best.dist2 != Infinity) {
ctx.stroke(); // //if hitting something
ctx.strokeStyle = "rgba(255,0,0,0.2)" // path[path.length - 1] = {
ctx.lineWidth = 18 // x: best.x,
ctx.stroke(); // y: best.y
ctx.strokeStyle = "#f00"; // };
ctx.lineWidth = 4 // laserHitMob(0.63);
ctx.stroke();
//draw little dots along the laser path
const sub = Vector.sub(path[1], path[0]) // reflection();
const mag = Vector.magnitude(sub) // checkForCollisions();
for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) { // if (best.dist2 != Infinity) {
const dist = Math.random() // //if hitting something
game.drawList.push({ // path[path.length - 1] = {
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5), // x: best.x,
y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5), // y: best.y
radius: 1 + 4 * Math.random(), // };
color: "rgba(255,0,0,0.5)", // laserHitMob(0.5);
time: Math.floor(2 + 33 * Math.random() * 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([0, 0]);
// ctx.globalAlpha = 1;
// }
// }
// },
// {
// name: "pulse", //15
// description: "power a <strong>laser</strong> that initiates a fusion <strong class='color-e'>explosion</strong><br>each pulse drains 25% of your current <strong class='color-f'>energy</strong>",
// 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 name: "foam", //16
description: "spray bubbly foam that <strong>sticks</strong> to enemies<br>does <strong class='color-d'>damage</strong> over time and <strong>slows</strong> movement", description: "spray bubbly foam that <strong>sticks</strong> to enemies<br>does <strong class='color-d'>damage</strong> over time and <strong>slows</strong> movement",

View File

@@ -64,12 +64,8 @@ const game = {
x: 0, x: 0,
y: 0 y: 0
}, },
levelsCleared: 0,
g: 0.001, 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, onTitlePage: true,
paused: false, paused: false,
testing: false, //testing mode: shows wireframe and some variables 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 delta: 1000 / 60, //speed of game engine //looks like it has to be 16 to match player input
buttonCD: 0, buttonCD: 0,
isBodyDamage: true, isBodyDamage: true,
levelsCleared: 0,
difficultyMode: null, 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, isDraftMode: false,
// dropFPS(cap = 40, time = 15) { // dropFPS(cap = 40, time = 15) {
// game.fpsCap = cap // game.fpsCap = cap
@@ -462,7 +464,7 @@ const game = {
game.makeGunHUD(); game.makeGunHUD();
mech.drop(); mech.drop();
mech.holdingTarget = null mech.holdingTarget = null
mech.addHealth(1); mech.addHealth(Infinity);
mech.alive = true; mech.alive = true;
level.onLevel = 0; level.onLevel = 0;
level.levelsCleared = 0; level.levelsCleared = 0;

View File

@@ -2,15 +2,23 @@
/* TODO: ******************************************* /* TODO: *******************************************
***************************************************** *****************************************************
new game loop structure: game loop is an object with named methods make draft mode default and add in negative mods
when looping each method is called in order like an array
allows me to dynamically add and remove functions to the game 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 mod: if you fire when out of ammo you gain 1 ammo pack at the cost of
10% max health 10% max health
20% of your current 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) gun: Spirit Bomb (singularity)
use charge up like rail gun use charge up like rail gun
@@ -143,7 +151,7 @@ const build = {
level.isBuildRun = true; level.isBuildRun = true;
for (let i = 0; i < build.list.length; i++) { for (let i = 0; i < build.list.length; i++) {
if (build.list[i].type === "field") { 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") { } else if (build.list[i].type === "gun") {
b.giveGuns(build.list[i].index) b.giveGuns(build.list[i].index)
} else if (build.list[i].type === "mod") { } else if (build.list[i].type === "mod") {

View File

@@ -42,22 +42,26 @@ const level = {
// if (level.isBuildRun) num++ // if (level.isBuildRun) num++
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty++ 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 b.dmgScale *= 0.94; //damage done by player decreases each level
game.accelScale *= 1.03 //mob acceleration increases each level game.accelScale *= 1.03 //mob acceleration increases each level
game.lookFreqScale *= 0.97 //mob cycles between looks decreases each level game.lookFreqScale *= 0.97 //mob cycles between looks decreases each level
game.CDScale *= 0.97 //mob CD time 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() difficultyDecrease(num = 1) { //used in easy mode for game.reset()
for (let i = 0; i < num; i++) { 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; if (game.dmgScale < 0.1) game.dmgScale = 0.1;
b.dmgScale /= 0.94; //damage done by player decreases each level b.dmgScale /= 0.94; //damage done by player decreases each level
game.accelScale /= 1.03 //mob acceleration increases each level game.accelScale /= 1.03 //mob acceleration increases each level
game.lookFreqScale /= 0.97 //mob cycles between looks decreases each level game.lookFreqScale /= 0.97 //mob cycles between looks decreases each level
game.CDScale /= 0.97 //mob CD time 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)
}, },
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************

View File

@@ -433,7 +433,7 @@ const mech = {
} }
}, },
addHealth(heal) { addHealth(heal) {
mech.health += heal; mech.health += heal * game.healScale;
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth(); mech.displayHealth();
}, },

View File

@@ -40,7 +40,6 @@ const powerUps = {
}, },
effect() { effect() {
let heal = ((this.size / 40) ** 2) let heal = ((this.size / 40) ** 2)
heal /= (0.95 + game.difficulty * 0.01)
heal = Math.min(mech.maxHealth - mech.health, heal) heal = Math.min(mech.maxHealth - mech.health, heal)
if (b.isModRecursiveHealing) heal *= 2 if (b.isModRecursiveHealing) heal *= 2
mech.addHealth(heal); mech.addHealth(heal);
@@ -290,10 +289,10 @@ const powerUps = {
if (mech.fieldMode === 0) { if (mech.fieldMode === 0) {
powerUps.spawn(x, y, "field") powerUps.spawn(x, y, "field")
if (Math.random() < b.modMoreDrops) 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") powerUps.spawn(x, y, "mod")
if (Math.random() < b.modMoreDrops) 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") powerUps.spawn(x, y, "gun")
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun") if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun")
} else if (Math.random() < 0.1) { } else if (Math.random() < 0.1) {