<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tilting Maze Game</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
overflow: hidden;
}
#gameContainer {
text-align: center;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
#mazeCanvas {
border: 3px solid #fff;
border-radius: 10px;
background-color: #2c3e50;
}
h1 {
color: white;
margin-bottom: 10px;
}
p {
color: #ecf0f1;
margin-bottom: 20px;
}
#winMessage {
color: #2ecc71;
font-size: 1.5em;
font-weight: bold;
margin-top: 15px;
display: none;
}
</style>
</head>
<body>
<div id="gameContainer">
<h1>Tilt the Maze!</h1>
<p>Tilt your device or use arrow keys to guide the ball to the green goal.</p>
<canvas id="mazeCanvas" width="400" height="400"></canvas>
<div id="winMessage">Congratulations! You Win!</div>
</div>
<script>
const canvas = document.getElementById('mazeCanvas');
const ctx = canvas.getContext('2d');
const winMessage = document.getElementById('winMessage');
const ball = {
x: 50,
y: 50,
radius: 10,
speed: 0.5,
color: '#e74c3c'
};
const goal = {
x: canvas.width - 50,
y: canvas.height - 50,
radius: 15,
color: '#2ecc71'
};
const walls = [
{ x: 0, y: 0, width: canvas.width, height: 10 },
{ x: 0, y: 0, width: 10, height: canvas.height },
{ x: canvas.width - 10, y: 0, width: 10, height: canvas.height },
{ x: 0, y: canvas.height - 10, width: canvas.width, height: 10 },
{ x: 100, y: 0, width: 10, height: 200 },
{ x: 200, y: 100, width: 10, height: 200 },
{ x: 300, y: 200, width: 10, height: 200 },
{ x: 0, y: 300, width: 200, height: 10 },
];
let tiltX = 0;
let tiltY = 0;
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', (event) => {
tiltX = (event.gamma || 0) / 30;
tiltY = (event.beta || 0) / 30;
});
} else {
console.log("DeviceOrientation not supported, using keyboard.");
}
const keys = {};
window.addEventListener('keydown', (e) => { keys[e.key] = true; });
window.addEventListener('keyup', (e) => { keys[e.key] = false; });
function updateBallPosition() {
let newX = ball.x;
let newY = ball.y;
if (keys['ArrowUp'] || keys['w']) tiltY = -1;
else if (keys['ArrowDown'] || keys['s']) tiltY = 1;
else if (keys['ArrowLeft'] || keys['a']) tiltX = -1;
else if (keys['ArrowRight'] || keys['d']) tiltX = 1;
else {
}
newX += tiltX * ball.speed;
newY += tiltY * ball.speed;
if (!isColliding(newX, newY)) {
ball.x = newX;
ball.y = newY;
}
if (Object.keys(keys).some(key => ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'w', 'a', 's', 'd'].includes(key))) {
tiltX = 0;
tiltY = 0;
}
}
function isColliding(x, y) {
for (let wall of walls) {
if (x + ball.radius > wall.x &&
x - ball.radius < wall.x + wall.width &&
y + ball.radius > wall.y &&
y - ball.radius < wall.y + wall.height) {
return true;
}
}
if (x - ball.radius < 0 || x + ball.radius > canvas.width || y - ball.radius < 0 || y + ball.radius > canvas.height) {
return true;
}
return false;
}
function checkWinCondition() {
const dx = ball.x - goal.x;
const dy = ball.y - goal.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < ball.radius + goal.radius) {
winMessage.style.display = 'block';
return true;
}
return false;
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(goal.x, goal.y, goal.radius, 0, Math.PI * 2);
ctx.fillStyle = goal.color;
ctx.fill();
ctx.fillStyle = '#34495e';
for (let wall of walls) {
ctx.fillRect(wall.x, wall.y, wall.width, wall.height);
}
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = ball.color;
ctx.fill();
}
function gameLoop() {
updateBallPosition();
if (!checkWinCondition()) {
draw();
requestAnimationFrame(gameLoop);
} else {
draw();
}
}
gameLoop();
</script>
</body>
</html>