finalized custom key inputs

This commit is contained in:
landgreen
2020-10-11 10:47:50 -07:00
parent 01a29430fa
commit 858fa5fb24
9 changed files with 469 additions and 304 deletions

View File

@@ -133,40 +133,66 @@
</details> </details>
</div> </div>
<div id="controls"> <div id="controls">
<details> <details id="control-details">
<summary>controls</summary> <summary>controls</summary>
<div id="details-div"> <div id="details-div">
<table> To change controls click a box<br>
and press an unused key.
<br><br>
<table id="control-table">
<tr> <tr>
<th>FIRE</th> <th>FIRE</th>
<td>left mouse</td> <td></td>
<td class='key-used'>MouseLeft</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<th>FIELD</th> <th>FIELD</th>
<td>right mouse / spacebar</td> <td id='key-field' class='key-input'>SPACE</td>
<td class='key-used'>MouseRight</td>
</tr> </tr>
<tr> <tr>
<th>MOVE</th> <th>JUMP</th>
<td>WASD / arrows</td> <td id='key-up' class='key-input'>W</td>
<td class='key-used'>ArrowUp</td>
</tr> </tr>
<tr> <tr>
<th>GUNS</th> <th>CROUCH&nbsp;</th>
<td>Q / E / mouse wheel</td> <td id='key-down' class='key-input'>S</td>
<td class='key-used'>ArrowDown</td>
</tr>
<tr>
<th>LEFT</th>
<td id='key-left' class='key-input'>A</td>
<td class='key-used'>ArrowLeft</td>
</tr>
<tr>
<th>RIGHT</th>
<td id='key-right' class='key-input'>D</td>
<td class='key-used'>ArrowRight</td>
</tr>
<tr>
<th>GUN → </th>
<td id='key-next-gun' class='key-input'>Q</td>
<td class='key-used'>MouseWheel</td>
</tr>
<tr>
<th>GUN ← </th>
<td id='key-previous-gun' class='key-input'>E</td>
<td class='key-used'>MouseWheel</td>
</tr> </tr>
<!-- <tr>
<th>ZOOM</th>
<td>- / + or i / o</td>
</tr> -->
<tr> <tr>
<th>PAUSE</th> <th>PAUSE</th>
<td>P</td> <td id='key-pause' class='key-input'>P</td>
<td></td>
</tr>
<tr>
<th>TESTING</th>
<td id='key-testing' class='key-input'>T</td>
<td></td>
</tr> </tr>
<!-- <tr>
<td>FULL SCREEN</td>
<td>enter</td>
</tr> -->
</table> </table>
<button id="control-reset" type="button">reset</button><span style="font-size: 60%;"> to default keys</span>
</div> </div>
</details> </details>
</div> </div>
@@ -354,12 +380,12 @@
<g class="draw-lines4" text-anchor="middle" stroke='#000' fill='none' stroke-width="2" font-size="38px" font-family="Arial Black, sans-serif"> <g class="draw-lines4" text-anchor="middle" stroke='#000' fill='none' stroke-width="2" font-size="38px" font-family="Arial Black, sans-serif">
<!-- <text class="fade-in" fill='#aaa' stroke="none" x="30" y="45">Q</text> <!-- <text class="fade-in" fill='#aaa' stroke="none" x="30" y="45">Q</text>
<text class="fade-in" fill='#aaa' stroke="none" x="170" y="45">E</text> --> <text class="fade-in" fill='#aaa' stroke="none" x="170" y="45">E</text> -->
<text x="30" y="45" stroke-width="2">Q</text> <text x="30" y="45" id="splash-previous-gun" stroke-width="2">Q</text>
<text x="170" y="45" stroke-width="2">E</text> <text x="170" y="45" id="splash-next-gun" stroke-width="2">E</text>
<text x="100" y="45">W</text> <text x="100" y="45" id="splash-up">W</text>
<text x="100" y="113">S</text> <text x="100" y="113" id="splash-down">S</text>
<text x="170" y="113">D</text> <text x="30" y="113" id="splash-left">A</text>
<text x="30" y="113">A</text> <text x="170" y="113" id="splash-right">D</text>
<!-- <text class="fade-in" fill='#999' x="100" y="45">W</text> <!-- <text class="fade-in" fill='#999' x="100" y="45">W</text>
<text class="fade-in" fill='#999' x="100" y="113">S</text> <text class="fade-in" fill='#999' x="100" y="113">S</text>
<text class="fade-in" fill='#999' x="170" y="113">D</text> <text class="fade-in" fill='#999' x="170" y="113">D</text>

