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>GTA VI: Vice Shores Heist - MOBILE EDITION</title>
<style>
body { margin:0; padding:0; background:#000; overflow:hidden; touch-action: none; }
canvas { display:block; margin:0 auto; background:#228B22; }
#controls {
position: fixed;
bottom: 10px;
left: 10px;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 20px;
box-sizing: border-box;
pointer-events: none;
}
.dpad, .action {
display: grid;
grid-template-columns: 50px 50px 50px;
gap: 5px;
pointer-events: auto;
}
button {
width: 50px;
height: 50px;
font-size: 20px;
background: rgba(255,255,255,0.3);
color: white;
border: 3px solid white;
border-radius: 10px;
backdrop-filter: blur(5px);
user-select: none;
touch-action: none;
}
.action { grid-template-columns: repeat(2, 1fr); }
#status {
position: fixed;
top: 10px;
left: 10px;
color: white;
font-family: Arial;
font-size: 14px;
background: rgba(0,0,0,0.5);
padding: 8px;
border-radius: 5px;
pointer-events: none;
}
</style>
</head>
<body>
<canvas id="game" width="800" height="500"></canvas>
<div id="status">Health: 100 | Cash: $0 | Wanted: 0 ★ | Mission: Steal a car</div>
<div id="controls">
<!-- D-Pad -->
<div class="dpad">
<div></div>
<button id="up">↑</button>
<div></div>
<button id="left">←</button>
<button id="down">↓</button>
<button id="right">→</button>
</div>
<!-- Action Buttons -->
<div class="action">
<button id="steal">STEAL (E)</button>
<button id="punch">PUNCH (Space)</button>
<button id="rob">ROB BANK (R)</button>
<button id="exit">EXIT CAR</button>
</div>
</div>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const status = document.getElementById('status');
// Game variables (same as your PC version)
let player = { x: 100, y: 100, size: 25, speed: 4 };
let health = 100;
let cash = 0;
let wanted = 0;
let inCar = false;
let currentCar = null;
let missionStage = 0; // 0=steal car, 1=go bank, 2=robbed, 3=escaped
let gameMessage = "";
// Objects
let cars = [
{ x: 300, y: 200, w: 45, h: 25, color: "#FF0000", taken: false },
{ x: 500, y: 350, w: 45, h: 25, color: "#0000FF", taken: false },
{ x: 150, y: 400, w: 45, h: 25, color: "#FFFF00", taken: false }
];
let peds = [];
for (let i = 0; i < 8; i++) {
peds.push({ x: Math.random()*700+50, y: Math.random()*400+50, size: 20, hp: 50 });
}
let police = [];
let hospital = { x: 50, y: 420, w: 60, h: 60 };
let policeStation = { x: 700, y: 420, w: 60, h: 60 };
let bank = { x: 600, y: 80, w: 80, h: 80 };
let keys = {}; // for PC testing too
// Touch controls
const btnUp = document.getElementById('up');
const btnDown = document.getElementById('down');
const btnLeft = document.getElementById('left');
const btnRight = document.getElementById('right');
const btnSteal = document.getElementById('steal');
const btnPunch = document.getElementById('punch');
const btnRob = document.getElementById('rob');
const btnExit = document.getElementById('exit');
function setTouch(btn, key, isDown) {
btn.addEventListener('touchstart', e => { e.preventDefault(); keys[key] = isDown; });
btn.addEventListener('touchend', e => { e.preventDefault(); keys[key] = false; });
// Also support mouse for testing
btn.addEventListener('mousedown', () => keys[key] = isDown);
btn.addEventListener('mouseup', () => keys[key] = false);
}
setTouch(btnUp, 'w', true);
setTouch(btnDown, 's', true);
setTouch(btnLeft, 'a', true);
setTouch(btnRight, 'd', true);
setTouch(btnSteal, 'e', true);
setTouch(btnPunch, ' ', true);
setTouch(btnRob, 'r', true);
setTouch(btnExit, 'exit', true);
// Keyboard support (for PC testing)
window.addEventListener('keydown', e => keys[e.key.toLowerCase()] = true);
window.addEventListener('keyup', e => keys[e.key.toLowerCase()] = false);
function resetPlayer(respawnX, respawnY) {
player.x = respawnX;
player.y = respawnY;
health = 100;
wanted = 0;
inCar = false;
currentCar = null;
police = [];
}
function spawnPolice() {
police = [];
for (let i = 0; i < 3; i++) {
police.push({
x: player.x + 150 + Math.random()*100,
y: player.y + (Math.random()*200 - 100),
size: 30
});
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Background (Vice Shores style)
ctx.fillStyle = "#228B22";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "#555";
ctx.lineWidth = 30;
ctx.strokeRect(20, 20, canvas.width-40, canvas.height-80);
// Hospital
ctx.fillStyle = "#00FF00";
ctx.fillRect(hospital.x, hospital.y, hospital.w, hospital.h);
ctx.fillStyle = "#000";
ctx.font = "12px Arial";
ctx.fillText("HOSPITAL", hospital.x-5, hospital.y-5);
// Police Station
ctx.fillStyle = "#0066FF";
ctx.fillRect(policeStation.x, policeStation.y, policeStation.w, policeStation.h);
ctx.fillStyle = "#000";
ctx.fillText("POLICE", policeStation.x+5, policeStation.y-5);
// Bank
ctx.fillStyle = "#FFDD00";
ctx.fillRect(bank.x, bank.y, bank.w, bank.h);
ctx.fillStyle = "#000";
ctx.fillText("BANK - ROB (R)", bank.x+8, bank.y+45);
// Cars
cars.forEach(car => {
ctx.fillStyle = car.color;
ctx.fillRect(car.x, car.y, car.w, car.h);
if (!car.taken) {
ctx.fillStyle = "#FFF";
ctx.font = "10px Arial";
ctx.fillText("STEAL", car.x, car.y-5);
}
});
// Pedestrians
peds.forEach(ped => {
ctx.fillStyle = "#00AA00";
ctx.fillRect(ped.x, ped.y, ped.size, ped.size);
});
// Police
police.forEach(cop => {
ctx.fillStyle = "#0000AA";
ctx.fillRect(cop.x, cop.y, cop.size, cop.size);
ctx.fillStyle = "#FFF";
ctx.fillText("COP", cop.x+2, cop.y-2);
});
// Player
ctx.fillStyle = inCar ? "#FF0000" : "#FFFFFF";
ctx.fillRect(player.x, player.y, player.size, player.size);
if (inCar) {
ctx.fillStyle = "#FFFF00";
ctx.fillText("IN CAR", player.x-10, player.y-5);
}
// HUD
status.textContent = `Health: ${health} | Cash: \[ {cash} | Wanted: ${wanted} ★ | Mission: ${missionStage===0?'Steal car':missionStage===1?'Go to Bank':missionStage===2?'ESCAPE COPS':'COMPLETE!'}`;
if (gameMessage) {
ctx.fillStyle = "rgba(0,0,0,0.7)";
ctx.fillRect(100, 180, 600, 80);
ctx.fillStyle = "#FF0000";
ctx.font = "28px Arial";
ctx.fillText(gameMessage, 120, 220);
}
}
function update() {
// Movement
let speed = inCar ? 7 : 4;
if (keys['w'] || keys['arrowup']) player.y -= speed;
if (keys['s'] || keys['arrowdown']) player.y += speed;
if (keys['a'] || keys['arrowleft']) player.x -= speed;
if (keys['d'] || keys['arrowright']) player.x += speed;
// Screen bounds
player.x = Math.max(0, Math.min(canvas.width - player.size, player.x));
player.y = Math.max(0, Math.min(canvas.height - player.size - 30, player.y));
if (inCar && currentCar) {
currentCar.x = player.x;
currentCar.y = player.y;
}
// Steal car
if (keys['e'] && !inCar) {
for (let car of cars) {
if (!car.taken &&
Math.abs(player.x - car.x) < 50 &&
Math.abs(player.y - car.y) < 50) {
inCar = true;
currentCar = car;
car.taken = true;
missionStage = Math.max(missionStage, 1);
keys['e'] = false;
break;
}
}
}
// Exit car
if ((keys['exit'] || keys['e']) && inCar) {
inCar = false;
currentCar = null;
keys['e'] = false;
}
// Punch
if (keys[' ']) {
peds = peds.filter(ped => {
if (Math.abs(player.x - ped.x) < 45 && Math.abs(player.y - ped.y) < 45) {
ped.hp -= 35;
if (ped.hp <= 0) {
cash += 15;
return false;
}
}
return true;
});
keys[' '] = false;
}
// Rob bank
if (keys['r'] && missionStage === 1 &&
player.x > bank.x - 30 && player.x < bank.x + bank.w + 30 &&
player.y > bank.y - 30 && player.y < bank.y + bank.h + 30) {
cash += 8000;
missionStage = 2;
wanted = 5;
spawnPolice();
gameMessage = "BANK ROBBED! RUN FROM THE COPS!";
keys['r'] = false;
}
// Police chase & arrest
police.forEach((cop, i) => {
if (cop.x < player.x) cop.x += 5;
if (cop.x > player.x) cop.x -= 5;
if (cop.y < player.y) cop.y += 5;
if (cop.y > player.y) cop.y -= 5;
if (Math.abs(cop.x - player.x) < 35 && Math.abs(cop.y - player.y) < 35) {
if (inCar) inCar = false;
gameMessage = "ARRESTED! Respawning at Police Station...";
setTimeout(() => {
resetPlayer(policeStation.x + 30, policeStation.y + 30);
gameMessage = "";
}, 1500);
police = [];
}
});
// Death check
if (health <= 0) {
gameMessage = "YOU DIED! Respawning at Hospital...";
setTimeout(() => {
resetPlayer(hospital.x + 30, hospital.y + 30);
gameMessage = "";
}, 1500);
}
// Win condition
if (missionStage === 2 && wanted === 0 && police.length === 0) {
gameMessage = `MISSION COMPLETE! You escaped with \]{cash} !`;
}
// Random damage from peds (realistic)
peds.forEach(ped => {
if (Math.random() < 0.01 && Math.abs(player.x - ped.x) < 60 && Math.abs(player.y - ped.y) < 60) {
health -= 1;
}
});
draw();
}
// Game loop
function gameLoop() {
update();
requestAnimationFrame(gameLoop);
}
// Auto spawn one new ped when too few
setInterval(() => {
if (peds.length < 6) {
peds.push({ x: Math.random()*700+50, y: Math.random()*400+50, size: 20, hp: 50 });
}
}, 8000);
gameLoop();
// Touch the canvas to close message sometimes
canvas.addEventListener('touchstart', () => {
if (gameMessage.includes("COMPLETE")) location.reload();
});
</script>
</body>
</html>1
1
13KB
13KB
118.0ms
148.0ms
118.0ms