/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Car class
var Car = Container.expand(function () {
var self = Container.call(this);
var carSprite = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carSprite.width;
self.height = carSprite.height;
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
});
// Set fixed size for all obstacles
obsSprite.width = 200;
obsSprite.height = 200;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22; // pixels per frame, can be increased for difficulty
self.update = function () {
self.y += self.speed;
};
return self;
});
// ObstacleBlack class (large, rare, black)
var ObstacleBlack = Container.expand(function () {
var self = Container.call(this);
var obsSprite = self.attachAsset('obstacleBlack', {
anchorX: 0.5,
anchorY: 0.5
});
obsSprite.width = 320;
obsSprite.height = 320;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22;
self.update = function () {
self.y += self.speed;
};
return self;
});
// ObstaclePurple class
var ObstaclePurple = Container.expand(function () {
var self = Container.call(this);
var obsSprite = self.attachAsset('obstaclePurple', {
anchorX: 0.5,
anchorY: 0.5
});
obsSprite.width = 200;
obsSprite.height = 200;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Road width: 1200px, centered
// Game area: 2048x2732
// Car asset: blue box, 200x350
// Obstacle asset: red box, 200x200
// Road lane asset: gray box, 2048x2732 (background, not used as a background, but for lane lines)
var ROAD_WIDTH = 1200;
var ROAD_LEFT = (2048 - ROAD_WIDTH) / 2;
var ROAD_RIGHT = ROAD_LEFT + ROAD_WIDTH;
var CAR_Y = 2732 - 500; // Car vertical position
// Draw lane lines (visual only)
var laneLines = [];
for (var i = 1; i < 4; i++) {
var laneX = ROAD_LEFT + ROAD_WIDTH / 4 * i;
for (var j = 0; j < 6; j++) {
var line = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: laneX,
y: j * 500 + 200,
alpha: 0.25
});
game.addChild(line);
laneLines.push(line);
}
}
// Add left and right lane edge lines
var edgeLines = [];
for (var j = 0; j < 6; j++) {
// Left edge (road boundary)
var leftEdge = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: ROAD_LEFT,
y: j * 500 + 200,
alpha: 0.7
});
game.addChild(leftEdge);
edgeLines.push(leftEdge);
// Right edge (road boundary)
var rightEdge = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: ROAD_RIGHT,
y: j * 500 + 200,
alpha: 0.7
});
game.addChild(rightEdge);
edgeLines.push(rightEdge);
// Far left vertical line (game border)
var farLeft = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 0 + 30,
// 30px from the very left
y: j * 500 + 200,
alpha: 0.4
});
game.addChild(farLeft);
edgeLines.push(farLeft);
// Far right vertical line (game border)
var farRight = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 30,
// 30px from the very right
y: j * 500 + 200,
alpha: 0.4
});
game.addChild(farRight);
edgeLines.push(farRight);
}
// Car
var car = new Car();
car.x = 2048 / 2;
car.y = CAR_Y;
game.addChild(car);
// Obstacles
var obstacles = [];
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Touch controls
var dragX = null;
var dragStartCarX = null;
// Move handler
function handleMove(x, y, obj) {
if (dragX !== null) {
// Clamp to road
var dx = x - dragX;
var newCarX = dragStartCarX + dx;
if (newCarX < ROAD_LEFT + car.width / 2) newCarX = ROAD_LEFT + car.width / 2;
if (newCarX > ROAD_RIGHT - car.width / 2) newCarX = ROAD_RIGHT - car.width / 2;
car.x = newCarX;
}
// Check collision
for (var i = 0; i < obstacles.length; i++) {
if (car.intersects(obstacles[i])) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
// Touch down
game.down = function (x, y, obj) {
// Only allow drag if touch is on car or below
if (y > car.y - car.height / 2 - 100) {
dragX = x;
dragStartCarX = car.x;
handleMove(x, y, obj);
}
};
// Touch up
game.up = function (x, y, obj) {
dragX = null;
dragStartCarX = null;
};
// Move
game.move = handleMove;
// Main update
game.update = function () {
// Animate lane lines for road movement
for (var i = 0; i < laneLines.length; i++) {
laneLines[i].y += 22;
if (laneLines[i].y > 2732 + 100) {
laneLines[i].y -= 2732 + 400;
}
}
// Animate edge lines for road movement
for (var i = 0; i < edgeLines.length; i++) {
edgeLines[i].y += 22;
if (edgeLines[i].y > 2732 + 100) {
edgeLines[i].y -= 2732 + 400;
}
}
// Obstacles update
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
if (obs.y - obs.height / 2 > 2732 + 100) {
// Passed, remove and score
obs.destroy();
obstacles.splice(i, 1);
score += 1;
scoreTxt.setText(score);
} else if (car.intersects(obs)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// --- Dynamic difficulty: obstacle speed and spawn rate scale with score ---
// Calculate difficulty scaling
var minSpawnInterval = 12; // minimum ticks between spawns (faster = more obstacles)
var maxSpawnInterval = 40; // slowest spawn interval (start)
var spawnInterval = Math.floor(maxSpawnInterval - Math.min(score, 60) * 0.4); // gets faster with score, clamps at min
if (spawnInterval < minSpawnInterval) spawnInterval = minSpawnInterval;
// Calculate speed scaling
var baseSpeed = 22;
var maxSpeed = 60;
var speed = baseSpeed + Math.min(score, 100) * 0.35; // up to maxSpeed
if (speed > maxSpeed) speed = maxSpeed;
// Update all obstacle speeds to match current difficulty
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = speed;
}
// Also update lane line and edge line speeds for road movement
for (var i = 0; i < laneLines.length; i++) {
laneLines[i].y += speed;
if (laneLines[i].y > 2732 + 100) {
laneLines[i].y -= 2732 + 400;
}
}
for (var i = 0; i < edgeLines.length; i++) {
edgeLines[i].y += speed;
if (edgeLines[i].y > 2732 + 100) {
edgeLines[i].y -= 2732 + 400;
}
}
// Spawn new obstacles
if (LK.ticks % spawnInterval === 0) {
// Random lane: 4 lanes
var lane = Math.floor(Math.random() * 4);
var laneCenter = ROAD_LEFT + ROAD_WIDTH / 8 + lane * (ROAD_WIDTH / 4);
// 7% black, 18% big red (removed), 30% normal, 45% purple
var obs;
var r = Math.random();
if (r < 0.07) {
obs = new ObstacleBlack();
} else if (r < 0.37) {
obs = new Obstacle();
} else {
obs = new ObstaclePurple();
}
obs.x = laneCenter;
obs.y = -obs.height / 2;
obs.speed = speed; // set initial speed
game.addChild(obs);
obstacles.push(obs);
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Car class
var Car = Container.expand(function () {
var self = Container.call(this);
var carSprite = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carSprite.width;
self.height = carSprite.height;
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
});
// Set fixed size for all obstacles
obsSprite.width = 200;
obsSprite.height = 200;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22; // pixels per frame, can be increased for difficulty
self.update = function () {
self.y += self.speed;
};
return self;
});
// ObstacleBlack class (large, rare, black)
var ObstacleBlack = Container.expand(function () {
var self = Container.call(this);
var obsSprite = self.attachAsset('obstacleBlack', {
anchorX: 0.5,
anchorY: 0.5
});
obsSprite.width = 320;
obsSprite.height = 320;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22;
self.update = function () {
self.y += self.speed;
};
return self;
});
// ObstaclePurple class
var ObstaclePurple = Container.expand(function () {
var self = Container.call(this);
var obsSprite = self.attachAsset('obstaclePurple', {
anchorX: 0.5,
anchorY: 0.5
});
obsSprite.width = 200;
obsSprite.height = 200;
self.width = obsSprite.width;
self.height = obsSprite.height;
self.speed = 22;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Road width: 1200px, centered
// Game area: 2048x2732
// Car asset: blue box, 200x350
// Obstacle asset: red box, 200x200
// Road lane asset: gray box, 2048x2732 (background, not used as a background, but for lane lines)
var ROAD_WIDTH = 1200;
var ROAD_LEFT = (2048 - ROAD_WIDTH) / 2;
var ROAD_RIGHT = ROAD_LEFT + ROAD_WIDTH;
var CAR_Y = 2732 - 500; // Car vertical position
// Draw lane lines (visual only)
var laneLines = [];
for (var i = 1; i < 4; i++) {
var laneX = ROAD_LEFT + ROAD_WIDTH / 4 * i;
for (var j = 0; j < 6; j++) {
var line = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: laneX,
y: j * 500 + 200,
alpha: 0.25
});
game.addChild(line);
laneLines.push(line);
}
}
// Add left and right lane edge lines
var edgeLines = [];
for (var j = 0; j < 6; j++) {
// Left edge (road boundary)
var leftEdge = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: ROAD_LEFT,
y: j * 500 + 200,
alpha: 0.7
});
game.addChild(leftEdge);
edgeLines.push(leftEdge);
// Right edge (road boundary)
var rightEdge = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: ROAD_RIGHT,
y: j * 500 + 200,
alpha: 0.7
});
game.addChild(rightEdge);
edgeLines.push(rightEdge);
// Far left vertical line (game border)
var farLeft = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 0 + 30,
// 30px from the very left
y: j * 500 + 200,
alpha: 0.4
});
game.addChild(farLeft);
edgeLines.push(farLeft);
// Far right vertical line (game border)
var farRight = LK.getAsset('laneLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 30,
// 30px from the very right
y: j * 500 + 200,
alpha: 0.4
});
game.addChild(farRight);
edgeLines.push(farRight);
}
// Car
var car = new Car();
car.x = 2048 / 2;
car.y = CAR_Y;
game.addChild(car);
// Obstacles
var obstacles = [];
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Touch controls
var dragX = null;
var dragStartCarX = null;
// Move handler
function handleMove(x, y, obj) {
if (dragX !== null) {
// Clamp to road
var dx = x - dragX;
var newCarX = dragStartCarX + dx;
if (newCarX < ROAD_LEFT + car.width / 2) newCarX = ROAD_LEFT + car.width / 2;
if (newCarX > ROAD_RIGHT - car.width / 2) newCarX = ROAD_RIGHT - car.width / 2;
car.x = newCarX;
}
// Check collision
for (var i = 0; i < obstacles.length; i++) {
if (car.intersects(obstacles[i])) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
// Touch down
game.down = function (x, y, obj) {
// Only allow drag if touch is on car or below
if (y > car.y - car.height / 2 - 100) {
dragX = x;
dragStartCarX = car.x;
handleMove(x, y, obj);
}
};
// Touch up
game.up = function (x, y, obj) {
dragX = null;
dragStartCarX = null;
};
// Move
game.move = handleMove;
// Main update
game.update = function () {
// Animate lane lines for road movement
for (var i = 0; i < laneLines.length; i++) {
laneLines[i].y += 22;
if (laneLines[i].y > 2732 + 100) {
laneLines[i].y -= 2732 + 400;
}
}
// Animate edge lines for road movement
for (var i = 0; i < edgeLines.length; i++) {
edgeLines[i].y += 22;
if (edgeLines[i].y > 2732 + 100) {
edgeLines[i].y -= 2732 + 400;
}
}
// Obstacles update
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
if (obs.y - obs.height / 2 > 2732 + 100) {
// Passed, remove and score
obs.destroy();
obstacles.splice(i, 1);
score += 1;
scoreTxt.setText(score);
} else if (car.intersects(obs)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// --- Dynamic difficulty: obstacle speed and spawn rate scale with score ---
// Calculate difficulty scaling
var minSpawnInterval = 12; // minimum ticks between spawns (faster = more obstacles)
var maxSpawnInterval = 40; // slowest spawn interval (start)
var spawnInterval = Math.floor(maxSpawnInterval - Math.min(score, 60) * 0.4); // gets faster with score, clamps at min
if (spawnInterval < minSpawnInterval) spawnInterval = minSpawnInterval;
// Calculate speed scaling
var baseSpeed = 22;
var maxSpeed = 60;
var speed = baseSpeed + Math.min(score, 100) * 0.35; // up to maxSpeed
if (speed > maxSpeed) speed = maxSpeed;
// Update all obstacle speeds to match current difficulty
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = speed;
}
// Also update lane line and edge line speeds for road movement
for (var i = 0; i < laneLines.length; i++) {
laneLines[i].y += speed;
if (laneLines[i].y > 2732 + 100) {
laneLines[i].y -= 2732 + 400;
}
}
for (var i = 0; i < edgeLines.length; i++) {
edgeLines[i].y += speed;
if (edgeLines[i].y > 2732 + 100) {
edgeLines[i].y -= 2732 + 400;
}
}
// Spawn new obstacles
if (LK.ticks % spawnInterval === 0) {
// Random lane: 4 lanes
var lane = Math.floor(Math.random() * 4);
var laneCenter = ROAD_LEFT + ROAD_WIDTH / 8 + lane * (ROAD_WIDTH / 4);
// 7% black, 18% big red (removed), 30% normal, 45% purple
var obs;
var r = Math.random();
if (r < 0.07) {
obs = new ObstacleBlack();
} else if (r < 0.37) {
obs = new Obstacle();
} else {
obs = new ObstaclePurple();
}
obs.x = laneCenter;
obs.y = -obs.height / 2;
obs.speed = speed; // set initial speed
game.addChild(obs);
obstacles.push(obs);
}
};
üstten görünümlü araba. In-Game asset. 2d. High contrast. No shadows
üstten görünümlü araba yap. In-Game asset. 2d. High contrast. No shadows
üstten görünümlü polis arabası çiz. In-Game asset. 2d. High contrast. No shadows
beyaz dikey trafik şeridi. In-Game asset. 2d. High contrast. No shadows