Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Tetris Game</title> | |
<style> | |
body { | |
margin: 0; | |
font-family: 'Arial', sans-serif; | |
background-color: #222; | |
color: white; | |
text-align: center; | |
} | |
canvas { | |
background-color: black; | |
display: block; | |
margin: 0 auto; | |
} | |
#gameCanvas { | |
border: 1px solid #444; | |
} | |
#welcomeScreen, #gameOverScreen { | |
display: none; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
background-color: rgba(0, 0, 0, 0.8); | |
padding: 20px; | |
border-radius: 10px; | |
width: 300px; | |
text-align: center; | |
} | |
#welcomeScreen { | |
background-image: url('tetris7.png'); | |
background-size: cover; | |
background-position: center; | |
} | |
#welcomeScreen input, #welcomeScreen button { | |
margin-top: 10px; | |
width: 100%; | |
padding: 10px; | |
border: none; | |
border-radius: 5px; | |
} | |
#gameOverScreen button { | |
margin-top: 10px; | |
width: 100%; | |
padding: 10px; | |
border: none; | |
border-radius: 5px; | |
background-color: #ff5555; | |
color: white; | |
font-size: 16px; | |
} | |
#homeButton { | |
margin-top: 10px; | |
width: 100%; | |
padding: 10px; | |
border: none; | |
border-radius: 5px; | |
background-color: #007BFF; | |
color: white; | |
font-size: 16px; | |
} | |
/* Style for control buttons */ | |
.control-buttons { | |
position: absolute; | |
bottom: 20px; | |
left: 50%; | |
transform: translateX(-50%); | |
display: flex; | |
justify-content: center; | |
gap: 10px; | |
} | |
.control-buttons button { | |
width: 50px; | |
height: 50px; | |
font-size: 24px; | |
background-color: #444; | |
color: white; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
} | |
.control-buttons button:hover { | |
background-color: #666; | |
} | |
.control-buttons button:active { | |
background-color: #333; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Tetris Game</h1> | |
<canvas id="gameCanvas" width="200" height="400"></canvas> | |
<div id="welcomeScreen"> | |
<h2>Welcome to Tetris!</h2> | |
<label for="usernameInput">Enter your name:</label> | |
<input type="text" id="usernameInput" placeholder="Your Name"> | |
<button onclick="startGame()">Start Game</button> | |
</div> | |
<div id="gameOverScreen"> | |
<h2 id="gameOverMessage">Game Over!</h2> | |
<p id="finalScore">Score: 0</p> | |
<button onclick="restartGame()">Restart</button> | |
<button id="homeButton" onclick="goHome()">Home</button> | |
</div> | |
<!-- On-screen control buttons --> | |
<div class="control-buttons"> | |
<button id="rotateBtn">🔄</button> | |
<button id="leftBtn">⬅️</button> | |
<button id="downBtn">⬇️</button> | |
<button id="rightBtn">➡️</button> | |
</div> | |
<script> | |
const canvas = document.getElementById('gameCanvas'); | |
const ctx = canvas.getContext('2d'); | |
const gridSize = { width: 10, height: 20 }; | |
const zoom = 20; | |
const fps = 5; // Slower falling speed | |
const colors = [ | |
'none', // Placeholder for index 0 (empty cell) | |
'#7800FF', // Purple | |
'#00FFFF', // Cyan | |
'#FFA500', // Orange | |
'#FFFF00', // Yellow | |
'#00FF00', // Green | |
'#FF0000', // Red | |
'#0000FF' // Blue | |
]; | |
let game = null; | |
let username = ''; | |
let music = new Audio('music.mp3'); // Create a global audio object | |
class Figure { | |
constructor() { | |
const figures = [ | |
[[1, 5, 9, 13], [4, 5, 6, 7]], // I | |
[[1, 2, 5, 6]], // O | |
[[1, 4, 5, 6], [0, 4, 5, 8], [4, 5, 6, 9], [2, 5, 6, 10]], // T | |
[[0, 1, 5, 6], [2, 4, 5, 7]], // S | |
[[1, 2, 4, 5], [1, 5, 6, 10]], // Z | |
[[0, 4, 5, 9], [2, 4, 5, 6], [4, 5, 6, 8], [0, 1, 5, 9]], // J | |
[[1, 5, 6, 9], [2, 4, 5, 6], [1, 5, 6, 10], [0, 4, 5, 7]] // L | |
]; | |
this.type = Math.floor(Math.random() * figures.length); | |
this.color = colors[this.type + 1]; // Assign different colors to each figure | |
this.rotation = 0; | |
this.x = 3; | |
this.y = 0; | |
this.figures = figures; | |
} | |
getCurrentFigure() { | |
return this.figures[this.type][this.rotation]; | |
} | |
rotate() { | |
this.rotation = (this.rotation + 1) % this.figures[this.type].length; | |
} | |
} | |
class Tetris { | |
constructor() { | |
this.height = gridSize.height; | |
this.width = gridSize.width; | |
this.field = Array.from({ length: this.height }, () => Array(this.width).fill(0)); | |
this.score = 0; | |
this.state = 'welcome'; | |
this.figure = null; | |
this.level = 2; | |
this.username = ''; | |
} | |
newFigure() { | |
this.figure = new Figure(); | |
} | |
intersects() { | |
for (let i = 0; i < 4; i++) { | |
for (let j = 0; j < 4; j++) { | |
if (this.figure.getCurrentFigure().includes(i * 4 + j)) { | |
const x = j + this.figure.x; | |
const y = i + this.figure.y; | |
if (x < 0 || x >= this.width || y >= this.height || this.field[y][x]) { | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
breakLines() { | |
let lines = 0; | |
for (let i = 0; i < this.height; i++) { | |
if (this.field[i].every(cell => cell !== 0)) { | |
lines++; | |
for (let k = i; k > 0; k--) { | |
this.field[k] = [...this.field[k - 1]]; | |
} | |
this.field[0] = Array(this.width).fill(0); | |
} | |
} | |
this.score += lines * lines; | |
} | |
goDown() { | |
this.figure.y += 1; | |
if (this.intersects()) { | |
this.figure.y -= 1; | |
this.freeze(); | |
} | |
} | |
goSide(dx) { | |
this.figure.x += dx; | |
if (this.intersects()) { | |
this.figure.x -= dx; | |
} | |
} | |
rotateFigure() { | |
const oldRotation = this.figure.rotation; | |
this.figure.rotate(); | |
if (this.intersects()) { | |
this.figure.rotation = oldRotation; | |
} | |
} | |
freeze() { | |
for (let i = 0; i < 4; i++) { | |
for (let j = 0; j < 4; j++) { | |
if (this.figure.getCurrentFigure().includes(i * 4 + j)) { | |
this.field[i + this.figure.y][j + this.figure.x] = this.figure.color; | |
} | |
} | |
} | |
this.breakLines(); | |
this.newFigure(); | |
if (this.intersects()) { | |
this.state = 'gameover'; | |
document.getElementById('gameOverMessage').textContent = `Game Over, ${this.username}!`; | |
document.getElementById('finalScore').textContent = `Score: ${this.score}`; | |
document.getElementById('gameOverScreen').style.display = 'block'; | |
stopMusic(); // Stop music on game over | |
} | |
} | |
} | |
function drawGrid() { | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
for (let i = 0; i < game.height; i++) { | |
for (let j = 0; j < game.width; j++) { | |
ctx.strokeStyle = 'gray'; | |
ctx.strokeRect(j * zoom, i * zoom, zoom, zoom); | |
if (game.field[i][j] !== 0) { | |
ctx.fillStyle = game.field[i][j]; | |
ctx.fillRect(j * zoom + 1, i * zoom + 1, zoom - 2, zoom - 2); | |
} | |
} | |
} | |
} | |
function drawFigure() { | |
if (game.figure !== null) { | |
const figure = game.figure.getCurrentFigure(); | |
for (let i = 0; i < 4; i++) { | |
for (let j = 0; j < 4; j++) { | |
if (figure.includes(i * 4 + j)) { | |
ctx.fillStyle = game.figure.color; | |
ctx.fillRect((j + game.figure.x) * zoom + 1, (i + game.figure.y) * zoom + 1, zoom - 2, zoom - 2); | |
} | |
} | |
} | |
} | |
} | |
function drawText() { | |
ctx.fillStyle = 'white'; | |
ctx.font = '14px Arial'; | |
ctx.fillText(`Score: ${game.score}`, 5, 15); | |
} | |
function updateGame() { | |
if (game.state === 'start') { | |
game.goDown(); | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
} | |
function startGame() { | |
username = document.getElementById('usernameInput').value; | |
if (!username) { | |
alert('Please enter your name.'); | |
return; | |
} | |
game = new Tetris(); | |
game.newFigure(); | |
game.username = username; | |
game.state = 'start'; | |
document.getElementById('welcomeScreen').style.display = 'none'; | |
startMusic(); // Start music when the game starts | |
gameLoop(); | |
} | |
function gameLoop() { | |
if (game.state !== 'gameover') { | |
updateGame(); | |
setTimeout(gameLoop, 1000 / fps); | |
} | |
} | |
function restartGame() { | |
document.getElementById('gameOverScreen').style.display = 'none'; | |
startGame(); | |
} | |
function goHome() { | |
document.getElementById('gameOverScreen').style.display = 'none'; | |
document.getElementById('welcomeScreen').style.display = 'block'; | |
} | |
function startMusic() { | |
music.loop = true; | |
music.volume = 0.5; | |
music.play(); | |
} | |
function stopMusic() { | |
music.pause(); | |
music.currentTime = 0; // Reset to start | |
} | |
// Handle keyboard controls | |
document.addEventListener('keydown', (event) => { | |
if (game && game.state === 'start') { | |
switch (event.key) { | |
case 'ArrowUp': | |
game.rotateFigure(); | |
break; | |
case 'ArrowDown': | |
game.goDown(); | |
break; | |
case 'ArrowLeft': | |
game.goSide(-1); | |
break; | |
case 'ArrowRight': | |
game.goSide(1); | |
break; | |
} | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
}); | |
// Handle touch controls | |
let touchStartX = 0; | |
let touchStartY = 0; | |
canvas.addEventListener('touchstart', (event) => { | |
event.preventDefault(); | |
touchStartX = event.touches[0].clientX; | |
touchStartY = event.touches[0].clientY; | |
}); | |
canvas.addEventListener('touchend', (event) => { | |
event.preventDefault(); | |
const touchEndX = event.changedTouches[0].clientX; | |
const touchEndY = event.changedTouches[0].clientY; | |
const dx = touchEndX - touchStartX; | |
const dy = touchEndY - touchStartY; | |
if (Math.abs(dx) > Math.abs(dy)) { | |
if (dx > 30) { // Swipe right | |
game.goSide(1); | |
} else if (dx < -30) { // Swipe left | |
game.goSide(-1); | |
} | |
} else { | |
if (dy > 30) { // Swipe down | |
game.goDown(); | |
} | |
} | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
}); | |
canvas.addEventListener('touchmove', (event) => { | |
event.preventDefault(); | |
}); | |
// On-screen button event handlers | |
document.getElementById('rotateBtn').addEventListener('click', () => { | |
if (game && game.state === 'start') { | |
game.rotateFigure(); | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
}); | |
document.getElementById('leftBtn').addEventListener('click', () => { | |
if (game && game.state === 'start') { | |
game.goSide(-1); | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
}); | |
document.getElementById('downBtn').addEventListener('click', () => { | |
if (game && game.state === 'start') { | |
game.goDown(); | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
}); | |
document.getElementById('rightBtn').addEventListener('click', () => { | |
if (game && game.state === 'start') { | |
game.goSide(1); | |
drawGrid(); | |
drawFigure(); | |
drawText(); | |
} | |
}); | |
window.onload = () => { | |
document.getElementById('welcomeScreen').style.display = 'block'; | |
// No need to play music on window load | |
}; | |
</script> | |
</body> | |
</html> | |