game.objects.pinwheel = new THREE.Mesh(pinwheelGeometry, [null, null, null, null, pinwheelMaterial, null]);
game.objects.pinwheel.position.setY(2);
game.objects.pinwheel.position.setZ(-1);
- game.objects.pinwheel.cameraX = 0;
- game.objects.pinwheel.cameraY = 9999;
+ game.objects.pinwheel.opacity = 0;
scene.add(game.objects.pinwheel);
const startingWindowsillMaterial = new THREE.MeshBasicMaterial({
});
game.objects.startingWindowsill = new THREE.Mesh(new THREE.PlaneGeometry(8, 12), startingWindowsillMaterial);
game.objects.startingWindowsill.position.set(-10.3, -game.courseRadius - 4, -7);
- scene.add(game.objects.startingWindowsill);
const endingWindowsillMaterial = new THREE.MeshBasicMaterial({
map: game.assets.textures.windowsill2,
transparent: true,
function pinwheelPositionUpdate(game, viewportX, viewportY) {
const vFOV = THREE.MathUtils.degToRad(game.view.camera.fov);
const viewportHeight = 2 * Math.tan(vFOV / 2) * (game.view.camera.position.z - game.objects.pinwheel.position.z);
- game.objects.pinwheel.cameraX = viewportHeight * viewportX;
- game.objects.pinwheel.cameraY = - viewportHeight * viewportY;
+ game.controls.positionX = viewportHeight * viewportX;
+ game.controls.positionY = - viewportHeight * viewportY;
}
- function cursorMoveEvent(canvasLocalX, canvasLocalY) {
- const canvasBb = game.view.canvas.getBoundingClientRect();
- // Intentional division by height instead of width in the following line, since
- // three.js controls the vertical FOV. So if we ever change the aspect ratio from 1:1,
- // y will still be in range (-0.5, 0.5), but the range for x will be smaller or larger.
- const x = (canvasLocalX - canvasBb.x - (canvasBb.width / 2)) / canvasBb.height;
- const y = (canvasLocalY - canvasBb.y - (canvasBb.height / 2)) / canvasBb.height;
- pinwheelPositionUpdate(game, x, y);
+ function cursorMoveEvent(game, viewportLocalX, viewportLocalY) {
+ if(game.settings['controls'] == 'mouse') {
+ const canvasBb = game.view.canvas.getBoundingClientRect();
+ // Intentional division by height instead of width in the following line, since
+ // three.js controls the vertical FOV. So if we ever change the aspect ratio from 1:1,
+ // y will still be in range (-0.5, 0.5), but the range for x will be smaller or larger.
+ const x = (viewportLocalX - canvasBb.x - (canvasBb.width / 2)) / canvasBb.height;
+ const y = (viewportLocalY - canvasBb.y - (canvasBb.height / 2)) / canvasBb.height;
+ pinwheelPositionUpdate(game, x, y);
+ }
+ }
+
+ function keyboardEvent(game, key, motion) {
+ if(game.settings['controls'] != 'keyboard') {
+ return;
+ }
+ if(motion == 'down') {
+ if(game.controls.heldKeys.includes(key)) {
+ return;
+ }
+ game.controls.heldKeys.push(key);
+ } else {
+ if(game.controls.heldKeys.includes(key)) {
+ game.controls.heldKeys.splice(game.controls.heldKeys.indexOf(key), 1);
+ }
+ }
+ if(game.settings['keyboard']['tapmode']) {
+ if(motion != 'down') {
+ return;
+ }
+ if(game.settings['keyboard']['up'].includes(key)) {
+ game.controls.speedY = Math.max(0.0, game.controls.speedY + 2.0);
+ }
+ if(game.settings['keyboard']['down'].includes(key)) {
+ game.controls.speedY = Math.min(0.0, game.controls.speedY - 2.0);
+ }
+ if(game.settings['keyboard']['right'].includes(key)) {
+ game.controls.speedX = Math.max(0.0, game.controls.speedX + 2.0);
+ }
+ if(game.settings['keyboard']['left'].includes(key)) {
+ game.controls.speedX = Math.min(0.0, game.controls.speedX - 2.0);
+ }
+ return;
+ }
+ if(motion == 'down' && game.settings['keyboard']['up'].includes(key)) {
+ game.controls.accelY = 15.0;
+ game.controls.speedY = 0.0;
+ }
+ if(motion == 'down' && game.settings['keyboard']['down'].includes(key)) {
+ game.controls.accelY = -15.0;
+ game.controls.speedY = 0.0;
+ }
+ if(motion == 'down' && game.settings['keyboard']['right'].includes(key)) {
+ game.controls.accelX = 15.0;
+ game.controls.speedX = 0.0;
+ }
+ if(motion == 'down' && game.settings['keyboard']['left'].includes(key)) {
+ game.controls.accelX = -15.0;
+ game.controls.speedX = 0.0;
+ }
+ if(motion == 'up' && game.settings['keyboard']['up'].includes(key)) {
+ game.controls.accelY = Math.min(0.0, game.controls.accelY);
+ game.controls.speedY = Math.min(0.0, game.controls.speedY);
+ }
+ if(motion == 'up' && game.settings['keyboard']['down'].includes(key)) {
+ game.controls.accelY = Math.max(0.0, game.controls.accelY);
+ game.controls.speedY = Math.max(0.0, game.controls.speedY);
+ }
+ if(motion == 'up' && game.settings['keyboard']['right'].includes(key)) {
+ game.controls.accelX = Math.min(0.0, game.controls.accelX);
+ game.controls.speedX = Math.min(0.0, game.controls.speedX);
+ }
+ if(motion == 'up' && game.settings['keyboard']['left'].includes(key)) {
+ game.controls.accelX = Math.max(0.0, game.controls.accelX);
+ game.controls.speedX = Math.max(0.0, game.controls.speedX);
+ }
}
- document.body.addEventListener('mousemove', e => cursorMoveEvent(e.clientX, e.clientY));
- document.body.addEventListener('touchmove', e => cursorMoveEvent(e.touches[0].clientX, e.touches[0].clientY));
+ document.body.addEventListener('mousemove', e => cursorMoveEvent(game, e.clientX, e.clientY));
+ document.body.addEventListener('touchmove', e => cursorMoveEvent(game, e.touches[0].clientX, e.touches[0].clientY));
+ document.body.addEventListener('keydown', e => keyboardEvent(game, e.key, 'down'));
+ document.body.addEventListener('keyup', e => keyboardEvent(game, e.key, 'up'));
// All vectors used by the game loop (no allocations inside)
game.var = {};
}
function reset(game) {
+ game.controls = {};
+ game.controls.positionX = 0;
+ game.controls.positionY = 0;
+ game.controls.speedX = 0;
+ game.controls.speedY = 0;
+ game.controls.accelX = 0;
+ game.controls.accelY = 0;
+ game.controls.heldKeys = [];
game.ui.reachedEnd = false;
if(game.settings['graphics'] <= 2 && !game.settings['highcontrast']) {
for(let i = 0; i < 6; i++) {
let delta = Math.min(game.view.clock.getDeltaTime(), 1 / 12) * (game.settings['difficulty']['speed'] / 100);
game.timeProgress = (game.timeProgress + delta);
+ const maxPinwheelSpeed = 8.0;
+ const maxPinwheelDistance = 5.0;
+ game.controls.speedX += delta * game.controls.accelX;
+ game.controls.speedY += delta * game.controls.accelY;
+ game.controls.speedX = Math.min(maxPinwheelSpeed, Math.max(-maxPinwheelSpeed, game.controls.speedX));
+ game.controls.speedY = Math.min(maxPinwheelSpeed, Math.max(-maxPinwheelSpeed, game.controls.speedY));
+ game.controls.positionX += delta * game.controls.speedX;
+ game.controls.positionY += delta * game.controls.speedY;
+ if(game.controls.positionX > maxPinwheelDistance) {
+ game.controls.positionX = maxPinwheelDistance;
+ game.controls.speedX = Math.max(0.0, game.controls.speedX);
+ game.controls.accelX = Math.max(0.0, game.controls.accelX);
+ } else if(game.controls.positionX < -maxPinwheelDistance) {
+ game.controls.positionX = -maxPinwheelDistance;
+ game.controls.speedX = Math.min(0.0, game.controls.speedX);
+ game.controls.accelX = Math.min(0.0, game.controls.accelX);
+ }
+ if(game.controls.positionY > maxPinwheelDistance) {
+ game.controls.positionY = maxPinwheelDistance;
+ game.controls.speedY = Math.max(0.0, game.controls.speedY);
+ game.controls.accelY = Math.max(0.0, game.controls.accelY);
+ } else if(game.controls.positionY < -maxPinwheelDistance) {
+ game.controls.positionY = -maxPinwheelDistance;
+ game.controls.speedY = Math.min(0.0, game.controls.speedY);
+ game.controls.accelY = Math.min(0.0, game.controls.accelY);
+ }
+
game.objects.pinwheel.rotation.z -= 5 * delta;
- game.objects.pinwheel.position.x = game.view.camera.position.x + game.objects.pinwheel.cameraX;
- game.objects.pinwheel.position.y = game.view.camera.position.y + game.objects.pinwheel.cameraY;
+ game.objects.pinwheel.position.x = game.view.camera.position.x + game.controls.positionX;
+ game.objects.pinwheel.position.y = game.view.camera.position.y + game.controls.positionY;
if(game.ui.currentPage != 'gameplay') {
let cameraSwayFactor = 1;
game.objects.feather.position.setX(-11.45 + 12 * Math.min(1, easeInOut(Math.max(0, game.timeProgress - 4) / 4)));
game.objects.feather.position.setY(-game.courseRadius - 4.2 + 4 * Math.min(1, easeInOut(Math.max(0, game.timeProgress - 4) / 4)));
game.objects.feather.position.setZ(-6.6 + 6.6 * Math.min(1, easeInOut(Math.max(0, game.timeProgress - 4) / 4)));
+ if(game.timeProgress > 6 && game.timeProgress < 7) {
+ game.controls.positionX = 0;
+ game.controls.positionY = -3;
+ }
game.objects.pinwheel.material[4].opacity = easeInOut(Math.max(0, (game.timeProgress - 7)));
if(game.timeProgress >= 8) {
game.view.music.offset = 0;
});
btn.innerText = keys.join(' or ');
}
- ui.querySelector('input[value="tapmode"]').checked = !!settings['tapmode'];
+ ui.querySelector('input[value="tapmode"]').checked = !!settings['keyboard']['tapmode'];
game.settings = settings;
}