View File

@@ -672,7 +672,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (mod.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), thrust: (mod.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: mod.isMutualism ? 5.6 : 2.8, //2x bonus damage from mod.isMutualism dmg: mod.isMutualism ? 6 : 3, //2x bonus damage from mod.isMutualism
lookFrequency: 97 + Math.floor(117 * Math.random()), lookFrequency: 97 + Math.floor(117 * Math.random()),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -2680,7 +2680,7 @@ const b = {
bullet[me].maxRadius = 30; bullet[me].maxRadius = 30;
bullet[me].restitution = 0.3; bullet[me].restitution = 0.3;
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 9 + 2 * mod.isFastSpores + 2 * mod.isSporeFreeze bullet[me].totalSpores = 8 + 2 * mod.isFastSpores + 2 * mod.isSporeFreeze
bullet[me].stuck = function () {}; bullet[me].stuck = function () {};
bullet[me].onDmg = function () {}; bullet[me].onDmg = function () {};
bullet[me].do = function () { bullet[me].do = function () {

View File

@@ -461,6 +461,7 @@ const game = {
player.force.y += player.mass * game.g; player.force.y += player.mass * game.g;
}, },
reset() { //run on first run, and each later run after you die reset() { //run on first run, and each later run after you die
input.endKeySensing();
b.removeAllGuns(); b.removeAllGuns();
mod.setupAllMods(); //sets mods to default values mod.setupAllMods(); //sets mods to default values
b.setFireCD(); b.setFireCD();

View File

@@ -36,6 +36,11 @@ if (screen.height < 800) {
if (screen.height < 600) document.getElementById("choose-grid").style.fontSize = "0.8em"; //1.3em is normal if (screen.height < 600) document.getElementById("choose-grid").style.fontSize = "0.8em"; //1.3em is normal
} }
//**********************************************************************
// check for URL parameters to load a custom game
//**********************************************************************
//example https://landgreen.github.io/sidescroller/index.html? //example https://landgreen.github.io/sidescroller/index.html?
// &gun1=minigun&gun2=laser // &gun1=minigun&gun2=laser
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot&field=phase%20decoherence%20field&difficulty=2 // &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot&field=phase%20decoherence%20field&difficulty=2
@@ -56,14 +61,11 @@ function getUrlVars() {
window.addEventListener('load', (event) => { window.addEventListener('load', (event) => {
const set = getUrlVars() const set = getUrlVars()
if (Object.keys(set).length !== 0) { if (Object.keys(set).length !== 0) {
// game.startGame()
openCustomBuildMenu(); openCustomBuildMenu();
//add custom selections based on url //add custom selections based on url
for (const property in set) { for (const property in set) {
// console.log(set[property], property);
set[property] = set[property].replace(/%20/g, " ") set[property] = set[property].replace(/%20/g, " ")
set[property] = set[property].replace(/%CE%A8/g, "Ψ") set[property] = set[property].replace(/%CE%A8/g, "Ψ")
if (property === "field") { if (property === "field") {
let found = false let found = false
let index let index
@@ -76,7 +78,6 @@ window.addEventListener('load', (event) => {
} }
if (found) build.choosePowerUp(document.getElementById(`field-${index}`), index, 'field') if (found) build.choosePowerUp(document.getElementById(`field-${index}`), index, 'field')
} }
if (property.substring(0, 3) === "gun") { if (property.substring(0, 3) === "gun") {
let found = false let found = false
let index let index
@@ -89,7 +90,6 @@ window.addEventListener('load', (event) => {
} }
if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun') if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun')
} }
if (property.substring(0, 3) === "mod") { if (property.substring(0, 3) === "mod") {
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < mod.mods.length; i++) {
if (set[property] === mod.mods[i].name) { if (set[property] === mod.mods[i].name) {
@@ -98,7 +98,6 @@ window.addEventListener('load', (event) => {
} }
} }
} }
if (property === "difficulty") { if (property === "difficulty") {
game.difficultyMode = Number(set[property]) game.difficultyMode = Number(set[property])
document.getElementById("difficulty-select-custom").value = Number(set[property]) document.getElementById("difficulty-select-custom").value = Number(set[property])
@@ -111,8 +110,9 @@ window.addEventListener('load', (event) => {
}); });
//**********************************************************************
//set up canvas //set up canvas
//**********************************************************************
var canvas = document.getElementById("canvas"); var canvas = document.getElementById("canvas");
//using "const" causes problems in safari when an ID shares the same name. //using "const" causes problems in safari when an ID shares the same name.
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
@@ -142,14 +142,14 @@ window.onresize = () => {
setupCanvas(); setupCanvas();
}; };
//**********************************************************************
//build build grid display // custom build grid display and pause
//**********************************************************************
const build = { const build = {
onLoadPowerUps() { onLoadPowerUps() {
const set = getUrlVars() const set = getUrlVars()
if (Object.keys(set).length !== 0) { if (Object.keys(set).length !== 0) {
for (const property in set) { for (const property in set) {
// console.log(`${property}: ${give[property]}`);
set[property] = set[property].replace(/%20/g, " ") set[property] = set[property].replace(/%20/g, " ")
if (property.substring(0, 3) === "gun") b.giveGuns(set[property]) if (property.substring(0, 3) === "gun") b.giveGuns(set[property])
if (property.substring(0, 3) === "mod") mod.giveMod(set[property]) if (property.substring(0, 3) === "mod") mod.giveMod(set[property])
@@ -165,7 +165,6 @@ const build = {
level.onLevel++ level.onLevel++
} }
} }
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove any bullets that might have spawned from mods bullet = []; //remove any bullets that might have spawned from mods
if (b.inventory.length > 0) { if (b.inventory.length > 0) {
@@ -206,7 +205,6 @@ const build = {
let el = document.getElementById("pause-grid-left") let el = document.getElementById("pause-grid-left")
el.style.display = "grid" el.style.display = "grid"
el.innerHTML = text el.innerHTML = text
text = ""; text = "";
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[mech.fieldMode].name}</div> ${mech.fieldUpgrades[mech.fieldMode].description}</div>` text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[mech.fieldMode].name}</div> ${mech.fieldUpgrades[mech.fieldMode].description}</div>`
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = mod.mods.length; i < len; i++) {
@@ -265,10 +263,8 @@ const build = {
if (mod.mods[index].count < mod.mods[index].maxCount) { if (mod.mods[index].count < mod.mods[index].maxCount) {
if (!who.classList.contains("build-mod-selected")) who.classList.add("build-mod-selected"); if (!who.classList.contains("build-mod-selected")) who.classList.add("build-mod-selected");
mod.giveMod(index) mod.giveMod(index)
// if (mod.mods[index].count > 1) who.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[index].name} (${mod.mods[index].count}x)</div> ${mod.mods[index].description}`
} else { } else {
mod.removeMod(index); mod.removeMod(index);
// who.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[index].name}</div> ${mod.mods[index].description}`
who.classList.remove("build-mod-selected"); who.classList.remove("build-mod-selected");
} }
} }
@@ -406,14 +402,11 @@ const build = {
b.activeGun = b.inventory[0] //set first gun to active gun b.activeGun = b.inventory[0] //set first gun to active gun
game.makeGunHUD(); game.makeGunHUD();
} }
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove any bullets that might have spawned from mods bullet = []; //remove any bullets that might have spawned from mods
const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value)) const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value))
level.difficultyIncrease(Math.min(99, levelsCleared * game.difficultyMode)) //increase difficulty based on modes level.difficultyIncrease(Math.min(99, levelsCleared * game.difficultyMode)) //increase difficulty based on modes
level.levelsCleared += levelsCleared; level.levelsCleared += levelsCleared;
document.body.style.cursor = "none"; document.body.style.cursor = "none";
document.body.style.overflow = "hidden" document.body.style.overflow = "hidden"
document.getElementById("build-grid").style.display = "none" document.getElementById("build-grid").style.display = "none"
@@ -430,15 +423,14 @@ function openCustomBuildMenu() {
document.body.style.overflowY = "scroll"; document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden"; document.body.style.overflowX = "hidden";
document.getElementById("info").style.display = 'none' document.getElementById("info").style.display = 'none'
game.startGame(true); //starts game, but pauses it game.startGame(true); //starts game, but pauses it
build.isCustomSelection = true; build.isCustomSelection = true;
game.paused = true; game.paused = true;
build.reset(); build.reset();
} }
//record settings so they can be reproduced in the custom menu
document.getElementById("build-button").addEventListener("click", () => { //setup build run document.getElementById("build-button").addEventListener("click", () => { //setup build run
//record settings so they can be reproduced in the custom menu
let field = 0; let field = 0;
let inventory = []; let inventory = [];
let modList = []; let modList = [];
@@ -449,11 +441,8 @@ document.getElementById("build-button").addEventListener("click", () => { //setu
modList.push(mod.mods[i].count) modList.push(mod.mods[i].count)
} }
} }
openCustomBuildMenu(); openCustomBuildMenu();
if (!game.firstRun) { //if player has already died once load that previous build if (!game.firstRun) { //if player has already died once load that previous build
// console.log(modList)
build.choosePowerUp(document.getElementById(`field-${field}`), field, 'field') build.choosePowerUp(document.getElementById(`field-${field}`), field, 'field')
for (let i = 0; i < inventory.length; i++) { for (let i = 0; i < inventory.length; i++) {
build.choosePowerUp(document.getElementById(`gun-${inventory[i]}`), inventory[i], 'gun') build.choosePowerUp(document.getElementById(`gun-${inventory[i]}`), inventory[i], 'gun')
@@ -483,105 +472,337 @@ document.getElementById("build-button").addEventListener("click", () => { //setu
modID.classList.add("build-grid-disabled"); modID.classList.add("build-grid-disabled");
modID.onclick = null modID.onclick = null
} }
// if (mod.mods[i].count > 0) mod.removeMod(i)
// if (modID.classList.contains("build-mod-selected")) modID.classList.remove("build-mod-selected");
} }
} }
} }
} }
}); });
// local storage
let localSettings = JSON.parse(localStorage.getItem("localSettings"));
// console.log(localSettings)
if (localSettings) {
// game.isBodyDamage = localSettings.isBodyDamage
// document.getElementById("body-damage").checked = localSettings.isBodyDamage
game.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.difficultyMode = localSettings.difficultyMode
document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === 'max') {
game.fpsCapDefault = 999999999;
} else {
game.fpsCapDefault = Number(localSettings.fpsCapDefault)
}
document.getElementById("fps-select").value = localSettings.fpsCapDefault
} else {
localSettings = {
isCommunityMaps: false,
difficultyMode: '1',
fpsCapDefault: 'max',
runCount: 0,
levelsClearedLastGame: 0
};
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault
}
//**********************************************************************
// settings
//**********************************************************************
document.getElementById("fps-select").addEventListener("input", () => {
let value = document.getElementById("fps-select").value
if (value === 'max') {
game.fpsCapDefault = 999999999;
} else {
game.fpsCapDefault = Number(value)
}
localSettings.fpsCapDefault = value
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
document.getElementById("community-maps").addEventListener("input", () => {
game.isCommunityMaps = document.getElementById("community-maps").checked
localSettings.isCommunityMaps = game.isCommunityMaps
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
// difficulty-select-custom event listener is set in build.makeGrid
document.getElementById("difficulty-select").addEventListener("input", () => {
game.difficultyMode = Number(document.getElementById("difficulty-select").value)
localSettings.difficultyMode = game.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
// ************************************************************************************************
// ************************************************************************************************ // ************************************************************************************************
// inputs // inputs
// ************************************************************************************************ // ************************************************************************************************
// ************************************************************************************************
const input = { const input = {
fire: false, // left mouse
field: false, // right mouse
up: false, // jump up: false, // jump
down: false, // crouch down: false, // crouch
left: false, left: false,
right: false, right: false,
field: false, // right mouse
fire: false, // left mouse
isPauseKeyReady: true, isPauseKeyReady: true,
key: { key: {
// fire: "ShiftLeft",
field: "Space",
up: "KeyW", // jump up: "KeyW", // jump
down: "KeyS", // crouch down: "KeyS", // crouch
left: "KeyA", left: "KeyA",
right: "KeyD", right: "KeyD",
field: "Space",
// fire: "ShiftLeft",
pause: "KeyP", pause: "KeyP",
nextGun: "KeyE", nextGun: "KeyE",
previousGun: "KeyQ", previousGun: "KeyQ",
testing: "KeyT" testing: "KeyT"
},
setDefault() {
input.key = {
// fire: "ShiftLeft",
field: "Space",
up: "KeyW", // jump
down: "KeyS", // crouch
left: "KeyA",
right: "KeyD",
pause: "KeyP",
nextGun: "KeyE",
previousGun: "KeyQ",
testing: "KeyT"
}
input.controlTextUpdate()
},
controlTextUpdate() {
function cleanText(text) {
return text.replace('Key', '').replace('Digit', '')
}
document.getElementById("key-field").innerHTML = cleanText(input.key.field)
document.getElementById("key-up").innerHTML = cleanText(input.key.up)
document.getElementById("key-down").innerHTML = cleanText(input.key.down)
document.getElementById("key-left").innerHTML = cleanText(input.key.left)
document.getElementById("key-right").innerHTML = cleanText(input.key.right)
document.getElementById("key-pause").innerHTML = cleanText(input.key.pause)
document.getElementById("key-next-gun").innerHTML = cleanText(input.key.nextGun)
document.getElementById("key-previous-gun").innerHTML = cleanText(input.key.previousGun)
document.getElementById("key-testing").innerHTML = cleanText(input.key.testing)
document.getElementById("splash-up").innerHTML = cleanText(input.key.up)[0]
document.getElementById("splash-down").innerHTML = cleanText(input.key.down)[0]
document.getElementById("splash-left").innerHTML = cleanText(input.key.left)[0]
document.getElementById("splash-right").innerHTML = cleanText(input.key.right)[0]
document.getElementById("splash-next-gun").innerHTML = cleanText(input.key.nextGun)[0]
document.getElementById("splash-previous-gun").innerHTML = cleanText(input.key.previousGun)[0]
localSettings.key = input.key
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
},
focus: null,
setTextFocus() {
const backgroundColor = "#fff"
document.getElementById("key-field").style.background = backgroundColor
document.getElementById("key-up").style.background = backgroundColor
document.getElementById("key-down").style.background = backgroundColor
document.getElementById("key-left").style.background = backgroundColor
document.getElementById("key-right").style.background = backgroundColor
document.getElementById("key-pause").style.background = backgroundColor
document.getElementById("key-next-gun").style.background = backgroundColor
document.getElementById("key-previous-gun").style.background = backgroundColor
document.getElementById("key-testing").style.background = backgroundColor
if (input.focus) input.focus.style.background = 'rgb(0, 200, 255)';
},
setKeys(event) {
//check for duplicate keys
if (event.code && !(
event.code === "ArrowRight" ||
event.code === "ArrowLeft" ||
event.code === "ArrowUp" ||
event.code === "ArrowDown" ||
event.code === input.key.field ||
event.code === input.key.up ||
event.code === input.key.down ||
event.code === input.key.left ||
event.code === input.key.right ||
event.code === input.key.pause ||
event.code === input.key.nextGun ||
event.code === input.key.previousGun ||
event.code === input.key.testing
)) {
switch (input.focus.id) {
case "key-field":
input.key.field = event.code
break;
case "key-up":
input.key.up = event.code
break;
case "key-down":
input.key.down = event.code
break;
case "key-left":
input.key.left = event.code
break;
case "key-right":
input.key.right = event.code
break;
case "key-pause":
input.key.pause = event.code
break;
case "key-next-gun":
input.key.nextGun = event.code
break;
case "key-previous-gun":
input.key.previousGun = event.code
break;
case "key-testing":
input.key.testing = event.code
break;
}
}
input.controlTextUpdate()
input.endKeySensing()
},
endKeySensing() {
window.removeEventListener("keydown", input.setKeys);
input.focus = null
input.setTextFocus()
} }
} }
document.getElementById("control-table").addEventListener('click', (event) => {
if (event.target.className === 'key-input') {
input.focus = event.target
input.setTextFocus()
window.addEventListener("keydown", input.setKeys);
}
});
document.getElementById("control-details").addEventListener("toggle", function () {
input.controlTextUpdate()
input.endKeySensing();
})
document.getElementById("control-reset").addEventListener('click', input.setDefault);
window.addEventListener("keyup", function (event) {
switch (event.code) {
case input.key.right:
case "ArrowRight":
input.right = false
break;
case input.key.left:
case "ArrowLeft":
input.left = false
break;
case input.key.up:
case "ArrowUp":
input.up = false
break;
case input.key.down:
case "ArrowDown":
input.down = false
break;
case input.key.field:
input.field = false
break
}
});
window.addEventListener("keydown", function (event) {
switch (event.code) {
case input.key.right:
case "ArrowRight":
input.right = true
break;
case input.key.left:
case "ArrowLeft":
input.left = true
break;
case input.key.up:
case "ArrowUp":
input.up = true
break;
case input.key.down:
case "ArrowDown":
input.down = true
break;
case input.key.field:
input.field = true
break
case input.key.nextGun:
game.nextGun();
break
case input.key.previousGun:
game.previousGun();
break
case input.key.pause:
if (!game.isChoosing && input.isPauseKeyReady && mech.alive) {
input.isPauseKeyReady = false
setTimeout(function () {
input.isPauseKeyReady = true
}, 300);
if (game.paused) {
build.unPauseGrid()
game.paused = false;
level.levelAnnounce();
document.body.style.cursor = "none";
requestAnimationFrame(cycle);
} else {
game.paused = true;
game.replaceTextLog = true;
build.pauseGrid()
document.body.style.cursor = "auto";
}
}
break
case input.key.testing:
if (mech.alive) {
if (game.testing) {
game.testing = false;
game.loop = game.normalLoop
if (game.isConstructionMode) {
document.getElementById("construct").style.display = 'none'
}
} else { //if (keys[191])
game.testing = true;
game.isCheating = true;
if (game.isConstructionMode) {
document.getElementById("construct").style.display = 'inline'
}
game.loop = game.testingLoop
}
}
break
}
if (game.testing) {
switch (event.key) {
case "o":
game.isAutoZoom = false;
game.zoomScale /= 0.9;
game.setZoom();
break;
case "i":
game.isAutoZoom = false;
game.zoomScale *= 0.9;
game.setZoom();
break
case "`":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "reroll");
break
case "1":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "heal");
break
case "2":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "ammo");
break
case "3":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "gun");
break
case "4":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "field");
break
case "5":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod");
break
case "6":
const index = body.length
spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50);
body[index].collisionFilter.category = cat.body;
body[index].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
body[index].classType = "body";
World.add(engine.world, body[index]); //add to world
break
case "7":
const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
spawn[pick](game.mouseInGame.x, game.mouseInGame.y);
break
case "8":
spawn.randomLevelBoss(game.mouseInGame.x, game.mouseInGame.y);
break
case "f":
const mode = (mech.fieldMode === mech.fieldUpgrades.length - 1) ? 0 : mech.fieldMode + 1
mech.setField(mode)
break
case "g":
b.giveGuns("all", 1000)
break
case "h":
mech.addHealth(Infinity)
mech.energy = mech.maxEnergy;
break
case "y":
mod.giveMod()
break
case "r":
Matter.Body.setPosition(player, game.mouseInGame);
Matter.Body.setVelocity(player, {
x: 0,
y: 0
});
// move bots to follow player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
x: 250 * (Math.random() - 0.5),
y: 250 * (Math.random() - 0.5)
}));
Matter.Body.setVelocity(bullet[i], {
x: 0,
y: 0
});
}
}
break
case "u":
level.nextLevel();
break
case "X": //capital X to make it hard to die
mech.death();
break
}
}
});
//mouse move input //mouse move input
document.body.addEventListener("mousemove", (e) => { document.body.addEventListener("mousemove", (e) => {
game.mouse.x = e.clientX; game.mouse.x = e.clientX;
@@ -645,179 +866,67 @@ document.body.addEventListener("wheel", (e) => {
passive: true passive: true
}); });
window.addEventListener("keyup", function (event) { //**********************************************************************
switch (event.code) { // local storage
case input.key.right: //**********************************************************************
case "ArrowRight": let localSettings = JSON.parse(localStorage.getItem("localSettings"));
input.right = false if (localSettings) {
break; input.key = localSettings.key
case input.key.left: game.isCommunityMaps = localSettings.isCommunityMaps
case "ArrowLeft": document.getElementById("community-maps").checked = localSettings.isCommunityMaps
input.left = false game.difficultyMode = localSettings.difficultyMode
break; document.getElementById("difficulty-select").value = localSettings.difficultyMode
case input.key.up: if (localSettings.fpsCapDefault === 'max') {
case "ArrowUp": game.fpsCapDefault = 999999999;
input.up = false } else {
break; game.fpsCapDefault = Number(localSettings.fpsCapDefault)
case input.key.down:
case "ArrowDown":
input.down = false
break;
case input.key.field:
input.field = false
break
} }
}, true); document.getElementById("fps-select").value = localSettings.fpsCapDefault
} else {
input.setDefault()
localSettings = {
isCommunityMaps: false,
difficultyMode: '1',
fpsCapDefault: 'max',
runCount: 0,
levelsClearedLastGame: 0,
key: input.key
};
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault
}
input.controlTextUpdate()
window.addEventListener("keydown", function (event) { //**********************************************************************
switch (event.code) { // settings
case input.key.right: //**********************************************************************
case "ArrowRight": document.getElementById("fps-select").addEventListener("input", () => {
input.right = true let value = document.getElementById("fps-select").value
break; if (value === 'max') {
case input.key.left: game.fpsCapDefault = 999999999;
case "ArrowLeft": } else {
input.left = true game.fpsCapDefault = Number(value)
break;
case input.key.up:
case "ArrowUp":
input.up = true
break;
case input.key.down:
case "ArrowDown":
input.down = true
break;
case input.key.field:
input.field = true
break
case input.key.nextGun:
game.nextGun();
break
case input.key.previousGun:
game.previousGun();
break
case input.key.pause:
if (!game.isChoosing && input.isPauseKeyReady) {
input.isPauseKeyReady = false
setTimeout(function () {
input.isPauseKeyReady = true
}, 300);
if (game.paused) {
build.unPauseGrid()
game.paused = false;
level.levelAnnounce();
document.body.style.cursor = "none";
requestAnimationFrame(cycle);
} else {
game.paused = true;
game.replaceTextLog = true;
build.pauseGrid()
document.body.style.cursor = "auto";
}
}
break
case input.key.testing:
if (game.testing) {
game.testing = false;
game.loop = game.normalLoop
if (game.isConstructionMode) {
document.getElementById("construct").style.display = 'none'
}
} else { //if (keys[191])
game.testing = true;
game.isCheating = true;
if (game.isConstructionMode) {
document.getElementById("construct").style.display = 'inline'
}
game.loop = game.testingLoop
}
break
} }
if (game.testing) { localSettings.fpsCapDefault = value
switch (event.key) { localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
case "o": });
game.isAutoZoom = false;
game.zoomScale /= 0.9; document.getElementById("community-maps").addEventListener("input", () => {
game.setZoom(); game.isCommunityMaps = document.getElementById("community-maps").checked
break; localSettings.isCommunityMaps = game.isCommunityMaps
case "i": localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
game.isAutoZoom = false; });
game.zoomScale *= 0.9;
game.setZoom(); // difficulty-select-custom event listener is set in build.makeGrid
break document.getElementById("difficulty-select").addEventListener("input", () => {
case "`": game.difficultyMode = Number(document.getElementById("difficulty-select").value)
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "reroll"); localSettings.difficultyMode = game.difficultyMode
break localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
case "1": localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "heal"); });
break
case "2":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "ammo");
break
case "3":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "gun");
break
case "4":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "field");
break
case "5":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod");
break
case "6":
const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
spawn[pick](game.mouseInGame.x, game.mouseInGame.y);
break
case "7":
const index = body.length
spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50);
body[index].collisionFilter.category = cat.body;
body[index].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
body[index].classType = "body";
World.add(engine.world, body[index]); //add to world
break
case "f":
const mode = (mech.fieldMode === mech.fieldUpgrades.length - 1) ? 0 : mech.fieldMode + 1
mech.setField(mode)
break
case "g":
b.giveGuns("all", 1000)
break
case "h":
mech.addHealth(Infinity)
mech.energy = mech.maxEnergy;
break
case "y":
mod.giveMod()
break
case "r":
Matter.Body.setPosition(player, game.mouseInGame);
Matter.Body.setVelocity(player, {
x: 0,
y: 0
});
// move bots to follow player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
x: 250 * (Math.random() - 0.5),
y: 250 * (Math.random() - 0.5)
}));
Matter.Body.setVelocity(bullet[i], {
x: 0,
y: 0
});
}
}
break
case "u":
level.nextLevel();
break
case "X": //capital X to make it hard to die
mech.death();
break
}
}
}, true);
//********************************************************************** //**********************************************************************
// main loop // main loop

