Meta Description" name="description" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Mobile Mini GTA</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
-webkit-user-select: none;
}
body {
background: #222;
overflow: hidden;
font-family: sans-serif;
}
canvas {
display: block;
background: #555;
margin: 0 auto;
}
#ui {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0,0,0,0.6);
padding: 8px;
border-radius: 5px;
font-size: 14px;
pointer-events: none;
}
/* Mobile Touch Controls */
.controls-container {
position: absolute;
bottom: 20px;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 20px;
pointer-events: none;
}
.btn-group {
display: flex;
gap: 10px;
pointer-events: auto;
}
.btn {
width: 65px;
height: 65px;
background: rgba(255, 255, 255, 0.3);
border: 2px solid #fff;
border-radius: 50%;
color: white;
font-size: 24px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
active-background: rgba(255, 255, 255, 0.6);
}
.btn:active {
background: rgba(255, 255, 255, 0.6);
}
</style>
</head>
<body>
<div id="ui">
<b>Mini GTA Mobile</b><br>
Speed: <span id="speedo">0</span> km/h
</div>
<canvas id="gameCanvas"></canvas>
<!-- Mobile Buttons -->
<div class="controls-container">
<!-- Steering Left/Right -->
<div class="btn-group">
<div class="btn" id="btnLeft">←</div>
<div class="btn" id="btnRight">→</div>
</div>
<!-- Race/Break -->
<div class="btn-group">
<div class="btn" id="btnDown">↓</div>
<div class="btn" id="btnUp">↑</div>
</div>
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
// Fit to mobile screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const car = {
x: canvas.width / 2,
y: canvas.height / 2,
width: 25,
height: 45,
angle: 0,
speed: 0,
maxSpeed: 4,
backSpeed: -2,
acc: 0.08,
friction: 0.04,
turnSpeed: 0.04
};
const keys = { ArrowUp: false, ArrowDown: false, ArrowLeft: false, ArrowRight: false };
// Touch Events Setup
function setupTouch(elementId, keyName) {
const btn = document.getElementById(elementId);
btn.addEventListener("touchstart", (e) => { e.preventDefault(); keys[keyName] = true; });
btn.addEventListener("touchend", (e) => { e.preventDefault(); keys[keyName] = false; });
}
setupTouch("btnUp", "ArrowUp");
setupTouch("btnDown", "ArrowDown");
setupTouch("btnLeft", "ArrowLeft");
setupTouch("btnRight", "ArrowRight");
// Buildings
const buildings = [
{ x: 50, y: 80, w: 100, h: 100, color: "#333" },
{ x: canvas.width - 150, y: 70, w: 110, h: 120, color: "#444" },
{ x: 40, y: canvas.height - 250, w: 120, h: 90, color: "#2b2b2b" },
{ x: canvas.width - 160, y: canvas.height - 260, w: 110, h: 110, color: "#3a3a3a" }
];
function checkCollision(r1, r2) {
return r1.x < r2.x + r2.w && r1.x + r1.width > r2.x && r1.y < r2.y + r2.h && r1.y + r1.height > r2.y;
}
function update() {
if (keys["ArrowUp"]) {
if (car.speed < car.maxSpeed) car.speed += car.acc;
} else if (keys["ArrowDown"]) {
if (car.speed > car.backSpeed) car.speed -= car.acc;
} else {
if (car.speed > 0) car.speed -= car.friction;
if (car.speed < 0) car.speed += car.friction;
if (Math.abs(car.speed) < 0.05) car.speed = 0;
}
if (car.speed !== 0) {
const rev = car.speed > 0 ? 1 : -1;
if (keys["ArrowLeft"]) car.angle -= car.turnSpeed * rev;
if (keys["ArrowRight"]) car.angle += car.turnSpeed * rev;
}
const oldX = car.x;
const oldY = car.y;
car.x += Math.sin(car.angle) * car.speed;
car.y -= Math.cos(car.angle) * car.speed;
// Borders
if (car.x < 0 || car.x > canvas.width - car.width) car.x = oldX;
if (car.y < 0 || car.y > canvas.height - car.height) car.y = oldY;
// Collision
buildings.forEach(bldg => {
if (checkCollision({x: car.x, y: car.y, width: car.width, height: car.height}, bldg)) {
car.speed = -car.speed * 0.3;
car.x = oldX;
car.y = oldY;
}
});
document.getElementById("speedo").innerText = Math.round(Math.abs(car.speed) * 25);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Grid lines
ctx.strokeStyle = "rgba(255,255,255,0.05)";
ctx.lineWidth = 1;
for(let i=0; i<canvas.width; i+=60) { ctx.beginPath(); ctx.moveTo(i,0); ctx.lineTo(i,canvas.height); ctx.stroke(); }
for(let j=0; j<canvas.height; j+=60) { ctx.beginPath(); ctx.moveTo(0,j); ctx.lineTo(canvas.width,j); ctx.stroke(); }
// Buildings
buildings.forEach(b => {
ctx.fillStyle = b.color;
ctx.fillRect(b.x, b.y, b.w, b.h);
ctx.strokeStyle = "#111";
ctx.strokeRect(b.x, b.y, b.w, b.h);
});
// Car
ctx.save();
ctx.translate(car.x + car.width/2, car.y + car.height/2);
ctx.rotate(car.angle);
ctx.fillStyle = "#ff3333";
ctx.fillRect(-car.width/2, -car.height/2, car.width, car.height);
ctx.fillStyle = "#88ccff";
ctx.fillRect(-car.width/2 + 4, -car.height/6, car.width - 8, car.height/3);
ctx.fillStyle = "#ffff00";
ctx.fillRect(-car.width/2 + 3, -car.height/2, 5, 3);
ctx.fillRect(car.width/2 - 8, -car.height/2, 5, 3);
ctx.restore();
}
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
</body>
</html>
1
1
7KB
7KB
182.0ms
192.0ms
182.0ms