spider boss
large mods shrink on death instead of disappearing new boss mob: spiderBoss mod - Bayesian interference -> determinism spawn 4 mods and 2 heals, future power ups are limited to one choice mod - Leveraged investments -> Bayesian interference 33% chance for double power ups to drop, remove all future ammo power ups (serious progress on my level construction tools, but it's not ready yet)
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
<div id="health"></div>
|
<div id="health"></div>
|
||||||
<div id="dmg"></div>
|
<div id="dmg"></div>
|
||||||
<div id="choose-background"></div>
|
<div id="choose-background"></div>
|
||||||
|
<div id='construct' contenteditable="true"></div>
|
||||||
|
|
||||||
<!-- guns -->
|
<!-- guns -->
|
||||||
<!-- <audio id="snare2" src="sounds\guns\snare2.ogg" preload="auto"></audio>
|
<!-- <audio id="snare2" src="sounds\guns\snare2.ogg" preload="auto"></audio>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const b = {
|
|||||||
modRecursiveHealing: null,
|
modRecursiveHealing: null,
|
||||||
modSquirrelFx: null,
|
modSquirrelFx: null,
|
||||||
isModCrit: null,
|
isModCrit: null,
|
||||||
isModBayesian: null,
|
modBayesian: null,
|
||||||
isModLowHealthDmg: null,
|
isModLowHealthDmg: null,
|
||||||
isModFarAwayDmg: null,
|
isModFarAwayDmg: null,
|
||||||
isModEntanglement: null,
|
isModEntanglement: null,
|
||||||
@@ -42,7 +42,6 @@ const b = {
|
|||||||
modLaserReflections: null,
|
modLaserReflections: null,
|
||||||
modLaserDamage: null,
|
modLaserDamage: null,
|
||||||
modLaserFieldDrain: null,
|
modLaserFieldDrain: null,
|
||||||
isModNoAmmo: null,
|
|
||||||
isModAmmoFromHealth: null,
|
isModAmmoFromHealth: null,
|
||||||
modMobDieAtHealth: null,
|
modMobDieAtHealth: null,
|
||||||
isModEnergyRecovery: null,
|
isModEnergyRecovery: null,
|
||||||
@@ -83,6 +82,7 @@ const b = {
|
|||||||
isModRest: null,
|
isModRest: null,
|
||||||
isModRPG: null,
|
isModRPG: null,
|
||||||
isMod3Missiles: null,
|
isMod3Missiles: null,
|
||||||
|
isModDeterminism: null,
|
||||||
modOnHealthChange() { //used with acid mod
|
modOnHealthChange() { //used with acid mod
|
||||||
if (b.isModAcidDmg && mech.health > 0.8) {
|
if (b.isModAcidDmg && mech.health > 0.8) {
|
||||||
b.modAcidDmg = 0.5
|
b.modAcidDmg = 0.5
|
||||||
@@ -116,7 +116,7 @@ const b = {
|
|||||||
mods: [{
|
mods: [{
|
||||||
name: "capacitor",
|
name: "capacitor",
|
||||||
// nameInfo: "<span id='mod-capacitor'></span>",
|
// nameInfo: "<span id='mod-capacitor'></span>",
|
||||||
description: "increase <strong class='color-d'>damage</strong> based on stored <strong class='color-f'>energy</strong><br><strong>+1%</strong> <strong class='color-d'>damage</strong> for every <strong>5%</strong> <strong class='color-f'>energy</strong>",
|
description: "increase <strong class='color-d'>damage</strong> based on stored <strong class='color-f'>energy</strong><br><strong>+1%</strong> <strong class='color-d'>damage</strong> for every <strong>5.5%</strong> <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -316,7 +316,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "scrap bots",
|
name: "scrap bots",
|
||||||
description: "<strong>+13%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot will follow you until you <strong>exit</strong> the map",
|
description: "<strong>+12%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot will follow you until you <strong>exit</strong> the map",
|
||||||
maxCount: 6,
|
maxCount: 6,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -324,7 +324,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.isModBotSpawner += 0.13;
|
b.isModBotSpawner += 0.12;
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
b.isModBotSpawner = 0;
|
b.isModBotSpawner = 0;
|
||||||
@@ -726,7 +726,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bayesian inference",
|
name: "Bayesian inference",
|
||||||
description: "<strong>33%</strong> chance for double <strong>power ups</strong> to drop<br>only <strong>one choice</strong> when selecting <strong>power ups</strong>",
|
description: "<strong>33%</strong> chance for double <strong>power ups</strong> to drop<br><strong>remove</strong> all future <strong>ammo</strong> power ups",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -734,10 +734,10 @@ const b = {
|
|||||||
},
|
},
|
||||||
requires: "",
|
requires: "",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
b.isModBayesian = 0.33;
|
b.modBayesian = 0.33;
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
b.isModBayesian = 0;
|
b.modBayesian = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -773,8 +773,8 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "leveraged investment",
|
name: "determinism",
|
||||||
description: "<strong>remove</strong> all future <strong>ammo</strong> power ups<br>spawn <strong>5</strong> <strong class='color-m'>mods</strong> and <strong>3</strong> <strong class='color-h'>healing</strong> power ups",
|
description: "spawn <strong>4</strong> <strong class='color-m'>mods</strong> and 2 <strong class='color-h'>heal</strong> power ups<br>future <strong>power ups</strong> are limited to <strong>one choice</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -782,23 +782,23 @@ const b = {
|
|||||||
},
|
},
|
||||||
requires: "",
|
requires: "",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
b.isModNoAmmo = true;
|
b.isModDeterminism = true;
|
||||||
for (let i = 0; i < 5; i++) { //if you change the six also change it in Born rule
|
for (let i = 0; i < 4; i++) { //if you change the six also change it in Born rule
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
||||||
}
|
}
|
||||||
for (let i = 0; i < 3; i++) { // spawn new mods
|
for (let i = 0; i < 2; i++) { // spawn new mods
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
b.isModNoAmmo = false;
|
b.isModDeterminism = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reallocation",
|
name: "reallocation",
|
||||||
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods can lose all stacks</em>",
|
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods lose all stacks</em>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -817,7 +817,7 @@ const b = {
|
|||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
@@ -839,7 +839,7 @@ const b = {
|
|||||||
bullet = [];
|
bullet = [];
|
||||||
|
|
||||||
let count = b.modCount
|
let count = b.modCount
|
||||||
if (b.isModNoAmmo) count -= 5 //remove the 5 bonus mods when getting rid of leveraged investment
|
if (b.isModDeterminism) count -= 4 //remove the 5 bonus mods when getting rid of determinism
|
||||||
for (let i = 0; i < count; i++) { // spawn new mods
|
for (let i = 0; i < count; i++) { // spawn new mods
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
||||||
}
|
}
|
||||||
@@ -1291,7 +1291,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quantum tunneling",
|
name: "quantum tunneling",
|
||||||
description: "<strong>foam</strong> bypasses <strong>shields</strong> to stick to mobs",
|
description: "<strong>foam</strong> bypasses <strong>shields</strong> and sticks to mobs",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -1650,7 +1650,7 @@ const b = {
|
|||||||
if (mech.health > 0.05) {
|
if (mech.health > 0.05) {
|
||||||
mech.damage(Math.max(0.01, b.isModAmmoFromHealth * mech.health));
|
mech.damage(Math.max(0.01, b.isModAmmoFromHealth * mech.health));
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
||||||
} else {
|
} else {
|
||||||
game.replaceTextLog = true;
|
game.replaceTextLog = true;
|
||||||
game.makeTextLog("not enough health for catabolism to produce ammo", 120);
|
game.makeTextLog("not enough health for catabolism to produce ammo", 120);
|
||||||
@@ -1673,7 +1673,7 @@ const b = {
|
|||||||
if (b.isModHarmDamage && mech.lastHarmCycle + 300 > mech.cycle) dmg *= 2;
|
if (b.isModHarmDamage && mech.lastHarmCycle + 300 > mech.cycle) dmg *= 2;
|
||||||
if (b.isModEnergyLoss) dmg *= 1.33;
|
if (b.isModEnergyLoss) dmg *= 1.33;
|
||||||
if (b.isModRest && player.speed < 1) dmg *= 1.20;
|
if (b.isModRest && player.speed < 1) dmg *= 1.20;
|
||||||
if (b.isModEnergyDamage) dmg *= 1 + mech.energy / 5;
|
if (b.isModEnergyDamage) dmg *= 1 + mech.energy / 5.5;
|
||||||
return dmg
|
return dmg
|
||||||
},
|
},
|
||||||
bulletRemove() { //run in main loop
|
bulletRemove() { //run in main loop
|
||||||
@@ -2385,11 +2385,11 @@ const b = {
|
|||||||
};
|
};
|
||||||
bullet[me].do = function () {};
|
bullet[me].do = function () {};
|
||||||
},
|
},
|
||||||
nailBot(speed = 1) {
|
nailBot(position = mech.pos) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = mech.angle;
|
const dir = mech.angle;
|
||||||
const RADIUS = (10 + 5 * Math.random())
|
const RADIUS = (10 + 5 * Math.random())
|
||||||
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 4, RADIUS, {
|
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
|
||||||
angle: dir,
|
angle: dir,
|
||||||
friction: 0,
|
friction: 0,
|
||||||
frictionStatic: 0,
|
frictionStatic: 0,
|
||||||
@@ -2439,16 +2439,12 @@ const b = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
Matter.Body.setVelocity(bullet[me], {
|
|
||||||
x: speed * Math.cos(dir),
|
|
||||||
y: speed * Math.sin(dir)
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
laserBot(speed = 1) {
|
laserBot(position = mech.pos) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = mech.angle;
|
const dir = mech.angle;
|
||||||
const RADIUS = (14 + 6 * Math.random())
|
const RADIUS = (14 + 6 * Math.random())
|
||||||
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 3, RADIUS, {
|
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
|
||||||
angle: dir,
|
angle: dir,
|
||||||
friction: 0,
|
friction: 0,
|
||||||
frictionStatic: 0,
|
frictionStatic: 0,
|
||||||
@@ -2558,10 +2554,6 @@ const b = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
Matter.Body.setVelocity(bullet[me], {
|
|
||||||
x: speed * Math.cos(dir),
|
|
||||||
y: speed * Math.sin(dir)
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
giveGuns(gun = "random", ammoPacks = 6) {
|
giveGuns(gun = "random", ammoPacks = 6) {
|
||||||
if (gun === "random") {
|
if (gun === "random") {
|
||||||
@@ -3435,7 +3427,7 @@ const b = {
|
|||||||
Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
|
Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
|
||||||
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9))
|
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9))
|
||||||
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
|
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
|
||||||
if (b.isModFoamShieldSKip) {
|
if (b.isModFoamShieldSKip && this.target.isShielded) {
|
||||||
this.target.damage(b.dmgScale * 0.0025, true); //shield damage bypass
|
this.target.damage(b.dmgScale * 0.0025, true); //shield damage bypass
|
||||||
} else {
|
} else {
|
||||||
this.target.damage(b.dmgScale * 0.005);
|
this.target.damage(b.dmgScale * 0.005);
|
||||||
|
|||||||
342
js/game.js
342
js/game.js
@@ -20,6 +20,7 @@ const game = {
|
|||||||
game.draw.cons();
|
game.draw.cons();
|
||||||
game.draw.testing();
|
game.draw.testing();
|
||||||
game.drawCircle();
|
game.drawCircle();
|
||||||
|
game.constructCycle()
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
game.testingOutput();
|
game.testingOutput();
|
||||||
game.drawCursor();
|
game.drawCursor();
|
||||||
@@ -322,8 +323,14 @@ const game = {
|
|||||||
if (game.testing) {
|
if (game.testing) {
|
||||||
game.testing = false;
|
game.testing = false;
|
||||||
game.loop = game.normalLoop
|
game.loop = game.normalLoop
|
||||||
|
if (game.isConstructionMode) {
|
||||||
|
document.getElementById("construct").style.display = 'none'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
game.testing = true;
|
game.testing = true;
|
||||||
|
if (game.isConstructionMode) {
|
||||||
|
document.getElementById("construct").style.display = 'inline'
|
||||||
|
}
|
||||||
game.loop = game.testingLoop
|
game.loop = game.testingLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -758,6 +765,7 @@ const game = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
testingOutput() {
|
testingOutput() {
|
||||||
|
if (!game.isConstructionMode) {
|
||||||
ctx.textAlign = "right";
|
ctx.textAlign = "right";
|
||||||
ctx.fillStyle = "#000";
|
ctx.fillStyle = "#000";
|
||||||
let line = 500;
|
let line = 500;
|
||||||
@@ -777,59 +785,12 @@ const game = {
|
|||||||
ctx.fillText("U: next level", x, line);
|
ctx.fillText("U: next level", x, line);
|
||||||
line += 20;
|
line += 20;
|
||||||
ctx.fillText("1-7: spawn things", x, line);
|
ctx.fillText("1-7: spawn things", x, line);
|
||||||
line += 30;
|
}
|
||||||
|
|
||||||
// ctx.fillText("cycle: " + game.cycle, x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("player cycle: " + mech.cycle, x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("x: " + player.position.x.toFixed(0), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("y: " + player.position.y.toFixed(0), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("Vx: " + mech.Vx.toFixed(2), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("Vy: " + mech.Vy.toFixed(2), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("Fx: " + player.force.x.toFixed(3), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("Fy: " + player.force.y.toFixed(3), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("yOff: " + mech.yOff.toFixed(1), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("mass: " + player.mass.toFixed(1), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("onGround: " + mech.onGround, x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("crouch: " + mech.crouch, x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("isHeadClear: " + mech.isHeadClear, x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("frictionAir: " + player.frictionAir.toFixed(3), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("stepSize: " + mech.stepSize.toFixed(2), x, line);
|
|
||||||
// line += 20;
|
|
||||||
// ctx.fillText("zoom: " + game.zoom.toFixed(4), x, line);
|
|
||||||
// line += 20;
|
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20);
|
ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20);
|
||||||
},
|
},
|
||||||
draw: {
|
draw: {
|
||||||
powerUp() {
|
powerUp() {
|
||||||
// draw power up
|
|
||||||
// ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
|
|
||||||
// for (let i = 0, len = powerUp.length; i < len; ++i) {
|
|
||||||
// let vertices = powerUp[i].vertices;
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(vertices[0].x, vertices[0].y);
|
|
||||||
// for (let j = 1; j < vertices.length; j += 1) {
|
|
||||||
// ctx.lineTo(vertices[j].x, vertices[j].y);
|
|
||||||
// }
|
|
||||||
// ctx.lineTo(vertices[0].x, vertices[0].y);
|
|
||||||
// ctx.fillStyle = powerUp[i].color;
|
|
||||||
// ctx.fill();
|
|
||||||
// }
|
|
||||||
// ctx.globalAlpha = 1;
|
|
||||||
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
|
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
|
||||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -872,133 +833,6 @@ const game = {
|
|||||||
ctx.fillStyle = game.draw.mapFill;
|
ctx.fillStyle = game.draw.mapFill;
|
||||||
ctx.fill(game.draw.mapPath);
|
ctx.fill(game.draw.mapPath);
|
||||||
},
|
},
|
||||||
// seeEdges() {
|
|
||||||
// const eye = {
|
|
||||||
// x: mech.pos.x + 20 * Math.cos(mech.angle),
|
|
||||||
// y: mech.pos.y + 20 * Math.sin(mech.angle)
|
|
||||||
// };
|
|
||||||
// //find all vertex nodes in range and in LOS
|
|
||||||
// findNodes = function (domain, center) {
|
|
||||||
// let nodes = [];
|
|
||||||
// for (let i = 0; i < domain.length; ++i) {
|
|
||||||
// let vertices = domain[i].vertices;
|
|
||||||
|
|
||||||
// for (let j = 0, len = vertices.length; j < len; j++) {
|
|
||||||
// //calculate distance to player
|
|
||||||
// const dx = vertices[j].x - center.x;
|
|
||||||
// const dy = vertices[j].y - center.y;
|
|
||||||
// if (dx * dx + dy * dy < 800 * 800 && Matter.Query.ray(domain, center, vertices[j]).length === 0) {
|
|
||||||
// nodes.push(vertices[j]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return nodes;
|
|
||||||
// };
|
|
||||||
// let nodes = findNodes(map, eye);
|
|
||||||
// //sort node list by angle to player
|
|
||||||
// nodes.sort(function (a, b) {
|
|
||||||
// //sub artan2 from player loc
|
|
||||||
// const dx = a.x - eye.x;
|
|
||||||
// const dy = a.y - eye.y;
|
|
||||||
// return Math.atan2(dy, dx) - Math.atan2(dy, dx);
|
|
||||||
// });
|
|
||||||
// //draw nodes
|
|
||||||
// ctx.lineWidth = 2;
|
|
||||||
// ctx.strokeStyle = "#000";
|
|
||||||
// ctx.beginPath();
|
|
||||||
// for (let i = 0; i < nodes.length; ++i) {
|
|
||||||
// ctx.lineTo(nodes[i].x, nodes[i].y);
|
|
||||||
// }
|
|
||||||
// ctx.stroke();
|
|
||||||
// },
|
|
||||||
// see() {
|
|
||||||
// const vertexCollision = function (
|
|
||||||
// v1,
|
|
||||||
// v1End,
|
|
||||||
// domain,
|
|
||||||
// best = {
|
|
||||||
// x: null,
|
|
||||||
// y: null,
|
|
||||||
// dist2: Infinity,
|
|
||||||
// who: null,
|
|
||||||
// v1: null,
|
|
||||||
// v2: null
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// for (let i = 0; i < domain.length; ++i) {
|
|
||||||
// let vertices = domain[i].vertices;
|
|
||||||
// const len = vertices.length - 1;
|
|
||||||
// for (let j = 0; j < len; j++) {
|
|
||||||
// results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
|
||||||
// if (results.onLine1 && results.onLine2) {
|
|
||||||
// const dx = v1.x - results.x;
|
|
||||||
// const dy = v1.y - results.y;
|
|
||||||
// const dist2 = dx * dx + dy * dy;
|
|
||||||
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
|
||||||
// best = {
|
|
||||||
// x: results.x,
|
|
||||||
// y: results.y,
|
|
||||||
// dist2: dist2,
|
|
||||||
// who: domain[i],
|
|
||||||
// v1: vertices[j],
|
|
||||||
// v2: vertices[j + 1]
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
|
||||||
// if (results.onLine1 && results.onLine2) {
|
|
||||||
// const dx = v1.x - results.x;
|
|
||||||
// const dy = v1.y - results.y;
|
|
||||||
// const dist2 = dx * dx + dy * dy;
|
|
||||||
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
|
||||||
// best = {
|
|
||||||
// x: results.x,
|
|
||||||
// y: results.y,
|
|
||||||
// dist2: dist2,
|
|
||||||
// who: domain[i],
|
|
||||||
// v1: vertices[0],
|
|
||||||
// v2: vertices[len]
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return best;
|
|
||||||
// };
|
|
||||||
// const range = 3000;
|
|
||||||
// ctx.beginPath();
|
|
||||||
// for (let i = 0; i < Math.PI * 2; i += Math.PI / 2 / 100) {
|
|
||||||
// const cosAngle = Math.cos(mech.angle + i);
|
|
||||||
// const sinAngle = Math.sin(mech.angle + i);
|
|
||||||
|
|
||||||
// const start = {
|
|
||||||
// x: mech.pos.x + 20 * cosAngle,
|
|
||||||
// y: mech.pos.y + 20 * sinAngle
|
|
||||||
// };
|
|
||||||
// const end = {
|
|
||||||
// x: mech.pos.x + range * cosAngle,
|
|
||||||
// y: mech.pos.y + range * sinAngle
|
|
||||||
// };
|
|
||||||
// let result = vertexCollision(start, end, map);
|
|
||||||
// result = vertexCollision(start, end, body, result);
|
|
||||||
// result = vertexCollision(start, end, mob, result);
|
|
||||||
|
|
||||||
// if (result.dist2 < range * range) {
|
|
||||||
// // ctx.arc(result.x, result.y, 2, 0, 2 * Math.PI);
|
|
||||||
// ctx.lineTo(result.x, result.y);
|
|
||||||
// } else {
|
|
||||||
// // ctx.arc(end.x, end.y, 2, 0, 2 * Math.PI);
|
|
||||||
// ctx.lineTo(end.x, end.y);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // ctx.lineWidth = 1;
|
|
||||||
// // ctx.strokeStyle = "#000";
|
|
||||||
// // ctx.stroke();
|
|
||||||
// ctx.fillStyle = "rgba(0,0,0,0.3)";
|
|
||||||
// ctx.fillStyle = "#fff";
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.clip();
|
|
||||||
// },
|
|
||||||
body() {
|
body() {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
for (let i = 0, len = body.length; i < len; ++i) {
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
@@ -1146,38 +980,144 @@ const game = {
|
|||||||
// if line1 and line2 are segments, they intersect if both of the above are true
|
// if line1 and line2 are segments, they intersect if both of the above are true
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
//was used in level design
|
copyToClipBoard(value) {
|
||||||
buildingUp(e) {
|
// Create a fake textarea
|
||||||
if (game.mouseDown) {
|
const textAreaEle = document.createElement('textarea');
|
||||||
game.getCoords.pos2.x = Math.round(game.mouseInGame.x / 25) * 25;
|
|
||||||
game.getCoords.pos2.y = Math.round(game.mouseInGame.y / 25) * 25;
|
|
||||||
let out;
|
|
||||||
|
|
||||||
//body rect mode
|
// Reset styles
|
||||||
out = `spawn.mapRect(${game.getCoords.pos1.x}, ${game.getCoords.pos1.y}, ${game.getCoords.pos2.x - game.getCoords.pos1.x}, ${game.getCoords.pos2.y -
|
textAreaEle.style.border = '0';
|
||||||
game.getCoords.pos1.y});`;
|
textAreaEle.style.padding = '0';
|
||||||
|
textAreaEle.style.margin = '0';
|
||||||
|
|
||||||
//mob spawn
|
// Set the absolute position
|
||||||
//out = `spawn.randomMob(${game.getCoords.pos1.x}, ${game.getCoords.pos1.y}, 0.3);`
|
// User won't see the element
|
||||||
|
textAreaEle.style.position = 'absolute';
|
||||||
|
textAreaEle.style.left = '-9999px';
|
||||||
|
textAreaEle.style.top = `0px`;
|
||||||
|
|
||||||
//draw foreground
|
// Set the value
|
||||||
//out = `level.fill.push({ x: ${game.getCoords.pos1.x}, y: ${game.getCoords.pos1.y}, width: ${game.getCoords.pos2.x-game.getCoords.pos1.x}, height: ${game.getCoords.pos2.y-game.getCoords.pos1.y}, color: "rgba(0,0,0,0.1)"});`;
|
textAreaEle.value = value
|
||||||
|
|
||||||
//draw background fill
|
// Append the textarea to body
|
||||||
//out = `level.fillBG.push({ x: ${game.getCoords.pos1.x}, y: ${game.getCoords.pos1.y}, width: ${game.getCoords.pos2.x-game.getCoords.pos1.x}, height: ${game.getCoords.pos2.y-game.getCoords.pos1.y}, color: "#ccc"});`;
|
document.body.appendChild(textAreaEle);
|
||||||
|
|
||||||
//svg mode
|
// Focus and select the text
|
||||||
//out = 'rect x="'+game.getCoords.pos1.x+'" y="'+ game.getCoords.pos1.y+'" width="'+(game.getCoords.pos2.x-game.getCoords.pos1.x)+'" height="'+(game.getCoords.pos2.y-game.getCoords.pos1.y)+'"';
|
textAreaEle.focus();
|
||||||
|
textAreaEle.select();
|
||||||
|
|
||||||
console.log(out);
|
// Execute the "copy" command
|
||||||
// document.getElementById("copy-this").innerHTML = out
|
try {
|
||||||
//
|
document.execCommand('copy');
|
||||||
// window.getSelection().removeAllRanges();
|
} catch (err) {
|
||||||
// var range = document.createRange();
|
// Unable to copy
|
||||||
// range.selectNode(document.getElementById('copy-this'));
|
} finally {
|
||||||
// window.getSelection().addRange(range);
|
// Remove the textarea
|
||||||
// document.execCommand('copy')
|
document.body.removeChild(textAreaEle);
|
||||||
// window.getSelection().removeAllRanges();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
constructMouseDownPosition: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
constructMapString: [],
|
||||||
|
constructCycle() {
|
||||||
|
if (game.isConstructionMode && game.constructMouseDownPosition) {
|
||||||
|
function round(num, round = 25) {
|
||||||
|
return Math.ceil(num / round) * round;
|
||||||
|
}
|
||||||
|
const x = round(game.constructMouseDownPosition.x)
|
||||||
|
const y = round(game.constructMouseDownPosition.y)
|
||||||
|
const dx = round(game.mouseInGame.x) - x
|
||||||
|
const dy = round(game.mouseInGame.y) - y
|
||||||
|
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeRect(x, y, dx, dy);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
outputMapString() {
|
||||||
|
let out = "" //combine set of map strings to one string
|
||||||
|
let outHTML = ""
|
||||||
|
for (let i = 0, len = game.constructMapString.length; i < len; i++) {
|
||||||
|
out += game.constructMapString[i];
|
||||||
|
outHTML += "<div>" + game.constructMapString[i] + "</div>"
|
||||||
|
}
|
||||||
|
game.copyToClipBoard(out)
|
||||||
|
document.getElementById("construct").innerHTML = outHTML
|
||||||
|
},
|
||||||
|
enableConstructMode() {
|
||||||
|
game.isConstructionMode = true;
|
||||||
|
game.isAutoZoom = false;
|
||||||
|
|
||||||
|
document.body.addEventListener("mouseup", (e) => {
|
||||||
|
if (game.testing && game.constructMouseDownPosition && game.mouseInGame.x > game.constructMouseDownPosition.x && game.mouseInGame.y > game.constructMouseDownPosition.y) { //make sure that the width and height are positive
|
||||||
|
function round(num, round = 25) {
|
||||||
|
return Math.ceil(num / round) * round;
|
||||||
|
}
|
||||||
|
//clean up positions
|
||||||
|
const x = round(game.constructMouseDownPosition.x)
|
||||||
|
const y = round(game.constructMouseDownPosition.y)
|
||||||
|
const dx = round(game.mouseInGame.x) - x
|
||||||
|
const dy = round(game.mouseInGame.y) - y
|
||||||
|
|
||||||
|
console.log(e.which)
|
||||||
|
if (e.which === 1) { //add map
|
||||||
|
game.constructMapString.push(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`) //store command as a string in the next element of an array
|
||||||
|
game.outputMapString();
|
||||||
|
|
||||||
|
//see map in world
|
||||||
|
spawn.mapRect(x, y, dx, dy);
|
||||||
|
len = map.length - 1
|
||||||
|
map[len].collisionFilter.category = cat.map;
|
||||||
|
map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||||
|
Matter.Body.setStatic(map[len], true); //make static
|
||||||
|
World.add(engine.world, map[len]); //add to world
|
||||||
|
|
||||||
|
game.draw.setPaths() //update map graphics
|
||||||
|
} else if (e.which === 3) { //add body
|
||||||
|
game.constructMapString.push(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`) //store command as a string in the next element of an array
|
||||||
|
game.outputMapString();
|
||||||
|
|
||||||
|
//see map in world
|
||||||
|
spawn.bodyRect(x, y, dx, dy);
|
||||||
|
len = body.length - 1
|
||||||
|
body[len].collisionFilter.category = cat.body;
|
||||||
|
body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||||
|
World.add(engine.world, body[len]); //add to world
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
game.constructMouseDownPosition.x = undefined
|
||||||
|
game.constructMouseDownPosition.y = undefined
|
||||||
|
});
|
||||||
|
game.constructMouseDownPosition.x = undefined
|
||||||
|
game.constructMouseDownPosition.y = undefined
|
||||||
|
document.body.addEventListener("mousedown", () => {
|
||||||
|
if (game.testing) {
|
||||||
|
game.constructMouseDownPosition.x = game.mouseInGame.x
|
||||||
|
game.constructMouseDownPosition.y = game.mouseInGame.y
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
|
||||||
|
if (game.testing && e.keyCode === 90 && game.constructMapString.length) {
|
||||||
|
if (game.constructMapString[game.constructMapString.length - 1][6] === 'm') { //remove map
|
||||||
|
game.constructMapString.pop();
|
||||||
|
game.outputMapString();
|
||||||
|
//remove from current level
|
||||||
|
const index = map.length - 1
|
||||||
|
Matter.World.remove(engine.world, map[index]);
|
||||||
|
map.splice(index, 1);
|
||||||
|
game.draw.setPaths() //update map graphics
|
||||||
|
} else if (game.constructMapString[game.constructMapString.length - 1][6] === 'b') { //remove body
|
||||||
|
game.constructMapString.pop();
|
||||||
|
game.outputMapString();
|
||||||
|
//remove from current level
|
||||||
|
const index = body.length - 1
|
||||||
|
Matter.World.remove(engine.world, body[index]);
|
||||||
|
body.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
34
js/index.js
34
js/index.js
@@ -268,39 +268,7 @@ const build = {
|
|||||||
document.getElementById("build-grid").style.display = "grid"
|
document.getElementById("build-grid").style.display = "grid"
|
||||||
},
|
},
|
||||||
shareURL() {
|
shareURL() {
|
||||||
// Create a fake textarea
|
game.copyToClipBoard(build.generateURL())
|
||||||
const textAreaEle = document.createElement('textarea');
|
|
||||||
|
|
||||||
// Reset styles
|
|
||||||
textAreaEle.style.border = '0';
|
|
||||||
textAreaEle.style.padding = '0';
|
|
||||||
textAreaEle.style.margin = '0';
|
|
||||||
|
|
||||||
// Set the absolute position
|
|
||||||
// User won't see the element
|
|
||||||
textAreaEle.style.position = 'absolute';
|
|
||||||
textAreaEle.style.left = '-9999px';
|
|
||||||
textAreaEle.style.top = `0px`;
|
|
||||||
|
|
||||||
// Set the value
|
|
||||||
textAreaEle.value = build.generateURL();
|
|
||||||
|
|
||||||
// Append the textarea to body
|
|
||||||
document.body.appendChild(textAreaEle);
|
|
||||||
|
|
||||||
// Focus and select the text
|
|
||||||
textAreaEle.focus();
|
|
||||||
textAreaEle.select();
|
|
||||||
|
|
||||||
// Execute the "copy" command
|
|
||||||
try {
|
|
||||||
document.execCommand('copy');
|
|
||||||
} catch (err) {
|
|
||||||
// Unable to copy
|
|
||||||
} finally {
|
|
||||||
// Remove the textarea
|
|
||||||
document.body.removeChild(textAreaEle);
|
|
||||||
}
|
|
||||||
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
|
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
|
||||||
},
|
},
|
||||||
generateURL() {
|
generateURL() {
|
||||||
|
|||||||
37
js/level.js
37
js/level.js
@@ -14,18 +14,18 @@ const level = {
|
|||||||
start() {
|
start() {
|
||||||
if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps();
|
if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps();
|
||||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||||
|
// game.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.difficultyIncrease(9)
|
// level.difficultyIncrease(9)
|
||||||
// b.giveGuns("foam")
|
// b.giveGuns("foam")
|
||||||
// mech.setField("time dilation field")
|
// mech.setField("time dilation field")
|
||||||
// b.giveMod("renormalization");
|
// b.giveMod("renormalization");
|
||||||
// b.giveMod("quantum tunneling");
|
// b.giveMod("quantum tunneling");
|
||||||
// b.giveGuns("grenades")
|
// b.giveGuns("rail gun")
|
||||||
// b.giveMod("rocket-propelled grenade");
|
|
||||||
// mech.setField("pilot wave")
|
// mech.setField("pilot wave")
|
||||||
// mech.setField("perfect diamagnetism")
|
// mech.setField("perfect diamagnetism")
|
||||||
|
|
||||||
level.intro(); //starting level
|
// level.intro(); //starting level
|
||||||
// level.testing();
|
level.testing();
|
||||||
// level.stronghold()
|
// level.stronghold()
|
||||||
// level.bosses();
|
// level.bosses();
|
||||||
// level.satellite();
|
// level.satellite();
|
||||||
@@ -152,19 +152,18 @@ const level = {
|
|||||||
spawn.mapRect(6400, -200, 400, 300); //right wall
|
spawn.mapRect(6400, -200, 400, 300); //right wall
|
||||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||||
|
spawn.boost(1500, 0, 900);
|
||||||
|
|
||||||
// spawn.bomberBoss(2900, -500)
|
// spawn.bomberBoss(2900, -500)
|
||||||
spawn.suckerBoss(1200, -500)
|
// spawn.suckerBoss(1200, -500)
|
||||||
// spawn.hopper(1200, -500)
|
// spawn.hopper(1200, -500, 70)
|
||||||
|
// spawn.hopper(1200, -500, 100)
|
||||||
// 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, "spiker")
|
||||||
// spawn.hopper(1200, -500)
|
spawn.spiderBoss(1200, -500)
|
||||||
// spawn.timeSkipBoss(2900, -500)
|
// spawn.timeSkipBoss(2900, -500)
|
||||||
// spawn.randomMob(1600, -500)
|
// spawn.randomMob(1600, -500)
|
||||||
spawn.boost()
|
|
||||||
spawn.boost(1500, 0, 1400);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
bosses() {
|
bosses() {
|
||||||
level.defaultZoom = 1500
|
level.defaultZoom = 1500
|
||||||
@@ -591,7 +590,9 @@ const level = {
|
|||||||
spawn.randomBoss(1600, -100, 0);
|
spawn.randomBoss(1600, -100, 0);
|
||||||
spawn.randomBoss(5000, -3900, -0.3);
|
spawn.randomBoss(5000, -3900, -0.3);
|
||||||
if (game.difficulty > 3) {
|
if (game.difficulty > 3) {
|
||||||
if (Math.random() < 0.25) {
|
if (Math.random() < 0.1) {
|
||||||
|
spawn.randomLevelBoss(2800, -1400);
|
||||||
|
} else if (Math.random() < 0.25) {
|
||||||
spawn.laserBoss(2900 + 300 * Math.random(), -2950 + 150 * Math.random());
|
spawn.laserBoss(2900 + 300 * Math.random(), -2950 + 150 * Math.random());
|
||||||
} else if (Math.random() < 0.33) {
|
} else if (Math.random() < 0.33) {
|
||||||
spawn.laserBoss(1800 + 250 * Math.random(), -2600 + 150 * Math.random());
|
spawn.laserBoss(1800 + 250 * Math.random(), -2600 + 150 * Math.random());
|
||||||
@@ -975,7 +976,7 @@ const level = {
|
|||||||
spawn.randomBoss(4000, -350, 0.6);
|
spawn.randomBoss(4000, -350, 0.6);
|
||||||
spawn.randomBoss(2750, -550, 0.1);
|
spawn.randomBoss(2750, -550, 0.1);
|
||||||
if (game.difficulty > 2) {
|
if (game.difficulty > 2) {
|
||||||
if (Math.random() < 0.1) { // tether ball
|
if (Math.random() < 0.09) { // tether ball
|
||||||
spawn.tetherBoss(4250, 0)
|
spawn.tetherBoss(4250, 0)
|
||||||
cons[cons.length] = Constraint.create({
|
cons[cons.length] = Constraint.create({
|
||||||
pointA: {
|
pointA: {
|
||||||
@@ -986,6 +987,9 @@ const level = {
|
|||||||
stiffness: 0.00007
|
stiffness: 0.00007
|
||||||
});
|
});
|
||||||
if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
|
if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
|
||||||
|
}
|
||||||
|
if (Math.random() < 0.08) {
|
||||||
|
spawn.randomLevelBoss(4250, -250);
|
||||||
} else {
|
} else {
|
||||||
//floor below right tall tower
|
//floor below right tall tower
|
||||||
spawn.bodyRect(3000, 50, 150, 250, 0.9);
|
spawn.bodyRect(3000, 50, 150, 250, 0.9);
|
||||||
@@ -1343,7 +1347,6 @@ const level = {
|
|||||||
spawn.randomBoss(-3250, -2700, 0.2);
|
spawn.randomBoss(-3250, -2700, 0.2);
|
||||||
spawn.randomBoss(-2450, -1100, 0);
|
spawn.randomBoss(-2450, -1100, 0);
|
||||||
if (game.difficulty > 4) spawn.randomLevelBoss(-3400, -2800);
|
if (game.difficulty > 4) spawn.randomLevelBoss(-3400, -2800);
|
||||||
|
|
||||||
},
|
},
|
||||||
warehouse() {
|
warehouse() {
|
||||||
level.defaultZoom = 1300
|
level.defaultZoom = 1300
|
||||||
@@ -1522,7 +1525,13 @@ const level = {
|
|||||||
//spawn.randomMob(1120, -1200, 0.3);
|
//spawn.randomMob(1120, -1200, 0.3);
|
||||||
//spawn.randomSmallMob(2200, -1775);
|
//spawn.randomSmallMob(2200, -1775);
|
||||||
|
|
||||||
if (game.difficulty > 2) spawn.snakeBoss(-1300 + Math.random() * 2000, -2200); //boss snake with head
|
if (game.difficulty > 3) {
|
||||||
|
if (Math.random() < 0.1) {
|
||||||
|
spawn.randomLevelBoss(-800, -1300)
|
||||||
|
} else {
|
||||||
|
spawn.snakeBoss(-1300 + Math.random() * 2000, -2200); //boss snake with head
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
office() {
|
office() {
|
||||||
level.defaultZoom = 1400
|
level.defaultZoom = 1400
|
||||||
|
|||||||
21
js/mobs.js
21
js/mobs.js
@@ -992,11 +992,11 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Math.random() < b.isModBotSpawner) {
|
if (Math.random() < b.isModBotSpawner) {
|
||||||
(Math.random() < 0.5) ? b.nailBot(): b.laserBot()
|
(Math.random() < 0.5) ? b.nailBot(this.position): b.laserBot(this.position)
|
||||||
|
if (mech.energy > 0.33) mech.energy -= 0.33
|
||||||
}
|
}
|
||||||
if (b.isModExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80))
|
if (b.isModExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80))
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
removeConsBB() {
|
removeConsBB() {
|
||||||
for (let i = 0, len = consBB.length; i < len; ++i) {
|
for (let i = 0, len = consBB.length; i < len; ++i) {
|
||||||
@@ -1040,20 +1040,31 @@ const mobs = {
|
|||||||
},
|
},
|
||||||
//replace dead mob with a regular body
|
//replace dead mob with a regular body
|
||||||
replace(i) {
|
replace(i) {
|
||||||
//large mobs or too many bodies go intangible and fall until removed from game to help performance
|
//if there are too many bodies don't turn into blocks to help performance
|
||||||
if (this.leaveBody && this.mass < 10 && body.length < 50) {
|
if (this.leaveBody && body.length < 60 && this.mass < 100) {
|
||||||
const len = body.length;
|
const len = body.length;
|
||||||
body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, this.vertices);
|
body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, this.vertices);
|
||||||
Matter.Body.setVelocity(body[len], this.velocity);
|
Matter.Body.setVelocity(body[len], this.velocity);
|
||||||
Matter.Body.setAngularVelocity(body[len], this.angularVelocity);
|
Matter.Body.setAngularVelocity(body[len], this.angularVelocity);
|
||||||
body[len].collisionFilter.category = cat.body;
|
body[len].collisionFilter.category = cat.body;
|
||||||
body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
|
body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
|
||||||
|
|
||||||
// if (body[len].mass > 10 || 45 + 10 * Math.random() < body.length) {
|
// if (body[len].mass > 10 || 45 + 10 * Math.random() < body.length) {
|
||||||
// body[len].collisionFilter.mask = cat.player | cat.bullet | cat.mob | cat.mobBullet;
|
// body[len].collisionFilter.mask = cat.player | cat.bullet | cat.mob | cat.mobBullet;
|
||||||
// }
|
// }
|
||||||
body[len].classType = "body";
|
body[len].classType = "body";
|
||||||
World.add(engine.world, body[len]); //add to world
|
World.add(engine.world, body[len]); //add to world
|
||||||
|
|
||||||
|
//large mobs shrink so they don't block paths
|
||||||
|
if (body[len].mass > 10) {
|
||||||
|
const shrink = function (that, massLimit) {
|
||||||
|
if (that.mass > massLimit) {
|
||||||
|
const scale = 0.95;
|
||||||
|
Matter.Body.scale(that, scale, scale);
|
||||||
|
setTimeout(shrink, 20, that, massLimit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
shrink(body[len], 9 + 5 * Math.random())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Matter.World.remove(engine.world, this);
|
Matter.World.remove(engine.world, this);
|
||||||
mob.splice(i, 1);
|
mob.splice(i, 1);
|
||||||
|
|||||||
17
js/player.js
17
js/player.js
@@ -371,7 +371,7 @@ const mech = {
|
|||||||
if (b.mods[i].count < b.mods[i].maxCount &&
|
if (b.mods[i].count < b.mods[i].maxCount &&
|
||||||
b.mods[i].name !== "quantum immortality" &&
|
b.mods[i].name !== "quantum immortality" &&
|
||||||
b.mods[i].name !== "Born rule" &&
|
b.mods[i].name !== "Born rule" &&
|
||||||
b.mods[i].name !== "leveraged investment" &&
|
b.mods[i].name !== "determinism" &&
|
||||||
b.mods[i].name !== "reallocation" &&
|
b.mods[i].name !== "reallocation" &&
|
||||||
b.mods[i].allowed()
|
b.mods[i].allowed()
|
||||||
) options.push(i);
|
) options.push(i);
|
||||||
@@ -603,7 +603,7 @@ const mech = {
|
|||||||
|
|
||||||
// freeze game and display a full screen red color
|
// freeze game and display a full screen red color
|
||||||
if (dmg > 0.05) {
|
if (dmg > 0.05) {
|
||||||
if (dmg > 0.15 * mech.holdingMassScale) mech.drop(); //drop block if holding
|
if (dmg > 0.20 * mech.holdingMassScale) mech.drop(); //drop block if holding
|
||||||
game.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
|
game.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
} else {
|
} else {
|
||||||
@@ -714,6 +714,13 @@ const mech = {
|
|||||||
mech.knee.x = (l / d) * (mech.foot.x - mech.hip.x) - (h / d) * (mech.foot.y - mech.hip.y) + mech.hip.x + offset;
|
mech.knee.x = (l / d) * (mech.foot.x - mech.hip.x) - (h / d) * (mech.foot.y - mech.hip.y) + mech.hip.x + offset;
|
||||||
mech.knee.y = (l / d) * (mech.foot.y - mech.hip.y) + (h / d) * (mech.foot.x - mech.hip.x) + mech.hip.y;
|
mech.knee.y = (l / d) * (mech.foot.y - mech.hip.y) + (h / d) * (mech.foot.x - mech.hip.x) + mech.hip.y;
|
||||||
},
|
},
|
||||||
|
// collisionImmune: false,
|
||||||
|
// beginCollisionImmune() {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// endCollisionImmune() {
|
||||||
|
|
||||||
|
// },
|
||||||
draw() {
|
draw() {
|
||||||
// mech.fillColor = (mech.collisionImmuneCycle < mech.cycle) ? "#fff" : "rgba(255,255,255,0.1)" //"#cff"
|
// mech.fillColor = (mech.collisionImmuneCycle < mech.cycle) ? "#fff" : "rgba(255,255,255,0.1)" //"#cff"
|
||||||
ctx.fillStyle = mech.fillColor;
|
ctx.fillStyle = mech.fillColor;
|
||||||
@@ -721,6 +728,12 @@ const mech = {
|
|||||||
|
|
||||||
//draw body
|
//draw body
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
// if (mech.collisionImmuneCycle < mech.cycle) {
|
||||||
|
// ctx.globalAlpha = 1
|
||||||
|
// if (mech.collisionImmune) mech.collisionImmune = false;
|
||||||
|
// } else {
|
||||||
|
// ctx.globalAlpha = 0.7
|
||||||
|
// }
|
||||||
ctx.globalAlpha = (mech.collisionImmuneCycle < mech.cycle) ? 1 : 0.7
|
ctx.globalAlpha = (mech.collisionImmuneCycle < mech.cycle) ? 1 : 0.7
|
||||||
ctx.translate(mech.pos.x, mech.pos.y);
|
ctx.translate(mech.pos.x, mech.pos.y);
|
||||||
mech.calcLeg(Math.PI, -3);
|
mech.calcLeg(Math.PI, -3);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const powerUps = {
|
|||||||
if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy;
|
if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy;
|
||||||
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 {
|
||||||
let ammo = Math.ceil((target.ammoPack * (1 + 0.1 * Math.random())));
|
let ammo = Math.ceil((target.ammoPack * (0.8 + 0.25 * Math.random())));
|
||||||
// if (level.isBuildRun) ammo = Math.floor(ammo * 1.1) //extra ammo on build run because no ammo from getting a new gun
|
// if (level.isBuildRun) ammo = Math.floor(ammo * 1.1) //extra ammo on build run because no ammo from getting a new gun
|
||||||
target.ammo += ammo;
|
target.ammo += ammo;
|
||||||
game.updateGunHUD();
|
game.updateGunHUD();
|
||||||
@@ -115,7 +115,7 @@ const powerUps = {
|
|||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.cancel("field")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>`
|
let text = `<div class='cancel' onclick='powerUps.cancel("field")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
|
||||||
if (!b.isModBayesian) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(mech.fieldUpgrades, choice1)
|
choice2 = pick(mech.fieldUpgrades, choice1)
|
||||||
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice2].name}</div> ${mech.fieldUpgrades[choice2].description}</div>`
|
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice2].name}</div> ${mech.fieldUpgrades[choice2].description}</div>`
|
||||||
choice3 = pick(mech.fieldUpgrades, choice1, choice2)
|
choice3 = pick(mech.fieldUpgrades, choice1, choice2)
|
||||||
@@ -160,7 +160,7 @@ const powerUps = {
|
|||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.cancel("mod")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
|
let text = `<div class='cancel' onclick='powerUps.cancel("mod")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice1})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice1].name}</div> ${b.mods[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice1})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice1].name}</div> ${b.mods[choice1].description}</div>`
|
||||||
if (!b.isModBayesian) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(choice1)
|
choice2 = pick(choice1)
|
||||||
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice2})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice2].name}</div> ${b.mods[choice2].description}</div>`
|
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice2})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice2].name}</div> ${b.mods[choice2].description}</div>`
|
||||||
choice3 = pick(choice1, choice2)
|
choice3 = pick(choice1, choice2)
|
||||||
@@ -198,7 +198,7 @@ const powerUps = {
|
|||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.cancel("gun")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>`
|
let text = `<div class='cancel' onclick='powerUps.cancel("gun")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
|
||||||
if (!b.isModBayesian) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(b.guns, choice1)
|
choice2 = pick(b.guns, choice1)
|
||||||
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
|
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
|
||||||
choice3 = pick(b.guns, choice1, choice2)
|
choice3 = pick(b.guns, choice1, choice2)
|
||||||
@@ -230,43 +230,43 @@ const powerUps = {
|
|||||||
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
||||||
if ((Math.random() * Math.random() - 0.3 > Math.sqrt(mech.health) && !b.isModEnergyHealth) || Math.random() < 0.035) { //spawn heal chance is higher at low health
|
if ((Math.random() * Math.random() - 0.3 > Math.sqrt(mech.health) && !b.isModEnergyHealth) || Math.random() < 0.035) { //spawn heal chance is higher at low health
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "heal");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "heal");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.15 && b.inventory.length > 0 && !b.isModNoAmmo) {
|
if (Math.random() < 0.15 && b.inventory.length > 0 && !b.modBayesian) {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "ammo");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "ammo");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.002 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3
|
if (Math.random() < 0.002 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3
|
||||||
powerUps.spawn(x, y, "gun");
|
powerUps.spawn(x, y, "gun");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "gun");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "gun");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.0027 * (15 - b.modCount)) { //a new mod has a low chance for each not acquired mod up to 15
|
if (Math.random() < 0.0027 * (15 - b.modCount)) { //a new mod has a low chance for each not acquired mod up to 15
|
||||||
powerUps.spawn(x, y, "mod");
|
powerUps.spawn(x, y, "mod");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "mod");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "mod");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.006) {
|
if (Math.random() < 0.006) {
|
||||||
powerUps.spawn(x, y, "field");
|
powerUps.spawn(x, y, "field");
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "field");
|
if (Math.random() < b.modBayesian) 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.isModBayesian) powerUps.spawn(x, y, "field")
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "field")
|
||||||
} else if (Math.random() < 0.9) {
|
} else if (Math.random() < 0.9) {
|
||||||
powerUps.spawn(x, y, "mod")
|
powerUps.spawn(x, y, "mod")
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "mod")
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "mod")
|
||||||
} else if (Math.random() < 0.5) {
|
} else if (Math.random() < 0.5) {
|
||||||
powerUps.spawn(x, y, "gun")
|
powerUps.spawn(x, y, "gun")
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "gun")
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "gun")
|
||||||
// } else if (Math.random() < 0.5) {
|
// } else if (Math.random() < 0.5) {
|
||||||
// powerUps.spawn(x, y, "field");
|
// powerUps.spawn(x, y, "field");
|
||||||
// if (Math.random() < b.isModBayesian) powerUps.spawn(x, y, "field");
|
// if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "field");
|
||||||
} else if (mech.health < 0.65 && !b.isModEnergyHealth) {
|
} else if (mech.health < 0.65 && !b.isModEnergyHealth) {
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
@@ -274,18 +274,18 @@ const powerUps = {
|
|||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
if (Math.random() < b.isModBayesian) {
|
if (Math.random() < b.modBayesian) {
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
}
|
}
|
||||||
} else if (!b.isModNoAmmo) {
|
} else if (!b.modBayesian) {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
if (Math.random() < b.isModBayesian) {
|
if (Math.random() < b.modBayesian) {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
@@ -296,10 +296,11 @@ const powerUps = {
|
|||||||
if (Math.random() < 0.5) {
|
if (Math.random() < 0.5) {
|
||||||
powerUps.spawn(x, y, "heal", false);
|
powerUps.spawn(x, y, "heal", false);
|
||||||
} else {
|
} else {
|
||||||
if (!b.isModNoAmmo) powerUps.spawn(x, y, "ammo", false);
|
if (!b.modBayesian) 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 (level.levelsCleared < 5) {
|
||||||
if (b.inventory.length === 0) {
|
if (b.inventory.length === 0) {
|
||||||
powerUps.spawn(x, y, "gun", false);
|
powerUps.spawn(x, y, "gun", false);
|
||||||
} else if (b.modCount === 0) {
|
} else if (b.modCount === 0) {
|
||||||
@@ -312,6 +313,11 @@ const powerUps = {
|
|||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
powerUps.spawnRandomPowerUp(x, y);
|
powerUps.spawnRandomPowerUp(x, y);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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") {
|
||||||
|
|||||||
83
js/spawn.js
83
js/spawn.js
@@ -81,7 +81,7 @@ const spawn = {
|
|||||||
},
|
},
|
||||||
randomLevelBoss(x, y) {
|
randomLevelBoss(x, y) {
|
||||||
// suckerBoss, laserBoss, tetherBoss, snakeBoss all need a particular level to work so they are not included
|
// suckerBoss, laserBoss, tetherBoss, snakeBoss all need a particular level to work so they are not included
|
||||||
const options = ["shooterBoss", "cellBossCulture", "bomberBoss"] //, "timeSkipBoss"
|
const options = ["spiderBoss"] //, "timeSkipBoss" //"shooterBoss", "cellBossCulture", "bomberBoss",
|
||||||
// const options = ["timeSkipBoss"]
|
// const options = ["timeSkipBoss"]
|
||||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||||
},
|
},
|
||||||
@@ -329,6 +329,7 @@ const spawn = {
|
|||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.big = false; //required for grow
|
me.big = false; //required for grow
|
||||||
me.accelMag = 0.00045 * game.accelScale;
|
me.accelMag = 0.00045 * game.accelScale;
|
||||||
|
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.player //can't touch other mobs
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
@@ -384,7 +385,6 @@ const spawn = {
|
|||||||
this.searchSpring();
|
this.searchSpring();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.springAttack();
|
this.springAttack();
|
||||||
//not properly effected by stun, if looking at player while stun will still attack...
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
||||||
@@ -638,6 +638,82 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
spiderBoss(x, y, radius = 50 + Math.ceil(Math.random() * 10)) {
|
||||||
|
let targets = [] //track who is in the node boss, for shields
|
||||||
|
mobs.spawn(x, y, 6, radius, "#b386e8");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
targets.push(me.id) //add to shield protection
|
||||||
|
me.friction = 0;
|
||||||
|
me.frictionAir = 0.0065;
|
||||||
|
me.lookTorque = 0.0000008; //controls spin while looking for player
|
||||||
|
me.g = 0.00025; //required if using 'gravity'
|
||||||
|
me.seePlayerFreq = Math.round((40 + 25 * Math.random()) * game.lookFreqScale);
|
||||||
|
const springStiffness = 0.00006;
|
||||||
|
const springDampening = 0.0006;
|
||||||
|
|
||||||
|
me.springTarget = {
|
||||||
|
x: me.position.x,
|
||||||
|
y: me.position.y
|
||||||
|
};
|
||||||
|
const len = cons.length;
|
||||||
|
cons[len] = Constraint.create({
|
||||||
|
pointA: me.springTarget,
|
||||||
|
bodyB: me,
|
||||||
|
stiffness: springStiffness,
|
||||||
|
damping: springDampening
|
||||||
|
});
|
||||||
|
cons[len].length = 100 + 1.5 * radius;
|
||||||
|
me.cons = cons[len];
|
||||||
|
|
||||||
|
me.springTarget2 = {
|
||||||
|
x: me.position.x,
|
||||||
|
y: me.position.y
|
||||||
|
};
|
||||||
|
const len2 = cons.length;
|
||||||
|
cons[len2] = Constraint.create({
|
||||||
|
pointA: me.springTarget2,
|
||||||
|
bodyB: me,
|
||||||
|
stiffness: springStiffness,
|
||||||
|
damping: springDampening
|
||||||
|
});
|
||||||
|
cons[len2].length = 100 + 1.5 * radius;
|
||||||
|
me.cons2 = cons[len2];
|
||||||
|
// Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
|
me.onDeath = function () {
|
||||||
|
this.removeCons();
|
||||||
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
|
};
|
||||||
|
me.do = function () {
|
||||||
|
this.gravity();
|
||||||
|
this.searchSpring();
|
||||||
|
this.checkStatus();
|
||||||
|
this.springAttack();
|
||||||
|
};
|
||||||
|
|
||||||
|
radius = 22 // radius of each node mob
|
||||||
|
const sideLength = 100 // distance between each node mob
|
||||||
|
const nodes = 6
|
||||||
|
const angle = 2 * Math.PI / nodes
|
||||||
|
|
||||||
|
spawn.allowShields = false; //don't want shields on individual boss mobs
|
||||||
|
|
||||||
|
for (let i = 0; i < nodes; ++i) {
|
||||||
|
spawn.stabber(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius);
|
||||||
|
targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields
|
||||||
|
}
|
||||||
|
//spawn shield for entire boss
|
||||||
|
spawn.bossShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
|
||||||
|
spawn.allowShields = true;
|
||||||
|
|
||||||
|
spawn.constrain2AdjacentMobs(nodes + 1, 0.05, true); //loop mobs together
|
||||||
|
for (let i = 0; i < nodes; ++i) { //attach to center mob
|
||||||
|
consBB[consBB.length] = Constraint.create({
|
||||||
|
bodyA: me,
|
||||||
|
bodyB: mob[mob.length - i - 1],
|
||||||
|
stiffness: 0.05
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
timeSkipBoss(x, y, radius = 70) {
|
timeSkipBoss(x, y, radius = 70) {
|
||||||
mobs.spawn(x, y, 6, radius, '#000');
|
mobs.spawn(x, y, 6, radius, '#000');
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
@@ -945,6 +1021,7 @@ const spawn = {
|
|||||||
me.spikeLength = 0;
|
me.spikeLength = 0;
|
||||||
me.isSpikeGrowing = false;
|
me.isSpikeGrowing = false;
|
||||||
me.isSpikeReset = true;
|
me.isSpikeReset = true;
|
||||||
|
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.player //can't touch other mobs
|
||||||
Matter.Body.rotate(me, Math.PI * 0.1);
|
Matter.Body.rotate(me, Math.PI * 0.1);
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
// me.onDamage = function () {};
|
// me.onDamage = function () {};
|
||||||
@@ -1013,7 +1090,7 @@ const spawn = {
|
|||||||
me.g = 0.0002; //required if using 'gravity'
|
me.g = 0.0002; //required if using 'gravity'
|
||||||
me.frictionStatic = 0;
|
me.frictionStatic = 0;
|
||||||
me.friction = 0;
|
me.friction = 0;
|
||||||
me.delay = 120 * game.CDScale;
|
me.delay = 90 * game.CDScale;
|
||||||
me.cd = Infinity;
|
me.cd = Infinity;
|
||||||
Matter.Body.rotate(me, Math.PI * 0.1);
|
Matter.Body.rotate(me, Math.PI * 0.1);
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
|
|||||||
19
style.css
19
style.css
@@ -95,6 +95,25 @@ summary {
|
|||||||
/* transition: display 0.5s; */
|
/* transition: display 0.5s; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#construct {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0%;
|
||||||
|
right: 0%;
|
||||||
|
z-index: 1;
|
||||||
|
width: 300px;
|
||||||
|
height: 320px;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
font-size: 0.9em;
|
||||||
|
user-select: text;
|
||||||
|
white-space: pre;
|
||||||
|
padding: 3px;
|
||||||
|
overflow: scroll;
|
||||||
|
/* border-radius: 0px; */
|
||||||
|
border: 2px #333 solid;
|
||||||
|
}
|
||||||
|
|
||||||
#choose-grid {
|
#choose-grid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|||||||
20
todo.txt
20
todo.txt
@@ -1,10 +1,24 @@
|
|||||||
|
|
||||||
|
|
||||||
foam gun now slows down when touching walls
|
large mods shrink on death instead of disappearing
|
||||||
mod - quantum foam now bypasses shields
|
new boss mob: spiderBoss
|
||||||
Bayesian now only give one mod choice on election, but 33% (from 20%) chance at double power ups
|
mod - Bayesian interference -> determinism
|
||||||
|
spawn 4 mods and 2 heals, future power ups are limited to one choice
|
||||||
|
mod - Leveraged investments -> Bayesian interference
|
||||||
|
33% chance for double power ups to drop, remove all future ammo power ups
|
||||||
|
|
||||||
|
(serious progress on my level construction tools, but it's not ready yet)
|
||||||
|
|
||||||
************** TODO - n-gon **************
|
************** TODO - n-gon **************
|
||||||
|
|
||||||
|
construct
|
||||||
|
display outline of map to be draw while mouse is down
|
||||||
|
toggle between maps and bodies
|
||||||
|
?highlight map/body mouse is over and be able to remove it?
|
||||||
|
display current output text in a box
|
||||||
|
live update it
|
||||||
|
|
||||||
|
|
||||||
mod - blocking with perfect diamagnetism fires your gun
|
mod - blocking with perfect diamagnetism fires your gun
|
||||||
maybe doesn't trigger cooldown?
|
maybe doesn't trigger cooldown?
|
||||||
does use ammo
|
does use ammo
|
||||||
|
|||||||
Reference in New Issue
Block a user