diff --git a/index.html b/index.html
index 7b18c8b..70da1f1 100644
--- a/index.html
+++ b/index.html
@@ -33,9 +33,7 @@
-
- Auto-Loading Heuristics
-
+
diff --git a/js/bullets.js b/js/bullets.js
index 5c92d0d..d51ad94 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -12,7 +12,7 @@ const b = {
modHealthDrain: null,
modNoAmmo: null,
modBulletsLastLonger: null,
- // modNonEuclidean: null,
+ modIsImmortal: null,
setModDefaults() {
b.modFireRate = 1;
b.modExplosionRadius = 1;
@@ -21,15 +21,15 @@ const b = {
b.modHealthDrain = 0;
b.modNoAmmo = 0;
b.modBulletsLastLonger = 1;
- // b.modNonEuclidean = false;
+ b.modIsImmortal = false;
},
- modText: function () {
- game.makeTextLog(`${b.mods[b.mod].name}
(left click)${b.mods[b.mod].description}
`, 1200);
- document.getElementById("mods").innerHTML = b.mods[b.mod].name
+ modText() {
+ if (b.mod !== null) game.makeTextLog(`${b.mods[b.mod].name}
${b.mods[b.mod].description}
`, 1200);
+ game.updateModHUD()
},
mods: [{
name: "Auto-Loading Heuristics",
- description: "your rate of fire 15% is faster",
+ description: "your rate of fire is 15% faster",
effect: () => {
b.mod = 0
b.modText();
@@ -40,7 +40,7 @@ const b = {
},
{
name: "Anti-Matter Cores",
- description: "your explosions are larger and do more damage",
+ description: "your explosions are larger and more dangerous",
effect: () => {
b.mod = 1
b.modText();
@@ -68,7 +68,7 @@ const b = {
effect: () => {
b.mod = 3
b.modText();
- b.setModDefaults(); //good with laser, Nano-Scale Manufacturing, Standing Wave Harmonics, Phase Decoherence Field
+ b.setModDefaults(); //good with laser, and all fields
b.modEnergySiphon = 0.2;
}
},
@@ -93,26 +93,26 @@ const b = {
}
},
{
- name: "Anti-Decay Coating",
- description: "your bullets last 25% longer",
+ name: "Decay Resistant Topology",
+ description: "your bullets last 30% longer",
effect: () => {
b.mod = 6
b.modText();
b.setModDefaults(); //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
- b.modBulletsLastLonger = 1.25
+ b.modBulletsLastLonger = 1.30
}
},
- // {
- // name: "Non-Euclidean Geometry",
- // description: "after you fall loop back to the top of the map",
- // have: false,
- // effect: () => {
- // b.mod = 7
- // b.modText();
- // b.setModDefaults(); //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
- // b.modNonEuclidean = true
- // }
- // },
+ {
+ name: "Quantum Immortality",
+ description: "after you die continue in an alternate reality with randomized abilities
",
+ effect: () => {
+ b.mod = 7
+ b.modText();
+ b.setModDefaults(); //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
+ b.modIsImmortal = true;
+ }
+ },
+
// () => {
// b.mod = 8;
// game.makeTextLog("Relativistic Velocity
(left click)Your bullets are effected extra by your own velocity
", 1200);
diff --git a/js/game.js b/js/game.js
index d922d65..d9f5cee 100644
--- a/js/game.js
+++ b/js/game.js
@@ -153,6 +153,16 @@ const game = {
}
game.boldActiveGunHUD();
},
+ updateModHUD() {
+ let text = ""
+ if (mech.fieldMode !== 0) {
+ text += mech.fieldUpgrades[mech.fieldMode].name
+ if (b.mod !== null) text += "
" + b.mods[b.mod].name
+ } else if (b.mod !== null) {
+ text += b.mods[b.mod].name
+ }
+ document.getElementById("mods").innerHTML = text
+ },
makeTextLog(text, time = 180) {
document.getElementById("text-log").innerHTML = text;
document.getElementById("text-log").style.opacity = 1;
@@ -250,10 +260,14 @@ const game = {
requestAnimationFrame(cycle);
} else {
game.paused = true;
- let text = "PAUSED
"
- // if (b.mod !== null) text+=
- //output current mod, field, and gun info when paused
- game.makeTextLog(text);
+ game.makeTextLog("PAUSED
", 1);
+ // let text = "PAUSED
"
+ // //output current mod, field, and gun info when paused
+ // if (mech.fieldMode !== 0) text += "
" + mech.fieldUpgrades[mech.fieldMode].name + "
" + mech.fieldUpgrades[mech.fieldMode].description + "
"
+ // if (b.mod !== null) text += "
" + b.mods[b.mod].name + "
" + b.mods[b.mod].description + "
"
+ // if (b.activeGun !== null) text += "
" + b.guns[b.activeGun].name + "
" + b.guns[b.activeGun].description + "
"
+ // text += "
"
+ // game.makeTextLog(text, 1);
}
}
@@ -270,9 +284,9 @@ const game = {
if (keys[70]) { //cycle fields with F
if (mech.fieldMode === mech.fieldUpgrades.length - 1) {
- mech.fieldUpgrades[0]()
+ mech.fieldUpgrades[0].effect()
} else {
- mech.fieldUpgrades[mech.fieldMode + 1]()
+ mech.fieldUpgrades[mech.fieldMode + 1].effect()
}
}
if (keys[71]) { // give all guns with G
@@ -361,8 +375,11 @@ const game = {
},
wipe() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
- // ctx.fillStyle = "#000";
+
+ // ctx.fillStyle = "rgba(255,255,255,1)";
+ // ctx.globalCompositeOperation = "difference";
// ctx.fillRect(0, 0, canvas.width, canvas.height);
+ // ctx.globalCompositeOperation = "source-over";
// ctx.globalAlpha = (mech.health < 0.7) ? (mech.health+0.3)*(mech.health+0.3) : 1
// if (mech.health < 0.7) {
@@ -393,11 +410,11 @@ const game = {
b.guns[i].have = false;
if (b.guns[i].ammo != Infinity) b.guns[i].ammo = 0;
}
+ b.activeGun = null;
game.paused = false;
engine.timing.timeScale = 1;
game.dmgScale = 1;
b.dmgScale = 0.7;
- b.activeGun = null;
game.makeGunHUD();
mech.drop();
mech.addHealth(1);
@@ -408,8 +425,7 @@ const game = {
document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0;
document.title = "n-gon";
- // mech.fieldUpgrades[0](); //reset to starting field? or let them keep the field
- if (!mech.fieldMode) mech.fieldUpgrades[0](); //reset to starting field? or let them keep the field
+ if (!mech.fieldMode) mech.fieldUpgrades[0].effect(); //reset to starting field? or let them keep the field
},
firstRun: true,
splashReturn() {
diff --git a/js/index.js b/js/index.js
index ae179bb..0923788 100644
--- a/js/index.js
+++ b/js/index.js
@@ -2,6 +2,9 @@
/* TODO: *******************************************
*****************************************************
+make player legs just slide if the player is above the normal speed
+ like when you fire the one shot
+
make power ups keep moving to player if the field is turned off
levels spawn by having the map aspects randomly fly into place
diff --git a/js/level.js b/js/level.js
index 7b75d31..09c8a0a 100644
--- a/js/level.js
+++ b/js/level.js
@@ -12,11 +12,11 @@ const level = {
onLevel: 0,
start() {
if (game.levelsCleared === 0) {
- // game.levelsCleared = 5; //for testing to simulate possible mobs spawns
+ // game.levelsCleared = 6; //for testing to simulate possible mobs spawns
// b.giveGuns("all", 1000)
// b.giveGuns(3) // set a starting gun for testing
- // mech.fieldUpgrades[2](); //give a field power up for testing
- // b.mods[6].effect(); //give specific mod
+ // mech.fieldUpgrades[2].effect(); //give a field power up for testing
+ // b.mods[7].effect(); //give specific mod
this.intro(); //starting level
// this.testingMap();
@@ -28,11 +28,11 @@ const level = {
// this.office();
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
- this[this.levels[this.onLevel]](); //picks the current map from the the levels array
- this.levelAnnounce();
+ level[level.levels[level.onLevel]](); //picks the current map from the the levels array
+ level.levelAnnounce();
}
game.setZoom();
- this.addToWorld(); //add bodies to game engine
+ level.addToWorld(); //add bodies to game engine
game.draw.setPaths();
},
difficultyIncrease() {
diff --git a/js/player.js b/js/player.js
index 1ca8e98..0b2ddeb 100644
--- a/js/player.js
+++ b/js/player.js
@@ -358,7 +358,61 @@ const mech = {
},
alive: true,
death() {
- if (this.alive) {
+ if (b.modIsImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
+ //remove mod
+ b.mod = null
+ b.setModDefaults();
+ b.modText();
+
+ //randomize guns
+ b.activeGun = null;
+ b.inventory = []; //removes guns and ammo
+ for (let i = 0, len = b.guns.length; i < len; ++i) {
+ b.guns[i].have = false;
+ if (b.guns[i].ammo != Infinity) b.guns[i].ammo = 0;
+ }
+ if (game.levelsCleared > 0) powerUps.gun.effect();
+ if (game.levelsCleared > 1) powerUps.gun.effect();
+ if (game.levelsCleared > 3) powerUps.gun.effect();
+ if (game.levelsCleared > 6) powerUps.gun.effect();
+ game.makeGunHUD();
+
+ //randomize field
+
+ if (game.levelsCleared > 5) {
+ mech.fieldUpgrades[Math.floor(Math.random() * (mech.fieldUpgrades.length))].effect();
+ } else {
+ mech.fieldUpgrades[0].effect();
+ }
+
+ mech.addHealth(1);
+ spawn.setSpawnList();
+ game.clearNow = true;
+
+ game.wipe = function () { //set wipe to have trails
+ ctx.fillStyle = "rgba(255,255,255,0.01)";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+
+ for (let i = 0; i < 7; i++) {
+ setTimeout(function () {
+ game.makeTextLog(` probability amplitude will synchronize in ${7-i} seconds
`, 1000);
+ game.wipe = function () { //set wipe to have trails
+ ctx.fillStyle = `rgba(255,255,255,${(i+1)*0.04})`;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+ }, (i + 1) * 1000);
+ }
+
+ setTimeout(function () {
+ game.wipe = function () { //set wipe to normal
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ }
+ game.makeTextLog("Quantum Immortality has stabilized your probability amplitude
welcome to your new reality
", 1000);
+ document.title = "n-gon: L" + (game.levelsCleared) + " " + level.levels[level.onLevel] + " version 2";
+ }, 8000);
+
+ } else if (this.alive) { //normal death code here
this.alive = false;
game.paused = true;
this.health = 0;
@@ -844,355 +898,387 @@ const mech = {
}
},
hold() {},
- fieldUpgrades: [
- () => {
- mech.fieldMode = 0;
- game.makeTextLog("Field Emitter
(right click or space bar)lets you pick up and throw objects
shields you from damage
", 1200);
- mech.setHoldDefaults();
- mech.hold = function () {
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
- mech.drawField();
- mech.grabPowerUp();
- mech.pushMobs();
- mech.lookForPickUp();
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.pickUp();
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ fieldText() {
+ game.makeTextLog(`${mech.fieldUpgrades[mech.fieldMode].name}
(right click or space bar)${mech.fieldUpgrades[mech.fieldMode].description}
`, 1200);
+ game.updateModHUD()
+ },
+ fieldUpgrades: [{
+ name: "Field Emitter",
+ description: "lets you pick up and throw objects
shields you from damage",
+ effect: () => {
+ mech.fieldMode = 0;
+ mech.fieldText();
+ // game.makeTextLog("
(right click or space bar)", 1200);
+ mech.setHoldDefaults();
+ mech.hold = function () {
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
+ mech.drawField();
+ mech.grabPowerUp();
+ mech.pushMobs();
+ mech.lookForPickUp();
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.pickUp();
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ }
+ mech.drawFieldMeter()
}
- mech.drawFieldMeter()
}
},
- () => {
- mech.fieldMode = 1;
- game.makeTextLog("Time Dilation Field
(right click or space bar) stop time while field is active
can fire while field is active
", 1200);
- mech.setHoldDefaults();
- mech.fieldFire = true;
- mech.grabRange = 130
- mech.isBodiesAsleep = false;
- mech.hold = function () {
- if (mech.isHolding) {
- mech.wakeCheck();
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
- const DRAIN = 0.0022
- if (mech.fieldMeter > DRAIN) {
- mech.fieldMeter -= DRAIN;
+ {
+ name: "Time Dilation Field",
+ description: "stop time while field is active
can fire while field is active",
+ effect: () => {
+ mech.fieldMode = 1;
+ mech.fieldText();
+ mech.setHoldDefaults();
+ mech.fieldFire = true;
+ mech.grabRange = 130
+ mech.isBodiesAsleep = false;
+ mech.hold = function () {
+ if (mech.isHolding) {
+ mech.wakeCheck();
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
+ const DRAIN = 0.0027
+ if (mech.fieldMeter > DRAIN) {
+ mech.fieldMeter -= DRAIN;
- //draw field everywhere
- ctx.fillStyle = "rgba(110,170,200," + (0.19 + 0.16 * Math.random()) + ")";
- ctx.fillRect(-100000, -100000, 200000, 200000)
+ //draw field everywhere
+ ctx.fillStyle = "rgba(110,170,200," + (0.19 + 0.16 * Math.random()) + ")";
+ ctx.fillRect(-100000, -100000, 200000, 200000)
- //stop time
- mech.isBodiesAsleep = true;
+ //stop time
+ mech.isBodiesAsleep = true;
- function sleep(who) {
- for (let i = 0, len = who.length; i < len; ++i) {
- if (!who[i].isSleeping) {
- who[i].storeVelocity = who[i].velocity
- who[i].storeAngularVelocity = who[i].angularVelocity
+ function sleep(who) {
+ for (let i = 0, len = who.length; i < len; ++i) {
+ if (!who[i].isSleeping) {
+ who[i].storeVelocity = who[i].velocity
+ who[i].storeAngularVelocity = who[i].angularVelocity
+ }
+ Matter.Sleeping.set(who[i], true)
}
- Matter.Sleeping.set(who[i], true)
}
- }
- sleep(mob);
- sleep(body);
- sleep(bullet);
- //doesn't really work, just slows down constraints
- for (let i = 0, len = cons.length; i < len; i++) {
- if (cons[i].stiffness !== 0) {
- cons[i].storeStiffness = cons[i].stiffness;
- cons[i].stiffness = 0;
+ sleep(mob);
+ sleep(body);
+ sleep(bullet);
+ //doesn't really work, just slows down constraints
+ for (let i = 0, len = cons.length; i < len; i++) {
+ if (cons[i].stiffness !== 0) {
+ cons[i].storeStiffness = cons[i].stiffness;
+ cons[i].stiffness = 0;
+ }
}
- }
- game.cycle--; //pause all functions that depend on game cycle increasing
+ game.cycle--; //pause all functions that depend on game cycle increasing
- mech.grabPowerUp();
- mech.lookForPickUp(180);
+ mech.grabPowerUp();
+ mech.lookForPickUp(180);
+ } else {
+ mech.wakeCheck();
+ mech.fieldCDcycle = mech.cycle + 120;
+ }
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.wakeCheck();
+ mech.pickUp();
} else {
mech.wakeCheck();
- mech.fieldCDcycle = mech.cycle + 120;
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.wakeCheck();
- mech.pickUp();
- } else {
- mech.wakeCheck();
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- }
- mech.drawFieldMeter()
- if (mech.fieldMode !== 1) {
- //wake up if this is no longer the current field mode, like after a new power up
- mech.wakeCheck();
+ mech.drawFieldMeter()
+ if (mech.fieldMode !== 1) {
+ //wake up if this is no longer the current field mode, like after a new power up
+ mech.wakeCheck();
+ }
}
}
},
- () => {
- mech.fieldMode = 2;
- game.makeTextLog("Electrostatic Force Field
(right click or space bar) field does damage on contact
blocks are thrown at a higher velocity
increased field regeneration
", 1200);
- mech.setHoldDefaults();
- //throw quicker and harder
- mech.grabRange = 225;
- mech.fieldShieldingScale = 2;
- mech.fieldRegen *= 3;
- mech.throwChargeRate = 3;
- mech.throwChargeMax = 140;
- mech.fieldDamage = 5; //passive field does extra damage
- // mech.fieldArc = 0.11
- // mech.calculateFieldThreshold(); //run after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
+ {
+ name: "Electrostatic Force Field",
+ description: "field does damage on contact
blocks are thrown at a higher velocity
increased field regeneration",
+ effect: () => {
+ mech.fieldMode = 2;
+ mech.fieldText();
+ mech.setHoldDefaults();
+ //throw quicker and harder
+ mech.grabRange = 225;
+ mech.fieldShieldingScale = 2;
+ mech.fieldRegen *= 3;
+ mech.throwChargeRate = 3;
+ mech.throwChargeMax = 140;
+ mech.fieldDamage = 5; //passive field does extra damage
+ // mech.fieldArc = 0.11
+ // mech.calculateFieldThreshold(); //run after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
- mech.hold = function () {
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.15) { //not hold but field button is pressed
- //draw electricity
- const Dx = Math.cos(mech.angle);
- const Dy = Math.sin(mech.angle);
- let x = mech.pos.x + 20 * Dx;
- let y = mech.pos.y + 20 * Dy;
- ctx.beginPath();
- ctx.moveTo(x, y);
- for (let i = 0; i < 8; i++) {
- x += 18 * (Dx + 2 * (Math.random() - 0.5))
- y += 18 * (Dy + 2 * (Math.random() - 0.5))
- ctx.lineTo(x, y);
- }
- ctx.lineWidth = 1 //0.5 + 2 * Math.random();
- ctx.strokeStyle = `rgba(100,20,50,${0.5+0.5*Math.random()})`;
- ctx.stroke();
-
- //draw field
- const range = 170;
- const arc = Math.PI * 0.11
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - arc, mech.angle + arc, false);
- ctx.lineTo(mech.pos.x + 13 * Math.cos(mech.angle), mech.pos.y + 13 * Math.sin(mech.angle));
- if (mech.holdingTarget) {
- ctx.fillStyle = "rgba(255,50,150," + (0.05 + 0.1 * Math.random()) + ")";
- } else {
- ctx.fillStyle = "rgba(255,50,150," + (0.13 + 0.18 * Math.random()) + ")";
- }
- ctx.fill();
-
- //draw random lines in field for cool effect
- // eye = 15;
- // ctx.beginPath();
- // ctx.moveTo(mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle));
- // const offAngle = mech.angle + 2 * Math.PI * mech.fieldArc * (Math.random() - 0.5);
- // ctx.lineTo(mech.pos.x + range * Math.cos(offAngle), mech.pos.y + range * Math.sin(offAngle));
- // ctx.strokeStyle = "rgba(100,20,50,0.2)";
- // ctx.stroke();
-
- mech.grabPowerUp();
- mech.pushMobs();
- mech.lookForPickUp();
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.pickUp();
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- }
- mech.drawFieldMeter()
- }
- },
- () => {
- mech.fieldMode = 3;
- game.makeTextLog("Negative Mass Field
(right click or space bar) field nullifies gravity
player can hold more massive objects
can fire while field is active
", 1200);
- //
decreased field shielding efficiency
- mech.setHoldDefaults();
- mech.fieldFire = true;
- mech.holdingMassScale = 0.05; //can hold heavier blocks with lower cost to jumping
- mech.fieldShieldingScale = 2;
-
- mech.hold = function () {
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
- const DRAIN = 0.0007
- if (mech.fieldMeter > DRAIN) {
- mech.pushMobs360(170);
- mech.grabPowerUp();
- mech.lookForPickUp(170);
- //look for nearby objects to make zero-g
- function zeroG(who) {
- for (let i = 0, len = who.length; i < len; ++i) {
- sub = Matter.Vector.sub(who[i].position, mech.pos);
- dist = Matter.Vector.magnitude(sub);
- if (dist < mech.grabRange) {
- who[i].force.y -= who[i].mass * (game.g * 1.06); //add a bit more then standard gravity
- }
- }
- }
- zeroG(powerUp);
- zeroG(body);
- // zeroG(bullet); //works fine, but not that noticeable and maybe not worth the possible performance hit
- // zeroG(mob); //mobs are too irregular to make this work?
-
- Matter.Body.setVelocity(player, {
- x: player.velocity.x,
- y: player.velocity.y * 0.97
- });
-
- if (keys[83] || keys[40]) { //down
- player.force.y -= 0.8 * player.mass * mech.gravity;
- mech.grabRange = mech.grabRange * 0.97 + 400 * 0.03;
- } else if (keys[87] || keys[38]) { //up
- mech.fieldMeter -= 3 * DRAIN;
- mech.grabRange = mech.grabRange * 0.97 + 750 * 0.03;
- player.force.y -= 1.2 * player.mass * mech.gravity;
- } else {
- mech.fieldMeter -= DRAIN;
- mech.grabRange = mech.grabRange * 0.97 + 650 * 0.03;
- player.force.y -= 1.07 * player.mass * mech.gravity; // slow upward drift
- }
-
- //add extra friction for horizontal motion
- if (keys[65] || keys[68] || keys[37] || keys[39]) {
- Matter.Body.setVelocity(player, {
- x: player.velocity.x * 0.85,
- y: player.velocity.y
- });
- }
-
- //draw zero-G range
+ mech.hold = function () {
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.15) { //not hold but field button is pressed
+ //draw electricity
+ const Dx = Math.cos(mech.angle);
+ const Dy = Math.sin(mech.angle);
+ let x = mech.pos.x + 20 * Dx;
+ let y = mech.pos.y + 20 * Dy;
ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, mech.grabRange, 0, 2 * Math.PI);
- ctx.fillStyle = "#f5f5ff";
- ctx.globalCompositeOperation = "difference";
- ctx.fill();
- ctx.globalCompositeOperation = "source-over";
- } else {
- //trigger cool down
- mech.fieldCDcycle = mech.cycle + 120;
- }
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.pickUp();
- mech.grabRange = 0
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- mech.grabRange = 0
- }
- mech.drawFieldMeter()
- }
- },
- () => {
- mech.fieldMode = 4;
- game.makeTextLog("Standing Wave Harmonics
(right click or space bar) oscillating shields always surround player
decreased field regeneration
", 1200);
- mech.setHoldDefaults();
- // mech.fieldShieldingScale = 0.5;
- mech.fieldRegen *= 0.2;
-
- mech.hold = function () {
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
- mech.grabPowerUp();
- mech.lookForPickUp(180);
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle) { //holding, but field button is released
- mech.pickUp();
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- }
- if (mech.fieldMeter > 0.1) {
- const grabRange1 = 85 + 60 * Math.sin(mech.cycle / 23)
- const grabRange2 = 80 + 70 * Math.sin(mech.cycle / 37)
- const grabRange3 = 70 + 70 * Math.sin(mech.cycle / 47)
- const netGrabRange = Math.max(grabRange1, grabRange2, grabRange3)
- ctx.fillStyle = "rgba(110,170,200," + (0.15 + 0.15 * Math.random()) + ")";
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, grabRange1, 0, 2 * Math.PI);
- ctx.fill();
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, grabRange2, 0, 2 * Math.PI);
- ctx.fill();
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, grabRange3, 0, 2 * Math.PI);
- ctx.fill();
- mech.pushMobs360(netGrabRange);
- }
- mech.drawFieldMeter()
- }
- },
- () => {
- mech.fieldMode = 5;
- game.makeTextLog("Nano-Scale Manufacturing
(passive effect) excess field energy used to build drones
increased field regeneration
", 1200);
- mech.setHoldDefaults();
- mech.fieldRegen *= 3;
- mech.hold = function () {
- if (mech.fieldMeter === 1) {
- mech.fieldMeter -= 0.5;
- b.guns[12].fire() //spawn drone
- }
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
- mech.pushMobs();
- mech.drawField();
- mech.grabPowerUp();
- mech.lookForPickUp();
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.pickUp();
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- }
- mech.drawFieldMeter()
- }
- },
- () => {
- mech.fieldMode = 6;
- game.makeTextLog("Phase Decoherence Field
(right click or space bar) intangible while field is active
can't see or be seen outside field
", 1200);
- mech.setHoldDefaults();
- // mech.grabRange = 230
- mech.hold = function () {
- mech.isStealth = false //isStealth is checked in mob foundPlayer()
- player.collisionFilter.mask = 0x010011 //0x010011 is normal
- if (mech.isHolding) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throw();
- } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
- const DRAIN = 0.002
- if (mech.fieldMeter > DRAIN) {
- mech.fieldMeter -= DRAIN;
-
- mech.isStealth = true //isStealth is checked in mob foundPlayer()
- player.collisionFilter.mask = 0x000001 //0x010011 is normals
-
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, mech.grabRange, 0, 2 * Math.PI);
- ctx.globalCompositeOperation = "destination-in"; //in or atop
- ctx.fillStyle = "rgba(255,255,255,0.25)";
- ctx.fill();
- ctx.globalCompositeOperation = "source-over";
- ctx.strokeStyle = "#000"
- ctx.lineWidth = 2;
+ ctx.moveTo(x, y);
+ for (let i = 0; i < 8; i++) {
+ x += 18 * (Dx + 2 * (Math.random() - 0.5))
+ y += 18 * (Dy + 2 * (Math.random() - 0.5))
+ ctx.lineTo(x, y);
+ }
+ ctx.lineWidth = 1 //0.5 + 2 * Math.random();
+ ctx.strokeStyle = `rgba(100,20,50,${0.5+0.5*Math.random()})`;
ctx.stroke();
+ //draw field
+ const range = 170;
+ const arc = Math.PI * 0.11
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - arc, mech.angle + arc, false);
+ ctx.lineTo(mech.pos.x + 13 * Math.cos(mech.angle), mech.pos.y + 13 * Math.sin(mech.angle));
+ if (mech.holdingTarget) {
+ ctx.fillStyle = "rgba(255,50,150," + (0.05 + 0.1 * Math.random()) + ")";
+ } else {
+ ctx.fillStyle = "rgba(255,50,150," + (0.13 + 0.18 * Math.random()) + ")";
+ }
+ ctx.fill();
+
+ //draw random lines in field for cool effect
+ // eye = 15;
+ // ctx.beginPath();
+ // ctx.moveTo(mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle));
+ // const offAngle = mech.angle + 2 * Math.PI * mech.fieldArc * (Math.random() - 0.5);
+ // ctx.lineTo(mech.pos.x + range * Math.cos(offAngle), mech.pos.y + range * Math.sin(offAngle));
+ // ctx.strokeStyle = "rgba(100,20,50,0.2)";
+ // ctx.stroke();
+
mech.grabPowerUp();
- mech.lookForPickUp(110);
+ mech.pushMobs();
+ mech.lookForPickUp();
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.pickUp();
} else {
- mech.fieldCDcycle = mech.cycle + 120;
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
- } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
- mech.pickUp();
- } else {
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ mech.drawFieldMeter()
+ }
+ }
+ },
+ {
+ name: "Negative Mass Field",
+ description: "field nullifies gravity
player can hold more massive objects
can fire while field is active",
+ effect: () => {
+ mech.fieldMode = 3;
+ mech.fieldText();
+ //
decreased field shielding efficiency
+ mech.setHoldDefaults();
+ mech.fieldFire = true;
+ mech.holdingMassScale = 0.05; //can hold heavier blocks with lower cost to jumping
+ mech.fieldShieldingScale = 2;
+
+ mech.hold = function () {
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
+ const DRAIN = 0.0006
+ if (mech.fieldMeter > DRAIN) {
+ mech.pushMobs360(170);
+ mech.grabPowerUp();
+ mech.lookForPickUp(170);
+ //look for nearby objects to make zero-g
+ function zeroG(who) {
+ for (let i = 0, len = who.length; i < len; ++i) {
+ sub = Matter.Vector.sub(who[i].position, mech.pos);
+ dist = Matter.Vector.magnitude(sub);
+ if (dist < mech.grabRange) {
+ who[i].force.y -= who[i].mass * (game.g * 1.06); //add a bit more then standard gravity
+ }
+ }
+ }
+ zeroG(powerUp);
+ zeroG(body);
+ // zeroG(bullet); //works fine, but not that noticeable and maybe not worth the possible performance hit
+ // zeroG(mob); //mobs are too irregular to make this work?
+
+ Matter.Body.setVelocity(player, {
+ x: player.velocity.x,
+ y: player.velocity.y * 0.97
+ });
+
+ if (keys[83] || keys[40]) { //down
+ player.force.y -= 0.8 * player.mass * mech.gravity;
+ mech.grabRange = mech.grabRange * 0.97 + 400 * 0.03;
+ } else if (keys[87] || keys[38]) { //up
+ mech.fieldMeter -= 3 * DRAIN;
+ mech.grabRange = mech.grabRange * 0.97 + 750 * 0.03;
+ player.force.y -= 1.2 * player.mass * mech.gravity;
+ } else {
+ mech.fieldMeter -= DRAIN;
+ mech.grabRange = mech.grabRange * 0.97 + 650 * 0.03;
+ player.force.y -= 1.07 * player.mass * mech.gravity; // slow upward drift
+ }
+
+ //add extra friction for horizontal motion
+ if (keys[65] || keys[68] || keys[37] || keys[39]) {
+ Matter.Body.setVelocity(player, {
+ x: player.velocity.x * 0.85,
+ y: player.velocity.y
+ });
+ }
+
+ //draw zero-G range
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, mech.grabRange, 0, 2 * Math.PI);
+ ctx.fillStyle = "#f5f5ff";
+ ctx.globalCompositeOperation = "difference";
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+ } else {
+ //trigger cool down
+ mech.fieldCDcycle = mech.cycle + 120;
+ }
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.pickUp();
+ mech.grabRange = 0
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ mech.grabRange = 0
+ }
+ mech.drawFieldMeter()
+ }
+ }
+ },
+ {
+ name: "Standing Wave Harmonics",
+ description: "oscillating shields always surround player
decreased field regeneration",
+ effect: () => {
+ mech.fieldMode = 4;
+ mech.fieldText();
+ mech.setHoldDefaults();
+ // mech.fieldShieldingScale = 0.5;
+ mech.fieldRegen *= 0.2;
+
+ mech.hold = function () {
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
+ mech.grabPowerUp();
+ mech.lookForPickUp(180);
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle) { //holding, but field button is released
+ mech.pickUp();
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ }
+ if (mech.fieldMeter > 0.1) {
+ const grabRange1 = 90 + 60 * Math.sin(mech.cycle / 23)
+ const grabRange2 = 85 + 70 * Math.sin(mech.cycle / 37)
+ const grabRange3 = 80 + 80 * Math.sin(mech.cycle / 47)
+ const netGrabRange = Math.max(grabRange1, grabRange2, grabRange3)
+ ctx.fillStyle = "rgba(110,170,200," + (0.15 + 0.15 * Math.random()) + ")";
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, grabRange1, 0, 2 * Math.PI);
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, grabRange2, 0, 2 * Math.PI);
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, grabRange3, 0, 2 * Math.PI);
+ ctx.fill();
+ mech.pushMobs360(netGrabRange);
+ }
+ mech.drawFieldMeter()
+ }
+ }
+ },
+ {
+ name: "Nano-Scale Manufacturing",
+ description: "excess field energy used to build drones
increased field regeneration",
+ effect: () => {
+ mech.fieldMode = 5;
+ mech.fieldText();
+ mech.setHoldDefaults();
+ mech.fieldRegen *= 3.5;
+ mech.hold = function () {
+ if (mech.fieldMeter === 1) {
+ mech.fieldMeter -= 0.5;
+ b.guns[12].fire() //spawn drone
+ }
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
+ mech.pushMobs();
+ mech.drawField();
+ mech.grabPowerUp();
+ mech.lookForPickUp();
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.pickUp();
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ }
+ mech.drawFieldMeter()
+ }
+ }
+ },
+ {
+ name: "Phase Decoherence Field",
+ description: "intangible while field is active
can't see or be seen outside field",
+ effect: () => {
+ mech.fieldMode = 6;
+ mech.fieldText();
+ mech.setHoldDefaults();
+ // mech.grabRange = 230
+ mech.hold = function () {
+ mech.isStealth = false //isStealth is checked in mob foundPlayer()
+ player.collisionFilter.mask = 0x010011 //0x010011 is normal
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throw();
+ } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
+ const DRAIN = 0.002
+ if (mech.fieldMeter > DRAIN) {
+ mech.fieldMeter -= DRAIN;
+
+ mech.isStealth = true //isStealth is checked in mob foundPlayer()
+ player.collisionFilter.mask = 0x000001 //0x010011 is normals
+
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, mech.grabRange, 0, 2 * Math.PI);
+ ctx.globalCompositeOperation = "destination-in"; //in or atop
+ ctx.fillStyle = "rgba(255,255,255,0.25)";
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+ ctx.strokeStyle = "#000"
+ ctx.lineWidth = 2;
+ ctx.stroke();
+
+ mech.grabPowerUp();
+ mech.lookForPickUp(110);
+ } else {
+ mech.fieldCDcycle = mech.cycle + 120;
+ }
+ } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
+ mech.pickUp();
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ }
+ mech.drawFieldMeter()
}
- mech.drawFieldMeter()
}
},
// () => {
diff --git a/js/powerups.js b/js/powerups.js
index 84108d6..b43db1a 100644
--- a/js/powerups.js
+++ b/js/powerups.js
@@ -28,9 +28,9 @@ const powerUps = {
while (mode === mech.fieldMode) {
mode = Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))
}
- mech.fieldUpgrades[mode](); //choose random field upgrade that you don't already have
+ mech.fieldUpgrades[mode].effect(); //choose random field upgrade that you don't already have
} else {
- mech.fieldUpgrades[this.mode](); //set a predetermined power up
+ mech.fieldUpgrades[this.mode].effect(); //set a predetermined power up
}
//pop the old field out in case player wants to swap back
if (previousMode !== 0) {
diff --git a/js/spawn.js b/js/spawn.js
index aa89bec..6ab1a6e 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -491,12 +491,12 @@ const spawn = {
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)
- if (game.levelsCleared > 6) {
- for (let i = 0; i < (game.levelsCleared - 5); ++i) {
- spawn.sucker(this.position.x + (Math.random() - 0.5) * radius * 2, this.position.y + (Math.random() - 0.5) * radius * 2, 20);
+ if (game.levelsCleared > 5) {
+ for (let i = 0; i < (game.levelsCleared - 3); ++i) {
+ spawn.sucker(this.position.x + (Math.random() - 0.5) * radius * 2, this.position.y + (Math.random() - 0.5) * radius * 2, 70 * Math.random());
Matter.Body.setVelocity(mob[mob.length - 1], {
- x: (Math.random() - 0.5) * 25,
- y: (Math.random() - 0.5) * 25
+ x: (Math.random() - 0.5) * 70,
+ y: (Math.random() - 0.5) * 70
});
}
}
@@ -540,7 +540,7 @@ const spawn = {
ctx.fill();
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI);
- ctx.fillStyle = "rgba(0,20,40,0.05)";
+ ctx.fillStyle = "rgba(0,0,0,0.05)";
ctx.fill();
//when player is inside event horizon
if (Matter.Vector.magnitude(Matter.Vector.sub(this.position, player.position)) < eventHorizon) {
diff --git a/style.css b/style.css
index 32cdab1..a2fed17 100644
--- a/style.css
+++ b/style.css
@@ -68,8 +68,8 @@ summary {
#health-bg {
position: absolute;
- top: 30px;
- left: 40px;
+ top: 15px;
+ left: 15px;
height: 20px;
width: 300px;
background-color: #000;
@@ -81,8 +81,8 @@ summary {
#health {
position: absolute;
- top: 30px;
- left: 40px;
+ top: 15px;
+ left: 15px;
height: 20px;
width: 0px;
transition: width 1s ease-out;
@@ -119,10 +119,10 @@ summary {
#guns {
position: absolute;
- top: 55px;
- left: 40px;
+ top: 40px;
+ left: 15px;
z-index: 2;
- font-size: 25px;
+ font-size: 23px;
color: #111;
background-color: rgba(255, 255, 255, 0.4);
user-select: none;
@@ -134,12 +134,14 @@ summary {
#mods {
position: absolute;
- top: 20px;
- right: 20px;
+ top: 15px;
+ right: 15px;
z-index: 2;
- font-size: 21px;
- color: #111;
+ font-size: 19px;
+ color: #000;
+ text-align: right;
opacity: 0.5;
+ line-height: 140%;
background-color: rgba(255, 255, 255, 0.4);
user-select: none;
pointer-events: none;