/****
* 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
};