From 9b5b2090b72b0b8b1468edc39cb5deddbff02077 Mon Sep 17 00:00:00 2001 From: landgreen Date: Thu, 10 Oct 2019 06:52:44 -0700 Subject: [PATCH] adding mobs to aerie level --- js/bullets.js | 33 +++++++--- js/level.js | 175 +++++++++++++++++++++++++++++++++++++------------ js/powerups.js | 27 -------- js/spawn.js | 77 ++++++++++++++++++++-- 4 files changed, 230 insertions(+), 82 deletions(-) diff --git a/js/bullets.js b/js/bullets.js index ed77e9c..5a70ecc 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -897,7 +897,7 @@ const b = { name: "drones", description: "release drones that seek out targets
waits at crosshairs if no targets are available", ammo: 0, - ammoPack: 23, + ammoPack: 21, have: false, fire() { const THRUST = 0.0015 @@ -929,31 +929,48 @@ const b = { this.force.y += this.mass * 0.0002; //find mob targets if (!(game.cycle % this.lookFrequency)) { - // this.close = null; this.lockedOn = null; - this.isFollowMouse = true; //if no target is found default to follow mouse let closeDist = Infinity; for (let i = 0, len = mob.length; i < len; ++i) { if ( - // mob[i].alive && - // mob[i].dropPowerUp && //don't target mob bullets Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { const TARGET_VECTOR = Matter.Vector.sub(this.position, mob[i].position) const DIST = Matter.Vector.magnitude(TARGET_VECTOR); if (DIST < closeDist) { - // this.close = mob[i].position; closeDist = DIST; this.lockedOn = mob[i] - this.isFollowMouse = false; + } + } + } + if (!this.lockedOn) { + //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 ( + (powerUp[i].name === "ammo" || powerUp[i].name === "gun" || (powerUp[i].name === "heal" && mech.health < 0.8)) && + Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 && + Matter.Query.ray(body, this.position, powerUp[i].position).length === 0 + ) { + const TARGET_VECTOR = Matter.Vector.sub(this.position, powerUp[i].position) + const DIST = Matter.Vector.magnitude(TARGET_VECTOR); + if (DIST < closeDist) { + if (DIST < 50) { //eat the power up if close enough + powerUp[i].effect(); + powerUp.splice(i, 1) + break; + } + closeDist = DIST; + this.lockedOn = powerUp[i] + } } } } } if (this.lockedOn) { //accelerate towards mobs this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST) - } else if (this.isFollowMouse) { //accelerate towards mouse + } else { //accelerate towards mouse this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.position, game.mouseInGame)), -this.mass * THRUST) } // speed cap instead of friction to give more agility diff --git a/js/level.js b/js/level.js index e9d9def..62f829b 100644 --- a/js/level.js +++ b/js/level.js @@ -7,24 +7,22 @@ let consBB = []; //all constraints between two bodies const level = { maxJump: 390, boostScale: 0.000023, - levels: ["skyscrapers", "rooftops", "warehouse", "highrise", "towers"], + levels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie"], onLevel: 0, start() { // 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.corridors(); + // this.aerie(); // this.rooftops(); // this.warehouse(); // this.highrise(); - // this.towers(); - - // game.levelsCleared = 3; //for testing to simulate possible mobs spawns + // this.office(); // b.giveGuns(11) // set a starting gun for testing - // mech.fieldUpgrades[6]() //give a field power up 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,21 +565,35 @@ const level = { //spawn.randomBoss(4850, -1250,0.7); if (game.levelsCleared > 4) spawn.bomber(2500, -2400, 100); }, - corridors() { + aerie() { + // game.setZoom(3000); + // game.levelsCleared = 116; //for testing to simulate possible mobs spawns + game.zoomTransition(1700) //1400 is normal + + const backwards = (Math.random() < 0.75) ? false : true; + if (backwards) { + mech.setPosToSpawn(4000, -3300); //normal spawn + level.exit.x = -100; + level.exit.y = -1025; + } else { + mech.setPosToSpawn(-50, -1050); //normal spawn + level.exit.x = 3950; + level.exit.y = -3275; + } + // mech.setPosToSpawn(2250, -900); // game.zoomTransition(1500) //1400 is normal - game.setZoom(3000); - // mech.setPosToSpawn(-50, -1050); //normal spawn - mech.setPosToSpawn(2250, -900); //normal spawn + level.enter.x = mech.spawnPos.x - 50; level.enter.y = mech.spawnPos.y + 20; - level.exit.x = 1500; - level.exit.y = -4875; this.addZone(level.exit.x, level.exit.y, 100, 30, "nextLevel"); powerUps.spawnStartingPowerUps(1075, -550); - // spawn.debris(0, -2200, 4500, 20); //20 debris per level + spawn.debris(-250, 50, 1650, 5); //20 debris per level + spawn.debris(2475, 0, 750, 5); //20 debris per level + spawn.debris(3450, 0, 2000, 10); //20 debris per level + spawn.debris(3500, -2350, 1500, 5); //20 debris per level document.body.style.backgroundColor = "#dcdcde"; - // //foreground + //foreground level.fill.push({ x: -100, y: -1000, @@ -596,46 +608,125 @@ const level = { height: 1550, color: "rgba(0,0,0,0.1)" }); + level.fill.push({ + x: 3700, + y: -3150, + width: 1100, + height: 900, + color: "rgba(0,0,0,0.1)" + }); - // //background - // level.fillBG.push({ - // x: 1300, - // y: -1800, - // width: 750, - // height: 1800, - // color: "#d4d4d7" - // }); + //background + level.fillBG.push({ + x: 4200, + y: -2250, + width: 100, + height: 2600, + color: "#c7c7ca" + }); + if (!backwards) { + level.fillBG.push({ + x: 3750, + y: -3650, + width: 550, + height: 400, + color: "#d4f4f4" + }); + level.fill.push({ + x: -275, + y: -1275, + width: 425, + height: 300, + color: "rgba(0,0,0,0.1)" + }); + } else { + level.fill.push({ + x: 3750, + y: -3650, + width: 550, + height: 400, + color: "rgba(0,0,0,0.1)" + }); + level.fillBG.push({ + x: -275, + y: -1275, + width: 425, + height: 300, + color: "#d4f4f4" + }); + } // starting room + spawn.mapRect(-100, -1010, 100, 30); spawn.mapRect(-300, -1000, 600, 50); - spawn.mapRect(-100, -975, 100, 975); spawn.mapRect(-300, -1300, 450, 50); spawn.mapRect(-300, -1300, 50, 350); - spawn.bodyRect(100, -1250, 200, 240); - - //top of building + if (!backwards) spawn.bodyRect(100, -1250, 200, 240); //remove on backwards + //left building + spawn.mapRect(-100, -975, 100, 975); + spawn.mapRect(-500, 100, 1950, 400); + spawn.boost(-425, 100, 1400); spawn.mapRect(600, -1000, 750, 50); spawn.mapRect(900, -500, 550, 50); spawn.mapRect(1250, -975, 100, 375); - spawn.bodyRect(1250, -600, 100, 100); + spawn.bodyRect(1250, -600, 100, 100, 0.7); spawn.mapRect(1250, -450, 100, 450); - spawn.bodyRect(1250, -1225, 100, 200); - spawn.bodyRect(1200, -1025, 350, 25); - spawn.bodyRect(1750, -800, 700, 50); - - // spawn.mapRect(2000, -3600, 450, 2500); - spawn.mapVertex(2225, -2150, "0 0 450 0 300 -2500 150 -2500") + if (!backwards) spawn.bodyRect(1250, -1225, 100, 200); //remove on backwards + if (!backwards) spawn.bodyRect(1200, -1025, 350, 25); //remove on backwards + //middle super tower + if (backwards) { + spawn.bodyRect(2000, -800, 700, 35); + } else { + spawn.bodyRect(1750, -800, 700, 35); + } + spawn.mapVertex(2225, -2100, "0 0 450 0 300 -2500 150 -2500") spawn.mapRect(2000, -750, 450, 300); - spawn.bodyRect(2175, -450, 100, 300); + spawn.bodyRect(2360, -450, 100, 300, 0.6); spawn.mapRect(2000, -150, 450, 350); - spawn.bodyRect(2450, 150, 150, 150); - // spawn.laserZone(2150, -2800, 5, 1800, 0.1) + spawn.bodyRect(2450, 150, 150, 150, 0.4); + spawn.mapRect(1550, 300, 4600, 200); //ground + //floor below right tall tower + spawn.bodyRect(3000, 50, 200, 275, 0.8); + spawn.bodyRect(4000, 50, 200, 200, 0.8); + spawn.bodyRect(4500, 50, 375, 250, 0.8); + spawn.bodyRect(4900, -100, 300, 400, 0.4); + spawn.boost(5350, 275, 2850); + spawn.mapRect(6050, -450, 100, 800); + //right tall tower + spawn.mapRect(3700, -3200, 100, 800); + spawn.mapRect(4700, -2910, 100, 510); + spawn.mapRect(3700, -2600, 300, 50); + spawn.mapRect(4100, -2900, 900, 50); + spawn.mapRect(3450, -2300, 1650, 100); + //exit room on top of tower + spawn.mapRect(3700, -3700, 600, 50); + spawn.mapRect(3700, -3700, 50, 500); + spawn.mapRect(4250, -3700, 50, 300); + spawn.mapRect(3700, -3250, 1100, 100); + spawn.mapRect(3950, -3260, 100, 30); + spawn.randomSmallMob(-225, 25); + spawn.randomSmallMob(1000, -1100); + spawn.randomSmallMob(4000, -250); + spawn.randomSmallMob(4450, -3000); + spawn.randomSmallMob(5600, 100); + spawn.randomMob(4275, -2600, 0.8); + spawn.randomMob(1050, -700, 0.8) + spawn.randomMob(6050, -500, 0.7); + spawn.randomMob(2150, -300, 0.6) + spawn.randomMob(3900, -2700, 0.8); + spawn.randomMob(1650, -1300, 0.7) + spawn.randomMob(-4100, -50, 0.7); + spawn.randomMob(4100, -50, 0.5); + spawn.randomMob(1700, -50, 0.3) + spawn.randomMob(2350, -900, 0.3) + spawn.randomMob(4700, -150, 0.2); + spawn.randomBoss(350, -500, 1) + spawn.randomBoss(4000, -350, 0.6); + spawn.randomBoss(2750, -550, 0.1); + if (game.levelsCleared > 2) spawn.suckerBoss(3000, -1000); - //pit - spawn.mapRect(-500, 100, 1950, 400); - spawn.boost(-425, 100, 1400); - spawn.mapRect(1550, 300, 1400, 200); + //add mini boss, giant hopper? or a black hole that spawns hoppers? }, skyscrapers() { game.zoomTransition(2000) //1400 is normal @@ -1128,7 +1219,7 @@ const level = { if (game.levelsCleared > 2) spawn.snaker(-1300 + Math.random() * 2000, -2200); //boss snake with head }, - towers() { + office() { game.zoomTransition(1400) if (Math.random() < 0.75) { //normal direction start in top left diff --git a/js/powerups.js b/js/powerups.js index e47d3c2..bb42368 100644 --- a/js/powerups.js +++ b/js/powerups.js @@ -168,9 +168,7 @@ const powerUps = { category: 0x100000, mask: 0x100001 }, - endCycle: game.cycle + 1080, //if change time also update color fade out color: target.color, - sat: 1, effect: target.effect, mode: mode, name: target.name, @@ -184,31 +182,6 @@ const powerUps = { } World.add(engine.world, powerUp[i]); //add to world }, - spawnHeal(x, y, size) { //used by the mass recycler power up - let i = powerUp.length; - const target = powerUps["heal"]; - powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, { - density: 0.001, - frictionAir: 0.01, - restitution: 0.8, - collisionFilter: { - group: 0, - category: 0x100000, - mask: 0x100001 - }, - endCycle: game.cycle + 1080, //if change time also update color fade out - color: target.color, - sat: 1, - effect: target.effect, - name: target.name, - size: size - }); - // Matter.Body.setVelocity(powerUp[i], { - // x: (Math.random() - 0.5) * 3, - // y: -7 * Math.random() - 5 - // }); - World.add(engine.world, powerUp[i]); //add to world - }, attractionLoop() { for (let i = 0, len = powerUp.length; i < len; ++i) { const dxP = player.position.x - powerUp[i].position.x; diff --git a/js/spawn.js b/js/spawn.js index 4fb2777..a1dc7ec 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -477,6 +477,73 @@ const spawn = { } } }, + suckerBoss(x, y, radius = 120 + Math.ceil(Math.random() * 70)) { + radius = 9 + radius / 8; //extra small + mobs.spawn(x, y, 12, radius, "#000"); + let me = mob[mob.length - 1]; + me.stroke = "transparent"; //used for drawSneaker + me.eventHorizon = radius * 33; //required for blackhole + me.seeAtDistance2 = (me.eventHorizon + 500) * (me.eventHorizon + 500); //vision limit is event horizon + me.accelMag = 0.00013 * game.accelScale; + // me.frictionAir = 0.005; + me.memory = 1000; + Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger + me.do = function () { + //keep it slow, to stop issues from explosion knock backs + if (this.speed > 7) { + Matter.Body.setVelocity(this, { + x: this.velocity.x * 0.99, + y: this.velocity.y * 0.99 + }); + } + 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); + + //draw darkness + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, eventHorizon * 0.25, 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.fillStyle = "rgba(0,0,0,0.5)"; + 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); + 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); + //draw line to player + ctx.beginPath(); + ctx.moveTo(this.position.x, this.position.y); + ctx.lineTo(mech.pos.x, mech.pos.y); + ctx.lineWidth = Math.min(60, this.radius * 2); + ctx.strokeStyle = "rgba(0,0,0,0.5)"; + ctx.stroke(); + ctx.beginPath(); + ctx.arc(mech.pos.x, mech.pos.y, 40, 0, 2 * Math.PI); + ctx.fillStyle = "rgba(0,0,0,0.3)"; + ctx.fill(); + } + } + } + }, beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) { mobs.spawn(x, y, 4, radius, "rgb(255,0,190)"); let me = mob[mob.length - 1]; @@ -1194,7 +1261,7 @@ const spawn = { let me = mob[mob.length - 1]; //touch nothing me.collisionFilter.category = 0x010000; //act like a body - me.collisionFilter.mask = 0x000001; //only collide with map + me.collisionFilter.mask = 0x000101; //only collide with map me.inertia = Infinity; me.g = 0.0004; //required for gravity me.restitution = 0; @@ -1258,7 +1325,7 @@ const spawn = { let me = mob[mob.length - 1]; //touch nothing me.collisionFilter.category = 0x010000; //act like a body - me.collisionFilter.mask = 0x000001; //only collide with map + me.collisionFilter.mask = 0x000101; //only collide with map me.g = 0.0003; //required for gravity // me.restitution = 0; me.stroke = "transparent" @@ -1306,7 +1373,7 @@ const spawn = { let me = mob[mob.length - 1]; //touch nothing me.collisionFilter.category = 0x010000; //act like a body - me.collisionFilter.mask = 0x000001; //only collide with map + me.collisionFilter.mask = 0x000101; //only collide with map me.g = 0.0003; //required for gravity // me.restitution = 0; me.stroke = "transparent" @@ -1354,7 +1421,7 @@ const spawn = { let me = mob[mob.length - 1]; //touch nothing me.collisionFilter.category = 0x010000; //act like a body - me.collisionFilter.mask = 0x000001; //only collide with map + me.collisionFilter.mask = 0x000101; //only collide with map me.g = 0.0003; //required for gravity me.restitution = 0; me.stroke = "transparent" @@ -1401,7 +1468,7 @@ const spawn = { let me = mob[mob.length - 1]; //touch nothing me.collisionFilter.category = 0x010000; //act like a body - me.collisionFilter.mask = 0x000001; //only collide with map + me.collisionFilter.mask = 0x000101; //only collide with map me.g = 0.0003; //required for gravity me.restitution = 0; me.stroke = "transparent"