labs 2/6 done
tech: chain reaction - blocks caught in explosions, explode
tech: shock wave reduces explosion damage by 30% (was 40%)
slime hazards now draw themselves in hazard.query()
I updated all the maps to remove hazard.draw()
but maybe I missed one let me know if you find a buggy slime
laser hazards also draw themselves in hazard.opticalQuery()
2/6 rooms for new level.labs() are completed
This commit is contained in:
18
js/bullet.js
18
js/bullet.js
@@ -302,7 +302,7 @@ const b = {
|
||||
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
|
||||
radius *= tech.explosiveRadius
|
||||
let dist, sub, knock;
|
||||
let dmg = radius * 0.013 * (tech.isExplosionStun ? 0.6 : 1);
|
||||
let dmg = radius * 0.013 * (tech.isExplosionStun ? 0.7 : 1);
|
||||
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
|
||||
if (tech.isSmallExplosion) {
|
||||
color = "rgba(255,0,30,0.7)"
|
||||
@@ -387,20 +387,32 @@ const b = {
|
||||
}
|
||||
|
||||
//body knock backs
|
||||
for (let i = 0, len = body.length; i < len; ++i) {
|
||||
if (body[i].isNotHoldable) continue
|
||||
for (let i = body.length - 1; i > -1; i--) {
|
||||
if (!body[i].isNotHoldable) {
|
||||
sub = Vector.sub(where, body[i].position);
|
||||
dist = Vector.magnitude(sub);
|
||||
if (dist < radius) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.022);
|
||||
body[i].force.x += knock.x;
|
||||
body[i].force.y += knock.y;
|
||||
if (tech.isBlockExplode) {
|
||||
if (body[i] === m.holdingTarget) m.drop()
|
||||
const size = 20 + 350 * Math.pow(body[i].mass, 0.25)
|
||||
const where = body[i].position
|
||||
const onLevel = level.onLevel //prevent explosions in the next level
|
||||
Matter.World.remove(engine.world, body[i]);
|
||||
body.splice(i, 1);
|
||||
setTimeout(() => {
|
||||
if (onLevel === level.onLevel) b.explosion(where, size); //makes bullet do explosive damage at end
|
||||
}, 150 + 300 * Math.random());
|
||||
}
|
||||
} else if (dist < alertRange) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.011);
|
||||
body[i].force.x += knock.x;
|
||||
body[i].force.y += knock.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//power up knock backs
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
|
||||
@@ -41,8 +41,8 @@ function playerOnGroundCheck(event) {
|
||||
m.yOff = m.yOffWhen.jump;
|
||||
m.hardLandCD = m.cycle + Math.min(momentum / 6.5 - 6, 40)
|
||||
//falling damage
|
||||
if (tech.isFallingDamage && m.immuneCycle < m.cycle) {
|
||||
m.damage(Math.min(Math.sqrt(momentum - 123) * 0.01, 0.25));
|
||||
if (tech.isFallingDamage && m.immuneCycle < m.cycle && momentum > 150) {
|
||||
m.damage(Math.min(Math.sqrt(momentum - 133) * 0.01, 0.25));
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
}
|
||||
} else {
|
||||
|
||||
420
js/level.js
420
js/level.js
@@ -12,17 +12,15 @@ const level = {
|
||||
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.zoomScale = 1000;
|
||||
// simulation.setZoom();
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// level.difficultyIncrease(30)
|
||||
// m.setField("standing wave harmonics")
|
||||
// tech.giveTech("spherical harmonics")
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||
// b.giveGuns("super balls")
|
||||
// b.giveGuns("grenades")
|
||||
// tech.isExplodeRadio = true
|
||||
// tech.giveTech("Z-pinch")
|
||||
// tech.giveTech("chain reaction")
|
||||
// tech.giveTech("MACHO")
|
||||
// tech.giveTech("supertemporal")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||
@@ -31,6 +29,7 @@ const level = {
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
|
||||
|
||||
level.intro(); //starting level
|
||||
// level.labs();
|
||||
// level.testing(); //not in rotation, used for testing
|
||||
// level.template(); //not in rotation, blank start new map development
|
||||
// level.final() //final boss level
|
||||
@@ -273,7 +272,7 @@ const level = {
|
||||
World.add(engine.world, map[i]); //add to world
|
||||
}
|
||||
},
|
||||
spinner(x, y, width, height, density = 0.001) {
|
||||
spinner(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0) {
|
||||
x = x + width / 2
|
||||
y = y + height / 2
|
||||
const who = body[body.length] = Bodies.rectangle(x, y, width, height, {
|
||||
@@ -282,11 +281,14 @@ const level = {
|
||||
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
|
||||
},
|
||||
isNotHoldable: true,
|
||||
frictionAir: 0.001,
|
||||
frictionAir: frictionAir,
|
||||
friction: 1,
|
||||
frictionStatic: 1,
|
||||
restitution: 0,
|
||||
});
|
||||
Matter.Body.setAngle(who, angle)
|
||||
Matter.Body.setAngularVelocity(who, angularVelocity);
|
||||
|
||||
|
||||
Matter.Body.setDensity(who, density)
|
||||
const constraint = Constraint.create({ //fix rotor in place, but allow rotation
|
||||
@@ -547,13 +549,13 @@ const level = {
|
||||
composite[composite.length] = rotor
|
||||
return rotor
|
||||
},
|
||||
toggle(x, y, isLockOn = false) {
|
||||
toggle(x, y, isOn = false, isLockOn = false) {
|
||||
spawn.mapVertex(x + 65, y + 2, "70 10 -70 10 -40 -10 40 -10");
|
||||
map[map.length - 1].restitution = 0;
|
||||
map[map.length - 1].friction = 1;
|
||||
map[map.length - 1].frictionStatic = 1;
|
||||
|
||||
spawn.bodyRect(x, y, 125, 15) //Portal platform
|
||||
spawn.bodyRect(x, y - 5, 120, 15) //Portal platform
|
||||
let flip = body[body.length - 1];
|
||||
flip.isNoSetCollision = true //prevents collision form being rewritten in level.addToWorld
|
||||
flip.collisionFilter.category = cat.body
|
||||
@@ -563,13 +565,20 @@ const level = {
|
||||
flip.frictionAir = 0.01
|
||||
flip.restitution = 0
|
||||
Matter.Body.setDensity(flip, 0.003)
|
||||
if (isOn) {
|
||||
Matter.Body.setAngle(flip, (0.25 - 0.5) * Math.PI)
|
||||
} else {
|
||||
Matter.Body.setAngle(flip, (-0.25 - 0.5) * Math.PI)
|
||||
setTimeout(function() {}, 100);
|
||||
}
|
||||
|
||||
// setTimeout(function() {
|
||||
|
||||
// }, 100);
|
||||
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: x + 65,
|
||||
y: y
|
||||
y: y - 5
|
||||
},
|
||||
bodyB: flip,
|
||||
stiffness: 1,
|
||||
@@ -580,7 +589,7 @@ const level = {
|
||||
|
||||
return {
|
||||
flip: flip,
|
||||
isOn: false,
|
||||
isOn: isOn,
|
||||
query() {
|
||||
const limit = {
|
||||
right: (-0.25 - 0.5) * Math.PI,
|
||||
@@ -923,7 +932,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
},
|
||||
hazard(x, y, width, height, damage = 0.003, color = "hsla(160, 100%, 35%,0.75)") {
|
||||
hazard(x, y, width, height, damage = 0.003) {
|
||||
return {
|
||||
min: {
|
||||
x: x,
|
||||
@@ -938,7 +947,12 @@ const level = {
|
||||
maxHeight: height,
|
||||
isOn: true,
|
||||
opticalQuery() {
|
||||
if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) {
|
||||
if (this.isOn) {
|
||||
//draw
|
||||
ctx.fillStyle = `hsla(0, 100%, 50%,${0.6+0.4*Math.random()})`
|
||||
ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
|
||||
//collision with player
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) {
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
|
||||
m.damage(damage)
|
||||
@@ -951,9 +965,15 @@ const level = {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
query() {
|
||||
if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
if (this.isOn) {
|
||||
ctx.fillStyle = "hsla(160, 100%, 35%,0.75)"
|
||||
const offset = 5 * Math.sin(simulation.cycle * 0.015)
|
||||
ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset)
|
||||
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
const drain = 0.003 + m.fieldRegen
|
||||
if (m.energy > drain) {
|
||||
m.energy -= drain
|
||||
@@ -991,20 +1011,14 @@ const level = {
|
||||
y: 0.95 * powerUpCollide[i].velocity.y
|
||||
});
|
||||
}
|
||||
},
|
||||
draw() {
|
||||
if (this.isOn) {
|
||||
ctx.fillStyle = color
|
||||
ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
|
||||
}
|
||||
},
|
||||
drawTides() {
|
||||
if (this.isOn) {
|
||||
ctx.fillStyle = color
|
||||
const offset = 10 * Math.sin(simulation.cycle * 0.015)
|
||||
ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset)
|
||||
}
|
||||
},
|
||||
// draw() {
|
||||
// if (this.isOn) {
|
||||
// ctx.fillStyle = color
|
||||
// ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
|
||||
// }
|
||||
// },
|
||||
level(isFill) {
|
||||
if (!m.isBodiesAsleep) {
|
||||
const growSpeed = 1
|
||||
@@ -1071,6 +1085,282 @@ const level = {
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
labs() {
|
||||
// level.difficultyIncrease(30)
|
||||
level.defaultZoom = 1800
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#dcdcdf";
|
||||
// document.body.style.backgroundColor = "#d5d5d5";
|
||||
let isDoorLeft, isDoorRight, x, y
|
||||
doCustom = []
|
||||
doCustomTopLayer = []
|
||||
offset = { x: 0, y: 0 }
|
||||
enterOptions = [
|
||||
() => { //lasers
|
||||
const x = offset.x
|
||||
const y = offset.y
|
||||
level.setPosToSpawn(x + 2300, y - 800);
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
spawn.mapRect(x + 1450, y - 750, 1300, 50); //entrance shelf
|
||||
spawn.mapRect(x + 1850, y - 1350, 50, 450); //entrance left wall
|
||||
spawn.bodyRect(x + 1860, y - 900, 30, 150); //entrance door
|
||||
|
||||
spawn.mapRect(x + 2000, y - 350, 750, 150); //toggle shelf
|
||||
const toggle = level.toggle(x + 2050, y - 350, true) //(x,y,isOn,isLockOn = true/false)
|
||||
|
||||
const hazard = level.hazard(x + 1040, y - 660, 1700, 10, 0.4) //laser
|
||||
spawn.mapRect(x + 1050, y - 665, 10, 20); //laser nose
|
||||
spawn.mapRect(x + 650, y - 705, 400, 100); //laser body
|
||||
const hazard2 = level.hazard(x - 150, y - 330, 600, 10, 0.4) //laser
|
||||
spawn.mapRect(x + 440, y - 335, 10, 20); //laser nose
|
||||
spawn.mapRect(x + 450, y - 375, 400, 100); //laser body
|
||||
//exit hazards
|
||||
const Xoffset = Math.floor(400 * Math.random())
|
||||
const hazard3 = level.hazard(x + Xoffset, y - 1300, 10, 1300, 0.4) //laser
|
||||
spawn.mapRect(x + Xoffset - 5, y - 1310, 20, 20); //laser nose
|
||||
const hazard4 = level.hazard(x + 2100, y - 200, 10, 200, 0.4) //laser
|
||||
spawn.mapRect(x + 2100 - 5, y - 210, 20, 20); //laser nose
|
||||
|
||||
spawn.randomSmallMob(x + 2225, y - 100);
|
||||
spawn.randomMob(x + 0, y - 125, 0);
|
||||
spawn.randomMob(x + 650, y - 100, 0.5);
|
||||
spawn.randomGroup(x + 1300, y - 250, 0.1);
|
||||
// spawn.randomSmallMob(1300, -70);
|
||||
// spawn.randomMob(2650, -975, 0.8);
|
||||
// spawn.randomGroup(1700, -900, 0.4);
|
||||
doCustomTopLayer.push(
|
||||
() => {
|
||||
toggle.query();
|
||||
hazard.isOn = toggle.isOn
|
||||
hazard2.isOn = toggle.isOn
|
||||
hazard3.isOn = toggle.isOn
|
||||
hazard4.isOn = toggle.isOn
|
||||
hazard.opticalQuery();
|
||||
hazard2.opticalQuery();
|
||||
hazard3.opticalQuery();
|
||||
hazard4.opticalQuery();
|
||||
}
|
||||
)
|
||||
|
||||
},
|
||||
// () => {
|
||||
// level.setPosToSpawn(x + 1250, y - 50);
|
||||
// spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
// }
|
||||
]
|
||||
exitOptions = [
|
||||
() => { //9 spinners
|
||||
const x = offset.x
|
||||
const y = offset.y
|
||||
level.exit.x = x + 1250;
|
||||
level.exit.y = y - 980;
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
|
||||
spawn.mapRect(x + 1050, y - 950, 500, 25); //exit platform
|
||||
spawn.mapRect(x + 1100, y - 1300, 25, 175); //exit side wall
|
||||
spawn.mapRect(x + 1475, y - 1300, 25, 175); //exit side wall
|
||||
if (0.33 < Math.random()) { //center large stage
|
||||
spawn.mapRect(x + 1050, y - 350, 500, 400);
|
||||
} else if (0.5 < Math.random()) {
|
||||
spawn.mapVertex(x + 1300, y - 310, "-300 0 -250 -425 250 -425 300 0");
|
||||
} else {
|
||||
spawn.mapVertex(x + 1300, y - 125, "-400 0 -250 -400 250 -400 400 0");
|
||||
}
|
||||
|
||||
spawn.bodyRect(x + 1275, y - 475, 125, 125, 0.25);
|
||||
spawn.bodyRect(x + 1825, y - 125, 125, 125, 0.25);
|
||||
spawn.bodyRect(x + 500, y - 100, 125, 100, 0.25);
|
||||
spawn.bodyRect(x + 0, y - 150, 100, 150, 0.25);
|
||||
spawn.bodyRect(x + 2375, y - 150, 125, 150, 0.25);
|
||||
spawn.bodyRect(x + 1075, y - 1075, 100, 125, 0.25);
|
||||
spawn.bodyRect(x + 1450, y - 1050, 100, 100, 0.25);
|
||||
|
||||
const density = 0.001
|
||||
const angle = 0
|
||||
const variance = Math.PI
|
||||
const frictionAir = 0
|
||||
const angularVelocity = 0.01
|
||||
const spinVariance = 0.02
|
||||
|
||||
balance1 = level.spinner(x + 150, y - 600, 25, 410, 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 + 300, y - 1000, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
balance3 = level.spinner(x + 650, y - 750, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
balance4 = level.spinner(x + 800, y - 1150, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
|
||||
balance5 = level.spinner(x + 1770, y - 1150, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
balance6 = level.spinner(x + 1930, y - 750, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
balance7 = level.spinner(x + 2270, y - 1000, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
balance8 = level.spinner(x + 2410, y - 600, 25, 410, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
|
||||
|
||||
spawn.randomMob(x + 1175, y - 725, 0.1);
|
||||
spawn.randomMob(x + 1450, y - 725, 0.2);
|
||||
spawn.randomMob(x + 425, y - 100, 0.3);
|
||||
spawn.randomMob(x + 2300, y - 125, 0.4);
|
||||
spawn.randomMob(x + 1300, y - 375, 0.5);
|
||||
|
||||
doCustom.push(
|
||||
() => {
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
ctx.fillRect(x + 1100, y - 1300, 400, 350)
|
||||
}
|
||||
)
|
||||
doCustomTopLayer.push(
|
||||
() => {
|
||||
ctx.fillStyle = "#233"
|
||||
ctx.beginPath();
|
||||
ctx.arc(balance1.pointA.x, balance1.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance2.pointA.x, balance2.pointA.y)
|
||||
ctx.arc(balance2.pointA.x, balance2.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance3.pointA.x, balance3.pointA.y)
|
||||
ctx.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance4.pointA.x, balance4.pointA.y)
|
||||
ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance5.pointA.x, balance5.pointA.y)
|
||||
ctx.arc(balance5.pointA.x, balance5.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance6.pointA.x, balance6.pointA.y)
|
||||
ctx.arc(balance6.pointA.x, balance6.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance7.pointA.x, balance7.pointA.y)
|
||||
ctx.arc(balance7.pointA.x, balance7.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance8.pointA.x, balance8.pointA.y)
|
||||
ctx.arc(balance8.pointA.x, balance8.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
}
|
||||
)
|
||||
}
|
||||
]
|
||||
emptyOptions = [ //nothing good here
|
||||
() => {
|
||||
const x = offset.x
|
||||
const y = offset.y
|
||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 1250, y - 600);
|
||||
}
|
||||
]
|
||||
lootOptions = [ //has some power up reward //field, ammo, research, gun
|
||||
() => {
|
||||
const x = offset.x
|
||||
const y = offset.y
|
||||
powerUps.spawnStartingPowerUps(x + 1250, y - 100);
|
||||
}
|
||||
]
|
||||
upDownOptions = [ //extra tall vertical section 3000x3000 //this is where the level boss is
|
||||
() => {
|
||||
const x = offset.x
|
||||
const y = offset.y
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(x + 1250, y - 600);
|
||||
|
||||
}
|
||||
]
|
||||
//pick which type of room spawns
|
||||
enter = enterOptions[Math.floor(Math.random() * enterOptions.length)];
|
||||
exit = exitOptions[Math.floor(Math.random() * exitOptions.length)];
|
||||
empty = emptyOptions[Math.floor(Math.random() * emptyOptions.length)];
|
||||
loot = lootOptions[Math.floor(Math.random() * lootOptions.length)];
|
||||
upDown = upDownOptions[Math.floor(Math.random() * upDownOptions.length)];
|
||||
|
||||
//3x2: 4 short rooms (3000x1500), 1 double tall room (3000x3000)
|
||||
//rooms
|
||||
let rooms = ["enter", "empty", "loot", "exit"]
|
||||
rooms = shuffle(rooms); //shuffles array order
|
||||
//look... you and I both know there is a better way to do this, but it works so I'm gonna focus on other things
|
||||
while ( //makes sure that the exit and entrance aren't both on the same floor
|
||||
(rooms[0] === "enter" && rooms[2] === "exit") ||
|
||||
(rooms[2] === "enter" && rooms[0] === "exit") ||
|
||||
(rooms[1] === "enter" && rooms[3] === "exit") ||
|
||||
(rooms[3] === "enter" && rooms[1] === "exit")
|
||||
) rooms = shuffle(rooms); //shuffles array order
|
||||
for (let i = 0; i < rooms.length; i++) {
|
||||
if (rooms[i] === "enter") rooms[i] = enter
|
||||
if (rooms[i] === "exit") rooms[i] = exit
|
||||
if (rooms[i] === "empty") rooms[i] = empty
|
||||
if (rooms[i] === "loot") rooms[i] = loot
|
||||
}
|
||||
//*********************************DON"T RUN THIS LINE IN THE FINAL VERSION ***************************************
|
||||
rooms = [exit, enter, empty, loot] //this is used to control what level spawns while building
|
||||
|
||||
outlineDoors = () => {
|
||||
spawn.mapRect(offset.x - 200, offset.y, 3000, 100); //floor
|
||||
spawn.mapRect(offset.x - 200, offset.y - 1400, 3000, 100); //ceiling
|
||||
if (!isDoorLeft) spawn.mapRect(offset.x - 200, offset.y - 1400, 100, 1500); //left wall
|
||||
if (isDoorRight) { //if door only add wall on right side
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 1400, 100, 1225); //right wall
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 10, 100, 20); //right doorstep
|
||||
const doorWidth = 15 + Math.floor(100 * Math.random() * Math.random())
|
||||
spawn.bodyRect(offset.x + 2750 - doorWidth / 2, offset.y - 175, doorWidth, 165); //block door
|
||||
} else {
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 1400, 100, 1500); //right wall
|
||||
}
|
||||
}
|
||||
outlineUpDown = () => {
|
||||
spawn.mapRect(offset.x - 200, offset.y + 1400, 3000, 100); //floor
|
||||
spawn.mapRect(offset.x - 200, offset.y - 1400, 3000, 100); //ceiling
|
||||
if (!isDoorLeft) spawn.mapRect(offset.x - 200, offset.y - 1400, 100, 2800); //left wall
|
||||
if (isDoorRight) { //if door only add wall on right side
|
||||
//upper door
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 1400, 100, 1225); //right wall
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 10, 100, 20); //right doorstep
|
||||
const doorWidth = 15 + Math.floor(100 * Math.random() * Math.random())
|
||||
spawn.bodyRect(offset.x + 2750 - doorWidth / 2, offset.y - 175, doorWidth, 165); //block door
|
||||
//lower door
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 1400 + 1400, 100, 1225); //right wall
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 10 + 1400, 100, 20); //right doorstep
|
||||
const doorWidth2 = 15 + Math.floor(100 * Math.random() * Math.random())
|
||||
spawn.bodyRect(offset.x + 2750 - doorWidth2 / 2, offset.y - 175 + 1400, doorWidth2, 165); //block door
|
||||
} else {
|
||||
spawn.mapRect(offset.x + 2700, offset.y - 1400, 100, 2800); //right wall
|
||||
}
|
||||
}
|
||||
|
||||
let rows = [
|
||||
() => {
|
||||
offset.y = 0
|
||||
rooms[0]()
|
||||
outlineDoors()
|
||||
|
||||
offset.y = -1400
|
||||
rooms[1]()
|
||||
outlineDoors()
|
||||
},
|
||||
() => {
|
||||
offset.y = -1400
|
||||
upDown()
|
||||
outlineUpDown()
|
||||
},
|
||||
() => {
|
||||
offset.y = 0
|
||||
rooms[2]()
|
||||
outlineDoors()
|
||||
|
||||
offset.y = -1400
|
||||
rooms[3]()
|
||||
outlineDoors()
|
||||
}
|
||||
]
|
||||
//*********************************RUN THIS LINE IN THE FINAL VERSION ***************************************
|
||||
// rows = shuffle(rows)
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (i === 0) {
|
||||
isDoorLeft = false
|
||||
isDoorRight = true
|
||||
} else if (i === 1) {
|
||||
isDoorLeft = true
|
||||
isDoorRight = true
|
||||
} else {
|
||||
isDoorLeft = true
|
||||
isDoorRight = false
|
||||
}
|
||||
offset.x = i * 2900
|
||||
rows[i]()
|
||||
}
|
||||
level.custom = () => {
|
||||
for (let i = 0, len = doCustom.length; i < len; i++) doCustom[i]() //runs all the active code from each room
|
||||
level.playerExitCheck();
|
||||
level.exit.draw();
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
for (let i = 0, len = doCustomTopLayer.length; i < len; i++) doCustomTopLayer[i]() //runs all the active code from each room
|
||||
};
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
null() {
|
||||
level.levels.pop(); //remove lore level from rotation
|
||||
//start a conversation based on the number of conversations seen
|
||||
@@ -1121,7 +1411,7 @@ const level = {
|
||||
level.customTopLayer = () => {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)";
|
||||
ctx.fillRect(-1950, -950, 3900, 1900);
|
||||
hazardSlime.drawTides();
|
||||
// hazardSlime.drawTides();
|
||||
|
||||
//draw center circle lines
|
||||
ctx.beginPath();
|
||||
@@ -1635,8 +1925,10 @@ const level = {
|
||||
spawn.mapRect(1225, -1955, 175, 30);
|
||||
const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
|
||||
let portal, portal2, portal3
|
||||
const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser
|
||||
const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser
|
||||
const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4) //laser
|
||||
spawn.mapRect(340, -2032.5, 20, 25); //laser nose
|
||||
const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4) //laser
|
||||
spawn.mapRect(1920, -2557.5, 20, 25); //laser nose
|
||||
const button = level.button(2100, -2600)
|
||||
const buttonDoor = level.button(600, -550)
|
||||
const door = level.door(312, -750, 25, 190, 185)
|
||||
@@ -1680,8 +1972,7 @@ const level = {
|
||||
portal2[3].query()
|
||||
portal3[2].query()
|
||||
portal3[3].query()
|
||||
hazard.opticalQuery();
|
||||
hazard2.opticalQuery();
|
||||
|
||||
if (button.isUp) {
|
||||
hazard.isOn = false;
|
||||
hazard2.isOn = false;
|
||||
@@ -1700,8 +1991,8 @@ const level = {
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
door.draw();
|
||||
hazard.draw();
|
||||
hazard2.draw();
|
||||
hazard.opticalQuery();
|
||||
hazard2.opticalQuery();
|
||||
portal[0].draw();
|
||||
portal[1].draw();
|
||||
portal[2].draw();
|
||||
@@ -1899,8 +2190,7 @@ const level = {
|
||||
|
||||
button1.query();
|
||||
button1.draw();
|
||||
hazard.query();
|
||||
hazard.level(button1.isUp)
|
||||
|
||||
rotor.rotate();
|
||||
|
||||
ctx.fillStyle = "hsl(175, 15%, 76%)"
|
||||
@@ -1919,9 +2209,11 @@ const level = {
|
||||
ctx.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance4.pointA.x, balance4.pointA.y)
|
||||
ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.moveTo(balance5.pointA.x, balance5.pointA.y)
|
||||
ctx.arc(balance5.pointA.x, balance5.pointA.y, 9, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
|
||||
hazard.draw();
|
||||
hazard.query();
|
||||
hazard.level(button1.isUp)
|
||||
};
|
||||
|
||||
level.setPosToSpawn(0, -50); //normal spawn
|
||||
@@ -2031,6 +2323,8 @@ const level = {
|
||||
balance2 = level.spinner(-2605 - 390, 500, 390, 25, 0.001) //falling
|
||||
balance3 = level.spinner(-2608 - 584, 1900, 584, 25, 0.001) //falling
|
||||
balance4 = level.spinner(-9300 - 25, 2205, 25, 380, 0.001) //exit
|
||||
balance5 = level.spinner(-2605 - 390, 1100, 390, 25, 0.001) //falling
|
||||
|
||||
// boost1.boostBounds.min.x = -boost1.boostBounds.min.x - 100
|
||||
// boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100
|
||||
// level.setPosToSpawn(300, -700); //-x // no need since 0
|
||||
@@ -2063,6 +2357,7 @@ const level = {
|
||||
balance2 = level.spinner(2605, 500, 390, 25, 0.001) //falling
|
||||
balance3 = level.spinner(2608, 1900, 584, 25, 0.001) //falling
|
||||
balance4 = level.spinner(9300, 2205, 25, 380, 0.001) //exit
|
||||
balance5 = level.spinner(2605, 1100, 390, 25, 0.001) //falling
|
||||
}
|
||||
|
||||
},
|
||||
@@ -2805,12 +3100,12 @@ const level = {
|
||||
const elevator1 = level.elevator(-790, -190, 180, 25, -1150) //, 0.007
|
||||
elevator1.addConstraint();
|
||||
// const button1 = level.button(-500, -200)
|
||||
const toggle1 = level.toggle(-500, -200) //(x,y,isLockOn = true/false)
|
||||
const toggle1 = level.toggle(-500, -200) //(x,y,isOn,isLockOn = true/false)
|
||||
|
||||
const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007
|
||||
elevator2.addConstraint();
|
||||
// const button2 = level.button(-3100, -1330)
|
||||
const toggle2 = level.toggle(-3100, -1330) //(x,y,isLockOn = true/false)
|
||||
const toggle2 = level.toggle(-3100, -1330) //(x,y,isOn, isLockOn = true/false)
|
||||
|
||||
|
||||
level.custom = () => {
|
||||
@@ -2958,7 +3253,7 @@ const level = {
|
||||
|
||||
spawn.bodyRect(-3410, -1425, 100, 100);
|
||||
spawn.bodyRect(-3390, -1525, 100, 100);
|
||||
spawn.bodyRect(-3245, -1425, 100, 100);
|
||||
// spawn.bodyRect(-3245, -1425, 100, 100);
|
||||
//building 3
|
||||
spawn.mapRect(-4450, -1750, 800, 1050);
|
||||
// spawn.mapRect(-3850, -2000, 125, 400);
|
||||
@@ -3819,7 +4114,7 @@ const level = {
|
||||
doorPlateform.openClose();
|
||||
}
|
||||
hazard.level(button.isUp)
|
||||
hazard.query();
|
||||
|
||||
level.exit.draw();
|
||||
level.enter.draw();
|
||||
};
|
||||
@@ -3836,7 +4131,7 @@ const level = {
|
||||
portal[1].draw();
|
||||
portal[2].draw();
|
||||
portal[3].draw();
|
||||
hazard.draw();
|
||||
hazard.query();
|
||||
//elevator
|
||||
if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) {
|
||||
if (elevator.plat.position.y > -200) { //bottom
|
||||
@@ -4461,7 +4756,6 @@ const level = {
|
||||
ctx.fillRect(4050, -905, 1125, 2);
|
||||
ctx.fillRect(4050, -865, 1125, 2);
|
||||
|
||||
hazard.query();
|
||||
buttonBedroom.query();
|
||||
buttonBedroom.draw();
|
||||
if (buttonBedroom.isUp) {
|
||||
@@ -4525,7 +4819,7 @@ const level = {
|
||||
ctx.fillStyle = "rgba(64,64,64,0.97)";
|
||||
ctx.fillRect(2800, -400, 275, 175);
|
||||
|
||||
hazard.draw();
|
||||
hazard.query();
|
||||
doorBedroom.draw();
|
||||
doorGrenier.draw();
|
||||
voletLucarne1.draw();
|
||||
@@ -5178,17 +5472,15 @@ const level = {
|
||||
const slimePitThree = level.hazard(6500, 200, 1000, 170);
|
||||
|
||||
level.custom = () => {
|
||||
slimePitOne.query();
|
||||
slimePitTwo.query();
|
||||
slimePitThree.query();
|
||||
slimePitOne.draw();
|
||||
slimePitTwo.draw();
|
||||
slimePitThree.draw();
|
||||
level.playerExitCheck();
|
||||
level.exit.draw();
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {};
|
||||
level.customTopLayer = () => {
|
||||
slimePitOne.query();
|
||||
slimePitTwo.query();
|
||||
slimePitThree.query();
|
||||
};
|
||||
|
||||
level.setPosToSpawn(-500, 550); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
@@ -5696,13 +5988,11 @@ const level = {
|
||||
slimePit.query();
|
||||
ctx.shadowColor = 'hsla(160, 100%, 50%, 1)'
|
||||
ctx.shadowBlur = 100;
|
||||
slimePit.draw()
|
||||
// slimePit.draw()
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.shadowColor = 'rgba(0, 0, 0, 0)'
|
||||
topSlime.query();
|
||||
|
||||
deliveryButton.query()
|
||||
deliverySlime.query()
|
||||
deliverySlime2.query()
|
||||
portal[2].query()
|
||||
//portal[3].query()
|
||||
portal2[2].query()
|
||||
@@ -5719,6 +6009,9 @@ const level = {
|
||||
}
|
||||
|
||||
level.customTopLayer = () => {
|
||||
topSlime.query();
|
||||
deliverySlime.query()
|
||||
deliverySlime2.query()
|
||||
drip1.draw()
|
||||
drip2.draw()
|
||||
drip3.draw()
|
||||
@@ -5763,9 +6056,9 @@ const level = {
|
||||
ctx.fill()
|
||||
|
||||
deliveryButton.draw()
|
||||
deliverySlime.draw()
|
||||
deliverySlime2.draw()
|
||||
topSlime.draw()
|
||||
// deliverySlime.draw()
|
||||
// deliverySlime2.draw()
|
||||
// topSlime.draw()
|
||||
buttonGreen.draw()
|
||||
buttonYellow.draw()
|
||||
buttonRed.draw()
|
||||
@@ -6224,7 +6517,6 @@ const level = {
|
||||
}
|
||||
|
||||
button.query();
|
||||
hazard.query();
|
||||
isButtonTapped = isButtonTapped || !button.isUp;
|
||||
hazard.level(!isButtonTapped);
|
||||
if (Matter.Query.region([player], hazard).length) m.energy -= 0.001;
|
||||
@@ -6271,8 +6563,7 @@ const level = {
|
||||
if (secretAnimTime2 > 150) secretAnimTime2 = 0;
|
||||
}
|
||||
|
||||
secretHazard.level(emergencyActivated);
|
||||
secretHazard.query();
|
||||
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(m.pos.x, m.pos.y, 200, 0, 2 * Math.PI);
|
||||
@@ -6290,12 +6581,11 @@ const level = {
|
||||
elevator.drawTrack();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
hazard.draw();
|
||||
secretHazard.draw();
|
||||
hazard.query();
|
||||
secretHazard.level(emergencyActivated);
|
||||
secretHazard.query();
|
||||
button.draw();
|
||||
|
||||
|
||||
|
||||
// Fire damage
|
||||
let isInRange = flames.reduce((a, i) => a || Math.sqrt((m.pos.x - i[0]) * (m.pos.x - i[0]) + (m.pos.y + 90 - i[1]) * (m.pos.y + 90 - i[1])) < 50, false);
|
||||
|
||||
|
||||
@@ -1526,7 +1526,7 @@ const spawn = {
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "rgba(150,0,255,0.15)";
|
||||
ctx.fillStyle = "rgba(150,0,255,0.1)";
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
|
||||
29
js/tech.js
29
js/tech.js
@@ -754,12 +754,30 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shock wave",
|
||||
description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>40%</strong>",
|
||||
name: "chain reaction",
|
||||
description: "<strong class='color-block'>blocks</strong> caught in <strong class='color-e'>explosions</strong> also <strong class='color-e'>explode</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequency: 1,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect() {
|
||||
tech.isBlockExplode = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isBlockExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shock wave",
|
||||
description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
@@ -3794,7 +3812,7 @@
|
||||
},
|
||||
remove() {
|
||||
tech.waveBeamSpeed = 10;
|
||||
tech.waveBeamDamage = 1.3 //this sets base wave beam damage
|
||||
tech.waveBeamDamage = 1.5 //this sets base wave beam damage
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -6928,5 +6946,6 @@
|
||||
harmonics: null,
|
||||
isStandingWaveExpand: null,
|
||||
isBlockExplosion: null,
|
||||
superBallDelay: null
|
||||
superBallDelay: null,
|
||||
isBlockExplode: null
|
||||
}
|
||||
37
todo.txt
37
todo.txt
@@ -1,23 +1,14 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
tech supertemporal - fire your super balls at the same place in space, but delayed in time
|
||||
tech: chain reaction - blocks caught in explosions, explode
|
||||
tech: shock wave reduces explosion damage by 30% (was 40%)
|
||||
|
||||
super ball starts with 3 not 4 balls, but they are is 25% larger, 10% faster, and 25% lower divergence
|
||||
(this makes adding more balls much stronger)
|
||||
gun - super balls has 15% less ammo
|
||||
|
||||
standing wave harmonics - still has no block cooldown, but now it has a cooldown for how often it can drain energy
|
||||
this should make rapidly blocking drain upto 10x less energy
|
||||
base blocking cost have increased by 25%
|
||||
|
||||
wormhole gets 10% duplication (was 7%)
|
||||
ice-IX does 15% more damage
|
||||
|
||||
new level element - toggle(x, y, isLockOn = false)
|
||||
similar to a button but doesn't require a block
|
||||
used on the level highrise
|
||||
can toggle "off and on" or "lock on"
|
||||
slime hazards now draw themselves in hazard.query()
|
||||
I updated all the maps to remove hazard.draw()
|
||||
but maybe I missed one let me know if you find a buggy slime
|
||||
laser hazards also draw themselves in hazard.opticalQuery()
|
||||
|
||||
2/6 rooms for new level.labs() are completed
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
@@ -76,10 +67,12 @@ make a switch level element
|
||||
angle of stick "light-switch"
|
||||
with colors?
|
||||
|
||||
level element: carousel
|
||||
use rotor code
|
||||
add blocks at the 4 ends of the rotor that maintain horizontal angle
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
standing wave harmonics - can block too often on the same mob if you push it into a corner
|
||||
add a cool down that only stops energy drain and iceIX, but still lets you block
|
||||
let standing wave harmonics get tech decorrelation
|
||||
|
||||
tech: cloaking field - decrease/increase cooldown on sneak attack?
|
||||
@@ -90,13 +83,6 @@ have throw charge scale with fire delay
|
||||
|
||||
in testing mode console log the body you click on
|
||||
|
||||
default negative mass field- move block horizontally?
|
||||
should this be a tech?
|
||||
|
||||
negative mass field tech - increase flight speed
|
||||
use the sphere ellipse graphic?
|
||||
move block horizontally and vertically with player
|
||||
|
||||
throwing a block removes the block and rewinds time 10 seconds (including health and energy)
|
||||
requires CPT, CPT gun, time dilation field?
|
||||
|
||||
@@ -386,6 +372,7 @@ possible names for tech
|
||||
axion - maybe a 3rd dark matter type tech
|
||||
Pigeonhole principle - if there are several things that are matched up
|
||||
regression to the mean
|
||||
tessellation = tiling of a flat surface is the covering of a plane using one or more geometric shapes, called tiles, with no overlaps and no gaps.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user