User prompt
Harita nın sağ ında market olsun markete gelince marketin içine ışınlalım ve 50 paraya 100 mermi allım ve marketin kapısına gelince başlangıç noktasına ışınlalım
User prompt
Ammo yıldızların altında yazsın
User prompt
Ammo sağ alt köşede yazsın
User prompt
Sadece 100 mermi ateş etmemiz lazım olsun 100 mermi bitince ekrana her tıkladığında mermi bitti yazsın yerden silah alınca tekrardan 100 mermisi olsun
User prompt
5 yıldız olunca çok fazla police spawnlansın
User prompt
5 yıldız olunca 10 tane police spawnlansın
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'civ.update')' in or related to this line: 'civ.update();' Line Number: 1255
User prompt
Araya 30 kere ateş edince arba yok olsun ve ekrana 2 saniyeliğine arba patladı yazsın
User prompt
Arbayla polisleride ezelim
User prompt
Biz arabadayken polisler bize hasar vermesin
User prompt
Dünya sınırsız olmasın
User prompt
Dünya sınırsız boyutta olsun
User prompt
Elinde akm var yazısı olmasın
User prompt
Elinde akm var yazısı çok büyük olsun
User prompt
Elinde akm var yazısı büyük olsun
User prompt
Elinde akm var yazısı büyük olsun
User prompt
Dahada büyük olsun
User prompt
Daha büyük olsun
User prompt
Yazı daha kalın olsun
User prompt
Daha küçük olsun
User prompt
Elinde akm yazısı daha büyük olsun
User prompt
Yıldızın oldu yerin biraz altında oyun bitene kadar elinde akm var yazsın
User prompt
Para barı birazdaha büyük olsun
User prompt
Player araba kunlanırken Npclerin üzerinden geçerse o npc ölsün
User prompt
Player arba kunlanırken npclerin üzerinden geçerse npc ler ölsün
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 48;
self.dir = 0;
self.owner = null; // 'player' or 'police'
self.update = function () {
self.x += Math.cos(self.dir) * self.speed;
self.y += Math.sin(self.dir) * self.speed;
};
return self;
});
// Car (stealable)
var Car = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 5; // much slower
self.acceleration = 0.2; // slower acceleration
self.deceleration = 0.3; // slower deceleration
self.direction = 0; // radians
self.driver = null; // player if inside
self.isPolice = false;
self.targetDir = 0; // for smooth steering
self.update = function () {
if (self.driver) {
// Smoothly turn toward target direction (set by dragDir)
var diff = self.targetDir - self.direction;
// Normalize angle to [-PI, PI]
while (diff > Math.PI) diff -= 2 * Math.PI;
while (diff < -Math.PI) diff += 2 * Math.PI;
self.direction += diff * 0.2; // smooth steering
// Gradually accelerate to maxSpeed
if (self.speed < self.maxSpeed) {
self.speed += self.acceleration;
if (self.speed > self.maxSpeed) self.speed = self.maxSpeed;
}
// Move in direction
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
} else {
// If no driver, slow down to stop
if (self.speed > 0) {
self.speed -= self.deceleration;
if (self.speed < 0) self.speed = 0;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
}
}
};
return self;
});
// CityBlock: road or building
var CityBlock = Container.expand(function () {
var self = Container.call(this);
self.type = 'road'; // or 'building'
self.setType = function (type) {
self.type = type;
if (self.asset) {
self.removeChild(self.asset);
}
if (type === 'road') {
self.asset = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
self.asset = self.attachAsset('building', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
return self;
});
var Civilian = Container.expand(function () {
var self = Container.call(this);
// Pick a random color asset for this civilian
var civAssetIdx = 1 + Math.floor(Math.random() * 6);
var civAssetName = 'civilian' + civAssetIdx;
self.asset = self.attachAsset(civAssetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.asset.alpha = 0.7;
// Add 'npc' label above the civilian
self.npcLabel = new Text2('npc', {
size: 38,
fill: 0xFFFFFF
});
self.npcLabel.anchor.set(0.5, 1);
self.npcLabel.y = -40;
self.addChild(self.npcLabel);
self.speed = 2 + Math.random() * 2;
self.direction = Math.random() * Math.PI * 2;
self.update = function () {
// Move in direction, bounce off buildings
var nx = self.x + Math.cos(self.direction) * self.speed;
var ny = self.y + Math.sin(self.direction) * self.speed;
var onRoad = false;
for (var i = 0; i < cityBlocks.length; i++) {
var b = cityBlocks[i];
if (b.type === 'road') {
var left = b.x - blockSize / 2;
var right = b.x + blockSize / 2;
var top = b.y - blockSize / 2;
var bottom = b.y + blockSize / 2;
if (nx >= left && nx <= right && ny >= top && ny <= bottom) {
onRoad = true;
break;
}
}
}
if (onRoad) {
self.x = nx;
self.y = ny;
} else {
self.direction = Math.random() * Math.PI * 2;
}
};
return self;
});
// Spawn 6 civilians at random road blocks (not near player or police)
// Mission marker
var Mission = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('mission', {
anchorX: 0.5,
anchorY: 0.5
});
self.active = true;
return self;
});
// Player character
var Player = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Add 'you' label above the player
self.youLabel = new Text2('you', {
size: 38,
fill: 0xFFFFFF
});
self.youLabel.anchor.set(0.5, 1);
self.youLabel.y = -80;
self.addChild(self.youLabel);
self.speed = 16;
self.inCar = null; // reference to car if inside
self.direction = 0; // radians, 0 = right
// Add gun to player's hand
self.gun = self.attachAsset('gun', {
anchorX: 0.1,
anchorY: 0.5
});
self.gun.x = 60; // offset from player center
self.gun.y = 0;
self.gun.visible = true;
self.lastShotDir = 0; // radians
self.update = function () {
// If in car, follow car and hide player sprite
if (self.inCar) {
self.x = self.inCar.x;
self.y = self.inCar.y;
self.visible = false;
self.gun.visible = false;
self.youLabel.visible = false;
} else {
self.visible = true;
self.gun.visible = true;
self.youLabel.visible = true;
// Gun follows player hand and points at last shot direction
self.gun.x = 60 * Math.cos(self.lastShotDir);
self.gun.y = 60 * Math.sin(self.lastShotDir);
self.gun.rotation = self.lastShotDir;
}
};
return self;
});
// Police car
var PoliceCar = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('police', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 2.5; // much slower (reduced for slower police)
self.acceleration = 0.08; // slower acceleration
self.deceleration = 0.15; // slower deceleration
self.direction = 0;
self.target = null; // player or car
self.isPolice = true;
self.targetDir = 0;
self.update = function () {
if (self.target) {
// Simple chase logic
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.targetDir = Math.atan2(dy, dx);
// Smoothly turn toward target direction
var diff = self.targetDir - self.direction;
while (diff > Math.PI) diff -= 2 * Math.PI;
while (diff < -Math.PI) diff += 2 * Math.PI;
self.direction += diff * 0.2;
// Accelerate to maxSpeed
if (self.speed < self.maxSpeed) {
self.speed += self.acceleration;
if (self.speed > self.maxSpeed) self.speed = self.maxSpeed;
}
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
} else {
self.speed = 0;
}
} else {
// If no target, slow down to stop
if (self.speed > 0) {
self.speed -= self.deceleration;
if (self.speed < 0) self.speed = 0;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
}
}
};
return self;
});
// Police shooter class (policeman on foot)
var PoliceShooter = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('police', {
anchorX: 0.5,
anchorY: 0.5
});
// Add 'POLIS' label above the police shooter
self.polisLabel = new Text2('POLIS', {
size: 38,
fill: 0xFFFFFF
});
self.polisLabel.anchor.set(0.5, 1);
self.polisLabel.y = -80;
self.addChild(self.polisLabel);
// Add gun to police shooter's hand
self.gun = self.attachAsset('gun', {
anchorX: 0.1,
anchorY: 0.5
});
self.gun.x = 60;
self.gun.y = 0;
self.gun.visible = true;
self.addChild(self.gun);
self.speed = 5; // reduced for slower police
self.target = null;
self.lastShotTick = 0;
self.lastShotDir = 0; // direction of last shot
self.update = function () {
// If not aggro (no target), patrol randomly on roads
if (!self.target) {
if (typeof self.patrolTarget === "undefined" || !self.patrolTarget) {
// Pick a random road block as patrol target
var roadBlocks = [];
for (var k = 0; k < cityBlocks.length; k++) {
if (cityBlocks[k].type === 'road') roadBlocks.push(cityBlocks[k]);
}
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
self.patrolTarget = {
x: roadBlocks[idx].x + (Math.random() - 0.5) * 100,
y: roadBlocks[idx].y + (Math.random() - 0.5) * 100
};
}
}
if (self.patrolTarget) {
var dx = self.patrolTarget.x - self.x;
var dy = self.patrolTarget.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.direction = Math.atan2(dy, dx);
self.x += Math.cos(self.direction) * self.speed * 0.5;
self.y += Math.sin(self.direction) * self.speed * 0.5;
} else {
// Arrived at patrol target, pick a new one next frame
self.patrolTarget = null;
}
// Gun points in patrol direction
self.lastShotDir = self.direction;
self.gun.x = 60 * Math.cos(self.lastShotDir);
self.gun.y = 60 * Math.sin(self.lastShotDir);
self.gun.rotation = self.lastShotDir;
}
} else {
// Move toward player if target exists
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 120) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Gun points at player
self.lastShotDir = Math.atan2(dy, dx);
self.gun.x = 60 * Math.cos(self.lastShotDir);
self.gun.y = 60 * Math.sin(self.lastShotDir);
self.gun.rotation = self.lastShotDir;
}
// Firing handled in game.update
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
// No title, no description
// Set backgroundColor to vibrant green for lush map
backgroundColor: 0x1ecb2a
});
/****
* Game Code
****/
// Mission marker - green ellipse
// Police car - white box with blue
// Car - yellow box
// Player (hero) - red ellipse
// Building - blue box
// City block (road) - gray box
// --- Fixed City Map Setup ---
var blockSize = 400;
var cityBlocks = [];
var cityBlockMap = {}; // key: "col,row" -> CityBlock
// Fixed grid size
var gridCols = 9;
var gridRows = 13;
// Use a simple procedural pattern: every even col/row is road, others are building
function getBlockType(col, row) {
// Make a simple city: roads every 2 blocks, rest are buildings
if (col % 2 === 0 || row % 2 === 0) return 'road';
return 'building';
}
// Helper to get or create a city block at (col, row)
function getOrCreateCityBlock(col, row) {
// Clamp to fixed grid
if (col < -Math.floor(gridCols / 2) || col > Math.floor(gridCols / 2) || row < -Math.floor(gridRows / 2) || row > Math.floor(gridRows / 2)) {
return null;
}
var key = col + ',' + row;
if (cityBlockMap[key]) return cityBlockMap[key];
var block = new CityBlock();
var type = getBlockType(col, row);
block.setType(type);
block.x = col * blockSize + blockSize / 2;
block.y = row * blockSize + blockSize / 2;
cityBlockMap[key] = block;
cityBlocks.push(block);
game.addChild(block);
return block;
}
// Generate fixed grid (centered at 0,0)
var initialCols = gridCols,
initialRows = gridRows;
var centerCol = 0,
centerRow = 0;
for (var row = -Math.floor(initialRows / 2); row <= Math.floor(initialRows / 2); row++) {
for (var col = -Math.floor(initialCols / 2); col <= Math.floor(initialCols / 2); col++) {
getOrCreateCityBlock(col, row);
}
}
// Helper to get all road blocks in a region (for spawning)
function getRoadBlocksInRegion(colMin, colMax, rowMin, rowMax) {
var blocks = [];
for (var row = rowMin; row <= rowMax; row++) {
for (var col = colMin; col <= colMax; col++) {
var block = getOrCreateCityBlock(col, row);
if (block && block.type === 'road') blocks.push(block);
}
}
return blocks;
}
// Helper to get nearest road block col/row for a given x/y
function getColRowForXY(x, y) {
var col = Math.round((x - blockSize / 2) / blockSize);
var row = Math.round((y - blockSize / 2) / blockSize);
// Clamp to grid
col = Math.max(-Math.floor(gridCols / 2), Math.min(Math.floor(gridCols / 2), col));
row = Math.max(-Math.floor(gridRows / 2), Math.min(Math.floor(gridRows / 2), row));
return {
col: col,
row: row
};
}
// --- Player Setup ---
// Spawn player at center of the infinite world (col=0, row=0)
var player = new Player();
player.x = 0 * blockSize + blockSize / 2;
player.y = 0 * blockSize + blockSize / 2;
game.addChild(player);
// --- Civilians Setup ---
var civilians = [];
// Spawn 6 civilians at random road blocks (not near player or police)
for (var i = 0; i < 6; i++) {
// Use a region around player for infinite world
var playerColRow = getColRowForXY(player.x, player.y);
var roadBlocks = getRoadBlocksInRegion(playerColRow.col - 7, playerColRow.col + 7, playerColRow.row - 7, playerColRow.row + 7);
// Avoid spawn near player
var filtered = [];
for (var j = 0; j < roadBlocks.length; j++) {
var b = roadBlocks[j];
var distToPlayer = Math.sqrt(Math.pow(b.x - player.x, 2) + Math.pow(b.y - player.y, 2));
if (distToPlayer > 400) filtered.push(b);
}
if (filtered.length > 0) {
var idx = Math.floor(Math.random() * filtered.length);
var civ = new Civilian();
civ.x = filtered[idx].x + (Math.random() - 0.5) * 100;
civ.y = filtered[idx].y + (Math.random() - 0.5) * 100;
civilians.push(civ);
game.addChild(civ);
}
}
// --- Cars Setup ---
var cars = [];
function spawnCar(x, y) {
var car = new Car();
car.x = x;
car.y = y;
car.direction = Math.random() * Math.PI * 2;
cars.push(car);
game.addChild(car);
return car;
}
// Place a few cars on roads using fixed world
var roadBlocksForCars = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
// Remove player's starting block
if (!(cityBlocks[i].x === player.x && cityBlocks[i].y === player.y)) {
roadBlocksForCars.push(cityBlocks[i]);
}
}
}
// Shuffle
for (var k = roadBlocksForCars.length - 1; k > 0; k--) {
var j = Math.floor(Math.random() * (k + 1));
var temp = roadBlocksForCars[k];
roadBlocksForCars[k] = roadBlocksForCars[j];
roadBlocksForCars[j] = temp;
}
// Spawn up to 4 cars in distinct available road blocks
var carsToSpawn = 4;
for (var i = 0; i < Math.min(carsToSpawn, roadBlocksForCars.length); i++) {
var block = roadBlocksForCars[i];
spawnCar(block.x, block.y);
}
// --- Police Setup ---
var policeCars = [];
function spawnPolice(x, y) {
var police = new PoliceCar();
police.x = x;
police.y = y;
police.direction = 0;
// Police do not chase the player anymore
police.target = null;
policeCars.push(police);
game.addChild(police);
return police;
}
// Start with three police cars at different road blocks
var policeStartBlocks = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
policeStartBlocks.push(cityBlocks[i]);
}
}
if (policeStartBlocks.length > 0) {
// Always spawn one at the top left of region
var policeStartX = cityBlocks[0].x;
var policeStartY = cityBlocks[0].y;
spawnPolice(policeStartX, policeStartY);
// Pick two more random road blocks (not the same as above)
var used = {};
used[policeStartX + ',' + policeStartY] = true;
for (var p = 0; p < 2; p++) {
var idx = Math.floor(Math.random() * policeStartBlocks.length);
var b = policeStartBlocks[idx];
var key = b.x + ',' + b.y;
if (!used[key]) {
spawnPolice(b.x, b.y);
used[key] = true;
}
}
}
// --- Mission Setup ---
var mission = new Mission();
// Place mission at far corner of grid
mission.x = cityBlocks[cityBlocks.length - 1].x;
mission.y = cityBlocks[cityBlocks.length - 1].y;
game.addChild(mission);
// --- Money on ground ---
var moneyPickups = [];
function spawnMoney(x, y) {
var m = new Container();
m.asset = m.attachAsset('mission', {
anchorX: 0.5,
anchorY: 0.5
});
m.x = x;
m.y = y;
m.value = 50;
moneyPickups.push(m);
game.addChild(m);
return m;
}
// Place 15 money pickups at random road blocks in grid
var roadBlocksForMoney = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
roadBlocksForMoney.push(cityBlocks[i]);
}
}
for (var i = 0; i < 15; i++) {
if (roadBlocksForMoney.length > 0) {
var idx = Math.floor(Math.random() * roadBlocksForMoney.length);
var b = roadBlocksForMoney[idx];
var mx = b.x + (Math.random() - 0.5) * (blockSize - 100);
var my = b.y + (Math.random() - 0.5) * (blockSize - 100);
spawnMoney(mx, my);
}
}
// --- Score and Wanted Level ---
var score = 0;
var wantedLevel = 1; // 1-5
var scoreTxt = new Text2('Score: 0', {
size: 90,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var wantedTxt = new Text2('★', {
size: 80,
fill: "#ff0"
});
wantedTxt.anchor.set(1, 0); // anchor to top right
wantedTxt.x = 0;
wantedTxt.y = 0;
LK.gui.topRight.addChild(wantedTxt);
// (Removed 'elinde akm var' text below the wanted stars)
// --- Timer ---
var timeLeft = 60; // seconds
var timerTxt = new Text2('60', {
size: 80,
fill: "#fff"
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
// --- Touch Controls ---
var dragDir = null; // {dx,dy}
var dragStart = null;
var dragNode = null;
var lastTouchX = 0,
lastTouchY = 0;
// --- Shooting & Health ---
var bullets = [];
var policeBullets = [];
var playerHealth = 5;
// Money system
var playerMoney = 0;
var moneyTxt = new Text2('₺ 0', {
size: 120,
fill: 0x44FF44
});
moneyTxt.anchor.set(0, 0);
moneyTxt.x = 100;
moneyTxt.y = 90;
LK.gui.addChild(moneyTxt);
var healthTxt = new Text2('♥♥♥♥♥', {
size: 80,
fill: 0xFF4444
});
healthTxt.anchor.set(0, 0); // anchor top left
// Place health bar at (100,0) to avoid platform menu
healthTxt.x = 100;
healthTxt.y = 0;
LK.gui.addChild(healthTxt);
// Track if police are aggressive (chasing) or passive
var policeAggro = false;
// Helper to update health display
function updateHealthDisplay() {
var hearts = '';
for (var i = 0; i < playerHealth; i++) hearts += '♥';
healthTxt.setText(hearts);
}
function updateMoneyDisplay() {
moneyTxt.setText('₺ ' + playerMoney);
}
var policeShooters = [];
// Spawn a few police shooters at random road blocks, not near player (fixed world)
for (var i = 0; i < 8; i++) {
var roadBlocks = [];
for (var j = 0; j < cityBlocks.length; j++) {
if (cityBlocks[j].type === 'road') {
var b = cityBlocks[j];
var distToPlayer = Math.sqrt(Math.pow(b.x - player.x, 2) + Math.pow(b.y - player.y, 2));
if (distToPlayer > 600) roadBlocks.push(b);
}
}
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
var shooter = new PoliceShooter();
shooter.x = roadBlocks[idx].x + (Math.random() - 0.5) * 100;
shooter.y = roadBlocks[idx].y + (Math.random() - 0.5) * 100;
shooter.target = null; // Do not target player at start
shooter.wasShotAt = false; // Only shoot if player shoots at them
policeShooters.push(shooter);
game.addChild(shooter);
}
}
// --- Helper Functions ---
function isOnRoad(x, y) {
// Returns true if (x,y) is on a road block (fixed world)
var colRow = getColRowForXY(x, y);
var block = getOrCreateCityBlock(colRow.col, colRow.row);
if (block && block.type === 'road') {
var left = block.x - blockSize / 2;
var right = block.x + blockSize / 2;
var top = block.y - blockSize / 2;
var bottom = block.y + blockSize / 2;
if (x >= left && x <= right && y >= top && y <= bottom) {
return true;
}
}
return false;
}
function clampToRoad(x, y) {
// Snap to nearest road block center (fixed world)
var colRow = getColRowForXY(x, y);
var block = getOrCreateCityBlock(colRow.col, colRow.row);
if (block && block.type === 'road') {
return {
x: block.x,
y: block.y
};
}
// If not road, search nearby
for (var r = -1; r <= 1; r++) {
for (var c = -1; c <= 1; c++) {
var b = getOrCreateCityBlock(colRow.col + c, colRow.row + r);
if (b && b.type === 'road') return {
x: b.x,
y: b.y
};
}
}
// Fallback: return original
return {
x: x,
y: y
};
}
function updateWantedDisplay() {
var stars = '';
for (var i = 0; i < wantedLevel; i++) stars += '★';
wantedTxt.setText(stars);
// Default color
var color = "#ff0";
// If 5 stars, flash red/blue
if (wantedLevel === 5) {
// Show "wandet" text for 3 seconds only on the frame wantedLevel becomes 5
if (typeof wandetTextShown === "undefined") wandetTextShown = false;
if (!wandetTextShown) {
// Remove previous if exists
if (typeof wandetText !== "undefined" && wandetText.parent) {
wandetText.parent.removeChild(wandetText);
wandetText = undefined;
}
wandetText = new Text2("wandet", {
size: 160,
fill: 0xFF2222
});
wandetText.anchor.set(0.5, 0);
wandetText.x = 2048 / 2;
wandetText.y = 500;
LK.gui.addChild(wandetText);
wandetTextShown = true;
LK.setTimeout(function () {
if (wandetText && wandetText.parent) {
wandetText.parent.removeChild(wandetText);
wandetText = undefined;
}
wandetTextShown = false;
}, 3000);
}
// Alternate color every 20 ticks (about 1/3 second at 60fps)
if (LK.ticks % 40 < 20) {
color = "#ff2222"; // red
} else {
color = "#2288ff"; // blue
}
}
if (wantedTxt && wantedTxt.style && typeof wantedTxt.style.fill !== "undefined") {
wantedTxt.style.fill = color;
}
}
function addScore(amt) {
score += amt;
scoreTxt.setText('Score: ' + score);
LK.setScore(score);
}
function resetMission() {
// Place mission at random road block (fixed world)
var roadBlocks = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
var b = cityBlocks[i];
var distToPlayer = Math.sqrt(Math.pow(b.x - player.x, 2) + Math.pow(b.y - player.y, 2));
if (distToPlayer > 400) roadBlocks.push(b);
}
}
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
mission.x = roadBlocks[idx].x;
mission.y = roadBlocks[idx].y;
mission.active = true;
mission.visible = true;
}
}
// --- Game Touch Controls ---
// Drag to move (swipe in direction to move)
game.down = function (x, y, obj) {
// Don't allow drag from top left 100x100
if (x < 100 && y < 100) return;
// --- SHOOTING LOGIC ---
// If not dragging, treat as tap to shoot
if (!dragNode && !dragDir && !player.inCar) {
// Player shoots toward (x, y)
var b = new Bullet();
b.x = player.x;
b.y = player.y;
b.dir = Math.atan2(y - b.y, x - b.x);
b.owner = 'player';
bullets.push(b);
game.addChild(b);
// Update player's gun direction to point at shot
player.lastShotDir = b.dir;
// No police aggro or wanted level increase when shooting police
}
// --- DRAG LOGIC (movement) ---
dragStart = {
x: x,
y: y
};
lastTouchX = x;
lastTouchY = y;
dragDir = null;
dragNode = player;
};
game.move = function (x, y, obj) {
if (!dragNode) return;
var dx = x - dragStart.x;
var dy = y - dragStart.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 30) {
dragDir = {
dx: dx,
dy: dy
};
}
lastTouchX = x;
lastTouchY = y;
};
game.up = function (x, y, obj) {
dragNode = null;
dragDir = null;
dragStart = null;
};
// --- Car Enter/Exit Logic ---
// Track tap times for triple-tap exit
var carTapTimes = [];
game.on('down', function (x, y, obj) {
// If player is not in car, check if tap is on car and player is close enough
if (!player.inCar) {
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
var dx = car.x - x;
var dy = car.y - y;
// Tap must be on car
if (Math.abs(dx) < 80 && Math.abs(dy) < 50) {
// Player must be close to car to enter
if (Math.abs(player.x - car.x) < 120 && Math.abs(player.y - car.y) < 80) {
player.inCar = car;
car.driver = player;
// Do not set car.speed here; Car.update will handle acceleration
car.direction = 0;
// Increase wanted level
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
// Police target car
for (var j = 0; j < policeCars.length; j++) {
policeCars[j].target = car;
}
// Reset tap times for exit
carTapTimes = [];
break;
}
}
}
} else {
// Player is in car: require triple-tap within 1 second to exit
var now = Date.now();
carTapTimes.push(now);
// Only keep last 3 taps
if (carTapTimes.length > 3) carTapTimes.shift();
if (carTapTimes.length === 3) {
// Check if 3 taps are within 1 second
if (carTapTimes[2] - carTapTimes[0] < 1000) {
var car = player.inCar;
player.inCar = null;
car.driver = null;
// Do not set car.speed to 0; Car.update will handle deceleration
// Place player next to car
player.x = car.x + 80;
player.y = car.y;
// Police target player
for (var j = 0; j < policeCars.length; j++) {
policeCars[j].target = player;
}
carTapTimes = [];
}
}
}
});
// --- Game Update Loop ---
game.update = function () {
// Timer
if (LK.ticks % 60 === 0 && timeLeft > 0) {
timeLeft--;
timerTxt.setText(timeLeft + '');
// Do not end the game when timer reaches zero
}
// Player movement
if (!player.inCar && dragDir) {
// Move player in drag direction, but only on road
var angle = Math.atan2(dragDir.dy, dragDir.dx);
var nx = player.x + Math.cos(angle) * player.speed;
var ny = player.y + Math.sin(angle) * player.speed;
if (isOnRoad(nx, ny)) {
player.x = nx;
player.y = ny;
}
// No infinite world: no need to generate new blocks in update
}
// Car movement (if player in car)
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
// If player is driving this car, set car's targetDir to drag direction
if (car.driver === player && dragDir) {
var angle = Math.atan2(dragDir.dy, dragDir.dx);
car.targetDir = angle;
}
car.update();
// Clamp car to road
if (car.driver) {
if (!isOnRoad(car.x, car.y)) {
// Stop car at edge
car.speed = 0;
}
}
}
// Police movement
for (var i = 0; i < policeCars.length; i++) {
var police = policeCars[i];
// Police patrol logic: move randomly on roads if not chasing
if (!policeAggro) {
if (typeof police.patrolTarget === "undefined" || !police.patrolTarget) {
// Pick a random road block as patrol target
var roadBlocks = [];
for (var k = 0; k < cityBlocks.length; k++) {
if (cityBlocks[k].type === 'road') roadBlocks.push(cityBlocks[k]);
}
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
police.patrolTarget = {
x: roadBlocks[idx].x + (Math.random() - 0.5) * 100,
y: roadBlocks[idx].y + (Math.random() - 0.5) * 100
};
}
}
if (police.patrolTarget) {
var dx = police.patrolTarget.x - police.x;
var dy = police.patrolTarget.y - police.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
police.direction = Math.atan2(dy, dx);
police.speed = police.maxSpeed * 0.5;
police.x += Math.cos(police.direction) * police.speed;
police.y += Math.sin(police.direction) * police.speed;
} else {
// Arrived at patrol target, pick a new one next frame
police.patrolTarget = null;
police.speed = 0;
}
}
} else {
police.update();
}
// Clamp police to road
if (!isOnRoad(police.x, police.y)) {
police.speed = 0;
}
// Police catch player
var target = police.target;
if (policeAggro && target && Math.abs(police.x - target.x) < 80 && Math.abs(police.y - target.y) < 80) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Police shooters update
for (var i = policeShooters.length - 1; i >= 0; i--) {
var shooter = policeShooters[i];
shooter.update();
// Remove if off map
if (shooter.x < 0 || shooter.x > 2048 || shooter.y < 0 || shooter.y > 2732) {
shooter.destroy();
policeShooters.splice(i, 1);
continue;
}
// --- Police shooter fires at player only if aggro (wasShotAt or policeAggro) ---
// Only fire if player is within 700px, not in car, and shooter is aggro
if (shooter.wasShotAt || policeAggro) {
var px = player.inCar ? player.inCar.x : player.x;
var py = player.inCar ? player.inCar.y : player.y;
var dx = px - shooter.x;
var dy = py - shooter.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 700 && LK.ticks - shooter.lastShotTick > 60) {
// Fire bullet toward player
var b = new Bullet();
b.x = shooter.x;
b.y = shooter.y;
b.dir = Math.atan2(dy, dx);
b.owner = 'police';
policeBullets.push(b);
game.addChild(b);
shooter.lastShotTick = LK.ticks;
}
}
}
// Bullets update (player)
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
if (b && typeof b.update === "function") {
b.update();
}
// Remove if off screen
if (b && typeof b.x === "number" && typeof b.y === "number" && (b.x < 0 || b.x > 2048 || b.y < 0 || b.y > 2732)) {
b.destroy();
bullets.splice(i, 1);
continue;
}
// --- Police car kill check ---
for (var j = policeCars.length - 1; j >= 0; j--) {
var police = policeCars[j];
if (police && b && typeof police.x === "number" && typeof police.y === "number" && typeof b.x === "number" && typeof b.y === "number" && Math.abs(police.x - b.x) < 60 && Math.abs(police.y - b.y) < 60) {
// Police car killed!
// Drop a gun at police car's position
var gunDrop = new Container();
gunDrop.asset = gunDrop.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
// Add 'gun' label above the dropped gun
gunDrop.gunLabel = new Text2('gun', {
size: 38,
fill: 0xFFFFFF
});
gunDrop.gunLabel.anchor.set(0.5, 1);
gunDrop.gunLabel.y = -30;
gunDrop.addChild(gunDrop.gunLabel);
gunDrop.x = police.x;
gunDrop.y = police.y;
gunDrop.isGunPickup = true;
game.addChild(gunDrop);
if (typeof gunPickups === "undefined") gunPickups = [];
gunPickups.push(gunDrop);
police.destroy();
policeCars.splice(j, 1);
b.destroy();
bullets.splice(i, 1);
addScore(20);
// Increase wanted level by 1 (max 5) when police car is killed
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
// Only aggro police if wantedLevel is 5
if (wantedLevel === 5 && typeof spawned5StarPolice === "undefined") {
for (var p = 0; p < policeShooters.length; p++) {
policeShooters[p].wasShotAt = true;
policeShooters[p].target = player;
}
for (var p = 0; p < policeCars.length; p++) {
policeCars[p].target = player;
}
policeAggro = true;
// Spawn 5 police cars at random road blocks (not near player)
var roadBlocks = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
var distToPlayer = Math.sqrt(Math.pow(cityBlocks[i].x - player.x, 2) + Math.pow(cityBlocks[i].y - player.y, 2));
if (distToPlayer > 400) {
roadBlocks.push(cityBlocks[i]);
}
}
}
for (var s = 0; s < 5; s++) {
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
var b = roadBlocks[idx];
var newPolice = spawnPolice(b.x, b.y);
newPolice.target = player;
// Remove this block from roadBlocks to avoid double-spawn at same spot
roadBlocks.splice(idx, 1);
}
}
spawned5StarPolice = true;
}
break;
}
}
// --- Police shooter kill check ---
for (var j = policeShooters.length - 1; j >= 0; j--) {
var shooter = policeShooters[j];
if (shooter && b && typeof shooter.x === "number" && typeof shooter.y === "number" && typeof b.x === "number" && typeof b.y === "number" && Math.abs(shooter.x - b.x) < 60 && Math.abs(shooter.y - b.y) < 60) {
// Mark this shooter as shot at, so it will shoot back
shooter.wasShotAt = true;
// --- Police shooter health logic ---
// Instantly kill police shooter with one bullet
b.destroy();
bullets.splice(i, 1);
// Police shooter killed!
// Drop a gun at police shooter's position
var gunDrop = new Container();
gunDrop.asset = gunDrop.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
// Add 'gun' label above the dropped gun
gunDrop.gunLabel = new Text2('gun', {
size: 38,
fill: 0xFFFFFF
});
gunDrop.gunLabel.anchor.set(0.5, 1);
gunDrop.gunLabel.y = -30;
gunDrop.addChild(gunDrop.gunLabel);
gunDrop.x = shooter.x;
gunDrop.y = shooter.y;
gunDrop.isGunPickup = true;
game.addChild(gunDrop);
if (typeof gunPickups === "undefined") gunPickups = [];
gunPickups.push(gunDrop);
shooter.destroy();
policeShooters.splice(j, 1);
// --- Spawn TWO new police shooters at random road blocks, not near player ---
for (var spawnCount = 0; spawnCount < 2; spawnCount++) {
var roadBlocks = [];
for (var k = 0; k < cityBlocks.length; k++) {
var b2 = cityBlocks[k];
if (b2.type === 'road') {
var distToPlayer = Math.sqrt(Math.pow(b2.x - player.x, 2) + Math.pow(b2.y - player.y, 2));
if (distToPlayer > 600) {
roadBlocks.push(b2);
}
}
}
if (roadBlocks.length > 0) {
var idx2 = Math.floor(Math.random() * roadBlocks.length);
var newShooter = new PoliceShooter();
newShooter.x = roadBlocks[idx2].x + (Math.random() - 0.5) * 100;
newShooter.y = roadBlocks[idx2].y + (Math.random() - 0.5) * 100;
if (policeAggro) {
newShooter.target = player;
newShooter.wasShotAt = true;
} else {
newShooter.target = null;
newShooter.wasShotAt = false;
}
policeShooters.push(newShooter);
game.addChild(newShooter);
}
}
addScore(15);
// Increase wanted level by 1 (max 5) when police shooter is killed
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
break;
// If not dead, do not break, allow other shooters to be checked
}
}
}
// Bullets update (police)
for (var i = policeBullets.length - 1; i >= 0; i--) {
var b = policeBullets[i];
if (b && typeof b.update === "function") {
b.update();
}
// Remove if off screen
if (b && typeof b.x === "number" && typeof b.y === "number" && (b.x < 0 || b.x > 2048 || b.y < 0 || b.y > 2732)) {
b.destroy();
policeBullets.splice(i, 1);
continue;
}
// Check hit player
var px = player.inCar ? player.inCar.x : player.x;
var py = player.inCar ? player.inCar.y : player.y;
if (Math.abs(px - b.x) < 60 && Math.abs(py - b.y) < 60) {
// Police bullet hits player: decrease health if not in car
if (!player.inCar && playerHealth > 0) {
playerHealth--;
updateHealthDisplay();
// Optional: flash screen on hit
LK.effects.flashScreen(0xff0000, 200);
// Game over if health reaches 0
if (playerHealth <= 0) {
LK.showGameOver();
return;
}
}
// If player is in car, do not take damage
b.destroy();
policeBullets.splice(i, 1);
}
}
// Player update
player.update();
// Civilians update and check for being shot by player or run over by car
for (var i = civilians.length - 1; i >= 0; i--) {
var civ = civilians[i];
civ.update();
var killed = false;
// Check if hit by any player bullet
for (var j = bullets.length - 1; j >= 0; j--) {
var b = bullets[j];
if (Math.abs(civ.x - b.x) < 60 && Math.abs(civ.y - b.y) < 60) {
killed = true;
// Remove bullet
b.destroy();
bullets.splice(j, 1);
break;
}
}
// Check if run over by any car driven by player
if (!killed) {
for (var c = 0; c < cars.length; c++) {
var car = cars[c];
if (car.driver === player) {
// Use a slightly larger hitbox for car
if (Math.abs(civ.x - car.x) < 90 && Math.abs(civ.y - car.y) < 70) {
killed = true;
break;
}
}
}
}
if (killed) {
// Civilian killed
// Drop money at civilian's position
spawnMoney(civ.x, civ.y);
// Respawn civilian at random road block (fixed world)
var roadBlocks = [];
for (var k = 0; k < cityBlocks.length; k++) {
if (cityBlocks[k].type === 'road') {
var b = cityBlocks[k];
var distToPlayer = Math.sqrt(Math.pow(b.x - player.x, 2) + Math.pow(b.y - player.y, 2));
if (distToPlayer > 400) roadBlocks.push(b);
}
}
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
var newCiv = new Civilian();
newCiv.x = roadBlocks[idx].x + (Math.random() - 0.5) * 100;
newCiv.y = roadBlocks[idx].y + (Math.random() - 0.5) * 100;
civilians.push(newCiv);
game.addChild(newCiv);
}
civ.destroy();
civilians.splice(i, 1);
addScore(10);
// Increase wanted level by 1 every time player kills an NPC, max 5
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
// Only aggro police if wantedLevel is 5
if (wantedLevel === 5) {
for (var p = 0; p < policeShooters.length; p++) {
policeShooters[p].wasShotAt = true;
policeShooters[p].target = player;
}
for (var p = 0; p < policeCars.length; p++) {
policeCars[p].target = player;
}
policeAggro = true;
}
// No break here: allow this to happen every time an NPC is killed
continue;
}
// --- Police run over by car logic ---
// Player can run over police shooters and police cars when driving a car
for (var c = 0; c < cars.length; c++) {
var car = cars[c];
if (car.driver === player) {
// Run over police shooters
for (var s = policeShooters.length - 1; s >= 0; s--) {
var shooter = policeShooters[s];
if (Math.abs(shooter.x - car.x) < 90 && Math.abs(shooter.y - car.y) < 70) {
// Police shooter killed by car
// Drop a gun at police shooter's position
var gunDrop = new Container();
gunDrop.asset = gunDrop.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
gunDrop.gunLabel = new Text2('gun', {
size: 38,
fill: 0xFFFFFF
});
gunDrop.gunLabel.anchor.set(0.5, 1);
gunDrop.gunLabel.y = -30;
gunDrop.addChild(gunDrop.gunLabel);
gunDrop.x = shooter.x;
gunDrop.y = shooter.y;
gunDrop.isGunPickup = true;
game.addChild(gunDrop);
if (typeof gunPickups === "undefined") gunPickups = [];
gunPickups.push(gunDrop);
shooter.destroy();
policeShooters.splice(s, 1);
// Spawn TWO new police shooters at random road blocks, not near player
for (var spawnCount = 0; spawnCount < 2; spawnCount++) {
var roadBlocks = [];
for (var k = 0; k < cityBlocks.length; k++) {
var b2 = cityBlocks[k];
if (b2.type === 'road') {
var distToPlayer = Math.sqrt(Math.pow(b2.x - player.x, 2) + Math.pow(b2.y - player.y, 2));
if (distToPlayer > 600) {
roadBlocks.push(b2);
}
}
}
if (roadBlocks.length > 0) {
var idx2 = Math.floor(Math.random() * roadBlocks.length);
var newShooter = new PoliceShooter();
newShooter.x = roadBlocks[idx2].x + (Math.random() - 0.5) * 100;
newShooter.y = roadBlocks[idx2].y + (Math.random() - 0.5) * 100;
if (policeAggro) {
newShooter.target = player;
newShooter.wasShotAt = true;
} else {
newShooter.target = null;
newShooter.wasShotAt = false;
}
policeShooters.push(newShooter);
game.addChild(newShooter);
}
}
addScore(15);
// Increase wanted level by 1 (max 5) when police shooter is killed
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
// Only aggro police if wantedLevel is 5
if (wantedLevel === 5) {
for (var p = 0; p < policeShooters.length; p++) {
policeShooters[p].wasShotAt = true;
policeShooters[p].target = player;
}
for (var p = 0; p < policeCars.length; p++) {
policeCars[p].target = player;
}
policeAggro = true;
}
// Only allow one run over per car per frame
break;
}
}
// Run over police cars
for (var pc = policeCars.length - 1; pc >= 0; pc--) {
var police = policeCars[pc];
if (Math.abs(police.x - car.x) < 90 && Math.abs(police.y - car.y) < 70) {
// Police car killed by car
// Drop a gun at police car's position
var gunDrop = new Container();
gunDrop.asset = gunDrop.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
gunDrop.gunLabel = new Text2('gun', {
size: 38,
fill: 0xFFFFFF
});
gunDrop.gunLabel.anchor.set(0.5, 1);
gunDrop.gunLabel.y = -30;
gunDrop.addChild(gunDrop.gunLabel);
gunDrop.x = police.x;
gunDrop.y = police.y;
gunDrop.isGunPickup = true;
game.addChild(gunDrop);
if (typeof gunPickups === "undefined") gunPickups = [];
gunPickups.push(gunDrop);
police.destroy();
policeCars.splice(pc, 1);
addScore(20);
// Increase wanted level by 1 (max 5) when police car is killed
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
// Only aggro police if wantedLevel is 5
if (wantedLevel === 5 && typeof spawned5StarPolice === "undefined") {
for (var p = 0; p < policeShooters.length; p++) {
policeShooters[p].wasShotAt = true;
policeShooters[p].target = player;
}
for (var p = 0; p < policeCars.length; p++) {
policeCars[p].target = player;
}
policeAggro = true;
// Spawn 5 police cars at random road blocks (not near player)
var roadBlocks = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') {
var distToPlayer = Math.sqrt(Math.pow(cityBlocks[i].x - player.x, 2) + Math.pow(cityBlocks[i].y - player.y, 2));
if (distToPlayer > 400) {
roadBlocks.push(cityBlocks[i]);
}
}
}
for (var s = 0; s < 5; s++) {
if (roadBlocks.length > 0) {
var idx = Math.floor(Math.random() * roadBlocks.length);
var b = roadBlocks[idx];
var newPolice = spawnPolice(b.x, b.y);
newPolice.target = player;
// Remove this block from roadBlocks to avoid double-spawn at same spot
roadBlocks.splice(idx, 1);
}
}
spawned5StarPolice = true;
}
// Only allow one run over per car per frame
break;
}
}
}
}
}
// Money pickup check
var px = player.inCar ? player.inCar.x : player.x;
var py = player.inCar ? player.inCar.y : player.y;
for (var i = moneyPickups.length - 1; i >= 0; i--) {
var m = moneyPickups[i];
if (Math.abs(m.x - px) < 60 && Math.abs(m.y - py) < 60) {
playerMoney += m.value;
updateMoneyDisplay();
m.destroy();
moneyPickups.splice(i, 1);
// Show "+50 money" text for 1 second at center-top of screen
if (typeof moneyPickupText !== "undefined" && moneyPickupText.parent) {
moneyPickupText.parent.removeChild(moneyPickupText);
moneyPickupText = undefined;
}
moneyPickupText = new Text2("+50 money", {
size: 120,
fill: 0x44FF44
});
moneyPickupText.anchor.set(0.5, 0);
moneyPickupText.x = 2048 / 2;
moneyPickupText.y = 320;
LK.gui.addChild(moneyPickupText);
LK.setTimeout(function () {
if (moneyPickupText && moneyPickupText.parent) {
moneyPickupText.parent.removeChild(moneyPickupText);
moneyPickupText = undefined;
}
}, 1000);
}
}
// Gun pickup check
if (typeof gunPickups === "undefined") gunPickups = [];
for (var i = gunPickups.length - 1; i >= 0; i--) {
var g = gunPickups[i];
if (Math.abs(g.x - px) < 60 && Math.abs(g.y - py) < 60) {
// Player picks up gun (could add ammo, powerup, etc. For now, just remove the gun)
g.destroy();
gunPickups.splice(i, 1);
// Show "+1 gun" text for 1 second at center-top of screen
if (typeof gunPickupText !== "undefined" && gunPickupText.parent) {
gunPickupText.parent.removeChild(gunPickupText);
gunPickupText = undefined;
}
gunPickupText = new Text2("+1 gun", {
size: 120,
fill: 0xFFF700
});
gunPickupText.anchor.set(0.5, 0);
// Place at top center, but not in top left 100x100
gunPickupText.x = 2048 / 2;
gunPickupText.y = 180;
LK.gui.addChild(gunPickupText);
// Remove after 1 second
LK.setTimeout(function () {
if (gunPickupText && gunPickupText.parent) {
gunPickupText.parent.removeChild(gunPickupText);
gunPickupText = undefined;
}
}, 1000);
// Optionally: add logic for ammo, weapon upgrade, etc.
}
}
// Mission check
if (mission.active) {
var px = player.inCar ? player.inCar.x : player.x;
var py = player.inCar ? player.inCar.y : player.y;
if (Math.abs(mission.x - px) < 80 && Math.abs(mission.y - py) < 80) {
// Complete mission
addScore(10 * wantedLevel);
mission.active = false;
mission.visible = false;
// Increase wanted level, spawn more police
wantedLevel = Math.min(5, wantedLevel + 1);
updateWantedDisplay();
if (wantedLevel > policeCars.length) {
// Spawn new police at random road
var roadBlocks = [];
for (var i = 0; i < cityBlocks.length; i++) {
if (cityBlocks[i].type === 'road') roadBlocks.push(cityBlocks[i]);
}
var idx = Math.floor(Math.random() * roadBlocks.length);
var b = roadBlocks[idx];
spawnPolice(b.x, b.y);
}
// Next mission after short delay
LK.setTimeout(function () {
resetMission();
}, 1200);
}
}
// Win condition removed: game never ends when score >= 100
};
// --- Start State ---
addScore(0);
updateWantedDisplay();
timerTxt.setText(timeLeft + '');
resetMission();
playerHealth = 5;
updateHealthDisplay();
playerMoney = 0;
updateMoneyDisplay();
policeAggro = false;
var policeHitCount = 0;
;
; ===================================================================
--- original.js
+++ change.js
@@ -337,15 +337,15 @@
/****
* Game Code
****/
-// --- Fixed City Map Setup ---
-// City block (road) - gray box
-// Building - blue box
-// Player (hero) - red ellipse
-// Car - yellow box
-// Police car - white box with blue
// Mission marker - green ellipse
+// Police car - white box with blue
+// Car - yellow box
+// Player (hero) - red ellipse
+// Building - blue box
+// City block (road) - gray box
+// --- Fixed City Map Setup ---
var blockSize = 400;
var cityBlocks = [];
var cityBlockMap = {}; // key: "col,row" -> CityBlock
// Fixed grid size
@@ -1219,8 +1219,154 @@
}
// No break here: allow this to happen every time an NPC is killed
continue;
}
+ // --- Police run over by car logic ---
+ // Player can run over police shooters and police cars when driving a car
+ for (var c = 0; c < cars.length; c++) {
+ var car = cars[c];
+ if (car.driver === player) {
+ // Run over police shooters
+ for (var s = policeShooters.length - 1; s >= 0; s--) {
+ var shooter = policeShooters[s];
+ if (Math.abs(shooter.x - car.x) < 90 && Math.abs(shooter.y - car.y) < 70) {
+ // Police shooter killed by car
+ // Drop a gun at police shooter's position
+ var gunDrop = new Container();
+ gunDrop.asset = gunDrop.attachAsset('gun', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ gunDrop.gunLabel = new Text2('gun', {
+ size: 38,
+ fill: 0xFFFFFF
+ });
+ gunDrop.gunLabel.anchor.set(0.5, 1);
+ gunDrop.gunLabel.y = -30;
+ gunDrop.addChild(gunDrop.gunLabel);
+ gunDrop.x = shooter.x;
+ gunDrop.y = shooter.y;
+ gunDrop.isGunPickup = true;
+ game.addChild(gunDrop);
+ if (typeof gunPickups === "undefined") gunPickups = [];
+ gunPickups.push(gunDrop);
+ shooter.destroy();
+ policeShooters.splice(s, 1);
+ // Spawn TWO new police shooters at random road blocks, not near player
+ for (var spawnCount = 0; spawnCount < 2; spawnCount++) {
+ var roadBlocks = [];
+ for (var k = 0; k < cityBlocks.length; k++) {
+ var b2 = cityBlocks[k];
+ if (b2.type === 'road') {
+ var distToPlayer = Math.sqrt(Math.pow(b2.x - player.x, 2) + Math.pow(b2.y - player.y, 2));
+ if (distToPlayer > 600) {
+ roadBlocks.push(b2);
+ }
+ }
+ }
+ if (roadBlocks.length > 0) {
+ var idx2 = Math.floor(Math.random() * roadBlocks.length);
+ var newShooter = new PoliceShooter();
+ newShooter.x = roadBlocks[idx2].x + (Math.random() - 0.5) * 100;
+ newShooter.y = roadBlocks[idx2].y + (Math.random() - 0.5) * 100;
+ if (policeAggro) {
+ newShooter.target = player;
+ newShooter.wasShotAt = true;
+ } else {
+ newShooter.target = null;
+ newShooter.wasShotAt = false;
+ }
+ policeShooters.push(newShooter);
+ game.addChild(newShooter);
+ }
+ }
+ addScore(15);
+ // Increase wanted level by 1 (max 5) when police shooter is killed
+ wantedLevel = Math.min(5, wantedLevel + 1);
+ updateWantedDisplay();
+ // Only aggro police if wantedLevel is 5
+ if (wantedLevel === 5) {
+ for (var p = 0; p < policeShooters.length; p++) {
+ policeShooters[p].wasShotAt = true;
+ policeShooters[p].target = player;
+ }
+ for (var p = 0; p < policeCars.length; p++) {
+ policeCars[p].target = player;
+ }
+ policeAggro = true;
+ }
+ // Only allow one run over per car per frame
+ break;
+ }
+ }
+ // Run over police cars
+ for (var pc = policeCars.length - 1; pc >= 0; pc--) {
+ var police = policeCars[pc];
+ if (Math.abs(police.x - car.x) < 90 && Math.abs(police.y - car.y) < 70) {
+ // Police car killed by car
+ // Drop a gun at police car's position
+ var gunDrop = new Container();
+ gunDrop.asset = gunDrop.attachAsset('gun', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ gunDrop.gunLabel = new Text2('gun', {
+ size: 38,
+ fill: 0xFFFFFF
+ });
+ gunDrop.gunLabel.anchor.set(0.5, 1);
+ gunDrop.gunLabel.y = -30;
+ gunDrop.addChild(gunDrop.gunLabel);
+ gunDrop.x = police.x;
+ gunDrop.y = police.y;
+ gunDrop.isGunPickup = true;
+ game.addChild(gunDrop);
+ if (typeof gunPickups === "undefined") gunPickups = [];
+ gunPickups.push(gunDrop);
+ police.destroy();
+ policeCars.splice(pc, 1);
+ addScore(20);
+ // Increase wanted level by 1 (max 5) when police car is killed
+ wantedLevel = Math.min(5, wantedLevel + 1);
+ updateWantedDisplay();
+ // Only aggro police if wantedLevel is 5
+ if (wantedLevel === 5 && typeof spawned5StarPolice === "undefined") {
+ for (var p = 0; p < policeShooters.length; p++) {
+ policeShooters[p].wasShotAt = true;
+ policeShooters[p].target = player;
+ }
+ for (var p = 0; p < policeCars.length; p++) {
+ policeCars[p].target = player;
+ }
+ policeAggro = true;
+ // Spawn 5 police cars at random road blocks (not near player)
+ var roadBlocks = [];
+ for (var i = 0; i < cityBlocks.length; i++) {
+ if (cityBlocks[i].type === 'road') {
+ var distToPlayer = Math.sqrt(Math.pow(cityBlocks[i].x - player.x, 2) + Math.pow(cityBlocks[i].y - player.y, 2));
+ if (distToPlayer > 400) {
+ roadBlocks.push(cityBlocks[i]);
+ }
+ }
+ }
+ for (var s = 0; s < 5; s++) {
+ if (roadBlocks.length > 0) {
+ var idx = Math.floor(Math.random() * roadBlocks.length);
+ var b = roadBlocks[idx];
+ var newPolice = spawnPolice(b.x, b.y);
+ newPolice.target = player;
+ // Remove this block from roadBlocks to avoid double-spawn at same spot
+ roadBlocks.splice(idx, 1);
+ }
+ }
+ spawned5StarPolice = true;
+ }
+ // Only allow one run over per car per frame
+ break;
+ }
+ }
+ }
+ }
}
// Money pickup check
var px = player.inCar ? player.inCar.x : player.x;
var py = player.inCar ? player.inCar.y : player.y;