/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -4;
self.collected = false;
// Animate coin rotation
tween(coinGraphics, {
rotation: Math.PI * 2
}, {
duration: 2000,
loop: true,
easing: tween.easeLinear
});
self.update = function () {
self.x += self.speed;
};
return self;
});
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishGraphics = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.gravity = 0.8;
self.swimForce = -12;
self.swim = function () {
self.velocityY = self.swimForce;
LK.getSound('swim').play();
// Animate swim effect
tween(fishGraphics, {
rotation: -0.3
}, {
duration: 150,
easing: tween.easeOut
});
tween(fishGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.easeIn
});
};
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotate fish based on velocity
fishGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocityY * 0.05));
// Keep fish within screen bounds - kill if hitting ceiling
if (self.y < 50) {
self.y = 50;
self.velocityY = 0;
// Fish hit ceiling - trigger game over
self.hitCeiling = true;
}
if (self.y > 2400) {
self.y = 2400;
self.velocityY = 0;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('shark', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = -4;
self.passed = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
var SeaDecoration = Container.expand(function (type) {
var self = Container.call(this);
var decorationGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -1;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x006994
});
/****
* Game Code
****/
// Game variables
var fish;
var obstacles = [];
var decorations = [];
var coins = [];
var spawnTimer = 0;
var decorationTimer = 0;
var coinTimer = 0;
var gameSpeed = 1;
var lastObstacleY = 0;
// Create ocean floor
var oceanFloor = game.addChild(LK.getAsset('oceanFloor', {
anchorX: 0,
anchorY: 1.0,
x: 0,
y: 2732
}));
// Create fish
fish = game.addChild(new Fish());
fish.x = 300;
fish.y = 1366;
// Create score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -150; // Offset from right edge
// Spawn obstacle function
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2200;
// Random Y position, but not too close to last obstacle
var minY = 200;
var maxY = 2200;
var targetY;
do {
targetY = minY + Math.random() * (maxY - minY);
} while (Math.abs(targetY - lastObstacleY) < 300);
obstacle.y = targetY;
lastObstacleY = targetY;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn decoration function
function spawnDecoration() {
var decorationType = Math.random() > 0.5 ? 'seaweed' : 'coral';
var decoration = new SeaDecoration(decorationType);
decoration.x = 2200;
decoration.y = 2732 - 150; // Near ocean floor
decorations.push(decoration);
game.addChild(decoration);
}
// Spawn coin function
function spawnCoin() {
var coin = new Coin();
coin.x = 2200;
coin.y = 300 + Math.random() * 1800; // Random Y position
coins.push(coin);
game.addChild(coin);
}
// Game input handling
game.down = function (x, y, obj) {
fish.swim();
};
// Main game update loop
game.update = function () {
// Check if fish hit ceiling
if (fish.hitCeiling) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
// Update spawn timers
spawnTimer++;
decorationTimer++;
coinTimer++;
// Spawn obstacles more frequently
var spawnRate = Math.max(30, 80 - Math.floor(LK.ticks / 1200)); // More frequent and faster difficulty increase
if (spawnTimer >= spawnRate) {
spawnObstacle();
spawnTimer = 0;
}
// Spawn decorations less frequently
if (decorationTimer >= 180) {
spawnDecoration();
decorationTimer = 0;
}
// Spawn coins occasionally
if (coinTimer >= 240) {
spawnCoin();
coinTimer = 0;
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check if obstacle passed fish (for scoring)
if (!obstacle.passed && obstacle.x < fish.x) {
obstacle.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
}
// Remove obstacles that are off screen
if (obstacle.x < -150) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection
if (fish.intersects(obstacle)) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
// Update decorations
for (var j = decorations.length - 1; j >= 0; j--) {
var decoration = decorations[j];
// Remove decorations that are off screen
if (decoration.x < -100) {
decoration.destroy();
decorations.splice(j, 1);
}
}
// Update coins
for (var k = coins.length - 1; k >= 0; k--) {
var coin = coins[k];
// Check coin collection
if (!coin.collected && fish.intersects(coin)) {
coin.collected = true;
LK.getSound('coin').play();
LK.setScore(LK.getScore() + 5); // Coins worth 5 points
scoreTxt.setText(LK.getScore());
coin.destroy();
coins.splice(k, 1);
continue;
}
// Remove coins that are off screen
if (coin.x < -100) {
coin.destroy();
coins.splice(k, 1);
}
}
// Check if fish hit ocean floor
if (fish.y >= 2600) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
// Increase game speed gradually
if (LK.ticks % 600 == 0) {
gameSpeed += 0.1;
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -4;
self.collected = false;
// Animate coin rotation
tween(coinGraphics, {
rotation: Math.PI * 2
}, {
duration: 2000,
loop: true,
easing: tween.easeLinear
});
self.update = function () {
self.x += self.speed;
};
return self;
});
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishGraphics = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.gravity = 0.8;
self.swimForce = -12;
self.swim = function () {
self.velocityY = self.swimForce;
LK.getSound('swim').play();
// Animate swim effect
tween(fishGraphics, {
rotation: -0.3
}, {
duration: 150,
easing: tween.easeOut
});
tween(fishGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.easeIn
});
};
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotate fish based on velocity
fishGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocityY * 0.05));
// Keep fish within screen bounds - kill if hitting ceiling
if (self.y < 50) {
self.y = 50;
self.velocityY = 0;
// Fish hit ceiling - trigger game over
self.hitCeiling = true;
}
if (self.y > 2400) {
self.y = 2400;
self.velocityY = 0;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('shark', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = -4;
self.passed = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
var SeaDecoration = Container.expand(function (type) {
var self = Container.call(this);
var decorationGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -1;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x006994
});
/****
* Game Code
****/
// Game variables
var fish;
var obstacles = [];
var decorations = [];
var coins = [];
var spawnTimer = 0;
var decorationTimer = 0;
var coinTimer = 0;
var gameSpeed = 1;
var lastObstacleY = 0;
// Create ocean floor
var oceanFloor = game.addChild(LK.getAsset('oceanFloor', {
anchorX: 0,
anchorY: 1.0,
x: 0,
y: 2732
}));
// Create fish
fish = game.addChild(new Fish());
fish.x = 300;
fish.y = 1366;
// Create score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -150; // Offset from right edge
// Spawn obstacle function
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2200;
// Random Y position, but not too close to last obstacle
var minY = 200;
var maxY = 2200;
var targetY;
do {
targetY = minY + Math.random() * (maxY - minY);
} while (Math.abs(targetY - lastObstacleY) < 300);
obstacle.y = targetY;
lastObstacleY = targetY;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn decoration function
function spawnDecoration() {
var decorationType = Math.random() > 0.5 ? 'seaweed' : 'coral';
var decoration = new SeaDecoration(decorationType);
decoration.x = 2200;
decoration.y = 2732 - 150; // Near ocean floor
decorations.push(decoration);
game.addChild(decoration);
}
// Spawn coin function
function spawnCoin() {
var coin = new Coin();
coin.x = 2200;
coin.y = 300 + Math.random() * 1800; // Random Y position
coins.push(coin);
game.addChild(coin);
}
// Game input handling
game.down = function (x, y, obj) {
fish.swim();
};
// Main game update loop
game.update = function () {
// Check if fish hit ceiling
if (fish.hitCeiling) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
// Update spawn timers
spawnTimer++;
decorationTimer++;
coinTimer++;
// Spawn obstacles more frequently
var spawnRate = Math.max(30, 80 - Math.floor(LK.ticks / 1200)); // More frequent and faster difficulty increase
if (spawnTimer >= spawnRate) {
spawnObstacle();
spawnTimer = 0;
}
// Spawn decorations less frequently
if (decorationTimer >= 180) {
spawnDecoration();
decorationTimer = 0;
}
// Spawn coins occasionally
if (coinTimer >= 240) {
spawnCoin();
coinTimer = 0;
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check if obstacle passed fish (for scoring)
if (!obstacle.passed && obstacle.x < fish.x) {
obstacle.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
}
// Remove obstacles that are off screen
if (obstacle.x < -150) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection
if (fish.intersects(obstacle)) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
// Update decorations
for (var j = decorations.length - 1; j >= 0; j--) {
var decoration = decorations[j];
// Remove decorations that are off screen
if (decoration.x < -100) {
decoration.destroy();
decorations.splice(j, 1);
}
}
// Update coins
for (var k = coins.length - 1; k >= 0; k--) {
var coin = coins[k];
// Check coin collection
if (!coin.collected && fish.intersects(coin)) {
coin.collected = true;
LK.getSound('coin').play();
LK.setScore(LK.getScore() + 5); // Coins worth 5 points
scoreTxt.setText(LK.getScore());
coin.destroy();
coins.splice(k, 1);
continue;
}
// Remove coins that are off screen
if (coin.x < -100) {
coin.destroy();
coins.splice(k, 1);
}
}
// Check if fish hit ocean floor
if (fish.y >= 2600) {
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
// Increase game speed gradually
if (LK.ticks % 600 == 0) {
gameSpeed += 0.1;
}
};