}
@media (min-width: 15cm) and (min-height: 15cm) {
@container (min-width: calc(100cqh - 4cm - 1rem - 4rem)) {
- .game-upintheair .ui-container.control-touchpad {
+ .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
margin: 0 calc(1rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
align-self: flex-end;
}
}
@container (min-width: calc(100cqh - 4cm - 1rem - 4rem)) and (max-width: calc(100cqh + 2 * 4cm + 2rem)) {
- .game-upintheair .ui-container.control-touchpad {
+ .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
margin: 0 calc(1rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin)))) 0 0;
align-self: flex-end;
}
right: 1rem;
}
@container (min-width: calc(100cqh - 4cm - 2rem)) {
- .game-upintheair .ui-container.control-touchpad {
+ .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
margin: 0 calc(2rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
align-self: flex-end;
}
}
@container (min-width: calc(100cqh - 4cm - 2rem)) and (max-width: calc(100cqh + 2 * 4cm + 4rem)) {
- .game-upintheair .ui-container.control-touchpad {
+ .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
margin: 0 calc(2rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin)))) 0 0;
align-self: flex-end;
}
border-radius: 3%;
border: 2px inset #808080;
}
+ .virtual-input-widget.thumbstick {
+ display: block;
+ background-color: #585858;
+ background-image: radial-gradient(circle, #808080, #484848);
+ border-radius: 50%;
+ border: 2px inset #808080;
+ }
+ .virtual-input-widget.thumbstick .circle {
+ position: relative;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ display: block;
+ width: 50%;
+ aspect-ratio: 1 / 1;
+ border-radius: 50%;
+ background-color: #ccc;
+ background-image: radial-gradient(#ccc 0%, #ccc 20%, #999 25%, #ccc 30%, #ccc 40%, #999 45%, #ccc 50%, #444 100%);
+ box-shadow: 0 0 .3cm #000;
+ }
.ui-page {
position: absolute;
left: 0;
</div>
</div>
<div class="virtual-input-widget">
-
+<div class="circle"></div>
</div>
</div>
<script type="module" src="main.js"></script>
game.objects = {};
game.view = {};
game.view.canvas = canvas;
- game.view.virtualInput = canvas.closest('.game-upintheair').querySelector('.virtual-input-widget');
+ game.ui.virtualInput = canvas.closest('.game-upintheair').querySelector('.virtual-input-widget');
const scene = new THREE.Scene();
game.view.camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
game.controls.positionY = - viewportHeight * viewportY;
}
- function cursorMoveEvent(game, viewportLocalX, viewportLocalY, pressed) {
+ function cursorMoveEvent(game, target, viewportLocalX, viewportLocalY, pressed) {
if(game.settings['controls'] == 'mouse' || game.settings['controls'] == 'touchpad') {
let sensorElem = game.view.canvas;
if(game.settings['controls'] == 'touchpad') {
- sensorElem = game.view.virtualInput;
+ sensorElem = game.ui.virtualInput;
}
let bbox = sensorElem.getBoundingClientRect();
// Intentional division by height instead of width in the following line, since
pinwheelPositionUpdate(game, x, y);
}
}
+ if(game.settings['controls'] == 'thumbstick') {
+ if(!game.ui.virtualInput.inProgress) {
+ return;
+ }
+ let bbox = game.ui.virtualInput.getBoundingClientRect();
+ let x, y;
+ if(pressed) {
+ x = (viewportLocalX - bbox.x - (bbox.width / 2)) / bbox.height;
+ y = (viewportLocalY - bbox.y - (bbox.height / 2)) / bbox.height;
+ let vLen = Math.sqrt(4 * x * x + 4 * y * y);
+ x = x / Math.max(vLen, 0.6);
+ y = y / Math.max(vLen, 0.6);
+ } else {
+ x = 0;
+ y = 0;
+ }
+ let speedScale = 7.0;
+ let deadZone = 0.2;
+ let speedX = x * 2;
+ if(Math.abs(speedX) < deadZone) {
+ speedX = 0.0;
+ }
+ let speedY = y * 2;
+ if(Math.abs(speedY) < deadZone) {
+ speedY = 0.0;
+ }
+ game.controls.speedX = speedScale * speedX;
+ game.controls.speedY = -1 * speedScale * speedY;
+ x *= 0.6;
+ y *= 0.6;
+ game.ui.virtualInput.children[0].style.left = ((0.5 + x) * 100) + '%';
+ game.ui.virtualInput.children[0].style.top = ((0.5 + y) * 100) + '%';
+ }
}
function keyboardEvent(game, key, motion) {
}
}
- document.body.addEventListener('mousemove', e => cursorMoveEvent(game, e.clientX, e.clientY, (e.buttons % 2 == 1)));
- document.body.addEventListener('mousedown', e => cursorMoveEvent(game, e.clientX, e.clientY, (e.buttons % 2 == 1)));
- document.body.addEventListener('mouseup', e => cursorMoveEvent(game, e.clientX, e.clientY, (e.buttons % 2 == 1)));
- document.body.addEventListener('touchmove', e => cursorMoveEvent(game, e.touches[0].clientX, e.touches[0].clientY, true));
+ document.body.addEventListener('mousemove', e => cursorMoveEvent(game, e.target, e.clientX, e.clientY, (e.buttons % 2 == 1)));
+ document.body.addEventListener('mousedown', e => {
+ if(game.settings['controls'] == 'thumbstick') {
+ if(e.target.closest('.virtual-input-widget') == game.ui.virtualInput) {
+ game.ui.virtualInput.inProgress = true;
+ } else {
+ game.ui.virtualInput.inProgress = false;
+ }
+ }
+ cursorMoveEvent(game, e.target, e.clientX, e.clientY, (e.buttons % 2 == 1));
+ });
+ document.body.addEventListener('mouseup', e => {
+ cursorMoveEvent(game, e.target, e.clientX, e.clientY, (e.buttons % 2 == 1));
+ if(game.settings['controls'] == 'thumbstick') {
+ game.ui.virtualInput.inProgress = false;
+ }
+ });
+ document.body.addEventListener('touchmove', e => cursorMoveEvent(game, e.target, e.touches[0].clientX, e.touches[0].clientY, true));
+ document.body.addEventListener('touchstart', e => {
+ if(game.settings['controls'] == 'thumbstick') {
+ if(e.target.closest('.virtual-input-widget') == game.ui.virtualInput) {
+ game.ui.virtualInput.inProgress = true;
+ } else {
+ game.ui.virtualInput.inProgress = false;
+ }
+ }
+ cursorMoveEvent(game, e.target, e.touches[0].clientX, e.touches[0].clientY, true);
+ });
+ document.body.addEventListener('touchend', e => {
+ if(game.settings['controls'] == 'thumbstick') {
+ cursorMoveEvent(game, e.target, 0, 0, false);
+ game.ui.virtualInput.inProgress = false;
+ }
+ });
document.body.addEventListener('keydown', e => keyboardEvent(game, e.key, 'down'));
document.body.addEventListener('keyup', e => keyboardEvent(game, e.key, 'up'));