Compare commits
No commits in common. "5635808d34811a1642a29fe686526cd2597cf5e0" and "5d1e90403e382b3298ed269c387aa11702676f60" have entirely different histories.
5635808d34
...
5d1e90403e
208
2048.css
208
2048.css
@ -1,146 +1,104 @@
|
|||||||
/* ======================
|
|
||||||
GLOBAL
|
|
||||||
====================== */
|
|
||||||
body {
|
body {
|
||||||
background: radial-gradient(circle at center, #0a0a0a, #000);
|
background-color: black;
|
||||||
background-size: 300% 300%;
|
color: white; /* opsional, biar teks tetap terlihat */
|
||||||
animation: bgMove 15s infinite alternate;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
font-family: 'Poppins', sans-serif;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Background animasi lembut */
|
hr {
|
||||||
@keyframes bgMove {
|
width: 500px;
|
||||||
0% { background-position: 0% 30%; }
|
|
||||||
50% { background-position: 50% 70%; }
|
|
||||||
100% { background-position: 100% 30%; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 40px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-shadow: 0 0 20px #00eaff, 0 0 40px #0099ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 12px 22px;
|
|
||||||
margin: 8px;
|
|
||||||
background: #111;
|
|
||||||
color: white;
|
|
||||||
border: 2px solid #00eaff;
|
|
||||||
border-radius: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.25s;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
box-shadow: 0 0 15px #00eaff;
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
#score {
|
|
||||||
color: #00eaff;
|
|
||||||
text-shadow: 0 0 10px #00eaff;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================
|
|
||||||
BOARD
|
|
||||||
====================== */
|
|
||||||
|
|
||||||
|
|
||||||
/* ==========================
|
|
||||||
BOARD — MIRIP BORDER LOGIN
|
|
||||||
========================== */
|
|
||||||
|
|
||||||
#board {
|
#board {
|
||||||
width: 460px;
|
width: 400px;
|
||||||
height: 460px;
|
height: 400px;
|
||||||
margin: 35px auto;
|
background-color: black;
|
||||||
padding: 20px;
|
margin: 0 auto;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
grid-template-rows: repeat(4, 1fr);
|
grid-template-rows: repeat(4, 1fr);
|
||||||
gap: 12px;
|
gap: 5px;
|
||||||
|
padding: 10px;
|
||||||
background: rgba(30, 0, 50, 0.6); /* DALAM GELAP SAMA LOGIN */
|
box-sizing: border-box;
|
||||||
backdrop-filter: blur(10px);
|
border: 2px solid red;
|
||||||
|
box-shadow: 0 0 20px red, 0 0 40px red, 0 0 60px red;
|
||||||
border: 2px solid rgba(0, 217, 255, 0.3); /* SAMA LOGIN */
|
border-radius: 15px;
|
||||||
border-radius: 20px;
|
|
||||||
|
|
||||||
box-shadow:
|
|
||||||
0 20px 60px rgba(0, 0, 0, 0.5),
|
|
||||||
0 0 40px rgba(0, 217, 255, 0.3),
|
|
||||||
inset 0 0 30px rgba(0, 217, 255, 0.1);
|
|
||||||
|
|
||||||
animation: glowBorderBoard 3s ease-in-out infinite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Border berubah warna seperti login */
|
|
||||||
@keyframes glowBorderBoard {
|
|
||||||
0%, 100% {
|
|
||||||
border-color: rgba(0, 217, 255, 0.4);
|
|
||||||
box-shadow:
|
|
||||||
0 20px 60px rgba(0, 0, 0, 0.5),
|
|
||||||
0 0 40px rgba(0, 217, 255, 0.3),
|
|
||||||
inset 0 0 30px rgba(0, 217, 255, 0.1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
border-color: rgba(255, 0, 255, 0.5);
|
|
||||||
box-shadow:
|
|
||||||
0 20px 60px rgba(0, 0, 0, 0.5),
|
|
||||||
0 0 50px rgba(255, 0, 255, 0.4),
|
|
||||||
inset 0 0 40px rgba(255, 0, 255, 0.15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ======================
|
|
||||||
TILE
|
|
||||||
====================== */
|
|
||||||
.tile {
|
.tile {
|
||||||
width: 100%;
|
font-size: 40px;
|
||||||
height: 100%;
|
|
||||||
border-radius: 14px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
font-size: 32px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* colored tiles */
|
||||||
|
|
||||||
|
.x2 {
|
||||||
|
background-color: #eee4da;
|
||||||
|
color: #727371;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x4 {
|
||||||
|
background-color: #ece0ca;
|
||||||
|
color: #727371;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x8 {
|
||||||
|
background-color: #f4b17a;
|
||||||
color: white;
|
color: white;
|
||||||
background: rgba(255, 255, 255, 0.06);
|
|
||||||
text-shadow: 0 0 10px white;
|
|
||||||
|
|
||||||
transition: 0.1s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* animasi tile baru */
|
.x16{
|
||||||
.tile.new {
|
background-color: #f59575;
|
||||||
animation: pop 0.25s ease-out;
|
color: white;
|
||||||
}
|
|
||||||
@keyframes pop {
|
|
||||||
0% { transform: scale(0.2); opacity: 0; }
|
|
||||||
100% { transform: scale(1); opacity: 1; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Neon warna berdasarkan angka */
|
.x32{
|
||||||
.tile-2 { background: #00eaff55; box-shadow: 0 0 10px #00eaff; }
|
background-color: #f57c5f;
|
||||||
.tile-4 { background: #00ff9955; box-shadow: 0 0 10px #00ff99; }
|
color: white;
|
||||||
.tile-8 { background: #ff00ff55; box-shadow: 0 0 10px #ff00ff; }
|
}
|
||||||
.tile-16 { background: #ff006655; box-shadow: 0 0 10px #ff0066; }
|
|
||||||
.tile-32 { background: #ffaa0055; box-shadow: 0 0 10px #ffaa00; }
|
|
||||||
.tile-64 { background: #ff000055; box-shadow: 0 0 10px #ff0000; }
|
|
||||||
.tile-128 { background: #5f00ff55; box-shadow: 0 0 10px #5f00ff; }
|
|
||||||
.tile-256 { background: #00ffea55; box-shadow: 0 0 10px #00ffea; }
|
|
||||||
.tile-512 { background: #ff00aa55; box-shadow: 0 0 10px #ff00aa; }
|
|
||||||
.tile-1024 { background: #00ffaa55; box-shadow: 0 0 10px #00ffaa; }
|
|
||||||
.tile-2048 { background: #ffd70066; box-shadow: 0 0 15px #ffd700; }
|
|
||||||
|
|
||||||
|
.x64{
|
||||||
|
background-color: #f65d3b;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x128{
|
||||||
|
background-color: #edce71;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x256{
|
||||||
|
background-color: #edcc63;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x512{
|
||||||
|
background-color: #edc651;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x1024{
|
||||||
|
background-color: #eec744;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x2048{
|
||||||
|
background-color: #ecc230;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x4096 {
|
||||||
|
background-color: #fe3d3d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x8192 {
|
||||||
|
background-color: #ff2020;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
@ -5,19 +5,14 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>2048</title>
|
<title>2048</title>
|
||||||
<link rel="stylesheet" href="2048.css">
|
<link rel="stylesheet" href="2048.css">
|
||||||
|
<script src="2048.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>2048</h1>
|
<h1>2048</h1>
|
||||||
<div id="top-menu">
|
|
||||||
<button class="btn" onclick="restartGame()">Restart</button>
|
|
||||||
<button class="btn" onclick="goHome()">Home</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<h2>Score: <span id="score">0</span></h2>
|
<h2>Score: <span id="score">0</span></h2>
|
||||||
<div id="board">
|
<div id="board">
|
||||||
</div>
|
</div>
|
||||||
<script src="2048.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
311
2048.js
311
2048.js
@ -1,311 +0,0 @@
|
|||||||
let board = [];
|
|
||||||
let score = 0;
|
|
||||||
|
|
||||||
// --- Audio setup ---
|
|
||||||
const audio = {
|
|
||||||
bg: new Audio("bgmusic.mp3"),
|
|
||||||
pop: new Audio("pop.mp3"),
|
|
||||||
merge: new Audio("merge.wav")
|
|
||||||
};
|
|
||||||
|
|
||||||
// lower default volumes
|
|
||||||
audio.bg.volume = 0.25;
|
|
||||||
audio.pop.volume = 0.9;
|
|
||||||
audio.merge.volume = 0.9;
|
|
||||||
audio.bg.loop = true;
|
|
||||||
|
|
||||||
// try to play background music; may be blocked until user interaction
|
|
||||||
function tryPlayBg() {
|
|
||||||
audio.bg.play().catch(() => {
|
|
||||||
// autoplay blocked — will try again on first user keypress or click
|
|
||||||
const unlock = () => {
|
|
||||||
audio.bg.play().catch(() => {});
|
|
||||||
window.removeEventListener("keydown", unlock);
|
|
||||||
window.removeEventListener("click", unlock);
|
|
||||||
};
|
|
||||||
window.addEventListener("keydown", unlock, { once: true });
|
|
||||||
window.addEventListener("click", unlock, { once: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- DOM ready: setup board and initial tiles ---
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
setupBoard();
|
|
||||||
addNewTile();
|
|
||||||
addNewTile();
|
|
||||||
tryPlayBg();
|
|
||||||
|
|
||||||
// keyboard controls (also used to unlock audio)
|
|
||||||
document.addEventListener("keydown", handleKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// SETUP BOARD (render tiles ONCE)
|
|
||||||
// ----------------------------
|
|
||||||
function setupBoard() {
|
|
||||||
board = [];
|
|
||||||
score = 0;
|
|
||||||
updateScore();
|
|
||||||
|
|
||||||
const container = document.getElementById("board");
|
|
||||||
if (!container) {
|
|
||||||
console.error("Board element not found (#board).");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty container and create fixed 4x4 cells
|
|
||||||
container.innerHTML = "";
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
board[r] = [];
|
|
||||||
for (let c = 0; c < 4; c++) {
|
|
||||||
board[r][c] = 0;
|
|
||||||
const tile = document.createElement("div");
|
|
||||||
tile.id = `${r}-${c}`;
|
|
||||||
tile.className = "tile"; // base class only
|
|
||||||
// ensure box sizing not influenced by text nodes
|
|
||||||
tile.style.boxSizing = "border-box";
|
|
||||||
container.appendChild(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// UPDATE UI FOR SINGLE TILE
|
|
||||||
// ----------------------------
|
|
||||||
function updateTile(row, col, num) {
|
|
||||||
const tile = document.getElementById(`${row}-${col}`);
|
|
||||||
if (!tile) return;
|
|
||||||
|
|
||||||
// reset classes to base
|
|
||||||
tile.className = "tile";
|
|
||||||
|
|
||||||
// force reflow to allow re-adding 'new' animation class reliably
|
|
||||||
void tile.offsetWidth;
|
|
||||||
|
|
||||||
if (num > 0) {
|
|
||||||
tile.textContent = num;
|
|
||||||
// add tile class for color (expects classes like tile-2, tile-4, ...)
|
|
||||||
tile.classList.add("tile-" + num);
|
|
||||||
|
|
||||||
// make numbers visually white-neon glow if desired:
|
|
||||||
// ensure text is centered by CSS; no inline style needed
|
|
||||||
} else {
|
|
||||||
tile.textContent = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// updates entire board DOM from board array
|
|
||||||
function refreshBoard() {
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
for (let c = 0; c < 4; c++) {
|
|
||||||
updateTile(r, c, board[r][c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateScore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// SCORE UI
|
|
||||||
// ----------------------------
|
|
||||||
function updateScore() {
|
|
||||||
const el = document.getElementById("score");
|
|
||||||
if (el) el.textContent = score;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// ADD NEW TILE (value 2, play pop sound + animation)
|
|
||||||
// ----------------------------
|
|
||||||
function addNewTile() {
|
|
||||||
const empty = [];
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
for (let c = 0; c < 4; c++) {
|
|
||||||
if (board[r][c] === 0) empty.push({ r, c });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty.length === 0) return false;
|
|
||||||
|
|
||||||
const spot = empty[Math.floor(Math.random() * empty.length)];
|
|
||||||
board[spot.r][spot.c] = 2;
|
|
||||||
|
|
||||||
const tile = document.getElementById(`${spot.r}-${spot.c}`);
|
|
||||||
if (tile) {
|
|
||||||
tile.classList.add("new");
|
|
||||||
// play pop sound
|
|
||||||
playSound(audio.pop);
|
|
||||||
// remove 'new' class after animation completes to keep DOM tidy
|
|
||||||
tile.addEventListener("animationend", function handler() {
|
|
||||||
tile.classList.remove("new");
|
|
||||||
tile.removeEventListener("animationend", handler);
|
|
||||||
});
|
|
||||||
// update text/color
|
|
||||||
updateTile(spot.r, spot.c, 2);
|
|
||||||
} else {
|
|
||||||
// fallback
|
|
||||||
updateTile(spot.r, spot.c, 2);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper to play sound safely
|
|
||||||
function playSound(soundObj) {
|
|
||||||
try {
|
|
||||||
soundObj.currentTime = 0;
|
|
||||||
soundObj.play().catch(() => {
|
|
||||||
// suppressed (autoplay or other)
|
|
||||||
});
|
|
||||||
} catch (e) { /* ignore */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// INPUT HANDLING
|
|
||||||
// ----------------------------
|
|
||||||
function handleKey(e) {
|
|
||||||
let moved = false;
|
|
||||||
if (e.key === "ArrowLeft") moved = moveLeft();
|
|
||||||
else if (e.key === "ArrowRight") moved = moveRight();
|
|
||||||
else if (e.key === "ArrowUp") moved = moveUp();
|
|
||||||
else if (e.key === "ArrowDown") moved = moveDown();
|
|
||||||
|
|
||||||
if (moved) {
|
|
||||||
// after a successful move: add tile, refresh board, play bg or unlock
|
|
||||||
addNewTile();
|
|
||||||
refreshBoard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- MOVE HELPERS ----------
|
|
||||||
function filterZero(row) {
|
|
||||||
return row.filter(n => n !== 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function slide(row) {
|
|
||||||
// row is an array of length 4
|
|
||||||
row = filterZero(row);
|
|
||||||
let mergedThisMove = false;
|
|
||||||
|
|
||||||
for (let i = 0; i < row.length - 1; i++) {
|
|
||||||
if (row[i] === row[i + 1]) {
|
|
||||||
row[i] = row[i] * 2;
|
|
||||||
// play merge sound and vibrate
|
|
||||||
playSound(audio.merge);
|
|
||||||
if (navigator.vibrate) navigator.vibrate(30);
|
|
||||||
|
|
||||||
score += row[i];
|
|
||||||
row[i + 1] = 0;
|
|
||||||
mergedThisMove = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
row = filterZero(row);
|
|
||||||
while (row.length < 4) row.push(0);
|
|
||||||
return { row, merged: mergedThisMove };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare arrays helper
|
|
||||||
function arraysEqual(a, b) {
|
|
||||||
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveLeft() {
|
|
||||||
let moved = false;
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
const { row: newRow } = slide(board[r]);
|
|
||||||
if (!arraysEqual(newRow, board[r])) moved = true;
|
|
||||||
board[r] = newRow;
|
|
||||||
}
|
|
||||||
if (moved) updateAfterMove();
|
|
||||||
return moved;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveRight() {
|
|
||||||
let moved = false;
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
let reversed = [...board[r]].reverse();
|
|
||||||
const { row: slid } = slide(reversed);
|
|
||||||
let newRow = slid.reverse();
|
|
||||||
if (!arraysEqual(newRow, board[r])) moved = true;
|
|
||||||
board[r] = newRow;
|
|
||||||
}
|
|
||||||
if (moved) updateAfterMove();
|
|
||||||
return moved;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveUp() {
|
|
||||||
let moved = false;
|
|
||||||
for (let c = 0; c < 4; c++) {
|
|
||||||
const col = [board[0][c], board[1][c], board[2][c], board[3][c]];
|
|
||||||
const { row: newCol } = slide(col);
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
if (board[r][c] !== newCol[r]) moved = true;
|
|
||||||
board[r][c] = newCol[r];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (moved) updateAfterMove();
|
|
||||||
return moved;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveDown() {
|
|
||||||
let moved = false;
|
|
||||||
for (let c = 0; c < 4; c++) {
|
|
||||||
const col = [board[3][c], board[2][c], board[1][c], board[0][c]];
|
|
||||||
const { row: slid } = slide(col);
|
|
||||||
const newCol = slid.reverse();
|
|
||||||
for (let r = 0; r < 4; r++) {
|
|
||||||
if (board[r][c] !== newCol[r]) moved = true;
|
|
||||||
board[r][c] = newCol[r];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (moved) updateAfterMove();
|
|
||||||
return moved;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateAfterMove() {
|
|
||||||
// update all tiles now (this keeps sizes stable)
|
|
||||||
refreshBoard();
|
|
||||||
// update score DOM
|
|
||||||
updateScore();
|
|
||||||
// small debounce is not required—moves are sequential
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// RESTART & HOME
|
|
||||||
// ----------------------------
|
|
||||||
function restartGame() {
|
|
||||||
setupBoard();
|
|
||||||
addNewTile();
|
|
||||||
addNewTile();
|
|
||||||
refreshBoard();
|
|
||||||
}
|
|
||||||
|
|
||||||
function goHome() {
|
|
||||||
// stops music to prevent continuing on homepage
|
|
||||||
try { audio.bg.pause(); audio.bg.currentTime = 0; } catch (e) {}
|
|
||||||
window.location.href = "Homepage.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------
|
|
||||||
// OPTIONAL: touch swipe for mobile
|
|
||||||
// ----------------------------
|
|
||||||
let touchStartX = 0;
|
|
||||||
let touchStartY = 0;
|
|
||||||
document.addEventListener("touchstart", function (e) {
|
|
||||||
const t = e.touches[0];
|
|
||||||
touchStartX = t.clientX;
|
|
||||||
touchStartY = t.clientY;
|
|
||||||
}, { passive: true });
|
|
||||||
|
|
||||||
document.addEventListener("touchend", function (e) {
|
|
||||||
const t = e.changedTouches[0];
|
|
||||||
const dx = t.clientX - touchStartX;
|
|
||||||
const dy = t.clientY - touchStartY;
|
|
||||||
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 30) {
|
|
||||||
if (dx > 0) moveRight() && addNewTile() && refreshBoard();
|
|
||||||
else moveLeft() && addNewTile() && refreshBoard();
|
|
||||||
} else if (Math.abs(dy) > 30) {
|
|
||||||
if (dy > 0) moveDown() && addNewTile() && refreshBoard();
|
|
||||||
else moveUp() && addNewTile() && refreshBoard();
|
|
||||||
}
|
|
||||||
}, { passive: true });
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user