/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BigMonster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('bigMonster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.5 + Math.random() * 1.5; self.direction = Math.random() * Math.PI * 2; self.damage = 5; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; }; return self; }); var BigWave = Container.expand(function () { var self = Container.call(this); var waveGraphics = self.attachAsset('bigWave', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2 + Math.random() * 2; self.direction = Math.random() * Math.PI * 2; self.damage = 4; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Add slight rotation for wave effect waveGraphics.rotation += 0.015; }; return self; }); var HugeWave = Container.expand(function () { var self = Container.call(this); var waveGraphics = self.attachAsset('hugeWave', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.8 + Math.random() * 1.8; self.direction = Math.random() * Math.PI * 2; self.damage = 7; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Add slight rotation for wave effect waveGraphics.rotation += 0.012; }; return self; }); var KingMonster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('kingMonster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.2 + Math.random() * 1.2; self.direction = Math.random() * Math.PI * 2; self.damage = 10; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; }; return self; }); var PlayerShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = 100; self.lastDamageTime = 0; self.damageDelay = 1000; // 1 second invincibility after damage self.takeDamage = function (amount) { var currentTime = Date.now(); if (currentTime - self.lastDamageTime < self.damageDelay) { return false; // Still invincible } self.health -= amount; self.lastDamageTime = currentTime; // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 500); LK.getSound('damage').play(); if (self.health <= 0) { self.health = 0; return true; // Game over } return false; }; self.heal = function (amount) { var oldHealth = self.health; self.health = Math.min(self.maxHealth, self.health + amount); return self.health - oldHealth; // Return actual healing amount }; return self; }); var SeaMonster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('seaMonster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2 + Math.random() * 2; self.direction = Math.random() * Math.PI * 2; self.damage = 5; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; }; return self; }); var Wave = Container.expand(function () { var self = Container.call(this); var waveGraphics = self.attachAsset('wave', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3 + Math.random() * 3; self.direction = Math.random() * Math.PI * 2; self.damage = 2; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Add slight rotation for wave effect waveGraphics.rotation += 0.02; }; return self; }); var Wreck = Container.expand(function () { var self = Container.call(this); var wreckGraphics = self.attachAsset('wreck', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1 + Math.random(); self.direction = Math.random() * Math.PI * 2; self.update = function () { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Slight rotation for floating effect wreckGraphics.rotation += 0.01; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x001f3f }); /**** * Game Code ****/ // Game variables var player; var enemies = []; var wrecks = []; var gameStartTime = Date.now(); var lastSpawnTime = 0; var spawnDelay = 2000; // Start with 2 second spawn delay var difficultyTimer = 0; // UI elements var healthText = new Text2('Health: 100', { size: 60, fill: 0xFFFFFF }); healthText.anchor.set(0, 0); healthText.x = 150; healthText.y = 50; LK.gui.topLeft.addChild(healthText); var timeText = new Text2('Time: 0s', { size: 60, fill: 0xFFFFFF }); timeText.anchor.set(0.5, 0); LK.gui.top.addChild(timeText); // Create player player = game.addChild(new PlayerShip()); player.x = 1024; player.y = 1366; // Drag controls var dragNode = null; function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; // Keep player within bounds dragNode.x = Math.max(40, Math.min(2008, dragNode.x)); dragNode.y = Math.max(60, Math.min(2672, dragNode.y)); } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; function spawnEnemy() { var enemy; var spawnSide = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left var currentTime = Date.now(); var survivalTime = Math.floor((currentTime - gameStartTime) / 1000); var enemyType = Math.random(); // Time-based enemy spawning logic if (survivalTime < 60) { // Less than 60 seconds: only waves and monsters if (enemyType < 0.5) { enemy = new SeaMonster(); } else { enemy = new Wave(); } } else if (survivalTime < 120) { // 60-120 seconds: big monsters and big waves if (enemyType < 0.5) { enemy = new BigMonster(); } else { enemy = new BigWave(); } } else if (survivalTime < 150) { // 120-150 seconds: king monsters and huge waves if (enemyType < 0.5) { enemy = new KingMonster(); } else { enemy = new HugeWave(); } } else { // 150+ seconds: everything can spawn if (enemyType < 0.15) { enemy = new SeaMonster(); } else if (enemyType < 0.3) { enemy = new Wave(); } else if (enemyType < 0.5) { enemy = new BigWave(); } else if (enemyType < 0.7) { enemy = new BigMonster(); } else if (enemyType < 0.85) { enemy = new HugeWave(); } else { enemy = new KingMonster(); } } // Position enemy at edge of screen switch (spawnSide) { case 0: // top enemy.x = Math.random() * 2048; enemy.y = -50; break; case 1: // right enemy.x = 2098; enemy.y = Math.random() * 2732; break; case 2: // bottom enemy.x = Math.random() * 2048; enemy.y = 2782; break; case 3: // left enemy.x = -50; enemy.y = Math.random() * 2732; break; } // Point enemy toward center of screen var centerX = 1024; var centerY = 1366; enemy.direction = Math.atan2(centerY - enemy.y, centerX - enemy.x); enemies.push(enemy); game.addChild(enemy); } function spawnWreck() { var wreck = new Wreck(); // Spawn wreck from random edge var spawnSide = Math.floor(Math.random() * 4); switch (spawnSide) { case 0: // top wreck.x = Math.random() * 2048; wreck.y = -25; break; case 1: // right wreck.x = 2073; wreck.y = Math.random() * 2732; break; case 2: // bottom wreck.x = Math.random() * 2048; wreck.y = 2757; break; case 3: // left wreck.x = -25; wreck.y = Math.random() * 2732; break; } wrecks.push(wreck); game.addChild(wreck); } // Start music LK.playMusic('ocean'); game.update = function () { var currentTime = Date.now(); difficultyTimer++; // Update time display var survivalTime = Math.floor((currentTime - gameStartTime) / 1000); timeText.setText('Time: ' + survivalTime + 's'); // Check for game end at 300 seconds if (survivalTime >= 300) { LK.showYouWin(); return; } // Increase difficulty over time if (difficultyTimer % 1800 == 0) { // Every 30 seconds spawnDelay = Math.max(500, spawnDelay - 100); } // Spawn enemies if (currentTime - lastSpawnTime > spawnDelay) { spawnEnemy(); lastSpawnTime = currentTime; // Sometimes spawn wreck too if (Math.random() < 0.3) { spawnWreck(); } } // Update and check enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; // Check if enemy is off screen (far off) if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check collision with player if (enemy.intersects(player)) { var gameOver = player.takeDamage(enemy.damage); if (gameOver) { LK.showGameOver(); return; } // Update health display healthText.setText('Health: ' + player.health); // Remove enemy after hit enemy.destroy(); enemies.splice(i, 1); } } // Update and check wrecks for (var j = wrecks.length - 1; j >= 0; j--) { var wreck = wrecks[j]; // Check if wreck is off screen if (wreck.x < -100 || wreck.x > 2148 || wreck.y < -100 || wreck.y > 2832) { wreck.destroy(); wrecks.splice(j, 1); continue; } // Check collision with player if (wreck.intersects(player)) { var actualHealing = player.heal(10); if (actualHealing > 0) { // Healed healthText.setText('Health: ' + player.health); } else { // Health is full, increase max health by 5 player.maxHealth += 5; player.health = player.maxHealth; healthText.setText('Health: ' + player.health); } LK.getSound('pickup').play(); wreck.destroy(); wrecks.splice(j, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BigMonster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('bigMonster', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5 + Math.random() * 1.5;
self.direction = Math.random() * Math.PI * 2;
self.damage = 5;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
};
return self;
});
var BigWave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('bigWave', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 2;
self.direction = Math.random() * Math.PI * 2;
self.damage = 4;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Add slight rotation for wave effect
waveGraphics.rotation += 0.015;
};
return self;
});
var HugeWave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('hugeWave', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.8 + Math.random() * 1.8;
self.direction = Math.random() * Math.PI * 2;
self.damage = 7;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Add slight rotation for wave effect
waveGraphics.rotation += 0.012;
};
return self;
});
var KingMonster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('kingMonster', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.2 + Math.random() * 1.2;
self.direction = Math.random() * Math.PI * 2;
self.damage = 10;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = 100;
self.lastDamageTime = 0;
self.damageDelay = 1000; // 1 second invincibility after damage
self.takeDamage = function (amount) {
var currentTime = Date.now();
if (currentTime - self.lastDamageTime < self.damageDelay) {
return false; // Still invincible
}
self.health -= amount;
self.lastDamageTime = currentTime;
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('damage').play();
if (self.health <= 0) {
self.health = 0;
return true; // Game over
}
return false;
};
self.heal = function (amount) {
var oldHealth = self.health;
self.health = Math.min(self.maxHealth, self.health + amount);
return self.health - oldHealth; // Return actual healing amount
};
return self;
});
var SeaMonster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('seaMonster', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 2;
self.direction = Math.random() * Math.PI * 2;
self.damage = 5;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
};
return self;
});
var Wave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('wave', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 + Math.random() * 3;
self.direction = Math.random() * Math.PI * 2;
self.damage = 2;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Add slight rotation for wave effect
waveGraphics.rotation += 0.02;
};
return self;
});
var Wreck = Container.expand(function () {
var self = Container.call(this);
var wreckGraphics = self.attachAsset('wreck', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1 + Math.random();
self.direction = Math.random() * Math.PI * 2;
self.update = function () {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Slight rotation for floating effect
wreckGraphics.rotation += 0.01;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001f3f
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var wrecks = [];
var gameStartTime = Date.now();
var lastSpawnTime = 0;
var spawnDelay = 2000; // Start with 2 second spawn delay
var difficultyTimer = 0;
// UI elements
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
healthText.x = 150;
healthText.y = 50;
LK.gui.topLeft.addChild(healthText);
var timeText = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeText.anchor.set(0.5, 0);
LK.gui.top.addChild(timeText);
// Create player
player = game.addChild(new PlayerShip());
player.x = 1024;
player.y = 1366;
// Drag controls
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// Keep player within bounds
dragNode.x = Math.max(40, Math.min(2008, dragNode.x));
dragNode.y = Math.max(60, Math.min(2672, dragNode.y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
function spawnEnemy() {
var enemy;
var spawnSide = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
var currentTime = Date.now();
var survivalTime = Math.floor((currentTime - gameStartTime) / 1000);
var enemyType = Math.random();
// Time-based enemy spawning logic
if (survivalTime < 60) {
// Less than 60 seconds: only waves and monsters
if (enemyType < 0.5) {
enemy = new SeaMonster();
} else {
enemy = new Wave();
}
} else if (survivalTime < 120) {
// 60-120 seconds: big monsters and big waves
if (enemyType < 0.5) {
enemy = new BigMonster();
} else {
enemy = new BigWave();
}
} else if (survivalTime < 150) {
// 120-150 seconds: king monsters and huge waves
if (enemyType < 0.5) {
enemy = new KingMonster();
} else {
enemy = new HugeWave();
}
} else {
// 150+ seconds: everything can spawn
if (enemyType < 0.15) {
enemy = new SeaMonster();
} else if (enemyType < 0.3) {
enemy = new Wave();
} else if (enemyType < 0.5) {
enemy = new BigWave();
} else if (enemyType < 0.7) {
enemy = new BigMonster();
} else if (enemyType < 0.85) {
enemy = new HugeWave();
} else {
enemy = new KingMonster();
}
}
// Position enemy at edge of screen
switch (spawnSide) {
case 0:
// top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
// bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
// left
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
// Point enemy toward center of screen
var centerX = 1024;
var centerY = 1366;
enemy.direction = Math.atan2(centerY - enemy.y, centerX - enemy.x);
enemies.push(enemy);
game.addChild(enemy);
}
function spawnWreck() {
var wreck = new Wreck();
// Spawn wreck from random edge
var spawnSide = Math.floor(Math.random() * 4);
switch (spawnSide) {
case 0:
// top
wreck.x = Math.random() * 2048;
wreck.y = -25;
break;
case 1:
// right
wreck.x = 2073;
wreck.y = Math.random() * 2732;
break;
case 2:
// bottom
wreck.x = Math.random() * 2048;
wreck.y = 2757;
break;
case 3:
// left
wreck.x = -25;
wreck.y = Math.random() * 2732;
break;
}
wrecks.push(wreck);
game.addChild(wreck);
}
// Start music
LK.playMusic('ocean');
game.update = function () {
var currentTime = Date.now();
difficultyTimer++;
// Update time display
var survivalTime = Math.floor((currentTime - gameStartTime) / 1000);
timeText.setText('Time: ' + survivalTime + 's');
// Check for game end at 300 seconds
if (survivalTime >= 300) {
LK.showYouWin();
return;
}
// Increase difficulty over time
if (difficultyTimer % 1800 == 0) {
// Every 30 seconds
spawnDelay = Math.max(500, spawnDelay - 100);
}
// Spawn enemies
if (currentTime - lastSpawnTime > spawnDelay) {
spawnEnemy();
lastSpawnTime = currentTime;
// Sometimes spawn wreck too
if (Math.random() < 0.3) {
spawnWreck();
}
}
// Update and check enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check if enemy is off screen (far off)
if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check collision with player
if (enemy.intersects(player)) {
var gameOver = player.takeDamage(enemy.damage);
if (gameOver) {
LK.showGameOver();
return;
}
// Update health display
healthText.setText('Health: ' + player.health);
// Remove enemy after hit
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update and check wrecks
for (var j = wrecks.length - 1; j >= 0; j--) {
var wreck = wrecks[j];
// Check if wreck is off screen
if (wreck.x < -100 || wreck.x > 2148 || wreck.y < -100 || wreck.y > 2832) {
wreck.destroy();
wrecks.splice(j, 1);
continue;
}
// Check collision with player
if (wreck.intersects(player)) {
var actualHealing = player.heal(10);
if (actualHealing > 0) {
// Healed
healthText.setText('Health: ' + player.health);
} else {
// Health is full, increase max health by 5
player.maxHealth += 5;
player.health = player.maxHealth;
healthText.setText('Health: ' + player.health);
}
LK.getSound('pickup').play();
wreck.destroy();
wrecks.splice(j, 1);
}
}
};