Witam. Mam tutaj kod do swojej gry zrobiony przez sztuczną inteligencję. ale nie wiem jak dodać dźwięki radarów i kroków. i jak potem dodać na stronie. Ktoś ma pomysł?
Oto kod.
<html lang="pl"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Magiczny Warsztat</title>
<meta name="description" content="Uratuj warsztat czarodzieja przed powiększonymi chowańcami w tej dostępnej, magicznej przygodzie!">
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
font-family: Arial, sans-serif;
background-color: #1a1a2e;
color: #ffffff;
overflow: hidden;
}
#gameArea {
width: 100%;
height: 100%;
position: relative;
}
#startMenu, #gameOverMenu, #instructionsMenu {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
background-color: rgba(0,0,0,0.7);
padding: 20px;
border-radius: 10px;
max-width: 80%;
max-height: 80%;
overflow-y: auto;
}
button {
font-size: 1.2em;
padding: 10px 20px;
margin: 10px;
cursor: pointer;
background-color: #4a4e69;
color: #ffffff;
border: none;
border-radius: 5px;
}
#player, .creature, .item {
position: absolute;
transition: all 0.3s ease;
}
#score, #timer, #health, #mana {
position: absolute;
top: 10px;
font-size: 1.2em;
}
#score { left: 10px; }
#timer { right: 10px; }
#health { left: 10px; top: 40px; }
#mana { left: 10px; top: 70px; }
.visually-hidden {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap;
}
#spells {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
}
.spell {
padding: 5px 10px;
background-color: #4a4e69;
border-radius: 5px;
cursor: pointer;
}
#narratorToggle, #instructionsButton {
position: absolute;
top: 10px;
z-index: 1000;
}
#narratorToggle { right: 10px; }
#instructionsButton { right: 150px; }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><style>
body, html {
touch-action: manipulation;
user-select: none;
-webkit-user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
</style></head>
<body>
<div id="gameArea" role="application" aria-label="Magiczny Warsztat">
<div id="startMenu">
<h1>Magiczny Warsztat</h1>
<p>Pomóż czarodziejowi pozbyć się powiększonych chowańców!</p>
<button id="startButton">Rozpocznij grę</button>
<button id="narratorToggle">Włącz/Wyłącz narrację</button>
<button id="instructionsButton">Instrukcje</button>
</div>
<div id="gameOverMenu" style="display: none;">
<h2>Koniec gry!</h2>
<p>Twój wynik: <span id="finalScore"></span></p>
<button id="restartButton">Zagraj ponownie</button>
</div>
<div id="instructionsMenu" style="display: none;">
<h2>Instrukcje</h2>
<p>Dla graczy widzących:</p>
<ul>
<li>Użyj strzałek lub przeciągnij palcem, aby się poruszać</li>
<li>Spacja lub dotknij ekranu, aby strzelać</li>
<li>Użyj klawiszy 1-4, aby rzucać zaklęcia</li>
</ul>
<p>Dla graczy niewidomych:</p>
<ul>
<li>Użyj klawiszy W, A, S, D do poruszania się</li>
<li>Enter, aby strzelać</li>
<li>Klawisze 1, 2, 3, 4 do rzucania zaklęć</li>
</ul>
<button id="closeInstructions">Zamknij instrukcje</button>
</div>
<div id="score" aria-live="polite">Wynik: 0</div>
<div id="timer" aria-live="polite">Czas: 60</div>
<div id="health" aria-live="polite">Życie: 100</div>
<div id="mana" aria-live="polite">Mana: 100</div>
<div id="player" role="img" aria-label="Gracz"></div>
<div id="spells">
<div class="spell" data-spell="fireball">1: Kula ognia</div>
<div class="spell" data-spell="wind">2: Dmący wicher</div>
<div class="spell" data-spell="heal">3: Leczenie zdrowia</div>
<div class="spell" data-spell="firewave">4: Fala ognia</div>
</div>
</div>
<audio id="backgroundMusic" loop="">
<source src="https://assets.caisual.com/games/uoie3tc90zfzu2bv/audio_1.mp3" type="audio/mpeg">
</audio>
<audio id="shootSound">
<source src="https://assets.caisual.com/games/uoie3tc90zfzu2bv/audio_2.ogg" type="audio/ogg">
</audio>
<audio id="hitSound">
<source src="https://assets.caisual.com/games/uoie3tc90zfzu2bv/audio_3.ogg" type="audio/ogg">
</audio>
<audio id="spellSound">
<source src="https://assets.caisual.com/games/uoie3tc90zfzu2bv/audio_4.mp3" type="audio/mpeg">
</audio>
<audio id="itemPickupSound">
<source src="https://assets.caisual.com/games/uoie3tc90zfzu2bv/audio_5.ogg" type="audio/ogg">
</audio>
<audio id="creatureDeathSound">
<source src="https://assets.caisual.com/games/atjotdfp5b3v3epk/creature_death_sound.ogg" type="audio/ogg">
</audio>
<audio id="victorySound">
<source src="https://assets.caisual.com/games/atjotdfp5b3v3epk/victory_trumpet_sound.ogg" type="audio/ogg">
</audio>
<audio id="radarSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/radar_beep.ogg" type="audio/ogg">
</audio>
<audio id="fireballSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/fireball_sound.ogg" type="audio/ogg">
</audio>
<audio id="windSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/wind_sound.ogg" type="audio/ogg">
</audio>
<audio id="healSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/heal_sound.ogg" type="audio/ogg">
</audio>
<audio id="firewaveSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/firewave_sound.ogg" type="audio/ogg">
</audio>
<audio id="healthChangeSound">
<source src="https://assets.caisual.com/games/waqoaa87mw2qs0to/health_change_sound.ogg" type="audio/ogg">
</audio>
<audio id="footstepSound">
<source src="https://assets.caisual.com/games/vgq6qkjrurd156hu/footstep_sound.ogg" type="audio/ogg">
</audio>
<script>
const gameArea = document.getElementById(’gameArea’);
const player = document.getElementById(’player’);
const startMenu = document.getElementById(’startMenu’);
const gameOverMenu = document.getElementById(’gameOverMenu’);
const instructionsMenu = document.getElementById(’instructionsMenu’);
const startButton = document.getElementById(’startButton’);
const restartButton = document.getElementById(’restartButton’);
const instructionsButton = document.getElementById(’instructionsButton’);
const closeInstructionsButton = document.getElementById(’closeInstructions’);
const scoreElement = document.getElementById(’score’);
const timerElement = document.getElementById(’timer’);
const healthElement = document.getElementById(’health’);
const manaElement = document.getElementById(’mana’);
const finalScoreElement = document.getElementById(’finalScore’);
const backgroundMusic = document.getElementById(’backgroundMusic’);
const shootSound = document.getElementById(’shootSound’);
const hitSound = document.getElementById(’hitSound’);
const spellSound = document.getElementById(’spellSound’);
const itemPickupSound = document.getElementById(’itemPickupSound’);
const creatureDeathSound = document.getElementById(’creatureDeathSound’);
const victorySound = document.getElementById(’victorySound’);
const narratorToggle = document.getElementById(’narratorToggle’);
const radarSound = document.getElementById(’radarSound’);
const fireballSound = document.getElementById(’fireballSound’);
const windSound = document.getElementById(’windSound’);
const healSound = document.getElementById(’healSound’);
const firewaveSound = document.getElementById(’firewaveSound’);
const healthChangeSound = document.getElementById(’healthChangeSound’);
const footstepSound = document.getElementById(’footstepSound’);
let score = 0;
let timeLeft = 60;
let health = 100;
let mana = 100;
let gameInterval;
let creatures = [];
let items = [];
let isGameActive = false;
let isShieldActive = false;
let isNarratorEnabled = false;
let radarInterval;
let lastMove = 0;
function startGame() {
startMenu.style.display = 'none’;
instructionsMenu.style.display = 'none’;
isGameActive = true;
score = 0;
timeLeft = 60;
health = 100;
mana = 100;
updateScore();
updateTimer();
updateHealth();
updateMana();
spawnPlayer();
gameInterval = setInterval(gameLoop, 1000);
radarInterval = setInterval(playRadarSound, 2000);
backgroundMusic.play();
if (isNarratorEnabled) {
speak("Gra rozpoczęta. Powodzenia!");
}
}
function gameLoop() {
if (timeLeft > 0) {
timeLeft–;
updateTimer();
if (Math.random() < 0.3) spawnCreature();
if (Math.random() < 0.1) spawnItem();
} else {
endGame();
}
}
function spawnPlayer() {
player.style.left = '50%’;
player.style.top = '90%’;
player.innerHTML = `
<svg width="40" height="40" viewBox="0 0 40 40">
<rect x="10" y="10" width="20" height="30" fill="#4a4e69" />
<circle cx="20" cy="15" r="10" fill="#9a8c98" />
</svg>
`;
}
function spawnCreature() {
const creature = document.createElement(’div’);
creature.className = 'creature’;
creature.role = 'img’;
creature.ariaLabel = 'Chowaniec’;
creature.style.left = Math.random() * (gameArea.clientWidth – 40) + 'px’;
creature.style.top = '0px’;
creature.innerHTML = `
<svg width="40" height="40" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="20" fill="#c9ada7" />
<circle cx="15" cy="15" r="5" fill="#22223b" />
<circle cx="25" cy="15" r="5" fill="#22223b" />
</svg>
`;
gameArea.appendChild(creature);
creatures.push(creature);
moveCreature(creature);
if (isNarratorEnabled) {
speak("Nowy chowaniec pojawił się!");
}
}
function spawnItem() {
const item = document.createElement(’div’);
item.className = 'item’;
item.role = 'img’;
const isHealthPotion = Math.random() < 0.5;
item.ariaLabel = isHealthPotion ? 'Mikstura życia’ : 'Mikstura many’;
item.style.left = Math.random() * (gameArea.clientWidth – 20) + 'px’;
item.style.top = '0px’;
item.innerHTML = `
<svg width="20" height="20" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="10" fill="${isHealthPotion ? '#ff0000′ : '#0000ff’}" />
</svg>
`;
gameArea.appendChild(item);
items.push(item);
moveItem(item);
if (isNarratorEnabled) {
speak(isHealthPotion ? "Pojawiła się mikstura życia!" : "Pojawiła się mikstura many!");
}
}
function moveCreature(creature) {
let pos = 0;
const id = setInterval(frame, 20);
function frame() {
if (pos >= gameArea.clientHeight || !isGameActive) {
clearInterval(id);
if (gameArea.contains(creature)) {
gameArea.removeChild(creature);
creatures = creatures.filter(c => c !== creature);
}
} else {
pos += 2;
creature.style.top = pos + 'px’;
checkCollisionWithPlayer(creature);
}
}
}
function moveItem(item) {
let pos = 0;
const id = setInterval(frame, 20);
function frame() {
if (pos >= gameArea.clientHeight || !isGameActive) {
clearInterval(id);
if (gameArea.contains(item)) {
gameArea.removeChild(item);
items = items.filter(i => i !== item);
}
} else {
pos += 3;
item.style.top = pos + 'px’;
checkItemCollisionWithPlayer(item);
}
}
}
function shoot(x, y) {
const bullet = document.createElement(’div’);
bullet.style.position = 'absolute’;
bullet.style.left = x + 'px’;
bullet.style.top = y + 'px’;
bullet.innerHTML = `
<svg width="10" height="10" viewBox="0 0 10 10">
<circle cx="5" cy="5" r="5" fill="#f2e9e4" />
</svg>
`;
gameArea.appendChild(bullet);
shootSound.play();
const id = setInterval(frame, 20);
function frame() {
y -= 5;
bullet.style.top = y + 'px’;
if (y < 0 || !isGameActive) {
clearInterval(id);
if (gameArea.contains(bullet)) {
gameArea.removeChild(bullet);
}
} else {
checkCollision(bullet);
}
}
}
function castSpell(spellType) {
if (mana < 20) {
if (isNarratorEnabled) {
speak("Niewystarczająca ilość many!");
}
return;
}
mana -= 20;
updateMana();
spellSound.play();
switch (spellType) {
case 'fireball’:
castFireball();
if (isNarratorEnabled) speak("Rzucono kulę ognia!");
break;
case 'wind’:
castWind();
if (isNarratorEnabled) speak("Rzucono dmący wicher!");
break;
case 'heal’:
castHeal();
if (isNarratorEnabled) speak("Rzucono leczenie zdrowia!");
break;
case 'firewave’:
castFireWave();
if (isNarratorEnabled) speak("Rzucono falę ognia!");
break;
}
}
function castFireball() {
const playerRect = player.getBoundingClientRect();
const fireball = document.createElement(’div’);
fireball.style.position = 'absolute’;
fireball.style.left = (playerRect.left + playerRect.width / 2) + 'px’;
fireball.style.top = playerRect.top + 'px’;
fireball.innerHTML = `
<svg width="20" height="20" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="10" fill="#ff4500" />
</svg>
`;
gameArea.appendChild(fireball);
fireballSound.play();
const id = setInterval(frame, 20);
function frame() {
let y = parseInt(fireball.style.top) – 10;
fireball.style.top = y + 'px’;
if (y < 0 || !isGameActive) {
clearInterval(id);
if (gameArea.contains(fireball)) {
gameArea.removeChild(fireball);
}
} else {
checkSpellCollision(fireball, 20);
}
}
}
function castWind() {
windSound.play();
creatures.forEach(creature => {
const creatureRect = creature.getBoundingClientRect();
let newY = creatureRect.top – 100;
if (newY < 0) newY = 0;
creature.style.top = newY + 'px’;
});
}
function castHeal() {
healSound.play();
health = Math.min(health + 30, 100);
updateHealth();
if (isNarratorEnabled) speak("Uleczono 30 punktów zdrowia!");
}
function castFireWave() {
firewaveSound.play();
const playerRect = player.getBoundingClientRect();
const fireWave = document.createElement(’div’);
fireWave.style.position = 'absolute’;
fireWave.style.left = '0px’;
fireWave.style.top = (playerRect.top – 20) + 'px’;
fireWave.style.width = '100%’;
fireWave.style.height = ’20px’;
fireWave.style.backgroundColor = 'rgba(255, 69, 0, 0.7)’;
gameArea.appendChild(fireWave);
setTimeout(() => {
if (gameArea.contains(fireWave)) {
gameArea.removeChild(fireWave);
}
}, 1000);
creatures.forEach(creature => {
const creatureRect = creature.getBoundingClientRect();
if (creatureRect.top < playerRect.top && creatureRect.top > playerRect.top – 100) {
removeCreature(creature);
score += 10;
updateScore();
}
});
}
function checkCollision(bullet) {
const bulletRect = bullet.getBoundingClientRect();
creatures.forEach(creature => {
const creatureRect = creature.getBoundingClientRect();
if (
bulletRect.left < creatureRect.right &&
bulletRect.right > creatureRect.left &&
bulletRect.top < creatureRect.bottom &&
bulletRect.bottom > creatureRect.top
) {
hitSound.play();
removeCreature(creature);
if (gameArea.contains(bullet)) {
gameArea.removeChild(bullet);
}
score += 10;
updateScore();
if (isNarratorEnabled) speak("Trafiono chowańca!");
}
});
}
function checkSpellCollision(spell, damage) {
const spellRect = spell.getBoundingClientRect();
creatures.forEach(creature => {
const creatureRect = creature.getBoundingClientRect();
if (
spellRect.left < creatureRect.right &&
spellRect.right > creatureRect.left &&
spellRect.top < creatureRect.bottom &&
spellRect.bottom > creatureRect.top
) {
hitSound.play();
removeCreature(creature);
score += damage;
updateScore();
if (isNarratorEnabled) speak("Trafiono chowańca zaklęciem!");
}
});
}
function checkCollisionWithPlayer(creature) {
const playerRect = player.getBoundingClientRect();
const creatureRect = creature.getBoundingClientRect();
if (
playerRect.left < creatureRect.right &&
playerRect.right > creatureRect.left &&
playerRect.top < creatureRect.bottom &&
playerRect.bottom > creatureRect.top
) {
if (!isShieldActive) {
health -= 10;
updateHealth();
healthChangeSound.play();
if (isNarratorEnabled) speak("Utracono 10 punktów życia!");
if (health <= 0) {
endGame();
}
} else {
if (isNarratorEnabled) speak("Tarcza ochroniła przed obrażeniami!");
}
removeCreature(creature);
}
}
function checkItemCollisionWithPlayer(item) {
const playerRect = player.getBoundingClientRect();
const itemRect = item.getBoundingClientRect();
if (
playerRect.left < itemRect.right &&
playerRect.right > itemRect.left &&
playerRect.top < itemRect.bottom &&
playerRect.bottom > itemRect.top
) {
if (item.ariaLabel === 'Mikstura życia’) {
health = Math.min(health + 20, 100);
updateHealth();
healthChangeSound.play();
if (isNarratorEnabled) speak("Zebrano miksturę życia! Dodano 20 punktów życia.");
} else {
mana = Math.min(mana + 20, 100);
updateMana();
if (isNarratorEnabled) speak("Zebrano miksturę many! Dodano 20 punktów many.");
}
itemPickupSound.play();
gameArea.removeChild(item);
items = items.filter(i => i !== item);
}
}
function removeCreature(creature) {
if (gameArea.contains(creature)) {
gameArea.removeChild(creature);
creatures = creatures.filter(c => c !== creature);
creatureDeathSound.play();
}
}
function updateScore() {
scoreElement.textContent = `Wynik: ${score}`;
scoreElement.setAttribute(’aria-label’, `Aktualny wynik to ${score} punktów`);
}
function updateTimer() {
timerElement.textContent = `Czas: ${timeLeft}`;
timerElement.setAttribute(’aria-label’, `Pozostało ${timeLeft} sekund`);
}
function updateHealth() {
healthElement.textContent = `Życie: ${health}`;
healthElement.setAttribute(’aria-label’, `Pozostało ${health} punktów życia`);
}
function updateMana() {
manaElement.textContent = `Mana: ${mana}`;
manaElement.setAttribute(’aria-label’, `Pozostało ${mana} punktów many`);
}
function endGame() {
isGameActive = false;
clearInterval(gameInterval);
clearInterval(radarInterval);
finalScoreElement.textContent = score;
gameOverMenu.style.display = 'block’;
backgroundMusic.pause();
backgroundMusic.currentTime = 0;
if (score > 0) {
victorySound.play();
}
if (isNarratorEnabled) {
speak(`Koniec gry! Twój końcowy wynik to ${score} punktów.`);
}
}
function speak(text) {
if (’speechSynthesis’ in window) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'pl-PL’;
speechSynthesis.speak(utterance);
}
}
function playRadarSound() {
if (isGameActive && creatures.length > 0) {
radarSound.play();
}
}
function playFootstepSound() {
footstepSound.currentTime = 0;
footstepSound.play();
}
startButton.addEventListener(’click’, startGame);
restartButton.addEventListener(’click’, startGame);
narratorToggle.addEventListener(’click’, () => {
isNarratorEnabled = !isNarratorEnabled;
if (isNarratorEnabled) {
speak("Narracja włączona");
} else {
speak("Narracja wyłączona");
}
});
instructionsButton.addEventListener(’click’, () => {
instructionsMenu.style.display = 'block’;
});
closeInstructionsButton.addEventListener(’click’, () => {
instructionsMenu.style.display = 'none’;
});
document.addEventListener(’keydown’, (e) => {
if (!isGameActive) return;
const playerRect = player.getBoundingClientRect();
const now = Date.now();
switch(e.key.toLowerCase()) {
case 'arrowleft’:
case 'a’:
player.style.left = Math.max(0, playerRect.left – 10) + 'px’;
if (now – lastMove > 300) {
playFootstepSound();
lastMove = now;
}
break;
case 'arrowright’:
case 'd’:
player.style.left = Math.min(gameArea.clientWidth – playerRect.width, playerRect.left + 10) + 'px’;
if (now – lastMove > 300) {
playFootstepSound();
lastMove = now;
}
break;
case 'arrowup’:
case 'w’:
player.style.top = Math.max(0, playerRect.top – 10) + 'px’;
if (now – lastMove > 300) {
playFootstepSound();
lastMove = now;
}
break;
case 'arrowdown’:
case 's’:
player.style.top = Math.min(gameArea.clientHeight – playerRect.height, playerRect.top + 10) + 'px’;
if (now – lastMove > 300) {
playFootstepSound();
lastMove = now;
}
break;
case ’ ’:
case 'enter’:
shoot(playerRect.left + playerRect.width / 2, playerRect.top);
break;
case '1′:
castSpell(’fireball’);
break;
case '2′:
castSpell(’wind’);
break;
case '3′:
castSpell(’heal’);
break;
case '4′:
castSpell(’firewave’);
break;
}
});
let touchStartX, touchStartY;
gameArea.addEventListener(’touchstart’, (e) => {
if (!isGameActive) return;
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
});
gameArea.addEventListener(’touchmove’, (e) => {
if (!isGameActive) return;
const touchEndX = e.touches[0].clientX;
const touchEndY = e.touches[0].clientY;
const deltaX = touchEndX – touchStartX;
const deltaY = touchEndY – touchStartY;
const playerRect = player.getBoundingClientRect();
const newLeft = Math.min(Math.max(0, playerRect.left + deltaX), gameArea.clientWidth – playerRect.width);
const newTop = Math.min(Math.max(0, playerRect.top + deltaY), gameArea.clientHeight – playerRect.height);
player.style.left = newLeft + 'px’;
player.style.top = newTop + 'px’;
const now = Date.now();
if (now – lastMove > 300) {
playFootstepSound();
lastMove = now;
}
touchStartX = touchEndX;
touchStartY = touchEndY;
});
gameArea.addEventListener(’touchend’, (e) => {
if (!isGameActive) return;
const playerRect = player.getBoundingClientRect();
shoot(playerRect.left + playerRect.width / 2, playerRect.top);
});
document.querySelectorAll(’.spell’).forEach(spellElement => {
spellElement.addEventListener(’click’, () => {
if (isGameActive) {
castSpell(spellElement.dataset.spell);
}
});
});
footstepSound.volume = 1.0; // Increase volume to maximum
</script>
<script>
(function() {
var originalConsoleError = console.error;
console.error = function() {
window.parent.postMessage({
type: 'error’,
message: Array.from(arguments).join(’ ’)
}, '*’);
originalConsoleError.apply(console, arguments);
};
window.addEventListener(’error’, function(event) {
window.parent.postMessage({
type: 'error’,
message: event.message,
source: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error ? event.error.stack : null
}, '*’);
});
window.addEventListener(’unhandledrejection’, function(event) {
window.parent.postMessage({
type: 'error’,
message: 'Unhandled Promise Rejection: ’ + event.reason,
error: event.reason ? event.reason.stack : null
}, '*’);
});
})();
</script><script defer="" src="https://static.cloudflareinsights.com/beacon.min.js/vcd15cbe7772f49c399c6a5babf22c1241717689176015" integrity="sha512-ZpsOmlRQV6y907TI0dKBHq9Md29nnaEIPlkf84rnaERnq6zvWvPUqr2ft8M1aS28oN72PdrCzSjY4U6VaAw1EQ==" data-cf-beacon="{"rayId":"8c5c8f6d2961bf44","version":"2024.8.0","r":1,"token":"5562e2e56e7244b2af1869a8c731adb3","serverTiming":{"name":{"cfExtPri":true,"cfL4":true}}}" crossorigin="anonymous"></script>
<script>
let lastTouchEnd = 0;
document.addEventListener(’touchstart’, function(e) {
if (e.touches.length > 1) {
e.preventDefault();
}
}, { passive: false });
document.addEventListener(’touchend’, function(e) {
const now = (new Date()).getTime();
if (now – lastTouchEnd <= 300) {
e.preventDefault();
}
lastTouchEnd = now;
}, false);
document.addEventListener(’touchmove’, function(e) {
if (e.touches.length > 1) {
e.preventDefault();
}
}, { passive: false });
</script></body></html>