Mobile First Overhaul: Touch gestures, dual tap/drag, instant responsiveness and ergonomic controls across all mini games
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Magisches Runen-Drehschloss (Cryptex Engine)
|
||||
// Magisches Runen-Drehschloss (Cryptex Engine - Mobile First)
|
||||
(function() {
|
||||
const DIALS = [
|
||||
// Dial 0: Houses
|
||||
@@ -49,9 +49,12 @@
|
||||
const symEl = document.getElementById(`sym${dialIdx}`);
|
||||
const lblEl = document.getElementById(`lbl${dialIdx}`);
|
||||
|
||||
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate(20);
|
||||
if (window.soundFX) window.soundFX.playStoneSlide();
|
||||
|
||||
// Quick flip animation
|
||||
symEl.style.transform = dir > 0 ? 'translateY(15px) scale(0.8)' : 'translateY(-15px) scale(0.8)';
|
||||
symEl.style.opacity = '0.3';
|
||||
symEl.style.transform = dir > 0 ? 'translateY(12px) scale(0.85)' : 'translateY(-12px) scale(0.85)';
|
||||
symEl.style.opacity = '0.4';
|
||||
|
||||
setTimeout(() => {
|
||||
const currentItem = dial[state[dialIdx]];
|
||||
@@ -59,11 +62,42 @@
|
||||
lblEl.innerText = currentItem.name;
|
||||
symEl.style.transform = 'translateY(0) scale(1)';
|
||||
symEl.style.opacity = '1';
|
||||
}, 100);
|
||||
|
||||
if (window.soundFX) window.soundFX.playStoneSlide();
|
||||
}, 80);
|
||||
};
|
||||
|
||||
// Mobile Swipe Handler for each cylinder
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const cyl = document.getElementById(`cylinder${i}`);
|
||||
if (!cyl) continue;
|
||||
|
||||
let startY = 0;
|
||||
let isTouching = false;
|
||||
|
||||
cyl.addEventListener('touchstart', (e) => {
|
||||
if (e.touches.length > 0) {
|
||||
startY = e.touches[0].clientY;
|
||||
isTouching = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
cyl.addEventListener('touchend', (e) => {
|
||||
if (!isTouching) return;
|
||||
isTouching = false;
|
||||
const endY = e.changedTouches[0].clientY;
|
||||
const diff = endY - startY;
|
||||
|
||||
// If swiped more than 20px
|
||||
if (Math.abs(diff) > 20) {
|
||||
e.preventDefault();
|
||||
if (diff < 0) {
|
||||
window.stepDial(i, 1); // Swipe Up -> Next
|
||||
} else {
|
||||
window.stepDial(i, -1); // Swipe Down -> Prev
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.checkCryptex = async function() {
|
||||
if (isUnlocked) return;
|
||||
|
||||
@@ -84,12 +118,15 @@
|
||||
|
||||
if (data.success) {
|
||||
isUnlocked = true;
|
||||
unlockBtn.style.display = 'none';
|
||||
if (unlockBtn) unlockBtn.style.display = 'none';
|
||||
|
||||
if (window.soundFX) {
|
||||
window.soundFX.playKeyChime();
|
||||
window.soundFX.playMagicSuccess();
|
||||
}
|
||||
if (window.navigator && window.navigator.vibrate) {
|
||||
window.navigator.vibrate([60, 100, 150]);
|
||||
}
|
||||
|
||||
// Show golden shine on cylinders
|
||||
document.querySelectorAll('.dial-cylinder').forEach(c => {
|
||||
@@ -111,10 +148,13 @@
|
||||
|
||||
setTimeout(() => {
|
||||
if (successPanel) successPanel.style.display = 'block';
|
||||
}, 800);
|
||||
}, 600);
|
||||
|
||||
} else {
|
||||
if (window.soundFX) window.soundFX.playWhoosh();
|
||||
if (window.navigator && window.navigator.vibrate) {
|
||||
window.navigator.vibrate([40, 40]);
|
||||
}
|
||||
|
||||
const box = document.querySelector('.cryptex-box');
|
||||
box.style.transform = 'translateX(-8px)';
|
||||
|
||||
Reference in New Issue
Block a user