Snek/src/js/main.js

124 lines
3.5 KiB
JavaScript
Raw Normal View History

2020-03-25 14:57:20 +00:00
(async () => {
location.hash='';
const assets=require('assets');
await new Promise(ok => assets.onReady(ok));
const main=document.querySelector('main');
const nav=main.querySelector('nav');
const canvas=main.querySelector('canvas');
let currentGame=null;
let currentInputs={};
const resizeCanvas=() => {
if(document.fullscreenElement) {
canvas.width=screen.width;
canvas.height=screen.height;
} else {
canvas.width=main.clientWidth;
canvas.height=main.clientHeight;
}
};
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
const levelList=assets.get('levelList');
Object.keys(levelList).forEach(category => {
2020-03-25 17:29:28 +00:00
const cat=levelList[category];
2020-03-25 14:57:20 +00:00
const section=nav.appendChild(document.createElement('section'));
const h1=section.appendChild(document.createElement('h1'));
h1.innerText=category[0].toUpperCase()+category.slice(1)+" Mode";
2020-03-25 17:29:28 +00:00
const p=section.appendChild(document.createElement('p'));
p.innerText=cat.desc;
2020-03-25 14:57:20 +00:00
const ul=section.appendChild(document.createElement('ul'));
2020-03-25 17:29:28 +00:00
cat.levels.forEach((level, i) => {
2020-03-25 14:57:20 +00:00
level=''+level;
const displayName=cat.levelDisplay
.replace(/<n>/g, level)
.replace(/<l>/g, level.toLowerCase());
const fileName=cat.levelFilename
.replace(/<n>/g, level)
.replace(/<l>/g, level.toLowerCase());
const li=ul.appendChild(document.createElement('li'));
const a=li.appendChild(document.createElement('a'));
a.href='#'+category+'/'+fileName;
a.innerText=displayName;
2020-03-25 17:29:28 +00:00
if(cat.levelDesc) {
const span=li.appendChild(document.createElement('span'));
span.innerText=cat.levelDesc[i];
}
2020-03-25 14:57:20 +00:00
});
});
const handleGamepads=() => {
const gp=navigator.getGamepads()[0];
let inputs=currentInputs;
if(!gp || !gp.axes) return;
const magnitude=Math.hypot(gp.axes[0], gp.axes[1]);
const angle=((Math.atan2(gp.axes[0], gp.axes[1])+2*Math.PI)%(2*Math.PI))/Math.PI;
if(magnitude>.5) {
if(angle>.25 && angle <.75) inputs.right=true;
else if(angle>.75 && angle<1.25) inputs.up=true;
else if(angle>1.25 && angle<1.75) inputs.left=true;
else inputs.down=true;
}
};
window.addEventListener('hashchange', async () => {
nav.classList.add('hidden');
const [_, category, filename]=location.hash.match(/([a-zA-Z0-9_-]+?)\/(.+)/);
const rules=levelList[category].rules || {};
const level=await (async () => {
const resp=await fetch('levels/'+filename);
return await resp.json();
})();
const SnekGame=require('snek');
const snek=new SnekGame(level, canvas, rules);
canvas.classList.remove('hidden');
snek.start();
2020-03-25 17:29:28 +00:00
snek.callback=evt => {
if(evt=='tick') {
if(navigator.getGamepads) handleGamepads();
snek.handleInputs(currentInputs);
}
2020-03-25 14:57:20 +00:00
};
currentGame=snek;
2020-03-25 17:29:28 +00:00
//XXX
window.snek=snek;
2020-03-25 14:57:20 +00:00
});
window.addEventListener('keydown', async e => {
2020-03-25 17:29:28 +00:00
if(e.key=='f') {
2020-03-25 14:57:20 +00:00
if(document.fullscreenElement) await document.exitFullscreen();
2020-03-25 17:29:28 +00:00
else await main.requestFullscreen();
2020-03-25 14:57:20 +00:00
resizeCanvas();
}
let inputs=currentInputs;
if(e.key=='ArrowUp') inputs.up=true;
else if(e.key=='ArrowDown') inputs.down=true;
else if(e.key=='ArrowLeft') inputs.left=true;
else if(e.key=='ArrowRight') inputs.right=true;
});
2020-03-26 09:47:22 +00:00
window.addEventListener('touchstart', e => {
let x=e.touches[0].clientX/window.innerWidth-.5;
let y=e.touches[0].clientY/window.innerHeight-.5;
const angle=((Math.atan2(x, y)+2*Math.PI)%(2*Math.PI))/Math.PI;
let inputs=currentInputs;
if(angle>.25 && angle <.75) inputs.right=true;
else if(angle>.75 && angle<1.25) inputs.up=true;
else if(angle>1.25 && angle<1.75) inputs.left=true;
else inputs.down=true;
});
2020-03-25 14:57:20 +00:00
})();