"use strict";
//collision groups
// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield | cat.phased
const cat = {
player: 0x1,
map: 0x10,
body: 0x100,
bullet: 0x1000,
powerUp: 0x10000,
mob: 0x100000,
mobBullet: 0x1000000,
mobShield: 0x10000000,
phased: 0x100000000,
}
function shuffle(array) {
var currentIndex = array.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
// shrink power up selection menu to find window height
if (screen.height < 800) {
document.getElementById("choose-grid").style.fontSize = "1em"; //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?
// &gun1=minigun&gun2=laser
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot&field=phase%20decoherence%20field&difficulty=2
//add ? to end of url then for each power up add
// &gun1=name&gun2=name
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot
// &field=phase%20decoherence%20field
// &difficulty=2
//use %20 for spaces
//difficulty is 0 easy, 1 normal, 2 hard, 4 why
function getUrlVars() {
let vars = {};
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, k, v) {
vars[k] = v;
});
return vars;
}
window.addEventListener('load', (event) => {
const set = getUrlVars()
if (Object.keys(set).length !== 0) {
openCustomBuildMenu();
//add custom selections based on url
for (const property in set) {
set[property] = set[property].replace(/%20/g, " ")
set[property] = set[property].replace(/%CE%A8/g, "Ψ")
if (property === "field") {
let found = false
let index
for (let i = 0; i < mech.fieldUpgrades.length; i++) {
if (set[property] === mech.fieldUpgrades[i].name) {
index = i;
found = true;
break;
}
}
if (found) build.choosePowerUp(document.getElementById(`field-${index}`), index, 'field')
}
if (property.substring(0, 3) === "gun") {
let found = false
let index
for (let i = 0; i < b.guns.length; i++) {
if (set[property] === b.guns[i].name) {
index = i;
found = true;
break;
}
}
if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun')
}
if (property.substring(0, 3) === "mod") {
for (let i = 0; i < mod.mods.length; i++) {
if (set[property] === mod.mods[i].name) {
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true)
break;
}
}
}
if (property === "difficulty") {
game.difficultyMode = Number(set[property])
document.getElementById("difficulty-select-custom").value = Number(set[property])
}
if (property === "level") {
document.getElementById("starting-level").value = Number(set[property])
}
if (property === "noPower") {
document.getElementById("no-power-ups").checked = Number(set[property])
}
}
}
});
//**********************************************************************
//set up canvas
//**********************************************************************
var canvas = document.getElementById("canvas");
//using "const" causes problems in safari when an ID shares the same name.
const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#fff";
//disable pop up menu on right click
document.oncontextmenu = function() {
return false;
}
function setupCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.width2 = canvas.width / 2; //precalculated because I use this often (in mouse look)
canvas.height2 = canvas.height / 2;
canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
// ctx.font = "18px Arial";
// ctx.textAlign = "center";
ctx.font = "25px Arial";
ctx.lineJoin = "round";
ctx.lineCap = "round";
// ctx.lineCap='square';
game.setZoom();
}
setupCanvas();
window.onresize = () => {
setupCanvas();
};
//**********************************************************************
// custom build grid display and pause
//**********************************************************************
const build = {
onLoadPowerUps() {
const set = getUrlVars()
if (Object.keys(set).length !== 0) {
for (const property in set) {
set[property] = set[property].replace(/%20/g, " ")
if (property.substring(0, 3) === "gun") b.giveGuns(set[property])
if (property.substring(0, 3) === "mod") mod.giveMod(set[property])
if (property === "field") mech.setField(set[property])
if (property === "difficulty") {
game.difficultyMode = Number(set[property])
document.getElementById("difficulty-select").value = Number(set[property])
}
if (property === "level") {
level.levelsCleared += Number(set[property]);
level.difficultyIncrease(Number(set[property]) * game.difficultyMode) //increase difficulty based on modes
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
level.onLevel++
}
}
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
if (b.inventory.length > 0) {
b.activeGun = b.inventory[0] //set first gun to active gun
game.makeGunHUD();
}
}
},
pauseGrid() {
let text = ""
if (!game.isChoosing) text += `
`;
let countGuns = 0
let countMods = 0
for (let i = 0, len = b.guns.length; i < len; i++) {
if (b.guns[i].have) {
text += `
${b.guns[i].name} - ${b.guns[i].ammo}
${b.guns[i].description}
`
countGuns++
}
}
let el = document.getElementById("pause-grid-left")
el.style.display = "grid"
el.innerHTML = text
text = "";
text += `
${mech.fieldUpgrades[mech.fieldMode].name}
${mech.fieldUpgrades[mech.fieldMode].description}
`
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (mod.mods[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : "";
if (mod.mods[i].isFieldMod) {
text += `
${mod.mods[i].name} ${isCount}
${mod.mods[i].description}
`
} else if (mod.mods[i].isGunMod) {
text += `
${mod.mods[i].name} ${isCount}
${mod.mods[i].description}
`
} else {
text += `
${mod.mods[i].name} ${isCount}
${mod.mods[i].description}
`
}
// if (mod.mods[i].count === 1) {
// text += `
${mod.mods[i].name}
${mod.mods[i].description}
`
// } else {
// text += `
${mod.mods[i].name} (${mod.mods[i].count}x)
${mod.mods[i].description}
`
// }
countMods++
}
}
el = document.getElementById("pause-grid-right")
el.style.display = "grid"
el.innerHTML = text
if (countMods > 5 || countGuns > 6) {
document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden";
}
},
unPauseGrid() {
document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
window.scrollTo(0, 0);
},
isCustomSelection: true,
choosePowerUp(who, index, type, isAllowed = false) {
if (type === "gun") {
let isDeselect = false
for (let i = 0, len = b.inventory.length; i < len; i++) { //look for selection in inventory
if (b.guns[b.inventory[i]].name === b.guns[index].name) { //if already clicked, remove gun
isDeselect = true
who.classList.remove("build-gun-selected");
//remove gun
b.inventory.splice(i, 1)
b.guns[index].count = 0;
b.guns[index].have = false;
if (b.guns[index].ammo != Infinity) b.guns[index].ammo = 0;
if (b.inventory.length === 0) b.activeGun = null;
game.makeGunHUD();
break
}
}
if (!isDeselect) { //add gun
who.classList.add("build-gun-selected");
b.giveGuns(index)
}
} else if (type === "field") {
if (mech.fieldMode !== index) {
document.getElementById("field-" + mech.fieldMode).classList.remove("build-field-selected");
mech.setField(index)
who.classList.add("build-field-selected");
}
} else if (type === "mod") { //remove mod if you have too many
if (mod.mods[index].count < mod.mods[index].maxCount) {
if (!who.classList.contains("build-mod-selected")) who.classList.add("build-mod-selected");
mod.giveMod(index)
} else {
mod.removeMod(index);
who.classList.remove("build-mod-selected");
}
}
//update mod text //disable not allowed mods
for (let i = 0, len = mod.mods.length; i < len; i++) {
const modID = document.getElementById("mod-" + i)
if (!mod.mods[i].isCustomHide) {
if (mod.mods[i].allowed() || isAllowed || mod.mods[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : "";
if (mod.mods[i].isFieldMod) {
modID.innerHTML = `