User prompt
Add drags for all cars. improve play experience
User prompt
Explosion effect should not cover all screen ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make police spawn from the edge of screen. Make map repeat and never end.
User prompt
Please fix the bug: 'TypeError: setTimeout is not a function' in or related to this line: 'setTimeout(function () {' Line Number: 719
User prompt
Crash effect more explosive. increase all speeds by 3 times ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make sure player car is a little bit faster than police cars for lower levels, increase difficulty with time, diamonds and police crashes. Place player car in the middle through game
User prompt
Enable to move car not map itself, create a repeating-itself to make sure game is endless. Enable player moves not only rotation
User prompt
Decrease police car spawn interval (more common). Make map moves according to button moves. Place player car always in the middle.
User prompt
İncrease car speed
User prompt
Place right button more left and down, remove left button
User prompt
Buttons are not visible?
User prompt
Both buttons to more to middle
User prompt
Place button to a more visible place, upper
User prompt
Place button on right and left bottom when needed (should be 1 on the screen always)
User prompt
Make action stick button visible
User prompt
Not playable
User prompt
Touch screen doesn't work
User prompt
Not playable
User prompt
Enable screen touch playing
User prompt
increase reality of city map with more details
User prompt
increase pace and change cars icons with real car photos, police cars & bugatti for player ca
User prompt
enable desktop joystick button to use with mouse
User prompt
enable desktop play mode
User prompt
i need player to move all directions
User prompt
show console button
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CityBackground = Container.expand(function () {
var self = Container.call(this);
var backgroundElements = [];
self.tileHeight = 400;
self.tilesPerRow = 10;
self.rows = 10;
// Helper function to create building complex
function createBuildingComplex(col, row, topY) {
var complex = new Container();
var buildingTypes = ['building', 'tallBuilding', 'skyscraper', 'apartment', 'office'];
var buildingType = buildingTypes[Math.floor(Math.random() * buildingTypes.length)];
var building = LK.getAsset(buildingType, {
anchorX: 0,
anchorY: 0
});
building.width = 150 + Math.random() * 50;
building.height = 200 + Math.random() * 200;
building.alpha = 0.8;
complex.addChild(building);
// Add windows effect with alpha variations
building.alpha = 0.7 + Math.random() * 0.3;
// Add sidewalk
var sidewalk = LK.getAsset('sidewalk', {
anchorX: 0,
anchorY: 0
});
sidewalk.width = 200;
sidewalk.height = 30;
sidewalk.y = building.height - 30;
complex.addChild(sidewalk);
// Randomly add street elements
if (Math.random() < 0.3) {
var streetLight = LK.getAsset('streetLight', {
anchorX: 0,
anchorY: 0
});
streetLight.x = 20 + Math.random() * 160;
streetLight.y = building.height - 80;
complex.addChild(streetLight);
}
if (Math.random() < 0.2) {
var tree = LK.getAsset('tree', {
anchorX: 0,
anchorY: 0
});
tree.x = 30 + Math.random() * 140;
tree.y = building.height - 60;
complex.addChild(tree);
}
if (Math.random() < 0.15) {
var mailbox = LK.getAsset('mailbox', {
anchorX: 0,
anchorY: 0
});
mailbox.x = 40 + Math.random() * 120;
mailbox.y = building.height - 30;
complex.addChild(mailbox);
}
complex.x = col * 200;
complex.y = topY;
return complex;
}
// Helper function to create road with details
function createRoadSection(col, row, topY) {
var roadSection = new Container();
var road = LK.getAsset('road', {
anchorX: 0,
anchorY: 0
});
road.width = 200;
road.height = 100;
roadSection.addChild(road);
// Add lane markings
for (var i = 0; i < 3; i++) {
var laneLine = LK.getAsset('laneLine', {
anchorX: 0,
anchorY: 0
});
laneLine.width = 200;
laneLine.height = 3;
laneLine.y = 25 + i * 25;
laneLine.alpha = 0.8;
roadSection.addChild(laneLine);
}
// Randomly add crosswalk
if (Math.random() < 0.2) {
var crosswalk = LK.getAsset('crosswalk', {
anchorX: 0,
anchorY: 0
});
crosswalk.width = 200;
crosswalk.height = 15;
crosswalk.y = 85;
crosswalk.alpha = 0.9;
roadSection.addChild(crosswalk);
}
// Randomly add parked vehicles
if (Math.random() < 0.3) {
var vehicleTypes = ['parkedCar', 'taxi'];
var vehicleType = vehicleTypes[Math.floor(Math.random() * vehicleTypes.length)];
var vehicle = LK.getAsset(vehicleType, {
anchorX: 0,
anchorY: 0
});
vehicle.width = 60;
vehicle.height = 100;
vehicle.x = 10 + Math.random() * 130;
vehicle.y = 0;
vehicle.alpha = 0.8;
roadSection.addChild(vehicle);
}
// Randomly add bus
if (Math.random() < 0.1) {
var bus = LK.getAsset('bus', {
anchorX: 0,
anchorY: 0
});
bus.width = 90;
bus.height = 200;
bus.x = 55;
bus.y = -50;
bus.alpha = 0.8;
roadSection.addChild(bus);
}
roadSection.x = col * 200;
roadSection.y = topY;
return roadSection;
}
// Create initial background tiles
for (var row = 0; row < self.rows; row++) {
for (var col = 0; col < self.tilesPerRow; col++) {
var element;
var elementType = Math.floor(Math.random() * 10);
var topY = (row - 2) * self.tileHeight;
if (elementType < 3) {
// Road with details (30% chance)
element = createRoadSection(col, row, topY);
} else if (elementType < 8) {
// Building complex (50% chance)
element = createBuildingComplex(col, row, topY);
} else {
// City block (20% chance)
element = LK.getAsset('cityBlock', {
anchorX: 0,
anchorY: 0
});
element.width = 200;
element.height = 200;
element.x = col * 200;
element.y = topY;
element.alpha = 0.7;
}
self.addChild(element);
backgroundElements.push(element);
}
}
self.update = function () {
// Move background based on player movement to keep player centered
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
}
// Find the bounds of current background elements
var minY = Infinity;
var maxY = -Infinity;
var minX = Infinity;
var maxX = -Infinity;
for (var i = 0; i < backgroundElements.length; i++) {
var element = backgroundElements[i];
minY = Math.min(minY, element.y);
maxY = Math.max(maxY, element.y);
minX = Math.min(minX, element.x);
maxX = Math.max(maxX, element.x);
}
// Add new tiles in all directions as needed for endless scrolling
// Add rows above if needed
if (minY > -self.y - 800) {
var newTopY = minY - self.tileHeight;
for (var col = 0; col < self.tilesPerRow; col++) {
var element;
var elementType = Math.floor(Math.random() * 10);
if (elementType < 3) {
element = createRoadSection(col, 0, newTopY);
} else if (elementType < 8) {
element = createBuildingComplex(col, 0, newTopY);
} else {
element = LK.getAsset('cityBlock', {
anchorX: 0,
anchorY: 0
});
element.width = 200;
element.height = 200;
element.x = col * 200;
element.y = newTopY;
element.alpha = 0.7;
}
self.addChild(element);
backgroundElements.push(element);
}
}
// Add rows below if needed
if (maxY < -self.y + 3500) {
var newBottomY = maxY + self.tileHeight;
for (var col = 0; col < self.tilesPerRow; col++) {
var element;
var elementType = Math.floor(Math.random() * 10);
if (elementType < 3) {
element = createRoadSection(col, 0, newBottomY);
} else if (elementType < 8) {
element = createBuildingComplex(col, 0, newBottomY);
} else {
element = LK.getAsset('cityBlock', {
anchorX: 0,
anchorY: 0
});
element.width = 200;
element.height = 200;
element.x = col * 200;
element.y = newBottomY;
element.alpha = 0.7;
}
self.addChild(element);
backgroundElements.push(element);
}
}
// Add columns left if needed
if (minX > -self.x - 400) {
var newLeftX = minX - 200;
for (var row = 0; row < Math.ceil((maxY - minY) / self.tileHeight) + 2; row++) {
var element;
var elementType = Math.floor(Math.random() * 10);
var yPos = minY + row * self.tileHeight;
if (elementType < 3) {
element = createRoadSection(0, 0, yPos);
} else if (elementType < 8) {
element = createBuildingComplex(0, 0, yPos);
} else {
element = LK.getAsset('cityBlock', {
anchorX: 0,
anchorY: 0
});
element.width = 200;
element.height = 200;
element.y = yPos;
element.alpha = 0.7;
}
element.x = newLeftX;
self.addChild(element);
backgroundElements.push(element);
}
}
// Add columns right if needed
if (maxX < -self.x + 2400) {
var newRightX = maxX + 200;
for (var row = 0; row < Math.ceil((maxY - minY) / self.tileHeight) + 2; row++) {
var element;
var elementType = Math.floor(Math.random() * 10);
var yPos = minY + row * self.tileHeight;
if (elementType < 3) {
element = createRoadSection(0, 0, yPos);
} else if (elementType < 8) {
element = createBuildingComplex(0, 0, yPos);
} else {
element = LK.getAsset('cityBlock', {
anchorX: 0,
anchorY: 0
});
element.width = 200;
element.height = 200;
element.y = yPos;
element.alpha = 0.7;
}
element.x = newRightX;
self.addChild(element);
backgroundElements.push(element);
}
}
// Remove elements that are too far away for memory management
for (var i = backgroundElements.length - 1; i >= 0; i--) {
var element = backgroundElements[i];
var distanceFromPlayer = Math.sqrt(Math.pow(element.x + self.x, 2) + Math.pow(element.y + self.y, 2));
if (distanceFromPlayer > 4000) {
element.destroy();
backgroundElements.splice(i, 1);
}
}
};
return self;
});
var Diamond = Container.expand(function () {
var self = Container.call(this);
var diamondGraphics = self.attachAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.rotationSpeed = 0.05;
self.update = function () {
diamondGraphics.rotation += self.rotationSpeed;
// Move diamonds based on player movement to keep world consistent
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
}
// Diamonds stay static in world - no movement with map
// Remove diamonds that go off screen (player moved away)
if (self.y > 2732 + 100 || self.y < -100 || self.x > 2048 + 100 || self.x < -100) {
self.destroy();
}
};
return self;
});
var DragEffect = Container.expand(function () {
var self = Container.call(this);
self.effectGraphics = self.attachAsset('getawayCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.effectGraphics.alpha = 0.3;
self.effectGraphics.tint = 0x00ffff;
self.effectGraphics.scaleX = 0.6;
self.effectGraphics.scaleY = 0.6;
self.lifetime = 20;
self.age = 0;
self.initialAlpha = 0.5;
self.update = function () {
self.age++;
var fadeRatio = 1 - self.age / self.lifetime;
self.effectGraphics.alpha = self.initialAlpha * fadeRatio;
self.effectGraphics.scaleX = 0.6 * fadeRatio;
self.effectGraphics.scaleY = 0.6 * fadeRatio;
// Move with world
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
}
if (self.age >= self.lifetime) {
self.destroy();
}
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 30;
self.age = 0;
self.update = function () {
self.age++;
explosionGraphics.alpha = 1 - self.age / self.lifetime;
explosionGraphics.scaleX = 1 + self.age / self.lifetime;
explosionGraphics.scaleY = 1 + self.age / self.lifetime;
// Move explosions based on player movement to keep world consistent
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
}
// Explosions stay static in world - no movement with map
if (self.age >= self.lifetime) {
self.destroy();
}
};
return self;
});
var GetawayCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('getawayCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 36; // Increased base speed by 3x
self.maxSpeed = 72; // Increased max speed by 3x to be faster than police
self.velocityX = 0;
self.velocityY = 0;
self.acceleration = 2.4; // Increased acceleration by 3x
self.friction = 0.85;
// Drag effect properties
self.dragTrail = [];
self.maxTrailLength = 8;
self.trailFadeSpeed = 0.8;
self.update = function () {
var inputX = 0;
var inputY = 0;
var hasInput = false;
// Apply active button input if available (mobile)
if (activeButton && activeButton.isActive) {
inputX = activeButton.currentX;
inputY = activeButton.currentY;
hasInput = true;
}
// Keyboard input removed - not supported in LK engine
// Apply input to velocity
if (hasInput) {
self.velocityX += inputX * self.acceleration;
self.velocityY += inputY * self.acceleration;
// Rotate car to face movement direction
if (inputX !== 0 || inputY !== 0) {
var angle = Math.atan2(inputY, inputX);
carGraphics.rotation = angle + Math.PI / 2;
}
}
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Limit velocity
var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (speed > self.maxSpeed) {
self.velocityX = self.velocityX / speed * self.maxSpeed;
self.velocityY = self.velocityY / speed * self.maxSpeed;
}
// Update drag trail effect
if (speed > 1) {
// Add current position to trail
self.dragTrail.unshift({
x: self.x,
y: self.y,
alpha: 1.0,
scale: 1.0
});
// Limit trail length
if (self.dragTrail.length > self.maxTrailLength) {
self.dragTrail.pop();
}
}
// Update trail particles
for (var i = 0; i < self.dragTrail.length; i++) {
var trail = self.dragTrail[i];
trail.alpha *= self.trailFadeSpeed;
trail.scale *= 0.95;
if (trail.alpha < 0.1) {
self.dragTrail.splice(i, 1);
i--;
}
}
// Keep player car centered - move world instead of car
self.x = 1024; // Always center horizontally
self.y = 1366; // Always center vertically
// Store velocity for world movement
self.worldVelocityX = self.velocityX;
self.worldVelocityY = self.velocityY;
};
return self;
});
var JoystickControl = Container.expand(function () {
var self = Container.call(this);
var joystickBase = self.attachAsset('joystickBase', {
anchorX: 0.5,
anchorY: 0.5
});
var joystickKnob = self.attachAsset('joystickKnob', {
anchorX: 0.5,
anchorY: 0.5
});
joystickBase.alpha = 1.0;
joystickKnob.alpha = 1.0;
joystickBase.tint = 0x7f8c8d; // Light gray for better visibility
joystickKnob.tint = 0xffffff; // White knob for contrast
self.isActive = false;
self.currentX = 0;
self.currentY = 0;
self.maxDistance = 100;
self.down = function (x, y, obj) {
self.isActive = true;
self.updateKnob(x, y);
};
self.move = function (x, y, obj) {
if (self.isActive) {
self.updateKnob(x, y);
}
};
self.up = function (x, y, obj) {
self.isActive = false;
joystickKnob.x = 0;
joystickKnob.y = 0;
self.currentX = 0;
self.currentY = 0;
};
self.updateKnob = function (x, y) {
var deltaX = x;
var deltaY = y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > self.maxDistance) {
deltaX = deltaX / distance * self.maxDistance;
deltaY = deltaY / distance * self.maxDistance;
}
joystickKnob.x = deltaX;
joystickKnob.y = deltaY;
self.currentX = deltaX / self.maxDistance;
self.currentY = deltaY / self.maxDistance;
};
return self;
});
var PoliceCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('policeCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.baseSpeed = 24; // Base speed slower than player (3x increase)
self.speed = self.baseSpeed;
self.targetCar = null;
self.lastCollisionCheck = false;
self.velocityX = 0;
self.velocityY = 0;
self.acceleration = 0.6; // Increased acceleration by 3x
self.friction = 0.95;
// Drag effect properties
self.dragTrail = [];
self.maxTrailLength = 6;
self.trailFadeSpeed = 0.75;
self.update = function () {
if (self.targetCar) {
var deltaX = self.targetCar.x - self.x;
var deltaY = self.targetCar.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 5) {
// Apply acceleration towards target
self.velocityX += deltaX / distance * self.acceleration;
self.velocityY += deltaY / distance * self.acceleration;
// Rotate car to face movement direction
var angle = Math.atan2(deltaY, deltaX);
carGraphics.rotation = angle + Math.PI / 2;
}
}
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Apply difficulty scaling to speed
var difficultyMultiplier = 1 + milestone * 0.3 + diamondsCollected * 0.02 + policeKills * 0.05;
var currentSpeed = self.baseSpeed * difficultyMultiplier;
// Ensure police are always slower than player max speed (3x increase)
if (currentSpeed > 60) currentSpeed = 60;
// Limit velocity
var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (speed > currentSpeed) {
self.velocityX = self.velocityX / speed * currentSpeed;
self.velocityY = self.velocityY / speed * currentSpeed;
}
// Move police car
self.x += self.velocityX;
self.y += self.velocityY;
// Update drag trail effect
var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (speed > 0.5) {
// Add current position to trail before world movement
self.dragTrail.unshift({
x: self.x,
y: self.y,
alpha: 0.8,
scale: 0.8
});
// Limit trail length
if (self.dragTrail.length > self.maxTrailLength) {
self.dragTrail.pop();
}
}
// Update trail particles
for (var i = 0; i < self.dragTrail.length; i++) {
var trail = self.dragTrail[i];
trail.alpha *= self.trailFadeSpeed;
trail.scale *= 0.92;
if (trail.alpha < 0.05) {
self.dragTrail.splice(i, 1);
i--;
}
}
// Move police cars based on player movement to keep world consistent
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
// Also move trail positions to keep them consistent with world movement
for (var i = 0; i < self.dragTrail.length; i++) {
self.dragTrail[i].x -= player.worldVelocityX;
self.dragTrail[i].y -= player.worldVelocityY;
}
}
// Police cars stay in world - no map movement
// Remove police cars that go off screen
if (self.y > 2732 + 100 || self.y < -100 || self.x > 2048 + 100 || self.x < -100) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Game variables
var player;
var policeCars = [];
var diamonds = [];
var explosions = [];
var gameSpeed = 1;
var milestone = 0;
var diamondsCollected = 0;
var policeKills = 0;
var mapSpeed = 36; // Increased by 3x
var mapOffsetY = 0;
var baseMapSpeed = 36; // Increased by 3x
// Background colors for different milestones
var backgroundColors = [0x2c3e50, 0x34495e, 0x1abc9c, 0x16a085, 0x27ae60, 0x2980b9];
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var diamondsTxt = new Text2('Diamonds: 0', {
size: 50,
fill: 0xF1C40F
});
diamondsTxt.anchor.set(0.5, 0);
diamondsTxt.x = 0;
diamondsTxt.y = 80;
LK.gui.top.addChild(diamondsTxt);
var killsTxt = new Text2('Police Crashes: 0', {
size: 50,
fill: 0xE74C3C
});
killsTxt.anchor.set(0.5, 0);
killsTxt.x = 0;
killsTxt.y = 140;
LK.gui.top.addChild(killsTxt);
// Initialize city background
var cityBackground = game.addChild(new CityBackground());
// Initialize joystick control
var joystick = new JoystickControl();
// Create right action button
var rightButton = new JoystickControl();
rightButton.x = 0;
rightButton.y = 0;
// Scale up the button for better visibility
rightButton.scaleX = 1.5;
rightButton.scaleY = 1.5;
LK.gui.center.addChild(rightButton);
rightButton.x = 300; // Move more left from center
rightButton.y = 400; // Move down from center
// Only show right button
rightButton.visible = true;
var activeButton = rightButton;
// Initialize player
player = game.addChild(new GetawayCar());
player.x = 1024; // Center horizontally
player.y = 1366; // Center vertically
// Spawn initial police cars
function spawnPoliceCar() {
var police = new PoliceCar();
// Spawn from screen edges
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
var margin = 50;
switch (edge) {
case 0:
// Top edge
police.x = Math.random() * 2048;
police.y = -margin;
break;
case 1:
// Right edge
police.x = 2048 + margin;
police.y = Math.random() * 2732;
break;
case 2:
// Bottom edge
police.x = Math.random() * 2048;
police.y = 2732 + margin;
break;
case 3:
// Left edge
police.x = -margin;
police.y = Math.random() * 2732;
break;
}
police.targetCar = player;
police.baseSpeed = 24; // Set base speed (3x increase)
police.speed = police.baseSpeed;
policeCars.push(police);
game.addChild(police);
}
// Spawn initial diamonds
function spawnDiamond() {
var diamond = new Diamond();
// Spawn diamonds around the current play area
diamond.x = player.x - 500 + Math.random() * 1000;
diamond.y = player.y - 500 + Math.random() * 1000;
// Keep diamonds within reasonable bounds
if (diamond.x < 50) diamond.x = 50;
if (diamond.x > 1998) diamond.x = 1998;
if (diamond.y < 50) diamond.y = 50;
if (diamond.y > 2682) diamond.y = 2682;
diamonds.push(diamond);
game.addChild(diamond);
}
// Initialize game objects
for (var i = 0; i < 3; i++) {
spawnPoliceCar();
}
for (var i = 0; i < 1; i++) {
spawnDiamond();
}
// Joystick controls are now handled by the JoystickControl class
// Desktop keyboard controls (removed - not supported in LK engine)
var keys = {};
// Touch and mouse controls for action buttons
game.down = function (x, y, obj) {
// Check if touch is in right button area
if (rightButton.visible) {
// Touch in right button area
var buttonPos = LK.gui.center.toLocal({
x: x,
y: y
});
buttonPos.x -= 300; // Adjust for right button offset
buttonPos.y -= 400; // Adjust for right button Y offset
var distance = Math.sqrt(buttonPos.x * buttonPos.x + buttonPos.y * buttonPos.y);
if (distance <= rightButton.maxDistance * 1.5) {
activeButton = rightButton;
rightButton.down(buttonPos.x, buttonPos.y, obj);
}
}
};
game.move = function (x, y, obj) {
if (activeButton && activeButton.isActive) {
if (activeButton === rightButton) {
var buttonPos = LK.gui.center.toLocal({
x: x,
y: y
});
buttonPos.x -= 300; // Adjust for right button offset
buttonPos.y -= 400; // Adjust for right button Y offset
rightButton.move(buttonPos.x, buttonPos.y, obj);
}
}
};
game.up = function (x, y, obj) {
if (activeButton && activeButton.isActive) {
activeButton.up(x, y, obj);
}
};
// Update score display
function updateScore() {
var totalScore = diamondsCollected * 100 + policeKills * 500;
LK.setScore(totalScore);
scoreTxt.setText('Score: ' + totalScore);
diamondsTxt.setText('Diamonds: ' + diamondsCollected);
killsTxt.setText('Police Crashes: ' + policeKills);
}
// Check milestone progression
function checkMilestone() {
var newMilestone = Math.floor(LK.getScore() / 1000);
if (newMilestone > milestone) {
milestone = newMilestone;
// Change background color
if (milestone < backgroundColors.length) {
tween(game, {
backgroundColor: backgroundColors[milestone]
}, {
duration: 2000
});
}
// Spawn additional police car
spawnPoliceCar();
}
}
// Create explosion effect
function createExplosion(x, y) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
explosions.push(explosion);
game.addChild(explosion);
// Make explosion more dramatic with tween animations
// Scale explosion from small to large
tween(explosion, {
scaleX: 3,
scaleY: 3
}, {
duration: 300,
easing: tween.easeOut
});
// Fade out with pulsing effect
tween(explosion, {
alpha: 0
}, {
duration: 600,
easing: tween.easeInOut
});
// Add rotation for more dynamic effect
tween(explosion, {
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.linear
});
// Add color tint animation to explosion for more visual impact
tween(explosion, {
tint: 0xff4500
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(explosion, {
tint: 0xffffff
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
// Main game loop
game.update = function () {
// Render drag effects for player car
if (player && player.dragTrail) {
for (var i = 0; i < player.dragTrail.length; i++) {
var trail = player.dragTrail[i];
if (trail.alpha > 0.1) {
var dragEffect = new DragEffect();
dragEffect.x = trail.x;
dragEffect.y = trail.y;
dragEffect.effectGraphics.alpha = trail.alpha * 0.4;
dragEffect.effectGraphics.scaleX = trail.scale * 0.7;
dragEffect.effectGraphics.scaleY = trail.scale * 0.7;
dragEffect.effectGraphics.tint = 0x6f869c;
dragEffect.lifetime = 15;
game.addChild(dragEffect);
}
}
}
// Render drag effects for police cars
for (var p = 0; p < policeCars.length; p++) {
var policeCar = policeCars[p];
if (policeCar.dragTrail) {
for (var i = 0; i < policeCar.dragTrail.length; i++) {
var trail = policeCar.dragTrail[i];
if (trail.alpha > 0.05) {
var dragEffect = new DragEffect();
dragEffect.x = trail.x;
dragEffect.y = trail.y;
dragEffect.effectGraphics.alpha = trail.alpha * 0.3;
dragEffect.effectGraphics.scaleX = trail.scale * 0.6;
dragEffect.effectGraphics.scaleY = trail.scale * 0.6;
dragEffect.effectGraphics.tint = 0x8e44ad;
dragEffect.lifetime = 12;
game.addChild(dragEffect);
}
}
}
}
// Check diamond collection
for (var i = diamonds.length - 1; i >= 0; i--) {
var diamond = diamonds[i];
if (!diamond.collected && player.intersects(diamond)) {
diamond.collected = true;
diamondsCollected++;
LK.getSound('collectDiamond').play();
diamond.destroy();
diamonds.splice(i, 1);
// Spawn new diamond
spawnDiamond();
}
}
// Check police car collisions with player
for (var i = 0; i < policeCars.length; i++) {
var police = policeCars[i];
if (player.intersects(police)) {
LK.getSound('gameOver').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Check police car collisions with each other
for (var i = policeCars.length - 1; i >= 0; i--) {
var police1 = policeCars[i];
var collided = false;
for (var j = i + 1; j < policeCars.length; j++) {
var police2 = policeCars[j];
if (police1.intersects(police2)) {
// Create explosion
var explosionX = (police1.x + police2.x) / 2;
var explosionY = (police1.y + police2.y) / 2;
createExplosion(explosionX, explosionY);
policeKills++;
LK.getSound('policeExplode').play();
// Increase map speed by 1%
mapSpeed = mapSpeed * 1.01;
// Remove both police cars
police1.destroy();
police2.destroy();
policeCars.splice(j, 1);
policeCars.splice(i, 1);
collided = true;
break;
}
}
if (collided) break;
}
// Clean up police cars that went off screen
for (var i = policeCars.length - 1; i >= 0; i--) {
var police = policeCars[i];
if (police.y > 2732 + 100) {
police.destroy();
policeCars.splice(i, 1);
}
}
// Clean up diamonds that went off screen
for (var i = diamonds.length - 1; i >= 0; i--) {
var diamond = diamonds[i];
if (diamond.y > 2732 + 100) {
diamond.destroy();
diamonds.splice(i, 1);
// Spawn new diamond
spawnDiamond();
}
}
// Clean up explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
if (explosion.age >= explosion.lifetime) {
explosions.splice(i, 1);
}
}
// Spawn new police cars periodically - increased frequency
if (LK.ticks % (120 - milestone * 15) === 0) {
spawnPoliceCar();
}
// Spawn new diamonds periodically
if (LK.ticks % 500 === 0) {
spawnDiamond();
}
// Map speed logic removed - car moves instead of map
// Update score and check milestones
updateScore();
checkMilestone();
// Win condition
if (LK.getScore() >= 10000) {
LK.showYouWin();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -317,8 +317,38 @@
}
};
return self;
});
+var DragEffect = Container.expand(function () {
+ var self = Container.call(this);
+ self.effectGraphics = self.attachAsset('getawayCar', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.effectGraphics.alpha = 0.3;
+ self.effectGraphics.tint = 0x00ffff;
+ self.effectGraphics.scaleX = 0.6;
+ self.effectGraphics.scaleY = 0.6;
+ self.lifetime = 20;
+ self.age = 0;
+ self.initialAlpha = 0.5;
+ self.update = function () {
+ self.age++;
+ var fadeRatio = 1 - self.age / self.lifetime;
+ self.effectGraphics.alpha = self.initialAlpha * fadeRatio;
+ self.effectGraphics.scaleX = 0.6 * fadeRatio;
+ self.effectGraphics.scaleY = 0.6 * fadeRatio;
+ // Move with world
+ if (player && player.worldVelocityX !== undefined) {
+ self.x -= player.worldVelocityX;
+ self.y -= player.worldVelocityY;
+ }
+ if (self.age >= self.lifetime) {
+ self.destroy();
+ }
+ };
+ return self;
+});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
@@ -354,8 +384,12 @@
self.velocityX = 0;
self.velocityY = 0;
self.acceleration = 2.4; // Increased acceleration by 3x
self.friction = 0.85;
+ // Drag effect properties
+ self.dragTrail = [];
+ self.maxTrailLength = 8;
+ self.trailFadeSpeed = 0.8;
self.update = function () {
var inputX = 0;
var inputY = 0;
var hasInput = false;
@@ -384,8 +418,32 @@
if (speed > self.maxSpeed) {
self.velocityX = self.velocityX / speed * self.maxSpeed;
self.velocityY = self.velocityY / speed * self.maxSpeed;
}
+ // Update drag trail effect
+ if (speed > 1) {
+ // Add current position to trail
+ self.dragTrail.unshift({
+ x: self.x,
+ y: self.y,
+ alpha: 1.0,
+ scale: 1.0
+ });
+ // Limit trail length
+ if (self.dragTrail.length > self.maxTrailLength) {
+ self.dragTrail.pop();
+ }
+ }
+ // Update trail particles
+ for (var i = 0; i < self.dragTrail.length; i++) {
+ var trail = self.dragTrail[i];
+ trail.alpha *= self.trailFadeSpeed;
+ trail.scale *= 0.95;
+ if (trail.alpha < 0.1) {
+ self.dragTrail.splice(i, 1);
+ i--;
+ }
+ }
// Keep player car centered - move world instead of car
self.x = 1024; // Always center horizontally
self.y = 1366; // Always center vertically
// Store velocity for world movement
@@ -456,8 +514,12 @@
self.velocityX = 0;
self.velocityY = 0;
self.acceleration = 0.6; // Increased acceleration by 3x
self.friction = 0.95;
+ // Drag effect properties
+ self.dragTrail = [];
+ self.maxTrailLength = 6;
+ self.trailFadeSpeed = 0.75;
self.update = function () {
if (self.targetCar) {
var deltaX = self.targetCar.x - self.x;
var deltaY = self.targetCar.y - self.y;
@@ -487,12 +549,42 @@
}
// Move police car
self.x += self.velocityX;
self.y += self.velocityY;
+ // Update drag trail effect
+ var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
+ if (speed > 0.5) {
+ // Add current position to trail before world movement
+ self.dragTrail.unshift({
+ x: self.x,
+ y: self.y,
+ alpha: 0.8,
+ scale: 0.8
+ });
+ // Limit trail length
+ if (self.dragTrail.length > self.maxTrailLength) {
+ self.dragTrail.pop();
+ }
+ }
+ // Update trail particles
+ for (var i = 0; i < self.dragTrail.length; i++) {
+ var trail = self.dragTrail[i];
+ trail.alpha *= self.trailFadeSpeed;
+ trail.scale *= 0.92;
+ if (trail.alpha < 0.05) {
+ self.dragTrail.splice(i, 1);
+ i--;
+ }
+ }
// Move police cars based on player movement to keep world consistent
if (player && player.worldVelocityX !== undefined) {
self.x -= player.worldVelocityX;
self.y -= player.worldVelocityY;
+ // Also move trail positions to keep them consistent with world movement
+ for (var i = 0; i < self.dragTrail.length; i++) {
+ self.dragTrail[i].x -= player.worldVelocityX;
+ self.dragTrail[i].y -= player.worldVelocityY;
+ }
}
// Police cars stay in world - no map movement
// Remove police cars that go off screen
if (self.y > 2732 + 100 || self.y < -100 || self.x > 2048 + 100 || self.x < -100) {
@@ -736,8 +828,45 @@
});
}
// Main game loop
game.update = function () {
+ // Render drag effects for player car
+ if (player && player.dragTrail) {
+ for (var i = 0; i < player.dragTrail.length; i++) {
+ var trail = player.dragTrail[i];
+ if (trail.alpha > 0.1) {
+ var dragEffect = new DragEffect();
+ dragEffect.x = trail.x;
+ dragEffect.y = trail.y;
+ dragEffect.effectGraphics.alpha = trail.alpha * 0.4;
+ dragEffect.effectGraphics.scaleX = trail.scale * 0.7;
+ dragEffect.effectGraphics.scaleY = trail.scale * 0.7;
+ dragEffect.effectGraphics.tint = 0x6f869c;
+ dragEffect.lifetime = 15;
+ game.addChild(dragEffect);
+ }
+ }
+ }
+ // Render drag effects for police cars
+ for (var p = 0; p < policeCars.length; p++) {
+ var policeCar = policeCars[p];
+ if (policeCar.dragTrail) {
+ for (var i = 0; i < policeCar.dragTrail.length; i++) {
+ var trail = policeCar.dragTrail[i];
+ if (trail.alpha > 0.05) {
+ var dragEffect = new DragEffect();
+ dragEffect.x = trail.x;
+ dragEffect.y = trail.y;
+ dragEffect.effectGraphics.alpha = trail.alpha * 0.3;
+ dragEffect.effectGraphics.scaleX = trail.scale * 0.6;
+ dragEffect.effectGraphics.scaleY = trail.scale * 0.6;
+ dragEffect.effectGraphics.tint = 0x8e44ad;
+ dragEffect.lifetime = 12;
+ game.addChild(dragEffect);
+ }
+ }
+ }
+ }
// Check diamond collection
for (var i = diamonds.length - 1; i >= 0; i--) {
var diamond = diamonds[i];
if (!diamond.collected && player.intersects(diamond)) {