launcher boss
This commit is contained in:
@@ -183,15 +183,15 @@ const level = {
|
|||||||
spawn.boost(1500, 0, 900);
|
spawn.boost(1500, 0, 900);
|
||||||
|
|
||||||
// spawn.bomberBoss(2900, -500)
|
// spawn.bomberBoss(2900, -500)
|
||||||
// spawn.launcherBoss(1200, -500)
|
spawn.launcherBoss(1200, -500)
|
||||||
spawn.launcher(1600, -400)
|
// spawn.launcher(1600, -400)
|
||||||
// spawn.stabber(1600, -500)
|
// spawn.spawner(1600, -500)
|
||||||
// spawn.cellBossCulture(1600, -500)
|
// spawn.cellBossCulture(1600, -500)
|
||||||
// spawn.shooter(1600, -500)
|
// spawn.shooter(1600, -500)
|
||||||
// spawn.striker(1600, -500)
|
// spawn.striker(1600, -500)
|
||||||
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
||||||
|
|
||||||
// spawn.nodeBoss(1200, -500, "spiker")
|
// spawn.nodeBoss(1200, -500, "launcher")
|
||||||
// spawn.spiderBoss(1200, -500)
|
// spawn.spiderBoss(1200, -500)
|
||||||
// spawn.timeSkipBoss(2900, -500)
|
// spawn.timeSkipBoss(2900, -500)
|
||||||
// spawn.randomMob(1600, -500)
|
// spawn.randomMob(1600, -500)
|
||||||
|
|||||||
62
js/mob.js
62
js/mob.js
@@ -244,7 +244,7 @@ const mobs = {
|
|||||||
locatePlayer() { // updates mob's memory of player location
|
locatePlayer() { // updates mob's memory of player location
|
||||||
this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //seconds before mob falls a sleep
|
this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //seconds before mob falls a sleep
|
||||||
this.seePlayer.position.x = player.position.x;
|
this.seePlayer.position.x = player.position.x;
|
||||||
this.seePlayer.position.y = player.position.y
|
this.seePlayer.position.y = player.position.y;
|
||||||
},
|
},
|
||||||
// locatePlayerByDist() {
|
// locatePlayerByDist() {
|
||||||
// if (this.distanceToPlayer2() < this.locateRange) {
|
// if (this.distanceToPlayer2() < this.locateRange) {
|
||||||
@@ -886,52 +886,20 @@ const mobs = {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
launch() {
|
// launch() {
|
||||||
if (!mech.isBodiesAsleep) {
|
// if (this.seePlayer.recall) {
|
||||||
const setNoseShape = () => {
|
// //fire
|
||||||
const mag = this.radius + this.radius * this.noseLength;
|
// spawn.seeker(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5);
|
||||||
this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag;
|
// const v = 15;
|
||||||
this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag;
|
// Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
};
|
// x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
||||||
//throw a mob/bullet at player
|
// y: this.velocity.y + this.fireDir.y * v + Math.random()
|
||||||
if (this.seePlayer.recall) {
|
// });
|
||||||
//set direction to turn to fire
|
// // recoil
|
||||||
if (!(game.cycle % this.seePlayerFreq)) {
|
// this.force.x -= 0.005 * this.fireDir.x * this.mass;
|
||||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
// this.force.y -= 0.005 * this.fireDir.y * this.mass;
|
||||||
}
|
// }
|
||||||
//rotate towards fireAngle
|
// },
|
||||||
const angle = this.angle + Math.PI / 2;
|
|
||||||
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
|
||||||
const threshold = 0.1;
|
|
||||||
if (c > threshold) {
|
|
||||||
this.torque += 0.0000045 * this.inertia;
|
|
||||||
} else if (c < -threshold) {
|
|
||||||
this.torque -= 0.0000045 * this.inertia;
|
|
||||||
} else if (this.noseLength > 1.5) {
|
|
||||||
//fire
|
|
||||||
spawn.seeker(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5);
|
|
||||||
const v = 15;
|
|
||||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
|
||||||
x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
|
||||||
y: this.velocity.y + this.fireDir.y * v + Math.random()
|
|
||||||
});
|
|
||||||
this.noseLength = 0;
|
|
||||||
// recoil
|
|
||||||
this.force.x -= 0.005 * this.fireDir.x * this.mass;
|
|
||||||
this.force.y -= 0.005 * this.fireDir.y * this.mass;
|
|
||||||
}
|
|
||||||
if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
|
|
||||||
setNoseShape();
|
|
||||||
} else if (this.noseLength > 0.1) {
|
|
||||||
this.noseLength -= this.fireFreq / 2;
|
|
||||||
setNoseShape();
|
|
||||||
}
|
|
||||||
// else if (this.noseLength < -0.1) {
|
|
||||||
// this.noseLength += this.fireFreq / 4;
|
|
||||||
// setNoseShape();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
turnToFacePlayer() {
|
turnToFacePlayer() {
|
||||||
//turn to face player
|
//turn to face player
|
||||||
const dx = player.position.x - this.position.x;
|
const dx = player.position.x - this.position.x;
|
||||||
|
|||||||
144
js/spawn.js
144
js/spawn.js
@@ -81,8 +81,8 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomLevelBoss(x, y) {
|
randomLevelBoss(x, y) {
|
||||||
// suckerBoss, laserBoss, tetherBoss, snakeBoss all need a particular level to work so they are not included
|
// other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included
|
||||||
const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss"] // , "timeSkipBoss"
|
const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss"] // , "timeSkipBoss"
|
||||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||||
},
|
},
|
||||||
//mob templates *********************************************************************************************
|
//mob templates *********************************************************************************************
|
||||||
@@ -1437,69 +1437,97 @@ const spawn = {
|
|||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
launcher(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
|
launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) {
|
||||||
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
|
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.vertices = Matter.Vertices.clockwiseSort(Matter.Vertices.rotate(me.vertices, Math.PI, me.position)); //make the pointy side of triangle the front
|
me.accelMag = 0.00002 * game.accelScale;
|
||||||
me.isVerticesChange = true
|
me.frictionStatic = 0;
|
||||||
// Matter.Body.rotate(me, Math.PI)
|
me.friction = 0;
|
||||||
|
// me.memory = 200;
|
||||||
me.memory = 120;
|
me.delay = 770 * game.CDScale;
|
||||||
me.fireFreq = 0.0065 + Math.random() * 0.003;
|
me.cd = Infinity;
|
||||||
me.noseLength = 0;
|
spawn.shield(me, x, y);
|
||||||
me.fireAngle = 0;
|
me.onDamage = function () {};
|
||||||
me.accelMag = 0.0006 * game.accelScale;
|
|
||||||
me.frictionAir = 0.04;
|
|
||||||
me.lookTorque = 0.0000028 * (Math.random() > 0.5 ? -1 : 1);
|
|
||||||
me.fireDir = {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
};
|
|
||||||
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
|
|
||||||
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
|
|
||||||
}
|
|
||||||
// spawn.shield(me, x, y);
|
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
|
||||||
|
if (
|
||||||
|
this.distanceToPlayer2() < this.seeAtDistance2 &&
|
||||||
|
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
!mech.isStealth
|
||||||
|
) {
|
||||||
|
this.foundPlayer();
|
||||||
|
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.3;
|
||||||
|
} else if (this.seePlayer.recall) {
|
||||||
|
this.lostPlayer();
|
||||||
|
this.cd = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.launch();
|
this.attraction();
|
||||||
|
if (this.seePlayer.recall && this.cd < game.cycle) {
|
||||||
|
this.cd = game.cycle + this.delay;
|
||||||
|
// this.torque += 0.0002 * this.inertia;
|
||||||
|
Matter.Body.setAngularVelocity(this, 0.14)
|
||||||
|
//fire a bullet from each vertex
|
||||||
|
for (let i = 0, len = this.vertices.length; i < len; i++) {
|
||||||
|
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 5)
|
||||||
|
//give the bullet a rotational velocity as if they were attached to a vertex
|
||||||
|
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -8)
|
||||||
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
|
x: this.velocity.x + velocity.x,
|
||||||
|
y: this.velocity.y + velocity.y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
launcherBoss(x, y, radius = 100) {
|
launcherBoss(x, y, radius = 75 + Math.ceil(Math.random() * 20)) {
|
||||||
mobs.spawn(x, y, 3, radius, "rgb(175,125,255)");
|
mobs.spawn(x, y, 7, radius, "rgb(150,150,255)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
me.accelMag = 0.000065 * game.accelScale;
|
||||||
me.isVerticesChange = true
|
me.memory = 720;
|
||||||
me.memory = 240;
|
me.delay = 420 * game.CDScale;
|
||||||
me.homePosition = {
|
me.cd = Infinity;
|
||||||
x: x,
|
spawn.shield(me, x, y, 1);
|
||||||
y: y
|
me.onDamage = function () {};
|
||||||
};
|
Matter.Body.setDensity(me, 0.002 + 0.0002 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
me.fireFreq = 0.015;
|
|
||||||
me.noseLength = 0;
|
|
||||||
me.fireAngle = 0;
|
|
||||||
me.accelMag = 0.005 * game.accelScale;
|
|
||||||
me.frictionAir = 0.05;
|
|
||||||
me.lookTorque = 0.000007 * (Math.random() > 0.5 ? -1 : 1);
|
|
||||||
me.fireDir = {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
};
|
|
||||||
Matter.Body.setDensity(me, 0.02 + 0.0008 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
|
||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
|
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
|
||||||
};
|
};
|
||||||
|
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
|
||||||
|
if (
|
||||||
|
this.distanceToPlayer2() < this.seeAtDistance2 &&
|
||||||
|
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
!mech.isStealth
|
||||||
|
) {
|
||||||
|
this.foundPlayer();
|
||||||
|
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.2;
|
||||||
|
} else if (this.seePlayer.recall) {
|
||||||
|
this.lostPlayer();
|
||||||
|
this.cd = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.launch();
|
this.attraction();
|
||||||
|
if (this.seePlayer.recall && this.cd < game.cycle) {
|
||||||
//gently return to starting location
|
this.cd = game.cycle + this.delay;
|
||||||
const sub = Vector.sub(this.homePosition, this.position)
|
// this.torque += 0.0002 * this.inertia;
|
||||||
const dist = Vector.magnitude(sub)
|
Matter.Body.setAngularVelocity(this, 0.11)
|
||||||
if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002)
|
//fire a bullet from each vertex
|
||||||
|
for (let i = 0, len = this.vertices.length; i < len; i++) {
|
||||||
|
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 7)
|
||||||
|
//give the bullet a rotational velocity as if they were attached to a vertex
|
||||||
|
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -10)
|
||||||
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
|
x: this.velocity.x + velocity.x,
|
||||||
|
y: this.velocity.y + velocity.y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
seeker(x, y, radius = 6, sides = 0) {
|
seeker(x, y, radius = 6, sides = 0) {
|
||||||
@@ -1511,9 +1539,9 @@ const spawn = {
|
|||||||
this.explode(this.mass * 10);
|
this.explode(this.mass * 10);
|
||||||
};
|
};
|
||||||
Matter.Body.setDensity(me, 0.00005); //normal is 0.001
|
Matter.Body.setDensity(me, 0.00005); //normal is 0.001
|
||||||
me.timeLeft = 420;
|
me.timeLeft = 380 * (0.8 + 0.4 * Math.random());
|
||||||
me.accelMag = 0.0004 * game.accelScale;
|
me.accelMag = 0.00012 * (0.8 + 0.4 * Math.random()) * game.accelScale;
|
||||||
me.frictionAir = 0.033;
|
me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random());
|
||||||
me.restitution = 0.5;
|
me.restitution = 0.5;
|
||||||
me.leaveBody = false;
|
me.leaveBody = false;
|
||||||
me.dropPowerUp = false;
|
me.dropPowerUp = false;
|
||||||
@@ -1521,7 +1549,11 @@ const spawn = {
|
|||||||
me.collisionFilter.category = cat.mobBullet;
|
me.collisionFilter.category = cat.mobBullet;
|
||||||
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerCheck();
|
// this.seePlayer.yes = false;
|
||||||
|
this.seePlayer.recall = true;
|
||||||
|
this.seePlayer.position.x = player.position.x;
|
||||||
|
this.seePlayer.position.y = player.position.y;
|
||||||
|
|
||||||
this.attraction();
|
this.attraction();
|
||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
};
|
};
|
||||||
|
|||||||
27
todo.txt
27
todo.txt
@@ -1,27 +1,16 @@
|
|||||||
|
|
||||||
|
mob: launchers now have a new fire mechanic
|
||||||
|
mob: launcher boss
|
||||||
|
huge rework of code organization, this might produce some new bugs around mods
|
||||||
|
|
||||||
************** TODO - n-gon **************
|
************** TODO - n-gon **************
|
||||||
|
|
||||||
new bug
|
|
||||||
NaN: player position, velocity, and mouse
|
|
||||||
level 1 skyscrapers: hard
|
|
||||||
after blocking with default field, or maybe getting hit, or maybe picking up a reroll (but I have credit for all 3 from quantum immortality)
|
|
||||||
only mod was quantum immortality
|
|
||||||
only gun grenades
|
|
||||||
mob: hoppers
|
|
||||||
mob: shooters
|
|
||||||
mob: boss shooter
|
|
||||||
best guess is something to do with the renamed mods
|
|
||||||
|
|
||||||
|
|
||||||
launchers shouldn't have to face the player
|
launchers shouldn't have to face the player
|
||||||
fire after a spin
|
fire after a spin
|
||||||
give bullets velocity from spin
|
give bullets velocity from spin
|
||||||
mob boss - launcher
|
mob boss - launcher
|
||||||
|
|
||||||
impact shear buff to 3 nails?
|
lower tier of basic mods
|
||||||
|
|
||||||
make a lower tier of basic mods
|
|
||||||
33% chance for basic mod on each selection
|
33% chance for basic mod on each selection
|
||||||
make an odds variable that starts at 0% and gains 33% for each normal mod, resets to 0% after get a basic mod
|
make an odds variable that starts at 0% and gains 33% for each normal mod, resets to 0% after get a basic mod
|
||||||
don't track these mods for avoiding no repeats
|
don't track these mods for avoiding no repeats
|
||||||
@@ -40,7 +29,7 @@ make a lower tier of basic mods
|
|||||||
spawn 2 heal
|
spawn 2 heal
|
||||||
spawn 2 reroll //or 1?
|
spawn 2 reroll //or 1?
|
||||||
|
|
||||||
improve movement fluidity, through mods, or default improvements
|
movement fluidity
|
||||||
let legs jump on mobs, but player will still take damage
|
let legs jump on mobs, but player will still take damage
|
||||||
like: ori and the blind forest, celeste
|
like: ori and the blind forest, celeste
|
||||||
many of the movement abilities in these games require levels to be built around the ability
|
many of the movement abilities in these games require levels to be built around the ability
|
||||||
@@ -57,6 +46,9 @@ rays can have width, how to use this?
|
|||||||
Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||||
wide lasers?
|
wide lasers?
|
||||||
|
|
||||||
|
new type of mob vision that uses ray query with thickness
|
||||||
|
maybe use for bosses
|
||||||
|
|
||||||
bug - mines spawn extra mines when fired at thin map wall while jumping
|
bug - mines spawn extra mines when fired at thin map wall while jumping
|
||||||
|
|
||||||
mod - negative mass field move faster
|
mod - negative mass field move faster
|
||||||
@@ -83,7 +75,8 @@ boss levels - small levels just a boss, and maybe a few mobs
|
|||||||
boss level for timeSkipBoss because of game instability for boss on normal levels
|
boss level for timeSkipBoss because of game instability for boss on normal levels
|
||||||
this might not fix issues
|
this might not fix issues
|
||||||
|
|
||||||
atmosphere levels: change the pace, give the user a rest between combat
|
atmosphere levels
|
||||||
|
change the pace, give the user a rest between combat
|
||||||
low or no combat, but more graphics
|
low or no combat, but more graphics
|
||||||
explore lore
|
explore lore
|
||||||
find power ups in "wrecked" mechs representing previous simulations
|
find power ups in "wrecked" mechs representing previous simulations
|
||||||
|
|||||||
Reference in New Issue
Block a user