/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy Car Class
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('enemyCar', {
anchorX: 0.5,
anchorY: 0.5
});
// Lane index (0,1,2)
self.lane = 1;
// Speed in px per frame
self.speed = 12;
// Update method called by LK
self.update = function () {
self.y += self.speed * gameSpeed;
};
return self;
});
// Obstacle Class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obs = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Lane index (0,1,2)
self.lane = 1;
// Speed in px per frame
self.speed = 12;
self.update = function () {
self.y += self.speed * gameSpeed;
};
return self;
});
// Player Car Class
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
// Current lane index (0 = left, 1 = center, 2 = right)
self.lane = 1;
// Move to lane with animation
self.moveToLane = function (laneIndex, duration) {
self.lane = laneIndex;
var targetX = getLaneX(laneIndex);
tween(self, {
x: targetX
}, {
duration: duration || 120,
easing: tween.cubicOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Obstacle: yellow ellipse (e.g. traffic cone)
// Enemy car: red box
// Player car: blue box
// Lane setup
var NUM_LANES = 3;
var laneWidth = 410; // 2048 / 5 = ~410, leaves margin on sides
var laneMargin = (2048 - NUM_LANES * laneWidth) / 2; // Center lanes
function getLaneX(laneIndex) {
// Center of each lane
return laneMargin + laneWidth * laneIndex + laneWidth / 2;
}
// Player car setup
var playerCar = new PlayerCar();
playerCar.x = getLaneX(1);
playerCar.y = 2732 - 350;
playerCar.lane = 1;
game.addChild(playerCar);
// Score display
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Game speed
var gameSpeed = 1.0;
var speedIncreaseInterval = 180; // every 3 seconds at 60fps
var speedIncreaseAmount = 0.08;
var maxGameSpeed = 2.8;
// Enemy/obstacle spawn
var enemyCars = [];
var obstacles = [];
var spawnTimer = 0;
var spawnInterval = 60; // frames between spawns (1 sec at 60fps), will decrease as speed increases
var minSpawnInterval = 24; // fastest spawn rate
// Touch/swipe handling
var dragStartX = null;
var dragStartY = null;
var dragActive = false;
var swipeThreshold = 80; // px
// Prevent input in top-left 100x100
function isInMenuArea(x, y) {
return x < 100 && y < 100;
}
// Touch down
game.down = function (x, y, obj) {
if (isInMenuArea(x, y)) return;
dragStartX = x;
dragStartY = y;
dragActive = true;
};
// Touch up
game.up = function (x, y, obj) {
dragStartX = null;
dragStartY = null;
dragActive = false;
};
// Touch move (swipe detection)
game.move = function (x, y, obj) {
if (!dragActive || dragStartX === null) return;
var dx = x - dragStartX;
var dy = y - dragStartY;
// Only consider horizontal swipes, ignore vertical
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > swipeThreshold) {
if (dx < 0 && playerCar.lane > 0) {
// Swipe left
playerCar.moveToLane(playerCar.lane - 1);
} else if (dx > 0 && playerCar.lane < NUM_LANES - 1) {
// Swipe right
playerCar.moveToLane(playerCar.lane + 1);
}
dragActive = false; // Only one move per swipe
}
};
// Helper: spawn enemy or obstacle
function spawnEnemyOrObstacle() {
// Randomly decide: 70% enemy car, 30% obstacle
var isEnemy = Math.random() < 0.7;
var lane = Math.floor(Math.random() * NUM_LANES);
if (isEnemy) {
var enemy = new EnemyCar();
enemy.lane = lane;
enemy.x = getLaneX(lane);
enemy.y = -200;
enemyCars.push(enemy);
game.addChild(enemy);
} else {
var obs = new Obstacle();
obs.lane = lane;
obs.x = getLaneX(lane);
obs.y = -120;
obstacles.push(obs);
game.addChild(obs);
}
}
// Main game update
game.update = function () {
// Increase game speed over time
if (LK.ticks % speedIncreaseInterval === 0 && gameSpeed < maxGameSpeed) {
gameSpeed += speedIncreaseAmount;
if (gameSpeed > maxGameSpeed) gameSpeed = maxGameSpeed;
// Decrease spawn interval as speed increases
spawnInterval = Math.max(minSpawnInterval, 60 - Math.floor((gameSpeed - 1) * 18));
}
// Spawn enemies/obstacles
spawnTimer++;
if (spawnTimer >= spawnInterval) {
spawnEnemyOrObstacle();
spawnTimer = 0;
}
// Update enemy cars
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
enemy.update();
// Collision detection
if (enemy.intersects(playerCar)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
// Passed player (score)
if (!enemy.passed && enemy.y > playerCar.y + 200) {
enemy.passed = true;
score++;
scoreTxt.setText(score);
}
// Remove off-screen
if (enemy.y > 2900) {
enemy.destroy();
enemyCars.splice(i, 1);
}
}
// Update obstacles
for (var j = obstacles.length - 1; j >= 0; j--) {
var obs = obstacles[j];
obs.update();
// Collision detection
if (obs.intersects(playerCar)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
// Passed player (score)
if (!obs.passed && obs.y > playerCar.y + 200) {
obs.passed = true;
score++;
scoreTxt.setText(score);
}
// Remove off-screen
if (obs.y > 2900) {
obs.destroy();
obstacles.splice(j, 1);
}
}
};
// Center score text horizontally
scoreTxt.setText(score);
scoreTxt.anchor.set(0.5, 0);
// Play music (if any, not specified in MVP) ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,234 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Enemy Car Class
+var EnemyCar = Container.expand(function () {
+ var self = Container.call(this);
+ var car = self.attachAsset('enemyCar', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Lane index (0,1,2)
+ self.lane = 1;
+ // Speed in px per frame
+ self.speed = 12;
+ // Update method called by LK
+ self.update = function () {
+ self.y += self.speed * gameSpeed;
+ };
+ return self;
+});
+// Obstacle Class
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var obs = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Lane index (0,1,2)
+ self.lane = 1;
+ // Speed in px per frame
+ self.speed = 12;
+ self.update = function () {
+ self.y += self.speed * gameSpeed;
+ };
+ return self;
+});
+// Player Car Class
+var PlayerCar = Container.expand(function () {
+ var self = Container.call(this);
+ var car = self.attachAsset('playerCar', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Current lane index (0 = left, 1 = center, 2 = right)
+ self.lane = 1;
+ // Move to lane with animation
+ self.moveToLane = function (laneIndex, duration) {
+ self.lane = laneIndex;
+ var targetX = getLaneX(laneIndex);
+ tween(self, {
+ x: targetX
+ }, {
+ duration: duration || 120,
+ easing: tween.cubicOut
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Obstacle: yellow ellipse (e.g. traffic cone)
+// Enemy car: red box
+// Player car: blue box
+// Lane setup
+var NUM_LANES = 3;
+var laneWidth = 410; // 2048 / 5 = ~410, leaves margin on sides
+var laneMargin = (2048 - NUM_LANES * laneWidth) / 2; // Center lanes
+function getLaneX(laneIndex) {
+ // Center of each lane
+ return laneMargin + laneWidth * laneIndex + laneWidth / 2;
+}
+// Player car setup
+var playerCar = new PlayerCar();
+playerCar.x = getLaneX(1);
+playerCar.y = 2732 - 350;
+playerCar.lane = 1;
+game.addChild(playerCar);
+// Score display
+var score = 0;
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Game speed
+var gameSpeed = 1.0;
+var speedIncreaseInterval = 180; // every 3 seconds at 60fps
+var speedIncreaseAmount = 0.08;
+var maxGameSpeed = 2.8;
+// Enemy/obstacle spawn
+var enemyCars = [];
+var obstacles = [];
+var spawnTimer = 0;
+var spawnInterval = 60; // frames between spawns (1 sec at 60fps), will decrease as speed increases
+var minSpawnInterval = 24; // fastest spawn rate
+// Touch/swipe handling
+var dragStartX = null;
+var dragStartY = null;
+var dragActive = false;
+var swipeThreshold = 80; // px
+// Prevent input in top-left 100x100
+function isInMenuArea(x, y) {
+ return x < 100 && y < 100;
+}
+// Touch down
+game.down = function (x, y, obj) {
+ if (isInMenuArea(x, y)) return;
+ dragStartX = x;
+ dragStartY = y;
+ dragActive = true;
+};
+// Touch up
+game.up = function (x, y, obj) {
+ dragStartX = null;
+ dragStartY = null;
+ dragActive = false;
+};
+// Touch move (swipe detection)
+game.move = function (x, y, obj) {
+ if (!dragActive || dragStartX === null) return;
+ var dx = x - dragStartX;
+ var dy = y - dragStartY;
+ // Only consider horizontal swipes, ignore vertical
+ if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > swipeThreshold) {
+ if (dx < 0 && playerCar.lane > 0) {
+ // Swipe left
+ playerCar.moveToLane(playerCar.lane - 1);
+ } else if (dx > 0 && playerCar.lane < NUM_LANES - 1) {
+ // Swipe right
+ playerCar.moveToLane(playerCar.lane + 1);
+ }
+ dragActive = false; // Only one move per swipe
+ }
+};
+// Helper: spawn enemy or obstacle
+function spawnEnemyOrObstacle() {
+ // Randomly decide: 70% enemy car, 30% obstacle
+ var isEnemy = Math.random() < 0.7;
+ var lane = Math.floor(Math.random() * NUM_LANES);
+ if (isEnemy) {
+ var enemy = new EnemyCar();
+ enemy.lane = lane;
+ enemy.x = getLaneX(lane);
+ enemy.y = -200;
+ enemyCars.push(enemy);
+ game.addChild(enemy);
+ } else {
+ var obs = new Obstacle();
+ obs.lane = lane;
+ obs.x = getLaneX(lane);
+ obs.y = -120;
+ obstacles.push(obs);
+ game.addChild(obs);
+ }
+}
+// Main game update
+game.update = function () {
+ // Increase game speed over time
+ if (LK.ticks % speedIncreaseInterval === 0 && gameSpeed < maxGameSpeed) {
+ gameSpeed += speedIncreaseAmount;
+ if (gameSpeed > maxGameSpeed) gameSpeed = maxGameSpeed;
+ // Decrease spawn interval as speed increases
+ spawnInterval = Math.max(minSpawnInterval, 60 - Math.floor((gameSpeed - 1) * 18));
+ }
+ // Spawn enemies/obstacles
+ spawnTimer++;
+ if (spawnTimer >= spawnInterval) {
+ spawnEnemyOrObstacle();
+ spawnTimer = 0;
+ }
+ // Update enemy cars
+ for (var i = enemyCars.length - 1; i >= 0; i--) {
+ var enemy = enemyCars[i];
+ enemy.update();
+ // Collision detection
+ if (enemy.intersects(playerCar)) {
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ }
+ // Passed player (score)
+ if (!enemy.passed && enemy.y > playerCar.y + 200) {
+ enemy.passed = true;
+ score++;
+ scoreTxt.setText(score);
+ }
+ // Remove off-screen
+ if (enemy.y > 2900) {
+ enemy.destroy();
+ enemyCars.splice(i, 1);
+ }
+ }
+ // Update obstacles
+ for (var j = obstacles.length - 1; j >= 0; j--) {
+ var obs = obstacles[j];
+ obs.update();
+ // Collision detection
+ if (obs.intersects(playerCar)) {
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ }
+ // Passed player (score)
+ if (!obs.passed && obs.y > playerCar.y + 200) {
+ obs.passed = true;
+ score++;
+ scoreTxt.setText(score);
+ }
+ // Remove off-screen
+ if (obs.y > 2900) {
+ obs.destroy();
+ obstacles.splice(j, 1);
+ }
+ }
+};
+// Center score text horizontally
+scoreTxt.setText(score);
+scoreTxt.anchor.set(0.5, 0);
+// Play music (if any, not specified in MVP)
\ No newline at end of file