/**** * 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 = 10; // 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 (default car) 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 () { // Track lastY for scoring if (self.lastY === undefined) self.lastY = self.y; self.y += roadSpeed; // No score for passing obstacles; scoring is handled by collecting boosts. self.lastY = self.y; }; return self; }); // Motorcycle obstacle var ObstacleMotorcycle = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle_motorcycle', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.update = function () { if (self.lastY === undefined) self.lastY = self.y; self.y += roadSpeed; self.lastY = self.y; }; return self; }); // Sports car obstacle var ObstacleSportsCar = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle_sportscar', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.update = function () { if (self.lastY === undefined) self.lastY = self.y; self.y += roadSpeed; self.lastY = self.y; }; return self; }); // Truck obstacle var ObstacleTruck = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle_truck', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.update = function () { if (self.lastY === undefined) self.lastY = self.y; self.y += roadSpeed; self.lastY = self.y; }; return self; }); // Van obstacle var ObstacleVan = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle_van', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; self.update = function () { if (self.lastY === undefined) self.lastY = self.y; self.y += roadSpeed; self.lastY = self.y; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Lane marker // Road // Speed boost // Obstacle // Car (player) // Play start sound at the very beginning of the game LK.getSound('Arabasssw').play(); // 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 = 10; var roadSpeedBase = 10; var roadSpeedBoosted = 24; 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); // Randomly select one of five obstacle types var type = Math.floor(Math.random() * 5); var obs; if (type === 0) { obs = new Obstacle(); // default car } else if (type === 1) { obs = new ObstacleTruck(); } else if (type === 2) { obs = new ObstacleMotorcycle(); } else if (type === 3) { obs = new ObstacleSportsCar(); } else { obs = new ObstacleVan(); } 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); // Add score for collecting boost score += 100; scoreTxt.setText(score); // 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(); } // Score is only updated by collecting boosts. // 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 () { // Play start sound LK.getSound('Arabasssw').play(); // 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; scoreTxt.setText(score); roadSpeed = roadSpeedBase; boostTicks = 0; // Reset lane markers spawnLaneMarkers(); });
===================================================================
--- original.js
+++ change.js
@@ -164,8 +164,10 @@
// Road
// Speed boost
// Obstacle
// Car (player)
+// Play start sound at the very beginning of the game
+LK.getSound('Arabasssw').play();
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var ROAD_WIDTH = 900;