<!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