From 14b5ffa1a623640ebb3c16af7c5e2239292a65cb Mon Sep 17 00:00:00 2001 From: landgreen Date: Fri, 11 Oct 2019 06:56:18 -0700 Subject: [PATCH] black hole boss balance --- js/bullets.js | 136 +++++++++++++++++++++++++++++++++++++++++++++---- js/level.js | 12 ++--- js/powerups.js | 4 +- js/spawn.js | 49 +++++++++++------- 4 files changed, 166 insertions(+), 35 deletions(-) diff --git a/js/bullets.js b/js/bullets.js index 5a70ecc..8aca658 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -398,8 +398,130 @@ const b = { ctx.globalAlpha = 1; } } - }, - { + // }, { + // name: "entropic beam", + // description: "steal entropy to heal
reflects off walls at 75% intensity
uses energy instead of ammunition", + // ammo: 0, + // // ammoPack: 350, + // ammoPack: Infinity, + // have: false, + // fire() { + // // mech.fireCDcycle = game.cycle + 1 + // //laser drains energy as well as bullets + // const FIELD_DRAIN = 0.0001 //should be 0.001 + // if (mech.fieldMeter < FIELD_DRAIN) { + // mech.fireCDcycle = game.cycle + 100; // cool down if out of energy + // } else { + // mech.fieldMeter -= mech.fieldRegen + FIELD_DRAIN + // let best; + // const color = "#a0a"; + // const range = 600; + // const path = [{ + // x: mech.pos.x + 20 * Math.cos(mech.angle), + // y: mech.pos.y + 20 * Math.sin(mech.angle) + // }, + // { + // x: mech.pos.x + range * Math.cos(mech.angle), + // y: mech.pos.y + range * Math.sin(mech.angle) + // } + // ]; + // const vertexCollision = function (v1, v1End, domain) { + // for (let i = 0; i < domain.length; ++i) { + // let vertices = domain[i].vertices; + // const len = vertices.length - 1; + // for (let j = 0; j < len; j++) { + // results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[j], + // v2: vertices[j + 1] + // }; + // } + // } + // } + // results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + // if (results.onLine1 && results.onLine2) { + // const dx = v1.x - results.x; + // const dy = v1.y - results.y; + // const dist2 = dx * dx + dy * dy; + // if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) { + // best = { + // x: results.x, + // y: results.y, + // dist2: dist2, + // who: domain[i], + // v1: vertices[0], + // v2: vertices[len] + // }; + // } + // } + // } + // }; + // const checkforCollisions = function () { + // best = { + // x: null, + // y: null, + // dist2: Infinity, + // who: null, + // v1: null, + // v2: null + // }; + // vertexCollision(path[path.length - 2], path[path.length - 1], mob); + // vertexCollision(path[path.length - 2], path[path.length - 1], map); + // vertexCollision(path[path.length - 2], path[path.length - 1], body); + // }; + // const laserHitMob = function (dmg) { + // if (best.who.alive) { + // dmg *= b.dmgScale * 0.02; + // mech.addHealth(0.002) + // best.who.damage(dmg); + // best.who.locatePlayer(); + // //draw mob damage circle + // ctx.fillStyle = color; + // ctx.beginPath(); + // ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); + // ctx.fill(); + // } + // }; + // checkforCollisions(); + // if (best.dist2 != Infinity) { + // //if hitting something + // path[path.length - 1] = { + // x: best.x, + // y: best.y + // }; + // laserHitMob(1); + // } + // ctx.fillStyle = color; + // ctx.strokeStyle = color; + // ctx.lineWidth = 4; + // for (let i = 1, len = path.length; i < len; ++i) { + // d = { + // x: path[i].x - path[i - 1].x, + // y: path[i].y - path[i - 1].y + // } + // const a = game.cycle * 5 + // p1 = { + // x: d.x / 2 * Math.cos(a) - d.y / 2 * Math.sin(a), + // y: d.x / 2 * Math.sin(a) + d.y / 2 * Math.cos(a), + // } + // const wave = 300 / Math.sqrt(d.x * d.x + d.y * d.y) + // ctx.beginPath(); + // ctx.moveTo(path[i - 1].x, path[i - 1].y); + // ctx.bezierCurveTo(path[i - 1].x + p1.x * wave, path[i - 1].y + p1.y * wave, path[i].x + p1.x * wave, path[i].y + p1.y * wave, path[i].x, path[i].y); + // ctx.stroke(); + // } + // } + // } + }, { name: "one shot", description: "fire a huge bullet with high recoil
effective at long distances", ammo: 0, @@ -794,7 +916,7 @@ const b = { }, { name: "spores", - description: "release an orb discharges spores after 2 seconds
spores seek out targets
spores can pass through blocks", + description: "release an orb that discharges spores after 2 seconds
spores seek out targets
spores can pass through blocks", ammo: 0, ammoPack: 6, have: false, @@ -895,7 +1017,7 @@ const b = { }, { name: "drones", - description: "release drones that seek out targets
waits at crosshairs if no targets are available", + description: "release drones that seek out targets
if no targets, drones move to mouse
", ammo: 0, ammoPack: 21, have: false, @@ -945,7 +1067,7 @@ const b = { } } if (!this.lockedOn) { - //grab a power up if it is ammo or a heal when player is low + //grab a power up if it is (ammo) or (a heal when player is low) let closeDist = Infinity; for (let i = 0, len = powerUp.length; i < len; ++i) { if ( @@ -984,10 +1106,6 @@ const b = { }) b.fireProps(mech.crouch ? 22 : 15, mech.crouch ? 26 : 1, dir, me); //cd , speed b.drawOneBullet(bullet[me].vertices); - // Matter.Body.setDensity(bullet[me], 0.000001); - // bullet[me].onDmg = function () { - // this.endCycle = 0; //bullet ends cycle after doing damage - // }; } }, ], diff --git a/js/level.js b/js/level.js index 62f829b..9c8ace1 100644 --- a/js/level.js +++ b/js/level.js @@ -13,16 +13,16 @@ const level = { // game.zoomScale = 1400 //1400 if (game.levelsCleared === 0) { document.title = "n-gon"; - this.intro(); //starting level + // this.intro(); //starting level // this.testingMap(); // this.bosses(); - // this.aerie(); + this.aerie(); // this.rooftops(); // this.warehouse(); // this.highrise(); // this.office(); - // b.giveGuns(11) // set a starting gun for testing - // mech.fieldUpgrades[5]() //give a field power up for testing + b.giveGuns(1) // set a starting gun for testing + mech.fieldUpgrades[5]() //give a field power up for testing } 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 @@ -567,8 +567,8 @@ const level = { }, aerie() { // game.setZoom(3000); - // game.levelsCleared = 116; //for testing to simulate possible mobs spawns - game.zoomTransition(1700) //1400 is normal + game.levelsCleared = 5; //for testing to simulate possible mobs spawns + game.zoomTransition(2100) //1400 is normal const backwards = (Math.random() < 0.75) ? false : true; if (backwards) { diff --git a/js/powerups.js b/js/powerups.js index bb42368..9292775 100644 --- a/js/powerups.js +++ b/js/powerups.js @@ -32,11 +32,9 @@ const powerUps = { } else { mech.fieldUpgrades[this.mode](); //set a predetermined power up } - if (previousMode !== 0) { //pop the old field out in case player wants to swap back - // mech.fieldMeter = 0 //drop field meter to zero to prevent automatic pickup mech.fieldCDcycle = game.cycle + 60; //trigger fieldCD to stop power up grab automatic pick up of spawn - powerUps.spawn(mech.pos.x, mech.pos.y, "field", false, previousMode); + powerUps.spawn(mech.pos.x, mech.pos.y - 15, "field", false, previousMode); } } }, diff --git a/js/spawn.js b/js/spawn.js index 1350474..52474bb 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -477,61 +477,75 @@ const spawn = { } } }, - suckerBoss(x, y, radius = 180 + Math.ceil(Math.random() * 70)) { - radius = 9 + radius / 8; //extra small + suckerBoss(x, y, radius = 20) { mobs.spawn(x, y, 12, radius, "#000"); let me = mob[mob.length - 1]; me.stroke = "transparent"; //used for drawSneaker - me.eventHorizon = radius * 30; //required for blackhole + me.eventHorizon = 900; //required for black hole me.seeAtDistance2 = (me.eventHorizon + 500) * (me.eventHorizon + 500); //vision limit is event horizon me.accelMag = 0.00011 * game.accelScale; + me.collisionFilter.mask = 0x001101 // me.frictionAir = 0.005; me.memory = 1000; - Matter.Body.setDensity(me, 0.0055); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.3); //extra dense //normal is 0.001 //makes effective life much larger me.onDeath = function () { + //applying forces to player doesn't seem to work inside this method, not sure why if (Math.random() < 0.35 || mech.fieldMode === 0) powerUps.spawn(this.position.x, this.position.y, "field"); //boss spawns field upgrades + // for (let i = 0; i < 70; i++) { + // const index = body.length + // spawn.bodyRect(this.position.x + 30 * (Math.random() - 0.5), this.position.y + 30 * (Math.random() - 0.5), 15 + 40 * Math.random(), 15 + 40 * Math.random()); + // body[index].collisionFilter.category = 0x010000; + // body[index].collisionFilter.mask = 0x111000; + // body[index].classType = "body"; + // World.add(engine.world, body[index]); //add to world + // } }; me.do = function () { //keep it slow, to stop issues from explosion knock backs - if (this.speed > 7) { + if (this.speed > 6) { Matter.Body.setVelocity(this, { - x: this.velocity.x * 0.99, - y: this.velocity.y * 0.99 + x: this.velocity.x * 0.95, + y: this.velocity.y * 0.95 }); } this.seePlayerByDistOrLOS(); if (this.seePlayer.recall) { - //eventHorizon waves in and out - eventHorizon = this.eventHorizon * (0.93 + 0.25 * Math.sin(game.cycle * 0.017)) - //accelerate towards the player const forceMag = this.accelMag * this.mass; const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x); this.force.x += forceMag * Math.cos(angle); this.force.y += forceMag * Math.sin(angle); + //eventHorizon waves in and out + eventHorizon = this.eventHorizon * (1 + 0.5 * Math.sin(game.cycle * 0.006)) //draw darkness ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, eventHorizon * 0.25, 0, 2 * Math.PI); + ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI); ctx.fillStyle = "rgba(0,0,0,0.9)"; ctx.fill(); ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, eventHorizon * 0.55, 0, 2 * Math.PI); + ctx.arc(this.position.x, this.position.y, eventHorizon * 0.4, 0, 2 * Math.PI); + ctx.fillStyle = "rgba(0,0,0,0.7)"; + ctx.fill(); + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, eventHorizon * 0.6, 0, 2 * Math.PI); ctx.fillStyle = "rgba(0,0,0,0.5)"; ctx.fill(); ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, eventHorizon * 0.8, 0, 2 * Math.PI); + ctx.fillStyle = "rgba(0,0,0,0.3)"; + ctx.fill(); + ctx.beginPath(); ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI); ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.fill(); - - this.healthBar(); //when player is inside event horizon if (Matter.Vector.magnitude(Matter.Vector.sub(this.position, player.position)) < eventHorizon) { - mech.damage(0.0003 * game.dmgScale); + mech.damage(0.0002 * game.dmgScale); if (mech.fieldMeter > 0.1) mech.fieldMeter -= 0.01 const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); - player.force.x -= 1.25 * Math.cos(angle) * player.mass * game.g * (mech.onGround ? 1.8 : 1); - player.force.y -= 0.97 * player.mass * game.g * Math.sin(angle); + player.force.x -= 1.5 * Math.cos(angle) * player.mass * game.g * (mech.onGround ? 1.7 : 1); + player.force.y -= 1.5 * Math.sin(angle) * player.mass * game.g; //draw line to player ctx.beginPath(); ctx.moveTo(this.position.x, this.position.y); @@ -544,6 +558,7 @@ const spawn = { ctx.fillStyle = "rgba(0,0,0,0.3)"; ctx.fill(); } + this.healthBar(); } } },