From f6238ff882e7458519c6a522d65a6ec6f7147b42 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 15 Mar 2020 19:31:47 -0700 Subject: [PATCH] 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 --- js/bullets.js | 25 +++++++++-- js/engine.js | 1 - js/game.js | 35 ++++++++++++--- js/player.js | 116 ++++++++++++++++++++++++++++++-------------------- todo.txt | 11 +++++ 5 files changed, 132 insertions(+), 56 deletions(-) diff --git a/js/bullets.js b/js/bullets.js index 27d1ecd..fead1b2 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -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 stuns mobs for 1 second
with the perfect diamagnetism 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 plasma torch's range by 33%", @@ -1107,7 +1124,7 @@ const b = { }, requires: "standing wave harmonics
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 precise volley of high velocity needles
needles deliver chemical damage over 3 seconds", + description: "fire a precise volley of high velocity needles
that apply chemical damage over 3 seconds", ammo: 0, ammoPack: 23, defaultAmmoPack: 23, @@ -2502,7 +2519,7 @@ const b = { }, { name: "vacuum bomb", //8 - description: "fire a bomb that sucks before exploding
click left mouse again to detonate", + description: "fire a bomb that sucks before exploding
click left mouse again to detonate", ammo: 0, ammoPack: 2, have: false, @@ -3032,7 +3049,7 @@ const b = { }, { name: "laser", //14 - description: "emit a beam of collimated coherent light
drains energy instead of ammunition", + description: "emit a beam of collimated coherent light
drains energy instead of ammunition", ammo: 0, ammoPack: Infinity, have: false, diff --git a/js/engine.js b/js/engine.js index fa8d0e4..83d047b 100644 --- a/js/engine.js +++ b/js/engine.js @@ -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 diff --git a/js/game.js b/js/game.js index 375dd43..e0b63d9 100644 --- a/js/game.js +++ b/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); } } }, diff --git a/js/player.js b/js/player.js index c2258ea..3387021 100644 --- a/js/player.js +++ b/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 energy when blocking
no recoil when blocking", - description: "blocking produces energy
blocking has no recoil or cool down", + description: "blocking does not drain energy
blocking has no cool down and less recoil", 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 energy to stop time
can fire bullets while field is active", + description: "use energy to stop time
you can move and fire while time is stopped", isEasyToAim: true, effect: () => { + // mech.fieldMeterColor = "#000" mech.fieldFire = true; mech.isBodiesAsleep = false; mech.hold = function () { @@ -1281,6 +1300,8 @@ const mech = { description: "use energy to emit damaging plasma
effective at close range", 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 energy to become intangible
moving and touching shields amplifies cost", 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 diff --git a/todo.txt b/todo.txt index e357ec8..54a112d 100644 --- a/todo.txt +++ b/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