elevators
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 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
This commit is contained in:
185
js/level.js
185
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,6 +2602,23 @@ const level = {
|
||||
level.exit.draw();
|
||||
level.enter.draw();
|
||||
};
|
||||
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)
|
||||
@@ -2516,6 +2637,8 @@ const level = {
|
||||
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);
|
||||
|
||||
11
js/player.js
11
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;
|
||||
}
|
||||
}
|
||||
|
||||
72
js/tech.js
72
js/tech.js
@@ -665,6 +665,23 @@
|
||||
// tech.isOneBullet = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "fracture analysis",
|
||||
description: "bullet impacts do <strong>400%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> 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 <strong class='color-d'>damage</strong> by <strong>4%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>",
|
||||
@@ -1856,20 +1873,25 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "fracture analysis",
|
||||
description: "bullet impacts do <strong>400%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> mobs",
|
||||
name: "MACHO",
|
||||
description: "a massive but compact object slowly <strong>follows</strong> you<br>take <strong>66%</strong> less <strong class='color-harm'>harm</strong> inside it's <strong>halo</strong>",
|
||||
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 <strong>follows</strong> you<br>take <strong>66%</strong> less <strong class='color-harm'>harm</strong> inside it's <strong>halo</strong>",
|
||||
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 <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
|
||||
@@ -2795,7 +2795,7 @@
|
||||
},
|
||||
{
|
||||
name: "replication",
|
||||
description: "<strong>8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>14</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||
description: "<strong>8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>18</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> 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 <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>18</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>21</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3243,12 +3243,12 @@
|
||||
level.difficultyDecrease(simulation.difficultyMode)
|
||||
// simulation.difficulty<span class='color-symbol'>-=</span>
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
31
todo.txt
31
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
|
||||
|
||||
Reference in New Issue
Block a user