parent
9db9b742fa
commit
39e761d334
@ -0,0 +1,152 @@ |
|||||||
|
let currentInputs={}; |
||||||
|
let handlers=[]; |
||||||
|
let config; |
||||||
|
|
||||||
|
const toAngleMagnitude=(x, y) => { |
||||||
|
return { |
||||||
|
angle: ((Math.atan2(x, y)+2*Math.PI)%(2*Math.PI))/Math.PI, |
||||||
|
magnitude: Math.hypot(x, y) |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
const handleAngleMagnitude=(x, y, threshold=0, fn=null, clearBuffer=false) => { |
||||||
|
const {angle, magnitude}=toAngleMagnitude(x, y); |
||||||
|
|
||||||
|
if(magnitude>threshold) { |
||||||
|
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; |
||||||
|
|
||||||
|
if(clearBuffer) inputs.clearBuffer=true; |
||||||
|
if(fn) fn(angle, magnitude); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const handleCrosspad=(() => { |
||||||
|
const fn=e => |
||||||
|
handleAngleMagnitude( |
||||||
|
e.touches[0].clientX-window.innerWidth/2, |
||||||
|
e.touches[0].clientY-window.innerHeight/2, |
||||||
|
0, |
||||||
|
null, |
||||||
|
!config.touchscreen.buffer |
||||||
|
); |
||||||
|
return { |
||||||
|
touchstart: fn, |
||||||
|
touchmove: fn |
||||||
|
}; |
||||||
|
})(); |
||||||
|
|
||||||
|
const handleKeyboard={ |
||||||
|
keydown: e => { |
||||||
|
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; |
||||||
|
|
||||||
|
if(!config.keyboard.buffer) inputs.clearBuffer=true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const handleJoystick=(() => { |
||||||
|
let center={ |
||||||
|
x: 0, |
||||||
|
y: 0 |
||||||
|
}; |
||||||
|
return { |
||||||
|
touchstart: e => { |
||||||
|
center.x=e.touches[0].clientX; |
||||||
|
center.y=e.touches[0].clientY; |
||||||
|
}, |
||||||
|
touchmove: e => |
||||||
|
handleAngleMagnitude( |
||||||
|
e.touches[0].clientX-center.x, |
||||||
|
e.touches[0].clientY-center.y, |
||||||
|
config.touchscreen.deadzone, |
||||||
|
null, |
||||||
|
!config.touchscreen.buffer |
||||||
|
) |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
const handleSwipe=(() => { |
||||||
|
let center={ |
||||||
|
x: 0, |
||||||
|
y: 0 |
||||||
|
}; |
||||||
|
let resetCenter=e => { |
||||||
|
center.x=e.touches[0].clientX; |
||||||
|
center.y=e.touches[0].clientY; |
||||||
|
}; |
||||||
|
return { |
||||||
|
touchstart: resetCenter, |
||||||
|
touchmove: e => |
||||||
|
handleAngleMagnitude( |
||||||
|
e.touches[0].clientX-center.x, |
||||||
|
e.touches[0].clientY-center.y, |
||||||
|
config.touchscreen.deadzone, |
||||||
|
() => resetCenter(e), |
||||||
|
!config.touchscreen.buffer |
||||||
|
) |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
const handleGamepads={ |
||||||
|
frame: () => { |
||||||
|
const gp=navigator.getGamepads()[0]; |
||||||
|
let inputs=currentInputs; |
||||||
|
if(!gp || !gp.axes) return; |
||||||
|
|
||||||
|
handleAngleMagnitude( |
||||||
|
gp.axes[0], |
||||||
|
gp.axes[1], |
||||||
|
config.gamepad.deadzone, |
||||||
|
null, |
||||||
|
!config.gamepad.buffer |
||||||
|
); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const handleEvent=(type, evt) => { |
||||||
|
for(let handler of handlers) { |
||||||
|
let fn=handler[type]; |
||||||
|
if(fn) fn(evt); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const enableHandler=handler => { |
||||||
|
if(!handlers.includes(handler)) handlers.push(handler); |
||||||
|
}; |
||||||
|
const disableHandler=handler => { |
||||||
|
let idx=handlers.indexOf(handler); |
||||||
|
if(idx!=-1) handlers.splice(idx, 1); |
||||||
|
}; |
||||||
|
|
||||||
|
const updateConfig=cfg => |
||||||
|
config=cfg; |
||||||
|
|
||||||
|
const clear=() => |
||||||
|
Object |
||||||
|
.keys(currentInputs) |
||||||
|
.forEach(key => delete currentInputs[key]); |
||||||
|
|
||||||
|
for(let type of ['keydown', 'touchstart', 'touchmove']) { |
||||||
|
window.addEventListener(type, handleEvent.bind(null, type)); |
||||||
|
} |
||||||
|
|
||||||
|
return module.exports={ |
||||||
|
inputs: currentInputs, |
||||||
|
clear, |
||||||
|
enableHandler, disableHandler, |
||||||
|
framefn: handleEvent.bind(null, 'frame'), |
||||||
|
availableHandlers: { |
||||||
|
keyboard: handleKeyboard, |
||||||
|
gamepad: handleGamepads, |
||||||
|
touchscreenCrosspad: handleCrosspad, |
||||||
|
touchscreenJoystick: handleJoystick, |
||||||
|
touchscreenSwipe: handleSwipe |
||||||
|
}, |
||||||
|
updateConfig |
||||||
|
}; |
@ -0,0 +1,18 @@ |
|||||||
|
const cache=Object.create(null); |
||||||
|
|
||||||
|
const get=async filename => { |
||||||
|
if(cache[filename]) return cache[filename]; |
||||||
|
const req=await fetch('levels/'+filename); |
||||||
|
const json=await req.json(); |
||||||
|
return cache[filename]=json; |
||||||
|
}; |
||||||
|
|
||||||
|
const clearCache=() => |
||||||
|
Object |
||||||
|
.keys(cache) |
||||||
|
.forEach(key => delete cache[key]); |
||||||
|
|
||||||
|
return module.exports={ |
||||||
|
get, |
||||||
|
clearCache |
||||||
|
}; |
Loading…
Reference in new issue