/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CivilianCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('civilianCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 3;
self.direction = Math.random() * Math.PI * 2;
self.changeTimer = 0;
self.update = function () {
self.changeTimer++;
// Change direction occasionally
if (self.changeTimer > 120 + Math.random() * 120) {
self.direction += (Math.random() - 0.5) * 0.5;
self.changeTimer = 0;
}
// Move
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Bounce off screen edges
if (self.x < 50 || self.x > 1998) {
self.direction = Math.PI - self.direction;
}
if (self.y < 50 || self.y > 2682) {
self.direction = -self.direction;
}
// Keep on screen
if (self.x < 50) self.x = 50;
if (self.x > 1998) self.x = 1998;
if (self.y < 50) self.y = 50;
if (self.y > 2682) self.y = 2682;
// Update rotation
carGraphics.rotation = self.direction + Math.PI / 2;
};
return self;
});
var MoneyBag = Container.expand(function () {
var self = Container.call(this);
var bagGraphics = self.attachAsset('moneyBag', {
anchorX: 0.5,
anchorY: 0.5
});
self.pulseTimer = 0;
self.update = function () {
self.pulseTimer += 0.1;
bagGraphics.scaleX = 1 + Math.sin(self.pulseTimer) * 0.2;
bagGraphics.scaleY = 1 + Math.sin(self.pulseTimer) * 0.2;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.maxSpeed = 12;
self.velocityX = 0;
self.velocityY = 0;
self.rotation = 0;
self.update = function () {
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= 0.95;
self.velocityY *= 0.95;
// Keep player on screen
if (self.x < 60) self.x = 60;
if (self.x > 1988) self.x = 1988;
if (self.y < 60) self.y = 60;
if (self.y > 2672) self.y = 2672;
// Update rotation based on velocity
if (Math.abs(self.velocityX) > 0.5 || Math.abs(self.velocityY) > 0.5) {
self.rotation = Math.atan2(self.velocityY, self.velocityX) + Math.PI / 2;
carGraphics.rotation = self.rotation;
}
};
return self;
});
var PoliceCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('policeCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
// Chase player
var dx = playerCar.x - self.x;
var dy = playerCar.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.velocityX += dx / distance * 0.3;
self.velocityY += dy / distance * 0.3;
}
// Limit speed
var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (currentSpeed > self.speed) {
self.velocityX = self.velocityX / currentSpeed * self.speed;
self.velocityY = self.velocityY / currentSpeed * self.speed;
}
// Apply movement
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= 0.98;
self.velocityY *= 0.98;
// Update rotation
if (Math.abs(self.velocityX) > 0.5 || Math.abs(self.velocityY) > 0.5) {
carGraphics.rotation = Math.atan2(self.velocityY, self.velocityX) + Math.PI / 2;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game variables
var playerCar;
var policeCars = [];
var civilianCars = [];
var moneyBags = [];
var moneySpawnTimer = 0;
var policeSpawnTimer = 0;
var wantedLevel = 1;
var dragActive = false;
// Create roads
for (var i = 0; i < 7; i++) {
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: i * 300 + 150,
y: 1366
});
game.addChild(road);
}
// Create buildings between roads
for (var j = 0; j < 6; j++) {
for (var k = 0; k < 10; k++) {
var building = LK.getAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
x: j * 300 + 300,
y: k * 300 + 150
});
game.addChild(building);
}
}
// Create player car
playerCar = game.addChild(new PlayerCar());
playerCar.x = 1024;
playerCar.y = 2000;
// Create initial civilian cars
for (var c = 0; c < 8; c++) {
var civilianCar = game.addChild(new CivilianCar());
civilianCar.x = Math.random() * 1900 + 100;
civilianCar.y = Math.random() * 2500 + 100;
civilianCars.push(civilianCar);
}
// Create initial police car
var initialPolice = game.addChild(new PoliceCar());
initialPolice.x = Math.random() * 1900 + 100;
initialPolice.y = Math.random() * 1000 + 100;
policeCars.push(initialPolice);
// Create initial money bags
for (var m = 0; m < 3; m++) {
var moneyBag = game.addChild(new MoneyBag());
moneyBag.x = Math.random() * 1800 + 200;
moneyBag.y = Math.random() * 2400 + 200;
moneyBags.push(moneyBag);
}
// UI
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var wantedTxt = new Text2('Wanted Level: 1', {
size: 60,
fill: 0xFF4444
});
wantedTxt.anchor.set(1, 0);
wantedTxt.x = -20;
wantedTxt.y = 100;
LK.gui.topRight.addChild(wantedTxt);
// Touch controls
game.down = function (x, y, obj) {
dragActive = true;
};
game.move = function (x, y, obj) {
if (dragActive) {
var dx = x - playerCar.x;
var dy = y - playerCar.y;
// Apply acceleration towards touch point
playerCar.velocityX += dx * 0.01;
playerCar.velocityY += dy * 0.01;
// Limit max speed
var currentSpeed = Math.sqrt(playerCar.velocityX * playerCar.velocityX + playerCar.velocityY * playerCar.velocityY);
if (currentSpeed > playerCar.maxSpeed) {
playerCar.velocityX = playerCar.velocityX / currentSpeed * playerCar.maxSpeed;
playerCar.velocityY = playerCar.velocityY / currentSpeed * playerCar.maxSpeed;
}
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Play background music
LK.playMusic('chase');
// Main game loop
game.update = function () {
// Update wanted level based on score
var newWantedLevel = Math.floor(LK.getScore() / 5) + 1;
if (newWantedLevel > wantedLevel && newWantedLevel <= 5) {
wantedLevel = newWantedLevel;
wantedTxt.setText('Wanted Level: ' + wantedLevel);
}
// Spawn money bags
moneySpawnTimer++;
if (moneySpawnTimer > 180) {
if (moneyBags.length < 5) {
var newMoney = game.addChild(new MoneyBag());
newMoney.x = Math.random() * 1800 + 200;
newMoney.y = Math.random() * 2400 + 200;
moneyBags.push(newMoney);
}
moneySpawnTimer = 0;
}
// Spawn police cars based on wanted level
policeSpawnTimer++;
if (policeSpawnTimer > 300 - wantedLevel * 40) {
if (policeCars.length < wantedLevel + 1) {
var newPolice = game.addChild(new PoliceCar());
newPolice.x = Math.random() * 1900 + 100;
newPolice.y = Math.random() * 500 + 100;
newPolice.speed = 6 + wantedLevel * 0.5;
policeCars.push(newPolice);
}
policeSpawnTimer = 0;
}
// Check money collection
for (var i = moneyBags.length - 1; i >= 0; i--) {
var money = moneyBags[i];
if (playerCar.intersects(money)) {
LK.setScore(LK.getScore() + 1);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('collect').play();
money.destroy();
moneyBags.splice(i, 1);
// Win condition
if (LK.getScore() >= 50) {
LK.showYouWin();
}
}
}
// Check police collisions
for (var j = 0; j < policeCars.length; j++) {
var police = policeCars[j];
if (playerCar.intersects(police)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
// Check civilian collisions
for (var k = 0; k < civilianCars.length; k++) {
var civilian = civilianCars[k];
if (playerCar.intersects(civilian)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CivilianCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('civilianCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 3;
self.direction = Math.random() * Math.PI * 2;
self.changeTimer = 0;
self.update = function () {
self.changeTimer++;
// Change direction occasionally
if (self.changeTimer > 120 + Math.random() * 120) {
self.direction += (Math.random() - 0.5) * 0.5;
self.changeTimer = 0;
}
// Move
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Bounce off screen edges
if (self.x < 50 || self.x > 1998) {
self.direction = Math.PI - self.direction;
}
if (self.y < 50 || self.y > 2682) {
self.direction = -self.direction;
}
// Keep on screen
if (self.x < 50) self.x = 50;
if (self.x > 1998) self.x = 1998;
if (self.y < 50) self.y = 50;
if (self.y > 2682) self.y = 2682;
// Update rotation
carGraphics.rotation = self.direction + Math.PI / 2;
};
return self;
});
var MoneyBag = Container.expand(function () {
var self = Container.call(this);
var bagGraphics = self.attachAsset('moneyBag', {
anchorX: 0.5,
anchorY: 0.5
});
self.pulseTimer = 0;
self.update = function () {
self.pulseTimer += 0.1;
bagGraphics.scaleX = 1 + Math.sin(self.pulseTimer) * 0.2;
bagGraphics.scaleY = 1 + Math.sin(self.pulseTimer) * 0.2;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.maxSpeed = 12;
self.velocityX = 0;
self.velocityY = 0;
self.rotation = 0;
self.update = function () {
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= 0.95;
self.velocityY *= 0.95;
// Keep player on screen
if (self.x < 60) self.x = 60;
if (self.x > 1988) self.x = 1988;
if (self.y < 60) self.y = 60;
if (self.y > 2672) self.y = 2672;
// Update rotation based on velocity
if (Math.abs(self.velocityX) > 0.5 || Math.abs(self.velocityY) > 0.5) {
self.rotation = Math.atan2(self.velocityY, self.velocityX) + Math.PI / 2;
carGraphics.rotation = self.rotation;
}
};
return self;
});
var PoliceCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('policeCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
// Chase player
var dx = playerCar.x - self.x;
var dy = playerCar.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.velocityX += dx / distance * 0.3;
self.velocityY += dy / distance * 0.3;
}
// Limit speed
var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (currentSpeed > self.speed) {
self.velocityX = self.velocityX / currentSpeed * self.speed;
self.velocityY = self.velocityY / currentSpeed * self.speed;
}
// Apply movement
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= 0.98;
self.velocityY *= 0.98;
// Update rotation
if (Math.abs(self.velocityX) > 0.5 || Math.abs(self.velocityY) > 0.5) {
carGraphics.rotation = Math.atan2(self.velocityY, self.velocityX) + Math.PI / 2;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game variables
var playerCar;
var policeCars = [];
var civilianCars = [];
var moneyBags = [];
var moneySpawnTimer = 0;
var policeSpawnTimer = 0;
var wantedLevel = 1;
var dragActive = false;
// Create roads
for (var i = 0; i < 7; i++) {
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: i * 300 + 150,
y: 1366
});
game.addChild(road);
}
// Create buildings between roads
for (var j = 0; j < 6; j++) {
for (var k = 0; k < 10; k++) {
var building = LK.getAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
x: j * 300 + 300,
y: k * 300 + 150
});
game.addChild(building);
}
}
// Create player car
playerCar = game.addChild(new PlayerCar());
playerCar.x = 1024;
playerCar.y = 2000;
// Create initial civilian cars
for (var c = 0; c < 8; c++) {
var civilianCar = game.addChild(new CivilianCar());
civilianCar.x = Math.random() * 1900 + 100;
civilianCar.y = Math.random() * 2500 + 100;
civilianCars.push(civilianCar);
}
// Create initial police car
var initialPolice = game.addChild(new PoliceCar());
initialPolice.x = Math.random() * 1900 + 100;
initialPolice.y = Math.random() * 1000 + 100;
policeCars.push(initialPolice);
// Create initial money bags
for (var m = 0; m < 3; m++) {
var moneyBag = game.addChild(new MoneyBag());
moneyBag.x = Math.random() * 1800 + 200;
moneyBag.y = Math.random() * 2400 + 200;
moneyBags.push(moneyBag);
}
// UI
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var wantedTxt = new Text2('Wanted Level: 1', {
size: 60,
fill: 0xFF4444
});
wantedTxt.anchor.set(1, 0);
wantedTxt.x = -20;
wantedTxt.y = 100;
LK.gui.topRight.addChild(wantedTxt);
// Touch controls
game.down = function (x, y, obj) {
dragActive = true;
};
game.move = function (x, y, obj) {
if (dragActive) {
var dx = x - playerCar.x;
var dy = y - playerCar.y;
// Apply acceleration towards touch point
playerCar.velocityX += dx * 0.01;
playerCar.velocityY += dy * 0.01;
// Limit max speed
var currentSpeed = Math.sqrt(playerCar.velocityX * playerCar.velocityX + playerCar.velocityY * playerCar.velocityY);
if (currentSpeed > playerCar.maxSpeed) {
playerCar.velocityX = playerCar.velocityX / currentSpeed * playerCar.maxSpeed;
playerCar.velocityY = playerCar.velocityY / currentSpeed * playerCar.maxSpeed;
}
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Play background music
LK.playMusic('chase');
// Main game loop
game.update = function () {
// Update wanted level based on score
var newWantedLevel = Math.floor(LK.getScore() / 5) + 1;
if (newWantedLevel > wantedLevel && newWantedLevel <= 5) {
wantedLevel = newWantedLevel;
wantedTxt.setText('Wanted Level: ' + wantedLevel);
}
// Spawn money bags
moneySpawnTimer++;
if (moneySpawnTimer > 180) {
if (moneyBags.length < 5) {
var newMoney = game.addChild(new MoneyBag());
newMoney.x = Math.random() * 1800 + 200;
newMoney.y = Math.random() * 2400 + 200;
moneyBags.push(newMoney);
}
moneySpawnTimer = 0;
}
// Spawn police cars based on wanted level
policeSpawnTimer++;
if (policeSpawnTimer > 300 - wantedLevel * 40) {
if (policeCars.length < wantedLevel + 1) {
var newPolice = game.addChild(new PoliceCar());
newPolice.x = Math.random() * 1900 + 100;
newPolice.y = Math.random() * 500 + 100;
newPolice.speed = 6 + wantedLevel * 0.5;
policeCars.push(newPolice);
}
policeSpawnTimer = 0;
}
// Check money collection
for (var i = moneyBags.length - 1; i >= 0; i--) {
var money = moneyBags[i];
if (playerCar.intersects(money)) {
LK.setScore(LK.getScore() + 1);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('collect').play();
money.destroy();
moneyBags.splice(i, 1);
// Win condition
if (LK.getScore() >= 50) {
LK.showYouWin();
}
}
}
// Check police collisions
for (var j = 0; j < policeCars.length; j++) {
var police = policeCars[j];
if (playerCar.intersects(police)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
// Check civilian collisions
for (var k = 0; k < civilianCars.length; k++) {
var civilian = civilianCars[k];
if (playerCar.intersects(civilian)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
};