/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Boat = Container.expand(function () { var self = Container.call(this); // Attach boat graphics var boatGraphics = self.attachAsset('boat', { anchorX: 0.5, anchorY: 0.5 }); // Boat properties self.isDragging = false; self.lastIntersecting = false; // Position boat in center initially self.x = 2048 / 2; self.y = 2732 / 2; self.update = function () { // Add gentle bobbing animation boatGraphics.rotation = Math.sin(LK.ticks * 0.05) * 0.1; }; return self; }); var BrokenShip = Container.expand(function () { var self = Container.call(this); // Attach broken ship graphics var shipGraphics = self.attachAsset('broken_ship', { anchorX: 0.5, anchorY: 0.5 }); // Ship properties self.speed = 2; self.lastIntersecting = false; // Random spawn position self.x = Math.random() * 1800 + 124; // Keep away from edges self.y = -100; // Start above screen self.update = function () { // Move down slowly self.y += self.speed; // Add gentle floating animation shipGraphics.rotation = Math.sin(LK.ticks * 0.03) * 0.2; shipGraphics.x = Math.sin(LK.ticks * 0.02) * 5; }; // Check if ship is off screen self.isOffScreen = function () { return self.y > 2832; // Below screen }; return self; }); // Game variables var Wave = Container.expand(function (waveType, direction) { var self = Container.call(this); // Default parameters waveType = waveType || 'wave_medium'; direction = direction || 'down'; // Attach wave graphics var waveGraphics = self.attachAsset(waveType, { anchorX: 0.5, anchorY: 0.5 }); // Wave properties - adjust speed based on wave type if (waveType === 'wave_small') { self.speed = 4.5; // 50% faster (3 * 1.5) } else if (waveType === 'wave_medium') { self.speed = 3.75; // 25% faster (3 * 1.25) } else if (waveType === 'wave_large') { self.speed = 3.3; // 10% faster (3 * 1.1) } else { self.speed = 3; // Default speed } self.direction = direction; self.waveType = waveType; // Set initial position based on direction self.setStartPosition = function () { switch (self.direction) { case 'down': self.x = Math.random() * 2048; self.y = -200; break; case 'up': self.x = Math.random() * 2048; self.y = 2732 + 200; break; case 'right': self.x = -200; self.y = Math.random() * 2732; break; case 'left': self.x = 2048 + 200; self.y = Math.random() * 2732; break; } }; // Initialize starting position self.setStartPosition(); // Track last position for off-screen detection self.lastX = self.x; self.lastY = self.y; self.update = function () { // Move wave based on direction switch (self.direction) { case 'down': self.y += self.speed; break; case 'up': self.y -= self.speed; break; case 'right': self.x += self.speed; break; case 'left': self.x -= self.speed; break; } // Add subtle floating animation waveGraphics.y = Math.sin(LK.ticks * 0.1 + self.x * 0.01) * 10; }; // Check if wave is off screen self.isOffScreen = function () { return self.x < -300 || self.x > 2348 || self.y < -300 || self.y > 3032; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1E3A5F // Deep ocean blue }); /**** * Game Code ****/ // Game variables // Wave assets - different sizes for variety // Boat asset // Sound effects // Tween library for smooth wave animations and effects var waves = []; var brokenShips = []; var boat; var dragNode = null; var gameStartTime = LK.ticks; var waveSpawnTimer = 0; var shipSpawnTimer = 0; var difficulty = 1; var playerHealth = 100; var maxHealth = 100; var currentRound = 1; var roundWaveCount = 0; var roundWaveTarget = 15; // Waves to spawn per round var roundCompleted = false; var roundDisplayTimer = 0; // Define wave types for each round var roundWaveTypes = { 1: ['wave_small'], // First round: minors only 2: ['wave_small', 'wave_medium'], // Second round: medium-small mixed 3: ['wave_medium'], // Third round: medium only 4: ['wave_medium', 'wave_large'], // Fourth round: major-medium mixed 5: ['wave_large'], // Fifth round: major only 6: ['wave_small', 'wave_medium', 'wave_large'] // Sixth round: all types }; // Create title text var titleTxt = new Text2('Wave Escape', { size: 120, fill: 0x87CEEB }); titleTxt.anchor.set(0.5, 0); titleTxt.y = 100; LK.gui.top.addChild(titleTxt); // Create health bar background var healthBarBg = LK.getAsset('healthBarBg', { width: 400, height: 40, color: 0x333333, shape: 'box' }); healthBarBg.x = 20; healthBarBg.y = 20; LK.gui.topLeft.addChild(healthBarBg); // Create health bar fill var healthBarFill = LK.getAsset('healthBarFill', { width: 396, height: 36, color: 0x00FF00, shape: 'box' }); healthBarFill.x = 22; healthBarFill.y = 22; LK.gui.topLeft.addChild(healthBarFill); // Create health text var healthTxt = new Text2('Health: 100', { size: 30, fill: 0xFFFFFF }); healthTxt.anchor.set(0, 0); healthTxt.x = 20; healthTxt.y = 70; LK.gui.topLeft.addChild(healthTxt); // Create round text var roundTxt = new Text2('Round 1 - Minor Waves', { size: 50, fill: 0xFFD700 }); roundTxt.anchor.set(0.5, 0); roundTxt.x = 1024; roundTxt.y = 200; game.addChild(roundTxt); // Fade out title after 3 seconds LK.setTimeout(function () { tween(titleTxt, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { titleTxt.destroy(); } }); }, 3000); // Create boat boat = game.addChild(new Boat()); // Wave directions for variety var waveDirections = ['down', 'up', 'left', 'right']; var waveTypes = ['wave_small', 'wave_medium', 'wave_large']; // Handle mouse/touch movement function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; // Keep boat within screen bounds if (dragNode.x < 40) dragNode.x = 40; if (dragNode.x > 2008) dragNode.x = 2008; if (dragNode.y < 40) dragNode.y = 40; if (dragNode.y > 2692) dragNode.y = 2692; } } game.move = handleMove; game.down = function (x, y, obj) { // Start dragging the boat dragNode = boat; boat.isDragging = true; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; if (boat) boat.isDragging = false; }; // Spawn wave function function spawnWave() { // Don't spawn if round is completed and waiting if (roundCompleted) return; var direction = waveDirections[Math.floor(Math.random() * waveDirections.length)]; // Get wave types for current round var availableWaveTypes = roundWaveTypes[currentRound] || ['wave_small']; var waveType = availableWaveTypes[Math.floor(Math.random() * availableWaveTypes.length)]; // Adjust spawn chance based on direction for balance if (Math.random() > 0.7) { var newWave = new Wave(waveType, direction); newWave.speed += difficulty * 0.5; // Increase speed with difficulty waves.push(newWave); game.addChild(newWave); roundWaveCount++; // Check if round target reached if (roundWaveCount >= roundWaveTarget) { roundCompleted = true; roundDisplayTimer = 180; // 3 seconds display } } } // Spawn broken ship function function spawnBrokenShip() { if (Math.random() > 0.3) { // 70% chance to spawn var newShip = new BrokenShip(); brokenShips.push(newShip); game.addChild(newShip); } } game.update = function () { // Handle round progression if (roundCompleted) { roundDisplayTimer--; // Update round text based on completion status if (roundDisplayTimer > 0) { if (currentRound < 6) { roundTxt.setText('Round ' + currentRound + ' Complete! Next: Round ' + (currentRound + 1)); } else { roundTxt.setText('All Rounds Complete! You Win!'); } } else { // Move to next round or win if (currentRound < 6) { currentRound++; roundWaveCount = 0; roundCompleted = false; // Update round display text var roundNames = { 1: 'Minor Waves', 2: 'Mixed Small-Medium', 3: 'Medium Waves', 4: 'Mixed Medium-Large', 5: 'Major Waves', 6: 'All Wave Types' }; roundTxt.setText('Round ' + currentRound + ' - ' + roundNames[currentRound]); } else { // Player completed all rounds - show victory LK.showYouWin(); return; } } } else { // Normal round display var roundNames = { 1: 'Minor Waves', 2: 'Mixed Small-Medium', 3: 'Medium Waves', 4: 'Mixed Medium-Large', 5: 'Major Waves', 6: 'All Wave Types' }; var progress = Math.min(roundWaveCount, roundWaveTarget); roundTxt.setText('Round ' + currentRound + ' - ' + roundNames[currentRound] + ' (' + progress + '/' + roundWaveTarget + ')'); } // Update survival time var survivalTime = Math.floor((LK.ticks - gameStartTime) / 60); // Increase difficulty over time difficulty = 1 + survivalTime / 30; // Spawn waves with increasing frequency waveSpawnTimer++; var spawnRate = Math.max(30 - Math.floor(difficulty * 5), 10); if (waveSpawnTimer >= spawnRate) { spawnWave(); waveSpawnTimer = 0; } // Spawn broken ships occasionally shipSpawnTimer++; if (shipSpawnTimer >= 180) { // Spawn every 3 seconds spawnBrokenShip(); shipSpawnTimer = 0; } // Update and check waves for (var i = waves.length - 1; i >= 0; i--) { var wave = waves[i]; // Initialize last position tracking if (wave.lastIntersecting === undefined) { wave.lastIntersecting = false; } // Check for collision with boat var currentIntersecting = wave.intersects(boat); if (!wave.lastIntersecting && currentIntersecting) { // Collision detected - reduce health based on wave type! var healthReduction = 5; // Default for small waves if (wave.waveType === 'wave_medium') { healthReduction = 10; } else if (wave.waveType === 'wave_large') { healthReduction = 20; } playerHealth -= healthReduction; LK.getSound('wave_crash').play(); // Flash effect on collision tween(boat, { alpha: 0.3 }, { duration: 100, onFinish: function onFinish() { tween(boat, { alpha: 1 }, { duration: 100 }); } }); LK.effects.flashScreen(0xFF0000, 500); // Update health bar var healthPercentage = playerHealth / maxHealth; healthBarFill.width = 396 * healthPercentage; // Change health bar color based on health level if (healthPercentage > 0.6) { healthBarFill.tint = 0x00FF00; // Green } else if (healthPercentage > 0.3) { healthBarFill.tint = 0xFFFF00; // Yellow } else { healthBarFill.tint = 0xFF0000; // Red } healthTxt.setText('Health: ' + playerHealth); // Check if health is depleted if (playerHealth <= 0) { LK.showGameOver(); return; } // Remove the wave that hit us wave.destroy(); waves.splice(i, 1); continue; } // Remove waves that are off screen if (wave.isOffScreen()) { wave.destroy(); waves.splice(i, 1); continue; } // Update last intersecting state wave.lastIntersecting = currentIntersecting; } // Update and check broken ships for (var j = brokenShips.length - 1; j >= 0; j--) { var ship = brokenShips[j]; // Initialize last position tracking if (ship.lastIntersecting === undefined) { ship.lastIntersecting = false; } // Check for collection with boat var shipIntersecting = ship.intersects(boat); if (!ship.lastIntersecting && shipIntersecting) { // Ship collected! var healthIncrease = 20; // If health is already full, increase max health by 10 if (playerHealth >= maxHealth) { maxHealth += 10; playerHealth = maxHealth; } else { // Otherwise restore 20 health, but don't exceed max playerHealth = Math.min(playerHealth + healthIncrease, maxHealth); } LK.getSound('collect_ship').play(); // Flash effect on collection (green) tween(boat, { tint: 0x00FF00 }, { duration: 200, onFinish: function onFinish() { tween(boat, { tint: 0xFFFFFF }, { duration: 200 }); } }); // Update health bar var healthPercentage = playerHealth / maxHealth; healthBarFill.width = 396 * healthPercentage; // Update health bar color if (healthPercentage > 0.6) { healthBarFill.tint = 0x00FF00; // Green } else if (healthPercentage > 0.3) { healthBarFill.tint = 0xFFFF00; // Yellow } else { healthBarFill.tint = 0xFF0000; // Red } healthTxt.setText('Health: ' + playerHealth); // Remove the collected ship ship.destroy(); brokenShips.splice(j, 1); continue; } // Remove ships that are off screen if (ship.isOffScreen()) { ship.destroy(); brokenShips.splice(j, 1); continue; } // Update last intersecting state ship.lastIntersecting = shipIntersecting; } // Add occasional splash sound for atmosphere if (LK.ticks % 300 === 0 && Math.random() > 0.7) { LK.getSound('splash').play(); } // Victory is now handled by round completion system };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boat = Container.expand(function () {
var self = Container.call(this);
// Attach boat graphics
var boatGraphics = self.attachAsset('boat', {
anchorX: 0.5,
anchorY: 0.5
});
// Boat properties
self.isDragging = false;
self.lastIntersecting = false;
// Position boat in center initially
self.x = 2048 / 2;
self.y = 2732 / 2;
self.update = function () {
// Add gentle bobbing animation
boatGraphics.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
};
return self;
});
var BrokenShip = Container.expand(function () {
var self = Container.call(this);
// Attach broken ship graphics
var shipGraphics = self.attachAsset('broken_ship', {
anchorX: 0.5,
anchorY: 0.5
});
// Ship properties
self.speed = 2;
self.lastIntersecting = false;
// Random spawn position
self.x = Math.random() * 1800 + 124; // Keep away from edges
self.y = -100; // Start above screen
self.update = function () {
// Move down slowly
self.y += self.speed;
// Add gentle floating animation
shipGraphics.rotation = Math.sin(LK.ticks * 0.03) * 0.2;
shipGraphics.x = Math.sin(LK.ticks * 0.02) * 5;
};
// Check if ship is off screen
self.isOffScreen = function () {
return self.y > 2832; // Below screen
};
return self;
});
// Game variables
var Wave = Container.expand(function (waveType, direction) {
var self = Container.call(this);
// Default parameters
waveType = waveType || 'wave_medium';
direction = direction || 'down';
// Attach wave graphics
var waveGraphics = self.attachAsset(waveType, {
anchorX: 0.5,
anchorY: 0.5
});
// Wave properties - adjust speed based on wave type
if (waveType === 'wave_small') {
self.speed = 4.5; // 50% faster (3 * 1.5)
} else if (waveType === 'wave_medium') {
self.speed = 3.75; // 25% faster (3 * 1.25)
} else if (waveType === 'wave_large') {
self.speed = 3.3; // 10% faster (3 * 1.1)
} else {
self.speed = 3; // Default speed
}
self.direction = direction;
self.waveType = waveType;
// Set initial position based on direction
self.setStartPosition = function () {
switch (self.direction) {
case 'down':
self.x = Math.random() * 2048;
self.y = -200;
break;
case 'up':
self.x = Math.random() * 2048;
self.y = 2732 + 200;
break;
case 'right':
self.x = -200;
self.y = Math.random() * 2732;
break;
case 'left':
self.x = 2048 + 200;
self.y = Math.random() * 2732;
break;
}
};
// Initialize starting position
self.setStartPosition();
// Track last position for off-screen detection
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
// Move wave based on direction
switch (self.direction) {
case 'down':
self.y += self.speed;
break;
case 'up':
self.y -= self.speed;
break;
case 'right':
self.x += self.speed;
break;
case 'left':
self.x -= self.speed;
break;
}
// Add subtle floating animation
waveGraphics.y = Math.sin(LK.ticks * 0.1 + self.x * 0.01) * 10;
};
// Check if wave is off screen
self.isOffScreen = function () {
return self.x < -300 || self.x > 2348 || self.y < -300 || self.y > 3032;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1E3A5F // Deep ocean blue
});
/****
* Game Code
****/
// Game variables
// Wave assets - different sizes for variety
// Boat asset
// Sound effects
// Tween library for smooth wave animations and effects
var waves = [];
var brokenShips = [];
var boat;
var dragNode = null;
var gameStartTime = LK.ticks;
var waveSpawnTimer = 0;
var shipSpawnTimer = 0;
var difficulty = 1;
var playerHealth = 100;
var maxHealth = 100;
var currentRound = 1;
var roundWaveCount = 0;
var roundWaveTarget = 15; // Waves to spawn per round
var roundCompleted = false;
var roundDisplayTimer = 0;
// Define wave types for each round
var roundWaveTypes = {
1: ['wave_small'],
// First round: minors only
2: ['wave_small', 'wave_medium'],
// Second round: medium-small mixed
3: ['wave_medium'],
// Third round: medium only
4: ['wave_medium', 'wave_large'],
// Fourth round: major-medium mixed
5: ['wave_large'],
// Fifth round: major only
6: ['wave_small', 'wave_medium', 'wave_large'] // Sixth round: all types
};
// Create title text
var titleTxt = new Text2('Wave Escape', {
size: 120,
fill: 0x87CEEB
});
titleTxt.anchor.set(0.5, 0);
titleTxt.y = 100;
LK.gui.top.addChild(titleTxt);
// Create health bar background
var healthBarBg = LK.getAsset('healthBarBg', {
width: 400,
height: 40,
color: 0x333333,
shape: 'box'
});
healthBarBg.x = 20;
healthBarBg.y = 20;
LK.gui.topLeft.addChild(healthBarBg);
// Create health bar fill
var healthBarFill = LK.getAsset('healthBarFill', {
width: 396,
height: 36,
color: 0x00FF00,
shape: 'box'
});
healthBarFill.x = 22;
healthBarFill.y = 22;
LK.gui.topLeft.addChild(healthBarFill);
// Create health text
var healthTxt = new Text2('Health: 100', {
size: 30,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 20;
healthTxt.y = 70;
LK.gui.topLeft.addChild(healthTxt);
// Create round text
var roundTxt = new Text2('Round 1 - Minor Waves', {
size: 50,
fill: 0xFFD700
});
roundTxt.anchor.set(0.5, 0);
roundTxt.x = 1024;
roundTxt.y = 200;
game.addChild(roundTxt);
// Fade out title after 3 seconds
LK.setTimeout(function () {
tween(titleTxt, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
titleTxt.destroy();
}
});
}, 3000);
// Create boat
boat = game.addChild(new Boat());
// Wave directions for variety
var waveDirections = ['down', 'up', 'left', 'right'];
var waveTypes = ['wave_small', 'wave_medium', 'wave_large'];
// Handle mouse/touch movement
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// Keep boat within screen bounds
if (dragNode.x < 40) dragNode.x = 40;
if (dragNode.x > 2008) dragNode.x = 2008;
if (dragNode.y < 40) dragNode.y = 40;
if (dragNode.y > 2692) dragNode.y = 2692;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Start dragging the boat
dragNode = boat;
boat.isDragging = true;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
if (boat) boat.isDragging = false;
};
// Spawn wave function
function spawnWave() {
// Don't spawn if round is completed and waiting
if (roundCompleted) return;
var direction = waveDirections[Math.floor(Math.random() * waveDirections.length)];
// Get wave types for current round
var availableWaveTypes = roundWaveTypes[currentRound] || ['wave_small'];
var waveType = availableWaveTypes[Math.floor(Math.random() * availableWaveTypes.length)];
// Adjust spawn chance based on direction for balance
if (Math.random() > 0.7) {
var newWave = new Wave(waveType, direction);
newWave.speed += difficulty * 0.5; // Increase speed with difficulty
waves.push(newWave);
game.addChild(newWave);
roundWaveCount++;
// Check if round target reached
if (roundWaveCount >= roundWaveTarget) {
roundCompleted = true;
roundDisplayTimer = 180; // 3 seconds display
}
}
}
// Spawn broken ship function
function spawnBrokenShip() {
if (Math.random() > 0.3) {
// 70% chance to spawn
var newShip = new BrokenShip();
brokenShips.push(newShip);
game.addChild(newShip);
}
}
game.update = function () {
// Handle round progression
if (roundCompleted) {
roundDisplayTimer--;
// Update round text based on completion status
if (roundDisplayTimer > 0) {
if (currentRound < 6) {
roundTxt.setText('Round ' + currentRound + ' Complete! Next: Round ' + (currentRound + 1));
} else {
roundTxt.setText('All Rounds Complete! You Win!');
}
} else {
// Move to next round or win
if (currentRound < 6) {
currentRound++;
roundWaveCount = 0;
roundCompleted = false;
// Update round display text
var roundNames = {
1: 'Minor Waves',
2: 'Mixed Small-Medium',
3: 'Medium Waves',
4: 'Mixed Medium-Large',
5: 'Major Waves',
6: 'All Wave Types'
};
roundTxt.setText('Round ' + currentRound + ' - ' + roundNames[currentRound]);
} else {
// Player completed all rounds - show victory
LK.showYouWin();
return;
}
}
} else {
// Normal round display
var roundNames = {
1: 'Minor Waves',
2: 'Mixed Small-Medium',
3: 'Medium Waves',
4: 'Mixed Medium-Large',
5: 'Major Waves',
6: 'All Wave Types'
};
var progress = Math.min(roundWaveCount, roundWaveTarget);
roundTxt.setText('Round ' + currentRound + ' - ' + roundNames[currentRound] + ' (' + progress + '/' + roundWaveTarget + ')');
}
// Update survival time
var survivalTime = Math.floor((LK.ticks - gameStartTime) / 60);
// Increase difficulty over time
difficulty = 1 + survivalTime / 30;
// Spawn waves with increasing frequency
waveSpawnTimer++;
var spawnRate = Math.max(30 - Math.floor(difficulty * 5), 10);
if (waveSpawnTimer >= spawnRate) {
spawnWave();
waveSpawnTimer = 0;
}
// Spawn broken ships occasionally
shipSpawnTimer++;
if (shipSpawnTimer >= 180) {
// Spawn every 3 seconds
spawnBrokenShip();
shipSpawnTimer = 0;
}
// Update and check waves
for (var i = waves.length - 1; i >= 0; i--) {
var wave = waves[i];
// Initialize last position tracking
if (wave.lastIntersecting === undefined) {
wave.lastIntersecting = false;
}
// Check for collision with boat
var currentIntersecting = wave.intersects(boat);
if (!wave.lastIntersecting && currentIntersecting) {
// Collision detected - reduce health based on wave type!
var healthReduction = 5; // Default for small waves
if (wave.waveType === 'wave_medium') {
healthReduction = 10;
} else if (wave.waveType === 'wave_large') {
healthReduction = 20;
}
playerHealth -= healthReduction;
LK.getSound('wave_crash').play();
// Flash effect on collision
tween(boat, {
alpha: 0.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(boat, {
alpha: 1
}, {
duration: 100
});
}
});
LK.effects.flashScreen(0xFF0000, 500);
// Update health bar
var healthPercentage = playerHealth / maxHealth;
healthBarFill.width = 396 * healthPercentage;
// Change health bar color based on health level
if (healthPercentage > 0.6) {
healthBarFill.tint = 0x00FF00; // Green
} else if (healthPercentage > 0.3) {
healthBarFill.tint = 0xFFFF00; // Yellow
} else {
healthBarFill.tint = 0xFF0000; // Red
}
healthTxt.setText('Health: ' + playerHealth);
// Check if health is depleted
if (playerHealth <= 0) {
LK.showGameOver();
return;
}
// Remove the wave that hit us
wave.destroy();
waves.splice(i, 1);
continue;
}
// Remove waves that are off screen
if (wave.isOffScreen()) {
wave.destroy();
waves.splice(i, 1);
continue;
}
// Update last intersecting state
wave.lastIntersecting = currentIntersecting;
}
// Update and check broken ships
for (var j = brokenShips.length - 1; j >= 0; j--) {
var ship = brokenShips[j];
// Initialize last position tracking
if (ship.lastIntersecting === undefined) {
ship.lastIntersecting = false;
}
// Check for collection with boat
var shipIntersecting = ship.intersects(boat);
if (!ship.lastIntersecting && shipIntersecting) {
// Ship collected!
var healthIncrease = 20;
// If health is already full, increase max health by 10
if (playerHealth >= maxHealth) {
maxHealth += 10;
playerHealth = maxHealth;
} else {
// Otherwise restore 20 health, but don't exceed max
playerHealth = Math.min(playerHealth + healthIncrease, maxHealth);
}
LK.getSound('collect_ship').play();
// Flash effect on collection (green)
tween(boat, {
tint: 0x00FF00
}, {
duration: 200,
onFinish: function onFinish() {
tween(boat, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
// Update health bar
var healthPercentage = playerHealth / maxHealth;
healthBarFill.width = 396 * healthPercentage;
// Update health bar color
if (healthPercentage > 0.6) {
healthBarFill.tint = 0x00FF00; // Green
} else if (healthPercentage > 0.3) {
healthBarFill.tint = 0xFFFF00; // Yellow
} else {
healthBarFill.tint = 0xFF0000; // Red
}
healthTxt.setText('Health: ' + playerHealth);
// Remove the collected ship
ship.destroy();
brokenShips.splice(j, 1);
continue;
}
// Remove ships that are off screen
if (ship.isOffScreen()) {
ship.destroy();
brokenShips.splice(j, 1);
continue;
}
// Update last intersecting state
ship.lastIntersecting = shipIntersecting;
}
// Add occasional splash sound for atmosphere
if (LK.ticks % 300 === 0 && Math.random() > 0.7) {
LK.getSound('splash').play();
}
// Victory is now handled by round completion system
};