new level - flocculation

new level - flocculation

snakeBoss does 40% less damage to player
This commit is contained in:
landgreen
2024-07-19 16:34:01 -07:00
parent fc70dfee2f
commit 5eae070238
6 changed files with 438 additions and 130 deletions

View File

@@ -1476,8 +1476,10 @@ window.addEventListener("keydown", function (event) {
} else { } else {
simulation.testing = true; simulation.testing = true;
simulation.loop = simulation.testingLoop simulation.loop = simulation.testingLoop
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
if (simulation.testing) tech.setCheating(); if (simulation.testing) tech.setCheating();
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'inline'
} else {
simulation.makeTextLog( simulation.makeTextLog(
`<table class="pause-table"> `<table class="pause-table">
<tr> <tr>
@@ -1531,8 +1533,8 @@ window.addEventListener("keydown", function (event) {
<tr> <tr>
<td class='key-input-pause'>⇧X</td> <td class='key-input-pause'>⇧X</td>
<td class='key-used'>restart</td> <td class='key-used'>restart</td>
</tr> </tr></table>`, Infinity);
</table>`, Infinity); }
} }
} }
break break

View File

@@ -9,7 +9,7 @@ const level = {
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later //see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers"], playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers", "flocculation"],
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", "arena", "soft", "flappyGon", "rings", "trial"], communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", "arena", "soft", "flappyGon", "rings", "trial"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [], levels: [],
@@ -17,6 +17,8 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode // simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// level.levelsCleared = 4
// level.updateDifficulty()
// tech.giveTech("performance") // tech.giveTech("performance")
// m.maxHealth = m.health = 1//00000000 // m.maxHealth = m.health = 1//00000000
// m.maxEnergy = m.energy = 10000000 // m.maxEnergy = m.energy = 10000000
@@ -45,33 +47,21 @@ const level = {
// tech.giveTech("1st ionization energy") // tech.giveTech("1st ionization energy")
// for (let i = 0; i < 1; ++i) tech.giveTech("booby trap") // for (let i = 0; i < 1; ++i) tech.giveTech("booby trap")
// for (let i = 0; i < 1; ++i) tech.giveTech("obsolescence") // for (let i = 0; i < 1; ++i) tech.giveTech("obsolescence")
// for (let i = 0; i < 1; ++i) tech.giveTech("arsenal") // for (let i = 0; i < 1; ++i) tech.giveTech("brainstorming")
// requestAnimationFrame(() => { for (let i = 0; i < 3; i++) tech.giveTech("mechatronics") }); // requestAnimationFrame(() => { for (let i = 0; i < 3; i++) tech.giveTech("mechatronics") });
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("paradigm shift") }); // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("eternalism") });
// for (let i = 0; i < 2; i++) tech.giveTech("nail-bot") // for (let i = 0; i < 2; i++) tech.giveTech("technical debt")
// m.lastKillCycle = m.cycle // m.lastKillCycle = m.cycle
// for (let i = 0; i < 1; ++i) tech.giveTech("cross-disciplinary") // for (let i = 0; i < 1; ++i) tech.giveTech("determinism")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 1; i++) powerUps.directSpawn(-50, -70, "difficulty", false); // for (let i = 0; i < 1; i++) powerUps.directSpawn(m.pos.x, m.pos.y - 50, "difficulty", false);
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing // spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
// level.testing(); // level.flocculation();
// for (let i = 0; i < 1; ++i) spawn.snakeBoss(1400, -500)
// for (let i = 0; i < 20; i++) powerUps.directSpawn(0, 0, "coupling");
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
// for (let i = 0; i < 4; ++i) spawn.sucker(1300, -500 + 100 * Math.random())
// spawn.hopper(1900, -500)
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
// tech.tech[322].frequency = 100
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech()
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level ************************************************** level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
// for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500) // for (let i = 0; i < 1; ++i) spawn.snakeBoss(1900, -500)
// for (let i = 0; i < 2; i++) spawn.ghoster(level.exit.x, level.exit.y) //ghosters need to spawn after the map loads // for (let i = 0; i < 2; i++) spawn.ghoster(level.exit.x, level.exit.y) //ghosters need to spawn after the map loads
// console.log(body[body.length - 1].mass)
// simulation.isAutoZoom = false; //look in close // simulation.isAutoZoom = false; //look in close
// simulation.zoomScale *= 0.5; // simulation.zoomScale *= 0.5;
// simulation.setZoom(); // simulation.setZoom();
@@ -922,10 +912,7 @@ const level = {
return who return who
} }
}, },
elevator(x, y, width, height, maxHeight, force = 0.003, friction = { elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }, isAtTop = false) {
up: 0.01,
down: 0.2
}, isAtTop = false) {
x += width / 2 x += width / 2
y += height / 2 y += height / 2
maxHeight += height / 2 maxHeight += height / 2
@@ -934,7 +921,7 @@ const level = {
const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, { const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.body, //cat.map, category: cat.body, //cat.map,
mask: cat.map | cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet mask: cat.player | cat.body | cat.bullet | cat.mob | cat.mobBullet //| cat.powerUp
}, },
inertia: Infinity, //prevents rotation inertia: Infinity, //prevents rotation
isNotHoldable: true, isNotHoldable: true,
@@ -990,17 +977,69 @@ const level = {
x: this.holdX, x: this.holdX,
y: this.position.y y: this.position.y
}); });
},
moveOnTouch() {
if (!m.isBodiesAsleep) {
if (this.isUp) { //moving up still with high air friction
this.force.y -= force * this.mass //hard force propels up, even with high friction
if (this.position.y < maxHeight) { //switch to down mode
this.isUp = false
this.frictionAir = friction.down
//adds a hard jerk at the top of vertical motion because it's fun
Matter.Body.setPosition(this, { x: this.holdX, y: maxHeight });
Matter.Body.setVelocity(this, { x: 0, y: 0 });
}
} else if (this.position.y + 10 * this.velocity.y > y) { //free falling down, with only air friction
//slow down early to avoid a jerky stop that can pass through blocks
Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y * 0.7 });
//switch to up mode
// if (this.position.y + this.velocity.y > y) {
// this.isUp = true
// this.frictionAir = friction.up
// }
}
Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y });
}
//draw line to show how far to will extend
ctx.beginPath();
ctx.moveTo(x, y + height / 2);
ctx.lineTo(x, maxHeight - height / 2);
ctx.strokeStyle = `rgba(0,0,0,0.2)`
// ctx.lineWidth = "3"
ctx.stroke();
//draw body
ctx.beginPath();
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
for (let j = 1; j < this.vertices.length; j++) {
ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
}
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
ctx.lineWidth = "2"
ctx.strokeStyle = `#333`
ctx.fillStyle = `rgba(200,200,200,1)`
//edge limits
if (this.position.y < maxHeight) {
Matter.Body.setPosition(this, { x: this.holdX, y: maxHeight });
} else if (this.position.y > y) {
ctx.fillStyle = `rgba(255,255,255,${0.5 + 0.15 * Math.random()})`
Matter.Body.setPosition(this, { x: this.holdX, y: y });
//undoing force of gravity
this.force.y -= this.mass * simulation.g;
if (Matter.Query.collides(this, [player]).length) {
this.isUp = true
this.frictionAir = friction.up
}
}
ctx.fill();
ctx.stroke();
// hold horizontal position
Matter.Body.setPosition(this, { x: this.holdX, y: this.position.y });
}, },
off() { off() {
Matter.Body.setPosition(this, { Matter.Body.setPosition(this, { x: this.holdX, y: this.position.y });
x: this.holdX, Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y });
y: this.position.y
});
Matter.Body.setVelocity(this, {
x: 0,
y: this.velocity.y
});
}, },
constraint: this.null, constraint: this.null,
addConstraint() { addConstraint() {
@@ -1028,73 +1067,69 @@ const level = {
who.classType = "body" who.classType = "body"
return who return who
}, },
spring(x, y, v = "-100 0 100 0 70 40 0 50 -70 40", force = 0.01, distance = 300, angle = 0) { // spring(x, y, v = "-100 0 100 0 70 40 0 50 -70 40", force = 0.01, distance = 300, angle = 0) {
const who = body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(v), { // const who = body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(v), {
collisionFilter: { // collisionFilter: {
category: cat.body, // category: cat.body,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet // mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
}, // },
inertia: Infinity, //prevents rotation // inertia: Infinity, //prevents rotation
isNotHoldable: true, // isNotHoldable: true,
friction: 1, // friction: 1,
frictionStatic: 1, // frictionStatic: 1,
restitution: 0, // restitution: 0,
frictionAir: 1, // frictionAir: 1,
density: 0.1, // density: 0.1,
isReady: true, // isReady: true,
isResetting: false, // isResetting: false,
query() { // query() {
if (this.isReady) { // if (this.isReady) {
if (Matter.Query.collides(this, [player]).length) { // if (Matter.Query.collides(this, [player]).length) {
this.isReady = false // this.isReady = false
this.constraint.stiffness = 0 // this.constraint.stiffness = 0
this.constraint.damping = 0 //0.3 // this.constraint.damping = 0 //0.3
this.frictionAir = 0 // this.frictionAir = 0
Matter.Body.setVelocity(this, { // Matter.Body.setVelocity(this, { x: 0, y: 0 });
x: 0, // //show graphically being ready?
y: 0 // }
}); // } else {
//show graphically being ready? // if (this.isResetting) {
// this.constraint.stiffness += 0.0005
} // if (this.constraint.stiffness > 0.1) {
} else { // this.isResetting = false
if (this.isResetting) { // this.isReady = true
this.constraint.stiffness += 0.0005 // }
if (this.constraint.stiffness > 0.1) { // } else {
this.isResetting = false // if (Vector.magnitudeSquared(Vector.sub(this.position, {
this.isReady = true // x: x,
} // y: y
} else { // })) < distance * distance) {
if (Vector.magnitudeSquared(Vector.sub(this.position, { // this.force.y -= force * this.mass
x: x, // } else {
y: y // this.constraint.damping = 1
})) < distance * distance) { // this.frictionAir = 1
this.force.y -= force * this.mass // this.isResetting = true
} else { // Matter.Body.setVelocity(this, {
this.constraint.damping = 1 // x: 0,
this.frictionAir = 1 // y: 0
this.isResetting = true // });
Matter.Body.setVelocity(this, { // }
x: 0, // }
y: 0 // }
}); // }
} // });
} // who.constraint = Constraint.create({
} // pointA: {
} // x: who.position.x,
}); // y: who.position.y
who.constraint = Constraint.create({ // },
pointA: { // bodyB: who,
x: who.position.x, // stiffness: 1,
y: who.position.y // damping: 1
}, // });
bodyB: who, // Composite.add(engine.world, who.constraint);
stiffness: 1, // return who
damping: 1 // },
});
Composite.add(engine.world, who.constraint);
return who
},
// rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) { // rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
// const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, { // const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
// density: density, // density: density,
@@ -4893,7 +4928,6 @@ const level = {
balance1 = level.spinner(x + 200, y - 500, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) { balance1 = level.spinner(x + 200, y - 500, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance2 = level.spinner(x + 200, y - 950, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) balance2 = level.spinner(x + 200, y - 950, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 650, y - 750, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) balance3 = level.spinner(x + 650, y - 750, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
// balance4 = level.spinner(x + 750, y - 1050, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance4 = level.spinner(x + 1250, y - 1000, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) balance4 = level.spinner(x + 1250, y - 1000, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
let isInRoom = false let isInRoom = false
@@ -6760,6 +6794,260 @@ const level = {
balance5 = level.rotor(2605, 1100, 390, 25, 0.001) //falling balance5 = level.rotor(2605, 1100, 390, 25, 0.001) //falling
} }
},
flocculation() {
level.announceMobTypes()
const button0 = level.button(1125, 795)
const button1 = level.button(6538, 2670)
const button2 = level.button(1225, -100)
button0.isUp = true
button1.isUp = true
button2.isUp = true
// const hazard = level.hazard(4550, 2750, 4550, 150)
const hazard = level.hazard(simulation.isHorizontalFlipped ? -7200 : 675, 50, 7500, 3000) //1869
// hazard.min.y = 3000 //REMOVE THIS IN LIVE VERSION!!!!! set slime to lowest level
let balance1, balance2, balance3, rotor1, rotor2
const drip1 = level.drip(6100, 1900, 2900, 100) // drip(x, yMin, yMax, period = 100, color = "hsla(160, 100%, 35%, 0.5)") {
const drip2 = level.drip(7300, 1900, 2900, 150)
const drip3 = level.drip(8750, 1900, 2900, 70)
//up mode triggered by player contact
const elevator0 = level.elevator(700, 1865, 200, 490, 1400, 0.011, { up: 0.01, down: 0.7 })
const elevator1 = level.elevator(3995, 2335, 210, 150, 1700, 0.011, { up: 0.01, down: 0.7 })
level.custom = () => {
drip1.draw();
drip2.draw();
drip3.draw();
if (button0.isUp) {
button0.query();
if (!button0.isUp) { //summon second set of mobs
//1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
spawn.randomMob(918, 2695, 0.1);
spawn.randomMob(1818, 2719, 0.2);
spawn.randomMob(2530, 2460, 0.2);
spawn.randomMob(3109, 2665, 0.3);
spawn.randomMob(3909, 2191, 0.3);
spawn.randomMob(4705, 2711, 0.4);
spawn.randomMob(5800, 2796, 0.5);
spawn.randomMob(7287, 2757, 0.6);
spawn.randomMob(5759, 2691, 0.9);
spawn.randomMob(5675, 2225, 0.8);
spawn.randomMob(7450, 2775, 0.8);
spawn.randomGroup(6600, 2400, 0.1);
if (simulation.difficulty > 1) spawn.randomLevelBoss(6076, 2341);
}
}
button0.draw();
if (button1.isUp) button1.query();
button1.draw();
if (button2.isUp) button2.query();
button2.draw();
ctx.fillStyle = "hsl(175, 15%, 76%)"
ctx.fillRect(7625, 2625, 400, 300)
ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
ctx.fillRect(6250, 1875, 700, 875)
ctx.fillRect(900, 1200, 600, 1725) //900, 1350, 600, 1600);
ctx.fillRect(3000, 1200, 1000, 1750);
ctx.fillRect(2200, 625, 400, 2050);
level.exit.drawAndCheck();
level.enter.draw();
};
level.customTopLayer = () => {
elevator0.moveOnTouch()
elevator1.moveOnTouch()
rotor1.rotate();
rotor2.rotate();
ctx.fillStyle = "#233"
ctx.beginPath();
ctx.arc(balance1.center.x, balance1.center.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance2.center.x, balance2.center.y)
ctx.arc(balance2.center.x, balance2.center.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance3.center.x, balance3.center.y)
ctx.arc(balance3.center.x, balance3.center.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance5.center.x, balance5.center.y)
ctx.arc(balance5.center.x, balance5.center.y, 9, 0, 2 * Math.PI);
ctx.moveTo(rotor1.center.x, rotor1.center.y)
ctx.arc(rotor1.center.x, rotor1.center.y, 9, 0, 2 * Math.PI);
ctx.moveTo(rotor2.center.x, rotor2.center.y)
ctx.arc(rotor2.center.x, rotor2.center.y, 9, 0, 2 * Math.PI);
ctx.fill();
hazard.query();
const drainRate = Math.max(1, 4 - hazard.min.y / 800)
hazard.level(
(button2.isUp || hazard.height < 1150) &&
(button0.isUp || hazard.height < 350) &&
button1.isUp
, drainRate) //true = hold, false = lower
exitDoor.isClosing = hazard.min.y < 2900
exitDoor.openClose();
exitDoor.draw();
};
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = 7800;
level.exit.y = 2865;
const exitDoor = level.door(7637, 2680, 25, 225, 195, 5)
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "hsl(138, 3%, 74%)";
color.map = "#3d4240"
powerUps.spawnStartingPowerUps(3475, 1775);
spawn.debris(4575, 2550, 1600, 6); //16 debris per level
spawn.debris(750, 2550, 2250, 6); //16 debris per level
spawn.mapRect(-500, -600, 200, 800); //left entrance wall
spawn.mapRect(-400, -600, 3550, 200); //ceiling
spawn.mapRect(-400, 0, 1400, 600);
spawn.mapRect(575, 475, 250, 250);
Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
spawn.mapRect(4075, 75, 250, 250);
Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
spawn.mapRect(4259, 1559, 282.5, 282.5);
Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
spawn.mapRect(3140, -600, 200, 800); //right down tube wall
spawn.mapRect(3150, 0, 1200, 200); //tube right exit ceiling
spawn.mapVertex(2400, 500, "-200 -100 -100 -200 100 -200 200 -100 200 200 -200 200");
spawn.mapVertex(2400, 1200, "-200 -200 200 -200 200 100 100 200 -100 200 -200 100");
spawn.mapVertex(1200, 2150, "-300 -300 300 -300 300 200 200 300 -200 300 -300 200");
spawn.mapVertex(1200, 1100, "-300 -200 -200 -300 200 -300 300 -200 300 300 -300 300");
spawn.mapVertex(3500, 950, "-500 -450 -400 -550 400 -550 500 -450 500 450 400 550 -400 550 -500 450");
spawn.mapVertex(3500, 1990, "-300 -40 -230 -110 230 -110 300 -40 300 40 230 110 -230 110 -300 40");
// spawn.mapVertex(2400, 1940, "-200 -40 -150 -90 150 -90 200 -40 200 40 150 90 -150 90 -200 40");
spawn.mapRect(2200, 1850, 400, 200);
spawn.bodyRect(3825, 2240, 150, 75, 0.5);
spawn.mapVertex(3500, 2452, "-500 -135 500 -135 500 35 400 135 -400 135 -500 35");
spawn.mapVertex(1200, 2875, "-400 0 -300 -100 300 -100 400 0");
spawn.mapVertex(1317, 275, "-500 0 -300 -200 300 -200 550 50 550 500 -500 500");
spawn.mapVertex(1300, -357, "-300 0 -400 -100 400 -100 300 0");
spawn.bodyRect(1550, -308, 50, 208, 0.5);
spawn.bodyRect(2000, 965, 525, 25, 0.5);
spawn.mapVertex(2400, 2850, "-350 -50 -300 -100 300 -100 350 -50 350 300 -350 300");
spawn.mapVertex(6600, 1925, "-350 0 -450 -100 450 -100 350 0");
spawn.mapVertex(6600, 2875, "-400 -50 -350 -100 350 -100 400 -50 400 300 -400 300");
spawn.bodyRect(2375, 300, 100, 100, 0.6);
spawn.bodyRect(1025, 1775, 100, 75, 0.6);
spawn.bodyRect(1250, 1825, 50, 25, 0.6);
spawn.bodyRect(3700, 275, 125, 125, 0.6);
spawn.bodyRect(5875, 2725, 200, 200, 0.6);
spawn.bodyRect(6900, 2590, 50, 50, 0.6);
spawn.mapRect(4200, 2325, 250, 625);
spawn.mapRect(-500, 50, 1200, 3050);
spawn.mapRect(-500, 2900, 9600, 775);
spawn.mapRect(4400, 0, 4700, 1900);
spawn.mapRect(4200, 0, 200, 1700);
// spawn.mapRect(6250, 2675, 700, 325);
// spawn.mapRect(6250, 1875, 700, 150);
//exit room
spawn.mapRect(8000, 1775, 1100, 1375);
spawn.mapRect(7625, 1825, 450, 825);
spawn.mapRect(7625, 2625, 50, 75);
spawn.mapRect(7625, 2890, 400, 25);
spawn.mapRect(7800, 2880, 100, 25);
spawn.randomMob(2450, 250, 0.2);
spawn.randomMob(3250, 325, 0.2);
spawn.randomMob(3625, 350, 0.3);
spawn.randomMob(1750, -25, 0.4);
spawn.randomMob(1300, 1750, 0.5);
spawn.randomMob(2350, 1725, 0.6);
spawn.randomMob(3350, 1775, 0.7);
spawn.randomMob(1025, 750, 0.8);
spawn.randomMob(2400, 1775, 0.8);
spawn.randomMob(1250, 1725, 0.8);
spawn.randomMob(775, 1775, 0.9);
powerUps.addResearchToLevel() //needs to run after mobs are spawned
spawn.secondaryBossChance(1822, 1336)
if (simulation.isHorizontalFlipped) { //flip the map horizontally
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
rotor1 = level.rotor(-5600, 2390, 850, 50, 0.001, 0, 0.01, 0, 0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) {
rotor2 = level.rotor(-2175, 1900, 650, 50, 0.001, 0, 0.01, 0, 0.0007)
balance1 = level.rotor(-800 - 25, -395, 25, 390, 0.001) //entrance
balance2 = level.rotor(-2605 - 390, 500, 390, 25, 0.001) //falling
balance3 = level.rotor(-2608 - 584, 1950, 584, 25, 0.001) //falling
balance5 = level.rotor(-2605 - 390, 1020, 390, 25, 0.001) //falling
button1.min.x = -button1.min.x - 126
button1.max.x = -button1.max.x + 126
button0.min.x = -button0.min.x - 126
button0.max.x = -button0.max.x + 126
button2.min.x = -button2.min.x - 126
button2.max.x = -button2.max.x + 126 // flip the button horizontally
drip1.x *= -1
drip2.x *= -1
drip3.x *= -1
elevator0.holdX *= -1
elevator1.holdX *= -1
// console.log(hazard)
hazard.min.x -= 840
hazard.max.x -= 840
level.custom = () => {
drip1.draw();
drip2.draw();
drip3.draw();
if (button0.isUp) {
button0.query();
if (!button0.isUp) { //summon second set of mobs
//1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
spawn.randomMob(-7475, 2800, 0.1);
spawn.randomMob(-6475, 2500, 0.2);
spawn.randomMob(-4575, 2775, 0.3);
spawn.randomMob(-7575, 2850, 0.3);
spawn.randomMob(-6425, 2575, 0.3);
spawn.randomMob(-5750, 2775, 0.4);
spawn.randomMob(-4675, 2800, 0.5);
spawn.randomMob(-3425, 2800, 0.6);
spawn.randomMob(-2475, 2475, 0.7);
spawn.randomMob(-3350, 2250, 0.8);
spawn.randomMob(-1275, 2725, 0.9);
spawn.randomGroup(-6225, 2400, 0.1);
if (simulation.difficulty > 1) spawn.randomLevelBoss(-6250, 2350);
}
}
button0.draw();
if (button1.isUp) button1.query();
button1.draw();
if (button2.isUp) button2.query();
button2.draw();
rotor1.rotate();
rotor2.rotate();
ctx.fillStyle = "hsl(175, 15%, 76%)"
ctx.fillRect(-8025, 2625, 400, 300)
ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
ctx.fillRect(-6950, 1875, 700, 875)
ctx.fillRect(-4000, 1400, 1000, 1550);
ctx.fillRect(-2600, 675, 400, 2025);
ctx.fillRect(-1500, 1375, 600, 1500);
level.exit.drawAndCheck();
level.enter.draw();
};
// level.customTopLayer = () => {};
} else {
rotor1 = level.rotor(4700, 2390, 850, 50, 0.001, 0, 0.01, 0, -0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) {
rotor2 = level.rotor(1525, 1900, 650, 50, 0.001, 0, 0.01, 0, -0.0007)
balance1 = level.rotor(800, -395, 25, 390, 0.001) //entrance
balance2 = level.rotor(2605, 500, 390, 25, 0.001) //falling
balance3 = level.rotor(2608, 1950, 584, 25, 0.001) //falling
balance5 = level.rotor(2605, 1020, 390, 25, 0.001) //falling
}
}, },
satellite() { satellite() {
level.announceMobTypes() level.announceMobTypes()

View File

@@ -1928,6 +1928,17 @@ const simulation = {
} }
}); });
document.body.addEventListener("wheel", (e) => {
if (e.deltaY > 0) {
simulation.setZoom(simulation.zoomScale / 0.9)
} else {
simulation.setZoom(simulation.zoomScale * 0.9)
}
});
//undo last element added after you press z //undo last element added after you press z
document.body.addEventListener("keydown", (event) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67 document.body.addEventListener("keydown", (event) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
if (simulation.testing && event.code === "KeyZ" && simulation.constructMapString.length) { if (simulation.testing && event.code === "KeyZ" && simulation.constructMapString.length) {

View File

@@ -7,7 +7,7 @@ const spawn = {
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss", "mantisBoss", "laserLayerBoss", "timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss", "mantisBoss", "laserLayerBoss",
"snakeBoss", "snakeBoss"
], ],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -3963,7 +3963,7 @@ const spawn = {
for (let i = 0; i < this.history.length - 1; i++) { for (let i = 0; i < this.history.length - 1; i++) {
if (Matter.Query.ray([player], this.history[i], this.history[i + 1], 10).length > 0) { if (Matter.Query.ray([player], this.history[i], this.history[i + 1], 10).length > 0) {
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60 m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60
const dmg = 0.25 * simulation.dmgScale const dmg = 0.15 * simulation.dmgScale
m.damage(dmg); m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x, x: m.pos.x,

View File

@@ -3648,7 +3648,7 @@ const tech = {
}, },
{ {
name: "unified field theory", name: "unified field theory",
description: `when <strong>paused</strong> you can <strong>switch</strong> ${powerUps.orb.field()} by clicking<br><strong>2x</strong> <em class='flicker'>${powerUps.orb.fieldTech()} frequency</em>`, description: `when <strong>paused</strong> you can click to <strong>change</strong> your ${powerUps.orb.field()}<br><strong>2x</strong> <em class='flicker'>${powerUps.orb.fieldTech()} frequency</em>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3787,7 +3787,7 @@ const tech = {
}, },
{ {
name: "determinism", name: "determinism",
description: `spawn ${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}<br>only <strong>1</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong> for ${powerUps.orb.field()}, ${powerUps.orb.tech()}, and ${powerUps.orb.gun()}`, description: `spawn ${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}${powerUps.orb.tech()}<br>${powerUps.orb.field()}, ${powerUps.orb.tech()}, and ${powerUps.orb.gun()} have only <strong>1</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3832,7 +3832,7 @@ const tech = {
{ {
name: "technical debt", name: "technical debt",
descriptionFunction() { descriptionFunction() {
return `<strong>4x</strong> <strong class='color-d'>damage</strong> but lose <strong>0.15x</strong> <strong class='color-d'>damage</strong><br>for each ${powerUps.orb.tech()} you have <em style ="float: right;">(${(tech.totalCount > 20 ? (Math.pow(0.85, tech.totalCount - 20)) : (4 - 0.15 * tech.totalCount)).toFixed(2)}x)</em>` return `decrease <strong class='color-d'>damage</strong> by <strong>0.15x</strong> for each ${powerUps.orb.tech()} you have<br>increase <strong class='color-d'>damage</strong> by <strong>4x</strong><em style ="float: right;">(${(tech.totalCount > 20 ? (Math.pow(0.85, tech.totalCount - 20)) : (4 - 0.15 * tech.totalCount)).toFixed(2)}x)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6960,7 +6960,7 @@ const tech = {
}, },
{ {
name: "railgun", name: "railgun",
description: `<strong>hold</strong> and <strong>release</strong> fire key to launch <strong>harpoons</strong><br>but, <strong>harpoons</strong> can't <strong>retract</strong>`, description: `<strong>hold</strong> and <strong>release</strong> fire to launch <strong>harpoons</strong><br>but, <strong>harpoons</strong> can't <strong>retract</strong>`,
// description: `<strong>+900%</strong> <strong>harpoon</strong> <strong class='color-ammo'>ammo</strong>, but it can't <strong>retract</strong><br><strong>+50%</strong> <strong>harpoon</strong> density and <strong class='color-d'>damage</strong>`, // description: `<strong>+900%</strong> <strong>harpoon</strong> <strong class='color-ammo'>ammo</strong>, but it can't <strong>retract</strong><br><strong>+50%</strong> <strong>harpoon</strong> density and <strong class='color-d'>damage</strong>`,
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
@@ -7914,7 +7914,7 @@ const tech = {
// description: "molecular assembler <strong class='color-print'>prints</strong> one <strong class='color-block'>block</strong><br>to <strong>jump</strong> off while midair", // description: "molecular assembler <strong class='color-print'>prints</strong> one <strong class='color-block'>block</strong><br>to <strong>jump</strong> off while midair",
descriptionFunction() { descriptionFunction() {
const fieldName = m.fieldMode === 8 ? "pilot wave" : "molecular assembler" const fieldName = m.fieldMode === 8 ? "pilot wave" : "molecular assembler"
return `pressing the <strong>jump</strong> key in <strong>midair</strong><br>will <strong class='color-print'>print</strong> a <strong class='color-block'>block</strong> to <strong>jump</strong> off` return `pressing <strong>jump</strong> in <strong>midair</strong><br>will <strong class='color-print'>print</strong> a <strong class='color-block'>block</strong> to <strong>jump</strong> off`
// return `${fieldName} <strong class='color-print'>prints</strong> a <strong class='color-block'>block</strong><br>to <strong>jump</strong> off while midair` // return `${fieldName} <strong class='color-print'>prints</strong> a <strong class='color-block'>block</strong><br>to <strong>jump</strong> off while midair`
}, },
isFieldTech: true, isFieldTech: true,
@@ -8114,7 +8114,7 @@ const tech = {
}, },
{ {
name: "degenerate matter", name: "degenerate matter",
description: `if your ${powerUps.orb.field()} key is active<br><strong>0.1x</strong> <strong class='color-defense'>damage taken</strong>`, description: `if your ${powerUps.orb.field()} is active<br><strong>0.1x</strong> <strong class='color-defense'>damage taken</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,

View File

@@ -1,19 +1,10 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
replaced tech, field, and gun text with orbs new level: flocculation
orbs length scale with px->em
cleaned up simulation variables text in pause menu
some minor tech description changes
total tech count no longer includes instant tech or removed tech
tech: planned obsolescence - at the start of each level eject your oldest tech and gain 1.1 damage snakeBoss does 40% less damage to player
heuristics 1.3 -> between 1 and 1.5 fire rate
combinatorial optimization 1.35->1.4 damage
difficulty reduction per level
0.85->0.87x damage done
1.23->1.22 damage taken
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -25,8 +16,28 @@ fix door.isClosing actually meaning isClosed?
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
tech - at the start of each new level eject the oldest tech you have and gain 10% damage new snakeBoss type that eats mobs
each time it eats:
heal?
get shield if full?
make boss longer (if snake)
get shield
get orbitals
spawn spawns (little red square mobs)
when boss dies
spawn eaten mobs?
spawn generic mobs?
nothing
make snake new colors, width
Boss mob - takes a snapshot of the positions of all mobs, player, blocks, power ups. Then 3 seconds later it teleports everything back to those spots.
after snap shot is stored draw outline of body positions for a second to show the change
immune after snapshot? or immune after teleport?
Boss mob - records the position of mobs every few cycles
makes a ghost copy of the mob that is delayed by a few seconds
ghost can damage player, but doesn't have a matter.js object
gives mobs short snake tails, like snakeBoss
brings 1 mob back to life every few seconds
merge multiple power ups of the same type if nearby merge multiple power ups of the same type if nearby
@@ -72,10 +83,6 @@ rework energy and health HUD
how? not sure there is a good way to do this... how? not sure there is a good way to do this...
should health be red or green? should health be red or green?
Boss mob - takes a snapshot of the positions of all mobs, player, blocks, power ups. Then 3 seconds later it teleports everything back to those spots.
after snap shot is stored draw outline of body positions for a second to show the change
immune after snapshot? or immune after teleport?
flip player upside down flip player upside down
how how
rotate player in matter.js rotate player in matter.js