<!DOCTYPE html>
<html lang="tr">
<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: San HTML - Final Fix</title>
<style>
body { margin: 0; overflow: hidden; background: #111; font-family: 'Verdana', sans-serif; touch-action: none; user-select: none; cursor: crosshair; }
canvas { display: block; }
#ui-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
#minimap-container {
position: absolute; top: 10px; right: 10px;
width: 140px; height: 140px;
border: 4px solid #fff; border-radius: 50%; overflow: hidden;
background: #000; box-shadow: 0 0 10px rgba(0,0,0,0.5);
}
#hud-stats {
position: absolute; top: 160px; right: 10px;
text-align: right; color: white; font-weight: bold; text-shadow: 2px 2px 0 #000;
}
#money { color: #2ecc71; font-size: 26px; margin-bottom: 5px; }
#wanted-level { color: #3498db; font-size: 22px; letter-spacing: 3px; }
#health-bar-bg { width: 130px; height: 12px; background: #444; border: 2px solid #fff; margin-left: auto; margin-top: 5px; }
#health-bar { width: 100%; height: 100%; background: #e74c3c; transition: width 0.2s; }
#ammo-display { font-size: 20px; color: #f1c40f; margin-top: 5px; display: none; }
#interact-msg {
position: absolute; top: 60%; left: 50%; transform: translate(-50%, -50%);
color: #fff; background: rgba(0,0,0,0.7); padding: 10px 20px; border-radius: 20px;
font-size: 20px; font-weight: bold; border: 2px solid #f1c40f;
display: none; z-index: 150;
}
#shop-menu {
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.9); z-index: 200;
display: none; flex-direction: column; align-items: center; justify-content: center;
pointer-events: auto; cursor: default;
}
.shop-item {
background: #222; color: white; border: 2px solid #f1c40f;
padding: 15px; width: 280px; margin: 10px; text-align: center;
cursor: pointer; font-size: 18px; font-weight: bold; transition: 0.2s;
}
.shop-item:hover { background: #f1c40f; color: black; transform: scale(1.05); }
#wasted-screen {
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(150, 0, 0, 0.6); z-index: 100;
display: none; flex-direction: column; align-items: center; justify-content: center;
}
#wasted-text { color: #fff; font-size: 70px; font-weight: 900; text-shadow: 4px 4px 0 #000; letter-spacing: 5px; transform: rotate(-5deg); }
#mission-msg { position: absolute; bottom: 120px; width: 100%; text-align: center; color: #f1c40f; font-size: 24px; font-weight: bold; text-shadow: 2px 2px 0 #000; display: none; }
/* Mobil Kontroller */
.btn { position: absolute; width: 65px; height: 65px; background: rgba(255,255,255,0.2); border: 2px solid rgba(255,255,255,0.4); border-radius: 50%; pointer-events: auto; display: none; color: white; align-items: center; justify-content: center; font-size: 24px; }
#joy-bg { position: absolute; bottom: 30px; left: 30px; width: 130px; height: 130px; background: rgba(255,255,255,0.1); border-radius: 50%; pointer-events: auto; display: none; }
#joy-stick { position: absolute; top: 50%; left: 50%; width: 50px; height: 50px; background: rgba(255,255,255,0.4); border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; }
#btn-enter { bottom: 110px; right: 25px; border-color: #f1c40f; background: rgba(241, 196, 15, 0.3); }
#btn-shoot { bottom: 30px; right: 25px; border-color: #e74c3c; background: rgba(231, 76, 60, 0.3); }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<div id="ui-layer">
<div id="minimap-container"><canvas id="minimap" width="150" height="150"></canvas></div>
<div id="hud-stats">
<div id="money">$100</div>
<div id="wanted-level">☆☆☆☆☆</div>
<div id="health-bar-bg"><div id="health-bar"></div></div>
<div id="ammo-display">🔫 0</div>
</div>
<div id="interact-msg">[E] ETKİLEŞİM</div>
<div id="mission-msg">GÖREV GÜNCELLENDİ</div>
<div id="wasted-screen">
<div id="wasted-text">YAKALANDIN</div>
</div>
<div id="shop-menu">
<h2 style="color:#f1c40f; text-shadow: 2px 2px 0 #000;">KARABORSA SİLAHÇI</h2>
<div class="shop-item" onclick="buyItem('health', 200)">❤️ CAN YENİLE ($200)</div>
<div class="shop-item" onclick="buyItem('ammo', 500)">🔫 MERMİ AL ($500)</div>
<div class="shop-item" onclick="buyItem('bribe', 1000)">⭐ POLİSTEN KURTUL ($1000)</div>
<div class="shop-item" style="border-color:#e74c3c; color:#e74c3c" onclick="closeShop()">KAPAT</div>
</div>
<div id="joy-bg"><div id="joy-stick"></div></div>
<div id="btn-enter" class="btn">👋</div>
<div id="btn-shoot" class="btn">🔥</div>
</div>
<script>
window.onload = init;
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const miniCanvas = document.getElementById('minimap');
const miniCtx = miniCanvas.getContext('2d');
const isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
let width, height;
let camera = { x: 0, y: 0 };
const BLOCK = 80;
const MAP_SIZE = 20;
let keys = { w:0, a:0, s:0, d:0, e:0, shoot:0 };
let mouse = { x: 0, y: 0, down: false };
let inputVector = { x:0, y:0 };
let map = [];
let roadTiles = [], sidewalkTiles = [];
// FIX: Kaldırım karelerini hızlıca kontrol etmek için bir Set oluşturuldu
let sidewalkSet = new Set();
let cars = [], peds = [], items = [], bullets = [], particles = [], shops = [];
let mission = { active: false, x: 0, y: 0 };
let isGamePaused = false;
let canInteract = null;
let player = {
x: 0, y: 0, angle: 0, targetAngle: 0, state: 'on_foot', car: null,
health: 100, money: 100, wanted: 0, weapon: 'fist', ammo: 0, lastAttack: 0,
radius: 6
};
function init() {
resize();
window.addEventListener('resize', resize);
setupControls();
generateMap();
respawnPlayer();
for(let i=0; i<12; i++) spawnCar();
for(let i=0; i<20; i++) spawnPed();
for(let i=0; i<3; i++) spawnShop();
nextMission();
requestAnimationFrame(loop);
}
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
if(isMobile) {
document.querySelectorAll('.btn').forEach(b => b.style.display = 'flex');
document.getElementById('joy-bg').style.display = 'block';
document.body.style.cursor = 'default';
}
}
// --- HARİTA & SPAWN ---
function generateMap() {
map = []; roadTiles = []; sidewalkTiles = []; sidewalkSet.clear();
for(let y=0; y<MAP_SIZE; y++) { let r=[]; for(let x=0; x<MAP_SIZE; x++) r.push(0); map.push(r); }
for(let x=2; x<MAP_SIZE-1; x+=4) for(let y=0; y<MAP_SIZE; y++) map[y][x] = 1;
for(let y=2; y<MAP_SIZE-1; y+=4) for(let x=0; x<MAP_SIZE; x++) map[y][x] = (map[y][x] === 1) ? 3 : 2;
for(let y=0; y<MAP_SIZE; y++) for(let x=0; x<MAP_SIZE; x++) {
if(map[y][x] > 0) roadTiles.push({x: x, y: y});
else {
let isSide = false;
if(x>0 && map[y][x-1]>0) isSide=true; if(x<MAP_SIZE-1 && map[y][x+1]>0) isSide=true;
if(y>0 && map[y-1][x]>0) isSide=true; if(y<MAP_SIZE-1 && map[y+1][x]>0) isSide=true;
if(isSide) {
sidewalkTiles.push({x: x, y: y});
sidewalkSet.add(`${x},${y}`);
}
}
}
}
function respawnPlayer() {
if(sidewalkTiles.length > 0) {
let t = sidewalkTiles[Math.floor(Math.random()*sidewalkTiles.length)];
player.x = t.x*BLOCK+BLOCK/2; player.y = t.y*BLOCK+BLOCK/2;
} else { player.x = 200; player.y = 200; }
player.health = 100; player.wanted = 0; player.weapon = 'fist';
player.state = 'on_foot'; player.car = null;
document.getElementById('wasted-screen').style.display = 'none';
updateUI();
}
function spawnCar() {
if(roadTiles.length === 0) return;
let t = roadTiles[Math.floor(Math.random()*roadTiles.length)];
let angle = map[t.y][t.x] === 1 ? Math.PI/2 : 0;
cars.push({x: t.x*BLOCK+BLOCK/2, y: t.y*BLOCK+BLOCK/2, angle: angle, speed: 2, radius: 15, color: ['#e74c3c','#8e44ad','#3498db','#fff'][Math.floor(Math.random()*4)]});
}
function spawnPed(type='civilian') {
if(sidewalkTiles.length === 0) return;
let t = sidewalkTiles[Math.floor(Math.random()*sidewalkTiles.length)];
peds.push({x: t.x*BLOCK+BLOCK/2, y: t.y*BLOCK+BLOCK/2, angle: Math.random()*6.28, type: type, health: 100, radius: 8, color: type==='police'?'#3498db':['#2ecc71','#d35400','#16a085'][Math.floor(Math.random()*3)]});
}
function spawnShop() {
if(sidewalkTiles.length === 0) return;
let t = sidewalkTiles[Math.floor(Math.random()*sidewalkTiles.length)];
shops.push({x: t.x*BLOCK+BLOCK/2, y: t.y*BLOCK+BLOCK/2});
}
function nextMission() {
if(sidewalkTiles.length === 0) return;
let t = sidewalkTiles[Math.floor(Math.random()*sidewalkTiles.length)];
mission.x = t.x*BLOCK+BLOCK/2; mission.y = t.y*BLOCK+BLOCK/2;
mission.active = true; showMsg("GÖREV: SARI ALANA GİT", "#f1c40f");
}
// --- ETKİLEŞİM & DÜKKAN ---
function checkInteractions() {
canInteract = null;
document.getElementById('interact-msg').style.display = 'none';
if(player.state !== 'on_foot') return;
let nearShop = shops.find(s => dist(player.x, player.y, s.x, s.y) < 65);
if(nearShop) { canInteract = 'shop'; document.getElementById('interact-msg').innerText = "[E] DÜKKANA GİR"; }
if(mission.active && dist(player.x, player.y, mission.x, mission.y) < 65) {
canInteract = 'mission'; document.getElementById('interact-msg').innerText = "[E] GÖREVİ YAP";
}
if(canInteract) document.getElementById('interact-msg').style.display = 'block';
}
function openShop() { document.getElementById('shop-menu').style.display='flex'; isGamePaused=true; }
function closeShop() { document.getElementById('shop-menu').style.display='none'; isGamePaused=false; }
function completeMission() {
player.money += 500; showMsg("BAŞARILI! +$500", "#2ecc71");
mission.active = false; setTimeout(nextMission, 3000);
}
function buyItem(item, cost) {
if(player.money>=cost) { player.money-=cost; if(item==='health')player.health=100; if(item==='ammo'){player.weapon='pistol';player.ammo+=30;} if(item==='bribe')player.wanted=0; updateUI(); showMsg("SATIN ALINDI!","#2ecc71"); }
else showMsg("YETERSİZ PARA!","#c0392b");
}
// --- FİZİK & HAREKET (TAKILMA ÖNLEYİCİ) ---
function checkCollision(x, y, r) {
let m = r;
if(isWall(x-m, y-m) || isWall(x+m, y-m) || isWall(x-m, y+m) || isWall(x+m, y+m)) return true;
return false;
}
function isWall(x, y) {
let gx = Math.floor(x/BLOCK), gy = Math.floor(y/BLOCK);
if(gx<0 || gx>=MAP_SIZE || gy<0 || gy>=MAP_SIZE) return true;
// FIX: Bir kare çim ise (0) VE aynı zamanda bir kaldırım değilse, o zaman duvardır.
return map[gy][gx] === 0 && !sidewalkSet.has(`${gx},${gy}`);
}
function update() {
if(isGamePaused || player.health<=0) return;
if(player.state === 'on_foot') {
let mx = isMobile ? inputVector.x : (keys.d-keys.a), my = isMobile ? inputVector.y : (keys.s-keys.w);
if(mx||my) {
let spd = 4;
if(isMobile) player.targetAngle = Math.atan2(my,mx);
let nextX = player.x + mx * spd * (isMobile?1:0.7);
if(!checkCollision(nextX, player.y, player.radius)) player.x = nextX;
let nextY = player.y + my * spd * (isMobile?1:0.7);
if(!checkCollision(player.x, nextY, player.radius)) player.y = nextY;
}
if(!isMobile) player.targetAngle = Math.atan2(mouse.y - (player.y-camera.y), mouse.x - (player.x-camera.x));
let diff = player.targetAngle - player.angle;
while (diff < -Math.PI) diff += Math.PI * 2; while (diff > Math.PI) diff -= Math.PI * 2;
player.angle += diff * 0.2;
if((!isMobile && mouse.down) || (isMobile && keys.shoot)) {
if(Date.now()-player.lastAttack>300) { attack(); player.lastAttack=Date.now(); }
}
checkInteractions();
items.forEach((it,i)=>{if(dist(player.x,player.y,it.x,it.y)<30){if(it.type==='gun'){player.weapon='pistol';player.ammo+=20;showMsg("SİLAH BULUNDU!","#2ecc71");}items.splice(i,1);}});
let pgx = Math.floor(player.x/BLOCK), pgy = Math.floor(player.y/BLOCK);
if(map[pgy] && map[pgy][pgx] === 0) {
if(map[pgy][pgx+1] !== 0) player.x += 2;
else if(map[pgy][pgx-1] !== 0) player.x -= 2;
else if(map[pgy+1][pgx] !== 0) player.y += 2;
else if(map[pgy-1][pgx] !== 0) player.y -= 2;
}
}
if(player.state === 'driving') {
let c=player.car, gas=keys.w||(inputVector.y<-0.3), rev=keys.s||(inputVector.y>0.3), left=keys.a||(inputVector.x<-0.3), right=keys.d||(inputVector.x>0.3);
if(gas)c.speed+=0.2; if(rev)c.speed-=0.2; c.speed*=0.96;
if(Math.abs(c.speed)>0.5) c.angle+=(right?0.06:(left?-0.06:0))*(c.speed>0?1:-1);
let nx=c.x+Math.cos(c.angle)*c.speed, ny=c.y+Math.sin(c.angle)*c.speed;
if(checkCollision(nx,ny,15)){c.speed*=-0.5;c.x-=Math.cos(c.angle)*10;c.y-=Math.sin(c.angle)*10;}else{c.x=nx;c.y=ny;}
peds.forEach((p,i)=>{if(dist(c.x,c.y,p.x,p.y)<25&&Math.abs(c.speed)>2)hitPed(p,i,true);});
player.x=c.x; player.y=c.y;
}
updateTraffic(); updatePeds(); updateBullets();
if(player.wanted > 0) {
let pols = peds.filter(p => p.type === 'police').length;
if(pols < player.wanted && Math.random() < 0.01) spawnPed('police');
}
camera.x += (player.x - width/2 - camera.x) * 0.1;
camera.y += (player.y - height/2 - camera.y) * 0.1;
updateUI(); drawMinimap();
}
function updateTraffic() {
cars.forEach(c => { if(c===player.car)return;
let gx=Math.floor(c.x/BLOCK), gy=Math.floor(c.y/BLOCK), type=map[gy]?map[gy][gx]:0, cx=gx*BLOCK+BLOCK/2, cy=gy*BLOCK+BLOCK/2;
if(type===1 && Math.abs(c.x-cx)>2)c.x+=(cx-c.x)*0.05; if(type===2 && Math.abs(c.y-cy)>2)c.y+=(cy-c.y)*0.05;
if(Math.abs(c.x-cx)<10 && Math.abs(c.y-cy)<10) {
if(type===3) c.angle=[0,Math.PI/2,Math.PI,-Math.PI/2][Math.floor(Math.random()*4)];
else if(type===1) c.angle=Math.sin(c.angle)>0?Math.PI/2:-Math.PI/2; else if(type===2) c.angle=Math.cos(c.angle)>0?0:Math.PI;
}
let stop=false; if(dist(c.x,c.y,player.x,player.y)<70)stop=true;
cars.forEach(o=>{if(c!==o && dist(c.x,c.y,o.x,o.y)<70 && Math.abs(Math.atan2(o.y-c.y,o.x-c.x)-c.angle)<1.0)stop=true;});
if(stop)c.speed*=0.8; else if(c.speed<3)c.speed+=0.1;
c.x+=Math.cos(c.angle)*c.speed; c.y+=Math.sin(c.angle)*c.speed;
if(c.x<0)c.x=MAP_SIZE*BLOCK;if(c.x>MAP_SIZE*BLOCK)c.x=0;if(c.y<0)c.y=MAP_SIZE*BLOCK;if(c.y>MAP_SIZE*BLOCK)c.y=0;
});
}
function updatePeds() {
peds.forEach((p, i) => { let speed=1;
if(p.type==='police'&&player.wanted>0){p.angle=Math.atan2(player.y-p.y,player.x-p.x);speed=3.2;if(dist(p.x,p.y,player.x,player.y)<200&&Math.random()<0.03)bullets.push({x:p.x,y:p.y,angle:p.angle+(Math.random()-0.5)*0.2,speed:10,owner:'police',life:60});}
else if(p.panic)speed=3;
let nx=p.x+Math.cos(p.angle)*speed, ny=p.y+Math.sin(p.angle)*speed;
if(!checkCollision(nx,ny,5)){p.x=nx;p.y=ny;}else p.angle=Math.random()*6.28;
if(Math.random()<0.01)p.angle+=(Math.random()-0.5);
});
}
function attack() {
if(player.weapon==='fist') peds.forEach((p,i)=>{if(dist(player.x,player.y,p.x,p.y)<40)hitPed(p,i,false);});
else if(player.weapon==='pistol'&&player.ammo>0){player.ammo--;bullets.push({x:player.x,y:player.y,angle:player.angle,speed:15,owner:'player',life:50});}
}
function hitPed(p,idx,isCar) {
p.health-=isCar?100:35; blood(p.x,p.y);
if(p.type!=='enemy'){player.wanted=Math.min(5,player.wanted+1);showMsg("ARANIYORSUN!","#e74c3c");}
if(p.health<=0){peds.splice(idx,1);if(p.type==='police')items.push({x:p.x,y:p.y,type:'gun'});}else p.panic=true;
}
function updateBullets() {
for(let i=bullets.length-1;i>=0;i--){let b=bullets[i];b.x+=Math.cos(b.angle)*b.speed;b.y+=Math.sin(b.angle)*b.speed;b.life--;if(isWall(b.x,b.y)||b.life<=0){bullets.splice(i,1);continue;}if(b.owner!=='player'&&dist(b.x,b.y,player.x,player.y)<20){player.health-=10;blood(player.x,player.y);bullets.splice(i,1);if(player.health<=0)document.getElementById('wasted-screen').style.display='flex',setTimeout(respawnPlayer,3000);}if(b.owner==='player')peds.forEach((p,idx)=>{if(dist(b.x,b.y,p.x,p.y)<20){hitPed(p,idx,false);bullets.splice(i,1);}});}
}
// --- ÇİZİM ---
function draw() {
ctx.setTransform(1,0,0,1,0,0); ctx.fillStyle='#2c3e50'; ctx.fillRect(0,0,width,height);
ctx.save(); ctx.translate(-camera.x,-camera.y);
let startX=Math.floor(camera.x/BLOCK), startY=Math.floor(camera.y/BLOCK), endX=startX+Math.ceil(width/BLOCK)+1, endY=startY+Math.ceil(height/BLOCK)+1;
for(let y=startY;y<endY;y++)for(let x=startX;x<endX;x++){if(x<0||y<0||x>=MAP_SIZE||y>=MAP_SIZE)continue;let px=x*BLOCK,py=y*BLOCK;if(map[y][x]===0){ctx.fillStyle='#27ae60';ctx.fillRect(px,py,BLOCK,BLOCK);ctx.fillStyle='#1e824c';ctx.fillRect(px+5,py+5,BLOCK-10,BLOCK-10);}else{ctx.fillStyle='#7f8c8d';ctx.fillRect(px,py,BLOCK,BLOCK);ctx.fillStyle='#f1c40f';if(map[y][x]===1)ctx.fillRect(px+38,py,4,BLOCK);if(map[y][x]===2)ctx.fillRect(px,py+38,BLOCK,4);}}
shops.forEach(s=>{ctx.fillStyle='rgba(155,89,182,0.5)';ctx.beginPath();ctx.arc(s.x,s.y,35,0,6.28);ctx.fill();ctx.fillStyle='#fff';ctx.font="12px Verdana";ctx.fillText("SHOP",s.x-15,s.y);});
if(mission.active){ctx.fillStyle='rgba(241,196,15,0.5)';ctx.beginPath();ctx.arc(mission.x,mission.y,45,0,6.28);ctx.fill();ctx.strokeStyle='#f1c40f';ctx.lineWidth=3;ctx.stroke();}
items.forEach(i=>{ctx.fillStyle='#e67e22';ctx.fillRect(i.x-10,i.y-10,20,20);ctx.strokeStyle='#fff';ctx.strokeRect(i.x-10,i.y-10,20,20);});
particles.forEach((p,i)=>{ctx.fillStyle=p.color;ctx.fillRect(p.x,p.y,p.size,p.size);p.life--;if(p.life<=0)particles.splice(i,1);});
cars.forEach(c=>{ctx.save();ctx.translate(c.x,c.y);ctx.rotate(c.angle);ctx.fillStyle=c.color;ctx.fillRect(-18,-10,36,20);ctx.fillStyle='#f1c40f';ctx.fillRect(18,-8,5,4);ctx.fillRect(18,4,5,4);ctx.restore();});
peds.forEach(p=>{ctx.save();ctx.translate(p.x,p.y);ctx.rotate(p.angle);ctx.fillStyle=p.type==='police'?'#2980b9':p.color;ctx.beginPath();ctx.arc(0,0,10,0,6.28);ctx.fill();ctx.restore();});
if(player.state==='on_foot'){ctx.save();ctx.translate(player.x,player.y);ctx.rotate(player.angle);ctx.fillStyle='#f39c12';ctx.beginPath();ctx.arc(0,0,9,0,6.28);ctx.fill();ctx.fillStyle='#000';if(player.weapon==='fist'){ctx.beginPath();ctx.arc(8,-8,3,0,6.28);ctx.fill();ctx.beginPath();ctx.arc(8,8,3,0,6.28);ctx.fill();}else ctx.fillRect(0,2,20,4);ctx.restore();}
ctx.fillStyle='#fff'; bullets.forEach(b=>{ctx.beginPath();ctx.arc(b.x,b.y,3,0,6.28);ctx.fill();});
ctx.restore();
}
function drawMinimap() {
miniCtx.fillStyle = '#222'; miniCtx.fillRect(0, 0, 150, 150);
miniCtx.save(); miniCtx.translate(75, 75); miniCtx.rotate(-player.angle); miniCtx.translate(-player.x/5, -player.y/5);
for(let y=0; y<MAP_SIZE; y++) for(let x=0; x<MAP_SIZE; x++) { if(map[y][x] > 0) { miniCtx.fillStyle = '#7f8c8d'; miniCtx.fillRect(x*BLOCK/5, y*BLOCK/5, BLOCK/5, BLOCK/5); } }
shops.forEach(s => { miniCtx.fillStyle = '#9b59b6'; miniCtx.beginPath(); miniCtx.arc(s.x/5, s.y/5, 4, 0, 6.28); miniCtx.fill(); });
if(mission.active) { miniCtx.fillStyle = '#f1c40f'; miniCtx.beginPath(); miniCtx.arc(mission.x/5, mission.y/5, 5, 0, 6.28); miniCtx.fill(); }
miniCtx.restore();
miniCtx.fillStyle = '#f39c12'; miniCtx.beginPath(); miniCtx.arc(75, 75, 3, 0, 6.28); miniCtx.fill();
}
function dist(x1,y1,x2,y2){return Math.sqrt((x1-x2)**2+(y1-y2)**2);}
function blood(x,y){for(let i=0;i<8;i++)particles.push({x,y,size:4,color:'#c0392b',life:30});}
function showMsg(t,c){let m=document.getElementById('mission-msg'); m.innerText=t; m.style.color=c; m.style.display='block'; setTimeout(()=>m.style.display='none',2000);}
function interact() {
if(isGamePaused) return;
if(player.state === 'driving') { player.state='on_foot'; player.x-=30; player.car=null; }
else { let near=cars.find(c=>dist(player.x,player.y,c.x,c.y)<60); if(near){player.state='driving'; player.car=near;} }
}
function updateUI() {
document.getElementById('money').innerText="$"+player.money; document.getElementById('health-bar').style.width=Math.max(0,player.health)+'%';
let s="";for(let i=0;i<5;i++)s+=i<player.wanted?"★":"☆";document.getElementById('wanted-level').innerText=s;
let btnShoot=document.getElementById('btn-shoot'), ammoDiv=document.getElementById('ammo-display');
if(player.weapon==='pistol'){if(isMobile)btnShoot.style.display='flex';ammoDiv.style.display='block';ammoDiv.innerText=`🔫 ${player.ammo}`;}
else{if(isMobile)btnShoot.style.display='none';ammoDiv.style.display='none';}
}
function setupControls() {
window.addEventListener('keydown', e => {
if(e.key.toLowerCase() === 'w') keys.w = 1;
if(e.key.toLowerCase() === 's') keys.s = 1;
if(e.key.toLowerCase() === 'a') keys.a = 1;
if(e.key.toLowerCase() === 'd') keys.d = 1;
if(e.key.toLowerCase() === 'e') {
if(canInteract==='shop') openShop();
else if(canInteract==='mission') completeMission();
else interact();
}
});
window.addEventListener('keyup', e => {
if(e.key.toLowerCase() === 'w') keys.w = 0;
if(e.key.toLowerCase() === 's') keys.s = 0;
if(e.key.toLowerCase() === 'a') keys.a = 0;
if(e.key.toLowerCase() === 'd') keys.d = 0;
});
window.addEventListener('mousemove', e => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
window.addEventListener('mousedown', e => {
if(e.button === 0) mouse.down = true;
});
window.addEventListener('mouseup', e => {
if(e.button === 0) mouse.down = false;
});
if(isMobile) {
let joy=document.getElementById('joy-bg'), stick=document.getElementById('joy-stick');
joy.addEventListener('touchstart', e => {
e.preventDefault();
let t = e.touches[0];
let r = joy.getBoundingClientRect();
let dx = t.clientX - (r.left + 70);
let dy = t.clientY - (r.top + 70);
let d = Math.min(Math.hypot(dx, dy), 50);
let a = Math.atan2(dy, dx);
inputVector.x = Math.cos(a) * (d/50);
inputVector.y = Math.sin(a) * (d/50);
stick.style.transform = `translate(calc(-50% + ${inputVector.x*50}px), calc(-50% + ${inputVector.y*50}px))`;
});
joy.addEventListener('touchmove', e => {
e.preventDefault();
let t = e.touches[0];
let r = joy.getBoundingClientRect();
let dx = t.clientX - (r.left + 70);
let dy = t.clientY - (r.top + 70);
let d = Math.min(Math.hypot(dx, dy), 50);
let a = Math.atan2(dy, dx);
inputVector.x = Math.cos(a) * (d/50);
inputVector.y = Math.sin(a) * (d/50);
stick.style.transform = `translate(calc(-50% + ${inputVector.x*50}px), calc(-50% + ${inputVector.y*50}px))`;
});
joy.addEventListener('touchend', () => {
inputVector = {x: 0, y: 0};
stick.style.transform = `translate(-50%, -50%)`;
});
document.getElementById('btn-enter').onclick = () => {
if(canInteract==='shop') openShop();
else if(canInteract==='mission') completeMission();
else interact();
};
document.getElementById('btn-shoot').addEventListener('touchstart', () => {
keys.shoot = 1;
});
document.getElementById('btn-shoot').addEventListener('touchend', () => {
keys.shoot = 0;
});
}
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
</script>
</body>
</html>
yumru atarsan mouse clikc ile polis aramaya başlar her vuruşta aranma yıldızı artar ve polisler sana saldırır takip eder

yakalanırsan yakalandın yazar oyun tekrar başlar

dükkanlara e ile basıp bir takım ürünler alabilirsin

can ,yenileme , silah , polisten kurtul

arabaya yanaşıp e ile basıp arabaya biner insanları ezebilirsin - polisi öldürünce silahını alabilirsin

sarı alana giderseniz e ye basarsanız para verir görev yapmış olursunuz

Selamlar yapay zeka ile basit birşey yaptım gta 2 benzeri geliştirmesi size kalmış kodları attım (buglar vs olabilir stabil çalışmayabilir iyi forumlar