/**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletSprite = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.update = function () { self.y += self.speed; }; return self; }); // Cash class var Cash = Container.expand(function () { var self = Container.call(this); var cashSprite = self.attachAsset('cash', { anchorX: 0.5, anchorY: 0.5 }); self.radius = cashSprite.width * 0.5; self.speed = 7; self.update = function () { self.y += self.speed; }; return self; }); var Joystick = Container.expand(function () { var self = Container.call(this); var base = self.attachAsset('joystick_base', { anchorX: 0.5, anchorY: 0.5 }); var handle = self.attachAsset('joystick_handle', { anchorX: 0.5, anchorY: 0.5 }); var startX = 0; var startY = 0; var isDragging = false; var maxDist = base.width * 0.3; // Max distance handle can move self.on('down', function (x, y) { isDragging = true; var pos = self.toLocal({ x: x, y: y }); startX = pos.x; startY = pos.y; }); self.on('move', function (x, y) { if (isDragging) { var pos = self.toLocal({ x: x, y: y }); var dx = pos.x - startX; var dy = pos.y - startY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > maxDist) { dx = dx / dist * maxDist; dy = dy / dist * maxDist; } handle.x = startX + dx; handle.y = startY + dy; self.directionX = dx / maxDist; self.directionY = dy / maxDist; } }); self.on('up', function () { isDragging = false; handle.x = startX; handle.y = startY; self.directionX = 0; self.directionY = 0; }); self.directionX = 0; self.directionY = 0; return self; }); // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); var obsSprite = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.radius = obsSprite.width * 0.5; self.speed = 7 + Math.random() * 3; self.direction = Math.random() < 0.5 ? 1 : -1; self.update = function () { // Move vertically down, with a little horizontal drift self.y += self.speed; self.x += self.direction * 2; }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerSprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.radius = playerSprite.width * 0.5; self.speed = 0; // Not used, but can be for future upgrades // For future: self.invincible = false; return self; }); // Police car class var Police = Container.expand(function () { var self = Container.call(this); var policeSprite = self.attachAsset('police', { anchorX: 0.5, anchorY: 0.5 }); self.radius = policeSprite.width * 0.5; self.speed = 2 + Math.random() * 1.5; // Much slower base speed for police self.update = function () { // Move towards player var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } }; return self; }); // Powerup class var Powerup = Container.expand(function () { var self = Container.call(this); var powerSprite = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.radius = powerSprite.width * 0.5; self.speed = 7; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Power-up: yellow ellipse // Cash: green ellipse // Obstacle: gray box // Police car: blue box // Player character: red box // Game area var GAME_W = 2048; var GAME_H = 2732; // Player instance var player = new Player(); game.addChild(player); player.x = GAME_W / 2; player.y = GAME_H - 400; // Arrays for game objects var policeCars = []; var cashItems = []; var powerups = []; var bullets = []; // Array to hold bullets // Score and wanted level var score = 0; var wantedLevel = 1; var timeSurvived = 0; // in ticks // GUI: Score var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // GUI: Wanted Level var wantedTxt = new Text2('Wanted: 1', { size: 80, fill: 0xFF4444 }); wantedTxt.anchor.set(0.5, 0); LK.gui.top.addChild(wantedTxt); wantedTxt.y = 130; // GUI: Cash var cashTxt = new Text2('$0', { size: 80, fill: 0x2ECC40 }); cashTxt.anchor.set(0.5, 0); LK.gui.top.addChild(cashTxt); cashTxt.y = 220; // Combo text (hidden by default) var comboTxt = new Text2('COMBO', { size: 200, fill: 0xffe066, font: "Impact" }); comboTxt.anchor.set(0.5, 0.5); comboTxt.visible = false; LK.gui.center.addChild(comboTxt); var comboTimer = 0; var comboShown = false; // Dragging var dragNode = null; // Powerup state var powerupActive = false; var powerupTimer = 0; // Helper: Clamp function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } ; // Joystick var joystick = new Joystick(); LK.gui.bottomLeft.addChild(joystick); joystick.x = 200; joystick.y = -600; // Move joystick further up from bottom // --- All-direction shoot button --- var shootBtn = new Text2('ATEŞ ET', { size: 90, fill: 0xffffff, font: "Impact" }); shootBtn.anchor.set(0.5, 0.5); shootBtn.x = 400; shootBtn.y = -400; shootBtn.bg = 0x222222; shootBtn.alpha = 0.85; shootBtn.interactive = true; shootBtn.buttonMode = true; LK.gui.bottomRight.addChild(shootBtn); var allDirectionShootActive = false; var allDirectionShootTimer = 0; // --- Custom button (TUŞ) --- var tusBtn = new Text2('TUŞ', { size: 90, fill: 0x00bfff, font: "Impact" }); tusBtn.anchor.set(0.5, 0.5); tusBtn.x = 400; tusBtn.y = -100; tusBtn.bg = 0x222222; tusBtn.alpha = 0.85; tusBtn.interactive = true; tusBtn.buttonMode = true; LK.gui.bottomRight.addChild(tusBtn); // You can add an event handler for tusBtn if needed, e.g.: // tusBtn.on('down', function () { /* action */ }); // --- Police kill button --- var killPoliceBtn = new Text2('POLİSLERİ YOK ET', { size: 90, fill: 0xff4444, font: "Impact" }); killPoliceBtn.anchor.set(0.5, 0.5); killPoliceBtn.x = 400; killPoliceBtn.y = -250; killPoliceBtn.bg = 0x222222; killPoliceBtn.alpha = 0.85; killPoliceBtn.interactive = true; killPoliceBtn.buttonMode = true; LK.gui.bottomRight.addChild(killPoliceBtn); // Button event: activate all-direction shooting for 2 seconds shootBtn.on('down', function () { if (!allDirectionShootActive) { allDirectionShootActive = true; allDirectionShootTimer = 120; // 2 seconds at 60fps LK.effects.flashObject(player, 0xffe066, 400); } }); // Button event: make all bullets destroy all police cars killPoliceBtn.on('down', function () { // For each bullet, destroy all police cars for (var b = 0; b < bullets.length; b++) { for (var i = policeCars.length - 1; i >= 0; i--) { policeCars[i].destroy(); policeCars.splice(i, 1); } } LK.effects.flashScreen(0xff4444, 400); }); // Spawning logic // Spawning logic var policeSpawnTimer = 0; var obstacleSpawnTimer = 0; var cashSpawnTimer = 0; var powerupSpawnTimer = 0; var shootTimer = 0; // Timer for player shooting // Main update loop game.update = function () { // Move player with joystick player.x += joystick.directionX * 20; // Adjust multiplier for speed player.y += joystick.directionY * 20; // Adjust multiplier for speed // Clamp player to game area player.x = clamp(player.x, 80, GAME_W - 80); player.y = clamp(player.y, 80, GAME_H - 80); // Increase time survived timeSurvived++; if (timeSurvived % 60 === 0) { score++; scoreTxt.setText(score + ''); } // Increase wanted level every 20 seconds if (timeSurvived % (60 * 20) === 0 && wantedLevel < 5) { wantedLevel++; wantedTxt.setText('Wanted: ' + wantedLevel); } // Spawn police cars policeSpawnTimer--; var policeLimit = Math.min(1 + wantedLevel, 6); if (policeCars.length < policeLimit && policeSpawnTimer <= 0) { var p = new Police(); // Spawn at random edge var edge = Math.floor(Math.random() * 4); if (edge === 0) { // Top p.x = Math.random() * (GAME_W - 200) + 100; p.y = -100; } else if (edge === 1) { // Bottom p.x = Math.random() * (GAME_W - 200) + 100; p.y = GAME_H + 100; } else if (edge === 2) { // Left p.x = -100; p.y = Math.random() * (GAME_H - 800) + 400; } else { // Right p.x = GAME_W + 100; p.y = Math.random() * (GAME_H - 800) + 400; } // Increase speed with wanted level (much slower scaling) p.speed = 2 + wantedLevel * 0.7 + Math.random() * 1.5; policeCars.push(p); game.addChild(p); policeSpawnTimer = 90 - wantedLevel * 10 + Math.floor(Math.random() * 30); } cashSpawnTimer--; if (cashItems.length < 2 && cashSpawnTimer <= 0) { var c = new Cash(); c.x = Math.random() * (GAME_W - 200) + 100; c.y = -100; cashItems.push(c); game.addChild(c); cashSpawnTimer = 180 + Math.floor(Math.random() * 120); } // Spawn powerup powerupSpawnTimer--; if (!powerupActive && powerups.length < 1 && powerupSpawnTimer <= 0) { var pu = new Powerup(); pu.x = Math.random() * (GAME_W - 200) + 100; pu.y = -100; powerups.push(pu); game.addChild(pu); powerupSpawnTimer = 900 + Math.floor(Math.random() * 600); } // Update police cars for (var i = policeCars.length - 1; i >= 0; i--) { var p = policeCars[i]; p.update(); // Remove if off screen if (p.x < -200 || p.x > GAME_W + 200 || p.y < -200 || p.y > GAME_H + 200) { p.destroy(); policeCars.splice(i, 1); continue; } // Collision with player if (!powerupActive && p.intersects(player)) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } ; // Player shooting shootTimer--; // All-direction shooting logic if (allDirectionShootActive) { allDirectionShootTimer--; // Fire bullets in all directions every 6 ticks (10 times per second) if (allDirectionShootTimer % 6 === 0) { for (var i = 0; i < 8; i++) { var angle = Math.PI * 2 / 8 * i; var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; // Give bullet a direction bullet.vx = Math.cos(angle) * 18; bullet.vy = Math.sin(angle) * 18; // Override update for this bullet bullet.update = function (b) { return function () { b.x += b.vx; b.y += b.vy; }; }(bullet); bullets.push(bullet); game.addChild(bullet); } } if (allDirectionShootTimer <= 0) { allDirectionShootActive = false; } } // Normal shooting (upwards) if not in all-direction mode if (!allDirectionShootActive && joystick.directionY < -0.5 && shootTimer <= 0) { // Shoot when pushing joystick up var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; bullets.push(bullet); game.addChild(bullet); shootTimer = 20; // Shoot every 20 ticks (approx 3 times per second) } // Update bullets for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; bullet.update(); // Remove if off screen if (bullet.y < -100) { bullet.destroy(); bullets.splice(b, 1); continue; } // Collision with police cars for (var i = policeCars.length - 1; i >= 0; i--) { var p = policeCars[i]; if (bullet.intersects(p)) { p.destroy(); policeCars.splice(i, 1); bullet.destroy(); bullets.splice(b, 1); score += 50; // Score for hitting police cashTxt.setText('$' + score); // Don't break inner loop, continue checking other police cars break; } } } } ; // Update cash for (var k = cashItems.length - 1; k >= 0; k--) { var c = cashItems[k]; c.update(); if (c.y > GAME_H + 100) { c.destroy(); cashItems.splice(k, 1); continue; } // Collect cash if (c.intersects(player)) { score += 10; scoreTxt.setText(score + ''); cashTxt.setText('$' + score); c.destroy(); cashItems.splice(k, 1); continue; } } // Show combo text if score reaches 300 (only once) if (!comboShown && score >= 300) { comboTxt.visible = true; comboTimer = 120; // 2 seconds at 60fps comboShown = true; } if (comboTimer > 0) { comboTimer--; if (comboTimer === 0) { comboTxt.visible = false; } } // Update powerups for (var m = powerups.length - 1; m >= 0; m--) { var pu = powerups[m]; pu.update(); if (pu.y > GAME_H + 100) { pu.destroy(); powerups.splice(m, 1); continue; } // Collect powerup if (pu.intersects(player)) { powerupActive = true; powerupTimer = 360; // 6 seconds // Flash player yellow LK.effects.flashObject(player, 0xffe066, 600); pu.destroy(); powerups.splice(m, 1); continue; } } // Powerup timer if (powerupActive) { powerupTimer--; if (powerupTimer <= 0) { powerupActive = false; } } };
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Cash class
var Cash = Container.expand(function () {
var self = Container.call(this);
var cashSprite = self.attachAsset('cash', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = cashSprite.width * 0.5;
self.speed = 7;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Joystick = Container.expand(function () {
var self = Container.call(this);
var base = self.attachAsset('joystick_base', {
anchorX: 0.5,
anchorY: 0.5
});
var handle = self.attachAsset('joystick_handle', {
anchorX: 0.5,
anchorY: 0.5
});
var startX = 0;
var startY = 0;
var isDragging = false;
var maxDist = base.width * 0.3; // Max distance handle can move
self.on('down', function (x, y) {
isDragging = true;
var pos = self.toLocal({
x: x,
y: y
});
startX = pos.x;
startY = pos.y;
});
self.on('move', function (x, y) {
if (isDragging) {
var pos = self.toLocal({
x: x,
y: y
});
var dx = pos.x - startX;
var dy = pos.y - startY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > maxDist) {
dx = dx / dist * maxDist;
dy = dy / dist * maxDist;
}
handle.x = startX + dx;
handle.y = startY + dy;
self.directionX = dx / maxDist;
self.directionY = dy / maxDist;
}
});
self.on('up', function () {
isDragging = false;
handle.x = startX;
handle.y = startY;
self.directionX = 0;
self.directionY = 0;
});
self.directionX = 0;
self.directionY = 0;
return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obsSprite = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = obsSprite.width * 0.5;
self.speed = 7 + Math.random() * 3;
self.direction = Math.random() < 0.5 ? 1 : -1;
self.update = function () {
// Move vertically down, with a little horizontal drift
self.y += self.speed;
self.x += self.direction * 2;
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = playerSprite.width * 0.5;
self.speed = 0; // Not used, but can be for future upgrades
// For future: self.invincible = false;
return self;
});
// Police car class
var Police = Container.expand(function () {
var self = Container.call(this);
var policeSprite = self.attachAsset('police', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = policeSprite.width * 0.5;
self.speed = 2 + Math.random() * 1.5; // Much slower base speed for police
self.update = function () {
// Move towards player
var dx = player.x - self.x;
var dy = player.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
};
return self;
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerSprite = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = powerSprite.width * 0.5;
self.speed = 7;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Power-up: yellow ellipse
// Cash: green ellipse
// Obstacle: gray box
// Police car: blue box
// Player character: red box
// Game area
var GAME_W = 2048;
var GAME_H = 2732;
// Player instance
var player = new Player();
game.addChild(player);
player.x = GAME_W / 2;
player.y = GAME_H - 400;
// Arrays for game objects
var policeCars = [];
var cashItems = [];
var powerups = [];
var bullets = []; // Array to hold bullets
// Score and wanted level
var score = 0;
var wantedLevel = 1;
var timeSurvived = 0; // in ticks
// GUI: Score
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// GUI: Wanted Level
var wantedTxt = new Text2('Wanted: 1', {
size: 80,
fill: 0xFF4444
});
wantedTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(wantedTxt);
wantedTxt.y = 130;
// GUI: Cash
var cashTxt = new Text2('$0', {
size: 80,
fill: 0x2ECC40
});
cashTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(cashTxt);
cashTxt.y = 220;
// Combo text (hidden by default)
var comboTxt = new Text2('COMBO', {
size: 200,
fill: 0xffe066,
font: "Impact"
});
comboTxt.anchor.set(0.5, 0.5);
comboTxt.visible = false;
LK.gui.center.addChild(comboTxt);
var comboTimer = 0;
var comboShown = false;
// Dragging
var dragNode = null;
// Powerup state
var powerupActive = false;
var powerupTimer = 0;
// Helper: Clamp
function clamp(val, min, max) {
return Math.max(min, Math.min(max, val));
}
;
// Joystick
var joystick = new Joystick();
LK.gui.bottomLeft.addChild(joystick);
joystick.x = 200;
joystick.y = -600; // Move joystick further up from bottom
// --- All-direction shoot button ---
var shootBtn = new Text2('ATEŞ ET', {
size: 90,
fill: 0xffffff,
font: "Impact"
});
shootBtn.anchor.set(0.5, 0.5);
shootBtn.x = 400;
shootBtn.y = -400;
shootBtn.bg = 0x222222;
shootBtn.alpha = 0.85;
shootBtn.interactive = true;
shootBtn.buttonMode = true;
LK.gui.bottomRight.addChild(shootBtn);
var allDirectionShootActive = false;
var allDirectionShootTimer = 0;
// --- Custom button (TUŞ) ---
var tusBtn = new Text2('TUŞ', {
size: 90,
fill: 0x00bfff,
font: "Impact"
});
tusBtn.anchor.set(0.5, 0.5);
tusBtn.x = 400;
tusBtn.y = -100;
tusBtn.bg = 0x222222;
tusBtn.alpha = 0.85;
tusBtn.interactive = true;
tusBtn.buttonMode = true;
LK.gui.bottomRight.addChild(tusBtn);
// You can add an event handler for tusBtn if needed, e.g.:
// tusBtn.on('down', function () { /* action */ });
// --- Police kill button ---
var killPoliceBtn = new Text2('POLİSLERİ YOK ET', {
size: 90,
fill: 0xff4444,
font: "Impact"
});
killPoliceBtn.anchor.set(0.5, 0.5);
killPoliceBtn.x = 400;
killPoliceBtn.y = -250;
killPoliceBtn.bg = 0x222222;
killPoliceBtn.alpha = 0.85;
killPoliceBtn.interactive = true;
killPoliceBtn.buttonMode = true;
LK.gui.bottomRight.addChild(killPoliceBtn);
// Button event: activate all-direction shooting for 2 seconds
shootBtn.on('down', function () {
if (!allDirectionShootActive) {
allDirectionShootActive = true;
allDirectionShootTimer = 120; // 2 seconds at 60fps
LK.effects.flashObject(player, 0xffe066, 400);
}
});
// Button event: make all bullets destroy all police cars
killPoliceBtn.on('down', function () {
// For each bullet, destroy all police cars
for (var b = 0; b < bullets.length; b++) {
for (var i = policeCars.length - 1; i >= 0; i--) {
policeCars[i].destroy();
policeCars.splice(i, 1);
}
}
LK.effects.flashScreen(0xff4444, 400);
});
// Spawning logic
// Spawning logic
var policeSpawnTimer = 0;
var obstacleSpawnTimer = 0;
var cashSpawnTimer = 0;
var powerupSpawnTimer = 0;
var shootTimer = 0; // Timer for player shooting
// Main update loop
game.update = function () {
// Move player with joystick
player.x += joystick.directionX * 20; // Adjust multiplier for speed
player.y += joystick.directionY * 20; // Adjust multiplier for speed
// Clamp player to game area
player.x = clamp(player.x, 80, GAME_W - 80);
player.y = clamp(player.y, 80, GAME_H - 80);
// Increase time survived
timeSurvived++;
if (timeSurvived % 60 === 0) {
score++;
scoreTxt.setText(score + '');
}
// Increase wanted level every 20 seconds
if (timeSurvived % (60 * 20) === 0 && wantedLevel < 5) {
wantedLevel++;
wantedTxt.setText('Wanted: ' + wantedLevel);
}
// Spawn police cars
policeSpawnTimer--;
var policeLimit = Math.min(1 + wantedLevel, 6);
if (policeCars.length < policeLimit && policeSpawnTimer <= 0) {
var p = new Police();
// Spawn at random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
p.x = Math.random() * (GAME_W - 200) + 100;
p.y = -100;
} else if (edge === 1) {
// Bottom
p.x = Math.random() * (GAME_W - 200) + 100;
p.y = GAME_H + 100;
} else if (edge === 2) {
// Left
p.x = -100;
p.y = Math.random() * (GAME_H - 800) + 400;
} else {
// Right
p.x = GAME_W + 100;
p.y = Math.random() * (GAME_H - 800) + 400;
}
// Increase speed with wanted level (much slower scaling)
p.speed = 2 + wantedLevel * 0.7 + Math.random() * 1.5;
policeCars.push(p);
game.addChild(p);
policeSpawnTimer = 90 - wantedLevel * 10 + Math.floor(Math.random() * 30);
}
cashSpawnTimer--;
if (cashItems.length < 2 && cashSpawnTimer <= 0) {
var c = new Cash();
c.x = Math.random() * (GAME_W - 200) + 100;
c.y = -100;
cashItems.push(c);
game.addChild(c);
cashSpawnTimer = 180 + Math.floor(Math.random() * 120);
}
// Spawn powerup
powerupSpawnTimer--;
if (!powerupActive && powerups.length < 1 && powerupSpawnTimer <= 0) {
var pu = new Powerup();
pu.x = Math.random() * (GAME_W - 200) + 100;
pu.y = -100;
powerups.push(pu);
game.addChild(pu);
powerupSpawnTimer = 900 + Math.floor(Math.random() * 600);
}
// Update police cars
for (var i = policeCars.length - 1; i >= 0; i--) {
var p = policeCars[i];
p.update();
// Remove if off screen
if (p.x < -200 || p.x > GAME_W + 200 || p.y < -200 || p.y > GAME_H + 200) {
p.destroy();
policeCars.splice(i, 1);
continue;
}
// Collision with player
if (!powerupActive && p.intersects(player)) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
;
// Player shooting
shootTimer--;
// All-direction shooting logic
if (allDirectionShootActive) {
allDirectionShootTimer--;
// Fire bullets in all directions every 6 ticks (10 times per second)
if (allDirectionShootTimer % 6 === 0) {
for (var i = 0; i < 8; i++) {
var angle = Math.PI * 2 / 8 * i;
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
// Give bullet a direction
bullet.vx = Math.cos(angle) * 18;
bullet.vy = Math.sin(angle) * 18;
// Override update for this bullet
bullet.update = function (b) {
return function () {
b.x += b.vx;
b.y += b.vy;
};
}(bullet);
bullets.push(bullet);
game.addChild(bullet);
}
}
if (allDirectionShootTimer <= 0) {
allDirectionShootActive = false;
}
}
// Normal shooting (upwards) if not in all-direction mode
if (!allDirectionShootActive && joystick.directionY < -0.5 && shootTimer <= 0) {
// Shoot when pushing joystick up
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
bullets.push(bullet);
game.addChild(bullet);
shootTimer = 20; // Shoot every 20 ticks (approx 3 times per second)
}
// Update bullets
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
bullet.update();
// Remove if off screen
if (bullet.y < -100) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
// Collision with police cars
for (var i = policeCars.length - 1; i >= 0; i--) {
var p = policeCars[i];
if (bullet.intersects(p)) {
p.destroy();
policeCars.splice(i, 1);
bullet.destroy();
bullets.splice(b, 1);
score += 50; // Score for hitting police
cashTxt.setText('$' + score);
// Don't break inner loop, continue checking other police cars
break;
}
}
}
}
;
// Update cash
for (var k = cashItems.length - 1; k >= 0; k--) {
var c = cashItems[k];
c.update();
if (c.y > GAME_H + 100) {
c.destroy();
cashItems.splice(k, 1);
continue;
}
// Collect cash
if (c.intersects(player)) {
score += 10;
scoreTxt.setText(score + '');
cashTxt.setText('$' + score);
c.destroy();
cashItems.splice(k, 1);
continue;
}
}
// Show combo text if score reaches 300 (only once)
if (!comboShown && score >= 300) {
comboTxt.visible = true;
comboTimer = 120; // 2 seconds at 60fps
comboShown = true;
}
if (comboTimer > 0) {
comboTimer--;
if (comboTimer === 0) {
comboTxt.visible = false;
}
}
// Update powerups
for (var m = powerups.length - 1; m >= 0; m--) {
var pu = powerups[m];
pu.update();
if (pu.y > GAME_H + 100) {
pu.destroy();
powerups.splice(m, 1);
continue;
}
// Collect powerup
if (pu.intersects(player)) {
powerupActive = true;
powerupTimer = 360; // 6 seconds
// Flash player yellow
LK.effects.flashObject(player, 0xffe066, 600);
pu.destroy();
powerups.splice(m, 1);
continue;
}
}
// Powerup timer
if (powerupActive) {
powerupTimer--;
if (powerupTimer <= 0) {
powerupActive = false;
}
}
};