added laser bot
This commit is contained in:
3835
js/bullets.js
3835
js/bullets.js
File diff suppressed because it is too large
Load Diff
464
js/engine.js
464
js/engine.js
@@ -1,233 +1,233 @@
|
|||||||
//matter.js ***********************************************************
|
//matter.js ***********************************************************
|
||||||
// module aliases
|
// module aliases
|
||||||
const Engine = Matter.Engine,
|
const Engine = Matter.Engine,
|
||||||
World = Matter.World,
|
World = Matter.World,
|
||||||
Events = Matter.Events,
|
Events = Matter.Events,
|
||||||
Composites = Matter.Composites,
|
Composites = Matter.Composites,
|
||||||
Composite = Matter.Composite,
|
Composite = Matter.Composite,
|
||||||
Constraint = Matter.Constraint,
|
Constraint = Matter.Constraint,
|
||||||
Vertices = Matter.Vertices,
|
Vertices = Matter.Vertices,
|
||||||
Query = Matter.Query,
|
Query = Matter.Query,
|
||||||
Body = Matter.Body,
|
Body = Matter.Body,
|
||||||
Bodies = Matter.Bodies;
|
Bodies = Matter.Bodies;
|
||||||
|
|
||||||
// create an engine
|
// create an engine
|
||||||
const engine = Engine.create();
|
const engine = Engine.create();
|
||||||
engine.world.gravity.scale = 0; //turn off gravity (it's added back in later)
|
engine.world.gravity.scale = 0; //turn off gravity (it's added back in later)
|
||||||
// engine.velocityIterations = 100
|
// engine.velocityIterations = 100
|
||||||
// engine.positionIterations = 100
|
// engine.positionIterations = 100
|
||||||
// engine.enableSleeping = true
|
// engine.enableSleeping = true
|
||||||
|
|
||||||
// matter events *********************************************************
|
// matter events *********************************************************
|
||||||
//************************************************************************
|
//************************************************************************
|
||||||
//************************************************************************
|
//************************************************************************
|
||||||
//************************************************************************
|
//************************************************************************
|
||||||
|
|
||||||
function playerOnGroundCheck(event) {
|
function playerOnGroundCheck(event) {
|
||||||
//runs on collisions events
|
//runs on collisions events
|
||||||
function enter() {
|
function enter() {
|
||||||
mech.numTouching++;
|
mech.numTouching++;
|
||||||
if (!mech.onGround) mech.enterLand();
|
if (!mech.onGround) mech.enterLand();
|
||||||
}
|
}
|
||||||
const pairs = event.pairs;
|
const pairs = event.pairs;
|
||||||
for (let i = 0, j = pairs.length; i != j; ++i) {
|
for (let i = 0, j = pairs.length; i != j; ++i) {
|
||||||
let pair = pairs[i];
|
let pair = pairs[i];
|
||||||
if (pair.bodyA === jumpSensor) {
|
if (pair.bodyA === jumpSensor) {
|
||||||
mech.standingOn = pair.bodyB; //keeping track to correctly provide recoil on jump
|
mech.standingOn = pair.bodyB; //keeping track to correctly provide recoil on jump
|
||||||
if (mech.standingOn.alive !== true) enter();
|
if (mech.standingOn.alive !== true) enter();
|
||||||
} else if (pair.bodyB === jumpSensor) {
|
} else if (pair.bodyB === jumpSensor) {
|
||||||
mech.standingOn = pair.bodyA; //keeping track to correctly provide recoil on jump
|
mech.standingOn = pair.bodyA; //keeping track to correctly provide recoil on jump
|
||||||
if (mech.standingOn.alive !== true) enter();
|
if (mech.standingOn.alive !== true) enter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mech.numTouching = 0;
|
mech.numTouching = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerOffGroundCheck(event) {
|
function playerOffGroundCheck(event) {
|
||||||
//runs on collisions events
|
//runs on collisions events
|
||||||
function enter() {
|
function enter() {
|
||||||
if (mech.onGround && mech.numTouching === 0) mech.enterAir();
|
if (mech.onGround && mech.numTouching === 0) mech.enterAir();
|
||||||
}
|
}
|
||||||
const pairs = event.pairs;
|
const pairs = event.pairs;
|
||||||
for (let i = 0, j = pairs.length; i != j; ++i) {
|
for (let i = 0, j = pairs.length; i != j; ++i) {
|
||||||
if (pairs[i].bodyA === jumpSensor) {
|
if (pairs[i].bodyA === jumpSensor) {
|
||||||
enter();
|
enter();
|
||||||
} else if (pairs[i].bodyB === jumpSensor) {
|
} else if (pairs[i].bodyB === jumpSensor) {
|
||||||
enter();
|
enter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerHeadCheck(event) {
|
function playerHeadCheck(event) {
|
||||||
//runs on collisions events
|
//runs on collisions events
|
||||||
if (mech.crouch) {
|
if (mech.crouch) {
|
||||||
mech.isHeadClear = true;
|
mech.isHeadClear = true;
|
||||||
const pairs = event.pairs;
|
const pairs = event.pairs;
|
||||||
for (let i = 0, j = pairs.length; i != j; ++i) {
|
for (let i = 0, j = pairs.length; i != j; ++i) {
|
||||||
if (pairs[i].bodyA === headSensor) {
|
if (pairs[i].bodyA === headSensor) {
|
||||||
mech.isHeadClear = false;
|
mech.isHeadClear = false;
|
||||||
} else if (pairs[i].bodyB === headSensor) {
|
} else if (pairs[i].bodyB === headSensor) {
|
||||||
mech.isHeadClear = false;
|
mech.isHeadClear = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mobCollisionChecks(event) {
|
function mobCollisionChecks(event) {
|
||||||
const pairs = event.pairs;
|
const pairs = event.pairs;
|
||||||
for (let i = 0, j = pairs.length; i != j; i++) {
|
for (let i = 0, j = pairs.length; i != j; i++) {
|
||||||
|
|
||||||
//body + player collision
|
//body + player collision
|
||||||
if (game.isBodyDamage && mech.damageImmune < mech.cycle) {
|
if (game.isBodyDamage && mech.damageImmune < mech.cycle) {
|
||||||
if (pairs[i].bodyA === playerBody || pairs[i].bodyA === playerHead) {
|
if (pairs[i].bodyA === playerBody || pairs[i].bodyA === playerHead) {
|
||||||
collidePlayer(pairs[i].bodyB)
|
collidePlayer(pairs[i].bodyB)
|
||||||
} else if (pairs[i].bodyB === playerBody || pairs[i].bodyB === playerHead) {
|
} else if (pairs[i].bodyB === playerBody || pairs[i].bodyB === playerHead) {
|
||||||
collidePlayer(pairs[i].bodyA)
|
collidePlayer(pairs[i].bodyA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
|
function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
|
||||||
if (obj.classType === "body" && obj.speed > speedThreshold && obj.mass > massThreshold) { //dmg from hitting a body
|
if (obj.classType === "body" && obj.speed > speedThreshold && obj.mass > massThreshold) { //dmg from hitting a body
|
||||||
const v = Matter.Vector.magnitude(Matter.Vector.sub(player.velocity, obj.velocity));
|
const v = Matter.Vector.magnitude(Matter.Vector.sub(player.velocity, obj.velocity));
|
||||||
if (v > speedThreshold) {
|
if (v > speedThreshold) {
|
||||||
mech.damageImmune = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
mech.damageImmune = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
||||||
let dmg = Math.sqrt((v - speedThreshold + 0.1) * (obj.mass - massThreshold)) * 0.01;
|
let dmg = Math.sqrt((v - speedThreshold + 0.1) * (obj.mass - massThreshold)) * 0.01;
|
||||||
dmg = Math.min(Math.max(dmg, 0.02), 0.15);
|
dmg = Math.min(Math.max(dmg, 0.02), 0.15);
|
||||||
mech.damage(dmg);
|
mech.damage(dmg);
|
||||||
game.drawList.push({ //add dmg to draw queue
|
game.drawList.push({ //add dmg to draw queue
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
radius: dmg * 500,
|
radius: dmg * 500,
|
||||||
color: game.mobDmgColor,
|
color: game.mobDmgColor,
|
||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else if (obj.isStatic && player.speed > speedThreshold * 2) { //falling dmg / hitting map dmg
|
// else if (obj.isStatic && player.speed > speedThreshold * 2) { //falling dmg / hitting map dmg
|
||||||
// mech.damageImmune = mech.cycle + 30;
|
// mech.damageImmune = mech.cycle + 30;
|
||||||
// console.log(player.speed)
|
// console.log(player.speed)
|
||||||
// let dmg = Math.min(Math.max(player.speed * 0.001, 0.02), 0.2);
|
// let dmg = Math.min(Math.max(player.speed * 0.001, 0.02), 0.2);
|
||||||
// mech.damage(dmg);
|
// mech.damage(dmg);
|
||||||
// game.drawList.push({
|
// game.drawList.push({
|
||||||
// //add dmg to draw queue
|
// //add dmg to draw queue
|
||||||
// x: pairs[i].activeContacts[0].vertex.x,
|
// x: pairs[i].activeContacts[0].vertex.x,
|
||||||
// y: pairs[i].activeContacts[0].vertex.y,
|
// y: pairs[i].activeContacts[0].vertex.y,
|
||||||
// radius: dmg * 500,
|
// radius: dmg * 500,
|
||||||
// color: game.mobDmgColor,
|
// color: game.mobDmgColor,
|
||||||
// time: game.drawTime
|
// time: game.drawTime
|
||||||
// });
|
// });
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
//mob + (player,bullet,body) collisions
|
//mob + (player,bullet,body) collisions
|
||||||
for (let k = 0; k < mob.length; k++) {
|
for (let k = 0; k < mob.length; k++) {
|
||||||
if (mob[k].alive && mech.alive) {
|
if (mob[k].alive && mech.alive) {
|
||||||
if (pairs[i].bodyA === mob[k]) {
|
if (pairs[i].bodyA === mob[k]) {
|
||||||
collideMob(pairs[i].bodyB);
|
collideMob(pairs[i].bodyB);
|
||||||
break;
|
break;
|
||||||
} else if (pairs[i].bodyB === mob[k]) {
|
} else if (pairs[i].bodyB === mob[k]) {
|
||||||
collideMob(pairs[i].bodyA);
|
collideMob(pairs[i].bodyA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collideMob(obj) {
|
function collideMob(obj) {
|
||||||
//player + mob collision
|
//player + mob collision
|
||||||
if (obj === playerBody || obj === playerHead) {
|
if (obj === playerBody || obj === playerHead) {
|
||||||
if (mech.damageImmune < mech.cycle) {
|
if (mech.damageImmune < mech.cycle) {
|
||||||
mech.damageImmune = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
mech.damageImmune = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
||||||
mob[k].foundPlayer();
|
mob[k].foundPlayer();
|
||||||
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
||||||
mech.damage(dmg);
|
mech.damage(dmg);
|
||||||
if (mob[k].onHit) mob[k].onHit(k);
|
if (mob[k].onHit) mob[k].onHit(k);
|
||||||
if (b.modAnnihilation && mob[k].dropPowerUp) {
|
if (b.modAnnihilation && mob[k].dropPowerUp) {
|
||||||
mob[k].death();
|
mob[k].death();
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
//add dmg to draw queue
|
//add dmg to draw queue
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
radius: dmg * 2000,
|
radius: dmg * 2000,
|
||||||
color: "rgba(255,0,255,0.2)",
|
color: "rgba(255,0,255,0.2)",
|
||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
//add dmg to draw queue
|
//add dmg to draw queue
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
radius: dmg * 500,
|
radius: dmg * 500,
|
||||||
color: game.mobDmgColor,
|
color: game.mobDmgColor,
|
||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//extra kick between player and mob //this section would be better with forces but they don't work...
|
//extra kick between player and mob //this section would be better with forces but they don't work...
|
||||||
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
||||||
Matter.Body.setVelocity(player, {
|
Matter.Body.setVelocity(player, {
|
||||||
x: player.velocity.x + 8 * Math.cos(angle),
|
x: player.velocity.x + 8 * Math.cos(angle),
|
||||||
y: player.velocity.y + 8 * Math.sin(angle)
|
y: player.velocity.y + 8 * Math.sin(angle)
|
||||||
});
|
});
|
||||||
Matter.Body.setVelocity(mob[k], {
|
Matter.Body.setVelocity(mob[k], {
|
||||||
x: mob[k].velocity.x - 8 * Math.cos(angle),
|
x: mob[k].velocity.x - 8 * Math.cos(angle),
|
||||||
y: mob[k].velocity.y - 8 * Math.sin(angle)
|
y: mob[k].velocity.y - 8 * Math.sin(angle)
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//mob + bullet collisions
|
//mob + bullet collisions
|
||||||
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
||||||
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)));
|
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)));
|
||||||
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)))
|
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)))
|
||||||
if (b.modIsCrit && !mob[k].seePlayer.recall) dmg *= 5
|
if (b.modIsCrit && !mob[k].seePlayer.recall) dmg *= 5
|
||||||
mob[k].foundPlayer();
|
mob[k].foundPlayer();
|
||||||
mob[k].damage(dmg);
|
mob[k].damage(dmg);
|
||||||
obj.onDmg(); //some bullets do actions when they hits things, like despawn
|
obj.onDmg(); //some bullets do actions when they hits things, like despawn
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
//add dmg to draw queue
|
//add dmg to draw queue
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
// radius: Math.sqrt(dmg) * 40,
|
// radius: Math.sqrt(dmg) * 40,
|
||||||
radius: Math.log(2 * dmg + 1.1) * 40,
|
radius: Math.log(2 * dmg + 1.1) * 40,
|
||||||
color: game.playerDmgColor,
|
color: game.playerDmgColor,
|
||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//mob + body collisions
|
//mob + body collisions
|
||||||
if (obj.classType === "body" && obj.speed > 5) {
|
if (obj.classType === "body" && obj.speed > 5) {
|
||||||
const v = Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity));
|
const v = Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity));
|
||||||
if (v > 8) {
|
if (v > 8) {
|
||||||
let dmg = b.dmgScale * v * Math.sqrt(obj.mass) * 0.05;
|
let dmg = b.dmgScale * v * Math.sqrt(obj.mass) * 0.05;
|
||||||
mob[k].damage(dmg);
|
mob[k].damage(dmg);
|
||||||
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
|
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
//add dmg to draw queue
|
//add dmg to draw queue
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
radius: Math.sqrt(dmg) * 40,
|
radius: Math.sqrt(dmg) * 40,
|
||||||
color: game.playerDmgColor,
|
color: game.playerDmgColor,
|
||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//determine if player is on the ground
|
//determine if player is on the ground
|
||||||
Events.on(engine, "collisionStart", function (event) {
|
Events.on(engine, "collisionStart", function (event) {
|
||||||
playerOnGroundCheck(event);
|
playerOnGroundCheck(event);
|
||||||
playerHeadCheck(event);
|
playerHeadCheck(event);
|
||||||
mobCollisionChecks(event);
|
mobCollisionChecks(event);
|
||||||
});
|
});
|
||||||
Events.on(engine, "collisionActive", function (event) {
|
Events.on(engine, "collisionActive", function (event) {
|
||||||
playerOnGroundCheck(event);
|
playerOnGroundCheck(event);
|
||||||
playerHeadCheck(event);
|
playerHeadCheck(event);
|
||||||
});
|
});
|
||||||
Events.on(engine, "collisionEnd", function (event) {
|
Events.on(engine, "collisionEnd", function (event) {
|
||||||
playerOffGroundCheck(event);
|
playerOffGroundCheck(event);
|
||||||
});
|
});
|
||||||
2098
js/game.js
2098
js/game.js
File diff suppressed because it is too large
Load Diff
692
js/index.js
692
js/index.js
@@ -1,347 +1,347 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
/* TODO: *******************************************
|
/* TODO: *******************************************
|
||||||
*****************************************************
|
*****************************************************
|
||||||
|
|
||||||
add builds with combinations of gun, field and mobs
|
add builds with combinations of gun, field and mobs
|
||||||
use the pull down menu
|
use the pull down menu
|
||||||
|
|
||||||
dynamically generate html about fields, guns and mods
|
dynamically generate html about fields, guns and mods
|
||||||
|
|
||||||
add grid check to improve queries over large body arrays
|
add grid check to improve queries over large body arrays
|
||||||
something about broad phase
|
something about broad phase
|
||||||
having trouble with this, might give up
|
having trouble with this, might give up
|
||||||
|
|
||||||
gun: like drones, but fast moving and short lived
|
gun: like drones, but fast moving and short lived
|
||||||
dies after doing damage
|
dies after doing damage
|
||||||
|
|
||||||
gun: Spirit Bomb (singularity)
|
gun: Spirit Bomb (singularity)
|
||||||
use charge up like rail gun
|
use charge up like rail gun
|
||||||
electricity graphics like plasma torch
|
electricity graphics like plasma torch
|
||||||
suck in nearby mobs, power ups?, blocks?
|
suck in nearby mobs, power ups?, blocks?
|
||||||
sucked in stuff increase size
|
sucked in stuff increase size
|
||||||
uses energy
|
uses energy
|
||||||
|
|
||||||
mod: auto pick up guns, heals, ammo
|
mod: auto pick up guns, heals, ammo
|
||||||
use the same rule for drones
|
use the same rule for drones
|
||||||
maybe give some other bonus too?
|
maybe give some other bonus too?
|
||||||
|
|
||||||
rework junk bot
|
rework junk bot
|
||||||
it's behavior is too unpredictable
|
it's behavior is too unpredictable
|
||||||
range is unclear
|
range is unclear
|
||||||
having the bullets last long after doing dmg isn't fun
|
having the bullets last long after doing dmg isn't fun
|
||||||
we want a fun gun that acts like a melee weapon
|
we want a fun gun that acts like a melee weapon
|
||||||
|
|
||||||
atmosphere levels
|
atmosphere levels
|
||||||
large rotating fan that the player has to move through
|
large rotating fan that the player has to move through
|
||||||
give the user a rest, between combat
|
give the user a rest, between combat
|
||||||
low combat
|
low combat
|
||||||
nonaggressive mobs
|
nonaggressive mobs
|
||||||
one mob attacking the passive mobs
|
one mob attacking the passive mobs
|
||||||
more graphics
|
more graphics
|
||||||
|
|
||||||
Boss levels
|
Boss levels
|
||||||
boss grows and spilt, if you don't kill it fast
|
boss grows and spilt, if you don't kill it fast
|
||||||
sensor that locks you in after you enter the boss room
|
sensor that locks you in after you enter the boss room
|
||||||
boss that eats other mobs and gains stats from them
|
boss that eats other mobs and gains stats from them
|
||||||
chance to spawn on any level (past level 5)
|
chance to spawn on any level (past level 5)
|
||||||
boss that knows how to shoot (player) bullets that collide with player
|
boss that knows how to shoot (player) bullets that collide with player
|
||||||
overwrite custom engine collision bullet mob function.
|
overwrite custom engine collision bullet mob function.
|
||||||
|
|
||||||
add a key that player picks up and needs to set on the exit door to open it
|
add a key that player picks up and needs to set on the exit door to open it
|
||||||
|
|
||||||
make power ups keep moving to player if the pickup field is turned off before they get picked up
|
make power ups keep moving to player if the pickup field is turned off before they get picked up
|
||||||
not sure how to do this without adding a constant check
|
not sure how to do this without adding a constant check
|
||||||
|
|
||||||
animate new level spawn by having the map aspects randomly fly into place
|
animate new level spawn by having the map aspects randomly fly into place
|
||||||
|
|
||||||
new map with repeating endlessness
|
new map with repeating endlessness
|
||||||
get ideas from Manifold Garden game
|
get ideas from Manifold Garden game
|
||||||
if falling, get teleported above the map
|
if falling, get teleported above the map
|
||||||
I tried it, but had trouble getting the camera to adjust to the teleportation
|
I tried it, but had trouble getting the camera to adjust to the teleportation
|
||||||
this can apply to blocks mobs, and power ups as well
|
this can apply to blocks mobs, and power ups as well
|
||||||
|
|
||||||
field power up effects
|
field power up effects
|
||||||
field allows player to hold and throw living mobs
|
field allows player to hold and throw living mobs
|
||||||
|
|
||||||
mod power ups ideas
|
mod power ups ideas
|
||||||
double jump
|
double jump
|
||||||
bullet on mob damage effects
|
bullet on mob damage effects
|
||||||
add to the array mob.do new mob behaviors
|
add to the array mob.do new mob behaviors
|
||||||
add a damage over time
|
add a damage over time
|
||||||
add a freeze
|
add a freeze
|
||||||
|
|
||||||
give mobs more animal-like behaviors
|
give mobs more animal-like behaviors
|
||||||
like rain world
|
like rain world
|
||||||
give mobs something to do when they don't see player
|
give mobs something to do when they don't see player
|
||||||
explore map
|
explore map
|
||||||
eat power ups
|
eat power ups
|
||||||
drop power up (if killed after eating one)
|
drop power up (if killed after eating one)
|
||||||
mobs some times aren't aggressive
|
mobs some times aren't aggressive
|
||||||
when low on life or after taking a large hit
|
when low on life or after taking a large hit
|
||||||
mobs can fight each other
|
mobs can fight each other
|
||||||
this might be hard to code
|
this might be hard to code
|
||||||
isolated mobs try to group up.
|
isolated mobs try to group up.
|
||||||
|
|
||||||
game mechanics
|
game mechanics
|
||||||
mechanics that support the physics engine
|
mechanics that support the physics engine
|
||||||
add rope/constraint
|
add rope/constraint
|
||||||
get ideas from game: limbo / inside
|
get ideas from game: limbo / inside
|
||||||
environmental hazards
|
environmental hazards
|
||||||
laser
|
laser
|
||||||
lava
|
lava
|
||||||
button / switch
|
button / switch
|
||||||
door
|
door
|
||||||
fizzler
|
fizzler
|
||||||
moving platform
|
moving platform
|
||||||
map zones
|
map zones
|
||||||
water
|
water
|
||||||
low friction ground
|
low friction ground
|
||||||
bouncy ground
|
bouncy ground
|
||||||
|
|
||||||
|
|
||||||
// collision info:
|
// collision info:
|
||||||
category mask
|
category mask
|
||||||
powerUp: 0x100000 0x100001
|
powerUp: 0x100000 0x100001
|
||||||
body: 0x010000 0x011111
|
body: 0x010000 0x011111
|
||||||
player: 0x001000 0x010011
|
player: 0x001000 0x010011
|
||||||
bullet: 0x000100 0x010011
|
bullet: 0x000100 0x010011
|
||||||
mob: 0x000010 0x011111
|
mob: 0x000010 0x011111
|
||||||
mobBullet: 0x000010 0x011101
|
mobBullet: 0x000010 0x011101
|
||||||
mobShield: 0x000010 0x001100
|
mobShield: 0x000010 0x001100
|
||||||
map: 0x000001 0x111111
|
map: 0x000001 0x111111
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//build build grid display
|
//build build grid display
|
||||||
const build = {
|
const build = {
|
||||||
isShowingBuilds: false,
|
isShowingBuilds: false,
|
||||||
list: [],
|
list: [],
|
||||||
choosePowerUp(who, index, type) {
|
choosePowerUp(who, index, type) {
|
||||||
//check if matching a current power up
|
//check if matching a current power up
|
||||||
for (let i = 0; i < build.list.length; i++) {
|
for (let i = 0; i < build.list.length; i++) {
|
||||||
if (build.list[i].index === index && build.list[i].type === type) { //if already click, toggle off
|
if (build.list[i].index === index && build.list[i].type === type) { //if already click, toggle off
|
||||||
build.list.splice(i, 1);
|
build.list.splice(i, 1);
|
||||||
who.style.backgroundColor = "#fff"
|
who.style.backgroundColor = "#fff"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if trying to get a second field
|
//check if trying to get a second field
|
||||||
if (type === "field") {
|
if (type === "field") {
|
||||||
for (let i = 0; i < build.list.length; i++) {
|
for (let i = 0; i < build.list.length; i++) {
|
||||||
if (build.list[i].type === "field") { //if already click, toggle off
|
if (build.list[i].type === "field") { //if already click, toggle off
|
||||||
build.list[i].who.style.backgroundColor = "#fff"
|
build.list[i].who.style.backgroundColor = "#fff"
|
||||||
build.list.splice(i, 1);
|
build.list.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build.list.length < 5) { //add to build array
|
if (build.list.length < 5) { //add to build array
|
||||||
// who.style.border = "2px solid #333"
|
// who.style.border = "2px solid #333"
|
||||||
who.style.backgroundColor = "#919ba8" //"#868f9a"
|
who.style.backgroundColor = "#919ba8" //"#868f9a"
|
||||||
build.list[build.list.length] = {
|
build.list[build.list.length] = {
|
||||||
who: who,
|
who: who,
|
||||||
index: index,
|
index: index,
|
||||||
type: type
|
type: type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
startBuildRun() {
|
startBuildRun() {
|
||||||
spawn.setSpawnList();
|
spawn.setSpawnList();
|
||||||
spawn.setSpawnList();
|
spawn.setSpawnList();
|
||||||
game.startGame();
|
game.startGame();
|
||||||
game.difficulty = 6;
|
game.difficulty = 6;
|
||||||
level.isBuildRun = true;
|
level.isBuildRun = true;
|
||||||
for (let i = 0; i < build.list.length; i++) {
|
for (let i = 0; i < build.list.length; i++) {
|
||||||
if (build.list[i].type === "field") {
|
if (build.list[i].type === "field") {
|
||||||
mech.fieldUpgrades[build.list[i].index].effect();
|
mech.fieldUpgrades[build.list[i].index].effect();
|
||||||
} else if (build.list[i].type === "gun") {
|
} else if (build.list[i].type === "gun") {
|
||||||
b.giveGuns(build.list[i].index)
|
b.giveGuns(build.list[i].index)
|
||||||
} else if (build.list[i].type === "mod") {
|
} else if (build.list[i].type === "mod") {
|
||||||
b.giveMod(build.list[i].index)
|
b.giveMod(build.list[i].index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("build-button").addEventListener("click", () => {
|
document.getElementById("build-button").addEventListener("click", () => {
|
||||||
document.getElementById("build-button").style.display = "none";
|
document.getElementById("build-button").style.display = "none";
|
||||||
const el = document.getElementById("build-grid")
|
const el = document.getElementById("build-grid")
|
||||||
if (build.isShowingBuilds) {
|
if (build.isShowingBuilds) {
|
||||||
el.style.display = "none"
|
el.style.display = "none"
|
||||||
build.isShowingBuilds = false
|
build.isShowingBuilds = false
|
||||||
document.body.style.overflow = "hidden"
|
document.body.style.overflow = "hidden"
|
||||||
document.getElementById("controls").style.display = 'inline'
|
document.getElementById("controls").style.display = 'inline'
|
||||||
document.getElementById("settings").style.display = 'inline'
|
document.getElementById("settings").style.display = 'inline'
|
||||||
} else {
|
} else {
|
||||||
build.list = []
|
build.list = []
|
||||||
// let text = '<p>choose up to 5 powers<br> <button type="button" id="build-begin-button" onclick="build.startBuildRun()">Begin Run</button></p>'
|
// let text = '<p>choose up to 5 powers<br> <button type="button" id="build-begin-button" onclick="build.startBuildRun()">Begin Run</button></p>'
|
||||||
let text =
|
let text =
|
||||||
`<div style="display: flex; justify-content: center; align-items: center;">
|
`<div style="display: flex; justify-content: center; align-items: center;">
|
||||||
<svg class="SVG-button" onclick="build.startBuildRun()" width="90" height="40">
|
<svg class="SVG-button" onclick="build.startBuildRun()" width="90" height="40">
|
||||||
<g stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Ariel, sans-serif">
|
<g stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Ariel, sans-serif">
|
||||||
<text x="15" y="31">start</text>
|
<text x="15" y="31">start</text>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="build-grid-module" style="font-size: 19px; line-height: 110%;">
|
<div class="build-grid-module" style="font-size: 19px; line-height: 110%;">
|
||||||
Choose up to five power ups. Once you start, only health and ammo will drop, so pick carefully.
|
Choose up to five power ups. Once you start, only health and ammo will drop, so pick carefully.
|
||||||
</div>`
|
</div>`
|
||||||
for (let i = 1, len = mech.fieldUpgrades.length; i < len; i++) {
|
for (let i = 1, len = mech.fieldUpgrades.length; i < len; i++) {
|
||||||
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'field')" ><div class="circle-grid field"></div> <strong style='font-size:1.3em;'>${mech.fieldUpgrades[i].name}</strong><br> ${mech.fieldUpgrades[i].description}</div>`
|
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'field')" ><div class="circle-grid field"></div> <strong style='font-size:1.3em;'>${mech.fieldUpgrades[i].name}</strong><br> ${mech.fieldUpgrades[i].description}</div>`
|
||||||
}
|
}
|
||||||
for (let i = 0, len = b.guns.length; i < len; i++) {
|
for (let i = 0, len = b.guns.length; i < len; i++) {
|
||||||
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="circle-grid gun"></div> <strong style='font-size:1.3em;'>${b.guns[i].name}</strong><br> ${b.guns[i].description}</div>`
|
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="circle-grid gun"></div> <strong style='font-size:1.3em;'>${b.guns[i].name}</strong><br> ${b.guns[i].description}</div>`
|
||||||
}
|
}
|
||||||
for (let i = 0, len = b.mods.length; i < len; i++) {
|
for (let i = 0, len = b.mods.length; i < len; i++) {
|
||||||
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'mod')"><div class="circle-grid mod"></div> <strong style='font-size:1.3em;'>${b.mods[i].name}</strong><br> ${b.mods[i].description}</div>`
|
text += `<div class="build-grid-module" onclick="build.choosePowerUp(this,${i},'mod')"><div class="circle-grid mod"></div> <strong style='font-size:1.3em;'>${b.mods[i].name}</strong><br> ${b.mods[i].description}</div>`
|
||||||
}
|
}
|
||||||
el.innerHTML = text
|
el.innerHTML = text
|
||||||
el.style.display = "grid"
|
el.style.display = "grid"
|
||||||
build.isShowingBuilds = true
|
build.isShowingBuilds = true
|
||||||
document.body.style.overflowY = "scroll";
|
document.body.style.overflowY = "scroll";
|
||||||
document.body.style.overflowX = "hidden";
|
document.body.style.overflowX = "hidden";
|
||||||
document.getElementById("controls").style.display = 'none'
|
document.getElementById("controls").style.display = 'none'
|
||||||
document.getElementById("settings").style.display = 'none'
|
document.getElementById("settings").style.display = 'none'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//set up canvas
|
//set up canvas
|
||||||
var canvas = document.getElementById("canvas");
|
var canvas = document.getElementById("canvas");
|
||||||
//using "const" causes problems in safari when an ID shares the same name.
|
//using "const" causes problems in safari when an ID shares the same name.
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
document.body.style.backgroundColor = "#fff";
|
document.body.style.backgroundColor = "#fff";
|
||||||
|
|
||||||
//disable pop up menu on right click
|
//disable pop up menu on right click
|
||||||
document.oncontextmenu = function () {
|
document.oncontextmenu = function () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupCanvas() {
|
function setupCanvas() {
|
||||||
canvas.width = window.innerWidth;
|
canvas.width = window.innerWidth;
|
||||||
canvas.height = window.innerHeight;
|
canvas.height = window.innerHeight;
|
||||||
canvas.width2 = canvas.width / 2; //precalculated because I use this often (in mouse look)
|
canvas.width2 = canvas.width / 2; //precalculated because I use this often (in mouse look)
|
||||||
canvas.height2 = canvas.height / 2;
|
canvas.height2 = canvas.height / 2;
|
||||||
canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
|
canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
|
||||||
ctx.font = "15px Arial";
|
ctx.font = "15px Arial";
|
||||||
ctx.lineJoin = "round";
|
ctx.lineJoin = "round";
|
||||||
ctx.lineCap = "round";
|
ctx.lineCap = "round";
|
||||||
// ctx.lineCap='square';
|
// ctx.lineCap='square';
|
||||||
game.setZoom();
|
game.setZoom();
|
||||||
}
|
}
|
||||||
setupCanvas();
|
setupCanvas();
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
setupCanvas();
|
setupCanvas();
|
||||||
};
|
};
|
||||||
|
|
||||||
//mouse move input
|
//mouse move input
|
||||||
document.body.addEventListener("mousemove", (e) => {
|
document.body.addEventListener("mousemove", (e) => {
|
||||||
game.mouse.x = e.clientX;
|
game.mouse.x = e.clientX;
|
||||||
game.mouse.y = e.clientY;
|
game.mouse.y = e.clientY;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.addEventListener("mouseup", (e) => {
|
document.body.addEventListener("mouseup", (e) => {
|
||||||
// game.buildingUp(e); //uncomment when building levels
|
// game.buildingUp(e); //uncomment when building levels
|
||||||
// game.mouseDown = false;
|
// game.mouseDown = false;
|
||||||
// console.log(e)
|
// console.log(e)
|
||||||
if (e.which === 3) {
|
if (e.which === 3) {
|
||||||
game.mouseDownRight = false;
|
game.mouseDownRight = false;
|
||||||
} else {
|
} else {
|
||||||
game.mouseDown = false;
|
game.mouseDown = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.addEventListener("mousedown", (e) => {
|
document.body.addEventListener("mousedown", (e) => {
|
||||||
if (e.which === 3) {
|
if (e.which === 3) {
|
||||||
game.mouseDownRight = true;
|
game.mouseDownRight = true;
|
||||||
} else {
|
} else {
|
||||||
game.mouseDown = true;
|
game.mouseDown = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//keyboard input
|
//keyboard input
|
||||||
const keys = [];
|
const keys = [];
|
||||||
document.body.addEventListener("keydown", (e) => {
|
document.body.addEventListener("keydown", (e) => {
|
||||||
keys[e.keyCode] = true;
|
keys[e.keyCode] = true;
|
||||||
game.keyPress();
|
game.keyPress();
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.addEventListener("keyup", (e) => {
|
document.body.addEventListener("keyup", (e) => {
|
||||||
keys[e.keyCode] = false;
|
keys[e.keyCode] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.addEventListener("wheel", (e) => {
|
document.body.addEventListener("wheel", (e) => {
|
||||||
if (e.deltaY > 0) {
|
if (e.deltaY > 0) {
|
||||||
game.nextGun();
|
game.nextGun();
|
||||||
} else {
|
} else {
|
||||||
game.previousGun();
|
game.previousGun();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("fps-select").addEventListener("input", () => {
|
document.getElementById("fps-select").addEventListener("input", () => {
|
||||||
let value = document.getElementById("fps-select").value
|
let value = document.getElementById("fps-select").value
|
||||||
if (value === 'max') {
|
if (value === 'max') {
|
||||||
game.fpsCapDefault = 999999999;
|
game.fpsCapDefault = 999999999;
|
||||||
} else if (value === '72') {
|
} else if (value === '72') {
|
||||||
game.fpsCapDefault = 72
|
game.fpsCapDefault = 72
|
||||||
} else if (value === '60') {
|
} else if (value === '60') {
|
||||||
game.fpsCapDefault = 60
|
game.fpsCapDefault = 60
|
||||||
} else if (value === '45') {
|
} else if (value === '45') {
|
||||||
game.fpsCapDefault = 45
|
game.fpsCapDefault = 45
|
||||||
} else if (value === '30') {
|
} else if (value === '30') {
|
||||||
game.fpsCapDefault = 30
|
game.fpsCapDefault = 30
|
||||||
} else if (value === '15') {
|
} else if (value === '15') {
|
||||||
game.fpsCapDefault = 15
|
game.fpsCapDefault = 15
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("body-damage").addEventListener("input", () => {
|
document.getElementById("body-damage").addEventListener("input", () => {
|
||||||
game.isBodyDamage = document.getElementById("body-damage").checked
|
game.isBodyDamage = document.getElementById("body-damage").checked
|
||||||
});
|
});
|
||||||
|
|
||||||
// function playSound(id) {
|
// function playSound(id) {
|
||||||
// //play sound
|
// //play sound
|
||||||
// if (false) {
|
// if (false) {
|
||||||
// //sounds are turned off for now
|
// //sounds are turned off for now
|
||||||
// // if (document.getElementById(id)) {
|
// // if (document.getElementById(id)) {
|
||||||
// var sound = document.getElementById(id); //setup audio
|
// var sound = document.getElementById(id); //setup audio
|
||||||
// sound.currentTime = 0; //reset position of playback to zero //sound.load();
|
// sound.currentTime = 0; //reset position of playback to zero //sound.load();
|
||||||
// sound.play();
|
// sound.play();
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function shuffle(array) {
|
function shuffle(array) {
|
||||||
var currentIndex = array.length,
|
var currentIndex = array.length,
|
||||||
temporaryValue,
|
temporaryValue,
|
||||||
randomIndex;
|
randomIndex;
|
||||||
// While there remain elements to shuffle...
|
// While there remain elements to shuffle...
|
||||||
while (0 !== currentIndex) {
|
while (0 !== currentIndex) {
|
||||||
// Pick a remaining element...
|
// Pick a remaining element...
|
||||||
randomIndex = Math.floor(Math.random() * currentIndex);
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
currentIndex -= 1;
|
currentIndex -= 1;
|
||||||
// And swap it with the current element.
|
// And swap it with the current element.
|
||||||
temporaryValue = array[currentIndex];
|
temporaryValue = array[currentIndex];
|
||||||
array[currentIndex] = array[randomIndex];
|
array[currentIndex] = array[randomIndex];
|
||||||
array[randomIndex] = temporaryValue;
|
array[randomIndex] = temporaryValue;
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//main loop ************************************************************
|
//main loop ************************************************************
|
||||||
//**********************************************************************
|
//**********************************************************************
|
||||||
function cycle() {
|
function cycle() {
|
||||||
if (!game.paused) requestAnimationFrame(cycle);
|
if (!game.paused) requestAnimationFrame(cycle);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const elapsed = now - game.then; // calc elapsed time since last loop
|
const elapsed = now - game.then; // calc elapsed time since last loop
|
||||||
if (elapsed > game.fpsInterval) { // if enough time has elapsed, draw the next frame
|
if (elapsed > game.fpsInterval) { // if enough time has elapsed, draw the next frame
|
||||||
game.then = now - (elapsed % game.fpsInterval); // Get ready for next frame by setting then=now. Also, adjust for fpsInterval not being multiple of 16.67
|
game.then = now - (elapsed % game.fpsInterval); // Get ready for next frame by setting then=now. Also, adjust for fpsInterval not being multiple of 16.67
|
||||||
game.loop();
|
game.loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3212
js/level.js
3212
js/level.js
File diff suppressed because it is too large
Load Diff
2020
js/mobs.js
2020
js/mobs.js
File diff suppressed because it is too large
Load Diff
3030
js/player.js
3030
js/player.js
File diff suppressed because it is too large
Load Diff
476
js/powerups.js
476
js/powerups.js
@@ -1,239 +1,239 @@
|
|||||||
let powerUp = [];
|
let powerUp = [];
|
||||||
|
|
||||||
const powerUps = {
|
const powerUps = {
|
||||||
heal: {
|
heal: {
|
||||||
name: "heal",
|
name: "heal",
|
||||||
color: "#0fb",
|
color: "#0fb",
|
||||||
size() {
|
size() {
|
||||||
return 40 * Math.sqrt(0.1 + Math.random() * 0.5);
|
return 40 * Math.sqrt(0.1 + Math.random() * 0.5);
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
let heal = (this.size / 40) ** 2
|
let heal = (this.size / 40) ** 2
|
||||||
if (b.fullHeal) heal = Infinity
|
if (b.fullHeal) heal = Infinity
|
||||||
heal = Math.min(1 - mech.health, heal)
|
heal = Math.min(1 - mech.health, heal)
|
||||||
mech.addHealth(heal);
|
mech.addHealth(heal);
|
||||||
if (heal > 0) game.makeTextLog("<div class='circle heal'></div> <span style='font-size:115%;'> <strong style = 'letter-spacing: 2px;'>heal</strong> " + (heal * 100).toFixed(0) + "%</span>", 300)
|
if (heal > 0) game.makeTextLog("<div class='circle heal'></div> <span style='font-size:115%;'> <strong style = 'letter-spacing: 2px;'>heal</strong> " + (heal * 100).toFixed(0) + "%</span>", 300)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ammo: {
|
ammo: {
|
||||||
name: "ammo",
|
name: "ammo",
|
||||||
color: "#467",
|
color: "#467",
|
||||||
size() {
|
size() {
|
||||||
return 17;
|
return 17;
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
//only get ammo for guns player has
|
//only get ammo for guns player has
|
||||||
let target;
|
let target;
|
||||||
// console.log(b.inventory.length)
|
// console.log(b.inventory.length)
|
||||||
if (b.inventory.length > 0) {
|
if (b.inventory.length > 0) {
|
||||||
//add ammo to a gun in inventory
|
//add ammo to a gun in inventory
|
||||||
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]];
|
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]];
|
||||||
//try 3 more times to give ammo to a gun with ammo, not Infinity
|
//try 3 more times to give ammo to a gun with ammo, not Infinity
|
||||||
if (target.ammo === Infinity) {
|
if (target.ammo === Infinity) {
|
||||||
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
||||||
if (target.ammo === Infinity) {
|
if (target.ammo === Infinity) {
|
||||||
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
||||||
if (target.ammo === Infinity) target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
if (target.ammo === Infinity) target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//if you don't have any guns just add ammo to a random gun you don't have yet
|
//if you don't have any guns just add ammo to a random gun you don't have yet
|
||||||
target = b.guns[Math.floor(Math.random() * b.guns.length)];
|
target = b.guns[Math.floor(Math.random() * b.guns.length)];
|
||||||
}
|
}
|
||||||
if (target.ammo === Infinity) {
|
if (target.ammo === Infinity) {
|
||||||
mech.fieldMeter = 1;
|
mech.fieldMeter = 1;
|
||||||
if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
|
if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
|
||||||
} else {
|
} else {
|
||||||
//ammo given scales as mobs take more hits to kill
|
//ammo given scales as mobs take more hits to kill
|
||||||
let ammo = Math.ceil((target.ammoPack * (0.45 + 0.06 * Math.random())) / Math.sqrt(b.dmgScale));
|
let ammo = Math.ceil((target.ammoPack * (0.45 + 0.06 * Math.random())) / Math.sqrt(b.dmgScale));
|
||||||
if (level.isBuildRun) ammo = Math.floor(ammo * 1.2)
|
if (level.isBuildRun) ammo = Math.floor(ammo * 1.2)
|
||||||
target.ammo += ammo;
|
target.ammo += ammo;
|
||||||
game.updateGunHUD();
|
game.updateGunHUD();
|
||||||
game.makeTextLog("<div class='circle gun'></div> <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300);
|
game.makeTextLog("<div class='circle gun'></div> <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
field: {
|
field: {
|
||||||
name: "field",
|
name: "field",
|
||||||
color: "#0cf",
|
color: "#0cf",
|
||||||
size() {
|
size() {
|
||||||
return 45;
|
return 45;
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
const previousMode = mech.fieldMode
|
const previousMode = mech.fieldMode
|
||||||
|
|
||||||
if (!this.mode) { //this.mode is set if the power up has been ejected from player
|
if (!this.mode) { //this.mode is set if the power up has been ejected from player
|
||||||
mode = mech.fieldMode
|
mode = mech.fieldMode
|
||||||
while (mode === mech.fieldMode) {
|
while (mode === mech.fieldMode) {
|
||||||
mode = Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))
|
mode = Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))
|
||||||
}
|
}
|
||||||
mech.fieldUpgrades[mode].effect(); //choose random field upgrade that you don't already have
|
mech.fieldUpgrades[mode].effect(); //choose random field upgrade that you don't already have
|
||||||
} else {
|
} else {
|
||||||
mech.fieldUpgrades[this.mode].effect(); //set a predetermined power up
|
mech.fieldUpgrades[this.mode].effect(); //set a predetermined power up
|
||||||
}
|
}
|
||||||
//pop the old field out in case player wants to swap back
|
//pop the old field out in case player wants to swap back
|
||||||
if (previousMode !== 0) {
|
if (previousMode !== 0) {
|
||||||
mech.fieldCDcycle = mech.cycle + 40; //trigger fieldCD to stop power up grab automatic pick up of spawn
|
mech.fieldCDcycle = mech.cycle + 40; //trigger fieldCD to stop power up grab automatic pick up of spawn
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y - 15, "field", false, previousMode);
|
powerUps.spawn(mech.pos.x, mech.pos.y - 15, "field", false, previousMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mod: {
|
mod: {
|
||||||
name: "mod",
|
name: "mod",
|
||||||
color: "#a8f",
|
color: "#a8f",
|
||||||
size() {
|
size() {
|
||||||
return 42;
|
return 42;
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
//find what mods I don't have
|
//find what mods I don't have
|
||||||
let options = [];
|
let options = [];
|
||||||
for (let i = 0; i < b.mods.length; i++) {
|
for (let i = 0; i < b.mods.length; i++) {
|
||||||
if (!b.mods[i].have) options.push(i);
|
if (!b.mods[i].have) options.push(i);
|
||||||
}
|
}
|
||||||
//give a random mod from the mods I don't have
|
//give a random mod from the mods I don't have
|
||||||
if (options.length > 0) {
|
if (options.length > 0) {
|
||||||
let newMod = options[Math.floor(Math.random() * options.length)]
|
let newMod = options[Math.floor(Math.random() * options.length)]
|
||||||
b.giveMod(newMod)
|
b.giveMod(newMod)
|
||||||
game.replaceTextLog = true;
|
game.replaceTextLog = true;
|
||||||
game.makeTextLog(`<div class="circle mod"></div> <strong style='font-size:30px;'>${b.mods[newMod].name}</strong><br><br> ${b.mods[newMod].description}`, 1000);
|
game.makeTextLog(`<div class="circle mod"></div> <strong style='font-size:30px;'>${b.mods[newMod].name}</strong><br><br> ${b.mods[newMod].description}`, 1000);
|
||||||
game.replaceTextLog = false;
|
game.replaceTextLog = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
gun: {
|
gun: {
|
||||||
name: "gun",
|
name: "gun",
|
||||||
color: "#26a",
|
color: "#26a",
|
||||||
size() {
|
size() {
|
||||||
return 35;
|
return 35;
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
//find what guns I don't have
|
//find what guns I don't have
|
||||||
let options = [];
|
let options = [];
|
||||||
if (b.activeGun === null && game.difficulty < 3) {
|
if (b.activeGun === null && game.difficulty < 3) {
|
||||||
//choose the first gun to be one that is good for the early game
|
//choose the first gun to be one that is good for the early game
|
||||||
for (let i = 0; i < b.guns.length; ++i) {
|
for (let i = 0; i < b.guns.length; ++i) {
|
||||||
if (!b.guns[i].have && b.guns[i].isStarterGun) options.push(i);
|
if (!b.guns[i].have && b.guns[i].isStarterGun) options.push(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//choose a gun you don't have
|
//choose a gun you don't have
|
||||||
for (let i = 0; i < b.guns.length; ++i) {
|
for (let i = 0; i < b.guns.length; ++i) {
|
||||||
if (!b.guns[i].have) options.push(i);
|
if (!b.guns[i].have) options.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//give player a gun they don't already have if possible
|
//give player a gun they don't already have if possible
|
||||||
game.replaceTextLog = true;
|
game.replaceTextLog = true;
|
||||||
if (options.length > 0) {
|
if (options.length > 0) {
|
||||||
let newGun = options[Math.floor(Math.random() * options.length)];
|
let newGun = options[Math.floor(Math.random() * options.length)];
|
||||||
if (b.activeGun === null) b.activeGun = newGun //if no active gun switch to new gun
|
if (b.activeGun === null) b.activeGun = newGun //if no active gun switch to new gun
|
||||||
game.makeTextLog(`${game.SVGleftMouse} <strong style='font-size:30px;'>${b.guns[newGun].name}</strong><br><br>${b.guns[newGun].description}`, 900);
|
game.makeTextLog(`${game.SVGleftMouse} <strong style='font-size:30px;'>${b.guns[newGun].name}</strong><br><br>${b.guns[newGun].description}`, 900);
|
||||||
b.guns[newGun].have = true;
|
b.guns[newGun].have = true;
|
||||||
b.inventory.push(newGun);
|
b.inventory.push(newGun);
|
||||||
b.guns[newGun].ammo += b.guns[newGun].ammoPack * 2;
|
b.guns[newGun].ammo += b.guns[newGun].ammoPack * 2;
|
||||||
game.makeGunHUD();
|
game.makeGunHUD();
|
||||||
} else {
|
} else {
|
||||||
//if you have all guns then get ammo
|
//if you have all guns then get ammo
|
||||||
const ammoTarget = Math.floor(Math.random() * (b.guns.length));
|
const ammoTarget = Math.floor(Math.random() * (b.guns.length));
|
||||||
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 2);
|
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 2);
|
||||||
b.guns[ammoTarget].ammo += ammo;
|
b.guns[ammoTarget].ammo += ammo;
|
||||||
game.updateGunHUD();
|
game.updateGunHUD();
|
||||||
game.makeTextLog("<span style='font-size:110%;'>+" + ammo + " ammo for " + b.guns[ammoTarget].name + "</span>", 300);
|
game.makeTextLog("<span style='font-size:110%;'>+" + ammo + " ammo for " + b.guns[ammoTarget].name + "</span>", 300);
|
||||||
}
|
}
|
||||||
game.replaceTextLog = false
|
game.replaceTextLog = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
||||||
if (Math.random() * Math.random() - 0.25 > Math.sqrt(mech.health) || Math.random() < 0.04) { //spawn heal chance is higher at low health
|
if (Math.random() * Math.random() - 0.25 > Math.sqrt(mech.health) || Math.random() < 0.04) { //spawn heal chance is higher at low health
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.2 && b.inventory.length > 0) {
|
if (Math.random() < 0.2 && b.inventory.length > 0) {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.004 * (4 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
if (Math.random() < 0.004 * (4 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
||||||
powerUps.spawn(x, y, "gun");
|
powerUps.spawn(x, y, "gun");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.004 * (7 - b.modCount)) {
|
if (Math.random() < 0.0035 * (7 - b.modCount)) {
|
||||||
powerUps.spawn(x, y, "mod");
|
powerUps.spawn(x, y, "mod");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.005) {
|
if (Math.random() < 0.005) {
|
||||||
powerUps.spawn(x, y, "field");
|
powerUps.spawn(x, y, "field");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
|
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
|
||||||
if (mech.fieldMode === 0) {
|
if (mech.fieldMode === 0) {
|
||||||
powerUps.spawn(x, y, "field")
|
powerUps.spawn(x, y, "field")
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field")
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field")
|
||||||
} else if (Math.random() < 0.3) {
|
} else if (Math.random() < 0.27) {
|
||||||
powerUps.spawn(x, y, "mod")
|
powerUps.spawn(x, y, "mod")
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod")
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod")
|
||||||
} else if (Math.random() < 0.3) {
|
} else if (Math.random() < 0.27) {
|
||||||
powerUps.spawn(x, y, "field");
|
powerUps.spawn(x, y, "field");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
||||||
} else if (Math.random() < 0.3) {
|
} else if (Math.random() < 0.27) {
|
||||||
powerUps.spawn(x, y, "gun")
|
powerUps.spawn(x, y, "gun")
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun")
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun")
|
||||||
} else if (mech.health < 0.6) {
|
} else if (mech.health < 0.6) {
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
||||||
if (Math.random() < 0.5) {
|
if (Math.random() < 0.5) {
|
||||||
powerUps.spawn(x, y, "heal", false);
|
powerUps.spawn(x, y, "heal", false);
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawn(x, y, "ammo", false);
|
powerUps.spawn(x, y, "ammo", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
|
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
|
||||||
if (b.inventory.length < 2 || game.isEasyMode) {
|
if (b.inventory.length < 2 || game.isEasyMode) {
|
||||||
powerUps.spawn(x, y, "gun", false); //starting gun
|
powerUps.spawn(x, y, "gun", false); //starting gun
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawn(x, y, target, moving = true, mode = null) {
|
spawn(x, y, target, moving = true, mode = null) {
|
||||||
if (!level.isBuildRun || target === "heal" || target === "ammo") {
|
if (!level.isBuildRun || target === "heal" || target === "ammo") {
|
||||||
let i = powerUp.length;
|
let i = powerUp.length;
|
||||||
target = powerUps[target];
|
target = powerUps[target];
|
||||||
size = target.size();
|
size = target.size();
|
||||||
powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, {
|
powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, {
|
||||||
density: 0.001,
|
density: 0.001,
|
||||||
frictionAir: 0.01,
|
frictionAir: 0.01,
|
||||||
restitution: 0.8,
|
restitution: 0.8,
|
||||||
inertia: Infinity, //prevents rotation
|
inertia: Infinity, //prevents rotation
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
group: 0,
|
group: 0,
|
||||||
category: 0x100000,
|
category: 0x100000,
|
||||||
mask: 0x100001
|
mask: 0x100001
|
||||||
},
|
},
|
||||||
color: target.color,
|
color: target.color,
|
||||||
effect: target.effect,
|
effect: target.effect,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
name: target.name,
|
name: target.name,
|
||||||
size: size
|
size: size
|
||||||
});
|
});
|
||||||
if (moving) {
|
if (moving) {
|
||||||
Matter.Body.setVelocity(powerUp[i], {
|
Matter.Body.setVelocity(powerUp[i], {
|
||||||
x: (Math.random() - 0.5) * 15,
|
x: (Math.random() - 0.5) * 15,
|
||||||
y: Math.random() * -9 - 3
|
y: Math.random() * -9 - 3
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
World.add(engine.world, powerUp[i]); //add to world
|
World.add(engine.world, powerUp[i]); //add to world
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
3384
js/spawn.js
3384
js/spawn.js
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user