[JavaScript] Tworzymy grę dotykową
Wczoraj wpadłem na pomysł, aby napisać jakiś artykuł o Touch events W JavaScript. W dobie smartfonów obsługa dotykowa to teraz podstawa, więc myślę, że dobrze będzie wiedzieć co nieco. Aby pokazać praktyczne wykorzystanie obsługi ekranu dotykiem stworzymy prostą grę.
Zamierzenie jest takie - na ekranie mają zostać wyświetlone elementy (np. kółka) o różnych rozmiarach, poruszające się w różnych kierunkach. Po tapnięciu przez użytkownika danego elementu, ma on znikać. Po usunięciu wszystkich elementów użytkownik powinien zobaczyć stosowny komunikat.
Kod HTML
Zacznijmy od utworzenia prostego dokumentu HTML. Na tym etapie stworzymy od razu div z licznikiem usuniętych elementów oraz div z komunikatem o wygranej. Zostanie on wyświetlony, gdy użytkownik usunie wszystkie kółka z planszy.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tapnij i usuń</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #1e1e1e;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
color: white;
font-family: 'Arial', sans-serif;
position: relative;
}
.circl {
position: absolute;
border-radius: 50%;
pointer-events: auto;
}
.circl-part {
transition: opacity 0.5s ease-out;
position: absolute;
border-radius: 50%;
pointer-events: none;
opacity: 1;
}
.counter {
position: absolute;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
border-radius: 5px;
padding: 5px;
font-size: 25px;
}
.message {
animation: popup 0.5s forwards;
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 10px;
background: rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 25px;
color: #ffffff;
}
/* Tworzymy animację dla komunikatu */
@keyframes popup {
from {
transform: translate(-50%, -60%);
opacity: 0;
}
to {
transform: translate(-50%, -50%);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="counter">Twój wynik: <span id="removedCount">0</span></div>
<div class="message" id="win">Gratulacje! Wygrałeś!</div>
</body>
</html>
Kod JavaScript
Kod naszej gry:
// Definiujemy kolory dla elementów
const colors = ["#FF5733", "#33FF57", "#3357FF", "#F1C40F", "#9B59B6", "#E74C3C"];
const NUM_CIRCL = 25; // Definiujemy ilość elementów
let removedCount = 0; // Ilość usuniętych elementów
const removedCountDisplay = document.getElementById('removedCount');
const winMessage = document.getElementById('win');
function removeCirclLogic(circl) {
const numCirclParts = 25;
for(let i = 0; i < numCirclParts; i++) {
const circlPart = document.createElement('div');
const size = Math.random() * 10 + 5;
circlPart.style.width = `${size}px`;
circlPart.style.height = `${size}px`;
circlPart.style.backgroundColor = circl.style.backgroundColor;
circlPart.classList.add('circl-part');
document.body.appendChild(circlPart);
const circlRect = circl.getBoundingClientRect();
circlPart.style.position = 'absolute';
circlPart.style.top = `${circlRect.top + window.scrollY + circlRect.height / 2}px`;
circlPart.style.left = `${circlRect.left + window.scrollX + circlRect.width / 2}px`;
const angle = Math.random() * 2 * Math.PI;
const distance = Math.random() * 100 + 20;
circlPart.style.transition = 'transform 0.5s ease, opacity 0.5s ease';
circlPart.style.transform = `translate(${Math.cos(angle) * distance}px, ${Math.sin(angle) * distance}px)`;
setTimeout(() => {
circlPart.style.opacity = '0';
setTimeout(() => {
circlPart.remove();
}, 500);
}, 100);
}
circl.remove();
updateRemovedCount();
}
for(let i = 0; i < NUM_CIRCL; i++) {
const circl = document.createElement("div");
const size = Math.random() * 50 + 10; // Generujemy losowy rozmiar elementu
circl.style.width = `${size}px`;
circl.style.height = `${size}px`;
circl.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
circl.classList.add("circl");
// Losowa pozycja elementu
circl.style.top = `${Math.random() * window.innerHeight}px`;
circl.style.left = `${Math.random() * window.innerWidth}px`;
// Wstawiamy wygenerowane elementy do <body>
document.body.appendChild(circl);
function showWinMessage() {
winMessage.style.display = 'block';
setTimeout(() => {
winMessage.style.display = 'none';}, 3000);
}
function updateRemovedCount() {
removedCount++;
removedCountDisplay.textContent = removedCount;
if(removedCount === NUM_DOTS) {
showWinMessage();
}
}
// Dodajemy event listeners do usuwania elementu po tapnięciu lub kliknięciu myszką
circl.addEventListener('click', () => {
removeCirclLogic(circl);
updateRemovedCount();
});
circl.addEventListener('touchstart', () => {
removeCirclLogic(circl);
});
animatedCircl(circl);
}
function animatedCircl(circl) {
let deltaX = (Math.random() - 0.5) * 2;
let deltaY = (Math.random() - 0.5) * 2;
function move() {
let rect = circl.getBoundingClientRect();
let newX = rect.left + deltaX;
let newY = rect.top + deltaY;
// Sprawdzamy granice ekranu
if(newX + rect.width > window.innerWidth || newX < 0) {
deltaX *= -1; // zmiana kierunku w poziomie
}
if(newY + rect.height > window.innerHeight || newY < 0) {
deltaY *= -1; // zmiana kierunku w pionie
}
circl.style.left = newX + 'px';
circl.style.top = newY + 'px';
requestAnimationFrame(move);
}
move();
}
Ciąg dalszy nastąpi...
Komentarze
Prześlij komentarz
Dzięki za komentarz!