diff --git a/.DS_Store b/.DS_Store
index cf66128..49bb66f 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/level.js b/js/level.js
index 614c2dd..03f5767 100644
--- a/js/level.js
+++ b/js/level.js
@@ -379,6 +379,71 @@ const level = {
World.add(engine.world, constraint);
return constraint
},
+ elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
+ x += width / 2
+ y += height / 2
+ maxHeight += height / 2
+ const yTravel = maxHeight - y
+ force += simulation.g
+ const who = body[body.length] = Bodies.rectangle(x, y, width, height, {
+ collisionFilter: {
+ 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
+ },
+ inertia: Infinity, //prevents rotation
+ isNotHoldable: true,
+ friction: 1,
+ frictionStatic: 1,
+ restitution: 0,
+ frictionAir: 0.001,
+ move() {
+ 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: x,
+ 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
+ Matter.Body.setVelocity(this, { //slow down early to avoid a jerky stop that can pass through blocks
+ x: 0,
+ y: this.velocity.y * 0.7
+ });
+ if (this.position.y + this.velocity.y > y) { //switch to up mode
+ this.isUp = true
+ this.frictionAir = friction.up
+ }
+ }
+
+ }
+ // hold horizontal position
+ Matter.Body.setPosition(this, {
+ x: x,
+ y: this.position.y
+ });
+ Matter.Body.setVelocity(this, {
+ x: 0,
+ y: this.velocity.y
+ });
+ },
+ drawTrack() {
+ ctx.fillStyle = "#ccc"
+ ctx.fillRect(x, y, 5, yTravel)
+ }
+ });
+ Matter.Body.setDensity(who, 0.01) //10x density for added stability
+ return who
+ },
platform(x, y, width, height, speed = 0, density = 0.001) {
x = x + width / 2
y = y + height / 2
@@ -410,6 +475,7 @@ const level = {
speed: speed,
}
constraint.pauseUntilCycle = 0 //to to pause platform at top and bottom
+
return constraint
},
rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
@@ -1866,7 +1932,7 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
},
satellite() {
- const elevator = level.platform(4210, -1325, 380, 30, -10)
+ const elevator = level.elevator(4210, -1297, 380, 85, -3450) //, 0.003, { up: 0.01, down: 0.2 }
level.custom = () => {
ctx.fillStyle = "#d4f4f4"
ctx.fillRect(-250, -750, 420, 450)
@@ -1894,19 +1960,21 @@ const level = {
ctx.fillStyle = "rgba(0,20,40,0.1)"
ctx.fillRect(4000, -1200, 1050, 1500)
ctx.fillRect(4100, -3450, 600, 2250)
- if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) { //elevator move
- if (elevator.pointA.y > -1275) { //bottom
- elevator.plat.speed = -10
- elevator.pauseUntilCycle = simulation.cycle + 90
- } else if (elevator.pointA.y < -3455) { //top
- elevator.plat.speed = 30
- elevator.pauseUntilCycle = simulation.cycle + 90
- }
- elevator.pointA = {
- x: elevator.pointA.x,
- y: elevator.pointA.y + elevator.plat.speed
- }
- }
+ elevator.move()
+ // elevator.drawTrack() //looks ugly
+ // if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) { //elevator move
+ // if (elevator.pointA.y > -1275) { //bottom
+ // elevator.plat.speed = -10
+ // elevator.pauseUntilCycle = simulation.cycle + 90
+ // } else if (elevator.pointA.y < -3455) { //top
+ // elevator.plat.speed = 30
+ // elevator.pauseUntilCycle = simulation.cycle + 90
+ // }
+ // elevator.pointA = {
+ // x: elevator.pointA.x,
+ // y: elevator.pointA.y + elevator.plat.speed
+ // }
+ // }
};
level.setPosToSpawn(-100, 210); //normal spawn
@@ -2025,10 +2093,11 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3950, -850);
},
rooftops() {
- const elevator = level.platform(1450, -1000, 235, 30, -2)
+ const elevator = level.elevator(1450, -1000, 235, 50, -2000)
level.custom = () => {
- ctx.fillStyle = "#ccc"
- ctx.fillRect(1567, -1990, 5, 1020)
+ elevator.move();
+ elevator.drawTrack();
+
ctx.fillStyle = "#d4f4f4"
if (isBackwards) {
ctx.fillRect(-650, -2300, 440, 300)
@@ -2063,19 +2132,6 @@ const level = {
} else {
ctx.fillRect(-650, -2300, 440, 300)
}
- if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) { //elevator move
- if (elevator.pointA.y > -980) { //bottom
- elevator.plat.speed = -2
- elevator.pauseUntilCycle = simulation.cycle + 60
- } else if (elevator.pointA.y < -1980) { //top
- elevator.plat.speed = 1
- elevator.pauseUntilCycle = simulation.cycle + 60
- }
- elevator.pointA = {
- x: elevator.pointA.x,
- y: elevator.pointA.y + elevator.plat.speed
- }
- }
};
level.defaultZoom = 1700
@@ -2487,6 +2543,54 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3075, -2050);
},
highrise() {
+ const isBlockMode = false
+ let slideBlock
+ if (isBlockMode) {
+ const x = -2750
+ const yMax = -1500
+ slideBlock = body[body.length] = Bodies.rectangle(x, -700, 200, 100, {
+ collisionFilter: {
+ 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
+ },
+ inertia: Infinity, //prevents rotation
+ isNotHoldable: true,
+ friction: 1,
+ frictionStatic: 1,
+ frictionAir: 0.001,
+ // restitution: 0,
+ isUp: true,
+ move() {
+ if (this.isUp) {
+ if (this.position.y > yMax) {
+ this.force.y -= 0.01 * this.mass
+ } else {
+ this.isUp = false
+ Matter.Body.setPosition(this, {
+ x: x,
+ y: yMax
+ });
+ Matter.Body.setVelocity(this, {
+ x: 0,
+ y: 0
+ });
+ }
+ } else if (this.position.y > -800) {
+ this.isUp = true
+ }
+ },
+ holdHorizontal() {
+ Matter.Body.setPosition(this, {
+ x: x,
+ y: this.position.y
+ });
+ Matter.Body.setVelocity(this, {
+ x: 0,
+ y: this.velocity.y
+ });
+ }
+ });
+ }
level.custom = () => {
ctx.fillStyle = "#d0d0d2"
ctx.fillRect(-2475, -2450, 25, 750)
@@ -2498,24 +2602,43 @@ const level = {
level.exit.draw();
level.enter.draw();
};
- level.customTopLayer = () => {
- ctx.fillStyle = "rgba(64,64,64,0.97)" //hidden section
- ctx.fillRect(-4450, -750, 800, 200)
- ctx.fillStyle = "rgba(0,0,0,0.12)"
- ctx.fillRect(-1830, -1150, 2030, 1150)
- ctx.fillRect(-3410, -2150, 495, 1550)
- ctx.fillRect(-2585, -1675, 420, 1125)
- ctx.fillRect(-1640, -1575, 540, 425)
- ctx.fillStyle = "rgba(200,0,255,0.2)"; //boost
- ctx.fillRect(-750, -25, 100, 25);
- ctx.fillRect(-2800, -625, 100, 25);
- ctx.fillStyle = "rgba(200,0,255,0.1)"; //boost
- ctx.fillRect(-750, -55, 100, 55);
- ctx.fillRect(-2800, -655, 100, 55);
- ctx.fillStyle = "rgba(200,0,255,0.05)"; //boost
- ctx.fillRect(-750, -120, 100, 120);
- ctx.fillRect(-2800, -720, 100, 120);
- };
+ if (isBlockMode) {
+ level.customTopLayer = () => {
+ ctx.fillStyle = "rgba(64,64,64,0.97)" //hidden section
+ ctx.fillRect(-4450, -750, 800, 200)
+ ctx.fillStyle = "rgba(0,0,0,0.12)"
+ ctx.fillRect(-1830, -1150, 2030, 1150)
+ ctx.fillRect(-3410, -2150, 495, 1550)
+ ctx.fillRect(-2585, -1675, 420, 1125)
+ ctx.fillRect(-1640, -1575, 540, 425)
+ //move sliding block
+ slideBlock.move()
+ slideBlock.holdHorizontal() //keep horizontal position constant
+
+
+
+ };
+ } else {
+ level.customTopLayer = () => {
+ ctx.fillStyle = "rgba(64,64,64,0.97)" //hidden section
+ ctx.fillRect(-4450, -750, 800, 200)
+ ctx.fillStyle = "rgba(0,0,0,0.12)"
+ ctx.fillRect(-1830, -1150, 2030, 1150)
+ ctx.fillRect(-3410, -2150, 495, 1550)
+ ctx.fillRect(-2585, -1675, 420, 1125)
+ ctx.fillRect(-1640, -1575, 540, 425)
+ ctx.fillStyle = "rgba(200,0,255,0.2)"; //boost
+ ctx.fillRect(-750, -25, 100, 25);
+ ctx.fillRect(-2800, -625, 100, 25);
+ ctx.fillStyle = "rgba(200,0,255,0.1)"; //boost
+ ctx.fillRect(-750, -55, 100, 55);
+ ctx.fillRect(-2800, -655, 100, 55);
+ ctx.fillStyle = "rgba(200,0,255,0.05)"; //boost
+ ctx.fillRect(-750, -120, 100, 120);
+ ctx.fillRect(-2800, -720, 100, 120);
+ };
+ }
+
level.setPosToSpawn(-300, -700); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
@@ -2575,7 +2698,7 @@ const level = {
spawn.mapRect(-4450, -600, 2300, 750);
spawn.mapRect(-2225, -450, 175, 550);
// spawn.mapRect(-2600, -975, 450, 50);
- spawn.boost(-2800, -600, 950);
+ if (!isBlockMode) spawn.boost(-2800, -600, 950);
spawn.mapRect(-3425, -1325, 525, 50);
spawn.mapRect(-3425, -2200, 525, 50);
spawn.mapRect(-2600, -1700, 450, 50);
diff --git a/js/player.js b/js/player.js
index f2f45d1..2887a2a 100644
--- a/js/player.js
+++ b/js/player.js
@@ -264,10 +264,11 @@ const m = {
x: 0,
y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5)
});
+
player.force.y = -m.jumpForce; //player jump force
Matter.Body.setVelocity(player, { //zero player y-velocity for consistent jumps
x: player.velocity.x,
- y: 0
+ y: Math.max(-10, Math.min(m.standingOn.velocity.y, 10)) //cap velocity contribution from blocks you are standing on to 10 in the vertical
});
}
@@ -1632,14 +1633,14 @@ const m = {
// m.fieldMeterColor = "#0c5"
// m.eyeFillColor = m.fieldMeterColor
m.hold = function() {
- if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) {
+ if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) {
if (tech.isSporeField) {
- for (let i = 0; i < 30; i++) {
- m.energy -= 0.088
+ for (let i = 0, len = Math.random() * 20; i < len; i++) {
+ m.energy -= 0.085
if (m.energy > 0) {
b.spore(m.pos)
} else {
- m.energy = 0.01
+ m.energy = 0.001
break;
}
}
diff --git a/js/tech.js b/js/tech.js
index d1f3a14..b877673 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -665,6 +665,23 @@
// tech.isOneBullet = false
// }
// },
+ {
+ name: "fracture analysis",
+ description: "bullet impacts do 400% damage
to stunned mobs",
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ allowed() {
+ return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isExplosionStun
+ },
+ requires: "a stun effect",
+ effect() {
+ tech.isCrit = true;
+ },
+ remove() {
+ tech.isCrit = false;
+ }
+ },
{
name: "microstates",
description: "increase damage by 4%
for every 10 active bullets",
@@ -1856,20 +1873,25 @@
}
},
{
- name: "fracture analysis",
- description: "bullet impacts do 400% damage
to stunned mobs",
+ name: "MACHO",
+ description: "a massive but compact object slowly follows you
take 66% less harm inside it's halo",
maxCount: 1,
count: 0,
- frequency: 2,
+ frequency: 1,
+ frequencyDefault: 1,
allowed() {
- return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isExplosionStun
+ return true
},
- requires: "a stun effect",
- effect() {
- tech.isCrit = true;
+ requires: "",
+ effect: () => {
+ tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO
+ spawn.MACHO()
},
remove() {
- tech.isCrit = false;
+ tech.isMACHO = false;
+ for (let i = 0, len = mob.length; i < len; i++) {
+ if (mob[i].isMACHO) mob[i].alive = false;
+ }
}
},
{
@@ -2735,28 +2757,6 @@
tech.wimpCount = 0
}
},
- {
- name: "MACHO",
- description: "a massive but compact object slowly follows you
take 66% less harm inside it's halo",
- maxCount: 1,
- count: 0,
- frequency: 1,
- frequencyDefault: 1,
- allowed() {
- return true
- },
- requires: "",
- effect: () => {
- tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO
- spawn.MACHO()
- },
- remove() {
- tech.isMACHO = false;
- for (let i = 0, len = mob.length; i < len; i++) {
- if (mob[i].isMACHO) mob[i].alive = false;
- }
- }
- },
{
name: "bubble fusion",
description: "after destroying a mob's natural shield
spawn 1-2 heals, ammo, or research",
@@ -2795,7 +2795,7 @@
},
{
name: "replication",
- description: "8% chance to duplicate spawned power ups
add 14 JUNK tech to the potential pool",
+ description: "8% chance to duplicate spawned power ups
add 18 JUNK tech to the potential pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -2807,12 +2807,12 @@
effect() {
tech.duplicateChance += 0.08
powerUps.setDo(); //needed after adjusting duplication chance
- tech.addJunkTechToPool(14)
+ tech.addJunkTechToPool(18)
},
remove() {
tech.duplicateChance = 0
powerUps.setDo(); //needed after adjusting duplication chance
- if (this.count > 1) tech.removeJunkTechFromPool(14)
+ if (this.count > 1) tech.removeJunkTechFromPool(18)
}
},
{
@@ -3230,7 +3230,7 @@
},
{
name: "dark patterns",
- description: "reduce combat difficulty by 1 level
add 18 JUNK tech to the potential pool",
+ description: "reduce combat difficulty by 1 level
add 21 JUNK tech to the potential pool",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3243,12 +3243,12 @@
level.difficultyDecrease(simulation.difficultyMode)
// simulation.difficulty-=
simulation.makeTextLog(`level.difficultyDecrease(simulation.difficultyMode)`)
- tech.addJunkTechToPool(18)
+ tech.addJunkTechToPool(21)
// for (let i = 0; i < tech.junk.length; i++) tech.tech.push(tech.junk[i])
},
remove() {
if (this.count > 0) {
- tech.removeJunkTechFromPool(18)
+ tech.removeJunkTechFromPool(21)
level.difficultyIncrease(simulation.difficultyMode)
}
}
diff --git a/todo.txt b/todo.txt
index b1209a9..63e7c84 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,12 +1,14 @@
******************************************************** NEXT PATCH ********************************************************
-tech: MACHO - an object follows you and gives you harm protection when you are inside it's halo
+jump now applies the velocity of the block you jumped off of
+ it might feel slightly different if you play n-gon often
+ it could add some bugs so let me know
-several nano-scale field tech now require some research, and have been buffed
- nano-scale mycelium, ice-IX, missile tech now consume 20% less energy to produce bullets
- nano-scale bot tech: spawn an extra bots
-
-some bug fixes
+elevators have more realistic physics
+ you can jump off them when they get to the top (fun!)
+ blocks interact with them in a more healthy way (no bleed through)
+ they can have a wider range of healthy speeds
+ it can hurt mobs
******************************************************** BUGS ********************************************************
@@ -52,6 +54,23 @@ is there a way to check if the player is stuck inside the map or block
******************************************************** TODO ********************************************************
+platform: jumps a bit before moving up
+ you can't use set position for y, because blocks drag a bit inside the platform
+ get delays working right
+ do something if the force is overwhelmed so much the platform moves backwards, or below lower/upper range
+ apply a constraint when still and remove it when moving
+ also apply thr constraint if the block goes outside normal bounds by too much
+
+should jump velocity add to current velocity?
+ maybe only add the velocity of what the player is standing on
+
+mob: molecule shapes - 2 separate mobs joined by a bond
+ use constraints: just spawn 2x or 3x groupings
+ low friction so they can spin around
+ spin when attacking player?
+ increase constraint length when attacking
+
+
make nano-scale upgrades all cost research, and buff those tech
make most future tech for guns / fields