field emitter power ups rework (trigger effects with just right click)

This commit is contained in:
landgreen
2019-09-17 05:58:19 -07:00
parent aa3882e34b
commit 869e8af738
4 changed files with 309 additions and 200 deletions

View File

@@ -773,7 +773,7 @@ const b = {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, 4.5, b.fireAttributes(dir)); bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, 4.5, b.fireAttributes(dir));
b.fireProps(mech.crouch ? 60 : 35, mech.crouch ? 30 : 17, dir, me); //cd , speed b.fireProps(mech.crouch ? 60 : 35, mech.crouch ? 25 : 14, dir, me); //cd , speed
b.drawOneBullet(bullet[me].vertices); b.drawOneBullet(bullet[me].vertices);
Matter.Body.setDensity(bullet[me], 0.000001); Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = game.cycle + 100; bullet[me].endCycle = game.cycle + 100;

View File

@@ -2,22 +2,6 @@
/* TODO: ******************************************* /* TODO: *******************************************
***************************************************** *****************************************************
run fast when shift is pressed
drains fieldMeter
walking animation isn't going to look good
give mobs more animal-like behaviors
like rainworld
give mobs something to do when they don't see player
explore map
eat power ups
drop power up (if killed after eating one)
mobs some times aren't aggressive
when low on life or after taking a large hit
mobs can fight each other
this might be hard to code
isolated mobs try to group up.
general gun power ups general gun power ups
+explosion radius +explosion radius
+dmg +dmg
@@ -29,20 +13,21 @@ general gun power ups
orbiting orb fires at random targets orbiting orb fires at random targets
missiles at random targets missiles at random targets
specific gun power ups have mob acceleration and look frequency scale with difficulty level
laser: less energy use this will speed up the responses of later mobs
rapid fire: less drag, less gravity, less randomness this should provide a feeling of difficulty without inflating the life of mobs
one shot: larger bullet
super balls: fire 4 balls give mobs more animal-like behaviors
spray: less drag +range like rainworld
needles: +dmg, or faster fire rate give mobs something to do when they don't see player
missiles: larger explosion radius explore map
flak: + more projectiles per shot eat power ups
M80: larger explosion radius drop power up (if killed after eating one)
grenades: larger explosion radius mobs some times aren't aggressive
spore: quicker hatching, more spores spawn, +dmg when low on life or after taking a large hit
drones: last longer mobs can fight each other
wave beam: longer range this might be hard to code
isolated mobs try to group up.
game mechanics game mechanics
mechanics that support the physics engine mechanics that support the physics engine

View File

@@ -14,6 +14,7 @@ const level = {
if (game.levelsCleared === 0) { if (game.levelsCleared === 0) {
this.intro(); //starting level this.intro(); //starting level
// b.giveGuns(0) // set a starting gun for testing // b.giveGuns(0) // set a starting gun for testing
// mech.fieldUpgrades[3]() //give a field power up for testing
// game.levelsCleared = 3; //for testing to simulate possible mobs spawns // game.levelsCleared = 3; //for testing to simulate possible mobs spawns
// this.bosses(); // this.bosses();
// this.testingMap(); // this.testingMap();

View File

@@ -507,17 +507,16 @@ const mech = {
this.gravity = 0.0019; this.gravity = 0.0019;
// this.phaseBlocks(0x011111) // this.phaseBlocks(0x011111)
}, },
drawFieldMeter() { drawFieldMeter(range = 60) {
if (this.fieldMeter < 1) { if (this.fieldMeter < 1) {
mech.fieldMeter += mech.fieldRegen; mech.fieldMeter += mech.fieldRegen;
ctx.fillStyle = "rgba(0, 0, 0, 0.4)"; ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
ctx.fillRect(this.pos.x - this.radius, this.pos.y - 50, 60, 10); ctx.fillRect(this.pos.x - this.radius, this.pos.y - 50, range, 10);
110, 170, 200
ctx.fillStyle = "rgb(50,220,255)"; ctx.fillStyle = "rgb(50,220,255)";
ctx.fillRect( ctx.fillRect(
this.pos.x - this.radius, this.pos.x - this.radius,
this.pos.y - 50, this.pos.y - 50,
60 * this.fieldMeter, range * this.fieldMeter,
10 10
); );
} else { } else {
@@ -816,17 +815,24 @@ const mech = {
}, },
() => { () => {
mech.fieldMode = 1; mech.fieldMode = 1;
game.makeTextLog("<h2>Time Dilation Field</h2><br><strong>active ability:</strong> hold left and right mouse to slow time<br><strong>passive bonus:</strong> +field regeneration", 1000); //<br><strong>passive bonus:</strong> can phase through blocks game.makeTextLog("<h2>Time Dilation Field</h2> field emitter slows time around the player", 1000);
mech.setHoldDefaults(); mech.setHoldDefaults();
mech.fieldRegen = 0.01; //0.0015 mech.fieldArc = 1; //field covers full 360 degrees
mech.calculateFieldThreshold();
mech.hold = function () { mech.hold = function () {
if (mech.isHolding) { if (mech.isHolding) {
mech.drawHold(mech.holdingTarget); mech.drawHold(mech.holdingTarget);
mech.holding(); mech.holding();
mech.throw(); mech.throw();
} else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down
if (mech.fieldMeter > mech.fieldRegen * 1.15) { const DRAIN = 0.0035 //mech.fieldRegen = 0.0015
mech.fieldMeter -= mech.fieldRegen * 1.15; if (mech.fieldMeter > DRAIN) {
mech.fieldMeter -= DRAIN;
mech.grabPowerUp();
// mech.pushMobs();
mech.lookForPickUp(130);
const range = 900; const range = 900;
//draw slow field //draw slow field
ctx.beginPath(); ctx.beginPath();
@@ -854,11 +860,6 @@ const mech = {
} else { } else {
mech.fieldCDcycle = game.cycle + 120; mech.fieldCDcycle = game.cycle + 120;
} }
} else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.1) { //field button is pressed
mech.drawField();
mech.grabPowerUp();
mech.pushMobs();
mech.lookForPickUp(130);
} else if (mech.holdingTarget && mech.fireCDcycle < game.cycle) { //holding, but field button is released } else if (mech.holdingTarget && mech.fireCDcycle < game.cycle) { //holding, but field button is released
mech.pickUp(); mech.pickUp();
} else { } else {
@@ -869,16 +870,15 @@ const mech = {
}, },
() => { () => {
mech.fieldMode = 2; mech.fieldMode = 2;
game.makeTextLog("<h2>Kinetic Energy Field</h2><br><strong>passive bonus:</strong> +field emitter damage<br><strong>passive bonus:</strong> +throw energy", 1000); game.makeTextLog("<h2>Kinetic Energy Field</h2> field emitter does damage on contact <br> blocks are thrown at a higher velocity", 1000);
mech.setHoldDefaults(); mech.setHoldDefaults();
// mech.fieldRegen = 0.0008; // 0.0015 is normal
//throw quicker and harder //throw quicker and harder
mech.throwChargeRate = 4; //0.5 mech.throwChargeRate = 3; //0.5
mech.throwChargeMax = 300; //50 mech.throwChargeMax = 150; //50
//passive field does extra damage //passive field does extra damage
mech.grabRange = 180; mech.grabRange = 180;
mech.fieldArc = 0.08; mech.fieldArc = 0.08;
mech.fieldDamage = 2.5; mech.fieldDamage = 2;
mech.hold = function () { mech.hold = function () {
if (mech.isHolding) { if (mech.isHolding) {
@@ -920,89 +920,24 @@ const mech = {
}, },
() => { () => {
mech.fieldMode = 3; mech.fieldMode = 3;
game.makeTextLog("<h2>Mass Recycler</h2><br><strong>active ability:</strong> hold left and right mouse to convert blocks into health<br><strong>negative effect:</strong> -energy regen", 1000); game.makeTextLog("<h2>Negative Mass Field</h2> field emitter nullifies gravity around player<br> field emitter can hold more massive objects", 1000);
mech.setHoldDefaults();
mech.fieldRegen = 0.0005; //0.0015
mech.hold = function () {
// health drain
// if (game.cycle % 360 === 0 && mech.health > 0.2) {
// mech.health = mech.health * 0.97 - 0.01;
// if (mech.health < 0) {
// mech.health = 0;
// mech.death();
// return;
// }
// mech.displayHealth();
// }
if (mech.isHolding) {
mech.drawHold(mech.holdingTarget);
mech.holding();
mech.throw();
} else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down
if (mech.fieldMeter > mech.fieldRegen) {
// mech.fieldMeter -= mech.fieldRegen
const range = 165;
//draw range
ctx.globalCompositeOperation = "screen" //"lighter" // "destination-atop" //"difference" //"color-burn";
ctx.beginPath();
ctx.arc(mech.pos.x, mech.pos.y, range, 0, 2 * Math.PI);
ctx.lineWidth = 1;
ctx.fillStyle = "rgba(150,210,180," + (0.9 + Math.random() * 0.1) + ")";
ctx.fill();
ctx.globalCompositeOperation = "source-over";
ctx.strokeStyle = "#364";
ctx.stroke();
//find all blocks in range
for (let i = 0, len = body.length; i < len; i++) {
if (!body[i].isNotHoldable) {
dist = Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, mech.pos))
const healCost = Math.sqrt(0.003 * body[i].mass) + 0.04
if (dist < range && mech.fieldMeter > healCost + 0.2) { // convert block to heal power up
// mech.fieldCDcycle = game.cycle + 4;
mech.fieldMeter -= healCost
powerUps.spawnHeal(body[i].position.x, body[i].position.y, 120 * healCost);
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
break
}
}
}
} else {
mech.fieldCDcycle = game.cycle + 120;
}
} else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.2) { //field button is pressed
mech.drawField();
mech.grabPowerUp();
mech.pushMobs();
mech.lookForPickUp(130);
} else if (mech.holdingTarget && mech.fireCDcycle < game.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)
}
mech.drawFieldMeter()
}
},
() => {
mech.fieldMode = 4;
game.makeTextLog("<h2>Negative Mass Field</h2><br><strong>active ability:</strong> hold left and right mouse to nullify gravity<br><strong>passive bonuses:</strong> +field size, +hold larger blocks", 1000);
mech.setHoldDefaults(); mech.setHoldDefaults();
mech.holdingMassScale = 0.05; //can hold heavier blocks
mech.fieldArc = 1; //field covers full 360 degrees mech.fieldArc = 1; //field covers full 360 degrees
mech.calculateFieldThreshold(); mech.calculateFieldThreshold();
mech.holdingMassScale = 0.05; //can hold heavier blocks
// mech.gravity = 0.0015; //passive reduce gravity from default 0.0019
mech.hold = function () { mech.hold = function () {
const range = 200 + 35 * Math.sin(game.cycle / 20) const range = 400
if (mech.isHolding) { if (mech.isHolding) {
mech.drawHold(mech.holdingTarget); mech.drawHold(mech.holdingTarget);
mech.holding(); mech.holding();
mech.throw(); mech.throw();
} else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down //push away } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down //push away
if (mech.fieldMeter > 0.005) { const DRAIN = 0.0025 //mech.fieldRegen = 0.0015
mech.fieldMeter -= 0.005; if (mech.fieldMeter > DRAIN) {
mech.fieldMeter -= DRAIN;
mech.grabPowerUp();
mech.lookForPickUp();
//look for nearby objects to make zero-g //look for nearby objects to make zero-g
function zeroG(who) { function zeroG(who) {
for (let i = 0, len = who.length; i < len; ++i) { for (let i = 0, len = who.length; i < len; ++i) {
@@ -1013,7 +948,7 @@ const mech = {
} }
} }
} }
zeroG(powerUp); // zeroG(powerUp);
zeroG(body); zeroG(body);
player.force.y -= player.mass * mech.gravity; // + 0.005 * Math.sin(game.cycle / 10); //wobble player.force.y -= player.mass * mech.gravity; // + 0.005 * Math.sin(game.cycle / 10); //wobble
@@ -1027,7 +962,7 @@ const mech = {
ctx.beginPath(); ctx.beginPath();
ctx.arc(mech.pos.x, mech.pos.y + 15, range, 0, 2 * Math.PI); ctx.arc(mech.pos.x, mech.pos.y + 15, range, 0, 2 * Math.PI);
ctx.globalCompositeOperation = "color-burn"; ctx.globalCompositeOperation = "color-burn";
ctx.fillStyle = "rgb(90,90,100)"; ctx.fillStyle = "rgb(120,120,130)";
ctx.fill(); ctx.fill();
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
@@ -1035,12 +970,6 @@ const mech = {
//trigger cooldown //trigger cooldown
mech.fieldCDcycle = game.cycle + 120; mech.fieldCDcycle = game.cycle + 120;
} }
} else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.2 && mech.fieldCDcycle < game.cycle) { //not hold but field button is pressed
mech.grabRange = range
mech.drawField();
mech.grabPowerUp();
mech.pushMobs();
mech.lookForPickUp();
} else if (mech.holdingTarget && mech.fireCDcycle < game.cycle && mech.fieldCDcycle < game.cycle) { //holding, but field button is released } else if (mech.holdingTarget && mech.fireCDcycle < game.cycle && mech.fieldCDcycle < game.cycle) { //holding, but field button is released
mech.pickUp(); mech.pickUp();
} else { } else {
@@ -1049,57 +978,127 @@ const mech = {
mech.drawFieldMeter() mech.drawFieldMeter()
} }
}, },
], () => {
mech.fieldMode = 4;
game.makeTextLog("<h2>Zero-Point Energy Field</h2> energy regeneration is improved<br> field emitter is extended to a circle around the player", 1000);
mech.setHoldDefaults();
mech.fieldRegen = 0.01; //0.0015
mech.fieldArc = 1; //field covers full 360 degrees
mech.calculateFieldThreshold();
mech.hold = function () {
mech.grabRange = 200 + 35 * Math.sin(game.cycle / 20)
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 < game.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)
}
mech.drawFieldMeter()
}
},
// () => { // () => {
// mech.fieldMode = 4; // mech.fieldMode = 1;
// game.makeTextLog("<h2>Negative Mass Field</h2><br><strong>active ability:</strong> hold left and right mouse to push things away<br><strong>passive bonuses:</strong> +field size, -player gravity", 1000); //<br><strong>passive bonus:</strong> can phase through blocks // game.makeTextLog("<h2>Time Dilation Field</h2><br><strong>active ability:</strong> hold left and right mouse to slow time<br><strong>passive bonus:</strong> +field regeneration", 1000); //<br><strong>passive bonus:</strong> can phase through blocks
// mech.setHoldDefaults(); // mech.setHoldDefaults();
// mech.fieldArc = 1; // mech.fieldRegen = 0.01; //0.0015
// mech.calculateFieldThreshold(); // mech.hold = function () {
// mech.holdingMassScale = 0.05; // if (mech.isHolding) {
// mech.gravity = 0.0015; //passive reduce gravity from default 0.0019 // mech.drawHold(mech.holdingTarget);
// mech.holding();
// mech.throw();
// } else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down
// if (mech.fieldMeter > mech.fieldRegen * 1.15) {
// mech.fieldMeter -= mech.fieldRegen * 1.15;
// const range = 900;
// //draw slow field
// ctx.beginPath();
// ctx.arc(mech.pos.x, mech.pos.y, range, 0, 2 * Math.PI);
// ctx.fillStyle = "#f5f5ff";
// ctx.globalCompositeOperation = "difference";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// function slow(who, friction = 0) {
// for (let i = 0, len = who.length; i < len; ++i) {
// dist = Matter.Vector.magnitude(Matter.Vector.sub(who[i].position, mech.pos))
// if (dist < range) {
// Matter.Body.setAngularVelocity(who[i], who[i].angularVelocity * friction)
// Matter.Body.setVelocity(who[i], {
// x: who[i].velocity.x * friction,
// y: who[i].velocity.y * friction
// });
// }
// }
// }
// slow(mob);
// slow(body);
// slow(bullet);
// } else {
// mech.fieldCDcycle = game.cycle + 120;
// }
// } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.1) { //field button is pressed
// mech.drawField();
// mech.grabPowerUp();
// mech.pushMobs();
// mech.lookForPickUp(130);
// } else if (mech.holdingTarget && mech.fireCDcycle < game.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)
// }
// mech.drawFieldMeter()
// }
// },
// () => {
// mech.fieldMode = 2;
// game.makeTextLog("<h2>Kinetic Energy Field</h2><br><strong>passive bonus:</strong> +field emitter damage<br><strong>passive bonus:</strong> +throw energy", 1000);
// mech.setHoldDefaults();
// // mech.fieldRegen = 0.0008; // 0.0015 is normal
// //throw quicker and harder
// mech.throwChargeRate = 4; //0.5
// mech.throwChargeMax = 300; //50
// //passive field does extra damage
// mech.grabRange = 180;
// mech.fieldArc = 0.08;
// mech.fieldDamage = 2.5;
// mech.hold = function () { // mech.hold = function () {
// if (mech.isHolding) { // if (mech.isHolding) {
// mech.drawHold(mech.holdingTarget); // mech.drawHold(mech.holdingTarget);
// mech.holding(); // mech.holding();
// mech.throw(); // mech.throw();
// } else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down //push away // } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.15) { //not hold but field button is pressed
// if (mech.fieldMeter > 0.004) { // //draw field
// mech.fieldMeter -= 0.004; // const range = mech.grabRange - 20;
// const range = 450 + 100 * Math.sin(game.cycle / 20)
// //draw push
// ctx.beginPath(); // ctx.beginPath();
// ctx.arc(mech.pos.x, mech.pos.y, range, 0, 2 * Math.PI); // ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - Math.PI * mech.fieldArc, mech.angle + Math.PI * mech.fieldArc, false);
// ctx.globalCompositeOperation = "color-burn"; // let eye = 13;
// ctx.fillStyle = "rgb(90,90,100)"; // ctx.lineTo(mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle));
// ctx.fill(); // if (mech.holdingTarget) {
// ctx.globalCompositeOperation = "source-over"; // ctx.fillStyle = "rgba(255,50,150," + (0.05 + 0.1 * Math.random()) + ")";
// function pushAway(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 < range) {
// knock = Matter.Vector.mult(Matter.Vector.normalise(sub), who[i].mass / 200);
// who[i].force.x += knock.x;
// who[i].force.y += knock.y;
// // player.force.x -= knock.x / 10;
// // player.force.y -= knock.y / 10;
// }
// }
// }
// pushAway(body);
// pushAway(mob);
// pushAway(bullet);
// pushAway(powerUp);
// } else { // } else {
// mech.fieldCDcycle = game.cycle + 120; // ctx.fillStyle = "rgba(255,50,150," + (0.15 + 0.15 * Math.random()) + ")";
// } // }
// } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.2) { //not hold but field button is pressed // ctx.fill();
// mech.grabRange = 200 + 50 * Math.sin(game.cycle / 20) // //draw random lines in field for cool effect
// mech.drawField(); // let offAngle = mech.angle + 2 * Math.PI * mech.fieldArc * (Math.random() - 0.5);
// ctx.beginPath();
// eye = 15;
// ctx.moveTo(mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle));
// ctx.lineTo(mech.pos.x + range * Math.cos(offAngle), mech.pos.y + range * Math.sin(offAngle));
// ctx.strokeStyle = "rgba(120,170,255,0.4)";
// ctx.stroke();
// mech.grabPowerUp(); // mech.grabPowerUp();
// mech.pushMobs(); // mech.pushMobs();
// mech.lookForPickUp(); // mech.lookForPickUp();
@@ -1111,14 +1110,138 @@ const mech = {
// mech.drawFieldMeter() // mech.drawFieldMeter()
// } // }
// }, // },
// ], // () => {
// phaseBlocks(mask = 0x010111) { // mech.fieldMode = 3;
// level.bodyCollisionFilterMask = mask; // game.makeTextLog("<h2>Mass Recycler</h2><br><strong>active ability:</strong> hold left and right mouse to convert blocks into health<br><strong>negative effect:</strong> -energy regen", 1000);
// mech.setHoldDefaults();
// mech.fieldRegen = 0.0005; //0.0015
// mech.hold = function () {
// // health drain
// // if (game.cycle % 360 === 0 && mech.health > 0.2) {
// // mech.health = mech.health * 0.97 - 0.01;
// // if (mech.health < 0) {
// // mech.health = 0;
// // mech.death();
// // return;
// // }
// // mech.displayHealth();
// // }
// if (mech.isHolding) {
// mech.drawHold(mech.holdingTarget);
// mech.holding();
// mech.throw();
// } else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down
// if (mech.fieldMeter > mech.fieldRegen) {
// // mech.fieldMeter -= mech.fieldRegen
// const range = 165;
// //draw range
// ctx.globalCompositeOperation = "screen" //"lighter" // "destination-atop" //"difference" //"color-burn";
// ctx.beginPath();
// ctx.arc(mech.pos.x, mech.pos.y, range, 0, 2 * Math.PI);
// ctx.lineWidth = 1;
// ctx.fillStyle = "rgba(150,210,180," + (0.9 + Math.random() * 0.1) + ")";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// ctx.strokeStyle = "#364";
// ctx.stroke();
// //find all blocks in range
// for (let i = 0, len = body.length; i < len; i++) { // for (let i = 0, len = body.length; i < len; i++) {
// body[i].collisionFilter.category = 0x0000001; // if (!body[i].isNotHoldable) {
// body[i].collisionFilter.mask = mask; // dist = Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, mech.pos))
// const healCost = Math.sqrt(0.003 * body[i].mass) + 0.04
// if (dist < range && mech.fieldMeter > healCost + 0.2) { // convert block to heal power up
// // mech.fieldCDcycle = game.cycle + 4;
// mech.fieldMeter -= healCost
// powerUps.spawnHeal(body[i].position.x, body[i].position.y, 120 * healCost);
// Matter.World.remove(engine.world, body[i]);
// body.splice(i, 1);
// break
// }
// }
// }
// } else {
// mech.fieldCDcycle = game.cycle + 120;
// }
// } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.2) { //field button is pressed
// mech.drawField();
// mech.grabPowerUp();
// mech.pushMobs();
// mech.lookForPickUp(130);
// } else if (mech.holdingTarget && mech.fireCDcycle < game.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)
// }
// mech.drawFieldMeter()
// } // }
// }, // },
// () => {
// mech.fieldMode = 4;
// game.makeTextLog("<h2>Negative Mass Field</h2><br><strong>active ability:</strong> hold left and right mouse to nullify gravity<br><strong>passive bonuses:</strong> +field size, +hold larger blocks", 1000);
// mech.setHoldDefaults();
// mech.fieldArc = 1; //field covers full 360 degrees
// mech.calculateFieldThreshold();
// mech.holdingMassScale = 0.05; //can hold heavier blocks
// // mech.gravity = 0.0015; //passive reduce gravity from default 0.0019
// mech.hold = function () {
// const range = 200 + 35 * Math.sin(game.cycle / 20)
// if (mech.isHolding) {
// mech.drawHold(mech.holdingTarget);
// mech.holding();
// mech.throw();
// } else if (game.mouseDown && (keys[32] || game.mouseDownRight) && mech.fieldCDcycle < game.cycle) { //both mouse keys down //push away
// if (mech.fieldMeter > 0.005) {
// mech.fieldMeter -= 0.005;
// //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 < range) {
// who[i].force.y -= who[i].mass * game.g;
// }
// }
// }
// zeroG(powerUp);
// zeroG(body);
// player.force.y -= player.mass * mech.gravity; // + 0.005 * Math.sin(game.cycle / 10); //wobble
// //add player vertical friction to reduce map jump craziness
// Matter.Body.setVelocity(player, {
// x: player.velocity.x,
// y: player.velocity.y * 0.99
// });
// //draw zero-G range
// ctx.beginPath();
// ctx.arc(mech.pos.x, mech.pos.y + 15, range, 0, 2 * Math.PI);
// ctx.globalCompositeOperation = "color-burn";
// ctx.fillStyle = "rgb(90,90,100)";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// } else {
// //trigger cooldown
// mech.fieldCDcycle = game.cycle + 120;
// }
// } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.2 && mech.fieldCDcycle < game.cycle) { //not hold but field button is pressed
// mech.grabRange = range
// mech.drawField();
// mech.grabPowerUp();
// mech.pushMobs();
// mech.lookForPickUp();
// } else if (mech.holdingTarget && mech.fireCDcycle < game.cycle && mech.fieldCDcycle < game.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)
// }
// mech.drawFieldMeter()
// }
// },
],
drawLeg(stroke) { drawLeg(stroke) {
// if (game.mouseInGame.x > this.pos.x) { // if (game.mouseInGame.x > this.pos.x) {
if (mech.angle > -Math.PI / 2 && mech.angle < Math.PI / 2) { if (mech.angle > -Math.PI / 2 && mech.angle < Math.PI / 2) {