perfect diamagnetism balance
perfect diamagnetism balance and graphics unique energy colors for fields game info on pause screen falling off the map, on easy and normal difficulty sets the player to the entrance sets power ups to the exit
This commit is contained in:
@@ -65,6 +65,7 @@ const b = {
|
||||
isModIceCrystals: null,
|
||||
modThrowChargeRate: null,
|
||||
isModBlockStun: null,
|
||||
isModStunField: null,
|
||||
modOnHealthChange() { //used with acid mod
|
||||
if (b.isModAcidDmg && mech.health > 0.8) {
|
||||
game.playerDmgColor = "rgba(0,80,80,0.9)"
|
||||
@@ -1065,6 +1066,22 @@ const b = {
|
||||
b.modLaserFieldDrain = 0.002;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "daze",
|
||||
description: "blocking <strong>stuns</strong> mobs for 1 second<br>with the <strong>perfect diamagnetism</strong> field",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism"
|
||||
},
|
||||
requires: "perfect diamagnetism",
|
||||
effect() {
|
||||
b.isModStunField += 60;
|
||||
},
|
||||
remove() {
|
||||
b.isModStunField = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "plasma jet",
|
||||
description: "increase <strong>plasma torch's</strong> range by <strong>33%</strong>",
|
||||
@@ -1107,7 +1124,7 @@ const b = {
|
||||
},
|
||||
requires: "standing wave harmonics<br>or perfect diamagnetism",
|
||||
effect() {
|
||||
b.modBlockDmg += 0.6 //if you change this value also update the for loop in the electricity graphics in mech.pushMass
|
||||
b.modBlockDmg += 0.4 //if you change this value also update the for loop in the electricity graphics in mech.pushMass
|
||||
},
|
||||
remove() {
|
||||
b.modBlockDmg = 0;
|
||||
@@ -2238,7 +2255,7 @@ const b = {
|
||||
},
|
||||
{
|
||||
name: "fléchettes", //3
|
||||
description: "fire a <strong>precise</strong> volley of <strong>high velocity</strong> needles<br>needles deliver <strong class='color-p'>chemical</strong> <strong class='color-d'>damage</strong> over 3 seconds",
|
||||
description: "fire a <strong>precise</strong> volley of <strong>high velocity</strong> needles<br>that apply <strong class='color-p'>chemical</strong> <strong class='color-d'>damage</strong> over 3 seconds",
|
||||
ammo: 0,
|
||||
ammoPack: 23,
|
||||
defaultAmmoPack: 23,
|
||||
@@ -2502,7 +2519,7 @@ const b = {
|
||||
},
|
||||
{
|
||||
name: "vacuum bomb", //8
|
||||
description: "fire a bomb that <strong>sucks</strong> before <strong class='color-e'>exploding</strong><br>click left mouse again to <strong>detonate</strong>",
|
||||
description: "fire a bomb that <strong>sucks</strong> before <strong class='color-e'>exploding</strong><br><strong>click</strong> left mouse again to <strong>detonate</strong>",
|
||||
ammo: 0,
|
||||
ammoPack: 2,
|
||||
have: false,
|
||||
@@ -3032,7 +3049,7 @@ const b = {
|
||||
},
|
||||
{
|
||||
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: "emit a <strong>beam</strong> of collimated coherent <strong>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
|
||||
ammo: 0,
|
||||
ammoPack: Infinity,
|
||||
have: false,
|
||||
|
||||
@@ -184,7 +184,6 @@ function collisionChecks(event) {
|
||||
// console.log(obj.dmg / (0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))))
|
||||
if (b.isModCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
|
||||
mob[k].foundPlayer();
|
||||
// console.log(dmg)
|
||||
mob[k].damage(dmg);
|
||||
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
|
||||
game.drawList.push({ //add dmg to draw queue
|
||||
|
||||
35
js/game.js
35
js/game.js
@@ -658,7 +658,21 @@ const game = {
|
||||
},
|
||||
checks() {
|
||||
if (mech.pos.y > game.fallHeight) { // if 4000px deep
|
||||
mech.death();
|
||||
if (game.difficultyMode > 2) {
|
||||
mech.death();
|
||||
} else {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
Matter.Body.setPosition(player, {
|
||||
x: level.enter.x + 50,
|
||||
y: level.enter.y - 20
|
||||
});
|
||||
mech.energy = 0;
|
||||
if (game.difficultyMode === 2) mech.damage(0.3);
|
||||
if (game.difficultyMode === 1) mech.damage(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(mech.cycle % 60)) { //once a second
|
||||
@@ -680,18 +694,29 @@ const game = {
|
||||
}
|
||||
|
||||
if (!(game.cycle % 420)) { //once every 7 seconds
|
||||
fallCheck = function (who) {
|
||||
fallCheck = function (who, save = false) {
|
||||
let i = who.length;
|
||||
while (i--) {
|
||||
if (who[i].position.y > game.fallHeight) {
|
||||
Matter.World.remove(engine.world, who[i]);
|
||||
who.splice(i, 1);
|
||||
if (save && game.difficultyMode < 2) {
|
||||
Matter.Body.setVelocity(who[i], {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
Matter.Body.setPosition(who[i], {
|
||||
x: level.exit.x + 30 * (Math.random() - 0.5),
|
||||
y: level.exit.y + 30 * (Math.random() - 0.5)
|
||||
});
|
||||
} else {
|
||||
Matter.World.remove(engine.world, who[i]);
|
||||
who.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
fallCheck(mob);
|
||||
fallCheck(body);
|
||||
fallCheck(powerUp);
|
||||
fallCheck(powerUp, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
116
js/player.js
116
js/player.js
@@ -682,6 +682,7 @@ const mech = {
|
||||
setHoldDefaults() {
|
||||
if (mech.energy < mech.fieldEnergyMax) mech.energy = mech.fieldEnergyMax;
|
||||
mech.fieldRegen = 0.001;
|
||||
mech.fieldMeterColor = "#0cf"
|
||||
mech.fieldShieldingScale = 1;
|
||||
mech.fieldDamageResistance = 1;
|
||||
mech.fieldFire = false;
|
||||
@@ -694,6 +695,7 @@ const mech = {
|
||||
mech.isBodiesAsleep = true;
|
||||
mech.wakeCheck();
|
||||
},
|
||||
fieldMeterColor: "#0cf",
|
||||
drawFieldMeter(range = 60) {
|
||||
if (mech.energy < mech.fieldEnergyMax) {
|
||||
mech.energy += mech.fieldRegen;
|
||||
@@ -701,7 +703,7 @@ const mech = {
|
||||
const xOff = mech.pos.x - mech.radius * mech.fieldEnergyMax
|
||||
const yOff = mech.pos.y - 50
|
||||
ctx.fillRect(xOff, yOff, range * mech.fieldEnergyMax, 10);
|
||||
ctx.fillStyle = "#0cf";
|
||||
ctx.fillStyle = mech.fieldMeterColor;
|
||||
ctx.fillRect(xOff, yOff, range * mech.energy, 10);
|
||||
}
|
||||
// else {
|
||||
@@ -817,7 +819,7 @@ const mech = {
|
||||
} else {
|
||||
mech.drop()
|
||||
}
|
||||
} else if (mech.throwCharge > 0) {
|
||||
} else if (mech.throwCharge > 0) { //Matter.Query.region(mob, player.bounds)
|
||||
//throw the body
|
||||
mech.fieldCDcycle = mech.cycle + 15;
|
||||
mech.isHolding = false;
|
||||
@@ -838,12 +840,13 @@ const mech = {
|
||||
setTimeout(solid, 150, mech.holdingTarget);
|
||||
|
||||
const charge = Math.min(mech.throwCharge / 5, 1)
|
||||
const speed = charge * Math.min(80, 64 / Math.pow(mech.holdingTarget.mass, 0.25));
|
||||
let speed = charge * Math.min(80, 64 / Math.pow(mech.holdingTarget.mass, 0.25));
|
||||
if (Matter.Query.collides(mech.holdingTarget, map).length !== 0) speed = 0
|
||||
|
||||
mech.throwCharge = 0;
|
||||
Matter.Body.setVelocity(mech.holdingTarget, {
|
||||
x: player.velocity.x + Math.cos(mech.angle) * speed,
|
||||
y: player.velocity.y + Math.sin(mech.angle) * speed
|
||||
x: player.velocity.x * 0.5 + Math.cos(mech.angle) * speed,
|
||||
y: player.velocity.y * 0.5 + Math.sin(mech.angle) * speed
|
||||
});
|
||||
//player recoil //stronger in x-dir to prevent jump hacking
|
||||
|
||||
@@ -895,34 +898,6 @@ const mech = {
|
||||
ctx.lineWidth = 1;
|
||||
ctx.stroke();
|
||||
},
|
||||
drawDiamagneticField(wave) {
|
||||
if (mech.holdingTarget) {
|
||||
ctx.fillStyle = "rgba(110,170,200," + (0.06 + 0.03 * Math.random()) + ")";
|
||||
ctx.strokeStyle = "rgba(110, 200, 235, " + (0.35 + 0.05 * Math.random()) + ")" //"#9bd" //"rgba(110, 200, 235, " + (0.5 + 0.1 * Math.random()) + ")"
|
||||
} else {
|
||||
ctx.fillStyle = "rgba(110,170,200," + (0.20 + 0.07 * Math.random() - 0.07 * wave) + ")";
|
||||
ctx.strokeStyle = "rgba(110, 200, 235, " + (0.3 + 0.5 * Math.random()) + ")" //"#9bd" //"rgba(110, 200, 235, " + (0.5 + 0.1 * Math.random()) + ")"
|
||||
}
|
||||
// const off = 2 * Math.cos(game.cycle * 0.1)
|
||||
const range = mech.fieldRange;
|
||||
ctx.beginPath();
|
||||
ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - Math.PI * mech.fieldArc, mech.angle + Math.PI * mech.fieldArc, false);
|
||||
ctx.lineWidth = 2.5 - 1.5 * wave;
|
||||
ctx.lineCap = "butt"
|
||||
ctx.stroke();
|
||||
let eye = 20;
|
||||
const curve = 0.5 + 0.06 * wave
|
||||
let aMag = (1 - curve * 1.2) * Math.PI * mech.fieldArc
|
||||
let a = mech.angle + aMag
|
||||
let cp1x = mech.pos.x + curve * range * Math.cos(a)
|
||||
let cp1y = mech.pos.y + curve * range * Math.sin(a)
|
||||
ctx.quadraticCurveTo(cp1x, cp1y, mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle))
|
||||
a = mech.angle - aMag
|
||||
cp1x = mech.pos.x + curve * range * Math.cos(a)
|
||||
cp1y = mech.pos.y + curve * range * Math.sin(a)
|
||||
ctx.quadraticCurveTo(cp1x, cp1y, mech.pos.x + 1 * range * Math.cos(mech.angle - Math.PI * mech.fieldArc), mech.pos.y + 1 * range * Math.sin(mech.angle - Math.PI * mech.fieldArc))
|
||||
ctx.fill();
|
||||
},
|
||||
grabPowerUp() { //look for power ups to grab with field
|
||||
const grabPowerUpRange2 = 156000 //(mech.fieldRange + 220) * (mech.fieldRange + 220)
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
@@ -962,15 +937,14 @@ const mech = {
|
||||
mech.energy -= fieldBlockCost
|
||||
if (mech.energy < 0) mech.energy = 0;
|
||||
if (mech.energy > mech.fieldEnergyMax) mech.energy = mech.fieldEnergyMax;
|
||||
mech.drawHold(who);
|
||||
mech.holdingTarget = null
|
||||
|
||||
const unit = Vector.normalise(Vector.sub(player.position, who.position))
|
||||
if (b.modBlockDmg) {
|
||||
who.damage(b.modBlockDmg)
|
||||
//draw electricity
|
||||
const step = 40
|
||||
ctx.beginPath();
|
||||
for (let i = 0, len = 2 * b.modBlockDmg / 0.7; i < len; i++) {
|
||||
for (let i = 0, len = 2 * b.modBlockDmg; i < len; i++) {
|
||||
let x = mech.pos.x - 20 * unit.x;
|
||||
let y = mech.pos.y - 20 * unit.y;
|
||||
ctx.moveTo(x, y);
|
||||
@@ -980,10 +954,13 @@ const mech = {
|
||||
ctx.lineTo(x, y);
|
||||
}
|
||||
}
|
||||
ctx.lineWidth = 2.5;
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeStyle = "#f0f";
|
||||
ctx.stroke();
|
||||
} else {
|
||||
mech.drawHold(who);
|
||||
}
|
||||
mech.holdingTarget = null
|
||||
//knock backs
|
||||
if (mech.fieldShieldingScale > 0) {
|
||||
const massRoot = Math.sqrt(Math.min(12, Math.max(0.15, who.mass))); // masses above 12 can start to overcome the push back
|
||||
@@ -1004,11 +981,20 @@ const mech = {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (b.isModStunField) mobs.statusStun(who, b.isModStunField)
|
||||
// mobs.statusSlow(who, b.isModStunField)
|
||||
const massRoot = Math.sqrt(Math.max(0.15, who.mass)); // masses above 12 can start to overcome the push back
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: player.velocity.x - (15 * unit.x) / massRoot,
|
||||
y: player.velocity.y - (15 * unit.y) / massRoot
|
||||
x: player.velocity.x - (20 * unit.x) / massRoot,
|
||||
y: player.velocity.y - (20 * unit.y) / massRoot
|
||||
});
|
||||
if (who.dropPowerUp && player.speed < 12) {
|
||||
const massRootCap = Math.sqrt(Math.min(10, Math.max(0.4, who.mass))); // masses above 12 can start to overcome the push back
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap,
|
||||
y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1181,23 +1167,55 @@ const mech = {
|
||||
{
|
||||
name: "perfect diamagnetism",
|
||||
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
||||
description: "<strong>blocking</strong> produces <strong class='color-f'>energy</strong><br><strong>blocking</strong> has no <strong>recoil</strong> or <strong>cool down</strong>",
|
||||
description: "<strong>blocking</strong> does not drain <strong class='color-f'>energy</strong><br><strong>blocking</strong> has no <strong>cool down</strong> and less <strong>recoil</strong>",
|
||||
isEasyToAim: false,
|
||||
effect: () => {
|
||||
mech.fieldShieldingScale = -2;
|
||||
mech.fieldShieldingScale = 0;
|
||||
mech.fieldMeterColor = "#0af"
|
||||
// mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||
// mech.calculateFieldThreshold();
|
||||
mech.hold = function () {
|
||||
const wave = Math.sin(mech.cycle * 0.025);
|
||||
const wave = Math.sin(mech.cycle * 0.02);
|
||||
mech.fieldRange = 165 + 10 * wave
|
||||
mech.fieldArc = 0.31 + 0.03 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||
mech.fieldArc = 0.3 + 0.03 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||
mech.calculateFieldThreshold();
|
||||
if (mech.isHolding) {
|
||||
mech.drawHold(mech.holdingTarget);
|
||||
mech.holding();
|
||||
mech.throwBlock();
|
||||
} else if ((keys[32] || game.mouseDownRight && mech.energy > 0.05 && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
|
||||
mech.drawDiamagneticField(wave);
|
||||
//draw field
|
||||
if (mech.holdingTarget) {
|
||||
ctx.fillStyle = "rgba(120,190,255," + (0.06 + 0.03 * Math.random()) + ")";
|
||||
ctx.strokeStyle = "rgba(120, 190, 255, " + (0.35 + 0.05 * Math.random()) + ")"
|
||||
} else {
|
||||
ctx.fillStyle = "rgba(120,190,255," + (0.3 + 0.13 * Math.random() - 0.15 * wave) + ")";
|
||||
ctx.strokeStyle = "rgba(120, 190, 255, " + (0.3 + 0.5 * Math.random()) + ")"
|
||||
}
|
||||
// if (mech.holdingTarget) {
|
||||
// ctx.fillStyle = "rgba(110,175,200," + (0.06 + 0.03 * Math.random()) + ")";
|
||||
// ctx.strokeStyle = "rgba(115, 220, 255, " + (0.35 + 0.05 * Math.random()) + ")"
|
||||
// } else {
|
||||
// ctx.fillStyle = "rgba(110,175,200," + (0.20 + 0.07 * Math.random() - 0.1 * wave) + ")";
|
||||
// ctx.strokeStyle = "rgba(115, 220, 255, " + (0.3 + 0.5 * Math.random()) + ")"
|
||||
// }
|
||||
ctx.beginPath();
|
||||
ctx.arc(mech.pos.x, mech.pos.y, mech.fieldRange, mech.angle - Math.PI * mech.fieldArc, mech.angle + Math.PI * mech.fieldArc, false);
|
||||
ctx.lineWidth = 2.5 - 1.5 * wave;
|
||||
ctx.lineCap = "butt"
|
||||
ctx.stroke();
|
||||
const curve = 0.57 + 0.04 * wave
|
||||
const aMag = (1 - curve * 1.2) * Math.PI * mech.fieldArc
|
||||
let a = mech.angle + aMag
|
||||
let cp1x = mech.pos.x + curve * mech.fieldRange * Math.cos(a)
|
||||
let cp1y = mech.pos.y + curve * mech.fieldRange * Math.sin(a)
|
||||
ctx.quadraticCurveTo(cp1x, cp1y, mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle))
|
||||
a = mech.angle - aMag
|
||||
cp1x = mech.pos.x + curve * mech.fieldRange * Math.cos(a)
|
||||
cp1y = mech.pos.y + curve * mech.fieldRange * Math.sin(a)
|
||||
ctx.quadraticCurveTo(cp1x, cp1y, mech.pos.x + 1 * mech.fieldRange * Math.cos(mech.angle - Math.PI * mech.fieldArc), mech.pos.y + 1 * mech.fieldRange * Math.sin(mech.angle - Math.PI * mech.fieldArc))
|
||||
ctx.fill();
|
||||
|
||||
mech.grabPowerUp();
|
||||
mech.lookForPickUp();
|
||||
mech.pushMobsFacing();
|
||||
@@ -1212,9 +1230,10 @@ const mech = {
|
||||
},
|
||||
{
|
||||
name: "time dilation field",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>can fire bullets while field is active</em>",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>you can move and fire while time is stopped</em>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
// mech.fieldMeterColor = "#000"
|
||||
mech.fieldFire = true;
|
||||
mech.isBodiesAsleep = false;
|
||||
mech.hold = function () {
|
||||
@@ -1281,6 +1300,8 @@ const mech = {
|
||||
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br><em>effective at close range</em>",
|
||||
isEasyToAim: false,
|
||||
effect: () => {
|
||||
mech.fieldMeterColor = "#f0f"
|
||||
|
||||
mech.hold = function () {
|
||||
if (mech.isHolding) {
|
||||
mech.drawHold(mech.holdingTarget);
|
||||
@@ -1449,8 +1470,10 @@ const mech = {
|
||||
effect: () => {
|
||||
mech.fieldFire = true;
|
||||
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
||||
// mech.fieldMeterColor = "#000"
|
||||
|
||||
mech.hold = function () {
|
||||
mech.drawFieldMeter()
|
||||
mech.fieldDamageResistance = 1;
|
||||
if (mech.isHolding) {
|
||||
mech.drawHold(mech.holdingTarget);
|
||||
@@ -1566,7 +1589,6 @@ const mech = {
|
||||
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)
|
||||
this.fieldDrawRadius = 0
|
||||
}
|
||||
mech.drawFieldMeter()
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1664,6 +1686,8 @@ const mech = {
|
||||
description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>moving</strong> and touching <strong>shields</strong> amplifies <strong>cost</strong>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
mech.fieldMeterColor = "#fff"
|
||||
|
||||
mech.hold = function () {
|
||||
mech.isStealth = false //isStealth disables most uses of foundPlayer()
|
||||
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
|
||||
|
||||
11
todo.txt
11
todo.txt
@@ -1,6 +1,17 @@
|
||||
perfect diamagnetism balance and graphics
|
||||
unique energy colors for fields
|
||||
game info on pause screen
|
||||
falling off the map, on easy and normal difficulty
|
||||
sets the player to the entrance
|
||||
sets power ups to the exit
|
||||
|
||||
|
||||
|
||||
|
||||
************** TODO - n-gon **************
|
||||
|
||||
perfect diamagnetism should get larger as it blocks more, and then slowly fad back to the normal size
|
||||
|
||||
gun or mod - drones that only last for 2 seconds
|
||||
|
||||
field - the basic field emitter, but no energy loss and no knock back on blocks
|
||||
|
||||
Reference in New Issue
Block a user