/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.rotationSpeed = (Math.random() - 0.5) * 0.04;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
asteroidGraphics.rotation += self.rotationSpeed;
// Wrap around screen
var padding = asteroidGraphics.width / 2; // Use asset size for padding
if (self.x < -padding) {
self.x = 2048 + padding; // Use fixed width
}
if (self.x > 2048 + padding) {
// Use fixed width
self.x = -padding;
}
if (self.y < -padding) {
self.y = 2732 + padding; // Use fixed height
}
if (self.y > 2732 + padding) {
// Use fixed height
self.y = -padding;
}
};
return self;
});
var CargoContainer = Container.expand(function () {
var self = Container.call(this);
var cargoGraphics = self.attachAsset('cargoContainer', {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.02;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.update = function () {
self.bobPhase += self.bobSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var CargoShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('cargoShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.fuel = 100;
self.maxFuel = 100;
self.fuelConsumption = 0.05;
self.cargoCapacity = 3;
self.cargo = 0;
self.shieldActive = false;
self.magnetActive = false;
self.magnetRange = 300;
// Create visual shield effect
var shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4
});
shield.visible = false;
// Create visual magnet effect
var magnetIndicator = self.attachAsset('magnet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
magnetIndicator.visible = false;
self.activateShield = function (duration) {
if (!self.shieldActive) {
LK.getSound('shieldActivate').play(); // Play activation sound
self.shieldActive = true;
shield.visible = true;
shield.alpha = 0.1;
// Animate shield appearance
tween(shield, {
alpha: 0.6
}, {
duration: 500,
easing: tween.elasticOut
});
LK.setTimeout(function () {
// Fade out shield when expiring
tween(shield, {
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
self.shieldActive = false;
shield.visible = false;
shield.alpha = 0.4;
}
});
}, duration || 5000);
}
};
self.activateMagnet = function (duration) {
if (!self.magnetActive) {
var _pulseMagnet = function pulseMagnet() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.2
}, {
duration: 800,
onFinish: function onFinish() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.5
}, {
duration: 800,
onFinish: _pulseMagnet
});
}
}
});
}
};
LK.getSound('magnetActivate').play(); // Play activation sound
self.magnetActive = true;
magnetIndicator.visible = true;
magnetIndicator.alpha = 0.2;
magnetIndicator.scale.set(0.5, 0.5);
// Animate magnet field appearance
tween(magnetIndicator, {
alpha: 0.5,
scaleX: 6,
scaleY: 6
}, {
duration: 800,
easing: tween.elasticOut
});
// Pulse the magnet field
_pulseMagnet();
LK.setTimeout(function () {
// Fade out magnet field when expiring
tween(magnetIndicator, {
alpha: 0,
scaleX: 10,
scaleY: 10
}, {
duration: 1000,
onFinish: function onFinish() {
self.magnetActive = false;
magnetIndicator.visible = false;
magnetIndicator.scale.set(0.5, 0.5);
}
});
}, duration || 5000);
}
};
self.consumeFuel = function () {
self.fuel -= self.fuelConsumption;
if (self.fuel <= 0) {
self.fuel = 0;
}
if (self.fuel <= 20 && self.fuel > 19.95) {
LK.getSound('lowFuel').play();
}
};
self.refuel = function (amount) {
self.fuel = Math.min(self.fuel + amount, self.maxFuel);
};
self.pickupCargo = function () {
if (self.cargo < self.cargoCapacity) {
self.cargo++;
return true;
}
return false;
};
self.deliverCargo = function () {
var delivered = self.cargo;
self.cargo = 0;
return delivered;
};
return self;
});
var EnemyDrone = Container.expand(function () {
var self = Container.call(this);
var droneGraphics = self.attachAsset('enemyDrone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.target = null;
self.patrolRadius = 300;
self.patrolCenter = {
x: 0,
y: 0
};
self.patrolAngle = Math.random() * Math.PI * 2;
self.patrolSpeed = 0.01;
self.setPatrolCenter = function (x, y, radius) {
self.patrolCenter.x = x;
self.patrolCenter.y = y;
if (radius) {
self.patrolRadius = radius;
}
};
self.setTarget = function (target) {
self.target = target;
};
self.update = function () {
if (self.target) {
// Move toward target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
} else {
// Patrol in a circle
self.patrolAngle += self.patrolSpeed;
self.x = self.patrolCenter.x + Math.cos(self.patrolAngle) * self.patrolRadius;
self.y = self.patrolCenter.y + Math.sin(self.patrolAngle) * self.patrolRadius;
}
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fuel';
var assetType;
switch (self.type) {
case 'fuel':
assetType = 'fuelPowerup';
break;
case 'shield':
assetType = 'shieldPowerup';
break;
case 'magnet':
assetType = 'magnet';
break;
default:
assetType = 'fuelPowerup';
}
var powerupGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.03;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.rotationSpeed = 0.02;
self.update = function () {
self.bobPhase += self.bobSpeed;
powerupGraphics.rotation += self.rotationSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var SpaceStation = Container.expand(function () {
var self = Container.call(this);
var stationGraphics = self.attachAsset('spaceStation', {
anchorX: 0.5,
anchorY: 0.5
});
self.rotationSpeed = 0.002;
self.isFlashing = false;
self.pulseTime = 0;
self.pulseFrequency = 0.05;
// Function to make the station flash to indicate it's ready for delivery
self.startFlashing = function () {
if (!self.isFlashing) {
var _flashCycle = function flashCycle() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0xf1c40f
}, {
duration: 800,
onFinish: function onFinish() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 800,
onFinish: _flashCycle
});
}
}
});
}
};
self.isFlashing = true;
// Flash between colors
_flashCycle();
}
};
// Function to stop flashing
self.stopFlashing = function () {
self.isFlashing = false;
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 400
});
};
self.update = function () {
stationGraphics.rotation += self.rotationSpeed;
// Pulse effect
self.pulseTime += self.pulseFrequency;
var pulseFactor = 1 + Math.sin(self.pulseTime) * 0.1;
stationGraphics.scale.set(pulseFactor, pulseFactor);
};
// Start flashing by default
self.startFlashing();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Game state
var ship;
var asteroids = [];
var cargoContainers = [];
var spaceStations = [];
var enemyDrones = [];
var powerups = [];
var fuelBarBg;
var fuelBarFront;
var cargoText;
var scoreText;
var levelText;
var highScoreText;
var gameActive = true;
var level = 1;
var score = 0;
var highScore = storage.highScore || 0;
var destX = 0;
var destY = 0;
var dragNode = null;
var rotationTween = null; // Added to track ship rotation tween
var lastSpawnTime = 0;
var difficultyTimer;
// Initialize UI elements
function initUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 10; // Position adjusted slightly if needed, but 10 seems okay
LK.gui.top.addChild(scoreText);
// High score text
highScoreText = new Text2('Best: ' + highScore, {
size: 50,
// Increased size
fill: 0xFFFFFF
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 90; // Adjusted y position to account for larger scoreText above
LK.gui.top.addChild(highScoreText);
// Level text
levelText = new Text2('Level: 1', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
levelText.x = -50;
levelText.y = 10;
LK.gui.topRight.addChild(levelText);
// Cargo text
cargoText = new Text2('Cargo: 0/3', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
cargoText.anchor.set(0, 0);
cargoText.x = 120; // Moved further right to avoid menu icon
cargoText.y = 10;
LK.gui.topLeft.addChild(cargoText);
// Fuel bar background
fuelBarBg = LK.getAsset('fuelBarBackground', {
anchorX: 0.5,
anchorY: 0.5
});
fuelBarBg.x = 0;
fuelBarBg.y = 40;
LK.gui.bottom.addChild(fuelBarBg);
// Fuel bar
fuelBarFront = LK.getAsset('fuelBar', {
anchorX: 0,
anchorY: 0.5
});
fuelBarFront.x = -fuelBarBg.width / 2;
fuelBarFront.y = 40;
LK.gui.bottom.addChild(fuelBarFront);
// Add visual labels
var fuelLabel = new Text2('FUEL', {
size: 45,
// Increased size
fill: 0xFFFFFF
});
fuelLabel.anchor.set(0.5, 0.5);
fuelLabel.y = 40; // Position remains centered on the bar
LK.gui.bottom.addChild(fuelLabel);
}
// Create cargo ship
function createShip() {
ship = new CargoShip();
ship.x = 2048 / 2;
ship.y = 2732 / 2;
game.addChild(ship);
}
// Create random asteroid
function createAsteroid() {
var asteroid = new Asteroid();
// Random position on the edge of the screen
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
asteroid.x = Math.random() * 2048;
asteroid.y = -100;
break;
case 1:
// Right
asteroid.x = 2148;
asteroid.y = Math.random() * 2732;
break;
case 2:
// Bottom
asteroid.x = Math.random() * 2048;
asteroid.y = 2832;
break;
case 3:
// Left
asteroid.x = -100;
asteroid.y = Math.random() * 2732;
break;
}
// Random speed (higher in higher levels)
var baseSpeed = 2 + level * 0.5;
var speed = baseSpeed * (0.5 + Math.random() * 0.5);
// Direction toward center with some randomness
var targetX = 2048 / 2 + (Math.random() - 0.5) * 1000;
var targetY = 2732 / 2 + (Math.random() - 0.5) * 1000;
var dx = targetX - asteroid.x;
var dy = targetY - asteroid.y;
var dist = Math.sqrt(dx * dx + dy * dy);
asteroid.speedX = dx / dist * speed;
asteroid.speedY = dy / dist * speed;
// Scale randomly
var scale = 0.8 + Math.random() * 0.8;
asteroid.scale.set(scale, scale);
asteroids.push(asteroid);
game.addChild(asteroid);
}
// Create cargo container
function createCargoContainer() {
var container = new CargoContainer();
// Random position (not too close to the edge)
container.x = 200 + Math.random() * (2048 - 400);
container.y = 200 + Math.random() * (2732 - 400);
container.originalY = container.y;
cargoContainers.push(container);
game.addChild(container);
}
// Create space station
function createSpaceStation() {
var station = new SpaceStation();
// Position near an edge but not too close
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
station.x = 400 + Math.random() * (2048 - 800);
station.y = 300;
break;
case 1:
// Right
station.x = 2048 - 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
case 2:
// Bottom
station.x = 400 + Math.random() * (2048 - 800);
station.y = 2732 - 300;
break;
case 3:
// Left
station.x = 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
}
spaceStations.push(station);
game.addChild(station);
}
// Create enemy drone
function createEnemyDrone() {
var drone = new EnemyDrone();
// Random position
drone.x = Math.random() * 2048;
drone.y = Math.random() * 2732;
// Set patrol area
drone.setPatrolCenter(drone.x, drone.y, 200 + Math.random() * 200);
// Set speed based on level
drone.speed = 1 + level * 0.3;
enemyDrones.push(drone);
game.addChild(drone);
}
// Create powerup
function createPowerup(type) {
if (!type) {
var types = ['fuel', 'shield', 'magnet'];
type = types[Math.floor(Math.random() * types.length)];
}
var powerup = new Powerup(type);
// Random position (not too close to the edge)
powerup.x = 300 + Math.random() * (2048 - 600);
powerup.y = 300 + Math.random() * (2732 - 600);
powerup.originalY = powerup.y;
powerups.push(powerup);
game.addChild(powerup);
}
// Spawn game objects based on level
function spawnObjects() {
var currentTime = Date.now();
// Only spawn new objects every 1-3 seconds depending on level
var spawnRate = Math.max(3000 - level * 200, 1000);
if (currentTime - lastSpawnTime > spawnRate) {
// Spawn asteroid
if (asteroids.length < 5 + level * 2) {
createAsteroid();
}
// Spawn cargo
if (cargoContainers.length < 3 + Math.floor(level / 2)) {
createCargoContainer();
}
// Spawn enemy drones in higher levels
if (level >= 2 && enemyDrones.length < level - 1) {
createEnemyDrone();
}
// Spawn powerup (less frequently)
if (Math.random() < 0.2) {
createPowerup();
}
lastSpawnTime = currentTime;
}
}
// Update ship movement based on destination
function updateShipMovement() {
if (destX && destY) {
var dx = destX - ship.x;
var dy = destY - ship.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
// Calculate rotation angle to face destination
var angle = Math.atan2(dy, dx);
// Rotate ship to face direction of travel
// Stop existing rotation tween if it exists and is running
if (rotationTween && rotationTween.playing) {
rotationTween.stop();
}
rotationTween = tween(ship, {
rotation: angle
}, {
duration: 150 // Slightly faster rotation
});
// Move toward destination
ship.x += dx / dist * ship.speed;
ship.y += dy / dist * ship.speed;
// Consume fuel while moving
ship.consumeFuel();
}
}
}
// Update enemy drones
function updateEnemyDrones() {
for (var i = 0; i < enemyDrones.length; i++) {
var drone = enemyDrones[i];
// Set ship as target if it's close
var dx = ship.x - drone.x;
var dy = ship.y - drone.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 500) {
drone.setTarget(ship);
} else {
drone.setTarget(null);
}
}
}
// Update UI elements
function updateUI() {
// Update fuel bar
var fuelPercentage = ship.fuel / ship.maxFuel;
fuelBarFront.width = fuelBarBg.width * fuelPercentage;
// Change fuel bar color based on level
if (fuelPercentage <= 0.2) {
fuelBarFront.tint = 0xe74c3c; // Red
} else if (fuelPercentage <= 0.5) {
fuelBarFront.tint = 0xf39c12; // Orange
} else {
fuelBarFront.tint = 0x27ae60; // Green
}
// Update text displays
cargoText.setText('Cargo: ' + ship.cargo + '/' + ship.cargoCapacity);
scoreText.setText('Score: ' + score);
levelText.setText('Level: ' + level);
}
// Check for ship collisions with game objects
function checkCollisions() {
// Check asteroid collisions
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (ship.intersects(asteroid)) {
if (ship.shieldActive) {
// Destroy asteroid if shield is active
asteroid.destroy();
asteroids.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 5;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check enemy drone collisions
for (var i = enemyDrones.length - 1; i >= 0; i--) {
var drone = enemyDrones[i];
if (ship.intersects(drone)) {
if (ship.shieldActive) {
// Destroy drone if shield is active
drone.destroy();
enemyDrones.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 10;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check cargo container pickups
for (var i = cargoContainers.length - 1; i >= 0; i--) {
var container = cargoContainers[i];
// Check direct collision
if (ship.intersects(container)) {
if (ship.pickupCargo()) {
// Remove container and add points
container.destroy();
cargoContainers.splice(i, 1);
// Play pickup sound
LK.getSound('pickup').play();
// Add points
score += 10;
}
}
// Check magnet range
else if (ship.magnetActive) {
var dx = ship.x - container.x;
var dy = ship.y - container.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < ship.magnetRange) {
// Move container toward ship
container.x += dx / dist * 5;
container.y += dy / dist * 5;
container.originalY = container.y;
}
}
}
// Check space station delivery
for (var i = 0; i < spaceStations.length; i++) {
var station = spaceStations[i];
// Update flashing based on cargo status
// Only call startFlashing if cargo exists AND the station isn't already flashing
if (ship.cargo > 0 && !station.isFlashing) {
station.startFlashing();
}
// Only call stopFlashing if cargo is zero AND the station is currently flashing
else if (ship.cargo <= 0 && station.isFlashing) {
station.stopFlashing();
}
if (ship.intersects(station) && ship.cargo > 0) {
// Deliver cargo
var deliveredCargo = ship.deliverCargo();
// Add points
var deliveryPoints = deliveredCargo * 25;
score += deliveryPoints;
// Play delivery sound
LK.getSound('delivery').play();
// Flash screen green
LK.effects.flashScreen(0x27ae60, 300);
// Visual success feedback
tween(station, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(station, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
// Check for level up
if (score >= level * 100) {
levelUp();
}
}
}
// Check powerup pickups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (ship.intersects(powerup)) {
// Apply powerup effect
switch (powerup.type) {
case 'fuel':
ship.refuel(50);
break;
case 'shield':
ship.activateShield(8000);
break;
case 'magnet':
ship.activateMagnet(10000);
break;
}
// Play powerup sound
LK.getSound('powerup').play();
// Add points
score += 5;
// Remove powerup
powerup.destroy();
powerups.splice(i, 1);
}
}
// Check if out of fuel
if (ship.fuel <= 0 && gameActive) {
gameOver();
}
}
// Level up function
function levelUp() {
LK.getSound('levelUp').play(); // Play level up sound
level++;
// Update level text
levelText.setText('Level: ' + level);
// Flash screen
LK.effects.flashScreen(0xf1c40f, 500);
// Show level up message
var levelUpText = new Text2('LEVEL UP!', {
size: 120,
fill: 0xf1c40f
});
levelUpText.anchor.set(0.5, 0.5);
levelUpText.alpha = 0;
LK.gui.center.addChild(levelUpText);
tween(levelUpText, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 700,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(levelUpText, {
alpha: 0
}, {
duration: 700,
onFinish: function onFinish() {
levelUpText.destroy();
}
});
}
});
// Create new space station if needed
if (spaceStations.length < Math.min(3, Math.floor(level / 2) + 1)) {
createSpaceStation();
}
// Increase ship speed slightly
ship.speed = 6 + level * 0.3;
// Add visual effects to ship to indicate power increase
tween(ship, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(ship, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
// Game over function
function gameOver() {
LK.getSound('gameOver').play(); // Play game over sound
gameActive = false;
// Flash screen red
LK.effects.flashScreen(0xe74c3c, 1000);
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
// Visual feedback for new high score
var newHighScoreText = new Text2('NEW HIGH SCORE!', {
size: 80,
fill: 0xf1c40f
});
newHighScoreText.anchor.set(0.5, 0.5);
newHighScoreText.alpha = 0;
LK.gui.center.addChild(newHighScoreText);
tween(newHighScoreText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.elasticOut
});
LK.setTimeout(function () {
tween(newHighScoreText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
newHighScoreText.destroy();
}
});
}, 2000);
}
// Set final score
LK.setScore(score);
// Show game over
LK.showGameOver();
}
// Tutorial system
var tutorialSteps = ["Tap to guide your ship to that location", "Collect floating cargo containers", "Deliver cargo to the flashing space station", "Watch your fuel level at the bottom", "Avoid asteroids - collect shields for protection", "Deliver more cargo to level up!"];
var currentTutorialStep = 0;
var tutorialText;
var tutorialShown = storage.tutorialShown || false;
function showTutorialStep() {
if (!tutorialText) {
tutorialText = new Text2(tutorialSteps[0], {
size: 70,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tutorialText);
}
if (currentTutorialStep < tutorialSteps.length) {
tutorialText.setText(tutorialSteps[currentTutorialStep]);
tutorialText.alpha = 0;
tween(tutorialText, {
alpha: 1
}, {
duration: 500
});
LK.setTimeout(function () {
// Check if tutorialText still exists before tweening
if (tutorialText && tutorialText.parent) {
tween(tutorialText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
// Check if tutorialText still exists before proceeding
if (tutorialText && tutorialText.parent) {
currentTutorialStep++;
if (currentTutorialStep < tutorialSteps.length) {
LK.setTimeout(showTutorialStep, 1000);
} else {
tutorialText.destroy();
tutorialText = null;
storage.tutorialShown = true;
}
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}
});
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}, 4000);
}
}
// Initialize game
function initGame() {
// Initialize UI
initUI();
// Create ship
createShip();
// Create initial objects
for (var i = 0; i < 5; i++) {
createAsteroid();
}
for (var i = 0; i < 3; i++) {
createCargoContainer();
}
// Create initial space station
createSpaceStation();
// Create initial powerup
createPowerup('fuel');
// Start background music
LK.playMusic('gameMusic');
// Show tutorial for new players
if (!tutorialShown) {
LK.setTimeout(showTutorialStep, 1000);
}
// Add Glaud text element
var glaudText = new Text2('Glaud', {
size: 60,
fill: 0xffa500 // Orange color
});
glaudText.anchor.set(0, 1); // Anchor bottom-left
// Position Glaud in the bottom-left corner (away from the fuel bar and top-left menu)
glaudText.x = 50; // Padding from left edge, ensuring it's not in the top-left 100x100 area
glaudText.y = 2732 - 120; // Padding from bottom edge, positioned above the fuel bar GUI elements
game.addChild(glaudText); // Add text to the main game stage
}
function handleDown(x, y, obj) {
destX = x;
destY = y;
dragNode = ship; // Set dragNode to enable dragging in handleMove
}
// Handle game moves
function handleMove(x, y, obj) {
if (dragNode) {
destX = x;
destY = y;
}
}
// Handle game releases
function handleUp(x, y, obj) {
dragNode = null;
}
// Set event handlers
game.down = handleDown;
game.move = handleMove;
game.up = handleUp;
// Initialize the game
initGame();
// Game update loop
game.update = function () {
if (gameActive) {
// Spawn new objects based on level
spawnObjects();
// Update ship movement
updateShipMovement();
// Update enemy drones
updateEnemyDrones();
// Check collisions
checkCollisions();
// Update UI
updateUI();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.rotationSpeed = (Math.random() - 0.5) * 0.04;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
asteroidGraphics.rotation += self.rotationSpeed;
// Wrap around screen
var padding = asteroidGraphics.width / 2; // Use asset size for padding
if (self.x < -padding) {
self.x = 2048 + padding; // Use fixed width
}
if (self.x > 2048 + padding) {
// Use fixed width
self.x = -padding;
}
if (self.y < -padding) {
self.y = 2732 + padding; // Use fixed height
}
if (self.y > 2732 + padding) {
// Use fixed height
self.y = -padding;
}
};
return self;
});
var CargoContainer = Container.expand(function () {
var self = Container.call(this);
var cargoGraphics = self.attachAsset('cargoContainer', {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.02;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.update = function () {
self.bobPhase += self.bobSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var CargoShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('cargoShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.fuel = 100;
self.maxFuel = 100;
self.fuelConsumption = 0.05;
self.cargoCapacity = 3;
self.cargo = 0;
self.shieldActive = false;
self.magnetActive = false;
self.magnetRange = 300;
// Create visual shield effect
var shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4
});
shield.visible = false;
// Create visual magnet effect
var magnetIndicator = self.attachAsset('magnet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
magnetIndicator.visible = false;
self.activateShield = function (duration) {
if (!self.shieldActive) {
LK.getSound('shieldActivate').play(); // Play activation sound
self.shieldActive = true;
shield.visible = true;
shield.alpha = 0.1;
// Animate shield appearance
tween(shield, {
alpha: 0.6
}, {
duration: 500,
easing: tween.elasticOut
});
LK.setTimeout(function () {
// Fade out shield when expiring
tween(shield, {
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
self.shieldActive = false;
shield.visible = false;
shield.alpha = 0.4;
}
});
}, duration || 5000);
}
};
self.activateMagnet = function (duration) {
if (!self.magnetActive) {
var _pulseMagnet = function pulseMagnet() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.2
}, {
duration: 800,
onFinish: function onFinish() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.5
}, {
duration: 800,
onFinish: _pulseMagnet
});
}
}
});
}
};
LK.getSound('magnetActivate').play(); // Play activation sound
self.magnetActive = true;
magnetIndicator.visible = true;
magnetIndicator.alpha = 0.2;
magnetIndicator.scale.set(0.5, 0.5);
// Animate magnet field appearance
tween(magnetIndicator, {
alpha: 0.5,
scaleX: 6,
scaleY: 6
}, {
duration: 800,
easing: tween.elasticOut
});
// Pulse the magnet field
_pulseMagnet();
LK.setTimeout(function () {
// Fade out magnet field when expiring
tween(magnetIndicator, {
alpha: 0,
scaleX: 10,
scaleY: 10
}, {
duration: 1000,
onFinish: function onFinish() {
self.magnetActive = false;
magnetIndicator.visible = false;
magnetIndicator.scale.set(0.5, 0.5);
}
});
}, duration || 5000);
}
};
self.consumeFuel = function () {
self.fuel -= self.fuelConsumption;
if (self.fuel <= 0) {
self.fuel = 0;
}
if (self.fuel <= 20 && self.fuel > 19.95) {
LK.getSound('lowFuel').play();
}
};
self.refuel = function (amount) {
self.fuel = Math.min(self.fuel + amount, self.maxFuel);
};
self.pickupCargo = function () {
if (self.cargo < self.cargoCapacity) {
self.cargo++;
return true;
}
return false;
};
self.deliverCargo = function () {
var delivered = self.cargo;
self.cargo = 0;
return delivered;
};
return self;
});
var EnemyDrone = Container.expand(function () {
var self = Container.call(this);
var droneGraphics = self.attachAsset('enemyDrone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.target = null;
self.patrolRadius = 300;
self.patrolCenter = {
x: 0,
y: 0
};
self.patrolAngle = Math.random() * Math.PI * 2;
self.patrolSpeed = 0.01;
self.setPatrolCenter = function (x, y, radius) {
self.patrolCenter.x = x;
self.patrolCenter.y = y;
if (radius) {
self.patrolRadius = radius;
}
};
self.setTarget = function (target) {
self.target = target;
};
self.update = function () {
if (self.target) {
// Move toward target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
} else {
// Patrol in a circle
self.patrolAngle += self.patrolSpeed;
self.x = self.patrolCenter.x + Math.cos(self.patrolAngle) * self.patrolRadius;
self.y = self.patrolCenter.y + Math.sin(self.patrolAngle) * self.patrolRadius;
}
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fuel';
var assetType;
switch (self.type) {
case 'fuel':
assetType = 'fuelPowerup';
break;
case 'shield':
assetType = 'shieldPowerup';
break;
case 'magnet':
assetType = 'magnet';
break;
default:
assetType = 'fuelPowerup';
}
var powerupGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.03;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.rotationSpeed = 0.02;
self.update = function () {
self.bobPhase += self.bobSpeed;
powerupGraphics.rotation += self.rotationSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var SpaceStation = Container.expand(function () {
var self = Container.call(this);
var stationGraphics = self.attachAsset('spaceStation', {
anchorX: 0.5,
anchorY: 0.5
});
self.rotationSpeed = 0.002;
self.isFlashing = false;
self.pulseTime = 0;
self.pulseFrequency = 0.05;
// Function to make the station flash to indicate it's ready for delivery
self.startFlashing = function () {
if (!self.isFlashing) {
var _flashCycle = function flashCycle() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0xf1c40f
}, {
duration: 800,
onFinish: function onFinish() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 800,
onFinish: _flashCycle
});
}
}
});
}
};
self.isFlashing = true;
// Flash between colors
_flashCycle();
}
};
// Function to stop flashing
self.stopFlashing = function () {
self.isFlashing = false;
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 400
});
};
self.update = function () {
stationGraphics.rotation += self.rotationSpeed;
// Pulse effect
self.pulseTime += self.pulseFrequency;
var pulseFactor = 1 + Math.sin(self.pulseTime) * 0.1;
stationGraphics.scale.set(pulseFactor, pulseFactor);
};
// Start flashing by default
self.startFlashing();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Game state
var ship;
var asteroids = [];
var cargoContainers = [];
var spaceStations = [];
var enemyDrones = [];
var powerups = [];
var fuelBarBg;
var fuelBarFront;
var cargoText;
var scoreText;
var levelText;
var highScoreText;
var gameActive = true;
var level = 1;
var score = 0;
var highScore = storage.highScore || 0;
var destX = 0;
var destY = 0;
var dragNode = null;
var rotationTween = null; // Added to track ship rotation tween
var lastSpawnTime = 0;
var difficultyTimer;
// Initialize UI elements
function initUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 10; // Position adjusted slightly if needed, but 10 seems okay
LK.gui.top.addChild(scoreText);
// High score text
highScoreText = new Text2('Best: ' + highScore, {
size: 50,
// Increased size
fill: 0xFFFFFF
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 90; // Adjusted y position to account for larger scoreText above
LK.gui.top.addChild(highScoreText);
// Level text
levelText = new Text2('Level: 1', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
levelText.x = -50;
levelText.y = 10;
LK.gui.topRight.addChild(levelText);
// Cargo text
cargoText = new Text2('Cargo: 0/3', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
cargoText.anchor.set(0, 0);
cargoText.x = 120; // Moved further right to avoid menu icon
cargoText.y = 10;
LK.gui.topLeft.addChild(cargoText);
// Fuel bar background
fuelBarBg = LK.getAsset('fuelBarBackground', {
anchorX: 0.5,
anchorY: 0.5
});
fuelBarBg.x = 0;
fuelBarBg.y = 40;
LK.gui.bottom.addChild(fuelBarBg);
// Fuel bar
fuelBarFront = LK.getAsset('fuelBar', {
anchorX: 0,
anchorY: 0.5
});
fuelBarFront.x = -fuelBarBg.width / 2;
fuelBarFront.y = 40;
LK.gui.bottom.addChild(fuelBarFront);
// Add visual labels
var fuelLabel = new Text2('FUEL', {
size: 45,
// Increased size
fill: 0xFFFFFF
});
fuelLabel.anchor.set(0.5, 0.5);
fuelLabel.y = 40; // Position remains centered on the bar
LK.gui.bottom.addChild(fuelLabel);
}
// Create cargo ship
function createShip() {
ship = new CargoShip();
ship.x = 2048 / 2;
ship.y = 2732 / 2;
game.addChild(ship);
}
// Create random asteroid
function createAsteroid() {
var asteroid = new Asteroid();
// Random position on the edge of the screen
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
asteroid.x = Math.random() * 2048;
asteroid.y = -100;
break;
case 1:
// Right
asteroid.x = 2148;
asteroid.y = Math.random() * 2732;
break;
case 2:
// Bottom
asteroid.x = Math.random() * 2048;
asteroid.y = 2832;
break;
case 3:
// Left
asteroid.x = -100;
asteroid.y = Math.random() * 2732;
break;
}
// Random speed (higher in higher levels)
var baseSpeed = 2 + level * 0.5;
var speed = baseSpeed * (0.5 + Math.random() * 0.5);
// Direction toward center with some randomness
var targetX = 2048 / 2 + (Math.random() - 0.5) * 1000;
var targetY = 2732 / 2 + (Math.random() - 0.5) * 1000;
var dx = targetX - asteroid.x;
var dy = targetY - asteroid.y;
var dist = Math.sqrt(dx * dx + dy * dy);
asteroid.speedX = dx / dist * speed;
asteroid.speedY = dy / dist * speed;
// Scale randomly
var scale = 0.8 + Math.random() * 0.8;
asteroid.scale.set(scale, scale);
asteroids.push(asteroid);
game.addChild(asteroid);
}
// Create cargo container
function createCargoContainer() {
var container = new CargoContainer();
// Random position (not too close to the edge)
container.x = 200 + Math.random() * (2048 - 400);
container.y = 200 + Math.random() * (2732 - 400);
container.originalY = container.y;
cargoContainers.push(container);
game.addChild(container);
}
// Create space station
function createSpaceStation() {
var station = new SpaceStation();
// Position near an edge but not too close
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
station.x = 400 + Math.random() * (2048 - 800);
station.y = 300;
break;
case 1:
// Right
station.x = 2048 - 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
case 2:
// Bottom
station.x = 400 + Math.random() * (2048 - 800);
station.y = 2732 - 300;
break;
case 3:
// Left
station.x = 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
}
spaceStations.push(station);
game.addChild(station);
}
// Create enemy drone
function createEnemyDrone() {
var drone = new EnemyDrone();
// Random position
drone.x = Math.random() * 2048;
drone.y = Math.random() * 2732;
// Set patrol area
drone.setPatrolCenter(drone.x, drone.y, 200 + Math.random() * 200);
// Set speed based on level
drone.speed = 1 + level * 0.3;
enemyDrones.push(drone);
game.addChild(drone);
}
// Create powerup
function createPowerup(type) {
if (!type) {
var types = ['fuel', 'shield', 'magnet'];
type = types[Math.floor(Math.random() * types.length)];
}
var powerup = new Powerup(type);
// Random position (not too close to the edge)
powerup.x = 300 + Math.random() * (2048 - 600);
powerup.y = 300 + Math.random() * (2732 - 600);
powerup.originalY = powerup.y;
powerups.push(powerup);
game.addChild(powerup);
}
// Spawn game objects based on level
function spawnObjects() {
var currentTime = Date.now();
// Only spawn new objects every 1-3 seconds depending on level
var spawnRate = Math.max(3000 - level * 200, 1000);
if (currentTime - lastSpawnTime > spawnRate) {
// Spawn asteroid
if (asteroids.length < 5 + level * 2) {
createAsteroid();
}
// Spawn cargo
if (cargoContainers.length < 3 + Math.floor(level / 2)) {
createCargoContainer();
}
// Spawn enemy drones in higher levels
if (level >= 2 && enemyDrones.length < level - 1) {
createEnemyDrone();
}
// Spawn powerup (less frequently)
if (Math.random() < 0.2) {
createPowerup();
}
lastSpawnTime = currentTime;
}
}
// Update ship movement based on destination
function updateShipMovement() {
if (destX && destY) {
var dx = destX - ship.x;
var dy = destY - ship.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
// Calculate rotation angle to face destination
var angle = Math.atan2(dy, dx);
// Rotate ship to face direction of travel
// Stop existing rotation tween if it exists and is running
if (rotationTween && rotationTween.playing) {
rotationTween.stop();
}
rotationTween = tween(ship, {
rotation: angle
}, {
duration: 150 // Slightly faster rotation
});
// Move toward destination
ship.x += dx / dist * ship.speed;
ship.y += dy / dist * ship.speed;
// Consume fuel while moving
ship.consumeFuel();
}
}
}
// Update enemy drones
function updateEnemyDrones() {
for (var i = 0; i < enemyDrones.length; i++) {
var drone = enemyDrones[i];
// Set ship as target if it's close
var dx = ship.x - drone.x;
var dy = ship.y - drone.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 500) {
drone.setTarget(ship);
} else {
drone.setTarget(null);
}
}
}
// Update UI elements
function updateUI() {
// Update fuel bar
var fuelPercentage = ship.fuel / ship.maxFuel;
fuelBarFront.width = fuelBarBg.width * fuelPercentage;
// Change fuel bar color based on level
if (fuelPercentage <= 0.2) {
fuelBarFront.tint = 0xe74c3c; // Red
} else if (fuelPercentage <= 0.5) {
fuelBarFront.tint = 0xf39c12; // Orange
} else {
fuelBarFront.tint = 0x27ae60; // Green
}
// Update text displays
cargoText.setText('Cargo: ' + ship.cargo + '/' + ship.cargoCapacity);
scoreText.setText('Score: ' + score);
levelText.setText('Level: ' + level);
}
// Check for ship collisions with game objects
function checkCollisions() {
// Check asteroid collisions
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (ship.intersects(asteroid)) {
if (ship.shieldActive) {
// Destroy asteroid if shield is active
asteroid.destroy();
asteroids.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 5;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check enemy drone collisions
for (var i = enemyDrones.length - 1; i >= 0; i--) {
var drone = enemyDrones[i];
if (ship.intersects(drone)) {
if (ship.shieldActive) {
// Destroy drone if shield is active
drone.destroy();
enemyDrones.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 10;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check cargo container pickups
for (var i = cargoContainers.length - 1; i >= 0; i--) {
var container = cargoContainers[i];
// Check direct collision
if (ship.intersects(container)) {
if (ship.pickupCargo()) {
// Remove container and add points
container.destroy();
cargoContainers.splice(i, 1);
// Play pickup sound
LK.getSound('pickup').play();
// Add points
score += 10;
}
}
// Check magnet range
else if (ship.magnetActive) {
var dx = ship.x - container.x;
var dy = ship.y - container.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < ship.magnetRange) {
// Move container toward ship
container.x += dx / dist * 5;
container.y += dy / dist * 5;
container.originalY = container.y;
}
}
}
// Check space station delivery
for (var i = 0; i < spaceStations.length; i++) {
var station = spaceStations[i];
// Update flashing based on cargo status
// Only call startFlashing if cargo exists AND the station isn't already flashing
if (ship.cargo > 0 && !station.isFlashing) {
station.startFlashing();
}
// Only call stopFlashing if cargo is zero AND the station is currently flashing
else if (ship.cargo <= 0 && station.isFlashing) {
station.stopFlashing();
}
if (ship.intersects(station) && ship.cargo > 0) {
// Deliver cargo
var deliveredCargo = ship.deliverCargo();
// Add points
var deliveryPoints = deliveredCargo * 25;
score += deliveryPoints;
// Play delivery sound
LK.getSound('delivery').play();
// Flash screen green
LK.effects.flashScreen(0x27ae60, 300);
// Visual success feedback
tween(station, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(station, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
// Check for level up
if (score >= level * 100) {
levelUp();
}
}
}
// Check powerup pickups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (ship.intersects(powerup)) {
// Apply powerup effect
switch (powerup.type) {
case 'fuel':
ship.refuel(50);
break;
case 'shield':
ship.activateShield(8000);
break;
case 'magnet':
ship.activateMagnet(10000);
break;
}
// Play powerup sound
LK.getSound('powerup').play();
// Add points
score += 5;
// Remove powerup
powerup.destroy();
powerups.splice(i, 1);
}
}
// Check if out of fuel
if (ship.fuel <= 0 && gameActive) {
gameOver();
}
}
// Level up function
function levelUp() {
LK.getSound('levelUp').play(); // Play level up sound
level++;
// Update level text
levelText.setText('Level: ' + level);
// Flash screen
LK.effects.flashScreen(0xf1c40f, 500);
// Show level up message
var levelUpText = new Text2('LEVEL UP!', {
size: 120,
fill: 0xf1c40f
});
levelUpText.anchor.set(0.5, 0.5);
levelUpText.alpha = 0;
LK.gui.center.addChild(levelUpText);
tween(levelUpText, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 700,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(levelUpText, {
alpha: 0
}, {
duration: 700,
onFinish: function onFinish() {
levelUpText.destroy();
}
});
}
});
// Create new space station if needed
if (spaceStations.length < Math.min(3, Math.floor(level / 2) + 1)) {
createSpaceStation();
}
// Increase ship speed slightly
ship.speed = 6 + level * 0.3;
// Add visual effects to ship to indicate power increase
tween(ship, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(ship, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
// Game over function
function gameOver() {
LK.getSound('gameOver').play(); // Play game over sound
gameActive = false;
// Flash screen red
LK.effects.flashScreen(0xe74c3c, 1000);
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
// Visual feedback for new high score
var newHighScoreText = new Text2('NEW HIGH SCORE!', {
size: 80,
fill: 0xf1c40f
});
newHighScoreText.anchor.set(0.5, 0.5);
newHighScoreText.alpha = 0;
LK.gui.center.addChild(newHighScoreText);
tween(newHighScoreText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.elasticOut
});
LK.setTimeout(function () {
tween(newHighScoreText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
newHighScoreText.destroy();
}
});
}, 2000);
}
// Set final score
LK.setScore(score);
// Show game over
LK.showGameOver();
}
// Tutorial system
var tutorialSteps = ["Tap to guide your ship to that location", "Collect floating cargo containers", "Deliver cargo to the flashing space station", "Watch your fuel level at the bottom", "Avoid asteroids - collect shields for protection", "Deliver more cargo to level up!"];
var currentTutorialStep = 0;
var tutorialText;
var tutorialShown = storage.tutorialShown || false;
function showTutorialStep() {
if (!tutorialText) {
tutorialText = new Text2(tutorialSteps[0], {
size: 70,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tutorialText);
}
if (currentTutorialStep < tutorialSteps.length) {
tutorialText.setText(tutorialSteps[currentTutorialStep]);
tutorialText.alpha = 0;
tween(tutorialText, {
alpha: 1
}, {
duration: 500
});
LK.setTimeout(function () {
// Check if tutorialText still exists before tweening
if (tutorialText && tutorialText.parent) {
tween(tutorialText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
// Check if tutorialText still exists before proceeding
if (tutorialText && tutorialText.parent) {
currentTutorialStep++;
if (currentTutorialStep < tutorialSteps.length) {
LK.setTimeout(showTutorialStep, 1000);
} else {
tutorialText.destroy();
tutorialText = null;
storage.tutorialShown = true;
}
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}
});
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}, 4000);
}
}
// Initialize game
function initGame() {
// Initialize UI
initUI();
// Create ship
createShip();
// Create initial objects
for (var i = 0; i < 5; i++) {
createAsteroid();
}
for (var i = 0; i < 3; i++) {
createCargoContainer();
}
// Create initial space station
createSpaceStation();
// Create initial powerup
createPowerup('fuel');
// Start background music
LK.playMusic('gameMusic');
// Show tutorial for new players
if (!tutorialShown) {
LK.setTimeout(showTutorialStep, 1000);
}
// Add Glaud text element
var glaudText = new Text2('Glaud', {
size: 60,
fill: 0xffa500 // Orange color
});
glaudText.anchor.set(0, 1); // Anchor bottom-left
// Position Glaud in the bottom-left corner (away from the fuel bar and top-left menu)
glaudText.x = 50; // Padding from left edge, ensuring it's not in the top-left 100x100 area
glaudText.y = 2732 - 120; // Padding from bottom edge, positioned above the fuel bar GUI elements
game.addChild(glaudText); // Add text to the main game stage
}
function handleDown(x, y, obj) {
destX = x;
destY = y;
dragNode = ship; // Set dragNode to enable dragging in handleMove
}
// Handle game moves
function handleMove(x, y, obj) {
if (dragNode) {
destX = x;
destY = y;
}
}
// Handle game releases
function handleUp(x, y, obj) {
dragNode = null;
}
// Set event handlers
game.down = handleDown;
game.move = handleMove;
game.up = handleUp;
// Initialize the game
initGame();
// Game update loop
game.update = function () {
if (gameActive) {
// Spawn new objects based on level
spawnObjects();
// Update ship movement
updateShipMovement();
// Update enemy drones
updateEnemyDrones();
// Check collisions
checkCollisions();
// Update UI
updateUI();
}
};
asteroid. In-Game asset. 2d. High contrast. No shadows
cargoContainer. In-Game asset. 2d. High contrast. No shadows
cargo spaceShip. In-Game asset. 2d. High contrast. No shadows
enemy space ship. In-Game asset. 2d. High contrast. No shadows
fuelPowerup. In-Game asset. 2d. High contrast. No shadows
spaceStation. In-Game asset. 2d. High contrast. No shadows
magnet. In-Game asset. 2d. High contrast. No shadows
shieldPowerup. In-Game asset. 2d. High contrast. No shadows
shield. In-Game asset. 2d. High contrast. No shadows