/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, energyRecord: 0, shipsUnlocked: 1 }); /**** * Classes ****/ var EnergyOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('energyOrb', { anchorX: 0.5, anchorY: 0.5 }); self.value = 10; self.speed = 5; // Glow effect self.glowFactor = 0; self.glowDirection = 1; self.update = function () { // Move upwards (towards player) self.y += self.speed; // Apply glow effect self.glowFactor += 0.05 * self.glowDirection; if (self.glowFactor >= 1) { self.glowDirection = -1; } else if (self.glowFactor <= 0) { self.glowDirection = 1; } orbGraphics.scaleX = 1 + self.glowFactor * 0.2; orbGraphics.scaleY = 1 + self.glowFactor * 0.2; }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.rotationSpeed = Math.random() * 0.04 - 0.02; self.update = function () { // Move upwards (towards player) self.y += self.speed; // Rotate the obstacle obstacleGraphics.rotation += self.rotationSpeed; }; return self; }); var Ship = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); self.velocity = { x: 0, y: 0 }; self.maxSpeed = 20; self.driftFactor = 0.92; self.acceleration = 0.25; self.energy = 0; self.maxEnergy = 100; self.isBoostActive = false; self.boostTimer = 0; self.boostDuration = 60; // 1 second at 60fps self.isInvulnerable = false; self.invulnerabilityTimer = 0; // Spawn boost trail particles self.createBoostTrail = function () { if (self.isBoostActive && LK.ticks % 3 === 0) { var trail = LK.getAsset('boostTrail', { anchorX: 0.5, anchorY: 0.5, x: self.x - 50 + (Math.random() * 20 - 10), y: self.y + 40 + (Math.random() * 20 - 10), alpha: 0.8 }); game.addChild(trail); boostTrails.push(trail); tween(trail, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 500, onFinish: function onFinish() { game.removeChild(trail); var index = boostTrails.indexOf(trail); if (index > -1) { boostTrails.splice(index, 1); } } }); } }; self.activateBoost = function () { if (self.energy >= 30 && !self.isBoostActive) { self.isBoostActive = true; self.boostTimer = self.boostDuration; self.energy -= 30; // Flash ship with green tint for boost LK.effects.flashObject(shipGraphics, 0x2ecc71, 300); // Play boost sound LK.getSound('boost').play(); } }; self.hit = function () { if (!self.isInvulnerable) { // Apply damage and make invulnerable briefly self.velocity.x *= -0.5; self.velocity.y *= 0.5; // Play crash sound LK.getSound('crash').play(); // Flash ship with red tint for damage LK.effects.flashObject(shipGraphics, 0xff0000, 500); self.isInvulnerable = true; self.invulnerabilityTimer = 90; // 1.5 seconds at 60fps } }; self.update = function () { // Update boost status if (self.isBoostActive) { self.boostTimer--; if (self.boostTimer <= 0) { self.isBoostActive = false; } } // Update invulnerability status if (self.isInvulnerable) { self.invulnerabilityTimer--; shipGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.5) * 0.5; if (self.invulnerabilityTimer <= 0) { self.isInvulnerable = false; shipGraphics.alpha = 1; } } // Apply movement physics if (self.isBoostActive) { self.velocity.y -= self.acceleration * 2; } // Apply drift physics self.velocity.x *= self.driftFactor; // Limit speed var currentSpeed = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y); var maxSpeedValue = self.isBoostActive ? self.maxSpeed * 1.5 : self.maxSpeed; if (currentSpeed > maxSpeedValue) { var ratio = maxSpeedValue / currentSpeed; self.velocity.x *= ratio; self.velocity.y *= ratio; } // Update position self.x += self.velocity.x; self.y += self.velocity.y; // Keep ship in bounds (horizontally) if (self.x < 150) { self.x = 150; self.velocity.x *= -0.5; } else if (self.x > 2048 - 150) { self.x = 2048 - 150; self.velocity.x *= -0.5; } // Apply rotation based on horizontal movement var targetRotation = self.velocity.x / self.maxSpeed * 0.6; shipGraphics.rotation = targetRotation; // Create boost trail particles self.createBoostTrail(); }; return self; }); var TrackSegment = Container.expand(function () { var self = Container.call(this); var segmentGraphics = self.attachAsset('trackSegment', { anchorX: 0.5, anchorY: 0 }); self.speed = 6; // Add stars for the track for (var i = 0; i < 15; i++) { var star = LK.getAsset('starField', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * segmentGraphics.width - segmentGraphics.width / 2, y: Math.random() * segmentGraphics.height, alpha: 0.2 + Math.random() * 0.8, scaleX: 0.2 + Math.random() * 0.8, scaleY: 0.2 + Math.random() * 0.8 }); self.addChild(star); } self.update = function () { // Move upwards self.y += self.speed; }; return self; }); var Wormhole = Container.expand(function () { var self = Container.call(this); var wormholeGraphics = self.attachAsset('wormhole', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.portalTarget = null; self.isActive = true; self.cooldown = 0; // Spin effect self.update = function () { // Move upwards (towards player) self.y += self.speed; // Rotate the wormhole wormholeGraphics.rotation += 0.02; // Pulse effect var pulse = (Math.sin(LK.ticks * 0.05) + 1) * 0.1; wormholeGraphics.scaleX = 1 + pulse; wormholeGraphics.scaleY = 1 + pulse; // Update cooldown if (self.cooldown > 0) { self.cooldown--; wormholeGraphics.alpha = 0.5; if (self.cooldown === 0) { self.isActive = true; wormholeGraphics.alpha = 1; } } }; self.transport = function (ship) { if (self.isActive && self.portalTarget) { // Play wormhole sound LK.getSound('wormhole').play(); // Transport the ship ship.x = self.portalTarget.x; ship.y = self.portalTarget.y - 150; // Apply small boost in y direction ship.velocity.y -= 5; // Deactivate this wormhole temporarily self.isActive = false; self.cooldown = 120; // 2 seconds at 60fps // Also deactivate the target wormhole if (self.portalTarget.isActive) { self.portalTarget.isActive = false; self.portalTarget.cooldown = 120; } return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables var ship; var trackSegments = []; var energyOrbs = []; var obstacles = []; var wormholes = []; var boostTrails = []; var lastTrackY = 0; var score = 0; var distance = 0; var gameStarted = false; var dragNode = null; var spawnRateMultiplier = 1; // UI Variables var scoreText; var energyBar; var energyBarBg; var distanceText; var highScoreText; var energyText; var startText; // Initialize the game function initGame() { // Set up background game.setBackgroundColor(0x0a0a20); // Initialize UI setupUI(); // Create player ship ship = new Ship(); ship.x = 2048 / 2; ship.y = 2732 - 400; game.addChild(ship); // Start with several track segments for (var i = 0; i < 10; i++) { createTrackSegment(2732 - i * 300); } // Start game music LK.playMusic('racingMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); // Initialize game state gameStarted = false; score = 0; distance = 0; // Set initial positions ship.velocity = { x: 0, y: 0 }; ship.energy = 0; // Update UI to show start text startText.visible = true; updateUI(); } function setupUI() { // Create score text scoreText = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -200; scoreText.y = 50; // Create distance text distanceText = new Text2('Distance: 0', { size: 50, fill: 0xFFFFFF }); distanceText.anchor.set(0, 0); LK.gui.topRight.addChild(distanceText); distanceText.x = -200; distanceText.y = 110; // Create energy bar background energyBarBg = LK.getAsset('bullet', { width: 400, height: 30, color: 0x333333, anchorX: 0, anchorY: 0 }); LK.gui.top.addChild(energyBarBg); energyBarBg.x = -200; energyBarBg.y = 50; // Create energy bar energyBar = LK.getAsset('bullet', { width: 0, height: 30, color: 0x2ecc71, anchorX: 0, anchorY: 0 }); LK.gui.top.addChild(energyBar); energyBar.x = -200; energyBar.y = 50; // Create energy text energyText = new Text2('Energy', { size: 30, fill: 0xFFFFFF }); energyText.anchor.set(0.5, 0.5); LK.gui.top.addChild(energyText); energyText.x = 0; energyText.y = 65; // Create high score text highScoreText = new Text2('High Score: ' + storage.highScore, { size: 40, fill: 0xF1C40F }); highScoreText.anchor.set(0, 0); LK.gui.top.addChild(highScoreText); highScoreText.x = 50; highScoreText.y = 50; // Create start text startText = new Text2('Tap and drag to control ship\nDouble tap to use boost', { size: 60, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); LK.gui.center.addChild(startText); } function updateUI() { // Update score text scoreText.setText('Score: ' + score); // Update distance text distanceText.setText('Distance: ' + Math.floor(distance / 100)); // Update energy bar energyBar.width = ship.energy / ship.maxEnergy * 400; // Update high score if needed if (score > storage.highScore) { storage.highScore = score; highScoreText.setText('High Score: ' + storage.highScore); } } // Create a new track segment function createTrackSegment(yPos) { var segment = new TrackSegment(); segment.x = 2048 / 2; segment.y = yPos; game.addChild(segment); trackSegments.push(segment); lastTrackY = yPos; } // Spawn a random element (energy orb, obstacle, or wormhole) function spawnRandomElement() { var randomValue = Math.random(); if (randomValue < 0.6) { // Spawn energy orb spawnEnergyOrb(); } else if (randomValue < 0.9) { // Spawn obstacle spawnObstacle(); } else { // Spawn wormhole pair spawnWormholePair(); } } // Spawn energy orb function spawnEnergyOrb() { var orb = new EnergyOrb(); orb.x = 300 + Math.random() * (2048 - 600); orb.y = -100; game.addChild(orb); energyOrbs.push(orb); } // Spawn obstacle function spawnObstacle() { var obstacle = new Obstacle(); obstacle.x = 300 + Math.random() * (2048 - 600); obstacle.y = -100; game.addChild(obstacle); obstacles.push(obstacle); } // Spawn a pair of connected wormholes function spawnWormholePair() { var wormhole1 = new Wormhole(); wormhole1.x = 400 + Math.random() * 500; wormhole1.y = -100; var wormhole2 = new Wormhole(); wormhole2.x = 2048 - 400 - Math.random() * 500; wormhole2.y = -800 - Math.random() * 500; // Link the wormholes to each other wormhole1.portalTarget = wormhole2; wormhole2.portalTarget = wormhole1; game.addChild(wormhole1); game.addChild(wormhole2); wormholes.push(wormhole1); wormholes.push(wormhole2); } // Handle movement event function handleMove(x, y, obj) { if (dragNode && gameStarted) { // Calculate the drag influence var targetX = x; var deltaX = targetX - dragNode.x; // Apply movement force to ship dragNode.velocity.x += deltaX * 0.1; } } // Game initialization initGame(); // Handle touch down on game game.down = function (x, y, obj) { var currentTime = Date.now(); if (!gameStarted) { // Start game on first tap gameStarted = true; startText.visible = false; return; } // Set drag node to ship dragNode = ship; // Handle double tap for boost if (ship.lastTapTime && currentTime - ship.lastTapTime < 300) { ship.activateBoost(); } ship.lastTapTime = currentTime; // Call move handler right away for instant effect handleMove(x, y, obj); }; // Handle touch up on game game.up = function (x, y, obj) { dragNode = null; }; // Handle move events game.move = handleMove; // Main game update function game.update = function () { if (!gameStarted) { return; } // Update distance and score distance += ship.isBoostActive ? 12 : 6; score = Math.floor(distance / 100) + ship.energy * 2; // Update difficulty spawnRateMultiplier = 1 + distance / 50000; // Update track segments for (var i = trackSegments.length - 1; i >= 0; i--) { var segment = trackSegments[i]; // Remove off-screen segments if (segment.y > 2732 + 300) { game.removeChild(segment); trackSegments.splice(i, 1); } } // Spawn new track segments as needed if (lastTrackY > -300) { createTrackSegment(-300); } // Randomly spawn game elements if (LK.ticks % Math.floor(50 / spawnRateMultiplier) === 0) { spawnRandomElement(); } // Update energy orbs for (var i = energyOrbs.length - 1; i >= 0; i--) { var orb = energyOrbs[i]; // Check for collisions with ship if (orb.intersects(ship)) { // Collect energy ship.energy = Math.min(ship.maxEnergy, ship.energy + orb.value); // Play collect sound LK.getSound('collect').play(); // Remove orb game.removeChild(orb); energyOrbs.splice(i, 1); // Add to score score += 50; // Track energy collection record if (ship.energy > storage.energyRecord) { storage.energyRecord = ship.energy; } continue; } // Remove off-screen orbs if (orb.y > 2732 + 100) { game.removeChild(orb); energyOrbs.splice(i, 1); } } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; // Check for collisions with ship if (obstacle.intersects(ship)) { ship.hit(); // Reduce energy ship.energy = Math.max(0, ship.energy - 20); // Remove obstacle game.removeChild(obstacle); obstacles.splice(i, 1); continue; } // Remove off-screen obstacles if (obstacle.y > 2732 + 100) { game.removeChild(obstacle); obstacles.splice(i, 1); } } // Update wormholes for (var i = wormholes.length - 1; i >= 0; i--) { var wormhole = wormholes[i]; // Check for collisions with ship if (wormhole.intersects(ship)) { var transported = wormhole.transport(ship); if (transported) { // Add to score for successful wormhole transport score += 100; } } // Remove off-screen wormholes if (wormhole.y > 2732 + 100) { // If this wormhole has a partner, remove the link if (wormhole.portalTarget) { wormhole.portalTarget.portalTarget = null; } game.removeChild(wormhole); wormholes.splice(i, 1); } } // Game over condition (more obstacles could be added later) if (ship.y < 0) { // Record high score if (score > storage.highScore) { storage.highScore = score; } // Show game over LK.showGameOver(); } // Update UI updateUI(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
energyRecord: 0,
shipsUnlocked: 1
});
/****
* Classes
****/
var EnergyOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('energyOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.speed = 5;
// Glow effect
self.glowFactor = 0;
self.glowDirection = 1;
self.update = function () {
// Move upwards (towards player)
self.y += self.speed;
// Apply glow effect
self.glowFactor += 0.05 * self.glowDirection;
if (self.glowFactor >= 1) {
self.glowDirection = -1;
} else if (self.glowFactor <= 0) {
self.glowDirection = 1;
}
orbGraphics.scaleX = 1 + self.glowFactor * 0.2;
orbGraphics.scaleY = 1 + self.glowFactor * 0.2;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.rotationSpeed = Math.random() * 0.04 - 0.02;
self.update = function () {
// Move upwards (towards player)
self.y += self.speed;
// Rotate the obstacle
obstacleGraphics.rotation += self.rotationSpeed;
};
return self;
});
var Ship = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 0,
y: 0
};
self.maxSpeed = 20;
self.driftFactor = 0.92;
self.acceleration = 0.25;
self.energy = 0;
self.maxEnergy = 100;
self.isBoostActive = false;
self.boostTimer = 0;
self.boostDuration = 60; // 1 second at 60fps
self.isInvulnerable = false;
self.invulnerabilityTimer = 0;
// Spawn boost trail particles
self.createBoostTrail = function () {
if (self.isBoostActive && LK.ticks % 3 === 0) {
var trail = LK.getAsset('boostTrail', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x - 50 + (Math.random() * 20 - 10),
y: self.y + 40 + (Math.random() * 20 - 10),
alpha: 0.8
});
game.addChild(trail);
boostTrails.push(trail);
tween(trail, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(trail);
var index = boostTrails.indexOf(trail);
if (index > -1) {
boostTrails.splice(index, 1);
}
}
});
}
};
self.activateBoost = function () {
if (self.energy >= 30 && !self.isBoostActive) {
self.isBoostActive = true;
self.boostTimer = self.boostDuration;
self.energy -= 30;
// Flash ship with green tint for boost
LK.effects.flashObject(shipGraphics, 0x2ecc71, 300);
// Play boost sound
LK.getSound('boost').play();
}
};
self.hit = function () {
if (!self.isInvulnerable) {
// Apply damage and make invulnerable briefly
self.velocity.x *= -0.5;
self.velocity.y *= 0.5;
// Play crash sound
LK.getSound('crash').play();
// Flash ship with red tint for damage
LK.effects.flashObject(shipGraphics, 0xff0000, 500);
self.isInvulnerable = true;
self.invulnerabilityTimer = 90; // 1.5 seconds at 60fps
}
};
self.update = function () {
// Update boost status
if (self.isBoostActive) {
self.boostTimer--;
if (self.boostTimer <= 0) {
self.isBoostActive = false;
}
}
// Update invulnerability status
if (self.isInvulnerable) {
self.invulnerabilityTimer--;
shipGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.5) * 0.5;
if (self.invulnerabilityTimer <= 0) {
self.isInvulnerable = false;
shipGraphics.alpha = 1;
}
}
// Apply movement physics
if (self.isBoostActive) {
self.velocity.y -= self.acceleration * 2;
}
// Apply drift physics
self.velocity.x *= self.driftFactor;
// Limit speed
var currentSpeed = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
var maxSpeedValue = self.isBoostActive ? self.maxSpeed * 1.5 : self.maxSpeed;
if (currentSpeed > maxSpeedValue) {
var ratio = maxSpeedValue / currentSpeed;
self.velocity.x *= ratio;
self.velocity.y *= ratio;
}
// Update position
self.x += self.velocity.x;
self.y += self.velocity.y;
// Keep ship in bounds (horizontally)
if (self.x < 150) {
self.x = 150;
self.velocity.x *= -0.5;
} else if (self.x > 2048 - 150) {
self.x = 2048 - 150;
self.velocity.x *= -0.5;
}
// Apply rotation based on horizontal movement
var targetRotation = self.velocity.x / self.maxSpeed * 0.6;
shipGraphics.rotation = targetRotation;
// Create boost trail particles
self.createBoostTrail();
};
return self;
});
var TrackSegment = Container.expand(function () {
var self = Container.call(this);
var segmentGraphics = self.attachAsset('trackSegment', {
anchorX: 0.5,
anchorY: 0
});
self.speed = 6;
// Add stars for the track
for (var i = 0; i < 15; i++) {
var star = LK.getAsset('starField', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * segmentGraphics.width - segmentGraphics.width / 2,
y: Math.random() * segmentGraphics.height,
alpha: 0.2 + Math.random() * 0.8,
scaleX: 0.2 + Math.random() * 0.8,
scaleY: 0.2 + Math.random() * 0.8
});
self.addChild(star);
}
self.update = function () {
// Move upwards
self.y += self.speed;
};
return self;
});
var Wormhole = Container.expand(function () {
var self = Container.call(this);
var wormholeGraphics = self.attachAsset('wormhole', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.portalTarget = null;
self.isActive = true;
self.cooldown = 0;
// Spin effect
self.update = function () {
// Move upwards (towards player)
self.y += self.speed;
// Rotate the wormhole
wormholeGraphics.rotation += 0.02;
// Pulse effect
var pulse = (Math.sin(LK.ticks * 0.05) + 1) * 0.1;
wormholeGraphics.scaleX = 1 + pulse;
wormholeGraphics.scaleY = 1 + pulse;
// Update cooldown
if (self.cooldown > 0) {
self.cooldown--;
wormholeGraphics.alpha = 0.5;
if (self.cooldown === 0) {
self.isActive = true;
wormholeGraphics.alpha = 1;
}
}
};
self.transport = function (ship) {
if (self.isActive && self.portalTarget) {
// Play wormhole sound
LK.getSound('wormhole').play();
// Transport the ship
ship.x = self.portalTarget.x;
ship.y = self.portalTarget.y - 150;
// Apply small boost in y direction
ship.velocity.y -= 5;
// Deactivate this wormhole temporarily
self.isActive = false;
self.cooldown = 120; // 2 seconds at 60fps
// Also deactivate the target wormhole
if (self.portalTarget.isActive) {
self.portalTarget.isActive = false;
self.portalTarget.cooldown = 120;
}
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state variables
var ship;
var trackSegments = [];
var energyOrbs = [];
var obstacles = [];
var wormholes = [];
var boostTrails = [];
var lastTrackY = 0;
var score = 0;
var distance = 0;
var gameStarted = false;
var dragNode = null;
var spawnRateMultiplier = 1;
// UI Variables
var scoreText;
var energyBar;
var energyBarBg;
var distanceText;
var highScoreText;
var energyText;
var startText;
// Initialize the game
function initGame() {
// Set up background
game.setBackgroundColor(0x0a0a20);
// Initialize UI
setupUI();
// Create player ship
ship = new Ship();
ship.x = 2048 / 2;
ship.y = 2732 - 400;
game.addChild(ship);
// Start with several track segments
for (var i = 0; i < 10; i++) {
createTrackSegment(2732 - i * 300);
}
// Start game music
LK.playMusic('racingMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
// Initialize game state
gameStarted = false;
score = 0;
distance = 0;
// Set initial positions
ship.velocity = {
x: 0,
y: 0
};
ship.energy = 0;
// Update UI to show start text
startText.visible = true;
updateUI();
}
function setupUI() {
// Create score text
scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -200;
scoreText.y = 50;
// Create distance text
distanceText = new Text2('Distance: 0', {
size: 50,
fill: 0xFFFFFF
});
distanceText.anchor.set(0, 0);
LK.gui.topRight.addChild(distanceText);
distanceText.x = -200;
distanceText.y = 110;
// Create energy bar background
energyBarBg = LK.getAsset('bullet', {
width: 400,
height: 30,
color: 0x333333,
anchorX: 0,
anchorY: 0
});
LK.gui.top.addChild(energyBarBg);
energyBarBg.x = -200;
energyBarBg.y = 50;
// Create energy bar
energyBar = LK.getAsset('bullet', {
width: 0,
height: 30,
color: 0x2ecc71,
anchorX: 0,
anchorY: 0
});
LK.gui.top.addChild(energyBar);
energyBar.x = -200;
energyBar.y = 50;
// Create energy text
energyText = new Text2('Energy', {
size: 30,
fill: 0xFFFFFF
});
energyText.anchor.set(0.5, 0.5);
LK.gui.top.addChild(energyText);
energyText.x = 0;
energyText.y = 65;
// Create high score text
highScoreText = new Text2('High Score: ' + storage.highScore, {
size: 40,
fill: 0xF1C40F
});
highScoreText.anchor.set(0, 0);
LK.gui.top.addChild(highScoreText);
highScoreText.x = 50;
highScoreText.y = 50;
// Create start text
startText = new Text2('Tap and drag to control ship\nDouble tap to use boost', {
size: 60,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startText);
}
function updateUI() {
// Update score text
scoreText.setText('Score: ' + score);
// Update distance text
distanceText.setText('Distance: ' + Math.floor(distance / 100));
// Update energy bar
energyBar.width = ship.energy / ship.maxEnergy * 400;
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
highScoreText.setText('High Score: ' + storage.highScore);
}
}
// Create a new track segment
function createTrackSegment(yPos) {
var segment = new TrackSegment();
segment.x = 2048 / 2;
segment.y = yPos;
game.addChild(segment);
trackSegments.push(segment);
lastTrackY = yPos;
}
// Spawn a random element (energy orb, obstacle, or wormhole)
function spawnRandomElement() {
var randomValue = Math.random();
if (randomValue < 0.6) {
// Spawn energy orb
spawnEnergyOrb();
} else if (randomValue < 0.9) {
// Spawn obstacle
spawnObstacle();
} else {
// Spawn wormhole pair
spawnWormholePair();
}
}
// Spawn energy orb
function spawnEnergyOrb() {
var orb = new EnergyOrb();
orb.x = 300 + Math.random() * (2048 - 600);
orb.y = -100;
game.addChild(orb);
energyOrbs.push(orb);
}
// Spawn obstacle
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 300 + Math.random() * (2048 - 600);
obstacle.y = -100;
game.addChild(obstacle);
obstacles.push(obstacle);
}
// Spawn a pair of connected wormholes
function spawnWormholePair() {
var wormhole1 = new Wormhole();
wormhole1.x = 400 + Math.random() * 500;
wormhole1.y = -100;
var wormhole2 = new Wormhole();
wormhole2.x = 2048 - 400 - Math.random() * 500;
wormhole2.y = -800 - Math.random() * 500;
// Link the wormholes to each other
wormhole1.portalTarget = wormhole2;
wormhole2.portalTarget = wormhole1;
game.addChild(wormhole1);
game.addChild(wormhole2);
wormholes.push(wormhole1);
wormholes.push(wormhole2);
}
// Handle movement event
function handleMove(x, y, obj) {
if (dragNode && gameStarted) {
// Calculate the drag influence
var targetX = x;
var deltaX = targetX - dragNode.x;
// Apply movement force to ship
dragNode.velocity.x += deltaX * 0.1;
}
}
// Game initialization
initGame();
// Handle touch down on game
game.down = function (x, y, obj) {
var currentTime = Date.now();
if (!gameStarted) {
// Start game on first tap
gameStarted = true;
startText.visible = false;
return;
}
// Set drag node to ship
dragNode = ship;
// Handle double tap for boost
if (ship.lastTapTime && currentTime - ship.lastTapTime < 300) {
ship.activateBoost();
}
ship.lastTapTime = currentTime;
// Call move handler right away for instant effect
handleMove(x, y, obj);
};
// Handle touch up on game
game.up = function (x, y, obj) {
dragNode = null;
};
// Handle move events
game.move = handleMove;
// Main game update function
game.update = function () {
if (!gameStarted) {
return;
}
// Update distance and score
distance += ship.isBoostActive ? 12 : 6;
score = Math.floor(distance / 100) + ship.energy * 2;
// Update difficulty
spawnRateMultiplier = 1 + distance / 50000;
// Update track segments
for (var i = trackSegments.length - 1; i >= 0; i--) {
var segment = trackSegments[i];
// Remove off-screen segments
if (segment.y > 2732 + 300) {
game.removeChild(segment);
trackSegments.splice(i, 1);
}
}
// Spawn new track segments as needed
if (lastTrackY > -300) {
createTrackSegment(-300);
}
// Randomly spawn game elements
if (LK.ticks % Math.floor(50 / spawnRateMultiplier) === 0) {
spawnRandomElement();
}
// Update energy orbs
for (var i = energyOrbs.length - 1; i >= 0; i--) {
var orb = energyOrbs[i];
// Check for collisions with ship
if (orb.intersects(ship)) {
// Collect energy
ship.energy = Math.min(ship.maxEnergy, ship.energy + orb.value);
// Play collect sound
LK.getSound('collect').play();
// Remove orb
game.removeChild(orb);
energyOrbs.splice(i, 1);
// Add to score
score += 50;
// Track energy collection record
if (ship.energy > storage.energyRecord) {
storage.energyRecord = ship.energy;
}
continue;
}
// Remove off-screen orbs
if (orb.y > 2732 + 100) {
game.removeChild(orb);
energyOrbs.splice(i, 1);
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check for collisions with ship
if (obstacle.intersects(ship)) {
ship.hit();
// Reduce energy
ship.energy = Math.max(0, ship.energy - 20);
// Remove obstacle
game.removeChild(obstacle);
obstacles.splice(i, 1);
continue;
}
// Remove off-screen obstacles
if (obstacle.y > 2732 + 100) {
game.removeChild(obstacle);
obstacles.splice(i, 1);
}
}
// Update wormholes
for (var i = wormholes.length - 1; i >= 0; i--) {
var wormhole = wormholes[i];
// Check for collisions with ship
if (wormhole.intersects(ship)) {
var transported = wormhole.transport(ship);
if (transported) {
// Add to score for successful wormhole transport
score += 100;
}
}
// Remove off-screen wormholes
if (wormhole.y > 2732 + 100) {
// If this wormhole has a partner, remove the link
if (wormhole.portalTarget) {
wormhole.portalTarget.portalTarget = null;
}
game.removeChild(wormhole);
wormholes.splice(i, 1);
}
}
// Game over condition (more obstacles could be added later)
if (ship.y < 0) {
// Record high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Show game over
LK.showGameOver();
}
// Update UI
updateUI();
};