View File

@@ -1038,7 +1038,7 @@ const mobs = {
powerUps.spawnRandomPowerUp(this.position.x, this.position.y); powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in game.checks() mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in game.checks()
if (Math.random() < mod.sporesOnDeath) { if (Math.random() < mod.sporesOnDeath) {
const len = Math.min(30, Math.floor(4 + this.mass * Math.random())) const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
b.spore(this.position) b.spore(this.position)
} }

View File

@@ -362,7 +362,7 @@ const mod = {
requires: "", requires: "",
effect() { effect() {
mod.sporesOnDeath += 0.09; mod.sporesOnDeath += 0.09;
for (let i = 0; i < 10; i++) { for (let i = 0; i < 8; i++) {
b.spore(mech.pos) b.spore(mech.pos)
} }
}, },
@@ -1211,27 +1211,27 @@ const mod = {
if (mod.duplicateChance < 0) mod.duplicateChance = 0 if (mod.duplicateChance < 0) mod.duplicateChance = 0
} }
mod.isBayesian = false mod.isBayesian = false
if (mod.duplicateChance) if (mod.duplicateChance === 0) game.draw.powerUp = game.draw.powerUpNormal
if (!mod.duplicateChance) game.draw.powerUp = game.draw.powerUpNormal
} }
}, },
{ {
name: "stimulated emission", name: "stimulated emission",
description: "<strong>9%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong>", description: "<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
return true return true
}, },
requires: "", requires: "",
effect: () => { effect() {
mod.duplicateChance += 0.09 mod.duplicateChance += 0.08
game.draw.powerUp = game.draw.powerUpBonus //change power up draw game.draw.powerUp = game.draw.powerUpBonus //change power up draw
this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${mod.duplicateChance}</em>`
}, },
remove() { remove() {
mod.duplicateChance -= 0.09 * this.count mod.duplicateChance -= 0.08 * this.count
if (!mod.duplicateChance) game.draw.powerUp = game.draw.powerUpNormal if (mod.duplicateChance === 0) game.draw.powerUp = game.draw.powerUpNormal
this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${mod.duplicateChance}</em>`
} }
}, },
{ {

View File

@@ -1376,7 +1376,7 @@ const mech = {
if (mod.isSporeField) { if (mod.isSporeField) {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones // mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
const len = Math.floor(6 + 4 * Math.random()) const len = Math.floor(6 + 4 * Math.random())
mech.energy -= len * 0.07; mech.energy -= len * 0.09;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
b.spore(mech.pos) b.spore(mech.pos)
} }

View File

@@ -63,10 +63,28 @@ table {
/* background-color: #ddd; */ /* background-color: #ddd; */
} }
th { tr {
padding: 10px;
text-align: left; text-align: left;
} }
td {
padding-left: 10px;
}
.key-input {
padding: 3px 8px;
border: 2px solid #333;
/* border-radius: 50px; */
background-color: #fff;
text-align: center;
}
.key-used {
color: #777;
font-size: 80%;
}
summary { summary {
font-size: 1.2em; font-size: 1.2em;
} }

View File

@@ -6,10 +6,21 @@ new key press detection system
I rewrote some fundamental systems so there may be some bugs I rewrote some fundamental systems so there may be some bugs
testing mode death is now shift X (was x+z) testing mode death is now shift X (was x+z)
you can now change your keys with the controls settings
this is probably buggy too
************** TODO - n-gon ************** ************** TODO - n-gon **************
add custom key settings laser portal field
put in local storage teleport to blocks and map elements in line of sight (like the how the laser works)
do damage to mobs in the path of your teleportation
go immune to damage for 1 second after teleportation
after jumping into the portal you can send things back to your old location, like bullets and blocks, and mobs
add testing key for spawn boss mob
look for mods that could update description text with count and mod.is information
this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${mod.duplicateChance}</em>`
give the power up boss the ability to eject your mobs if it hits you give the power up boss the ability to eject your mobs if it hits you