Compare commits
2 commits
2a67ab40ee
...
3a571a9c30
Author | SHA1 | Date | |
---|---|---|---|
3a571a9c30 | |||
b12ac2fab9 |
6 changed files with 103 additions and 14 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"touchscreen": {
|
||||
"enabled": true,
|
||||
"mode": "swipe",
|
||||
"mode": "crosspad",
|
||||
"deadzone": 50,
|
||||
"buffer": false
|
||||
},
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<main>
|
||||
<nav></nav>
|
||||
<canvas class="hidden"></canvas>
|
||||
<div id="hud" class="hidden"></div>
|
||||
</main>
|
||||
<footer>
|
||||
<img src="assets/icon32.png">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
let currentInputs={};
|
||||
let handlers=[];
|
||||
let config;
|
||||
let hud;
|
||||
|
||||
const toAngleMagnitude=(x, y) => {
|
||||
return {
|
||||
|
@ -25,6 +26,26 @@ const handleAngleMagnitude=(x, y, threshold=0, fn=null, clearBuffer=false) => {
|
|||
}
|
||||
|
||||
const handleCrosspad=(() => {
|
||||
const ns='http://www.w3.org/2000/svg';
|
||||
const cross=document.createElementNS(ns, 'svg');
|
||||
cross.classList.add('crosspadOverlay');
|
||||
cross.setAttribute('width', 1000);
|
||||
cross.setAttribute('height', 1000);
|
||||
let dr=document.createElementNS(ns, 'line');
|
||||
dr.setAttribute('x1', 0);
|
||||
dr.setAttribute('y1', 0);
|
||||
dr.setAttribute('x2', 1000);
|
||||
dr.setAttribute('y2', 1000);
|
||||
dr.setAttribute('stroke', 'black');
|
||||
cross.appendChild(dr);
|
||||
let dl=document.createElementNS(ns, 'line');
|
||||
dl.setAttribute('x1', 1000);
|
||||
dl.setAttribute('y1', 0);
|
||||
dl.setAttribute('x2', 0);
|
||||
dl.setAttribute('y2', 1000);
|
||||
dl.setAttribute('stroke', 'black');
|
||||
cross.appendChild(dl);
|
||||
|
||||
const fn=e =>
|
||||
handleAngleMagnitude(
|
||||
e.touches[0].clientX-window.innerWidth/2,
|
||||
|
@ -35,7 +56,9 @@ const handleCrosspad=(() => {
|
|||
);
|
||||
return {
|
||||
touchstart: fn,
|
||||
touchmove: fn
|
||||
touchmove: fn,
|
||||
init: () => hud.appendChild(cross),
|
||||
fini: () => hud.removeChild(cross)
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -112,22 +135,29 @@ const handleGamepads={
|
|||
|
||||
const handleEvent=(type, evt) => {
|
||||
for(let handler of handlers) {
|
||||
console.log(type, handler);
|
||||
let fn=handler[type];
|
||||
if(fn) fn(evt);
|
||||
}
|
||||
};
|
||||
|
||||
const enableHandler=handler => {
|
||||
if(!handlers.includes(handler)) handlers.push(handler);
|
||||
if(!handlers.includes(handler)) {
|
||||
handlers.push(handler);
|
||||
if(handler.init) handler.init();
|
||||
}
|
||||
};
|
||||
const disableHandler=handler => {
|
||||
let idx=handlers.indexOf(handler);
|
||||
if(idx!=-1) handlers.splice(idx, 1);
|
||||
if(idx!=-1) {
|
||||
handlers.splice(idx, 1);
|
||||
if(handler.fini) handler.fini();
|
||||
}
|
||||
};
|
||||
|
||||
const updateConfig=cfg =>
|
||||
config=cfg;
|
||||
const setHud=elem =>
|
||||
hud=elem;
|
||||
|
||||
const clear=() =>
|
||||
Object
|
||||
|
@ -150,5 +180,5 @@ return module.exports={
|
|||
touchscreenJoystick: handleJoystick,
|
||||
touchscreenSwipe: handleSwipe
|
||||
},
|
||||
updateConfig
|
||||
updateConfig, setHud
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
const main=document.querySelector('main');
|
||||
const nav=main.querySelector('nav');
|
||||
const canvas=main.querySelector('canvas');
|
||||
const hud=main.querySelector('#hud');
|
||||
|
||||
// load config
|
||||
const config=assets.get('config'); //TODO use an actual config module
|
||||
|
@ -26,7 +27,7 @@
|
|||
let currentGame=null;
|
||||
|
||||
// forward-declare functions
|
||||
let resizeCanvas, getLevel, startGame, handleWin, handleDeath, menu, help;
|
||||
let resizeCanvas, getLevel, startGame, handleWin, handleDeath, menu, help, restart;
|
||||
|
||||
// handle window resize and fullscreen
|
||||
resizeCanvas=() => {
|
||||
|
@ -119,6 +120,7 @@
|
|||
// setup the DOM
|
||||
nav.classList.add('hidden');
|
||||
canvas.classList.remove('hidden');
|
||||
hud.classList.remove('hidden');
|
||||
|
||||
// push some userdata to the snake
|
||||
snek.userdata={
|
||||
|
@ -142,12 +144,13 @@
|
|||
// setup the DOM
|
||||
nav.classList.remove('hidden');
|
||||
canvas.classList.add('hidden');
|
||||
hud.classList.add('hidden');
|
||||
};
|
||||
|
||||
// display the win popup
|
||||
handleWin=async snek => {
|
||||
// get userdata back
|
||||
const {category, levelId, filename}=snek.userdata;
|
||||
// hide the HUD
|
||||
hud.classList.add('hidden');
|
||||
|
||||
// create and configure popup
|
||||
let popup=new Popup("Finished!");
|
||||
|
@ -171,10 +174,11 @@
|
|||
|
||||
// act on it
|
||||
if(result=='retry') {
|
||||
startGame(category, levelId, filename);
|
||||
restart();
|
||||
} else if(result=='menu') {
|
||||
location.hash='menu';
|
||||
} else if(result=='next') {
|
||||
const {category, levelId}=snek.userdata;
|
||||
let nextId=(+levelId)+1;
|
||||
let {levelString}=getLevel(category, nextId)
|
||||
location.hash=levelString;
|
||||
|
@ -183,8 +187,8 @@
|
|||
|
||||
// display the death popup
|
||||
handleDeath=async snek => {
|
||||
// get userdata back
|
||||
const {category, levelId, filename}=snek.userdata;
|
||||
// hide the HUD
|
||||
hud.classList.add('hidden');
|
||||
|
||||
// create and configure popup
|
||||
let popup=new Popup("Finished!");
|
||||
|
@ -204,12 +208,29 @@
|
|||
|
||||
// act on it
|
||||
if(result=='retry') {
|
||||
startGame(category, levelId, filename);
|
||||
restart();
|
||||
} else if(result=='menu') {
|
||||
location.hash='menu';
|
||||
}
|
||||
};
|
||||
|
||||
// quick restart
|
||||
restart=() => {
|
||||
if(currentGame && currentGame.playing) {
|
||||
const {category, levelId, filename}=currentGame.userdata;
|
||||
startGame(category, levelId, filename);
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', e => {
|
||||
if(e.key=='r') restart();
|
||||
});
|
||||
(() => {
|
||||
let restartbtn=hud.appendChild(document.createElement('span'));
|
||||
restartbtn.classList.add('restart');
|
||||
restartbtn.addEventListener('click', restart);
|
||||
restartbtn.addEventListener('touchend', restart);
|
||||
})();
|
||||
|
||||
// handle page navigation
|
||||
window.addEventListener('hashchange', () => {
|
||||
const hash=location.hash.substr(1);
|
||||
|
@ -222,6 +243,7 @@
|
|||
});
|
||||
|
||||
// enable input methods according to config
|
||||
input.setHud(hud);
|
||||
if(config.keyboard.enabled) {
|
||||
input.enableHandler(input.availableHandlers.keyboard);
|
||||
}
|
||||
|
|
34
src/less/hud.less
Normal file
34
src/less/hud.less
Normal file
|
@ -0,0 +1,34 @@
|
|||
#hud {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
& > * {
|
||||
position: fixed;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.restart {
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
&::before {
|
||||
content: '⟳';
|
||||
font-size: 3rem;
|
||||
opacity: .5;
|
||||
color: @accentfg;
|
||||
}
|
||||
}
|
||||
|
||||
.crosspadOverlay {
|
||||
pointer-events: none;
|
||||
top: 50vh;
|
||||
left: 50vw;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ em {
|
|||
|
||||
header, footer {
|
||||
background: @accentbg;
|
||||
|
||||
|
||||
img {
|
||||
border: 4px solid @accentfg;
|
||||
border-radius: 2px;
|
||||
|
@ -105,3 +105,5 @@ p {
|
|||
// setup the popups
|
||||
@import 'popup';
|
||||
|
||||
// setup the hud
|
||||
@import 'hud';
|
||||
|
|
Loading…
Reference in a new issue