User prompt
Increase the size you can click for up and down movement
User prompt
Increase the side of the range to click for left movement
User prompt
Increase the range of where you can click for up and down movement
User prompt
Make the range of the left and right button presses bigger
User prompt
Make it so the tap doesn’t have to be directly in line with the player, but just in the general direction
User prompt
Make it so if I tap in any direction of the player it moves 1 in that direction including up and down replace the old movement code
User prompt
Replace the swipe to move with a tap to move system
User prompt
Make it so if the player moves it does a a split second delay before it can be moved again
User prompt
Can you make a slight delay after each input before another input is pressed
User prompt
Redo the code for player movement
User prompt
Please fix the bug: 'Can't find variable: btnRight' in or related to this line: 'btnRight.visible = true;' Line Number: 153
User prompt
Show the buttons
User prompt
Make buttons using assets that when pressed control the movement of the player
User prompt
Make buttons for the movement
User prompt
Make the buttons show
User prompt
Make the player controlled using buttons
User prompt
Make the lower land go even lower
User prompt
Move the collectables and the enemies slightly down
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'player.visual.parent.addChild')' in or related to this line: 'player.visual.parent.addChild(player.visual);' Line Number: 472
User prompt
Make it so the player blocks the view of the enemies and collectables instead of them blocking the view of the player
User prompt
Make the player visual use an asset
User prompt
Change the controls so it uses 4 buttons to control it
User prompt
Make the up and down controls less sensitive
User prompt
Make it 6 lanes by adding a up and down feature
User prompt
Add a visual representation of where the player is
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Represents a single collectible in the corridor var Collectible = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('collectible', { anchorX: 0.5, anchorY: 1 }); self.lane = 1; self.depth = 0; self.type = 'collectible'; self.active = true; self.getHitbox = function () { return { x: self.x - sprite.width / 2, y: self.y - sprite.height, w: sprite.width, h: sprite.height }; }; return self; }); // Represents a single obstacle in the corridor var Obstacle = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 1 }); // Logical position in corridor space self.lane = 1; // 0=left, 1=center, 2=right self.depth = 0; // Distance from player (z) self.type = 'obstacle'; self.active = true; // For collision detection self.getHitbox = function () { // Returns {x, y, w, h} in screen space return { x: self.x - sprite.width / 2, y: self.y - sprite.height, w: sprite.width, h: sprite.height }; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Raycasting & Corridor Parameters --- // Corridor wall slice (vertical rectangle, will be stretched/scaled for perspective) // Floor slice (horizontal rectangle, will be stretched/scaled for perspective) // Ceiling slice (horizontal rectangle, will be stretched/scaled for perspective) // Obstacle (box) // Collectible (ellipse) var corridor = { width: 3, // 3 lanes: 0=left, 1=center, 2=right laneWidth: 700, // virtual lane width in world units (increased for bigger lanes) depthSlices: 16, // how many slices to render for perspective maxDepth: 16, // how far to render (in slices) fov: Math.PI / 3, // 60 deg field of view wallColor: 0x4444aa, floorColor: 0x222222, ceilingColor: 0x111133 }; // Player state var player = { lane: 1, // 0=left, 1=center, 2=right moving: false, moveTarget: 1, // target lane moveTween: null, alive: true }; // Game state var speed = 0.18; // units per frame (z axis) var speedIncrease = 0.00004; // per frame var maxSpeed = 0.38; var objects = []; // all obstacles and collectibles var spawnTimer = 0; var spawnInterval = 38; // frames between spawns var score = 0; var distance = 0; // how far player has run (for difficulty) var lastTouchX = null; // --- GUI --- var scoreTxt = new Text2('0', { size: 220, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var distTxt = new Text2('0m', { size: 120, fill: "#aaa" }); distTxt.anchor.set(0.5, 0); LK.gui.top.addChild(distTxt); distTxt.y = 220; // --- Corridor rendering nodes --- var wallNodes = []; var floorNodes = []; var ceilingNodes = []; for (var i = 0; i < corridor.depthSlices; i++) { // Left wall var wl = LK.getAsset('wallSlice', { anchorX: 0.5, anchorY: 1 }); game.addChild(wl); wallNodes.push(wl); // Right wall var wr = LK.getAsset('wallSlice', { anchorX: 0.5, anchorY: 1 }); game.addChild(wr); wallNodes.push(wr); // Floor var fl = LK.getAsset('floorSlice', { anchorX: 0.5, anchorY: 0 }); game.addChild(fl); floorNodes.push(fl); // Ceiling var cl = LK.getAsset('ceilingSlice', { anchorX: 0.5, anchorY: 1 }); game.addChild(cl); ceilingNodes.push(cl); } // --- Helper: Perspective projection for fake-3D --- function projectZ(z) { // Returns scale and y offset for a given depth (z) // Camera is at y = horizonY, looking down corridor var screenH = 2732; var horizonY = screenH * 0.42; var vanishY = horizonY; var baseScale = 1.0; // Perspective: scale = nearPlane / (z + nearPlane) var near = 1.2; var scale = near / (z + near); var y = vanishY + screenH * 0.32 / (z + 0.7); return { scale: scale, y: y }; } // --- Helper: X position for lane at given depth --- function laneX(lane, z) { // Center lane is at 2048/2, left/right offset by laneWidth * scale var centerX = 2048 / 2; var laneOffset = (lane - 1) * corridor.laneWidth; var p = projectZ(z); return centerX + laneOffset * p.scale; } // --- Spawning obstacles and collectibles --- function spawnObject() { // Randomly choose obstacle or collectible var isObstacle = Math.random() < 0.7; var lane = Math.floor(Math.random() * corridor.width); var depth = corridor.maxDepth + 2; // spawn just beyond farthest slice var obj; if (isObstacle) { obj = new Obstacle(); } else { obj = new Collectible(); } obj.lane = lane; obj.depth = depth; obj.active = true; objects.push(obj); game.addChild(obj); } // --- Input: Swipe or tap to move left/right --- game.down = function (x, y, obj) { lastTouchX = x; // Tap-to-move: if not moving, tap left/right of center to move if (!player.moving && player.alive) { var centerX = 2048 / 2; if (x < centerX - 250 && player.lane > 0) { movePlayerTo(player.lane - 1); } else if (x > centerX + 250 && player.lane < 2) { movePlayerTo(player.lane + 1); } } }; game.move = function (x, y, obj) { if (lastTouchX === null) return; var dx = x - lastTouchX; if (Math.abs(dx) > 180 && player.alive) { // If not moving, move immediately if (!player.moving) { if (dx > 0 && player.lane < 2) { movePlayerTo(player.lane + 1); } else if (dx < 0 && player.lane > 0) { movePlayerTo(player.lane - 1); } lastTouchX = x; } else { // If already moving, queue the next move if (typeof player.queuedMove === "undefined") player.queuedMove = null; if (dx > 0 && player.lane < 2) { player.queuedMove = player.lane + 1; } else if (dx < 0 && player.lane > 0) { player.queuedMove = player.lane - 1; } lastTouchX = x; } } }; game.up = function (x, y, obj) { lastTouchX = null; }; // --- Move player to lane with tween --- function movePlayerTo(targetLane) { if (player.moving || !player.alive) return; player.moveTarget = targetLane; player.moving = true; var start = player.lane; var end = targetLane; var t = { v: start }; player.moveTween = tween(t, { v: end }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { player.lane = end; player.moving = false; // If a move was queued during the tween, perform it now if (typeof player.queuedMove !== "undefined" && player.queuedMove !== null && player.queuedMove !== player.lane) { var nextLane = player.queuedMove; player.queuedMove = null; movePlayerTo(nextLane); } } }); // We'll interpolate player.lane visually in render player.laneTweenObj = t; } // --- Main update loop --- game.update = function () { if (!player.alive) return; // Increase speed over time speed += speedIncrease; if (speed > maxSpeed) speed = maxSpeed; distance += speed; distTxt.setText(Math.floor(distance) + "m"); // Spawn new objects spawnTimer--; if (spawnTimer <= 0) { spawnObject(); spawnTimer = spawnInterval - Math.floor(distance / 60); if (spawnTimer < 18) spawnTimer = 18; } // Move objects closer (decrease depth) for (var i = objects.length - 1; i >= 0; i--) { var obj = objects[i]; obj.depth -= speed; if (obj.depth < 0.2) { // Passed player, remove obj.destroy(); objects.splice(i, 1); continue; } // Project to screen var p = projectZ(obj.depth); obj.scaleX = obj.scaleY = p.scale * 1.2; obj.x = laneX(obj.lane, obj.depth); obj.y = p.y + 320 * p.scale; obj.visible = obj.depth > 0.2 && obj.depth < corridor.maxDepth + 2; } // Player lane interpolation (for smooth movement) var visLane = player.lane; if (player.moving && player.laneTweenObj) { visLane = player.laneTweenObj.v; } // --- Render corridor slices --- for (var i = 0; i < corridor.depthSlices; i++) { // Offset z by distance to make walls/floor/ceiling scroll opposite to objects var z = i + 1.2 - distance % 1; // reverse scroll direction var p = projectZ(z); // Walls var wallW = 80 * p.scale * 2.2; var wallH = 800 * p.scale * 2.2; // Left wall var wl = wallNodes[i * 2]; wl.x = laneX(0, z) - corridor.laneWidth * p.scale / 2 - wallW / 2; wl.y = p.y + wallH; wl.width = wallW; wl.height = wallH; wl.visible = true; // Right wall var wr = wallNodes[i * 2 + 1]; wr.x = laneX(2, z) + corridor.laneWidth * p.scale / 2 + wallW / 2; wr.y = p.y + wallH; wr.width = wallW; wr.height = wallH; wr.visible = true; // Floor var fl = floorNodes[i]; fl.x = 2048 / 2; fl.y = p.y + wallH; fl.width = corridor.laneWidth * corridor.width * p.scale * 1.1; fl.height = 80 * p.scale * 2.2; fl.visible = true; // Ceiling var cl = ceilingNodes[i]; cl.x = 2048 / 2; cl.y = p.y - 80 * p.scale * 1.2; cl.width = corridor.laneWidth * corridor.width * p.scale * 1.1; cl.height = 80 * p.scale * 2.2; cl.visible = true; } // --- Collision detection --- // Player is always at z=0, y=bottom of screen var playerZ = 0.7; var playerP = projectZ(playerZ); var playerX = laneX(visLane, playerZ); var playerY = playerP.y + 320 * playerP.scale; var playerW = 340 * playerP.scale * 1.2; var playerH = 420 * playerP.scale * 1.2; // --- Render player visual representation --- if (typeof player.visual === "undefined") { // Create the player visual as a big ellipse, anchor center player.visual = LK.getAsset('collectible', { anchorX: 0.5, anchorY: 1 }); player.visual.width = 340; player.visual.height = 420; player.visual.alpha = 0.92; game.addChild(player.visual); } player.visual.visible = player.alive; player.visual.x = playerX; player.visual.y = playerY; player.visual.scaleX = playerW / player.visual.width; player.visual.scaleY = playerH / player.visual.height; // For debugging, could render a player shadow here for (var i = objects.length - 1; i >= 0; i--) { var obj = objects[i]; if (!obj.active) continue; // Only check collision if close enough if (obj.depth < 1.2 && obj.depth > 0.2) { var dx = Math.abs(obj.x - playerX); var dy = Math.abs(obj.y - playerY); var hitW = (playerW + obj.width) / 2; var hitH = (playerH + obj.height) / 2; if (dx < hitW * 0.7 && dy < hitH * 0.7) { if (obj.type === 'obstacle') { // Hit obstacle: game over player.alive = false; LK.effects.flashScreen(0xff0000, 900); LK.showGameOver(); return; } else if (obj.type === 'collectible') { // Collect item obj.active = false; score += 1; LK.setScore(score); scoreTxt.setText(score); tween(obj, { scaleX: 2.2, scaleY: 2.2, alpha: 0 }, { duration: 220, easing: tween.cubicOut, onFinish: function onFinish() { obj.destroy(); } }); objects.splice(i, 1); } } } } }; // --- Reset game state on new game --- function resetGame() { // Remove all objects for (var i = 0; i < objects.length; i++) { objects[i].destroy(); } objects = []; player.lane = 1; player.moving = false; player.moveTarget = 1; player.moveTween = null; player.alive = true; speed = 0.18; score = 0; distance = 0; spawnTimer = 18; scoreTxt.setText('0'); distTxt.setText('0m'); } resetGame(); // --- LK handles game over and reset automatically, but listen for new game start --- LK.on('gameStart', function () { resetGame(); });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Represents a single collectible in the corridor
var Collectible = Container.expand(function () {
var self = Container.call(this);
var sprite = self.attachAsset('collectible', {
anchorX: 0.5,
anchorY: 1
});
self.lane = 1;
self.depth = 0;
self.type = 'collectible';
self.active = true;
self.getHitbox = function () {
return {
x: self.x - sprite.width / 2,
y: self.y - sprite.height,
w: sprite.width,
h: sprite.height
};
};
return self;
});
// Represents a single obstacle in the corridor
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var sprite = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
// Logical position in corridor space
self.lane = 1; // 0=left, 1=center, 2=right
self.depth = 0; // Distance from player (z)
self.type = 'obstacle';
self.active = true;
// For collision detection
self.getHitbox = function () {
// Returns {x, y, w, h} in screen space
return {
x: self.x - sprite.width / 2,
y: self.y - sprite.height,
w: sprite.width,
h: sprite.height
};
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// --- Raycasting & Corridor Parameters ---
// Corridor wall slice (vertical rectangle, will be stretched/scaled for perspective)
// Floor slice (horizontal rectangle, will be stretched/scaled for perspective)
// Ceiling slice (horizontal rectangle, will be stretched/scaled for perspective)
// Obstacle (box)
// Collectible (ellipse)
var corridor = {
width: 3,
// 3 lanes: 0=left, 1=center, 2=right
laneWidth: 700,
// virtual lane width in world units (increased for bigger lanes)
depthSlices: 16,
// how many slices to render for perspective
maxDepth: 16,
// how far to render (in slices)
fov: Math.PI / 3,
// 60 deg field of view
wallColor: 0x4444aa,
floorColor: 0x222222,
ceilingColor: 0x111133
};
// Player state
var player = {
lane: 1,
// 0=left, 1=center, 2=right
moving: false,
moveTarget: 1,
// target lane
moveTween: null,
alive: true
};
// Game state
var speed = 0.18; // units per frame (z axis)
var speedIncrease = 0.00004; // per frame
var maxSpeed = 0.38;
var objects = []; // all obstacles and collectibles
var spawnTimer = 0;
var spawnInterval = 38; // frames between spawns
var score = 0;
var distance = 0; // how far player has run (for difficulty)
var lastTouchX = null;
// --- GUI ---
var scoreTxt = new Text2('0', {
size: 220,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var distTxt = new Text2('0m', {
size: 120,
fill: "#aaa"
});
distTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(distTxt);
distTxt.y = 220;
// --- Corridor rendering nodes ---
var wallNodes = [];
var floorNodes = [];
var ceilingNodes = [];
for (var i = 0; i < corridor.depthSlices; i++) {
// Left wall
var wl = LK.getAsset('wallSlice', {
anchorX: 0.5,
anchorY: 1
});
game.addChild(wl);
wallNodes.push(wl);
// Right wall
var wr = LK.getAsset('wallSlice', {
anchorX: 0.5,
anchorY: 1
});
game.addChild(wr);
wallNodes.push(wr);
// Floor
var fl = LK.getAsset('floorSlice', {
anchorX: 0.5,
anchorY: 0
});
game.addChild(fl);
floorNodes.push(fl);
// Ceiling
var cl = LK.getAsset('ceilingSlice', {
anchorX: 0.5,
anchorY: 1
});
game.addChild(cl);
ceilingNodes.push(cl);
}
// --- Helper: Perspective projection for fake-3D ---
function projectZ(z) {
// Returns scale and y offset for a given depth (z)
// Camera is at y = horizonY, looking down corridor
var screenH = 2732;
var horizonY = screenH * 0.42;
var vanishY = horizonY;
var baseScale = 1.0;
// Perspective: scale = nearPlane / (z + nearPlane)
var near = 1.2;
var scale = near / (z + near);
var y = vanishY + screenH * 0.32 / (z + 0.7);
return {
scale: scale,
y: y
};
}
// --- Helper: X position for lane at given depth ---
function laneX(lane, z) {
// Center lane is at 2048/2, left/right offset by laneWidth * scale
var centerX = 2048 / 2;
var laneOffset = (lane - 1) * corridor.laneWidth;
var p = projectZ(z);
return centerX + laneOffset * p.scale;
}
// --- Spawning obstacles and collectibles ---
function spawnObject() {
// Randomly choose obstacle or collectible
var isObstacle = Math.random() < 0.7;
var lane = Math.floor(Math.random() * corridor.width);
var depth = corridor.maxDepth + 2; // spawn just beyond farthest slice
var obj;
if (isObstacle) {
obj = new Obstacle();
} else {
obj = new Collectible();
}
obj.lane = lane;
obj.depth = depth;
obj.active = true;
objects.push(obj);
game.addChild(obj);
}
// --- Input: Swipe or tap to move left/right ---
game.down = function (x, y, obj) {
lastTouchX = x;
// Tap-to-move: if not moving, tap left/right of center to move
if (!player.moving && player.alive) {
var centerX = 2048 / 2;
if (x < centerX - 250 && player.lane > 0) {
movePlayerTo(player.lane - 1);
} else if (x > centerX + 250 && player.lane < 2) {
movePlayerTo(player.lane + 1);
}
}
};
game.move = function (x, y, obj) {
if (lastTouchX === null) return;
var dx = x - lastTouchX;
if (Math.abs(dx) > 180 && player.alive) {
// If not moving, move immediately
if (!player.moving) {
if (dx > 0 && player.lane < 2) {
movePlayerTo(player.lane + 1);
} else if (dx < 0 && player.lane > 0) {
movePlayerTo(player.lane - 1);
}
lastTouchX = x;
} else {
// If already moving, queue the next move
if (typeof player.queuedMove === "undefined") player.queuedMove = null;
if (dx > 0 && player.lane < 2) {
player.queuedMove = player.lane + 1;
} else if (dx < 0 && player.lane > 0) {
player.queuedMove = player.lane - 1;
}
lastTouchX = x;
}
}
};
game.up = function (x, y, obj) {
lastTouchX = null;
};
// --- Move player to lane with tween ---
function movePlayerTo(targetLane) {
if (player.moving || !player.alive) return;
player.moveTarget = targetLane;
player.moving = true;
var start = player.lane;
var end = targetLane;
var t = {
v: start
};
player.moveTween = tween(t, {
v: end
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
player.lane = end;
player.moving = false;
// If a move was queued during the tween, perform it now
if (typeof player.queuedMove !== "undefined" && player.queuedMove !== null && player.queuedMove !== player.lane) {
var nextLane = player.queuedMove;
player.queuedMove = null;
movePlayerTo(nextLane);
}
}
});
// We'll interpolate player.lane visually in render
player.laneTweenObj = t;
}
// --- Main update loop ---
game.update = function () {
if (!player.alive) return;
// Increase speed over time
speed += speedIncrease;
if (speed > maxSpeed) speed = maxSpeed;
distance += speed;
distTxt.setText(Math.floor(distance) + "m");
// Spawn new objects
spawnTimer--;
if (spawnTimer <= 0) {
spawnObject();
spawnTimer = spawnInterval - Math.floor(distance / 60);
if (spawnTimer < 18) spawnTimer = 18;
}
// Move objects closer (decrease depth)
for (var i = objects.length - 1; i >= 0; i--) {
var obj = objects[i];
obj.depth -= speed;
if (obj.depth < 0.2) {
// Passed player, remove
obj.destroy();
objects.splice(i, 1);
continue;
}
// Project to screen
var p = projectZ(obj.depth);
obj.scaleX = obj.scaleY = p.scale * 1.2;
obj.x = laneX(obj.lane, obj.depth);
obj.y = p.y + 320 * p.scale;
obj.visible = obj.depth > 0.2 && obj.depth < corridor.maxDepth + 2;
}
// Player lane interpolation (for smooth movement)
var visLane = player.lane;
if (player.moving && player.laneTweenObj) {
visLane = player.laneTweenObj.v;
}
// --- Render corridor slices ---
for (var i = 0; i < corridor.depthSlices; i++) {
// Offset z by distance to make walls/floor/ceiling scroll opposite to objects
var z = i + 1.2 - distance % 1; // reverse scroll direction
var p = projectZ(z);
// Walls
var wallW = 80 * p.scale * 2.2;
var wallH = 800 * p.scale * 2.2;
// Left wall
var wl = wallNodes[i * 2];
wl.x = laneX(0, z) - corridor.laneWidth * p.scale / 2 - wallW / 2;
wl.y = p.y + wallH;
wl.width = wallW;
wl.height = wallH;
wl.visible = true;
// Right wall
var wr = wallNodes[i * 2 + 1];
wr.x = laneX(2, z) + corridor.laneWidth * p.scale / 2 + wallW / 2;
wr.y = p.y + wallH;
wr.width = wallW;
wr.height = wallH;
wr.visible = true;
// Floor
var fl = floorNodes[i];
fl.x = 2048 / 2;
fl.y = p.y + wallH;
fl.width = corridor.laneWidth * corridor.width * p.scale * 1.1;
fl.height = 80 * p.scale * 2.2;
fl.visible = true;
// Ceiling
var cl = ceilingNodes[i];
cl.x = 2048 / 2;
cl.y = p.y - 80 * p.scale * 1.2;
cl.width = corridor.laneWidth * corridor.width * p.scale * 1.1;
cl.height = 80 * p.scale * 2.2;
cl.visible = true;
}
// --- Collision detection ---
// Player is always at z=0, y=bottom of screen
var playerZ = 0.7;
var playerP = projectZ(playerZ);
var playerX = laneX(visLane, playerZ);
var playerY = playerP.y + 320 * playerP.scale;
var playerW = 340 * playerP.scale * 1.2;
var playerH = 420 * playerP.scale * 1.2;
// --- Render player visual representation ---
if (typeof player.visual === "undefined") {
// Create the player visual as a big ellipse, anchor center
player.visual = LK.getAsset('collectible', {
anchorX: 0.5,
anchorY: 1
});
player.visual.width = 340;
player.visual.height = 420;
player.visual.alpha = 0.92;
game.addChild(player.visual);
}
player.visual.visible = player.alive;
player.visual.x = playerX;
player.visual.y = playerY;
player.visual.scaleX = playerW / player.visual.width;
player.visual.scaleY = playerH / player.visual.height;
// For debugging, could render a player shadow here
for (var i = objects.length - 1; i >= 0; i--) {
var obj = objects[i];
if (!obj.active) continue;
// Only check collision if close enough
if (obj.depth < 1.2 && obj.depth > 0.2) {
var dx = Math.abs(obj.x - playerX);
var dy = Math.abs(obj.y - playerY);
var hitW = (playerW + obj.width) / 2;
var hitH = (playerH + obj.height) / 2;
if (dx < hitW * 0.7 && dy < hitH * 0.7) {
if (obj.type === 'obstacle') {
// Hit obstacle: game over
player.alive = false;
LK.effects.flashScreen(0xff0000, 900);
LK.showGameOver();
return;
} else if (obj.type === 'collectible') {
// Collect item
obj.active = false;
score += 1;
LK.setScore(score);
scoreTxt.setText(score);
tween(obj, {
scaleX: 2.2,
scaleY: 2.2,
alpha: 0
}, {
duration: 220,
easing: tween.cubicOut,
onFinish: function onFinish() {
obj.destroy();
}
});
objects.splice(i, 1);
}
}
}
}
};
// --- Reset game state on new game ---
function resetGame() {
// Remove all objects
for (var i = 0; i < objects.length; i++) {
objects[i].destroy();
}
objects = [];
player.lane = 1;
player.moving = false;
player.moveTarget = 1;
player.moveTween = null;
player.alive = true;
speed = 0.18;
score = 0;
distance = 0;
spawnTimer = 18;
scoreTxt.setText('0');
distTxt.setText('0m');
}
resetGame();
// --- LK handles game over and reset automatically, but listen for new game start ---
LK.on('gameStart', function () {
resetGame();
});