/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Coin class var Coin = Container.expand(function () { var self = Container.call(this); self.lane = 1; self.collected = false; // Attach asset var coinAsset = self.attachAsset('coin', { anchorX: 0.5, anchorY: 1 }); // Update per frame self.update = function () { self.y += game.speed * game.deltaTime; }; return self; }); // Obstacle class (train/barrier) var Obstacle = Container.expand(function () { var self = Container.call(this); // lane: 0,1,2 self.lane = 1; self.type = 'barrier'; // 'train' or 'barrier' self.passed = false; // Attach asset self.setType = function (type) { self.type = type; if (self.asset) { self.removeChild(self.asset); } if (type === 'train') { self.asset = self.attachAsset('train', { anchorX: 0.5, anchorY: 1 }); } else { self.asset = self.attachAsset('barrier', { anchorX: 0.5, anchorY: 1 }); } }; // Update per frame self.update = function () { self.y += game.speed * game.deltaTime; }; return self; }); // Player character class var Runner = Container.expand(function () { var self = Container.call(this); // Attach runner asset (box, blue) var runnerAsset = self.attachAsset('runner', { anchorX: 0.5, anchorY: 1 }); // Lane index: 0 (left), 1 (center), 2 (right) self.lane = 1; self.targetLane = 1; self.laneX = [game.laneLeftX, game.laneCenterX, game.laneRightX]; // Jumping and ducking state self.isJumping = false; self.isDucking = false; self.jumpStartY = 0; self.jumpTime = 0; self.duckTime = 0; // --- Running animation state --- self.runAnimTime = 0; self.runAnimDuration = 600; // ms for a full step cycle (slower bobbing) self.runAnimAmplitude = 18; // px up/down self.runAnimSideAmplitude = 7; // px left/right self.runAnimTween = null; // Move to lane (with tween) self.moveToLane = function (lane) { if (lane < 0) lane = 0; if (lane > 2) lane = 2; if (lane !== self.lane) { self.targetLane = lane; tween(self, { x: self.laneX[lane] }, { duration: 120, easing: tween.cubicOut }); self.lane = lane; } }; // Start jump self.jump = function () { if (!self.isJumping && !self.isDucking) { self.isJumping = true; self.jumpStartY = self.y; self.jumpTime = 0; } }; // Start duck self.duck = function () { if (!self.isJumping && !self.isDucking) { self.isDucking = true; self.duckTime = 0; // Shrink runner visually tween(runnerAsset, { scaleY: 0.5 }, { duration: 80, easing: tween.cubicIn }); } }; // Update per frame self.update = function () { // --- Running animation (bobbing up/down and slight left/right) --- if (!self.isJumping && !self.isDucking) { self.runAnimTime += game.deltaTime; if (self.runAnimTime > self.runAnimDuration) self.runAnimTime -= self.runAnimDuration; var t = self.runAnimTime / self.runAnimDuration; var bobY = Math.sin(t * Math.PI * 2) * self.runAnimAmplitude; var bobX = Math.sin(t * Math.PI * 4) * self.runAnimSideAmplitude; runnerAsset.y = bobY; runnerAsset.x = bobX; } else { runnerAsset.y = 0; runnerAsset.x = 0; } // Jumping: simple parabolic jump if (self.isJumping) { self.jumpTime += game.deltaTime; var t = self.jumpTime / game.jumpDuration; if (t > 1) t = 1; // Parabola: y = -4h * (t-0.5)^2 + h var h = game.jumpHeight; var dy = -4 * h * (t - 0.5) * (t - 0.5) + h; self.y = self.jumpStartY - dy; if (t >= 1) { self.isJumping = false; self.y = self.jumpStartY; } } // Ducking: stay ducked for duckDuration if (self.isDucking) { self.duckTime += game.deltaTime; if (self.duckTime >= game.duckDuration) { self.isDucking = false; // Restore runner scale tween(runnerAsset, { scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ // No title, no description backgroundColor: 0x000000 }); /**** * Game Code ****/ // city background image // --- Game constants --- game.laneCount = 3; game.laneWidth = 400; game.laneLeftX = 524; game.laneCenterX = 1024; game.laneRightX = 1524; game.groundY = 2300; game.runnerY = game.groundY; game.jumpHeight = 350; game.jumpDuration = 700; // ms (increased for longer jump) game.duckDuration = 600; // ms (increased for longer duck) game.deltaTime = 16.67; // ms, will be updated per frame game.speed = 50 / 60; // px per frame (50 px/sec at 60 FPS) game.speedIncrease = 5 / 60 / (60 * 1000 / 16.67); // px per frame per ms (5 px/minute) game.maxSpeed = 300 / 60; // cap at 300 px/sec (arbitrary, can be adjusted) game.spawnTimer = 0; game.spawnInterval = 900; // ms game.coinSpawnTimer = 0; game.coinSpawnInterval = 600; // ms game.distance = 0; game.coins = 0; game.lastTick = Date.now(); // --- Asset initialization (shapes) --- // Add city background image (behind all gameplay elements) var cityBg = LK.getAsset('citybg', { anchorX: 0.5, anchorY: 1, x: 1024, y: 2732, scaleX: 2048 / 1920, // assuming citybg is 1920x1080, scale to fit width scaleY: 2732 / 1080 // scale to fit height (portrait) }); game.addChild(cityBg); // --- Game objects --- var runner = new Runner(); runner.x = game.laneCenterX; runner.y = game.runnerY; game.addChild(runner); var obstacles = []; var coins = []; // --- GUI --- var scoreTxt = new Text2('0', { size: 110, fill: 0xFFF700 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var coinTxt = new Text2('0', { size: 80, fill: 0xFFD700 }); coinTxt.anchor.set(0, 0); coinTxt.x = 120; coinTxt.y = 0; LK.gui.top.addChild(coinTxt); // --- Touch controls (swipe) --- var touchStartX = 0; var touchStartY = 0; var touchStartTime = 0; var swipeThreshold = 80; var swipeTime = 350; // Only allow one swipe per gesture var swipeUsed = false; game.down = function (x, y, obj) { touchStartX = x; touchStartY = y; touchStartTime = Date.now(); swipeUsed = false; }; game.move = function (x, y, obj) { if (swipeUsed) return; var dx = x - touchStartX; var dy = y - touchStartY; var dt = Date.now() - touchStartTime; if (dt > swipeTime) return; // Too slow // Horizontal swipe if (Math.abs(dx) > swipeThreshold && Math.abs(dx) > Math.abs(dy)) { if (dx > 0) { // Swipe right runner.moveToLane(runner.lane + 1); } else { // Swipe left runner.moveToLane(runner.lane - 1); } swipeUsed = true; } // Vertical swipe else if (Math.abs(dy) > swipeThreshold && Math.abs(dy) > Math.abs(dx)) { if (dy < 0) { // Swipe up runner.jump(); } else { // Swipe down runner.duck(); } swipeUsed = true; } }; game.up = function (x, y, obj) { // No-op }; // --- Main update loop --- game.update = function () { // Delta time var now = Date.now(); game.deltaTime = now - game.lastTick; if (game.deltaTime > 60) game.deltaTime = 60; game.lastTick = now; // Increase speed if (game.speed < game.maxSpeed) { game.speed += game.speedIncrease * game.deltaTime; if (game.speed > game.maxSpeed) game.speed = game.maxSpeed; } // Update runner runner.update(); // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y > 2800) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with runner if (!obs.passed && obs.lane === runner.lane) { // Only check if close enough var obsTop = obs.y - obs.asset.height; var runnerBottom = runner.y; var runnerTop = runner.y - runner.height; // For train: must jump over if (obs.type === 'train') { if (!runner.isJumping && runnerBottom > obsTop && runnerTop < obs.y) { // Collision! LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } // For barrier: must duck under else if (obs.type === 'barrier') { // Barrier is low, so if not ducking and feet overlap, collision if (!runner.isDucking && runnerBottom > obsTop && runnerTop < obs.y) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } // If ducking, skip collision (runner passes under barrier) } } } // Update coins for (var j = coins.length - 1; j >= 0; j--) { var coin = coins[j]; coin.update(); // Remove if off screen if (coin.y > 2800) { coin.destroy(); coins.splice(j, 1); continue; } // Collect coin if (!coin.collected && coin.lane === runner.lane) { var coinTop = coin.y - coin.height; var runnerBottom = runner.y; var runnerTop = runner.y - runner.height; if (runnerBottom > coinTop && runnerTop < coin.y) { coin.collected = true; coin.destroy(); coins.splice(j, 1); game.coins += 1; coinTxt.setText(game.coins); } } } // Spawn obstacles game.spawnTimer += game.deltaTime; if (game.spawnTimer > game.spawnInterval) { game.spawnTimer = 0; // Randomly pick lane and type var lane = Math.floor(Math.random() * 3); var type = Math.random() < 0.6 ? 'train' : 'barrier'; var obs = new Obstacle(); obs.lane = lane; obs.setType(type); obs.x = [game.laneLeftX, game.laneCenterX, game.laneRightX][lane]; // Spawn obstacles further up (more visible distance) obs.y = game.groundY - 1800; game.addChild(obs); obstacles.push(obs); } // Spawn coins further up (more visible distance) game.coinSpawnTimer += game.deltaTime; if (game.coinSpawnTimer > game.coinSpawnInterval) { game.coinSpawnTimer = 0; var lane = Math.floor(Math.random() * 3); var coin = new Coin(); coin.lane = lane; coin.x = [game.laneLeftX, game.laneCenterX, game.laneRightX][lane]; coin.y = game.groundY - 1500; game.addChild(coin); coins.push(coin); } // Update distance and score game.distance += game.speed * game.deltaTime * 0.04; var score = Math.floor(game.distance) + game.coins * 10; scoreTxt.setText(score); LK.setScore(score); }; // --- Place runner at correct y --- runner.y = game.runnerY; // --- Place GUI elements --- scoreTxt.x = 1024; scoreTxt.y = 30; coinTxt.y = 30;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Coin class
var Coin = Container.expand(function () {
var self = Container.call(this);
self.lane = 1;
self.collected = false;
// Attach asset
var coinAsset = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 1
});
// Update per frame
self.update = function () {
self.y += game.speed * game.deltaTime;
};
return self;
});
// Obstacle class (train/barrier)
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// lane: 0,1,2
self.lane = 1;
self.type = 'barrier'; // 'train' or 'barrier'
self.passed = false;
// Attach asset
self.setType = function (type) {
self.type = type;
if (self.asset) {
self.removeChild(self.asset);
}
if (type === 'train') {
self.asset = self.attachAsset('train', {
anchorX: 0.5,
anchorY: 1
});
} else {
self.asset = self.attachAsset('barrier', {
anchorX: 0.5,
anchorY: 1
});
}
};
// Update per frame
self.update = function () {
self.y += game.speed * game.deltaTime;
};
return self;
});
// Player character class
var Runner = Container.expand(function () {
var self = Container.call(this);
// Attach runner asset (box, blue)
var runnerAsset = self.attachAsset('runner', {
anchorX: 0.5,
anchorY: 1
});
// Lane index: 0 (left), 1 (center), 2 (right)
self.lane = 1;
self.targetLane = 1;
self.laneX = [game.laneLeftX, game.laneCenterX, game.laneRightX];
// Jumping and ducking state
self.isJumping = false;
self.isDucking = false;
self.jumpStartY = 0;
self.jumpTime = 0;
self.duckTime = 0;
// --- Running animation state ---
self.runAnimTime = 0;
self.runAnimDuration = 600; // ms for a full step cycle (slower bobbing)
self.runAnimAmplitude = 18; // px up/down
self.runAnimSideAmplitude = 7; // px left/right
self.runAnimTween = null;
// Move to lane (with tween)
self.moveToLane = function (lane) {
if (lane < 0) lane = 0;
if (lane > 2) lane = 2;
if (lane !== self.lane) {
self.targetLane = lane;
tween(self, {
x: self.laneX[lane]
}, {
duration: 120,
easing: tween.cubicOut
});
self.lane = lane;
}
};
// Start jump
self.jump = function () {
if (!self.isJumping && !self.isDucking) {
self.isJumping = true;
self.jumpStartY = self.y;
self.jumpTime = 0;
}
};
// Start duck
self.duck = function () {
if (!self.isJumping && !self.isDucking) {
self.isDucking = true;
self.duckTime = 0;
// Shrink runner visually
tween(runnerAsset, {
scaleY: 0.5
}, {
duration: 80,
easing: tween.cubicIn
});
}
};
// Update per frame
self.update = function () {
// --- Running animation (bobbing up/down and slight left/right) ---
if (!self.isJumping && !self.isDucking) {
self.runAnimTime += game.deltaTime;
if (self.runAnimTime > self.runAnimDuration) self.runAnimTime -= self.runAnimDuration;
var t = self.runAnimTime / self.runAnimDuration;
var bobY = Math.sin(t * Math.PI * 2) * self.runAnimAmplitude;
var bobX = Math.sin(t * Math.PI * 4) * self.runAnimSideAmplitude;
runnerAsset.y = bobY;
runnerAsset.x = bobX;
} else {
runnerAsset.y = 0;
runnerAsset.x = 0;
}
// Jumping: simple parabolic jump
if (self.isJumping) {
self.jumpTime += game.deltaTime;
var t = self.jumpTime / game.jumpDuration;
if (t > 1) t = 1;
// Parabola: y = -4h * (t-0.5)^2 + h
var h = game.jumpHeight;
var dy = -4 * h * (t - 0.5) * (t - 0.5) + h;
self.y = self.jumpStartY - dy;
if (t >= 1) {
self.isJumping = false;
self.y = self.jumpStartY;
}
}
// Ducking: stay ducked for duckDuration
if (self.isDucking) {
self.duckTime += game.deltaTime;
if (self.duckTime >= game.duckDuration) {
self.isDucking = false;
// Restore runner scale
tween(runnerAsset, {
scaleY: 1
}, {
duration: 80,
easing: tween.cubicOut
});
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
// No title, no description
backgroundColor: 0x000000
});
/****
* Game Code
****/
// city background image
// --- Game constants ---
game.laneCount = 3;
game.laneWidth = 400;
game.laneLeftX = 524;
game.laneCenterX = 1024;
game.laneRightX = 1524;
game.groundY = 2300;
game.runnerY = game.groundY;
game.jumpHeight = 350;
game.jumpDuration = 700; // ms (increased for longer jump)
game.duckDuration = 600; // ms (increased for longer duck)
game.deltaTime = 16.67; // ms, will be updated per frame
game.speed = 50 / 60; // px per frame (50 px/sec at 60 FPS)
game.speedIncrease = 5 / 60 / (60 * 1000 / 16.67); // px per frame per ms (5 px/minute)
game.maxSpeed = 300 / 60; // cap at 300 px/sec (arbitrary, can be adjusted)
game.spawnTimer = 0;
game.spawnInterval = 900; // ms
game.coinSpawnTimer = 0;
game.coinSpawnInterval = 600; // ms
game.distance = 0;
game.coins = 0;
game.lastTick = Date.now();
// --- Asset initialization (shapes) ---
// Add city background image (behind all gameplay elements)
var cityBg = LK.getAsset('citybg', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2732,
scaleX: 2048 / 1920,
// assuming citybg is 1920x1080, scale to fit width
scaleY: 2732 / 1080 // scale to fit height (portrait)
});
game.addChild(cityBg);
// --- Game objects ---
var runner = new Runner();
runner.x = game.laneCenterX;
runner.y = game.runnerY;
game.addChild(runner);
var obstacles = [];
var coins = [];
// --- GUI ---
var scoreTxt = new Text2('0', {
size: 110,
fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var coinTxt = new Text2('0', {
size: 80,
fill: 0xFFD700
});
coinTxt.anchor.set(0, 0);
coinTxt.x = 120;
coinTxt.y = 0;
LK.gui.top.addChild(coinTxt);
// --- Touch controls (swipe) ---
var touchStartX = 0;
var touchStartY = 0;
var touchStartTime = 0;
var swipeThreshold = 80;
var swipeTime = 350;
// Only allow one swipe per gesture
var swipeUsed = false;
game.down = function (x, y, obj) {
touchStartX = x;
touchStartY = y;
touchStartTime = Date.now();
swipeUsed = false;
};
game.move = function (x, y, obj) {
if (swipeUsed) return;
var dx = x - touchStartX;
var dy = y - touchStartY;
var dt = Date.now() - touchStartTime;
if (dt > swipeTime) return; // Too slow
// Horizontal swipe
if (Math.abs(dx) > swipeThreshold && Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) {
// Swipe right
runner.moveToLane(runner.lane + 1);
} else {
// Swipe left
runner.moveToLane(runner.lane - 1);
}
swipeUsed = true;
}
// Vertical swipe
else if (Math.abs(dy) > swipeThreshold && Math.abs(dy) > Math.abs(dx)) {
if (dy < 0) {
// Swipe up
runner.jump();
} else {
// Swipe down
runner.duck();
}
swipeUsed = true;
}
};
game.up = function (x, y, obj) {
// No-op
};
// --- Main update loop ---
game.update = function () {
// Delta time
var now = Date.now();
game.deltaTime = now - game.lastTick;
if (game.deltaTime > 60) game.deltaTime = 60;
game.lastTick = now;
// Increase speed
if (game.speed < game.maxSpeed) {
game.speed += game.speedIncrease * game.deltaTime;
if (game.speed > game.maxSpeed) game.speed = game.maxSpeed;
}
// Update runner
runner.update();
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.y > 2800) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with runner
if (!obs.passed && obs.lane === runner.lane) {
// Only check if close enough
var obsTop = obs.y - obs.asset.height;
var runnerBottom = runner.y;
var runnerTop = runner.y - runner.height;
// For train: must jump over
if (obs.type === 'train') {
if (!runner.isJumping && runnerBottom > obsTop && runnerTop < obs.y) {
// Collision!
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// For barrier: must duck under
else if (obs.type === 'barrier') {
// Barrier is low, so if not ducking and feet overlap, collision
if (!runner.isDucking && runnerBottom > obsTop && runnerTop < obs.y) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
// If ducking, skip collision (runner passes under barrier)
}
}
}
// Update coins
for (var j = coins.length - 1; j >= 0; j--) {
var coin = coins[j];
coin.update();
// Remove if off screen
if (coin.y > 2800) {
coin.destroy();
coins.splice(j, 1);
continue;
}
// Collect coin
if (!coin.collected && coin.lane === runner.lane) {
var coinTop = coin.y - coin.height;
var runnerBottom = runner.y;
var runnerTop = runner.y - runner.height;
if (runnerBottom > coinTop && runnerTop < coin.y) {
coin.collected = true;
coin.destroy();
coins.splice(j, 1);
game.coins += 1;
coinTxt.setText(game.coins);
}
}
}
// Spawn obstacles
game.spawnTimer += game.deltaTime;
if (game.spawnTimer > game.spawnInterval) {
game.spawnTimer = 0;
// Randomly pick lane and type
var lane = Math.floor(Math.random() * 3);
var type = Math.random() < 0.6 ? 'train' : 'barrier';
var obs = new Obstacle();
obs.lane = lane;
obs.setType(type);
obs.x = [game.laneLeftX, game.laneCenterX, game.laneRightX][lane];
// Spawn obstacles further up (more visible distance)
obs.y = game.groundY - 1800;
game.addChild(obs);
obstacles.push(obs);
}
// Spawn coins further up (more visible distance)
game.coinSpawnTimer += game.deltaTime;
if (game.coinSpawnTimer > game.coinSpawnInterval) {
game.coinSpawnTimer = 0;
var lane = Math.floor(Math.random() * 3);
var coin = new Coin();
coin.lane = lane;
coin.x = [game.laneLeftX, game.laneCenterX, game.laneRightX][lane];
coin.y = game.groundY - 1500;
game.addChild(coin);
coins.push(coin);
}
// Update distance and score
game.distance += game.speed * game.deltaTime * 0.04;
var score = Math.floor(game.distance) + game.coins * 10;
scoreTxt.setText(score);
LK.setScore(score);
};
// --- Place runner at correct y ---
runner.y = game.runnerY;
// --- Place GUI elements ---
scoreTxt.x = 1024;
scoreTxt.y = 30;
coinTxt.y = 30;
kuş bakışı polis ama kuzeye doğru baksın. In-Game asset. 2d. High contrast. No shadows
donat. In-Game asset. 2d. High contrast. No shadows
bariyer. In-Game asset. 2d. High contrast. No shadows
kuş bakışı İçinde hırsız olan araba. In-Game asset. 2d. High contrast. No shadows
şehir resmi binalar. In-Game asset. 2d. High contrast. No shadows
kuş bakışı 3 ayrı yol ve kuş bakışı kenarda binalar . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat