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:
landgreen
2021-06-17 13:03:03 -07:00
parent fe05a57a13
commit f89b228226
7 changed files with 456 additions and 148 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -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 explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius radius *= tech.explosiveRadius
let dist, sub, knock; 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.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) { if (tech.isSmallExplosion) {
color = "rgba(255,0,30,0.7)" color = "rgba(255,0,30,0.7)"
@@ -387,20 +387,32 @@ const b = {
} }
//body knock backs //body knock backs
for (let i = 0, len = body.length; i < len; ++i) { for (let i = body.length - 1; i > -1; i--) {
if (body[i].isNotHoldable) continue if (!body[i].isNotHoldable) {
sub = Vector.sub(where, body[i].position); sub = Vector.sub(where, body[i].position);
dist = Vector.magnitude(sub); dist = Vector.magnitude(sub);
if (dist < radius) { if (dist < radius) {
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.022); knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.022);
body[i].force.x += knock.x; body[i].force.x += knock.x;
body[i].force.y += knock.y; 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) { } else if (dist < alertRange) {
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.011); knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.011);
body[i].force.x += knock.x; body[i].force.x += knock.x;
body[i].force.y += knock.y; body[i].force.y += knock.y;
} }
} }
}
//power up knock backs //power up knock backs
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {

View File

@@ -41,8 +41,8 @@ function playerOnGroundCheck(event) {
m.yOff = m.yOffWhen.jump; m.yOff = m.yOffWhen.jump;
m.hardLandCD = m.cycle + Math.min(momentum / 6.5 - 6, 40) m.hardLandCD = m.cycle + Math.min(momentum / 6.5 - 6, 40)
//falling damage //falling damage
if (tech.isFallingDamage && m.immuneCycle < m.cycle) { if (tech.isFallingDamage && m.immuneCycle < m.cycle && momentum > 150) {
m.damage(Math.min(Math.sqrt(momentum - 123) * 0.01, 0.25)); 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 m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
} }
} else { } else {

View File

@@ -12,17 +12,15 @@ const level = {
start() { start() {
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.zoomScale = 1000;
// simulation.setZoom();
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// level.difficultyIncrease(30) // level.difficultyIncrease(30)
// m.setField("standing wave harmonics") // m.setField("standing wave harmonics")
// tech.giveTech("spherical harmonics") // tech.giveTech("spherical harmonics")
// for (let i = 0; i < 9; i++) 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.isExplodeRadio = true
// tech.giveTech("Z-pinch") // tech.giveTech("chain reaction")
// tech.giveTech("MACHO") // tech.giveTech("MACHO")
// tech.giveTech("supertemporal") // tech.giveTech("supertemporal")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length") // 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") // for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
level.intro(); //starting level level.intro(); //starting level
// level.labs();
// level.testing(); //not in rotation, used for testing // level.testing(); //not in rotation, used for testing
// level.template(); //not in rotation, blank start new map development // level.template(); //not in rotation, blank start new map development
// level.final() //final boss level // level.final() //final boss level
@@ -273,7 +272,7 @@ const level = {
World.add(engine.world, map[i]); //add to world 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 x = x + width / 2
y = y + height / 2 y = y + height / 2
const who = body[body.length] = Bodies.rectangle(x, y, width, height, { 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 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, isNotHoldable: true,
frictionAir: 0.001, frictionAir: frictionAir,
friction: 1, friction: 1,
frictionStatic: 1, frictionStatic: 1,
restitution: 0, restitution: 0,
}); });
Matter.Body.setAngle(who, angle)
Matter.Body.setAngularVelocity(who, angularVelocity);
Matter.Body.setDensity(who, density) Matter.Body.setDensity(who, density)
const constraint = Constraint.create({ //fix rotor in place, but allow rotation const constraint = Constraint.create({ //fix rotor in place, but allow rotation
@@ -547,13 +549,13 @@ const level = {
composite[composite.length] = rotor composite[composite.length] = rotor
return 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"); spawn.mapVertex(x + 65, y + 2, "70 10 -70 10 -40 -10 40 -10");
map[map.length - 1].restitution = 0; map[map.length - 1].restitution = 0;
map[map.length - 1].friction = 1; map[map.length - 1].friction = 1;
map[map.length - 1].frictionStatic = 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]; let flip = body[body.length - 1];
flip.isNoSetCollision = true //prevents collision form being rewritten in level.addToWorld flip.isNoSetCollision = true //prevents collision form being rewritten in level.addToWorld
flip.collisionFilter.category = cat.body flip.collisionFilter.category = cat.body
@@ -563,13 +565,20 @@ const level = {
flip.frictionAir = 0.01 flip.frictionAir = 0.01
flip.restitution = 0 flip.restitution = 0
Matter.Body.setDensity(flip, 0.003) 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) Matter.Body.setAngle(flip, (-0.25 - 0.5) * Math.PI)
setTimeout(function() {}, 100); }
// setTimeout(function() {
// }, 100);
cons[cons.length] = Constraint.create({ cons[cons.length] = Constraint.create({
pointA: { pointA: {
x: x + 65, x: x + 65,
y: y y: y - 5
}, },
bodyB: flip, bodyB: flip,
stiffness: 1, stiffness: 1,
@@ -580,7 +589,7 @@ const level = {
return { return {
flip: flip, flip: flip,
isOn: false, isOn: isOn,
query() { query() {
const limit = { const limit = {
right: (-0.25 - 0.5) * Math.PI, 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 { return {
min: { min: {
x: x, x: x,
@@ -938,7 +947,12 @@ const level = {
maxHeight: height, maxHeight: height,
isOn: true, isOn: true,
opticalQuery() { 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) { if (m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
m.damage(damage) m.damage(damage)
@@ -951,9 +965,15 @@ const level = {
}); });
} }
} }
}
}, },
query() { 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 const drain = 0.003 + m.fieldRegen
if (m.energy > drain) { if (m.energy > drain) {
m.energy -= drain m.energy -= drain
@@ -991,20 +1011,14 @@ const level = {
y: 0.95 * powerUpCollide[i].velocity.y 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) { level(isFill) {
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
const growSpeed = 1 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() { null() {
level.levels.pop(); //remove lore level from rotation level.levels.pop(); //remove lore level from rotation
//start a conversation based on the number of conversations seen //start a conversation based on the number of conversations seen
@@ -1121,7 +1411,7 @@ const level = {
level.customTopLayer = () => { level.customTopLayer = () => {
ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.fillRect(-1950, -950, 3900, 1900); ctx.fillRect(-1950, -950, 3900, 1900);
hazardSlime.drawTides(); // hazardSlime.drawTides();
//draw center circle lines //draw center circle lines
ctx.beginPath(); ctx.beginPath();
@@ -1635,8 +1925,10 @@ const level = {
spawn.mapRect(1225, -1955, 175, 30); 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 const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
let portal, portal2, portal3 let portal, portal2, portal3
const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4) //laser
const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //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 button = level.button(2100, -2600)
const buttonDoor = level.button(600, -550) const buttonDoor = level.button(600, -550)
const door = level.door(312, -750, 25, 190, 185) const door = level.door(312, -750, 25, 190, 185)
@@ -1680,8 +1972,7 @@ const level = {
portal2[3].query() portal2[3].query()
portal3[2].query() portal3[2].query()
portal3[3].query() portal3[3].query()
hazard.opticalQuery();
hazard2.opticalQuery();
if (button.isUp) { if (button.isUp) {
hazard.isOn = false; hazard.isOn = false;
hazard2.isOn = false; hazard2.isOn = false;
@@ -1700,8 +1991,8 @@ const level = {
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
door.draw(); door.draw();
hazard.draw(); hazard.opticalQuery();
hazard2.draw(); hazard2.opticalQuery();
portal[0].draw(); portal[0].draw();
portal[1].draw(); portal[1].draw();
portal[2].draw(); portal[2].draw();
@@ -1899,8 +2190,7 @@ const level = {
button1.query(); button1.query();
button1.draw(); button1.draw();
hazard.query();
hazard.level(button1.isUp)
rotor.rotate(); rotor.rotate();
ctx.fillStyle = "hsl(175, 15%, 76%)" 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.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance4.pointA.x, balance4.pointA.y) ctx.moveTo(balance4.pointA.x, balance4.pointA.y)
ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI); 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(); ctx.fill();
hazard.query();
hazard.draw(); hazard.level(button1.isUp)
}; };
level.setPosToSpawn(0, -50); //normal spawn level.setPosToSpawn(0, -50); //normal spawn
@@ -2031,6 +2323,8 @@ const level = {
balance2 = level.spinner(-2605 - 390, 500, 390, 25, 0.001) //falling balance2 = level.spinner(-2605 - 390, 500, 390, 25, 0.001) //falling
balance3 = level.spinner(-2608 - 584, 1900, 584, 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 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.min.x = -boost1.boostBounds.min.x - 100
// boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100 // boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100
// level.setPosToSpawn(300, -700); //-x // no need since 0 // 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 balance2 = level.spinner(2605, 500, 390, 25, 0.001) //falling
balance3 = level.spinner(2608, 1900, 584, 25, 0.001) //falling balance3 = level.spinner(2608, 1900, 584, 25, 0.001) //falling
balance4 = level.spinner(9300, 2205, 25, 380, 0.001) //exit 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 const elevator1 = level.elevator(-790, -190, 180, 25, -1150) //, 0.007
elevator1.addConstraint(); elevator1.addConstraint();
// const button1 = level.button(-500, -200) // 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 const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007
elevator2.addConstraint(); elevator2.addConstraint();
// const button2 = level.button(-3100, -1330) // 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 = () => { level.custom = () => {
@@ -2958,7 +3253,7 @@ const level = {
spawn.bodyRect(-3410, -1425, 100, 100); spawn.bodyRect(-3410, -1425, 100, 100);
spawn.bodyRect(-3390, -1525, 100, 100); spawn.bodyRect(-3390, -1525, 100, 100);
spawn.bodyRect(-3245, -1425, 100, 100); // spawn.bodyRect(-3245, -1425, 100, 100);
//building 3 //building 3
spawn.mapRect(-4450, -1750, 800, 1050); spawn.mapRect(-4450, -1750, 800, 1050);
// spawn.mapRect(-3850, -2000, 125, 400); // spawn.mapRect(-3850, -2000, 125, 400);
@@ -3819,7 +4114,7 @@ const level = {
doorPlateform.openClose(); doorPlateform.openClose();
} }
hazard.level(button.isUp) hazard.level(button.isUp)
hazard.query();
level.exit.draw(); level.exit.draw();
level.enter.draw(); level.enter.draw();
}; };
@@ -3836,7 +4131,7 @@ const level = {
portal[1].draw(); portal[1].draw();
portal[2].draw(); portal[2].draw();
portal[3].draw(); portal[3].draw();
hazard.draw(); hazard.query();
//elevator //elevator
if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) { if (elevator.pauseUntilCycle < simulation.cycle && !m.isBodiesAsleep) {
if (elevator.plat.position.y > -200) { //bottom if (elevator.plat.position.y > -200) { //bottom
@@ -4461,7 +4756,6 @@ const level = {
ctx.fillRect(4050, -905, 1125, 2); ctx.fillRect(4050, -905, 1125, 2);
ctx.fillRect(4050, -865, 1125, 2); ctx.fillRect(4050, -865, 1125, 2);
hazard.query();
buttonBedroom.query(); buttonBedroom.query();
buttonBedroom.draw(); buttonBedroom.draw();
if (buttonBedroom.isUp) { if (buttonBedroom.isUp) {
@@ -4525,7 +4819,7 @@ const level = {
ctx.fillStyle = "rgba(64,64,64,0.97)"; ctx.fillStyle = "rgba(64,64,64,0.97)";
ctx.fillRect(2800, -400, 275, 175); ctx.fillRect(2800, -400, 275, 175);
hazard.draw(); hazard.query();
doorBedroom.draw(); doorBedroom.draw();
doorGrenier.draw(); doorGrenier.draw();
voletLucarne1.draw(); voletLucarne1.draw();
@@ -5178,17 +5472,15 @@ const level = {
const slimePitThree = level.hazard(6500, 200, 1000, 170); const slimePitThree = level.hazard(6500, 200, 1000, 170);
level.custom = () => { level.custom = () => {
slimePitOne.query();
slimePitTwo.query();
slimePitThree.query();
slimePitOne.draw();
slimePitTwo.draw();
slimePitThree.draw();
level.playerExitCheck(); level.playerExitCheck();
level.exit.draw(); level.exit.draw();
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => {}; level.customTopLayer = () => {
slimePitOne.query();
slimePitTwo.query();
slimePitThree.query();
};
level.setPosToSpawn(-500, 550); //normal spawn level.setPosToSpawn(-500, 550); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
@@ -5696,13 +5988,11 @@ const level = {
slimePit.query(); slimePit.query();
ctx.shadowColor = 'hsla(160, 100%, 50%, 1)' ctx.shadowColor = 'hsla(160, 100%, 50%, 1)'
ctx.shadowBlur = 100; ctx.shadowBlur = 100;
slimePit.draw() // slimePit.draw()
ctx.shadowBlur = 0; ctx.shadowBlur = 0;
ctx.shadowColor = 'rgba(0, 0, 0, 0)' ctx.shadowColor = 'rgba(0, 0, 0, 0)'
topSlime.query();
deliveryButton.query() deliveryButton.query()
deliverySlime.query()
deliverySlime2.query()
portal[2].query() portal[2].query()
//portal[3].query() //portal[3].query()
portal2[2].query() portal2[2].query()
@@ -5719,6 +6009,9 @@ const level = {
} }
level.customTopLayer = () => { level.customTopLayer = () => {
topSlime.query();
deliverySlime.query()
deliverySlime2.query()
drip1.draw() drip1.draw()
drip2.draw() drip2.draw()
drip3.draw() drip3.draw()
@@ -5763,9 +6056,9 @@ const level = {
ctx.fill() ctx.fill()
deliveryButton.draw() deliveryButton.draw()
deliverySlime.draw() // deliverySlime.draw()
deliverySlime2.draw() // deliverySlime2.draw()
topSlime.draw() // topSlime.draw()
buttonGreen.draw() buttonGreen.draw()
buttonYellow.draw() buttonYellow.draw()
buttonRed.draw() buttonRed.draw()
@@ -6224,7 +6517,6 @@ const level = {
} }
button.query(); button.query();
hazard.query();
isButtonTapped = isButtonTapped || !button.isUp; isButtonTapped = isButtonTapped || !button.isUp;
hazard.level(!isButtonTapped); hazard.level(!isButtonTapped);
if (Matter.Query.region([player], hazard).length) m.energy -= 0.001; if (Matter.Query.region([player], hazard).length) m.energy -= 0.001;
@@ -6271,8 +6563,7 @@ const level = {
if (secretAnimTime2 > 150) secretAnimTime2 = 0; if (secretAnimTime2 > 150) secretAnimTime2 = 0;
} }
secretHazard.level(emergencyActivated);
secretHazard.query();
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 200, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, 200, 0, 2 * Math.PI);
@@ -6290,12 +6581,11 @@ const level = {
elevator.drawTrack(); elevator.drawTrack();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
hazard.draw(); hazard.query();
secretHazard.draw(); secretHazard.level(emergencyActivated);
secretHazard.query();
button.draw(); button.draw();
// Fire damage // 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); 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);

View File

@@ -1526,7 +1526,7 @@ const spawn = {
ctx.stroke(); ctx.stroke();
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI); 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(); ctx.fill();
} }

View File

@@ -754,12 +754,30 @@
} }
}, },
{ {
name: "shock wave", name: "chain reaction",
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>", description: "<strong class='color-block'>blocks</strong> caught in <strong class='color-e'>explosions</strong> also <strong class='color-e'>explode</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, 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() { 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) 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() { remove() {
tech.waveBeamSpeed = 10; 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, harmonics: null,
isStandingWaveExpand: null, isStandingWaveExpand: null,
isBlockExplosion: null, isBlockExplosion: null,
superBallDelay: null superBallDelay: null,
isBlockExplode: null
} }

View File

@@ -1,23 +1,14 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** 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 slime hazards now draw themselves in hazard.query()
(this makes adding more balls much stronger) I updated all the maps to remove hazard.draw()
gun - super balls has 15% less ammo but maybe I missed one let me know if you find a buggy slime
laser hazards also draw themselves in hazard.opticalQuery()
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"
2/6 rooms for new level.labs() are completed
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -76,10 +67,12 @@ make a switch level element
angle of stick "light-switch" angle of stick "light-switch"
with colors? with colors?
level element: carousel
use rotor code
add blocks at the 4 ends of the rotor that maintain horizontal angle
******************************************************** TODO ******************************************************** ******************************************************** 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 let standing wave harmonics get tech decorrelation
tech: cloaking field - decrease/increase cooldown on sneak attack? 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 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) throwing a block removes the block and rewinds time 10 seconds (including health and energy)
requires CPT, CPT gun, time dilation field? requires CPT, CPT gun, time dilation field?
@@ -386,6 +372,7 @@ possible names for tech
axion - maybe a 3rd dark matter type tech axion - maybe a 3rd dark matter type tech
Pigeonhole principle - if there are several things that are matched up Pigeonhole principle - if there are several things that are matched up
regression to the mean 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.