/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Boost class var Boost = Container.expand(function () { var self = Container.call(this); var boostAsset = self.attachAsset('boost', { anchorX: 0.5, anchorY: 0.5 }); self.width = boostAsset.width; self.height = boostAsset.height; self.update = function () { self.y += roadSpeed; }; return self; }); // Car class var Car = Container.expand(function () { var self = Container.call(this); var carAsset = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); // For collision, use the container itself self.width = carAsset.width; self.height = carAsset.height; // Car speed (pixels per tick) self.speed = 18; // Lateral speed (for smooth steering) self.lateralSpeed = 0; // Max lateral speed self.maxLateralSpeed = 32; // Steering target (x position) self.targetX = self.x; // Update method self.update = function () { // Smoothly move towards targetX var dx = self.targetX - self.x; if (Math.abs(dx) > 2) { self.lateralSpeed = Math.max(-self.maxLateralSpeed, Math.min(self.maxLateralSpeed, dx * 0.25)); self.x += self.lateralSpeed; } else { self.lateralSpeed = 0; self.x = self.targetX; } }; return self; }); // Lane marker class var Lane = Container.expand(function () { var self = Container.call(this); var laneAsset = self.attachAsset('lane', { anchorX: 0.5, anchorY: 0.5 }); self.width = laneAsset.width; self.height = laneAsset.height; self.update = function () { self.y += roadSpeed; }; return self; }); // Obstacle class 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; // Update method: move down by road speed self.update = function () { self.y += roadSpeed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Lane marker // Road // Speed boost // Obstacle // Car (player) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var ROAD_WIDTH = 900; var ROAD_X = (GAME_WIDTH - ROAD_WIDTH) / 2; var ROAD_Y = 0; var LANE_COUNT = 3; var LANE_WIDTH = ROAD_WIDTH / LANE_COUNT; var CAR_START_X = GAME_WIDTH / 2; var CAR_START_Y = GAME_HEIGHT - 500; var OBSTACLE_MIN_GAP = 600; var OBSTACLE_MAX_GAP = 1100; var BOOST_CHANCE = 0.25; // 25% chance to spawn a boost with an obstacle // Road speed (pixels per tick) var roadSpeed = 18; var roadSpeedBase = 18; var roadSpeedBoosted = 32; var boostDuration = 90; // ticks (1.5 seconds) var boostTicks = 0; // Score var score = 0; // Arrays for game objects var obstacles = []; var boosts = []; var lanes = []; // Road background var road = LK.getAsset('road', { anchorX: 0, anchorY: 0, x: ROAD_X, y: ROAD_Y }); game.addChild(road); // Lane markers function spawnLaneMarkers() { // Remove old lanes for (var i = 0; i < lanes.length; i++) { lanes[i].destroy(); } lanes = []; // For each lane (except the leftmost), draw a marker for (var l = 1; l < LANE_COUNT; l++) { for (var y = -200; y < GAME_HEIGHT + 200; y += 400) { var lane = new Lane(); lane.x = ROAD_X + l * LANE_WIDTH; lane.y = y; lanes.push(lane); game.addChild(lane); } } } spawnLaneMarkers(); // Car (player) var car = new Car(); car.x = CAR_START_X; car.y = CAR_START_Y; car.targetX = car.x; game.addChild(car); // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Helper: get lane center x function getLaneCenter(laneIdx) { return ROAD_X + LANE_WIDTH * (laneIdx + 0.5); } // Helper: spawn an obstacle (and maybe a boost) function spawnObstacle() { // Random lane var laneIdx = Math.floor(Math.random() * LANE_COUNT); var obs = new Obstacle(); obs.x = getLaneCenter(laneIdx); obs.y = -obs.height / 2; obstacles.push(obs); game.addChild(obs); // Maybe spawn a boost in a different lane if (Math.random() < BOOST_CHANCE) { var boostLane = laneIdx; // Try to pick a different lane if (LANE_COUNT > 1) { while (boostLane === laneIdx) { boostLane = Math.floor(Math.random() * LANE_COUNT); } } var boost = new Boost(); boost.x = getLaneCenter(boostLane); boost.y = obs.y; boosts.push(boost); game.addChild(boost); } } // Helper: spawn lane markers as they scroll function updateLaneMarkers() { for (var i = lanes.length - 1; i >= 0; i--) { var lane = lanes[i]; lane.update(); if (lane.y > GAME_HEIGHT + 200) { // Recycle to top lane.y -= GAME_HEIGHT + 400; } } } // Dragging var dragging = false; var dragOffsetX = 0; // Touch/mouse controls game.down = function (x, y, obj) { // Only allow drag if touch is on car or on road if (x > ROAD_X && x < ROAD_X + ROAD_WIDTH && y > 0 && y < GAME_HEIGHT) { dragging = true; dragOffsetX = x - car.x; // Set targetX immediately car.targetX = Math.max(ROAD_X + car.width / 2, Math.min(ROAD_X + ROAD_WIDTH - car.width / 2, x - dragOffsetX)); } }; game.up = function (x, y, obj) { dragging = false; }; game.move = function (x, y, obj) { if (dragging) { // Clamp to road var tx = Math.max(ROAD_X + car.width / 2, Math.min(ROAD_X + ROAD_WIDTH - car.width / 2, x - dragOffsetX)); car.targetX = tx; } }; // Game update var lastObstacleY = -OBSTACLE_MIN_GAP; game.update = function () { // Update car car.update(); // Update lane markers updateLaneMarkers(); // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y - obs.height / 2 > GAME_HEIGHT + 100) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with car if (car.intersects(obs)) { // Flash screen red, game over LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } // Update boosts for (var i = boosts.length - 1; i >= 0; i--) { var boost = boosts[i]; boost.update(); // Remove if off screen if (boost.y - boost.height / 2 > GAME_HEIGHT + 100) { boost.destroy(); boosts.splice(i, 1); continue; } // Collect boost if (car.intersects(boost)) { boost.destroy(); boosts.splice(i, 1); // Activate speed boost boostTicks = boostDuration; roadSpeed = roadSpeedBoosted; // Flash car yellow LK.effects.flashObject(car, 0xffeb3b, 400); } } // Handle boost timer if (boostTicks > 0) { boostTicks--; if (boostTicks === 0) { roadSpeed = roadSpeedBase; } } // Spawn new obstacles if (obstacles.length === 0 || obstacles[obstacles.length - 1].y > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) { spawnObstacle(); } // Update score: based on distance survived score += Math.floor(roadSpeed / 4); scoreTxt.setText(score); // Check if car is off the road if (car.x - car.width / 2 < ROAD_X || car.x + car.width / 2 > ROAD_X + ROAD_WIDTH) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } }; // Reset game state on new game LK.on('gameStart', function () { // Remove all obstacles and boosts for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy(); for (var i = 0; i < boosts.length; i++) boosts[i].destroy(); obstacles = []; boosts = []; // Reset car position car.x = CAR_START_X; car.y = CAR_START_Y; car.targetX = car.x; // Reset score and speed score = 0; roadSpeed = roadSpeedBase; boostTicks = 0; scoreTxt.setText(score); // Reset lane markers spawnLaneMarkers(); });
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,313 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Boost class
+var Boost = Container.expand(function () {
+ var self = Container.call(this);
+ var boostAsset = self.attachAsset('boost', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = boostAsset.width;
+ self.height = boostAsset.height;
+ self.update = function () {
+ self.y += roadSpeed;
+ };
+ return self;
+});
+// Car class
+var Car = Container.expand(function () {
+ var self = Container.call(this);
+ var carAsset = self.attachAsset('car', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // For collision, use the container itself
+ self.width = carAsset.width;
+ self.height = carAsset.height;
+ // Car speed (pixels per tick)
+ self.speed = 18;
+ // Lateral speed (for smooth steering)
+ self.lateralSpeed = 0;
+ // Max lateral speed
+ self.maxLateralSpeed = 32;
+ // Steering target (x position)
+ self.targetX = self.x;
+ // Update method
+ self.update = function () {
+ // Smoothly move towards targetX
+ var dx = self.targetX - self.x;
+ if (Math.abs(dx) > 2) {
+ self.lateralSpeed = Math.max(-self.maxLateralSpeed, Math.min(self.maxLateralSpeed, dx * 0.25));
+ self.x += self.lateralSpeed;
+ } else {
+ self.lateralSpeed = 0;
+ self.x = self.targetX;
+ }
+ };
+ return self;
+});
+// Lane marker class
+var Lane = Container.expand(function () {
+ var self = Container.call(this);
+ var laneAsset = self.attachAsset('lane', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = laneAsset.width;
+ self.height = laneAsset.height;
+ self.update = function () {
+ self.y += roadSpeed;
+ };
+ return self;
+});
+// Obstacle class
+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;
+ // Update method: move down by road speed
+ self.update = function () {
+ self.y += roadSpeed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Lane marker
+// Road
+// Speed boost
+// Obstacle
+// Car (player)
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var ROAD_WIDTH = 900;
+var ROAD_X = (GAME_WIDTH - ROAD_WIDTH) / 2;
+var ROAD_Y = 0;
+var LANE_COUNT = 3;
+var LANE_WIDTH = ROAD_WIDTH / LANE_COUNT;
+var CAR_START_X = GAME_WIDTH / 2;
+var CAR_START_Y = GAME_HEIGHT - 500;
+var OBSTACLE_MIN_GAP = 600;
+var OBSTACLE_MAX_GAP = 1100;
+var BOOST_CHANCE = 0.25; // 25% chance to spawn a boost with an obstacle
+// Road speed (pixels per tick)
+var roadSpeed = 18;
+var roadSpeedBase = 18;
+var roadSpeedBoosted = 32;
+var boostDuration = 90; // ticks (1.5 seconds)
+var boostTicks = 0;
+// Score
+var score = 0;
+// Arrays for game objects
+var obstacles = [];
+var boosts = [];
+var lanes = [];
+// Road background
+var road = LK.getAsset('road', {
+ anchorX: 0,
+ anchorY: 0,
+ x: ROAD_X,
+ y: ROAD_Y
+});
+game.addChild(road);
+// Lane markers
+function spawnLaneMarkers() {
+ // Remove old lanes
+ for (var i = 0; i < lanes.length; i++) {
+ lanes[i].destroy();
+ }
+ lanes = [];
+ // For each lane (except the leftmost), draw a marker
+ for (var l = 1; l < LANE_COUNT; l++) {
+ for (var y = -200; y < GAME_HEIGHT + 200; y += 400) {
+ var lane = new Lane();
+ lane.x = ROAD_X + l * LANE_WIDTH;
+ lane.y = y;
+ lanes.push(lane);
+ game.addChild(lane);
+ }
+ }
+}
+spawnLaneMarkers();
+// Car (player)
+var car = new Car();
+car.x = CAR_START_X;
+car.y = CAR_START_Y;
+car.targetX = car.x;
+game.addChild(car);
+// Score text
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Helper: get lane center x
+function getLaneCenter(laneIdx) {
+ return ROAD_X + LANE_WIDTH * (laneIdx + 0.5);
+}
+// Helper: spawn an obstacle (and maybe a boost)
+function spawnObstacle() {
+ // Random lane
+ var laneIdx = Math.floor(Math.random() * LANE_COUNT);
+ var obs = new Obstacle();
+ obs.x = getLaneCenter(laneIdx);
+ obs.y = -obs.height / 2;
+ obstacles.push(obs);
+ game.addChild(obs);
+ // Maybe spawn a boost in a different lane
+ if (Math.random() < BOOST_CHANCE) {
+ var boostLane = laneIdx;
+ // Try to pick a different lane
+ if (LANE_COUNT > 1) {
+ while (boostLane === laneIdx) {
+ boostLane = Math.floor(Math.random() * LANE_COUNT);
+ }
+ }
+ var boost = new Boost();
+ boost.x = getLaneCenter(boostLane);
+ boost.y = obs.y;
+ boosts.push(boost);
+ game.addChild(boost);
+ }
+}
+// Helper: spawn lane markers as they scroll
+function updateLaneMarkers() {
+ for (var i = lanes.length - 1; i >= 0; i--) {
+ var lane = lanes[i];
+ lane.update();
+ if (lane.y > GAME_HEIGHT + 200) {
+ // Recycle to top
+ lane.y -= GAME_HEIGHT + 400;
+ }
+ }
+}
+// Dragging
+var dragging = false;
+var dragOffsetX = 0;
+// Touch/mouse controls
+game.down = function (x, y, obj) {
+ // Only allow drag if touch is on car or on road
+ if (x > ROAD_X && x < ROAD_X + ROAD_WIDTH && y > 0 && y < GAME_HEIGHT) {
+ dragging = true;
+ dragOffsetX = x - car.x;
+ // Set targetX immediately
+ car.targetX = Math.max(ROAD_X + car.width / 2, Math.min(ROAD_X + ROAD_WIDTH - car.width / 2, x - dragOffsetX));
+ }
+};
+game.up = function (x, y, obj) {
+ dragging = false;
+};
+game.move = function (x, y, obj) {
+ if (dragging) {
+ // Clamp to road
+ var tx = Math.max(ROAD_X + car.width / 2, Math.min(ROAD_X + ROAD_WIDTH - car.width / 2, x - dragOffsetX));
+ car.targetX = tx;
+ }
+};
+// Game update
+var lastObstacleY = -OBSTACLE_MIN_GAP;
+game.update = function () {
+ // Update car
+ car.update();
+ // Update lane markers
+ updateLaneMarkers();
+ // Update obstacles
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obs = obstacles[i];
+ obs.update();
+ // Remove if off screen
+ if (obs.y - obs.height / 2 > GAME_HEIGHT + 100) {
+ obs.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ // Collision with car
+ if (car.intersects(obs)) {
+ // Flash screen red, game over
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Update boosts
+ for (var i = boosts.length - 1; i >= 0; i--) {
+ var boost = boosts[i];
+ boost.update();
+ // Remove if off screen
+ if (boost.y - boost.height / 2 > GAME_HEIGHT + 100) {
+ boost.destroy();
+ boosts.splice(i, 1);
+ continue;
+ }
+ // Collect boost
+ if (car.intersects(boost)) {
+ boost.destroy();
+ boosts.splice(i, 1);
+ // Activate speed boost
+ boostTicks = boostDuration;
+ roadSpeed = roadSpeedBoosted;
+ // Flash car yellow
+ LK.effects.flashObject(car, 0xffeb3b, 400);
+ }
+ }
+ // Handle boost timer
+ if (boostTicks > 0) {
+ boostTicks--;
+ if (boostTicks === 0) {
+ roadSpeed = roadSpeedBase;
+ }
+ }
+ // Spawn new obstacles
+ if (obstacles.length === 0 || obstacles[obstacles.length - 1].y > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
+ spawnObstacle();
+ }
+ // Update score: based on distance survived
+ score += Math.floor(roadSpeed / 4);
+ scoreTxt.setText(score);
+ // Check if car is off the road
+ if (car.x - car.width / 2 < ROAD_X || car.x + car.width / 2 > ROAD_X + ROAD_WIDTH) {
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ }
+};
+// Reset game state on new game
+LK.on('gameStart', function () {
+ // Remove all obstacles and boosts
+ for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy();
+ for (var i = 0; i < boosts.length; i++) boosts[i].destroy();
+ obstacles = [];
+ boosts = [];
+ // Reset car position
+ car.x = CAR_START_X;
+ car.y = CAR_START_Y;
+ car.targetX = car.x;
+ // Reset score and speed
+ score = 0;
+ roadSpeed = roadSpeedBase;
+ boostTicks = 0;
+ scoreTxt.setText(score);
+ // Reset lane markers
+ spawnLaneMarkers();
});
\ No newline at end of file