/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Character = Container.expand(function () { var self = Container.call(this); // Create base circle under character var base = self.attachAsset('characterBase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); // Character type (boy or girl) self.type = ""; // Character containers self.bodyContainer = new Container(); self.headContainer = new Container(); self.armsContainer = new Container(); self.legsContainer = new Container(); self.facialContainer = new Container(); // Add all containers to self self.addChild(self.legsContainer); self.addChild(self.bodyContainer); self.addChild(self.armsContainer); self.addChild(self.headContainer); self.addChild(self.facialContainer); // Animation properties self.bobTimer = 0; self.blinkTimer = 0; self.isBlinking = false; self.armSwingDirection = 1; // Initialize with type self.initialize = function (characterType) { self.type = characterType; // Reset containers self.bodyContainer.removeChildren(); self.headContainer.removeChildren(); self.armsContainer.removeChildren(); self.legsContainer.removeChildren(); self.facialContainer.removeChildren(); // Build character based on type if (characterType === "boy") { // Body var body = self.bodyContainer.attachAsset('boyBody', { anchorX: 0.5, anchorY: 0.5, y: 30 }); // Head var head = self.headContainer.attachAsset('boyHead', { anchorX: 0.5, anchorY: 0.5, y: -80 }); // Hair for boy character - simple short hair that sticks to the head var boyHairTop = self.headContainer.attachAsset('boyHair', { anchorX: 0.5, anchorY: 0.5, y: -120, width: 130, height: 40, scaleX: 1.1 }); // Left Eye var leftEye = self.facialContainer.attachAsset('boyEyes', { anchorX: 0.5, anchorY: 0.5, x: -25, y: -90 }); // Right Eye var rightEye = self.facialContainer.attachAsset('boyEyes', { anchorX: 0.5, anchorY: 0.5, x: 25, y: -90 }); // Mouth var mouth = self.facialContainer.attachAsset('boyMouth', { anchorX: 0.5, anchorY: 0.5, y: -60 }); // Left Arm var leftArm = self.armsContainer.attachAsset('boyArm', { anchorX: 0.5, anchorY: 0, x: -65, y: -20, rotation: 0.2 }); // Right Arm var rightArm = self.armsContainer.attachAsset('boyArm', { anchorX: 0.5, anchorY: 0, x: 65, y: -20, rotation: -0.2 }); // Left Leg var leftLeg = self.legsContainer.attachAsset('boyLeg', { anchorX: 0.5, anchorY: 0, x: -30, y: 100 }); // Right Leg var rightLeg = self.legsContainer.attachAsset('boyLeg', { anchorX: 0.5, anchorY: 0, x: 30, y: 100 }); } else { // Body var body = self.bodyContainer.attachAsset('girlBody', { anchorX: 0.5, anchorY: 0.5, y: 30 }); // Head var head = self.headContainer.attachAsset('girlHead', { anchorX: 0.5, anchorY: 0.5, y: -80 }); // Hair - main part var hair = self.headContainer.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0.5, y: -100 }); // Add additional hair sections for a more styled look var hairBangs = self.headContainer.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0.5, y: -120, width: 130, height: 50, scaleX: 1.1, scaleY: 0.6 }); // Side hair strands var leftHairStrand = self.headContainer.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0, x: -60, y: -100, width: 40, height: 120, scaleY: 1.2 }); var rightHairStrand = self.headContainer.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0, x: 60, y: -100, width: 40, height: 120, scaleY: 1.2 }); // Left Eye var leftEye = self.facialContainer.attachAsset('girlEyes', { anchorX: 0.5, anchorY: 0.5, x: -25, y: -90 }); // Right Eye var rightEye = self.facialContainer.attachAsset('girlEyes', { anchorX: 0.5, anchorY: 0.5, x: 25, y: -90 }); // Mouth var mouth = self.facialContainer.attachAsset('girlMouth', { anchorX: 0.5, anchorY: 0.5, y: -60 }); // Left Arm var leftArm = self.armsContainer.attachAsset('girlArm', { anchorX: 0.5, anchorY: 0, x: -65, y: -20, rotation: 0.2 }); // Right Arm var rightArm = self.armsContainer.attachAsset('girlArm', { anchorX: 0.5, anchorY: 0, x: 65, y: -20, rotation: -0.2 }); // Left Leg var leftLeg = self.legsContainer.attachAsset('girlLeg', { anchorX: 0.5, anchorY: 0, x: -30, y: 100 }); // Right Leg var rightLeg = self.legsContainer.attachAsset('girlLeg', { anchorX: 0.5, anchorY: 0, x: 30, y: 100 }); } ; LK.setInterval(function () { self.blink(); }, 3000); // Start with scale 0 self.scaleX = 0; self.scaleY = 0; }; // Blink animation self.blink = function () { if (self.isBlinking) { return; } var leftEye = self.facialContainer.children[0]; var rightEye = self.facialContainer.children[1]; self.isBlinking = true; // Close eyes tween(leftEye, { scaleY: 0.1 }, { duration: 100, easing: tween.easeOut }); tween(rightEye, { scaleY: 0.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Open eyes tween(leftEye, { scaleY: 1 }, { duration: 100, easing: tween.easeOut }); tween(rightEye, { scaleY: 1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { self.isBlinking = false; } }); } }); }; // Continuous update for idle animations self.update = function () { // Bob up and down self.bobTimer += 0.05; var bobOffset = Math.sin(self.bobTimer) * 5; self.headContainer.y = bobOffset * 0.5; self.bodyContainer.y = bobOffset * 0.3; // Swing arms slightly if (self.armsContainer.children.length >= 2) { var leftArm = self.armsContainer.children[0]; var rightArm = self.armsContainer.children[1]; leftArm.rotation = 0.2 + Math.sin(self.bobTimer) * 0.1; rightArm.rotation = -0.2 - Math.sin(self.bobTimer) * 0.1; } }; // Animate character appearance self.appear = function () { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.elasticOut }); // Add a little jump after appearing LK.setTimeout(function () { tween(self, { y: self.y - 30 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.y + 30 }, { duration: 400, easing: tween.bounceOut }); } }); }, 600); }; // Handle selection self.down = function (x, y, obj) { // Shrink when pressed tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); // Make eyes bigger on press if (self.facialContainer.children.length >= 2) { var leftEye = self.facialContainer.children[0]; var rightEye = self.facialContainer.children[1]; var mouth = self.facialContainer.children[2]; tween(leftEye, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, easing: tween.easeOut }); tween(rightEye, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, easing: tween.easeOut }); // Make the character smile when clicked if (mouth) { tween(mouth, { scaleX: 1.5, scaleY: 1.7, y: -55 }, { duration: 200, easing: tween.elasticOut }); } } }; self.up = function (x, y, obj) { // Play sound only if settingsButton.soundOn is true if (!settingsButton || settingsButton.soundOn) { LK.getSound('buttonClick').play(); } // Return eyes to normal if (self.facialContainer.children.length >= 2) { var leftEye = self.facialContainer.children[0]; var rightEye = self.facialContainer.children[1]; var mouth = self.facialContainer.children[2]; tween(leftEye, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); tween(rightEye, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); // Return mouth to normal if (mouth) { tween(mouth, { scaleX: 1.0, scaleY: 1.0, y: -60 }, { duration: 300, easing: tween.easeOut }); } } // Check if character is on a raft after startGame was called var parentIsRaft = obj.parent instanceof Raft; if (parentIsRaft) { // Get the raft instance var raft = obj.parent; // Show "Let's go!" text when clicked on raft var goText = new Text2("Let's go!", { size: 80, fill: 0xFF4500 }); goText.anchor.set(0.5, 0.5); goText.x = 0; goText.y = -150; goText.alpha = 0; self.addChild(goText); // Animate text appearance and fade away tween(goText, { alpha: 1, y: goText.y - 50 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // After appearing, fade out LK.setTimeout(function () { tween(goText, { alpha: 0, y: goText.y - 30 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.removeChild(goText); } }); }, 1000); } }); // Animate the raft moving down with character on it tween(raft, { y: 3000 // Move down beyond the screen }, { duration: 5000, easing: tween.easeIn, onFinish: function onFinish() { // Game completed or next scene could be triggered here LK.showYouWin(); } }); return; // Skip the rest of the function } // Show "Hello!" text when clicked (only in character selection) var helloText = new Text2("Hello!", { size: 80, fill: 0xFF4500 }); helloText.anchor.set(0.5, 0.5); helloText.x = 0; helloText.y = -150; helloText.alpha = 0; self.addChild(helloText); // Animate text appearance and fade away tween(helloText, { alpha: 1, y: helloText.y - 50 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // After appearing, fade out LK.setTimeout(function () { tween(helloText, { alpha: 0, y: helloText.y - 30 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.removeChild(helloText); } }); }, 1000); } }); // Expand then return to normal size tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { // Celebrate selection with a spin tween(self.headContainer, { rotation: Math.PI * 2 }, { duration: 500, easing: tween.elasticOut }); tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Character selected! characterSelected(self.type); } }); } }); }; return self; }); var Ocean = Container.expand(function () { var self = Container.call(this); // Water layers var waterBg = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, tint: 0x0066CC, // Deep blue width: 4096, // Double screen width height: 3000 }); // Create waves self.waves = []; for (var i = 0; i < 8; i++) { var wave = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, tint: 0x55AADD, // Lighter blue alpha: 0.4, width: 500 + Math.random() * 700, height: 30, x: Math.random() * 2048 - 1024, y: Math.random() * 1000 - 500 }); self.waves.push(wave); } // Animation properties self.waveTimer = 0; // Update wave positions self.update = function () { self.waveTimer += 0.02; // Animate each wave for (var i = 0; i < self.waves.length; i++) { var wave = self.waves[i]; wave.x += 0.5; // Slow movement right // Loop waves back to the left side when they go off screen if (wave.x > 2048 + wave.width / 2) { wave.x = -wave.width / 2; wave.y = Math.random() * 1000 - 500; } // Slight bobbing wave.y += Math.sin(self.waveTimer + i) * 0.5; } }; return self; }); var PlayButton = Container.expand(function () { var self = Container.call(this); // Create shadow first so it appears behind the button var shadow = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: 10, y: 10 }); // Create base circle var buttonBase = self.attachAsset('playButtonBase', { anchorX: 0.5, anchorY: 0.5 }); // Create play triangle and rotate it to point right var playIcon = self.attachAsset('playTriangle', { anchorX: 0.5, anchorY: 0.5, x: 15, // Offset slightly to the right for better visual centering rotation: Math.PI / 4 // 45 degrees in radians }); // Variables to track button state self.isPressed = false; self.isAnimating = false; // Set interactive state functions self.down = function (x, y, obj) { if (self.isAnimating) { return; } self.isPressed = true; // Shrink button when pressed tween(buttonBase, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); tween(playIcon, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); // Move shadow closer tween(shadow, { x: 5, y: 5 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { if (!self.isPressed || self.isAnimating) { return; } self.isPressed = false; self.isAnimating = true; // Play sound only if settingsButton.soundOn is true if (!settingsButton || settingsButton.soundOn) { LK.getSound('buttonClick').play(); } // Return to normal size with a bounce tween(buttonBase, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { tween(buttonBase, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { self.isAnimating = false; // Trigger the "play" action self.triggerPlay(); } }); } }); // Return play icon to normal with a bounce tween(playIcon, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { tween(playIcon, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); } }); // Return shadow to normal position tween(shadow, { x: 10, y: 10 }, { duration: 200, easing: tween.easeOut }); }; // Function called when button is clicked self.triggerPlay = function () { // Spin the button when clicked self.isAnimating = true; // Celebrate by spinning the button tween(self, { rotation: Math.PI * 2 }, { duration: 1000, easing: tween.elasticOut, onFinish: function onFinish() { self.rotation = 0; self.isAnimating = false; // Show character selection showCharacterSelection(); } }); }; // Idle animation to make the button more playful self.startIdleAnimation = function () { function pulseButton() { if (self.isPressed || self.isAnimating) { LK.setTimeout(pulseButton, 2000); return; } tween(buttonBase, { scaleX: 1.05, scaleY: 1.05 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(buttonBase, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(pulseButton, 2000); } }); } }); } // Start the idle animation LK.setTimeout(pulseButton, 2000); }; // Initial scale effect when the button appears buttonBase.scaleX = 0; buttonBase.scaleY = 0; playIcon.scaleX = 0; playIcon.scaleY = 0; shadow.scaleX = 0; shadow.scaleY = 0; self.appear = function () { tween(shadow, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.elasticOut }); tween(buttonBase, { scaleX: 1, scaleY: 1 }, { duration: 700, easing: tween.elasticOut }); tween(playIcon, { scaleX: 1, scaleY: 1 }, { duration: 700, easing: tween.elasticOut, onFinish: function onFinish() { self.startIdleAnimation(); } }); }; return self; }); var Raft = Container.expand(function () { var self = Container.call(this); // Create raft base var raftBase = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, tint: 0x8B4513, // Brown color for wood width: 400, height: 200 }); // Create wood planks for (var i = 0; i < 5; i++) { var plank = self.attachAsset('boyBody', { anchorX: 0.5, anchorY: 0.5, tint: 0x995533, // Slightly different brown width: 350, height: 30, y: -80 + i * 40 }); } // Bob animation values self.bobTimer = 0; self.bobAmount = 5; // Update for bobbing animation self.update = function () { self.bobTimer += 0.03; self.y = self.bobAmount * Math.sin(self.bobTimer); // Slight rotation to simulate waves self.rotation = Math.sin(self.bobTimer * 0.7) * 0.02; }; return self; }); var SettingsButton = Container.expand(function () { var self = Container.call(this); // Create shadow for button var shadow = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: 5, y: 5, scaleX: 0.6, scaleY: 0.6 }); // Create button base var buttonBase = self.attachAsset('playButtonBase', { anchorX: 0.5, anchorY: 0.5, tint: 0x555555, scaleX: 0.6, scaleY: 0.6 }); // Track sound state self.soundOn = true; // Add text to button var buttonText = new Text2("Sound ON", { size: 50, fill: '#FFFFFF' }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); // Variables to track button state self.isPressed = false; self.isAnimating = false; // Set interactive state functions self.down = function (x, y, obj) { if (self.isAnimating) { return; } self.isPressed = true; // Shrink button when pressed tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { if (!self.isPressed || self.isAnimating) { return; } self.isPressed = false; self.isAnimating = true; // Play sound only if sound is still on if (self.soundOn) { LK.getSound('buttonClick').play(); } // Return to normal size with a bounce tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { self.isAnimating = false; // Toggle sound self.toggleSound(); } }); } }); }; // Toggle sound on/off self.toggleSound = function () { self.soundOn = !self.soundOn; // Update button text buttonText.setText(self.soundOn ? "Sound ON" : "Sound OFF"); // Update button color tween(buttonBase, { tint: self.soundOn ? 0x555555 : 0x993333 }, { duration: 300, easing: tween.easeOut }); // Set global sound mute state using available methods if (self.soundOn) { // Use LK.getSound() to control individual sounds // Set volume back to normal for any future sounds var buttonSound = LK.getSound('buttonClick'); var gameMusic = LK.getSound('TheCool9'); if (buttonSound) { buttonSound.volume = 0.7; } if (gameMusic) { gameMusic.volume = 1.0; } } else { // Mute all sounds by setting their volume to 0 var buttonSound = LK.getSound('buttonClick'); var gameMusic = LK.getSound('TheCool9'); if (buttonSound) { buttonSound.volume = 0; } if (gameMusic) { gameMusic.volume = 0; } } }; // Initial animation when button appears self.appear = function () { self.scaleX = 0; self.scaleY = 0; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 700, easing: tween.elasticOut }); }; return self; }); var Shore = Container.expand(function () { var self = Container.call(this); // Create sandy beach var sand = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, tint: 0xF4D03F, // Sandy color width: 800, height: 500 }); // Create some palm trees var palm1 = self.attachAsset('boyBody', { anchorX: 0.5, anchorY: 1.0, tint: 0x6E2C00, // Brown trunk width: 40, height: 200, x: -150, y: -100, rotation: -0.1 }); var palm2 = self.attachAsset('boyBody', { anchorX: 0.5, anchorY: 1.0, tint: 0x6E2C00, // Brown trunk width: 40, height: 180, x: 180, y: -120, rotation: 0.15 }); // Create palm leaves var leaves1 = self.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0.5, tint: 0x2ECC71, // Green width: 200, height: 150, x: -150, y: -250 }); var leaves2 = self.attachAsset('girlHair', { anchorX: 0.5, anchorY: 0.5, tint: 0x2ECC71, // Green width: 200, height: 150, x: 180, y: -270 }); return self; }); var StartGameButton = Container.expand(function () { var self = Container.call(this); // Create shadow for button var shadow = self.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, x: 10, y: 10 }); // Create button base var buttonBase = self.attachAsset('playButtonBase', { anchorX: 0.5, anchorY: 0.5, tint: 0x4CAF50 // Green color for start button }); // Add text to button var buttonText = new Text2("Start Game", { size: 80, fill: '#FFFFFF' }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); // Variables to track button state self.isPressed = false; self.isAnimating = false; // Set interactive state functions self.down = function (x, y, obj) { if (self.isAnimating) { return; } self.isPressed = true; // Shrink button when pressed tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); // Move shadow closer tween(shadow, { x: 5, y: 5 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { if (!self.isPressed || self.isAnimating) { return; } self.isPressed = false; self.isAnimating = true; // Play sound only if settingsButton.soundOn is true if (!settingsButton || settingsButton.soundOn) { LK.getSound('buttonClick').play(); } // Return to normal size with a bounce tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { self.isAnimating = false; // Make button disappear tween(self, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Remove button if (self.parent) { self.parent.removeChild(self); } // Find raft and character var raft = null; var shore = null; var character = null; // Find raft and shore in the scene for (var i = 0; i < game.children.length; i++) { if (game.children[i] instanceof Raft) { raft = game.children[i]; } if (game.children[i] instanceof Shore) { shore = game.children[i]; } } if (raft && raft.children.length > 0) { // Find the character in the raft for (var j = 0; j < raft.children.length; j++) { if (raft.children[j] instanceof Character) { character = raft.children[j]; } } if (character && shore) { // Move character out of raft var globalCharPos = raft.toGlobal(character.position); game.addChild(character); character.position = globalCharPos; // Make character swim animation var swimToShore = function swimToShore() { // Make character "swim" by moving arms and legs if (character.armsContainer && character.armsContainer.children.length >= 2) { var leftArm = character.armsContainer.children[0]; var rightArm = character.armsContainer.children[1]; // Animate arms in swimming motion tween.loop(leftArm, { rotation: [-0.2, 0.8, -0.2] }, { duration: 800 }); tween.loop(rightArm, { rotation: [0.2, -0.8, 0.2] }, { duration: 800 }); } if (character.legsContainer && character.legsContainer.children.length >= 2) { var leftLeg = character.legsContainer.children[0]; var rightLeg = character.legsContainer.children[1]; // Animate legs in swimming motion tween.loop(leftLeg, { rotation: [0, 0.3, 0] }, { duration: 600 }); tween.loop(rightLeg, { rotation: [0, -0.3, 0] }, { duration: 600 }); } // Move character toward shore tween(character, { y: shore.y - 100 // Stop just above shore }, { duration: 5000, easing: tween.easeInOut, onFinish: function onFinish() { // Character reached the shore // Stop swimming animation if (character.armsContainer && character.armsContainer.children.length >= 2) { tween.stopAll(character.armsContainer.children[0]); tween.stopAll(character.armsContainer.children[1]); } if (character.legsContainer && character.legsContainer.children.length >= 2) { tween.stopAll(character.legsContainer.children[0]); tween.stopAll(character.legsContainer.children[1]); } // Show celebration var celebrateText = new Text2("Made it to shore!", { size: 100, fill: 0xFF4500 }); celebrateText.anchor.set(0.5, 0.5); celebrateText.x = 2048 / 2; celebrateText.y = 500; celebrateText.alpha = 0; game.addChild(celebrateText); tween(celebrateText, { alpha: 1, y: celebrateText.y - 50 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Show win screen after delay LK.setTimeout(function () { LK.showYouWin(); }, 2000); } }); } }); }; // Move raft away to simulate "exiting" the raft tween(raft, { y: raft.y - 150, rotation: 0.3 }, { duration: 1000, easing: tween.easeOut, onFinish: swimToShore }); } } } }); } }); } }); // Return shadow to normal position tween(shadow, { x: 10, y: 10 }, { duration: 200, easing: tween.easeOut }); }; // Initial animation when button appears self.appear = function () { self.scaleX = 0; self.scaleY = 0; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 700, easing: tween.elasticOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x00FF00 }); /**** * Game Code ****/ // Set the game's background color to a softer green game.setBackgroundColor(0x66CC99); // Game state variables var showingCharacterSelection = false; var selectedCharacter = null; var boyCharacter = null; var girlCharacter = null; // Create and add settings button var settingsButton = new SettingsButton(); game.addChild(settingsButton); // Position in top right with some margin settingsButton.x = 2048 - 120; settingsButton.y = 120; // Make the button appear with animation settingsButton.appear(); // Update function for character animations and ocean/raft game.update = function () { // Update character animations if they exist if (boyCharacter) { boyCharacter.update(); } if (girlCharacter) { girlCharacter.update(); } // Update ocean and raft if they exist for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child instanceof Ocean) { child.update(); } if (child instanceof Raft) { child.update(); } } }; // Create the play button and center it on screen var playButton = new PlayButton(); game.addChild(playButton); // Position the button in the center of the screen playButton.x = 2048 / 2; playButton.y = 2732 / 2; // Make the button appear with animation playButton.appear(); // Function to show character selection screen function showCharacterSelection() { if (showingCharacterSelection) { return; } showingCharacterSelection = true; // Make play button disappear tween(playButton, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Remove play button from display game.removeChild(playButton); // Create character options boyCharacter = new Character(); boyCharacter.initialize("boy"); game.addChild(boyCharacter); boyCharacter.x = 2048 / 3; boyCharacter.y = 2732 / 2; girlCharacter = new Character(); girlCharacter.initialize("girl"); game.addChild(girlCharacter); girlCharacter.x = 2048 * 2 / 3; girlCharacter.y = 2732 / 2; // Make characters appear with animation boyCharacter.appear(); girlCharacter.appear(); } }); } // Function called when a character is selected function characterSelected(characterType) { selectedCharacter = characterType; console.log("Selected character: " + characterType); // Make the non-selected character sad and disappear var nonSelectedCharacter = characterType === "boy" ? girlCharacter : boyCharacter; var selectedCharacterObj = characterType === "boy" ? boyCharacter : girlCharacter; // Make selected character happy if (selectedCharacterObj.facialContainer.children.length >= 3) { var mouth = selectedCharacterObj.facialContainer.children[2]; // Make mouth bigger and smile tween(mouth, { scaleX: 1.5, scaleY: 1.5, y: -55 }, { duration: 300, easing: tween.elasticOut }); } // Make non-selected character sad if (nonSelectedCharacter.facialContainer.children.length >= 3) { var sadMouth = nonSelectedCharacter.facialContainer.children[2]; // Make mouth smaller and frown tween(sadMouth, { scaleX: 0.8, scaleY: -1.2, y: -50 }, { duration: 300, easing: tween.easeOut }); } // Fade out and shrink non-selected character tween(nonSelectedCharacter, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(nonSelectedCharacter); } }); // Jump and move the selected character to center LK.setTimeout(function () { // Jump up first tween(selectedCharacterObj, { y: selectedCharacterObj.y - 100 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { // Move to center while in air tween(selectedCharacterObj, { x: 2048 / 2 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { // Land with bounce tween(selectedCharacterObj, { y: 2732 / 2, scaleY: 0.7, scaleX: 1.3 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { // Bounce back to normal tween(selectedCharacterObj, { scaleY: 1.1, scaleX: 0.9 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Return to normal scale tween(selectedCharacterObj, { scaleY: 1.0, scaleX: 1.0 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Celebrate with a spin tween(selectedCharacterObj.headContainer, { rotation: Math.PI * 2 }, { duration: 800, easing: tween.elasticOut, onFinish: function onFinish() { // Reset rotation selectedCharacterObj.headContainer.rotation = 0; // Add start game button var startGameBtn = new StartGameButton(); game.addChild(startGameBtn); startGameBtn.x = 2048 / 2; startGameBtn.y = 2732 / 2 + 350; // Position below character startGameBtn.appear(); } }); } }); } }); } }); } }); } }); }, 300); } // Function to start the game function startGame() { console.log("Starting game with character: " + selectedCharacter); // Store the current background color var originalBackgroundColor = game.backgroundColor; // Create a black overlay for the screen var blackOverlay = new Container(); var blackBg = blackOverlay.attachAsset('buttonShadow', { anchorX: 0.5, anchorY: 0.5, width: 4096, // Make it twice the screen width to ensure full coverage height: 5464, // Make it twice the screen height to ensure full coverage tint: 0x000000, // Pure black alpha: 0 }); game.addChild(blackOverlay); blackOverlay.x = 2048 / 2; blackOverlay.y = 2732 / 2; // Fade to black tween(blackBg, { alpha: 1 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Wait for 3 seconds with black screen LK.setTimeout(function () { // Create ocean scene var ocean = new Ocean(); ocean.x = 2048 / 2; ocean.y = 2732 / 2; game.addChild(ocean); // Create shore at the far side var shore = new Shore(); shore.x = 2048 / 2; shore.y = 3000; // Position below the screen game.addChild(shore); // Create raft and position it in the center var raft = new Raft(); raft.x = 2048 / 2; raft.y = 2732 / 2; game.addChild(raft); // Add the selected character to the raft var selectedCharacterObj = selectedCharacter === "boy" ? boyCharacter : girlCharacter; // Move character to raft raft.addChild(selectedCharacterObj); selectedCharacterObj.x = 0; selectedCharacterObj.y = -80; // Position on raft // Remove settings button and any remaining UI if (settingsButton && settingsButton.parent) { game.removeChild(settingsButton); } // Create start game button to trigger swimming animation var startGameBtn = new StartGameButton(); game.addChild(startGameBtn); startGameBtn.x = 2048 / 2; startGameBtn.y = 2732 - 200; // Position near bottom startGameBtn.appear(); // Fade the black screen out tween(blackBg, { alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { // Remove the black overlay game.removeChild(blackOverlay); // Set game background to sky blue game.setBackgroundColor(0x87CEEB); } }); }, 3000); } }); } // Rainbow effect for the background var rainbowColors = [0x66CC99, 0x66CCFF, 0xCC99FF, 0xFF99CC, 0xFFCC66, 0x99FF99]; var currentColorIndex = 0; // A function to cycle through background colors function cycleBackgroundColor() { currentColorIndex = (currentColorIndex + 1) % rainbowColors.length; // Animate the color change var targetColor = rainbowColors[currentColorIndex]; tween(game, { backgroundColor: targetColor }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Schedule the next color change LK.setTimeout(cycleBackgroundColor, 4000); } }); } // Start the background color animation after a delay LK.setTimeout(cycleBackgroundColor, 4000);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
// Create base circle under character
var base = self.attachAsset('characterBase', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
// Character type (boy or girl)
self.type = "";
// Character containers
self.bodyContainer = new Container();
self.headContainer = new Container();
self.armsContainer = new Container();
self.legsContainer = new Container();
self.facialContainer = new Container();
// Add all containers to self
self.addChild(self.legsContainer);
self.addChild(self.bodyContainer);
self.addChild(self.armsContainer);
self.addChild(self.headContainer);
self.addChild(self.facialContainer);
// Animation properties
self.bobTimer = 0;
self.blinkTimer = 0;
self.isBlinking = false;
self.armSwingDirection = 1;
// Initialize with type
self.initialize = function (characterType) {
self.type = characterType;
// Reset containers
self.bodyContainer.removeChildren();
self.headContainer.removeChildren();
self.armsContainer.removeChildren();
self.legsContainer.removeChildren();
self.facialContainer.removeChildren();
// Build character based on type
if (characterType === "boy") {
// Body
var body = self.bodyContainer.attachAsset('boyBody', {
anchorX: 0.5,
anchorY: 0.5,
y: 30
});
// Head
var head = self.headContainer.attachAsset('boyHead', {
anchorX: 0.5,
anchorY: 0.5,
y: -80
});
// Hair for boy character - simple short hair that sticks to the head
var boyHairTop = self.headContainer.attachAsset('boyHair', {
anchorX: 0.5,
anchorY: 0.5,
y: -120,
width: 130,
height: 40,
scaleX: 1.1
});
// Left Eye
var leftEye = self.facialContainer.attachAsset('boyEyes', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: -90
});
// Right Eye
var rightEye = self.facialContainer.attachAsset('boyEyes', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: -90
});
// Mouth
var mouth = self.facialContainer.attachAsset('boyMouth', {
anchorX: 0.5,
anchorY: 0.5,
y: -60
});
// Left Arm
var leftArm = self.armsContainer.attachAsset('boyArm', {
anchorX: 0.5,
anchorY: 0,
x: -65,
y: -20,
rotation: 0.2
});
// Right Arm
var rightArm = self.armsContainer.attachAsset('boyArm', {
anchorX: 0.5,
anchorY: 0,
x: 65,
y: -20,
rotation: -0.2
});
// Left Leg
var leftLeg = self.legsContainer.attachAsset('boyLeg', {
anchorX: 0.5,
anchorY: 0,
x: -30,
y: 100
});
// Right Leg
var rightLeg = self.legsContainer.attachAsset('boyLeg', {
anchorX: 0.5,
anchorY: 0,
x: 30,
y: 100
});
} else {
// Body
var body = self.bodyContainer.attachAsset('girlBody', {
anchorX: 0.5,
anchorY: 0.5,
y: 30
});
// Head
var head = self.headContainer.attachAsset('girlHead', {
anchorX: 0.5,
anchorY: 0.5,
y: -80
});
// Hair - main part
var hair = self.headContainer.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0.5,
y: -100
});
// Add additional hair sections for a more styled look
var hairBangs = self.headContainer.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0.5,
y: -120,
width: 130,
height: 50,
scaleX: 1.1,
scaleY: 0.6
});
// Side hair strands
var leftHairStrand = self.headContainer.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0,
x: -60,
y: -100,
width: 40,
height: 120,
scaleY: 1.2
});
var rightHairStrand = self.headContainer.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0,
x: 60,
y: -100,
width: 40,
height: 120,
scaleY: 1.2
});
// Left Eye
var leftEye = self.facialContainer.attachAsset('girlEyes', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: -90
});
// Right Eye
var rightEye = self.facialContainer.attachAsset('girlEyes', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: -90
});
// Mouth
var mouth = self.facialContainer.attachAsset('girlMouth', {
anchorX: 0.5,
anchorY: 0.5,
y: -60
});
// Left Arm
var leftArm = self.armsContainer.attachAsset('girlArm', {
anchorX: 0.5,
anchorY: 0,
x: -65,
y: -20,
rotation: 0.2
});
// Right Arm
var rightArm = self.armsContainer.attachAsset('girlArm', {
anchorX: 0.5,
anchorY: 0,
x: 65,
y: -20,
rotation: -0.2
});
// Left Leg
var leftLeg = self.legsContainer.attachAsset('girlLeg', {
anchorX: 0.5,
anchorY: 0,
x: -30,
y: 100
});
// Right Leg
var rightLeg = self.legsContainer.attachAsset('girlLeg', {
anchorX: 0.5,
anchorY: 0,
x: 30,
y: 100
});
}
;
LK.setInterval(function () {
self.blink();
}, 3000);
// Start with scale 0
self.scaleX = 0;
self.scaleY = 0;
};
// Blink animation
self.blink = function () {
if (self.isBlinking) {
return;
}
var leftEye = self.facialContainer.children[0];
var rightEye = self.facialContainer.children[1];
self.isBlinking = true;
// Close eyes
tween(leftEye, {
scaleY: 0.1
}, {
duration: 100,
easing: tween.easeOut
});
tween(rightEye, {
scaleY: 0.1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Open eyes
tween(leftEye, {
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
tween(rightEye, {
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isBlinking = false;
}
});
}
});
};
// Continuous update for idle animations
self.update = function () {
// Bob up and down
self.bobTimer += 0.05;
var bobOffset = Math.sin(self.bobTimer) * 5;
self.headContainer.y = bobOffset * 0.5;
self.bodyContainer.y = bobOffset * 0.3;
// Swing arms slightly
if (self.armsContainer.children.length >= 2) {
var leftArm = self.armsContainer.children[0];
var rightArm = self.armsContainer.children[1];
leftArm.rotation = 0.2 + Math.sin(self.bobTimer) * 0.1;
rightArm.rotation = -0.2 - Math.sin(self.bobTimer) * 0.1;
}
};
// Animate character appearance
self.appear = function () {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.elasticOut
});
// Add a little jump after appearing
LK.setTimeout(function () {
tween(self, {
y: self.y - 30
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 30
}, {
duration: 400,
easing: tween.bounceOut
});
}
});
}, 600);
};
// Handle selection
self.down = function (x, y, obj) {
// Shrink when pressed
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
// Make eyes bigger on press
if (self.facialContainer.children.length >= 2) {
var leftEye = self.facialContainer.children[0];
var rightEye = self.facialContainer.children[1];
var mouth = self.facialContainer.children[2];
tween(leftEye, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
easing: tween.easeOut
});
tween(rightEye, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
easing: tween.easeOut
});
// Make the character smile when clicked
if (mouth) {
tween(mouth, {
scaleX: 1.5,
scaleY: 1.7,
y: -55
}, {
duration: 200,
easing: tween.elasticOut
});
}
}
};
self.up = function (x, y, obj) {
// Play sound only if settingsButton.soundOn is true
if (!settingsButton || settingsButton.soundOn) {
LK.getSound('buttonClick').play();
}
// Return eyes to normal
if (self.facialContainer.children.length >= 2) {
var leftEye = self.facialContainer.children[0];
var rightEye = self.facialContainer.children[1];
var mouth = self.facialContainer.children[2];
tween(leftEye, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
tween(rightEye, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
// Return mouth to normal
if (mouth) {
tween(mouth, {
scaleX: 1.0,
scaleY: 1.0,
y: -60
}, {
duration: 300,
easing: tween.easeOut
});
}
}
// Check if character is on a raft after startGame was called
var parentIsRaft = obj.parent instanceof Raft;
if (parentIsRaft) {
// Get the raft instance
var raft = obj.parent;
// Show "Let's go!" text when clicked on raft
var goText = new Text2("Let's go!", {
size: 80,
fill: 0xFF4500
});
goText.anchor.set(0.5, 0.5);
goText.x = 0;
goText.y = -150;
goText.alpha = 0;
self.addChild(goText);
// Animate text appearance and fade away
tween(goText, {
alpha: 1,
y: goText.y - 50
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// After appearing, fade out
LK.setTimeout(function () {
tween(goText, {
alpha: 0,
y: goText.y - 30
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
self.removeChild(goText);
}
});
}, 1000);
}
});
// Animate the raft moving down with character on it
tween(raft, {
y: 3000 // Move down beyond the screen
}, {
duration: 5000,
easing: tween.easeIn,
onFinish: function onFinish() {
// Game completed or next scene could be triggered here
LK.showYouWin();
}
});
return; // Skip the rest of the function
}
// Show "Hello!" text when clicked (only in character selection)
var helloText = new Text2("Hello!", {
size: 80,
fill: 0xFF4500
});
helloText.anchor.set(0.5, 0.5);
helloText.x = 0;
helloText.y = -150;
helloText.alpha = 0;
self.addChild(helloText);
// Animate text appearance and fade away
tween(helloText, {
alpha: 1,
y: helloText.y - 50
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// After appearing, fade out
LK.setTimeout(function () {
tween(helloText, {
alpha: 0,
y: helloText.y - 30
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
self.removeChild(helloText);
}
});
}, 1000);
}
});
// Expand then return to normal size
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Celebrate selection with a spin
tween(self.headContainer, {
rotation: Math.PI * 2
}, {
duration: 500,
easing: tween.elasticOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Character selected!
characterSelected(self.type);
}
});
}
});
};
return self;
});
var Ocean = Container.expand(function () {
var self = Container.call(this);
// Water layers
var waterBg = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x0066CC,
// Deep blue
width: 4096,
// Double screen width
height: 3000
});
// Create waves
self.waves = [];
for (var i = 0; i < 8; i++) {
var wave = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x55AADD,
// Lighter blue
alpha: 0.4,
width: 500 + Math.random() * 700,
height: 30,
x: Math.random() * 2048 - 1024,
y: Math.random() * 1000 - 500
});
self.waves.push(wave);
}
// Animation properties
self.waveTimer = 0;
// Update wave positions
self.update = function () {
self.waveTimer += 0.02;
// Animate each wave
for (var i = 0; i < self.waves.length; i++) {
var wave = self.waves[i];
wave.x += 0.5; // Slow movement right
// Loop waves back to the left side when they go off screen
if (wave.x > 2048 + wave.width / 2) {
wave.x = -wave.width / 2;
wave.y = Math.random() * 1000 - 500;
}
// Slight bobbing
wave.y += Math.sin(self.waveTimer + i) * 0.5;
}
};
return self;
});
var PlayButton = Container.expand(function () {
var self = Container.call(this);
// Create shadow first so it appears behind the button
var shadow = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: 10,
y: 10
});
// Create base circle
var buttonBase = self.attachAsset('playButtonBase', {
anchorX: 0.5,
anchorY: 0.5
});
// Create play triangle and rotate it to point right
var playIcon = self.attachAsset('playTriangle', {
anchorX: 0.5,
anchorY: 0.5,
x: 15,
// Offset slightly to the right for better visual centering
rotation: Math.PI / 4 // 45 degrees in radians
});
// Variables to track button state
self.isPressed = false;
self.isAnimating = false;
// Set interactive state functions
self.down = function (x, y, obj) {
if (self.isAnimating) {
return;
}
self.isPressed = true;
// Shrink button when pressed
tween(buttonBase, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
tween(playIcon, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
// Move shadow closer
tween(shadow, {
x: 5,
y: 5
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
if (!self.isPressed || self.isAnimating) {
return;
}
self.isPressed = false;
self.isAnimating = true;
// Play sound only if settingsButton.soundOn is true
if (!settingsButton || settingsButton.soundOn) {
LK.getSound('buttonClick').play();
}
// Return to normal size with a bounce
tween(buttonBase, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(buttonBase, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAnimating = false;
// Trigger the "play" action
self.triggerPlay();
}
});
}
});
// Return play icon to normal with a bounce
tween(playIcon, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(playIcon, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Return shadow to normal position
tween(shadow, {
x: 10,
y: 10
}, {
duration: 200,
easing: tween.easeOut
});
};
// Function called when button is clicked
self.triggerPlay = function () {
// Spin the button when clicked
self.isAnimating = true;
// Celebrate by spinning the button
tween(self, {
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.elasticOut,
onFinish: function onFinish() {
self.rotation = 0;
self.isAnimating = false;
// Show character selection
showCharacterSelection();
}
});
};
// Idle animation to make the button more playful
self.startIdleAnimation = function () {
function pulseButton() {
if (self.isPressed || self.isAnimating) {
LK.setTimeout(pulseButton, 2000);
return;
}
tween(buttonBase, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(buttonBase, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
LK.setTimeout(pulseButton, 2000);
}
});
}
});
}
// Start the idle animation
LK.setTimeout(pulseButton, 2000);
};
// Initial scale effect when the button appears
buttonBase.scaleX = 0;
buttonBase.scaleY = 0;
playIcon.scaleX = 0;
playIcon.scaleY = 0;
shadow.scaleX = 0;
shadow.scaleY = 0;
self.appear = function () {
tween(shadow, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.elasticOut
});
tween(buttonBase, {
scaleX: 1,
scaleY: 1
}, {
duration: 700,
easing: tween.elasticOut
});
tween(playIcon, {
scaleX: 1,
scaleY: 1
}, {
duration: 700,
easing: tween.elasticOut,
onFinish: function onFinish() {
self.startIdleAnimation();
}
});
};
return self;
});
var Raft = Container.expand(function () {
var self = Container.call(this);
// Create raft base
var raftBase = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x8B4513,
// Brown color for wood
width: 400,
height: 200
});
// Create wood planks
for (var i = 0; i < 5; i++) {
var plank = self.attachAsset('boyBody', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x995533,
// Slightly different brown
width: 350,
height: 30,
y: -80 + i * 40
});
}
// Bob animation values
self.bobTimer = 0;
self.bobAmount = 5;
// Update for bobbing animation
self.update = function () {
self.bobTimer += 0.03;
self.y = self.bobAmount * Math.sin(self.bobTimer);
// Slight rotation to simulate waves
self.rotation = Math.sin(self.bobTimer * 0.7) * 0.02;
};
return self;
});
var SettingsButton = Container.expand(function () {
var self = Container.call(this);
// Create shadow for button
var shadow = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: 5,
y: 5,
scaleX: 0.6,
scaleY: 0.6
});
// Create button base
var buttonBase = self.attachAsset('playButtonBase', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x555555,
scaleX: 0.6,
scaleY: 0.6
});
// Track sound state
self.soundOn = true;
// Add text to button
var buttonText = new Text2("Sound ON", {
size: 50,
fill: '#FFFFFF'
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
// Variables to track button state
self.isPressed = false;
self.isAnimating = false;
// Set interactive state functions
self.down = function (x, y, obj) {
if (self.isAnimating) {
return;
}
self.isPressed = true;
// Shrink button when pressed
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
if (!self.isPressed || self.isAnimating) {
return;
}
self.isPressed = false;
self.isAnimating = true;
// Play sound only if sound is still on
if (self.soundOn) {
LK.getSound('buttonClick').play();
}
// Return to normal size with a bounce
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAnimating = false;
// Toggle sound
self.toggleSound();
}
});
}
});
};
// Toggle sound on/off
self.toggleSound = function () {
self.soundOn = !self.soundOn;
// Update button text
buttonText.setText(self.soundOn ? "Sound ON" : "Sound OFF");
// Update button color
tween(buttonBase, {
tint: self.soundOn ? 0x555555 : 0x993333
}, {
duration: 300,
easing: tween.easeOut
});
// Set global sound mute state using available methods
if (self.soundOn) {
// Use LK.getSound() to control individual sounds
// Set volume back to normal for any future sounds
var buttonSound = LK.getSound('buttonClick');
var gameMusic = LK.getSound('TheCool9');
if (buttonSound) {
buttonSound.volume = 0.7;
}
if (gameMusic) {
gameMusic.volume = 1.0;
}
} else {
// Mute all sounds by setting their volume to 0
var buttonSound = LK.getSound('buttonClick');
var gameMusic = LK.getSound('TheCool9');
if (buttonSound) {
buttonSound.volume = 0;
}
if (gameMusic) {
gameMusic.volume = 0;
}
}
};
// Initial animation when button appears
self.appear = function () {
self.scaleX = 0;
self.scaleY = 0;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 700,
easing: tween.elasticOut
});
};
return self;
});
var Shore = Container.expand(function () {
var self = Container.call(this);
// Create sandy beach
var sand = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xF4D03F,
// Sandy color
width: 800,
height: 500
});
// Create some palm trees
var palm1 = self.attachAsset('boyBody', {
anchorX: 0.5,
anchorY: 1.0,
tint: 0x6E2C00,
// Brown trunk
width: 40,
height: 200,
x: -150,
y: -100,
rotation: -0.1
});
var palm2 = self.attachAsset('boyBody', {
anchorX: 0.5,
anchorY: 1.0,
tint: 0x6E2C00,
// Brown trunk
width: 40,
height: 180,
x: 180,
y: -120,
rotation: 0.15
});
// Create palm leaves
var leaves1 = self.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x2ECC71,
// Green
width: 200,
height: 150,
x: -150,
y: -250
});
var leaves2 = self.attachAsset('girlHair', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x2ECC71,
// Green
width: 200,
height: 150,
x: 180,
y: -270
});
return self;
});
var StartGameButton = Container.expand(function () {
var self = Container.call(this);
// Create shadow for button
var shadow = self.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
x: 10,
y: 10
});
// Create button base
var buttonBase = self.attachAsset('playButtonBase', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x4CAF50 // Green color for start button
});
// Add text to button
var buttonText = new Text2("Start Game", {
size: 80,
fill: '#FFFFFF'
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
// Variables to track button state
self.isPressed = false;
self.isAnimating = false;
// Set interactive state functions
self.down = function (x, y, obj) {
if (self.isAnimating) {
return;
}
self.isPressed = true;
// Shrink button when pressed
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
// Move shadow closer
tween(shadow, {
x: 5,
y: 5
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
if (!self.isPressed || self.isAnimating) {
return;
}
self.isPressed = false;
self.isAnimating = true;
// Play sound only if settingsButton.soundOn is true
if (!settingsButton || settingsButton.soundOn) {
LK.getSound('buttonClick').play();
}
// Return to normal size with a bounce
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAnimating = false;
// Make button disappear
tween(self, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove button
if (self.parent) {
self.parent.removeChild(self);
}
// Find raft and character
var raft = null;
var shore = null;
var character = null;
// Find raft and shore in the scene
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] instanceof Raft) {
raft = game.children[i];
}
if (game.children[i] instanceof Shore) {
shore = game.children[i];
}
}
if (raft && raft.children.length > 0) {
// Find the character in the raft
for (var j = 0; j < raft.children.length; j++) {
if (raft.children[j] instanceof Character) {
character = raft.children[j];
}
}
if (character && shore) {
// Move character out of raft
var globalCharPos = raft.toGlobal(character.position);
game.addChild(character);
character.position = globalCharPos;
// Make character swim animation
var swimToShore = function swimToShore() {
// Make character "swim" by moving arms and legs
if (character.armsContainer && character.armsContainer.children.length >= 2) {
var leftArm = character.armsContainer.children[0];
var rightArm = character.armsContainer.children[1];
// Animate arms in swimming motion
tween.loop(leftArm, {
rotation: [-0.2, 0.8, -0.2]
}, {
duration: 800
});
tween.loop(rightArm, {
rotation: [0.2, -0.8, 0.2]
}, {
duration: 800
});
}
if (character.legsContainer && character.legsContainer.children.length >= 2) {
var leftLeg = character.legsContainer.children[0];
var rightLeg = character.legsContainer.children[1];
// Animate legs in swimming motion
tween.loop(leftLeg, {
rotation: [0, 0.3, 0]
}, {
duration: 600
});
tween.loop(rightLeg, {
rotation: [0, -0.3, 0]
}, {
duration: 600
});
}
// Move character toward shore
tween(character, {
y: shore.y - 100 // Stop just above shore
}, {
duration: 5000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Character reached the shore
// Stop swimming animation
if (character.armsContainer && character.armsContainer.children.length >= 2) {
tween.stopAll(character.armsContainer.children[0]);
tween.stopAll(character.armsContainer.children[1]);
}
if (character.legsContainer && character.legsContainer.children.length >= 2) {
tween.stopAll(character.legsContainer.children[0]);
tween.stopAll(character.legsContainer.children[1]);
}
// Show celebration
var celebrateText = new Text2("Made it to shore!", {
size: 100,
fill: 0xFF4500
});
celebrateText.anchor.set(0.5, 0.5);
celebrateText.x = 2048 / 2;
celebrateText.y = 500;
celebrateText.alpha = 0;
game.addChild(celebrateText);
tween(celebrateText, {
alpha: 1,
y: celebrateText.y - 50
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show win screen after delay
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
});
}
});
};
// Move raft away to simulate "exiting" the raft
tween(raft, {
y: raft.y - 150,
rotation: 0.3
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: swimToShore
});
}
}
}
});
}
});
}
});
// Return shadow to normal position
tween(shadow, {
x: 10,
y: 10
}, {
duration: 200,
easing: tween.easeOut
});
};
// Initial animation when button appears
self.appear = function () {
self.scaleX = 0;
self.scaleY = 0;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 700,
easing: tween.elasticOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x00FF00
});
/****
* Game Code
****/
// Set the game's background color to a softer green
game.setBackgroundColor(0x66CC99);
// Game state variables
var showingCharacterSelection = false;
var selectedCharacter = null;
var boyCharacter = null;
var girlCharacter = null;
// Create and add settings button
var settingsButton = new SettingsButton();
game.addChild(settingsButton);
// Position in top right with some margin
settingsButton.x = 2048 - 120;
settingsButton.y = 120;
// Make the button appear with animation
settingsButton.appear();
// Update function for character animations and ocean/raft
game.update = function () {
// Update character animations if they exist
if (boyCharacter) {
boyCharacter.update();
}
if (girlCharacter) {
girlCharacter.update();
}
// Update ocean and raft if they exist
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child instanceof Ocean) {
child.update();
}
if (child instanceof Raft) {
child.update();
}
}
};
// Create the play button and center it on screen
var playButton = new PlayButton();
game.addChild(playButton);
// Position the button in the center of the screen
playButton.x = 2048 / 2;
playButton.y = 2732 / 2;
// Make the button appear with animation
playButton.appear();
// Function to show character selection screen
function showCharacterSelection() {
if (showingCharacterSelection) {
return;
}
showingCharacterSelection = true;
// Make play button disappear
tween(playButton, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove play button from display
game.removeChild(playButton);
// Create character options
boyCharacter = new Character();
boyCharacter.initialize("boy");
game.addChild(boyCharacter);
boyCharacter.x = 2048 / 3;
boyCharacter.y = 2732 / 2;
girlCharacter = new Character();
girlCharacter.initialize("girl");
game.addChild(girlCharacter);
girlCharacter.x = 2048 * 2 / 3;
girlCharacter.y = 2732 / 2;
// Make characters appear with animation
boyCharacter.appear();
girlCharacter.appear();
}
});
}
// Function called when a character is selected
function characterSelected(characterType) {
selectedCharacter = characterType;
console.log("Selected character: " + characterType);
// Make the non-selected character sad and disappear
var nonSelectedCharacter = characterType === "boy" ? girlCharacter : boyCharacter;
var selectedCharacterObj = characterType === "boy" ? boyCharacter : girlCharacter;
// Make selected character happy
if (selectedCharacterObj.facialContainer.children.length >= 3) {
var mouth = selectedCharacterObj.facialContainer.children[2];
// Make mouth bigger and smile
tween(mouth, {
scaleX: 1.5,
scaleY: 1.5,
y: -55
}, {
duration: 300,
easing: tween.elasticOut
});
}
// Make non-selected character sad
if (nonSelectedCharacter.facialContainer.children.length >= 3) {
var sadMouth = nonSelectedCharacter.facialContainer.children[2];
// Make mouth smaller and frown
tween(sadMouth, {
scaleX: 0.8,
scaleY: -1.2,
y: -50
}, {
duration: 300,
easing: tween.easeOut
});
}
// Fade out and shrink non-selected character
tween(nonSelectedCharacter, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(nonSelectedCharacter);
}
});
// Jump and move the selected character to center
LK.setTimeout(function () {
// Jump up first
tween(selectedCharacterObj, {
y: selectedCharacterObj.y - 100
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
// Move to center while in air
tween(selectedCharacterObj, {
x: 2048 / 2
}, {
duration: 300,
easing: tween.linear,
onFinish: function onFinish() {
// Land with bounce
tween(selectedCharacterObj, {
y: 2732 / 2,
scaleY: 0.7,
scaleX: 1.3
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
// Bounce back to normal
tween(selectedCharacterObj, {
scaleY: 1.1,
scaleX: 0.9
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return to normal scale
tween(selectedCharacterObj, {
scaleY: 1.0,
scaleX: 1.0
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Celebrate with a spin
tween(selectedCharacterObj.headContainer, {
rotation: Math.PI * 2
}, {
duration: 800,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Reset rotation
selectedCharacterObj.headContainer.rotation = 0;
// Add start game button
var startGameBtn = new StartGameButton();
game.addChild(startGameBtn);
startGameBtn.x = 2048 / 2;
startGameBtn.y = 2732 / 2 + 350; // Position below character
startGameBtn.appear();
}
});
}
});
}
});
}
});
}
});
}
});
}, 300);
}
// Function to start the game
function startGame() {
console.log("Starting game with character: " + selectedCharacter);
// Store the current background color
var originalBackgroundColor = game.backgroundColor;
// Create a black overlay for the screen
var blackOverlay = new Container();
var blackBg = blackOverlay.attachAsset('buttonShadow', {
anchorX: 0.5,
anchorY: 0.5,
width: 4096,
// Make it twice the screen width to ensure full coverage
height: 5464,
// Make it twice the screen height to ensure full coverage
tint: 0x000000,
// Pure black
alpha: 0
});
game.addChild(blackOverlay);
blackOverlay.x = 2048 / 2;
blackOverlay.y = 2732 / 2;
// Fade to black
tween(blackBg, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wait for 3 seconds with black screen
LK.setTimeout(function () {
// Create ocean scene
var ocean = new Ocean();
ocean.x = 2048 / 2;
ocean.y = 2732 / 2;
game.addChild(ocean);
// Create shore at the far side
var shore = new Shore();
shore.x = 2048 / 2;
shore.y = 3000; // Position below the screen
game.addChild(shore);
// Create raft and position it in the center
var raft = new Raft();
raft.x = 2048 / 2;
raft.y = 2732 / 2;
game.addChild(raft);
// Add the selected character to the raft
var selectedCharacterObj = selectedCharacter === "boy" ? boyCharacter : girlCharacter;
// Move character to raft
raft.addChild(selectedCharacterObj);
selectedCharacterObj.x = 0;
selectedCharacterObj.y = -80; // Position on raft
// Remove settings button and any remaining UI
if (settingsButton && settingsButton.parent) {
game.removeChild(settingsButton);
}
// Create start game button to trigger swimming animation
var startGameBtn = new StartGameButton();
game.addChild(startGameBtn);
startGameBtn.x = 2048 / 2;
startGameBtn.y = 2732 - 200; // Position near bottom
startGameBtn.appear();
// Fade the black screen out
tween(blackBg, {
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Remove the black overlay
game.removeChild(blackOverlay);
// Set game background to sky blue
game.setBackgroundColor(0x87CEEB);
}
});
}, 3000);
}
});
}
// Rainbow effect for the background
var rainbowColors = [0x66CC99, 0x66CCFF, 0xCC99FF, 0xFF99CC, 0xFFCC66, 0x99FF99];
var currentColorIndex = 0;
// A function to cycle through background colors
function cycleBackgroundColor() {
currentColorIndex = (currentColorIndex + 1) % rainbowColors.length;
// Animate the color change
var targetColor = rainbowColors[currentColorIndex];
tween(game, {
backgroundColor: targetColor
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Schedule the next color change
LK.setTimeout(cycleBackgroundColor, 4000);
}
});
}
// Start the background color animation after a delay
LK.setTimeout(cycleBackgroundColor, 4000);