/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Obstacle var Obstacle = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.speed = 0; self.lane = 1; self.update = function () { self.y += self.speed; }; return self; }); // Player Car var PlayerCar = Container.expand(function () { var self = Container.call(this); var carAsset = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); self.width = carAsset.width; self.height = carAsset.height; self.lane = 1; // 0: left, 1: center, 2: right self.invincible = false; self.invincibleTimer = 0; // Flash effect for invincibility self.setInvincible = function (duration) { self.invincible = true; self.invincibleTimer = LK.ticks + Math.floor(duration * 60 / 1000); tween(self, { alpha: 0.5 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 100, easing: tween.linear }); } }); }; self.update = function () { if (self.invincible && LK.ticks > self.invincibleTimer) { self.invincible = false; self.alpha = 1; } }; return self; }); // PowerUp var PowerUp = Container.expand(function () { var self = Container.call(this); var puAsset = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.width = puAsset.width; self.height = puAsset.height; self.speed = 0; self.lane = 1; self.update = function () { self.y += self.speed; }; return self; }); // Rival Car var RivalCar = Container.expand(function () { var self = Container.call(this); var rivalAsset = self.attachAsset('rival', { anchorX: 0.5, anchorY: 0.5 }); self.width = rivalAsset.width; self.height = rivalAsset.height; self.speed = 0; self.lane = 1; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Road lane // Power-up (star) // Obstacle (barrier) // Rival car // Car (player) // Lane positions (3 lanes) var laneCount = 3; var laneWidth = 400; var laneX = [2048 / 2 - laneWidth, // left 2048 / 2, // center 2048 / 2 + laneWidth // right ]; // Draw road lanes (visual only) for (var i = 0; i < laneCount + 1; i++) { var laneLine = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, x: 2048 / 2 - laneWidth * 1.5 + i * laneWidth, y: 0, scaleY: 7 }); laneLine.alpha = 0.2; game.addChild(laneLine); } // Player car var player = new PlayerCar(); player.x = laneX[1]; player.y = 2732 - 400; player.lane = 1; game.addChild(player); // Score var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Power-up timer text var powerupTxt = new Text2('', { size: 70, fill: 0xFFE082 }); powerupTxt.anchor.set(0.5, 0); LK.gui.top.addChild(powerupTxt); powerupTxt.y = 130; // Game state var rivals = []; var obstacles = []; var powerups = []; var gameSpeed = 18; // pixels per frame var spawnTimer = 0; var powerupActive = false; var powerupEndTick = 0; var dragNode = null; var lastTouchX = 0; // Helper: Clamp lane function clampLane(lane) { if (lane < 0) return 0; if (lane > laneCount - 1) return laneCount - 1; return lane; } // Helper: Move player to x function movePlayerToX(x) { // Find closest lane var minDist = 99999; var bestLane = 1; for (var i = 0; i < laneCount; i++) { var dist = Math.abs(x - laneX[i]); if (dist < minDist) { minDist = dist; bestLane = i; } } player.lane = bestLane; // Tween to lane center tween.stop(player, { x: true }); tween(player, { x: laneX[bestLane] }, { duration: 120, easing: tween.cubicOut }); } // Touch/drag controls game.down = function (x, y, obj) { // Only allow drag if touch is on player car or below it if (y >= player.y - player.height / 2 && y <= player.y + player.height / 2) { dragNode = player; lastTouchX = x; } }; game.move = function (x, y, obj) { if (dragNode === player) { // Move car horizontally, snap to nearest lane movePlayerToX(x); lastTouchX = x; } }; game.up = function (x, y, obj) { dragNode = null; }; // Spawning logic function spawnRival() { var rival = new RivalCar(); rival.lane = Math.floor(Math.random() * laneCount); rival.x = laneX[rival.lane]; rival.y = -rival.height; rival.speed = gameSpeed + Math.random() * 4; rivals.push(rival); game.addChild(rival); } function spawnObstacle() { var obs = new Obstacle(); obs.lane = Math.floor(Math.random() * laneCount); obs.x = laneX[obs.lane]; obs.y = -obs.height; obs.speed = gameSpeed; obstacles.push(obs); game.addChild(obs); } function spawnPowerUp() { var pu = new PowerUp(); pu.lane = Math.floor(Math.random() * laneCount); pu.x = laneX[pu.lane]; pu.y = -pu.height; pu.speed = gameSpeed; powerups.push(pu); game.addChild(pu); } // Main update loop game.update = function () { // Increase score over time if (LK.ticks % 6 === 0) { score += 1; scoreTxt.setText(score); } // Power-up timer if (powerupActive) { var ticksLeft = powerupEndTick - LK.ticks; if (ticksLeft > 0) { powerupTxt.setText('Invincible: ' + Math.ceil(ticksLeft / 60) + 's'); } else { powerupActive = false; player.invincible = false; player.alpha = 1; powerupTxt.setText(''); } } // Player update (invincibility) player.update(); // Spawn rivals, obstacles, powerups if (spawnTimer <= 0) { var r = Math.random(); if (r < 0.45) { spawnRival(); } else if (r < 0.8) { spawnObstacle(); } else { spawnPowerUp(); } spawnTimer = 36 + Math.floor(Math.random() * 30); // ~0.6s } else { spawnTimer--; } // Update rivals for (var i = rivals.length - 1; i >= 0; i--) { var rival = rivals[i]; rival.update(); // Remove if off screen if (rival.y > 2732 + rival.height) { rival.destroy(); rivals.splice(i, 1); continue; } // Collision with player if (rival.intersects(player)) { if (!player.invincible) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } else { // Remove rival rival.destroy(); rivals.splice(i, 1); continue; } } } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); if (obs.y > 2732 + obs.height) { obs.destroy(); obstacles.splice(i, 1); continue; } if (obs.intersects(player)) { if (!player.invincible) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } else { obs.destroy(); obstacles.splice(i, 1); continue; } } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var pu = powerups[i]; pu.update(); if (pu.y > 2732 + pu.height) { pu.destroy(); powerups.splice(i, 1); continue; } if (pu.intersects(player)) { // Activate invincibility for 3 seconds powerupActive = true; powerupEndTick = LK.ticks + 180; player.setInvincible(3000); powerupTxt.setText('Invincible: 3s'); pu.destroy(); powerups.splice(i, 1); continue; } } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,341 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Obstacle
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var obsAsset = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = obsAsset.width;
+ self.height = obsAsset.height;
+ self.speed = 0;
+ self.lane = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player Car
+var PlayerCar = Container.expand(function () {
+ var self = Container.call(this);
+ var carAsset = self.attachAsset('car', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = carAsset.width;
+ self.height = carAsset.height;
+ self.lane = 1; // 0: left, 1: center, 2: right
+ self.invincible = false;
+ self.invincibleTimer = 0;
+ // Flash effect for invincibility
+ self.setInvincible = function (duration) {
+ self.invincible = true;
+ self.invincibleTimer = LK.ticks + Math.floor(duration * 60 / 1000);
+ tween(self, {
+ alpha: 0.5
+ }, {
+ duration: 100,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ tween(self, {
+ alpha: 1
+ }, {
+ duration: 100,
+ easing: tween.linear
+ });
+ }
+ });
+ };
+ self.update = function () {
+ if (self.invincible && LK.ticks > self.invincibleTimer) {
+ self.invincible = false;
+ self.alpha = 1;
+ }
+ };
+ return self;
+});
+// PowerUp
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var puAsset = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = puAsset.width;
+ self.height = puAsset.height;
+ self.speed = 0;
+ self.lane = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Rival Car
+var RivalCar = Container.expand(function () {
+ var self = Container.call(this);
+ var rivalAsset = self.attachAsset('rival', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = rivalAsset.width;
+ self.height = rivalAsset.height;
+ self.speed = 0;
+ self.lane = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Road lane
+// Power-up (star)
+// Obstacle (barrier)
+// Rival car
+// Car (player)
+// Lane positions (3 lanes)
+var laneCount = 3;
+var laneWidth = 400;
+var laneX = [2048 / 2 - laneWidth,
+// left
+2048 / 2,
+// center
+2048 / 2 + laneWidth // right
+];
+// Draw road lanes (visual only)
+for (var i = 0; i < laneCount + 1; i++) {
+ var laneLine = LK.getAsset('lane', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 2048 / 2 - laneWidth * 1.5 + i * laneWidth,
+ y: 0,
+ scaleY: 7
+ });
+ laneLine.alpha = 0.2;
+ game.addChild(laneLine);
+}
+// Player car
+var player = new PlayerCar();
+player.x = laneX[1];
+player.y = 2732 - 400;
+player.lane = 1;
+game.addChild(player);
+// Score
+var score = 0;
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Power-up timer text
+var powerupTxt = new Text2('', {
+ size: 70,
+ fill: 0xFFE082
+});
+powerupTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(powerupTxt);
+powerupTxt.y = 130;
+// Game state
+var rivals = [];
+var obstacles = [];
+var powerups = [];
+var gameSpeed = 18; // pixels per frame
+var spawnTimer = 0;
+var powerupActive = false;
+var powerupEndTick = 0;
+var dragNode = null;
+var lastTouchX = 0;
+// Helper: Clamp lane
+function clampLane(lane) {
+ if (lane < 0) return 0;
+ if (lane > laneCount - 1) return laneCount - 1;
+ return lane;
+}
+// Helper: Move player to x
+function movePlayerToX(x) {
+ // Find closest lane
+ var minDist = 99999;
+ var bestLane = 1;
+ for (var i = 0; i < laneCount; i++) {
+ var dist = Math.abs(x - laneX[i]);
+ if (dist < minDist) {
+ minDist = dist;
+ bestLane = i;
+ }
+ }
+ player.lane = bestLane;
+ // Tween to lane center
+ tween.stop(player, {
+ x: true
+ });
+ tween(player, {
+ x: laneX[bestLane]
+ }, {
+ duration: 120,
+ easing: tween.cubicOut
+ });
+}
+// Touch/drag controls
+game.down = function (x, y, obj) {
+ // Only allow drag if touch is on player car or below it
+ if (y >= player.y - player.height / 2 && y <= player.y + player.height / 2) {
+ dragNode = player;
+ lastTouchX = x;
+ }
+};
+game.move = function (x, y, obj) {
+ if (dragNode === player) {
+ // Move car horizontally, snap to nearest lane
+ movePlayerToX(x);
+ lastTouchX = x;
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Spawning logic
+function spawnRival() {
+ var rival = new RivalCar();
+ rival.lane = Math.floor(Math.random() * laneCount);
+ rival.x = laneX[rival.lane];
+ rival.y = -rival.height;
+ rival.speed = gameSpeed + Math.random() * 4;
+ rivals.push(rival);
+ game.addChild(rival);
+}
+function spawnObstacle() {
+ var obs = new Obstacle();
+ obs.lane = Math.floor(Math.random() * laneCount);
+ obs.x = laneX[obs.lane];
+ obs.y = -obs.height;
+ obs.speed = gameSpeed;
+ obstacles.push(obs);
+ game.addChild(obs);
+}
+function spawnPowerUp() {
+ var pu = new PowerUp();
+ pu.lane = Math.floor(Math.random() * laneCount);
+ pu.x = laneX[pu.lane];
+ pu.y = -pu.height;
+ pu.speed = gameSpeed;
+ powerups.push(pu);
+ game.addChild(pu);
+}
+// Main update loop
+game.update = function () {
+ // Increase score over time
+ if (LK.ticks % 6 === 0) {
+ score += 1;
+ scoreTxt.setText(score);
+ }
+ // Power-up timer
+ if (powerupActive) {
+ var ticksLeft = powerupEndTick - LK.ticks;
+ if (ticksLeft > 0) {
+ powerupTxt.setText('Invincible: ' + Math.ceil(ticksLeft / 60) + 's');
+ } else {
+ powerupActive = false;
+ player.invincible = false;
+ player.alpha = 1;
+ powerupTxt.setText('');
+ }
+ }
+ // Player update (invincibility)
+ player.update();
+ // Spawn rivals, obstacles, powerups
+ if (spawnTimer <= 0) {
+ var r = Math.random();
+ if (r < 0.45) {
+ spawnRival();
+ } else if (r < 0.8) {
+ spawnObstacle();
+ } else {
+ spawnPowerUp();
+ }
+ spawnTimer = 36 + Math.floor(Math.random() * 30); // ~0.6s
+ } else {
+ spawnTimer--;
+ }
+ // Update rivals
+ for (var i = rivals.length - 1; i >= 0; i--) {
+ var rival = rivals[i];
+ rival.update();
+ // Remove if off screen
+ if (rival.y > 2732 + rival.height) {
+ rival.destroy();
+ rivals.splice(i, 1);
+ continue;
+ }
+ // Collision with player
+ if (rival.intersects(player)) {
+ if (!player.invincible) {
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ } else {
+ // Remove rival
+ rival.destroy();
+ rivals.splice(i, 1);
+ continue;
+ }
+ }
+ }
+ // Update obstacles
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obs = obstacles[i];
+ obs.update();
+ if (obs.y > 2732 + obs.height) {
+ obs.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ if (obs.intersects(player)) {
+ if (!player.invincible) {
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ } else {
+ obs.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ }
+ }
+ // Update powerups
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ var pu = powerups[i];
+ pu.update();
+ if (pu.y > 2732 + pu.height) {
+ pu.destroy();
+ powerups.splice(i, 1);
+ continue;
+ }
+ if (pu.intersects(player)) {
+ // Activate invincibility for 3 seconds
+ powerupActive = true;
+ powerupEndTick = LK.ticks + 180;
+ player.setInvincible(3000);
+ powerupTxt.setText('Invincible: 3s');
+ pu.destroy();
+ powerups.splice(i, 1);
+ continue;
+ }
+ }
+};
\ No newline at end of file