User prompt
Every time a seagull is spawned play the seagull sound effect.
User prompt
Update as needed with: // Increase buffer size for more stability var heightBuffer = Array(30).fill(0); // Changed from 15 to 30 for more samples // Modify the smoothing weights in getSmoothedHeight function getSmoothedHeight(newHeight) { heightBuffer[bufferIndex] = newHeight; bufferIndex = (bufferIndex + 1) % heightBuffer.length; // Weighted average giving more importance to recent values var total = 0; var weights = 0; for (var i = 0; i < heightBuffer.length; i++) { var weight = Math.pow(0.95, i); // Exponential decay total += heightBuffer[(bufferIndex - i + heightBuffer.length) % heightBuffer.length] * weight; weights += weight; } var smoothedHeight = total / weights; // Increase smoothing factor for more stability lastSmoothedHeight = lastSmoothedHeight * 0.85 + smoothedHeight * 0.15; // Changed from 0.7/0.3 return lastSmoothedHeight; } // Then in the update function, adjust the pitch smoothing: targetPitch = normalizedPitch * 0.6 + lastPitch * 0.4; // Changed from 0.8/0.2
User prompt
Update fish class with: var Fish = Container.expand(function() { var self = Container.call(this); var fishGraphics = self.attachAsset('fish', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -3 - Math.random() * 2; self.y = 2732 * (0.87 + Math.random() * 0.1); self.x = 2248; // Use simple sine wave for animation instead of tweens self.baseY = self.y; self.startTime = LK.ticks; self.update = function() { self.x += self.speed; // Smooth swimming motion using sine wave self.y = self.baseY + Math.sin((LK.ticks - self.startTime) * 0.05) * 15; fishGraphics.rotation = Math.sin((LK.ticks - self.startTime) * 0.1) * 0.1; if (self.x < -100) { self.destroy(); } }; return self; });
User prompt
Add a random scale to the spawned fish between 0.5 and 1.5
User prompt
Lower the frequency of the fish spawn.
User prompt
Update fish with: var Fish = Container.expand(function() { var self = Container.call(this); var fishGraphics = self.attachAsset('fish', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -3 - Math.random() * 2; // Slower than seagulls self.y = 2732 * (0.87 + Math.random() * 0.1); // Position between 87-97% of screen height self.x = 2248; // Start off-screen right // Swimming animation function swimAnimation() { // Gentle up and down movement tween(self, { y: self.y + (Math.random() * 40 - 20) // Smaller vertical movement }, { duration: 2000, easing: tween.easeInOut, onFinish: swimAnimation }); // Tail-swishing effect tween(fishGraphics, { rotation: 0.1 }, { duration: 500, easing: tween.easeInOut, onFinish: function() { tween(fishGraphics, { rotation: -0.1 }, { duration: 500, easing: tween.easeInOut, onFinish: function() { swimAnimation(); } }); } }); } swimAnimation(); self.update = function() { self.x += self.speed; // Remove if off screen if (self.x < -100) { self.destroy(); } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Update surfer as needed with: if (verticalSpeed < -2) { // Moving up - reduce sensitivity from 0.005 to 0.003 verticalRotation = Math.min(0.3, -verticalSpeed * 0.003); } else if (verticalSpeed > 2) { // Moving down - reduce sensitivity from 0.005 to 0.003 verticalRotation = Math.max(-0.4, -verticalSpeed * 0.003); } // Then find the rotation smoothing section and adjust these values // Reduce rotation response speed from 0.05 to 0.03 velocityRot += (baseRotation + waveRotation + verticalRotation - self.rotation) * 0.03; // Increase damping from 0.9 to 0.95 for smoother transitions velocityRot *= 0.95;
Code edit (1 edits merged)
Please save this source code
User prompt
Anchor to the score centered so that it stays centered as it grows.
User prompt
Update as needed only with: var currentWholeMultiplier = Math.floor(multiplier); if (currentWholeMultiplier > lastWholeMultiplier) { console.log("New multiplier:", currentWholeMultiplier); // Create text like the calibration text var popupText = new Text2(currentWholeMultiplier + "X MULTIPLIER!", { size: 120, fill: 0xFFFFFF, align: 'center', weight: 800 }); // Set anchor first popupText.anchor.set(0.5, 0.5); // Add to GUI center immediately LK.gui.center.addChild(popupText); // Set initial scale after adding to GUI popupText.scale.set(0.1); // Animate in tween(popupText.scale, { x: 1.2, y: 1.2 }, { duration: 400, easing: tween.elasticOut, onFinish: function() { // Animate out tween(popupText, { alpha: 0, y: popupText.y - 100 }, { duration: 800, delay: 600, easing: tween.easeOut, onFinish: function() { LK.gui.center.removeChild(popupText); popupText.destroy(); } }); } }); lastWholeMultiplier = currentWholeMultiplier; } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update game.update as needed with: var currentWholeMultiplier = Math.floor(multiplier); if (currentWholeMultiplier > lastWholeMultiplier) { console.log("Multiplier increased:", currentWholeMultiplier); // Debug log var popupText = new Text2(currentWholeMultiplier + "X MULTIPLIER!", { size: 120, fill: 0xFFFFFF, weight: 800 }); popupText.anchor.set(0.5, 0.5); popupText.scale.set(0.1, 0.1); // Add to center of screen explicitly popupText.x = 2048/2; // Half of screen width popupText.y = 2732/2; // Half of screen height LK.gui.center.addChild(popupText); tween(popupText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 400, easing: tween.elasticOut, onFinish: function() { tween(popupText, { alpha: 0, y: popupText.y - 100 }, { duration: 800, delay: 600, easing: tween.easeOut, onFinish: function() { popupText.destroy(); } }); } }); lastWholeMultiplier = currentWholeMultiplier; } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Adjust cloud scale based on generated alpha.
User prompt
Wait until clouds are fully off screen before destroying.
User prompt
In the cloud spawning block in game.update where it says game.addChildAt. Allow it to either be game.getChildIndex(poseidon) or the same +1
User prompt
Change the cloud spawning interval to 2-4 seconds.
User prompt
Add a random alpha setting to clouds in the range of 0.5-0.9
User prompt
Clouds should spawn on the same layer as Poseidon. Change initialization accordingly.
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: lastCloudSpawn' in or related to this line: 'if (Date.now() - lastCloudSpawn > cloudSpawnInterval) {' Line Number: 767
User prompt
Increase the frequency of cloud generation to every 1-3 seconds.
User prompt
Cloud spawning should always happen.
User prompt
Move the cloud spawning code out of the wave system calibrating check.
User prompt
Create a cloud class that generates clouds off the top third of the screen to the right. The clouds will travel left and be destroyed off of the screen.
User prompt
Use the storage plugin and add a Best score in the bottom left corner. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { bestScore: 0 }); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Cloud = Container.expand(function () { var self = Container.call(this); var cloudAlpha = 0.5 + Math.random() * 0.4; // Random alpha between 0.5 and 0.9 var cloudGraphics = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5, alpha: cloudAlpha }); cloudGraphics.scale.set(cloudAlpha, cloudAlpha); // Scale based on alpha // Initialize cloud position self.x = 2248; // Start off-screen right self.y = Math.random() * (2732 * 0.33); // Top third of screen self.speed = -2 - Math.random() * 2; // Random speed variation self.update = function () { self.x += self.speed; // Remove if off screen if (self.x < -self.width) { self.destroy(); } }; return self; }); var Fish = Container.expand(function () { var self = Container.call(this); var fishGraphics = self.attachAsset('fish', { anchorX: 0.5, anchorY: 0.5 }); var randomScale = 0.5 + Math.random(); // Random scale between 0.5 and 1.5 fishGraphics.scale.set(randomScale, randomScale); self.speed = -3 - Math.random() * 2; // Slower than seagulls self.y = 2732 * (0.87 + Math.random() * 0.1); // Position between 87-97% of screen height self.x = 2248; // Start off-screen right // Use simple sine wave for animation instead of tweens self.baseY = self.y; self.startTime = LK.ticks; self.update = function () { self.x += self.speed; // Smooth swimming motion using sine wave self.y = self.baseY + Math.sin((LK.ticks - self.startTime) * 0.05) * 15; fishGraphics.rotation = Math.sin((LK.ticks - self.startTime) * 0.1) * 0.1; // Remove if off screen if (self.x < -100) { self.destroy(); } }; return self; }); var ParticleSystem = Container.expand(function () { var self = Container.call(this); self.addWaterParticle = function (x, y, type) { var particle = ParticlePool.get(); if (type === 'trail') { // Move spawn point up and behind surfer particle.x = x - 100; // Spawn behind (to the right of) surfer particle.y = y + 10; // Raised up from previous +90 } else { // Keep original splash positioning particle.x = x + Math.random() * 130 - 40; particle.y = y - 20; } particle.init(type); self.addChild(particle); }; self.update = function () { for (var i = self.children.length - 1; i >= 0; i--) { var particle = self.children[i]; if (particle.update) { particle.update(); } // Remove particles that have moved far off screen if (particle.x < -500 || particle.x > 2548 || particle.y < -500 || particle.y > 3232) { ParticlePool["return"](particle); self.removeChild(particle); } } }; return self; }); var Rock = Container.expand(function () { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 1 // Anchor to top since we're stretching upward }); // Set scales independently rock.scaleX = 2; rock.scaleY = 2; // Start with a base scale self.checkCollision = function (surfer) { var rockWidth = self.width; var rockHeight = self.height; var rockTop = self.y - rockHeight; var points = [{ x: self.x, y: rockTop }, { x: self.x - rockWidth * 0.4, y: self.y - rockHeight * 0.1 }, { x: self.x + rockWidth * 0.4, y: self.y - rockHeight * 0.1 }]; var surferBox = { x: surfer.x - 30, y: surfer.y - 30, width: 60, height: 60 }; return isPointInTriangle(surferBox.x, surferBox.y, points) || isPointInTriangle(surferBox.x + surferBox.width, surferBox.y, points) || isPointInTriangle(surferBox.x, surferBox.y + surferBox.height, points) || isPointInTriangle(surferBox.x + surferBox.width, surferBox.y + surferBox.height, points); }; self.update = function () { if (self.lastX === undefined) { self.lastX = self.x; } // Initialize lastX if not set self.x -= 8; if (self.x < -self.width) { self.destroy(); } self.lastX = self.x; // Update lastX }; return self; }); var Seagull = Container.expand(function () { var self = Container.call(this); var seagullGraphics = self.attachAsset('seagull', { anchorX: 0.5, anchorY: 0.5 }); // Circle collision data self.radius = 65; self.collisionX = 0; self.collisionY = 0; self.speed = -5 - Math.random() * 3; // Random speed variation self.y = Math.random() * (2732 * 0.33); // Top third of screen self.x = 2248; // Start off-screen right // Flying animation function flyAnimation() { tween(self, { y: self.y + (Math.random() * 100 - 50) }, { duration: 1000, easing: tween.easeInOut, onFinish: flyAnimation }); // Wing flap effect tween(seagullGraphics, { scaleY: 0.8, y: 5 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(seagullGraphics, { scaleY: 1, y: 0 }, { duration: 500, easing: tween.easeInOut }); } }); } flyAnimation(); self.update = function () { self.x += self.speed; // Update collision circle position self.collisionX = self.x; self.collisionY = self.y; // Remove if off screen if (self.x < -100) { self.destroy(); } // Circle collision with surfer var dx = self.collisionX - surfer.x; var dy = self.collisionY - surfer.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.radius + 40) { // 40 is approximate surfer radius LK.showGameOver(); } }; return self; }); var Surfer = Container.expand(function () { var self = Container.call(this); var BASE_GRAVITY = 1.5; // Reduced for smoother acceleration var MAX_SPEED = 40; // Increased for longer falls var DAMPENING = 0.98; // Less dampening for smoother motion var WAVE_OFFSET = -30; var FIXED_X = 2048 * 0.35; var MAX_AIR_VELOCITY = -25; // Only applies when surfer is above wave var velocityY = 0; var velocityRot = 0; var activeTween = null; // Initialize activeTween variable var lastWaveY = 2732 * 0.85; // Match WaveSystem's baseY var initialized = false; var surferGraphics = self.attachAsset('surfer', { anchorX: 0.5, anchorY: 0.8 }); self.x = FIXED_X; self.y = lastWaveY + WAVE_OFFSET; // Start at base wave height self.setWaveSystem = function (ws) { waveSystem = ws; if (!waveSystem.points) { waveSystem.points = []; } initialized = true; }; self.update = function () { // Add tween cleanup if (activeTween) { tween.stop(activeTween); } if (!waveSystem) { return; } var normalizedX = self.x / 2048; var pointIndex = Math.floor(normalizedX * (waveSystem.points.length - 1)); var nextPointIndex = Math.min(pointIndex + 1, waveSystem.points.length - 1); var progress = normalizedX * (waveSystem.points.length - 1) - pointIndex; var currentPoint = waveSystem.points[pointIndex]; var nextPoint = waveSystem.points[nextPointIndex]; if (currentPoint && nextPoint) { var targetY = currentPoint.y + (nextPoint.y - currentPoint.y) * progress + WAVE_OFFSET; } else { return; // Exit update if points are undefined } var waveRising = targetY < lastWaveY; var aboveWave = self.y < targetY; if (waveRising && !aboveWave) { // Natural wave following - no limits when on the wave velocityY = (targetY - self.y) * 0.2; self.y += velocityY; } else { // In air or falling velocityY += BASE_GRAVITY; velocityY *= DAMPENING; // Only cap velocity when above the wave if (aboveWave && velocityY < MAX_AIR_VELOCITY) { velocityY = MAX_AIR_VELOCITY; } self.y += velocityY; if (self.y > targetY && velocityY > 0) { var fallVelocity = velocityY; // Capture velocity before reset self.y = targetY; velocityY = 0; if (aboveWave && fallVelocity > 15) { // Only splash on significant falls createSplash(); } } } lastWaveY = targetY; var baseRotation = -0.1; // Slight left tilt as base position var waveRotation = Math.sin(LK.ticks / 30) * 0.05; // Gentle wave motion // Calculate vertical movement speed var verticalSpeed = self.y - lastWaveY; // Add rotation based on vertical movement var verticalRotation = 0; if (verticalSpeed < -2) { // Moving up - reduce sensitivity from 0.005 to 0.003 verticalRotation = Math.min(0.3, -verticalSpeed * 0.003); } else if (verticalSpeed > 2) { // Moving down - reduce sensitivity from 0.005 to 0.003 verticalRotation = Math.max(-0.4, -verticalSpeed * 0.003); } // Smoothly apply all rotations velocityRot += (baseRotation + waveRotation + verticalRotation - self.rotation) * 0.03; // Reduce rotation response speed from 0.05 to 0.03 velocityRot *= 0.95; // Increase damping from 0.9 to 0.95 for smoother transitions self.rotation += velocityRot; // Create trail particles whenever touching water if (self.y >= targetY) { createTrail(); } var targetAngle = Math.atan2(nextPoint.y - currentPoint.y, nextPoint.x - currentPoint.x); // ... rest of the rotation code ... particles.children.forEach(function (particle) { if (particle.update) { particle.update(); } }); }; self.getScore = function () { return Math.floor(score); }; // Then in the Surfer class, replace the particle system with: var particles = self.addChild(new ParticleSystem()); function createSplash() { for (var i = 0; i < 50; i++) { // Move splash up by 40 to match trail Y position game.particles.addWaterParticle(FIXED_X, self.y + 40, 'splash'); } } function createTrail() { // Create fewer particles but more frequently for trail for (var i = 0; i < 4; i++) { game.particles.addWaterParticle(FIXED_X, self.y, 'trail'); } } return self; }); var WaterParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('wave_point', { anchorX: 0.5, anchorY: 0.5 }); var speed, angle, scale; self.init = function (type) { // Reset properties scale = 1; self.type = type; if (type === 'trail') { speed = Math.random() * 8 + 6; angle = Math.PI + (Math.random() * 0.4 - 0.2); scale = 0.7; particleGraphics.alpha = 0.8; } else { speed = Math.random() * 12 + 8; angle = -Math.PI / 2 + (Math.random() * 1.4 - 0.7); scale = 1.2; particleGraphics.alpha = 0.9; } self.scale.set(scale, scale); }; self.update = function () { scale -= self.type === 'splash' ? 0.04 : 0.02; self.scale.set(scale, scale); if (scale <= 0) { // Instead of destroying, return to pool if (self.parent) { self.parent.removeChild(self); } ParticlePool["return"](self); return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; }; return self; }); var WaveSystem = Container.expand(function () { var self = Container.call(this); var NUM_POINTS = 40; var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.85; var MIN_PITCH = 60; var MAX_PITCH = 400; var calibrationSamples = []; self.isCalibrating = true; var CALIBRATION_SAMPLES = 100; // Doubled to 100 samples var CALIBRATION_VOLUME_THRESHOLD = 0.5; // Minimum volume to count as valid input var calibrationStartTime = LK.ticks; var CALIBRATION_TIMEOUT = 300; // 5 seconds (60 ticks per second) var WAVE_HEIGHT = 2000; var lastPitch = 0; // Create calibration message var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.alpha = 0.7; background.scale.set(10, 2); // Adjust scale as needed // Add background first so it's behind the text LK.gui.center.addChild(background); var calibrationText = new Text2("Make some noise!\nHum high and low to calibrate", { size: 60, fill: 0xFFFFFF, align: 'center' }); calibrationText.anchor.set(0.5, 0.5); LK.gui.center.addChild(calibrationText); // Progress indicator var progressText = new Text2("0%", { size: 40, fill: 0xFFFFFF, alpha: 0.8 }); progressText.anchor.set(0.5, 0.5); progressText.y = calibrationText.y + 80; LK.gui.center.addChild(progressText); // Removed visual pitch indicator and labels function updatePitchRange(pitch) { if (facekit.volume > CALIBRATION_VOLUME_THRESHOLD) { calibrationSamples.push(pitch); // Update progress display var progress = Math.min(100, Math.floor(calibrationSamples.length / CALIBRATION_SAMPLES * 100)); progressText.setText(progress + "%"); // Removed pitch indicator position update as visual indicator is no longer used if (calibrationSamples.length >= CALIBRATION_SAMPLES) { finishCalibration(); } } // Check for timeout if (LK.ticks - calibrationStartTime > CALIBRATION_TIMEOUT) { if (calibrationSamples.length < 10) { // Not enough samples // Reset and extend time calibrationSamples = []; calibrationStartTime = LK.ticks; calibrationText.setText("Let's try again!\nMake some noise - hum or speak"); } else { finishCalibration(); // Use what we have } } } function finishCalibration() { var sortedPitches = calibrationSamples.sort(function (a, b) { return a - b; }); MIN_PITCH = sortedPitches[Math.floor(calibrationSamples.length * 0.1)]; MAX_PITCH = sortedPitches[Math.floor(calibrationSamples.length * 0.9)]; // Add padding to range MIN_PITCH = Math.max(30, MIN_PITCH - 10); MAX_PITCH = MAX_PITCH + 20; self.isCalibrating = false; // Show completion message calibrationText.setText("Ready!"); background.destroy(); calibrationText.destroy(); progressText.destroy(); // Fade out completion message tween(calibrationText, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { return calibrationText.destroy(); } }); // Removed pitch meter cleanup console.log("Calibrated pitch range:", MIN_PITCH, "to", MAX_PITCH); } // Enhanced smoothing system var heightBuffer = Array(30).fill(0); var bufferIndex = 0; var lastSmoothedHeight = 0; // Water fill rectangles var waterRects = []; var NUM_WATER_SECTIONS = 80; // Reduced from 80 for (var i = 0; i < NUM_WATER_SECTIONS; i++) { var rect = self.attachAsset('wave_line', { anchorX: 0.5, // Center anchor anchorY: 0, // Top anchor height: 2732, width: SCREEN_WIDTH / NUM_WATER_SECTIONS + 1, // Tiny overlap to prevent pixel gaps tint: 0x0066cc, alpha: 0.3 }); waterRects.push(rect); } // Create wave line segments var lines = []; function createLines() { // Clean up any existing lines first lines.forEach(function (line) { line.destroy(); self.removeChild(line); }); lines = []; // Create new lines for (var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 4 }); lines.push(line); } } // Call initial creation createLines(); function gaussianCurve(x) { return Math.exp(-(x * x) / 0.8); } function getSmoothedHeight(newHeight) { heightBuffer[bufferIndex] = newHeight; bufferIndex = (bufferIndex + 1) % heightBuffer.length; // Simplified smoothing calculation var total = 0; var weights = 0; for (var i = 0; i < heightBuffer.length; i++) { var weight = Math.pow(0.95, i); // Exponential decay total += heightBuffer[(bufferIndex - i + heightBuffer.length) % heightBuffer.length] * weight; weights += weight; } var smoothedHeight = total / weights; lastSmoothedHeight = lastSmoothedHeight * 0.85 + smoothedHeight * 0.15; // Changed from 0.7/0.3 return lastSmoothedHeight; } self.update = function () { // Always calculate wave points first, regardless of calibration state var targetPitch = 0; if (facekit.volume > 0.5) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch * 0.6 + lastPitch * 0.4; } lastPitch += (targetPitch - lastPitch) * 0.2; var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT); points = []; for (var i = 0; i < NUM_POINTS; i++) { var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH; var distanceFromCenter = (x - SCREEN_WIDTH * 0.35) / (SCREEN_WIDTH * 0.45); var heightFactor = gaussianCurve(distanceFromCenter); var y = baseY - smoothedHeight * heightFactor; points.push({ x: x, y: y }); } // Always update water rectangles for (var i = 0; i < NUM_WATER_SECTIONS; i++) { var rect = waterRects[i]; var xPosition = i / NUM_WATER_SECTIONS * SCREEN_WIDTH; var exactPointPosition = xPosition / SCREEN_WIDTH * (NUM_POINTS - 1); var pointIndex = Math.floor(exactPointPosition); var nextPointIndex = Math.min(pointIndex + 1, NUM_POINTS - 1); var progress = exactPointPosition - pointIndex; var y1 = points[pointIndex].y; var y2 = points[nextPointIndex].y; var y = y1 + (y2 - y1) * progress; rect.x = xPosition; rect.y = y; rect.height = 2732 - y; rect.alpha = 0.3 + Math.sin(LK.ticks * 0.02 + i * 0.2) * 0.02; } self.points = points; // Handle calibration if still calibrating if (self.isCalibrating) { if (facekit.volume > CALIBRATION_VOLUME_THRESHOLD) { calibrationSamples.push(facekit.pitch); var progress = Math.min(100, Math.floor(calibrationSamples.length / CALIBRATION_SAMPLES * 100)); progressText.setText(progress + "%"); if (calibrationSamples.length >= CALIBRATION_SAMPLES) { finishCalibration(); } } if (LK.ticks - calibrationStartTime > CALIBRATION_TIMEOUT) { if (calibrationSamples.length < 10) { calibrationSamples = []; calibrationStartTime = LK.ticks; calibrationText.setText("Let's try again!\nMake some noise - hum or speak"); } else { finishCalibration(); } } } else { // Only update score when not calibrating if (facekit.volume > 0.5) { score += smoothedHeight / WAVE_HEIGHT * multiplier; multiplier += 0.001; } else { multiplier = Math.max(1, multiplier - 0.01); } } // Always update wave line segments for (var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; var dx = end.x - start.x; var dy = end.y - start.y; var length = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); lines[i].x += (start.x - lines[i].x) * 0.3; lines[i].y += (start.y - lines[i].y) * 0.3; lines[i].width += (length - lines[i].width) * 0.3; var angleDiff = angle - lines[i].rotation; if (angleDiff > Math.PI) { angleDiff -= Math.PI * 2; } if (angleDiff < -Math.PI) { angleDiff += Math.PI * 2; } lines[i].rotation += angleDiff * 0.3; } }; self.destroy = function () { waterRects.forEach(function (rect) { return rect.destroy(); }); lines.forEach(function (line) { return line.destroy(); }); waterRects = []; lines = []; Container.prototype.destroy.call(this); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ var ParticlePool = { pool: [], maxSize: 200, get: function get() { if (this.pool.length > 0) { var particle = this.pool.pop(); particle.visible = true; return particle; } return new WaterParticle(); }, "return": function _return(particle) { if (this.pool.length < this.maxSize) { // Reset particle properties particle.visible = false; particle.scale.set(1, 1); particle.x = 0; particle.y = 0; particle.rotation = 0; this.pool.push(particle); } else { particle.destroy(); } } }; function isPointInTriangle(px, py, points) { var p0 = points[0], p1 = points[1], p2 = points[2]; var A = 1 / 2 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y); var sign = A < 0 ? -1 : 1; var s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * px + (p0.x - p2.x) * py) * sign; var t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * px + (p1.x - p0.x) * py) * sign; return s > 0 && t > 0 && s + t < 2 * A * sign; } var lastScoreDisplay = -1; var lastMultiplierDisplay = -1; var originalSetInterval = LK.setInterval; LK.setInterval = function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var timer = originalSetInterval.apply(this, args); gameTimers.push(timer); return timer; }; var originalSetTimeout = LK.setTimeout; LK.setTimeout = function () { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } var timer = originalSetTimeout.apply(this, args); gameTimers.push(timer); return timer; }; var gameTimers = []; var seagullSpawnInterval = 6000; // Spawn every 3 seconds var lastSeagullSpawn = 0; var lastCloudSpawn = 0; var cloudSpawnInterval = 1000 + Math.random() * 2000; // Random interval between 1-3 seconds function spawnSeagull() { if (Date.now() - lastSeagullSpawn > seagullSpawnInterval) { var seagull = new Seagull(); game.addChild(seagull); lastSeagullSpawn = Date.now(); seagullSpawnInterval = 4000 + Math.random() * 4000; // Random interval between 2-4 seconds LK.getSound('seagull').play(); // Play seagull sound effect } } var rocks = []; var lastRockTime = 0; var fishSpawnInterval = 8000; var lastFishSpawn = 0; var lastWholeMultiplier = 1; var score = 0; // Initialize score variable var multiplier = 1; var lastWaveHeight = 0; var lastWaveUpdate = 0; var devicePerformance = 1; // Default performance multiplier var poseidon = LK.getAsset('poseidon', { anchorX: 0.5, anchorY: 0.5 }); game.addChild(poseidon); var mouth = LK.getAsset('mouth', { anchorX: 0.5, // Center anchor anchorY: 0.5, // Center anchor alpha: 0 // Initialize alpha to 0 }); game.addChild(mouth); var waveSystem = game.addChild(new WaveSystem()); var particles = new ParticleSystem(); game.particles = game.addChild(new ParticleSystem()); var surfer = game.addChild(new Surfer()); surfer.setWaveSystem(waveSystem); var scoreText = new Text2("", { size: 100, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var multiplierText = new Text2("", { size: 60, fill: 0xFFFFFF, alpha: 0.8 }); multiplierText.anchor.set(1, 1); LK.gui.bottomRight.addChild(multiplierText); var bestScoreText = new Text2("Best: " + storage.bestScore, { size: 60, fill: 0xFFFFFF, alpha: 0.8 }); bestScoreText.anchor.set(0, 1); LK.gui.bottomLeft.addChild(bestScoreText); // Game update function var lastUpdateTime = 0; game.update = function () { var now = Date.now(); if (now - lastUpdateTime < 16) { // Don't update faster than 60fps return; } lastUpdateTime = now; // Every 300 frames, log counts if (LK.ticks % 600 === 0) { console.log('Active timers:', gameTimers.length); } if (LK.ticks % 300 === 0) { console.log('Particle count:', game.particles.children.length); console.log('Wave points:', waveSystem.points.length); console.log('Total game children:', game.children.length); console.log('Active tweens:', tween.getActiveTweens ? tween.getActiveTweens().length : 0); } waveSystem.update(); surfer.update(); particles.update(); // Update Poseidon's position to follow the player's face if (facekit.noseTip) { poseidon.x = facekit.noseTip.x; poseidon.y = facekit.noseTip.y; } // Update mouth position to follow the player's mouth if (facekit.mouthCenter) { mouth.x = facekit.mouthCenter.x; mouth.y = facekit.mouthCenter.y + 90; if (facekit.volume > 0.45) { // Change alpha to 1 when volume is greater than 0.35 mouth.alpha = 1; } else { mouth.alpha = 0; } } // Only spawn obstacles if not calibrating if (!waveSystem.isCalibrating) { // Rock spawning if (LK.ticks - lastRockTime > 240 + Math.random() * 360) { lastRockTime = LK.ticks; var rock = game.addChild(new Rock()); rock.x = 2548; // Start off right side rock.y = 2732 + 200; // Place base below screen // Set the vertical scale independently for random height rock.children[0].scaleY = 3 + Math.random() * 4; // Random height between 3x and 7x rocks.push(rock); } // Seagull spawning spawnSeagull(); } // Cloud spawning if (Date.now() - lastCloudSpawn > cloudSpawnInterval) { var cloud = new Cloud(); game.addChildAt(cloud, game.getChildIndex(poseidon) + (Math.random() < 0.5 ? 0 : 1)); // Add cloud at Poseidon's layer or one above lastCloudSpawn = Date.now(); cloudSpawnInterval = 2000 + Math.random() * 2000; // Random interval between 2-4 seconds } if (Date.now() - lastFishSpawn > fishSpawnInterval) { var fish = new Fish(); game.addChild(fish); lastFishSpawn = Date.now(); fishSpawnInterval = 3000 + Math.random() * 3000; // Random interval between 3-6 seconds } // Update and check rocks for (var i = rocks.length - 1; i >= 0; i--) { var rock = rocks[i]; rock.update(); // Remove destroyed rocks if (!rock.parent) { rocks.splice(i, 1); continue; } // Check collision with surfer if (rock.checkCollision(surfer)) { LK.showGameOver(); } } game.children.forEach(function (child) { if (child instanceof Seagull && child.update) { child.update(); } }); var currentScore = Math.floor(score); if (currentScore !== lastScoreDisplay) { lastScoreDisplay = currentScore; scoreText.setText(currentScore.toLocaleString()); } if (currentScore > storage.bestScore) { storage.bestScore = currentScore; bestScoreText.setText("Best: " + storage.bestScore); } var currentMultiplier = Math.floor(multiplier * 10) / 10; // Round to 1 decimal if (currentMultiplier !== lastMultiplierDisplay) { lastMultiplierDisplay = currentMultiplier; multiplierText.setText("x" + currentMultiplier.toFixed(1)); } var currentWholeMultiplier = Math.floor(multiplier); if (currentWholeMultiplier > lastWholeMultiplier) { console.log("Multiplier increased:", currentWholeMultiplier); // Debug log var popupText = new Text2(currentWholeMultiplier + "X MULTIPLIER!", { size: 120, fill: 0xFFFFFF, align: 'center', weight: 800 }); popupText.anchor.set(0.5, 0.5); LK.gui.center.addChild(popupText); popupText.scale.set(0.1); // Animate in tween(popupText.scale, { x: 1.2, y: 1.2 }, { duration: 400, easing: tween.elasticOut, onFinish: function onFinish() { // Animate out tween(popupText, { alpha: 0, y: popupText.y - 100 }, { duration: 800, delay: 600, easing: tween.easeOut, onFinish: function onFinish() { LK.gui.center.removeChild(popupText); popupText.destroy(); } }); } }); lastWholeMultiplier = currentWholeMultiplier; } };
===================================================================
--- original.js
+++ change.js
@@ -680,9 +680,10 @@
if (Date.now() - lastSeagullSpawn > seagullSpawnInterval) {
var seagull = new Seagull();
game.addChild(seagull);
lastSeagullSpawn = Date.now();
- seagullSpawnInterval = 4000 + Math.random() * 4000; // Random interval between 2-4 seconds
+ seagullSpawnInterval = 4000 + Math.random() * 4000; // Random interval between 2-4 seconds
+ LK.getSound('seagull').play(); // Play seagull sound effect
}
}
var rocks = [];
var lastRockTime = 0;
A surfer standing and riding on a surfboard. Side profile. Cartoon. Full body. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A peaked blue rock. Cartoon style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Poseidon’s face. Cartoon style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An opened pair of lips as if singing . Light Skin color. Cell shading vector art style. Facing forward. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A tropical fish. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows