/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cloud = Container.expand(function (cloudType) {
var self = Container.call(this);
var cloudGraphics;
if (cloudType === 'small') {
cloudGraphics = self.attachAsset('cloudSmall', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.3;
} else {
cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.2;
}
self.cloudType = cloudType;
self.floatTimer = Math.random() * Math.PI * 2;
self.floatSpeed = 0.01 + Math.random() * 0.005;
self.originalY = 0;
self.update = function () {
// Gentle horizontal movement
self.x += self.speed;
// Gentle vertical floating
self.floatTimer += self.floatSpeed;
self.y = self.originalY + Math.sin(self.floatTimer) * 8;
// Reset position when cloud moves off screen
if (self.x > 2200) {
self.x = -150;
}
};
return self;
});
var Fish = Container.expand(function (fishType) {
var self = Container.call(this);
var fishGraphics;
if (fishType === 'small') {
fishGraphics = self.attachAsset('fishSmall', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 10;
self.speed = 2;
} else if (fishType === 'medium') {
fishGraphics = self.attachAsset('fishMedium', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 25;
self.speed = 1.5;
} else if (fishType === 'red') {
fishGraphics = self.attachAsset('fishRed', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 15;
self.speed = 1.8;
} else if (fishType === 'green') {
fishGraphics = self.attachAsset('fishGreen', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 20;
self.speed = 1.6;
} else if (fishType === 'yellow') {
fishGraphics = self.attachAsset('fishYellow', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 12;
self.speed = 2.2;
} else if (fishType === 'purple') {
fishGraphics = self.attachAsset('fishPurple', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 30;
self.speed = 1.4;
} else if (fishType === 'tiny') {
fishGraphics = self.attachAsset('fishTiny', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 5;
self.speed = 3;
} else if (fishType === 'huge') {
fishGraphics = self.attachAsset('fishHuge', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 100;
self.speed = 0.8;
} else {
fishGraphics = self.attachAsset('fishLarge', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 50;
self.speed = 1;
}
self.direction = Math.random() > 0.5 ? 1 : -1;
self.fishType = fishType;
self.caught = false;
// Add eyes to fish
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position eyes based on fish size
var eyeSpacing = fishGraphics.width * 0.3;
var eyeOffsetY = -fishGraphics.height * 0.1;
leftEye.x = -eyeSpacing / 2;
leftEye.y = eyeOffsetY;
leftPupil.x = -eyeSpacing / 2;
leftPupil.y = eyeOffsetY;
rightEye.x = eyeSpacing / 2;
rightEye.y = eyeOffsetY;
rightPupil.x = eyeSpacing / 2;
rightPupil.y = eyeOffsetY;
if (self.direction === -1) {
fishGraphics.scaleX = -1;
// Flip eyes for left-facing fish
leftEye.scaleX = -1;
leftPupil.scaleX = -1;
rightEye.scaleX = -1;
rightPupil.scaleX = -1;
}
self.update = function () {
if (!self.caught) {
self.x += self.speed * self.direction;
self.y += Math.sin(LK.ticks * 0.02 + self.x * 0.01) * 0.5;
}
};
return self;
});
var FishingLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('fishingLine', {
anchorX: 0.5,
anchorY: 0
});
var hookGraphics = self.attachAsset('hook', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.targetDepth = 0;
self.currentDepth = 0;
self.castPosition = 0;
lineGraphics.height = 10;
hookGraphics.y = 10;
hookGraphics.visible = false;
function castLine(x, targetY) {
self.isActive = true;
// Always cast from the ship's person position
self.x = ship.x + 30; // Person is at ship.x + 30
self.castPosition = self.x;
// Cast to much greater depths - allow casting all the way to bottom of game area
var maxDepth = 2732 - 400; // Full screen height minus water surface
self.targetDepth = Math.min(maxDepth, Math.max(200, targetY - 400 + 500)); // Ensure minimum depth and add extra depth
self.currentDepth = 0;
hookGraphics.visible = true;
hookGraphics.y = 0;
// Add visual enhancement - make line thicker when casting deep
var depthRatio = self.targetDepth / maxDepth;
lineGraphics.width = 4 + depthRatio * 6; // Line gets thicker for deeper casts (4-10px)
lineGraphics.tint = 0x654321 + Math.floor(depthRatio * 0x222222); // Slightly darker for deeper casts
tween(self, {
currentDepth: self.targetDepth
}, {
duration: 1500 + depthRatio * 1000,
//{S} // Longer animation for deeper casts
easing: tween.easeOut,
onFinish: function onFinish() {
LK.getSound('splash').play();
}
});
}
function reelIn() {
if (self.isActive) {
var depthRatio = self.currentDepth / (2732 - 400);
tween(self, {
currentDepth: 0
}, {
duration: 1000 + depthRatio * 800,
// Longer reel-in for deeper casts
easing: tween.easeIn,
onFinish: function onFinish() {
self.isActive = false;
hookGraphics.visible = false;
lineGraphics.height = 10;
lineGraphics.width = 4; // Reset line width
lineGraphics.tint = 0xffffff; // Reset line color
}
});
}
}
self.cast = castLine;
self.reel = reelIn;
self.update = function () {
if (self.isActive) {
lineGraphics.height = self.currentDepth + 10;
hookGraphics.y = self.currentDepth;
}
};
return self;
});
var Frog = Container.expand(function () {
var self = Container.call(this);
var frogGraphics = self.attachAsset('frog', {
anchorX: 0.5,
anchorY: 0.5
});
// Add eyes to frog
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position frog eyes on top of head
leftEye.x = -8;
leftEye.y = -8;
leftPupil.x = -8;
leftPupil.y = -8;
rightEye.x = 8;
rightEye.y = -8;
rightPupil.x = 8;
rightPupil.y = -8;
self.hopTimer = 0;
self.hopDelay = Math.random() * 180 + 120;
self.isHopping = false;
self.hop = function () {
self.isHopping = true;
var targetX = Math.random() * 1800 + 124;
var originalY = self.y;
tween(self, {
x: targetX,
y: originalY - 30
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: originalY
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isHopping = false;
self.hopTimer = 0;
self.hopDelay = Math.random() * 180 + 120;
}
});
}
});
};
self.update = function () {
self.hopTimer++;
if (self.hopTimer >= self.hopDelay && !self.isHopping) {
self.hop();
}
};
return self;
});
var Rock = Container.expand(function (rockType) {
var self = Container.call(this);
var rockGraphics;
if (rockType === 'large') {
rockGraphics = self.attachAsset('rockLarge', {
anchorX: 0.5,
anchorY: 1
});
} else {
rockGraphics = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 1
});
}
self.rockType = rockType;
return self;
});
var Seaweed = Container.expand(function (seaweedType) {
var self = Container.call(this);
var seaweedGraphics;
if (seaweedType === 'tall') {
seaweedGraphics = self.attachAsset('seaweedTall', {
anchorX: 0.5,
anchorY: 1
});
} else {
seaweedGraphics = self.attachAsset('seaweed', {
anchorX: 0.5,
anchorY: 1
});
}
self.seaweedType = seaweedType;
self.swayTimer = Math.random() * Math.PI * 2;
self.swaySpeed = 0.02 + Math.random() * 0.01;
self.update = function () {
self.swayTimer += self.swaySpeed;
seaweedGraphics.rotation = Math.sin(self.swayTimer) * 0.1;
};
return self;
});
var Ship = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 1
});
var mastGraphics = self.attachAsset('mast', {
anchorX: 0.5,
anchorY: 1
});
mastGraphics.x = -50;
mastGraphics.y = -120;
var personGraphics = self.attachAsset('person', {
anchorX: 0.5,
anchorY: 1
});
personGraphics.x = 30;
personGraphics.y = -120;
// Add eyes to person
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position person eyes on face
leftEye.x = 25;
leftEye.y = -100;
leftPupil.x = 25;
leftPupil.y = -100;
rightEye.x = 35;
rightEye.y = -100;
rightPupil.x = 35;
rightPupil.y = -100;
self.bobTimer = 0;
self.originalY = 0;
self.update = function () {
self.bobTimer += 0.02;
self.y = self.originalY + Math.sin(self.bobTimer) * 3;
};
return self;
});
var Sun = Container.expand(function () {
var self = Container.call(this);
var sunGraphics = self.attachAsset('sun', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowTimer = 0;
self.glowSpeed = 0.008;
self.update = function () {
// Gentle glow effect
self.glowTimer += self.glowSpeed;
var glowScale = 1 + Math.sin(self.glowTimer) * 0.1;
sunGraphics.scaleX = glowScale;
sunGraphics.scaleY = glowScale;
// Subtle alpha pulsing
sunGraphics.alpha = 0.9 + Math.sin(self.glowTimer * 1.5) * 0.1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var waterBackground = game.addChild(LK.getAsset('water', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 400
}));
var ship = game.addChild(new Ship());
ship.x = 1024;
ship.y = 400;
ship.originalY = 400;
var fishingLine = game.addChild(new FishingLine());
fishingLine.y = 350;
var fish = [];
var frogs = [];
var lilyPads = [];
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var instructionText = new Text2('Tap to cast line, tap again to reel in!', {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
instructionText.y = -20;
LK.gui.bottom.addChild(instructionText);
// Create fishing rod cast button
var castButton = new Text2('🎣 CAST', {
size: 80,
fill: 0xFFD700
});
castButton.anchor.set(1, 0);
castButton.x = -50;
castButton.y = 50;
LK.gui.topRight.addChild(castButton);
// Create sun in the sky
var sun = game.addChild(new Sun());
sun.x = 1600;
sun.y = 120;
// Create clouds with wind movement
var clouds = [];
for (var i = 0; i < 6; i++) {
var cloudType = Math.random() > 0.5 ? 'normal' : 'small';
var cloud = game.addChild(new Cloud(cloudType));
cloud.x = Math.random() * 2400 - 200; // Start some clouds off-screen
cloud.y = Math.random() * 200 + 80; // Sky area
cloud.originalY = cloud.y;
// Add gentle wind movement with tween
var windDelay = Math.random() * 3000;
LK.setTimeout(function () {
tween(cloud, {
x: cloud.x + Math.random() * 400 - 200
}, {
duration: 8000 + Math.random() * 4000,
easing: tween.easeInOut
});
}, windDelay);
clouds.push(cloud);
}
// Create lily pads
for (var i = 0; i < 8; i++) {
var lilyPad = game.addChild(LK.getAsset('lilyPad', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 1800 + 124,
y: Math.random() * 200 + 450
}));
lilyPads.push(lilyPad);
}
// Create underwater rocks at much greater depths and make them bigger
var rocks = [];
for (var i = 0; i < 20; i++) {
var rockType = Math.random() > 0.5 ? 'large' : 'normal'; // More large rocks
var rock = game.addChild(new Rock(rockType));
rock.x = Math.random() * 1800 + 124;
rock.y = Math.random() * 1200 + 1400; // Place rocks much deeper (1400-2600 range)
// Make rocks bigger with tween animation
var scaleMultiplier = Math.random() * 1.5 + 1.5; // Scale between 1.5x to 3x
tween(rock, {
scaleX: scaleMultiplier,
scaleY: scaleMultiplier
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeOut
});
rocks.push(rock);
}
// Create underwater seaweed
var seaweeds = [];
for (var i = 0; i < 20; i++) {
var seaweedType = Math.random() > 0.6 ? 'tall' : 'normal';
var seaweed = game.addChild(new Seaweed(seaweedType));
seaweed.x = Math.random() * 1800 + 124;
seaweed.y = Math.random() * 1200 + 1000; // Place seaweed throughout water depth
seaweeds.push(seaweed);
}
// Create frogs
for (var i = 0; i < 4; i++) {
var frog = game.addChild(new Frog());
frog.x = Math.random() * 1800 + 124;
frog.y = 380;
frogs.push(frog);
}
var fishSpawnTimer = 0;
var gameStarted = false;
function spawnFish() {
// More diverse fish types with emphasis on variety including tiny and huge fish
var fishTypes = ['tiny', 'small', 'small', 'small', 'medium', 'medium', 'large', 'red', 'green', 'yellow', 'purple', 'small', 'medium', 'large', 'huge'];
var randomType = fishTypes[Math.floor(Math.random() * fishTypes.length)];
var newFish = new Fish(randomType);
var spawnSide = Math.random() > 0.5;
if (spawnSide) {
newFish.x = -100;
newFish.direction = 1;
} else {
newFish.x = 2148;
newFish.direction = -1;
}
newFish.y = Math.random() * 1800 + 600; // Spawn fish much deeper (600-2400 range)
fish.push(newFish);
game.addChild(newFish);
}
function checkFishCatch() {
if (!fishingLine.isActive) return;
var hookX = fishingLine.x;
var hookY = fishingLine.y + fishingLine.currentDepth;
for (var i = fish.length - 1; i >= 0; i--) {
var currentFish = fish[i];
if (currentFish.caught) continue;
var distance = Math.sqrt(Math.pow(hookX - currentFish.x, 2) + Math.pow(hookY - currentFish.y, 2));
if (distance < 40) {
currentFish.caught = true;
LK.setScore(LK.getScore() + currentFish.points);
scoreText.setText('Score: ' + LK.getScore());
LK.getSound('catch').play();
tween(currentFish, {
alpha: 0,
scaleX: 1.5 * (currentFish.direction === -1 ? -1 : 1),
scaleY: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
currentFish.destroy();
}
});
fish.splice(i, 1);
fishingLine.reel();
break;
}
}
}
var shipMoving = false;
game.down = function (x, y, obj) {
// Convert game coordinates to GUI coordinates for button check
var guiPos = LK.gui.toLocal({
x: x,
y: y
});
var buttonLeft = castButton.x - castButton.width;
var buttonRight = castButton.x;
var buttonTop = castButton.y;
var buttonBottom = castButton.y + castButton.height;
var isOnButton = guiPos.x >= buttonLeft && guiPos.x <= buttonRight && guiPos.y >= buttonTop && guiPos.y <= buttonBottom;
// Check if tap is on cast button
if (isOnButton) {
if (fishingLine.isActive) {
fishingLine.reel();
} else if (!shipMoving) {
// Cast to a deep location in front of the ship
var castX = ship.x;
var castY = 1500; // Cast to deep waters
fishingLine.cast(castX, castY);
gameStarted = true;
}
return;
}
// Check if tap is on or near the ship (within ship bounds)
var shipLeft = ship.x - 150; // Ship width is 300, so half is 150
var shipRight = ship.x + 150;
var shipTop = ship.y - 120; // Ship height is 120
var shipBottom = ship.y;
var isOnShip = x >= shipLeft && x <= shipRight && y >= shipTop && y <= shipBottom;
// If fishing line is active, reel it in
if (fishingLine.isActive) {
fishingLine.reel();
return;
}
// If tap is on ship and ship is not moving, cast fishing line
if (isOnShip && !shipMoving) {
fishingLine.cast(x, y);
gameStarted = true;
return;
}
// If tap is on water (not on ship) and ship is not moving, move ship to that location
if (!isOnShip && !shipMoving && !fishingLine.isActive) {
shipMoving = true;
var targetX = Math.max(150, Math.min(1898, x)); // Keep ship within screen bounds
tween(ship, {
x: targetX
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
shipMoving = false;
}
});
}
};
game.update = function () {
if (!gameStarted) return;
fishSpawnTimer++;
// Spawn fish more frequently (every 60 ticks instead of 120)
if (fishSpawnTimer >= 60) {
spawnFish();
fishSpawnTimer = 0;
// Sometimes spawn multiple fish at once for abundance
if (Math.random() < 0.3) {
spawnFish();
}
}
// Clean up fish that have moved off screen
for (var i = fish.length - 1; i >= 0; i--) {
var currentFish = fish[i];
if (currentFish.x < -150 || currentFish.x > 2200) {
if (!currentFish.caught) {
currentFish.destroy();
fish.splice(i, 1);
}
}
}
checkFishCatch();
// Update cast button text based on fishing line state
if (fishingLine.isActive) {
castButton.setText('🎣 REEL');
castButton.fill = 0xFF6B35;
} else if (shipMoving) {
castButton.setText('🎣 WAIT');
castButton.fill = 0x888888;
} else {
castButton.setText('🎣 CAST');
castButton.fill = 0xFFD700;
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cloud = Container.expand(function (cloudType) {
var self = Container.call(this);
var cloudGraphics;
if (cloudType === 'small') {
cloudGraphics = self.attachAsset('cloudSmall', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.3;
} else {
cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.2;
}
self.cloudType = cloudType;
self.floatTimer = Math.random() * Math.PI * 2;
self.floatSpeed = 0.01 + Math.random() * 0.005;
self.originalY = 0;
self.update = function () {
// Gentle horizontal movement
self.x += self.speed;
// Gentle vertical floating
self.floatTimer += self.floatSpeed;
self.y = self.originalY + Math.sin(self.floatTimer) * 8;
// Reset position when cloud moves off screen
if (self.x > 2200) {
self.x = -150;
}
};
return self;
});
var Fish = Container.expand(function (fishType) {
var self = Container.call(this);
var fishGraphics;
if (fishType === 'small') {
fishGraphics = self.attachAsset('fishSmall', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 10;
self.speed = 2;
} else if (fishType === 'medium') {
fishGraphics = self.attachAsset('fishMedium', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 25;
self.speed = 1.5;
} else if (fishType === 'red') {
fishGraphics = self.attachAsset('fishRed', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 15;
self.speed = 1.8;
} else if (fishType === 'green') {
fishGraphics = self.attachAsset('fishGreen', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 20;
self.speed = 1.6;
} else if (fishType === 'yellow') {
fishGraphics = self.attachAsset('fishYellow', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 12;
self.speed = 2.2;
} else if (fishType === 'purple') {
fishGraphics = self.attachAsset('fishPurple', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 30;
self.speed = 1.4;
} else if (fishType === 'tiny') {
fishGraphics = self.attachAsset('fishTiny', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 5;
self.speed = 3;
} else if (fishType === 'huge') {
fishGraphics = self.attachAsset('fishHuge', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 100;
self.speed = 0.8;
} else {
fishGraphics = self.attachAsset('fishLarge', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 50;
self.speed = 1;
}
self.direction = Math.random() > 0.5 ? 1 : -1;
self.fishType = fishType;
self.caught = false;
// Add eyes to fish
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position eyes based on fish size
var eyeSpacing = fishGraphics.width * 0.3;
var eyeOffsetY = -fishGraphics.height * 0.1;
leftEye.x = -eyeSpacing / 2;
leftEye.y = eyeOffsetY;
leftPupil.x = -eyeSpacing / 2;
leftPupil.y = eyeOffsetY;
rightEye.x = eyeSpacing / 2;
rightEye.y = eyeOffsetY;
rightPupil.x = eyeSpacing / 2;
rightPupil.y = eyeOffsetY;
if (self.direction === -1) {
fishGraphics.scaleX = -1;
// Flip eyes for left-facing fish
leftEye.scaleX = -1;
leftPupil.scaleX = -1;
rightEye.scaleX = -1;
rightPupil.scaleX = -1;
}
self.update = function () {
if (!self.caught) {
self.x += self.speed * self.direction;
self.y += Math.sin(LK.ticks * 0.02 + self.x * 0.01) * 0.5;
}
};
return self;
});
var FishingLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('fishingLine', {
anchorX: 0.5,
anchorY: 0
});
var hookGraphics = self.attachAsset('hook', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.targetDepth = 0;
self.currentDepth = 0;
self.castPosition = 0;
lineGraphics.height = 10;
hookGraphics.y = 10;
hookGraphics.visible = false;
function castLine(x, targetY) {
self.isActive = true;
// Always cast from the ship's person position
self.x = ship.x + 30; // Person is at ship.x + 30
self.castPosition = self.x;
// Cast to much greater depths - allow casting all the way to bottom of game area
var maxDepth = 2732 - 400; // Full screen height minus water surface
self.targetDepth = Math.min(maxDepth, Math.max(200, targetY - 400 + 500)); // Ensure minimum depth and add extra depth
self.currentDepth = 0;
hookGraphics.visible = true;
hookGraphics.y = 0;
// Add visual enhancement - make line thicker when casting deep
var depthRatio = self.targetDepth / maxDepth;
lineGraphics.width = 4 + depthRatio * 6; // Line gets thicker for deeper casts (4-10px)
lineGraphics.tint = 0x654321 + Math.floor(depthRatio * 0x222222); // Slightly darker for deeper casts
tween(self, {
currentDepth: self.targetDepth
}, {
duration: 1500 + depthRatio * 1000,
//{S} // Longer animation for deeper casts
easing: tween.easeOut,
onFinish: function onFinish() {
LK.getSound('splash').play();
}
});
}
function reelIn() {
if (self.isActive) {
var depthRatio = self.currentDepth / (2732 - 400);
tween(self, {
currentDepth: 0
}, {
duration: 1000 + depthRatio * 800,
// Longer reel-in for deeper casts
easing: tween.easeIn,
onFinish: function onFinish() {
self.isActive = false;
hookGraphics.visible = false;
lineGraphics.height = 10;
lineGraphics.width = 4; // Reset line width
lineGraphics.tint = 0xffffff; // Reset line color
}
});
}
}
self.cast = castLine;
self.reel = reelIn;
self.update = function () {
if (self.isActive) {
lineGraphics.height = self.currentDepth + 10;
hookGraphics.y = self.currentDepth;
}
};
return self;
});
var Frog = Container.expand(function () {
var self = Container.call(this);
var frogGraphics = self.attachAsset('frog', {
anchorX: 0.5,
anchorY: 0.5
});
// Add eyes to frog
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position frog eyes on top of head
leftEye.x = -8;
leftEye.y = -8;
leftPupil.x = -8;
leftPupil.y = -8;
rightEye.x = 8;
rightEye.y = -8;
rightPupil.x = 8;
rightPupil.y = -8;
self.hopTimer = 0;
self.hopDelay = Math.random() * 180 + 120;
self.isHopping = false;
self.hop = function () {
self.isHopping = true;
var targetX = Math.random() * 1800 + 124;
var originalY = self.y;
tween(self, {
x: targetX,
y: originalY - 30
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: originalY
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isHopping = false;
self.hopTimer = 0;
self.hopDelay = Math.random() * 180 + 120;
}
});
}
});
};
self.update = function () {
self.hopTimer++;
if (self.hopTimer >= self.hopDelay && !self.isHopping) {
self.hop();
}
};
return self;
});
var Rock = Container.expand(function (rockType) {
var self = Container.call(this);
var rockGraphics;
if (rockType === 'large') {
rockGraphics = self.attachAsset('rockLarge', {
anchorX: 0.5,
anchorY: 1
});
} else {
rockGraphics = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 1
});
}
self.rockType = rockType;
return self;
});
var Seaweed = Container.expand(function (seaweedType) {
var self = Container.call(this);
var seaweedGraphics;
if (seaweedType === 'tall') {
seaweedGraphics = self.attachAsset('seaweedTall', {
anchorX: 0.5,
anchorY: 1
});
} else {
seaweedGraphics = self.attachAsset('seaweed', {
anchorX: 0.5,
anchorY: 1
});
}
self.seaweedType = seaweedType;
self.swayTimer = Math.random() * Math.PI * 2;
self.swaySpeed = 0.02 + Math.random() * 0.01;
self.update = function () {
self.swayTimer += self.swaySpeed;
seaweedGraphics.rotation = Math.sin(self.swayTimer) * 0.1;
};
return self;
});
var Ship = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 1
});
var mastGraphics = self.attachAsset('mast', {
anchorX: 0.5,
anchorY: 1
});
mastGraphics.x = -50;
mastGraphics.y = -120;
var personGraphics = self.attachAsset('person', {
anchorX: 0.5,
anchorY: 1
});
personGraphics.x = 30;
personGraphics.y = -120;
// Add eyes to person
var leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var leftPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = self.attachAsset('eyePupil', {
anchorX: 0.5,
anchorY: 0.5
});
// Position person eyes on face
leftEye.x = 25;
leftEye.y = -100;
leftPupil.x = 25;
leftPupil.y = -100;
rightEye.x = 35;
rightEye.y = -100;
rightPupil.x = 35;
rightPupil.y = -100;
self.bobTimer = 0;
self.originalY = 0;
self.update = function () {
self.bobTimer += 0.02;
self.y = self.originalY + Math.sin(self.bobTimer) * 3;
};
return self;
});
var Sun = Container.expand(function () {
var self = Container.call(this);
var sunGraphics = self.attachAsset('sun', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowTimer = 0;
self.glowSpeed = 0.008;
self.update = function () {
// Gentle glow effect
self.glowTimer += self.glowSpeed;
var glowScale = 1 + Math.sin(self.glowTimer) * 0.1;
sunGraphics.scaleX = glowScale;
sunGraphics.scaleY = glowScale;
// Subtle alpha pulsing
sunGraphics.alpha = 0.9 + Math.sin(self.glowTimer * 1.5) * 0.1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var waterBackground = game.addChild(LK.getAsset('water', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 400
}));
var ship = game.addChild(new Ship());
ship.x = 1024;
ship.y = 400;
ship.originalY = 400;
var fishingLine = game.addChild(new FishingLine());
fishingLine.y = 350;
var fish = [];
var frogs = [];
var lilyPads = [];
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var instructionText = new Text2('Tap to cast line, tap again to reel in!', {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
instructionText.y = -20;
LK.gui.bottom.addChild(instructionText);
// Create fishing rod cast button
var castButton = new Text2('🎣 CAST', {
size: 80,
fill: 0xFFD700
});
castButton.anchor.set(1, 0);
castButton.x = -50;
castButton.y = 50;
LK.gui.topRight.addChild(castButton);
// Create sun in the sky
var sun = game.addChild(new Sun());
sun.x = 1600;
sun.y = 120;
// Create clouds with wind movement
var clouds = [];
for (var i = 0; i < 6; i++) {
var cloudType = Math.random() > 0.5 ? 'normal' : 'small';
var cloud = game.addChild(new Cloud(cloudType));
cloud.x = Math.random() * 2400 - 200; // Start some clouds off-screen
cloud.y = Math.random() * 200 + 80; // Sky area
cloud.originalY = cloud.y;
// Add gentle wind movement with tween
var windDelay = Math.random() * 3000;
LK.setTimeout(function () {
tween(cloud, {
x: cloud.x + Math.random() * 400 - 200
}, {
duration: 8000 + Math.random() * 4000,
easing: tween.easeInOut
});
}, windDelay);
clouds.push(cloud);
}
// Create lily pads
for (var i = 0; i < 8; i++) {
var lilyPad = game.addChild(LK.getAsset('lilyPad', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 1800 + 124,
y: Math.random() * 200 + 450
}));
lilyPads.push(lilyPad);
}
// Create underwater rocks at much greater depths and make them bigger
var rocks = [];
for (var i = 0; i < 20; i++) {
var rockType = Math.random() > 0.5 ? 'large' : 'normal'; // More large rocks
var rock = game.addChild(new Rock(rockType));
rock.x = Math.random() * 1800 + 124;
rock.y = Math.random() * 1200 + 1400; // Place rocks much deeper (1400-2600 range)
// Make rocks bigger with tween animation
var scaleMultiplier = Math.random() * 1.5 + 1.5; // Scale between 1.5x to 3x
tween(rock, {
scaleX: scaleMultiplier,
scaleY: scaleMultiplier
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeOut
});
rocks.push(rock);
}
// Create underwater seaweed
var seaweeds = [];
for (var i = 0; i < 20; i++) {
var seaweedType = Math.random() > 0.6 ? 'tall' : 'normal';
var seaweed = game.addChild(new Seaweed(seaweedType));
seaweed.x = Math.random() * 1800 + 124;
seaweed.y = Math.random() * 1200 + 1000; // Place seaweed throughout water depth
seaweeds.push(seaweed);
}
// Create frogs
for (var i = 0; i < 4; i++) {
var frog = game.addChild(new Frog());
frog.x = Math.random() * 1800 + 124;
frog.y = 380;
frogs.push(frog);
}
var fishSpawnTimer = 0;
var gameStarted = false;
function spawnFish() {
// More diverse fish types with emphasis on variety including tiny and huge fish
var fishTypes = ['tiny', 'small', 'small', 'small', 'medium', 'medium', 'large', 'red', 'green', 'yellow', 'purple', 'small', 'medium', 'large', 'huge'];
var randomType = fishTypes[Math.floor(Math.random() * fishTypes.length)];
var newFish = new Fish(randomType);
var spawnSide = Math.random() > 0.5;
if (spawnSide) {
newFish.x = -100;
newFish.direction = 1;
} else {
newFish.x = 2148;
newFish.direction = -1;
}
newFish.y = Math.random() * 1800 + 600; // Spawn fish much deeper (600-2400 range)
fish.push(newFish);
game.addChild(newFish);
}
function checkFishCatch() {
if (!fishingLine.isActive) return;
var hookX = fishingLine.x;
var hookY = fishingLine.y + fishingLine.currentDepth;
for (var i = fish.length - 1; i >= 0; i--) {
var currentFish = fish[i];
if (currentFish.caught) continue;
var distance = Math.sqrt(Math.pow(hookX - currentFish.x, 2) + Math.pow(hookY - currentFish.y, 2));
if (distance < 40) {
currentFish.caught = true;
LK.setScore(LK.getScore() + currentFish.points);
scoreText.setText('Score: ' + LK.getScore());
LK.getSound('catch').play();
tween(currentFish, {
alpha: 0,
scaleX: 1.5 * (currentFish.direction === -1 ? -1 : 1),
scaleY: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
currentFish.destroy();
}
});
fish.splice(i, 1);
fishingLine.reel();
break;
}
}
}
var shipMoving = false;
game.down = function (x, y, obj) {
// Convert game coordinates to GUI coordinates for button check
var guiPos = LK.gui.toLocal({
x: x,
y: y
});
var buttonLeft = castButton.x - castButton.width;
var buttonRight = castButton.x;
var buttonTop = castButton.y;
var buttonBottom = castButton.y + castButton.height;
var isOnButton = guiPos.x >= buttonLeft && guiPos.x <= buttonRight && guiPos.y >= buttonTop && guiPos.y <= buttonBottom;
// Check if tap is on cast button
if (isOnButton) {
if (fishingLine.isActive) {
fishingLine.reel();
} else if (!shipMoving) {
// Cast to a deep location in front of the ship
var castX = ship.x;
var castY = 1500; // Cast to deep waters
fishingLine.cast(castX, castY);
gameStarted = true;
}
return;
}
// Check if tap is on or near the ship (within ship bounds)
var shipLeft = ship.x - 150; // Ship width is 300, so half is 150
var shipRight = ship.x + 150;
var shipTop = ship.y - 120; // Ship height is 120
var shipBottom = ship.y;
var isOnShip = x >= shipLeft && x <= shipRight && y >= shipTop && y <= shipBottom;
// If fishing line is active, reel it in
if (fishingLine.isActive) {
fishingLine.reel();
return;
}
// If tap is on ship and ship is not moving, cast fishing line
if (isOnShip && !shipMoving) {
fishingLine.cast(x, y);
gameStarted = true;
return;
}
// If tap is on water (not on ship) and ship is not moving, move ship to that location
if (!isOnShip && !shipMoving && !fishingLine.isActive) {
shipMoving = true;
var targetX = Math.max(150, Math.min(1898, x)); // Keep ship within screen bounds
tween(ship, {
x: targetX
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
shipMoving = false;
}
});
}
};
game.update = function () {
if (!gameStarted) return;
fishSpawnTimer++;
// Spawn fish more frequently (every 60 ticks instead of 120)
if (fishSpawnTimer >= 60) {
spawnFish();
fishSpawnTimer = 0;
// Sometimes spawn multiple fish at once for abundance
if (Math.random() < 0.3) {
spawnFish();
}
}
// Clean up fish that have moved off screen
for (var i = fish.length - 1; i >= 0; i--) {
var currentFish = fish[i];
if (currentFish.x < -150 || currentFish.x > 2200) {
if (!currentFish.caught) {
currentFish.destroy();
fish.splice(i, 1);
}
}
}
checkFishCatch();
// Update cast button text based on fishing line state
if (fishingLine.isActive) {
castButton.setText('🎣 REEL');
castButton.fill = 0xFF6B35;
} else if (shipMoving) {
castButton.setText('🎣 WAIT');
castButton.fill = 0x888888;
} else {
castButton.setText('🎣 CAST');
castButton.fill = 0xFFD700;
}
};