User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 40; var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.7; var MIN_PITCH = 50; var MAX_PITCH = 300; // Adjusted max pitch var WAVE_HEIGHT = 2300; // Slightly more than needed to ensure we can hit top var lastPitch = 0; // Smoothing buffer var heightBuffer = Array(10).fill(0); // Store last 10 height values var bufferIndex = 0; // Create a single continuous line var 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); } function gaussianCurve(x) { return Math.exp(-(x * x) / 0.8); // Wider spread (0.5 -> 0.8) } function getSmoothedHeight(newHeight) { heightBuffer[bufferIndex] = newHeight; bufferIndex = (bufferIndex + 1) % heightBuffer.length; // Average the buffer return heightBuffer.reduce((a, b) => a + b) / heightBuffer.length; } self.update = function() { var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } // Smooth the pitch transition lastPitch += (targetPitch - lastPitch) * 0.15; // Get smoothed height var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT); points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = (i / (NUM_POINTS - 1)) * SCREEN_WIDTH; // Wider curve centered at 20% of screen var distanceFromCenter = (x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.4); // Increased spread var heightFactor = gaussianCurve(distanceFromCenter); var y = baseY - (smoothedHeight * heightFactor); points.push({x: x, y: y}); } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 40; // More points for smoother curve var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.7; // Base water level var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 2200; // Much higher maximum var lastPitch = 0; // Create a single continuous line var 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); } function gaussianCurve(x) { return Math.exp(-(x * x) / 0.5); // Wider, smoother bell curve } self.update = function() { // Update pitch with more aggressive scaling var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); // Square the pitch to make high notes reach higher targetPitch = normalizedPitch * normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate curve points points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = (i / (NUM_POINTS - 1)) * SCREEN_WIDTH; // Use gaussian curve for smooth bell shape var distanceFromCenter = (x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.3); var heightFactor = gaussianCurve(distanceFromCenter); var y = baseY - (lastPitch * WAVE_HEIGHT * heightFactor); points.push({x: x, y: y}); } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 30; // More points for smoother curve var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.7; // Base water level var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 1500; // Increased maximum height var lastPitch = 0; // Create a single continuous line var 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); } // Helper function for smooth curve function smoothStep(x) { return x * x * (3 - 2 * x); } self.update = function() { // Update pitch smoothly var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); // Enhance high-end response normalizedPitch = Math.pow(normalizedPitch, 0.8); // Makes higher pitches easier to reach targetPitch = normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate curve points points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = (i / (NUM_POINTS - 1)) * SCREEN_WIDTH; // Create smoother curve with wider peak var distanceFromCenter = Math.abs(x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.5); distanceFromCenter = Math.min(1, distanceFromCenter); var heightFactor = 1 - smoothStep(distanceFromCenter); // Calculate height with enhanced range var height = lastPitch * WAVE_HEIGHT * heightFactor; // Add slight curve to the peak if(heightFactor > 0.8) { height *= smoothStep((heightFactor - 0.8) * 5); } var y = baseY - height; points.push({x: x, y: y}); } // Update line segments to form smooth curve for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 20; // Fewer points, we'll space them out more var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.7; // Base water level var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 800; var lastPitch = 0; // Create a single continuous line var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 4 // Slightly thicker line }); lines.push(line); } self.update = function() { // Update pitch smoothly var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate curve points points = []; for(var i = 0; i < NUM_POINTS; i++) { // Create smooth curve that peaks at player position var x = (i / (NUM_POINTS - 1)) * SCREEN_WIDTH; var distanceFromCenter = Math.abs(x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.4); var heightFactor = Math.max(0, 1 - distanceFromCenter); var y = baseY - (lastPitch * WAVE_HEIGHT * heightFactor); points.push({x: x, y: y}); } // Update line segments to form smooth curve for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 60; var POINT_DISTANCE = 35; var points = []; var baseY = 2732 * 0.7; var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 800; var lastPitch = 0; var moveSpeed = 2; // Slower movement speed // Create lines between points var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 3 }); lines.push(line); } self.update = function() { var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate point positions for a single continuous wave var points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = i * POINT_DISTANCE; // Simple curve that rises based on pitch var heightMultiplier = Math.max(0, 1 - (i / (NUM_POINTS - 1))); var waveHeight = WAVE_HEIGHT * lastPitch * heightMultiplier; points.push({ x: x, y: baseY - waveHeight }); } // Move all points left for(var i = 0; i < lines.length; i++) { lines[i].x -= moveSpeed; if(lines[i].x < -POINT_DISTANCE) { lines[i].x += NUM_POINTS * POINT_DISTANCE; } } // Update line segments for(var i = 0; i < lines.length - 1; 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].width = length; lines[i].rotation = angle; lines[i].y = start.y; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace the wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 60; // More points for smoother curve var POINT_DISTANCE = 35; // Closer points var points = []; var baseY = 2732 * 0.7; var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 800; var wavePhase = 0; var lastPitch = 0; // Wave propagation parameters var WAVE_SPEED = 0.02; // Slower wave movement var WAVE_LENGTH = 4; // Longer waves // Create lines between points var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 3 }); lines.push(line); } self.update = function() { wavePhase += WAVE_SPEED; var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate point positions with gradual wave propagation var points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = i * POINT_DISTANCE; // Create gradual wave propagation var phaseOffset = (x / (POINT_DISTANCE * NUM_POINTS)) * Math.PI * WAVE_LENGTH; var waveHeight = Math.abs(Math.sin(wavePhase + phaseOffset)) * WAVE_HEIGHT * lastPitch; // Add distance-based attenuation var distanceAttenuation = 1 - (i / NUM_POINTS); waveHeight *= distanceAttenuation; points.push({ x: x, y: baseY - waveHeight }); } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 40; // More points for smoother curve var POINT_DISTANCE = 50; // Closer points var points = []; var baseY = 2732 * 0.7; var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 800; var wavePhase = 0; var lastPitch = 0; // Create lines between points var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 3 // Slightly thicker line }); lines.push(line); } self.update = function() { wavePhase += 0.05; var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } lastPitch += (targetPitch - lastPitch) * 0.1; // Calculate point positions var points = []; for(var i = 0; i < NUM_POINTS; i++) { var x = i * POINT_DISTANCE; var phaseOffset = (x / (POINT_DISTANCE * NUM_POINTS)) * Math.PI * 2; // Use absolute sine for upward-only waves var waveHeight = Math.abs(Math.sin(wavePhase + phaseOffset)) * WAVE_HEIGHT * lastPitch; points.push({ x: x - (wavePhase * 50) % POINT_DISTANCE, // Smooth movement y: baseY - waveHeight // Subtract for upward motion }); } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 30; var POINT_DISTANCE = 70; var points = []; var baseY = 2732 * 0.7; // Increased pitch and wave height ranges var MIN_PITCH = 50; var MAX_PITCH = 500; var WAVE_HEIGHT = 800; // Wave shape parameters var wavePhase = 0; var lastPitch = 0; // Create initial points for(var i = 0; i < NUM_POINTS; i++) { var point = self.attachAsset('wave_point', { anchorX: 0.5, anchorY: 0.5 }); point.x = i * POINT_DISTANCE; point.y = baseY; points.push(point); } // Add line segments between points var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5 }); lines.push(line); } self.update = function() { // Update wave phase wavePhase += 0.05; // Controls wave movement speed // Get current pitch influence var targetPitch = 0; if(facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } // Smooth pitch transitions lastPitch += (targetPitch - lastPitch) * 0.1; // Update points for(var i = 0; i < points.length; i++) { points[i].x -= 5; // Move left if(points[i].x < -POINT_DISTANCE) { points[i].x += NUM_POINTS * POINT_DISTANCE; } // Calculate wave height using sine wave and pitch var phaseOffset = (points[i].x / (POINT_DISTANCE * NUM_POINTS)) * Math.PI * 2; var waveHeight = Math.sin(wavePhase + phaseOffset) * WAVE_HEIGHT * lastPitch; // Add pitch-based offset var pitchOffset = (lastPitch - 0.5) * WAVE_HEIGHT; // Combine wave and pitch effects points[i].y = baseY + waveHeight + pitchOffset; } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace wave system with: var WaveSystem = Container.expand(function() { var self = Container.call(this); var NUM_POINTS = 30; // Increased points for smoother curve var POINT_DISTANCE = 70; // Decreased distance for tighter wave var points = []; var baseY = 2732 * 0.7; // Moved down to 70% of screen height // Pitch calibration var MIN_PITCH = 50; // Base noise level var MAX_PITCH = 150; // Typical high pitch var WAVE_HEIGHT = 400; // Maximum wave displacement // Create initial points for(var i = 0; i < NUM_POINTS; i++) { var point = self.attachAsset('wave_point', { anchorX: 0.5, anchorY: 0.5 }); point.x = i * POINT_DISTANCE; point.y = baseY; points.push(point); } // Add line segments between points var lines = []; for(var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5 }); lines.push(line); } self.update = function() { // Move points left for(var i = 0; i < points.length; i++) { points[i].x -= 5; // Speed of wave movement // If point moves off screen, move it to the right if(points[i].x < -POINT_DISTANCE) { points[i].x += NUM_POINTS * POINT_DISTANCE; } // Real-time wave height adjustment if(facekit.volume > 0.15) { // Normalize pitch between 0 and 1 var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); // Apply wave height with smooth transition var targetY = baseY - (normalizedPitch - 0.5) * WAVE_HEIGHT; points[i].y += (targetY - points[i].y) * 0.1; } else { // Gradually return to baseline when quiet points[i].y += (baseY - points[i].y) * 0.1; } } // Update line segments for(var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; // Position line lines[i].x = start.x; lines[i].y = start.y; // Calculate line length and rotation 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].width = length; lines[i].rotation = angle; } }; return self; }); ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (2 edits merged)
Please save this source code
User prompt
Update with: var waveSystem = game.addChild(new WaveSystem()); // Debug text for pitch/volume var debugText = new Text2("", { size: 50, fill: 0xFFFFFF }); debugText.anchor.set(0, 0); LK.gui.top.addChild(debugText); game.update = function() { waveSystem.update(); debugText.setText("Volume: " + facekit.volume.toFixed(2) + " Pitch: " + facekit.pitch.toFixed(2)); }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Remove playerorb class
User prompt
Remove game line class
User prompt
Replace self.update method with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; var MIN_VOLUME = 0.15; var SINGING_VOLUME = 0.25; // New constants for gameplay var BOTTOM_PITCH = 100; // Lowest note ('do') var TOP_PITCH = 200; // Highest note ('do' one octave up) var PITCH_BUFFER = 10; // Allow ±10 pitch units for matching if (this.smoothedPitch === undefined) { this.smoothedPitch = pitch; this.pitchHistory = []; } // Only process real singing if (volume > MIN_VOLUME) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; // Map pitch to screen space var normalizedPitch = (this.smoothedPitch - BOTTOM_PITCH) / (TOP_PITCH - BOTTOM_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); // Map to screen height, but leave 20% padding top and bottom normalizedPitch = normalizedPitch * 0.6 + 0.2; this.targetY = (1 - normalizedPitch) * 2732; // Debug display scoreText.setText( "Pitch: " + this.smoothedPitch.toFixed(0) + "\nPos: " + normalizedPitch.toFixed(2) ); } self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace the self.update method with this: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; var MIN_VOLUME = 0.15; var SINGING_VOLUME = 0.25; if (this.calibrationState === undefined) { this.calibrationState = "waiting"; this.smoothedPitch = pitch; this.pitchHistory = []; this.calibrationValues = []; scoreText.setText("Sing 'Happy Birthday' to calibrate! (When ready)"); } if (volume > MIN_VOLUME) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; } switch(this.calibrationState) { case "waiting": if (volume > SINGING_VOLUME) { this.calibrationState = "calibrating"; this.calibrationStartTime = LK.ticks; console.log("Calibration started!"); } scoreText.setText("Volume: " + volume.toFixed(2)); break; case "calibrating": if (volume > SINGING_VOLUME) { this.calibrationValues.push(this.smoothedPitch); } if (LK.ticks - this.calibrationStartTime > 480) { var validPitches = this.calibrationValues.filter(p => p > 0); validPitches.sort((a, b) => a - b); // Find the median pitch (center of their range) var medianPitch = validPitches[Math.floor(validPitches.length / 2)]; // Calculate standard deviation to understand spread var avgPitch = validPitches.reduce((a, b) => a + b) / validPitches.length; var variance = validPitches.reduce((a, b) => a + Math.pow(b - avgPitch, 2), 0) / validPitches.length; var stdDev = Math.sqrt(variance); // Set range to median ± 1.5 standard deviations // This should capture ~87% of normal singing range this.minPitch = medianPitch - (stdDev * 1.5); this.maxPitch = medianPitch + (stdDev * 1.5); console.log("Calibration complete!", "Median:", medianPitch.toFixed(1), "Min:", this.minPitch.toFixed(1), "Max:", this.maxPitch.toFixed(1), "StdDev:", stdDev.toFixed(1)); this.calibrationState = "ready"; } break; case "ready": if (volume > MIN_VOLUME) { // Linear mapping but with some padding var normalizedPitch = (this.smoothedPitch - this.minPitch) / (this.maxPitch - this.minPitch); // Add 20% padding on top and bottom normalizedPitch = normalizedPitch * 0.6 + 0.2; normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); this.targetY = (1 - normalizedPitch) * 2732; scoreText.setText( "Pitch: " + this.smoothedPitch.toFixed(0) + "\nRange: " + this.minPitch.toFixed(0) + " - " + this.maxPitch.toFixed(0) + "\nPos: " + normalizedPitch.toFixed(2) ); } break; } self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Delete the self.update section of player orb class.
User prompt
Update self.update as needed with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; // Increased volume thresholds var MIN_VOLUME = 0.15; // For any pitch detection var SINGING_VOLUME = 0.25; // For calibration/actual notes if (this.calibrationState === undefined) { this.calibrationState = "waiting"; this.smoothedPitch = pitch; this.pitchHistory = []; this.calibrationValues = []; this.minPitch = 0; this.maxPitch = 0; scoreText.setText("Sing 'Happy Birthday' to calibrate! (When ready)"); } // Only process pitch when volume is significant if (volume > MIN_VOLUME) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; } switch(this.calibrationState) { case "waiting": // Start calibration on first strong note if (volume > SINGING_VOLUME) { this.calibrationState = "calibrating"; this.calibrationStartTime = LK.ticks; console.log("Calibration started!", "Volume:", volume); } scoreText.setText("Volume: " + volume.toFixed(2) + "\nNeed " + SINGING_VOLUME.toFixed(2) + " to start"); break; case "calibrating": // Only collect values when actually singing if (volume > SINGING_VOLUME) { this.calibrationValues.push(this.smoothedPitch); console.log("Recorded pitch:", this.smoothedPitch.toFixed(1), "Volume:", volume.toFixed(2)); } scoreText.setText("Calibrating... Keep singing!\nTime left: " + ((480 - (LK.ticks - this.calibrationStartTime))/60).toFixed(1) + "s"); if (LK.ticks - this.calibrationStartTime > 480) { var validPitches = this.calibrationValues.filter(p => p > 0); validPitches.sort((a, b) => a - b); var lowIndex = Math.floor(validPitches.length * 0.1); var highIndex = Math.floor(validPitches.length * 0.9); this.minPitch = validPitches[lowIndex]; this.maxPitch = validPitches[highIndex]; console.log("Calibration complete!", "Min:", this.minPitch.toFixed(1), "Max:", this.maxPitch.toFixed(1), "Samples:", validPitches.length); this.calibrationState = "ready"; } break; case "ready": if (volume > MIN_VOLUME) { var normalizedPitch = Math.log(this.smoothedPitch / this.minPitch) / Math.log(this.maxPitch / this.minPitch); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); this.targetY = (1 - normalizedPitch) * 2732; scoreText.setText( "Volume: " + volume.toFixed(2) + "\nPitch: " + this.smoothedPitch.toFixed(0) + "\nNorm: " + normalizedPitch.toFixed(2) ); } break; } self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update in player orb with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; if (this.calibrationState === undefined) { this.calibrationState = "waiting"; // waiting -> calibrating -> ready this.smoothedPitch = pitch; this.pitchHistory = []; this.calibrationValues = []; this.minPitch = 0; this.maxPitch = 0; scoreText.setText("Sing 'Happy Birthday' to calibrate!"); } // Always maintain smooth pitch for responsiveness if (volume > 0.1) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; } // Calibration logic switch(this.calibrationState) { case "waiting": // Start calibration when first strong note is detected if (volume > 0.2) { this.calibrationState = "calibrating"; this.calibrationStartTime = LK.ticks; console.log("Calibration started!"); } break; case "calibrating": // Collect pitch values during singing if (volume > 0.2) { this.calibrationValues.push(this.smoothedPitch); scoreText.setText("Calibrating... Keep singing!"); } // End calibration after about 8 seconds (typical Happy Birthday duration) if (LK.ticks - this.calibrationStartTime > 480) { // 60 ticks per second // Filter out outliers and set range var validPitches = this.calibrationValues.filter(p => p > 0); validPitches.sort((a, b) => a - b); // Use 10th and 90th percentiles to avoid extreme outliers var lowIndex = Math.floor(validPitches.length * 0.1); var highIndex = Math.floor(validPitches.length * 0.9); this.minPitch = validPitches[lowIndex]; this.maxPitch = validPitches[highIndex]; console.log("Calibration complete!", "Min:", this.minPitch.toFixed(1), "Max:", this.maxPitch.toFixed(1)); this.calibrationState = "ready"; } break; case "ready": if (volume > 0.1) { // Use calibrated range for normalization var normalizedPitch = Math.log(this.smoothedPitch / this.minPitch) / Math.log(this.maxPitch / this.minPitch); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); this.targetY = (1 - normalizedPitch) * 2732; scoreText.setText( "P:" + this.smoothedPitch.toFixed(0) + " N:" + normalizedPitch.toFixed(2) ); } break; } self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update in player orb with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; if (this.smoothedPitch === undefined) { this.smoothedPitch = pitch; this.pitchHistory = []; this.rangeHistory = []; this.detectedRange = null; } if (volume > 0.1) { // Maintain pitch history for smoothing this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; // Collect range data from first few strong notes if (volume > 0.2 && this.rangeHistory.length < 10) { this.rangeHistory.push(this.smoothedPitch); } // After collecting enough samples, detect vocal range if (!this.detectedRange && this.rangeHistory.length >= 5) { var avgRange = this.rangeHistory.reduce((a, b) => a + b, 0) / this.rangeHistory.length; if (avgRange < 130) this.detectedRange = "bass"; else if (avgRange < 180) this.detectedRange = "tenor"; else if (avgRange < 250) this.detectedRange = "alto"; else this.detectedRange = "soprano"; // Set range-specific min/max switch(this.detectedRange) { case "bass": this.minPitch = 80; this.maxPitch = 180; break; case "tenor": this.minPitch = 100; this.maxPitch = 200; break; case "alto": this.minPitch = 150; this.maxPitch = 300; break; case "soprano": this.minPitch = 200; this.maxPitch = 400; break; } } // Use detected range for normalization if (this.detectedRange) { var normalizedPitch = Math.log(this.smoothedPitch / this.minPitch) / Math.log(this.maxPitch / this.minPitch); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); this.targetY = (1 - normalizedPitch) * 2732; } console.log( "Pitch:", this.smoothedPitch.toFixed(1), "Range:", this.detectedRange || "detecting", "Normalized:", normalizedPitch?.toFixed(2) ); } scoreText.setText( "Range: " + (this.detectedRange || "detecting") + " P:" + this.smoothedPitch?.toFixed(0) ); self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; if (this.smoothedPitch === undefined) { this.smoothedPitch = pitch; this.pitchHistory = []; } // Debug values to help us calibrate var minPitch = 50; // Adjust based on your lowest comfortable note var maxPitch = 400; // Adjust based on your highest comfortable note if (volume > 0.1) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; // Try logarithmic scaling for more natural note spacing var normalizedPitch = Math.log(this.smoothedPitch / minPitch) / Math.log(maxPitch / minPitch); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); this.targetY = (1 - normalizedPitch) * 2732; console.log( "Raw Pitch:", pitch.toFixed(1), "Smoothed:", this.smoothedPitch.toFixed(1), "Normalized:", normalizedPitch.toFixed(2) ); } // Show both raw and normalized values for debugging scoreText.setText("P:" + this.smoothedPitch?.toFixed(0) + " N:" + (this.smoothedPitch ? (Math.log(this.smoothedPitch / minPitch) / Math.log(maxPitch / minPitch)).toFixed(2) : "---")); self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update in player orb with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; if (this.smoothedPitch === undefined) { this.smoothedPitch = pitch; this.pitchHistory = []; } if (volume > 0.1) { this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { this.pitchHistory.shift(); } var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; // Calculate which staff line/space we're closest to var normalizedPitch = Math.max(0, Math.min(1, (this.smoothedPitch - 100) / 100)); var staffPosition = Math.floor(normalizedPitch * 11); // Dividing into 11 positions (6 spaces including above/below staff) this.targetY = (1 - normalizedPitch) * 2732; console.log( "Pitch:", this.smoothedPitch.toFixed(1), "Position:", staffPosition, "Line/Space:", ["Below", "E", "F", "G", "A", "B", "C", "D", "E", "F", "Above"][staffPosition] ); } // Updated debug display to show musical note var staffPosition = Math.floor(Math.max(0, Math.min(1, (this.smoothedPitch - 100) / 100)) * 11); var note = ["Below", "E", "F", "G", "A", "B", "C", "D", "E", "F", "Above"][staffPosition] || "---"; scoreText.setText("Note: " + note + " (P:" + this.smoothedPitch?.toFixed(0) + ")"); self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update in player orb with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; // Initialize smoothedPitch if it doesn't exist if (this.smoothedPitch === undefined) { this.smoothedPitch = pitch; this.pitchHistory = []; } // Only process when actually singing if (volume > 0.1) { // Keep a rolling window of pitch values this.pitchHistory.push(pitch); if (this.pitchHistory.length > 5) { // Adjust window size as needed this.pitchHistory.shift(); } // Calculate average pitch from history var avgPitch = this.pitchHistory.reduce((a, b) => a + b, 0) / this.pitchHistory.length; // Smooth the transition this.smoothedPitch = this.smoothedPitch * 0.8 + avgPitch * 0.2; // Map smoothed pitch to screen position (adjust range based on your 100-200 observation) var normalizedPitch = Math.max(0, Math.min(1, (this.smoothedPitch - 100) / 100)); this.targetY = (1 - normalizedPitch) * 2732; console.log("Raw:", pitch.toFixed(1), "Smoothed:", this.smoothedPitch.toFixed(1)); } scoreText.setText("V:" + volume.toFixed(2) + " P:" + this.smoothedPitch?.toFixed(2)); // Regular movement interpolation self.y += (self.targetY - self.y) * 0.1; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Replace self.update in player orb with: self.update = function () { var pitch = facekit.pitch; var volume = facekit.volume; // Only log when actually making sound if (volume > 0.1) { console.log("Active Pitch:", pitch.toFixed(2)); } scoreText.setText("V:" + volume.toFixed(2) + " P:" + pitch.toFixed(2)); // Keep current interpolation self.y += (self.targetY - self.y) * 0.1; };
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var WaveSystem = Container.expand(function () { var self = Container.call(this); var NUM_POINTS = 40; var SCREEN_WIDTH = 2048; var points = []; var baseY = 2732 * 0.7; var MIN_PITCH = 50; var MAX_PITCH = 300; // Adjusted max pitch var WAVE_HEIGHT = 2300; // Slightly more than needed to ensure we can hit top var lastPitch = 0; // Smoothing buffer var heightBuffer = Array(10).fill(0); // Store last 10 height values var bufferIndex = 0; // Create a single continuous line var 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); } function gaussianCurve(x) { return Math.exp(-(x * x) / 0.8); // Wider spread (0.5 -> 0.8) } function getSmoothedHeight(newHeight) { heightBuffer[bufferIndex] = newHeight; bufferIndex = (bufferIndex + 1) % heightBuffer.length; // Average the buffer return heightBuffer.reduce(function (a, b) { return a + b; }) / heightBuffer.length; } self.update = function () { var targetPitch = 0; if (facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch; } // Smooth the pitch transition lastPitch += (targetPitch - lastPitch) * 0.15; // Get smoothed height var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT); points = []; for (var i = 0; i < NUM_POINTS; i++) { var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH; // Wider curve centered at 20% of screen var distanceFromCenter = (x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.4); // Increased spread var heightFactor = gaussianCurve(distanceFromCenter); var y = baseY - smoothedHeight * heightFactor; points.push({ x: x, y: y }); } // Update line segments for (var i = 0; i < lines.length; i++) { var start = points[i]; var end = points[i + 1]; lines[i].x = start.x; lines[i].y = start.y; 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].width = length; lines[i].rotation = angle; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ var waveSystem = game.addChild(new WaveSystem()); // Debug text for pitch/volume var debugText = new Text2("", { size: 50, fill: 0xFFFFFF }); debugText.anchor.set(0, 0); LK.gui.top.addChild(debugText); // Game update function game.update = function () { waveSystem.update(); debugText.setText("Volume: " + facekit.volume.toFixed(2) + " Pitch: " + facekit.pitch.toFixed(2)); };
===================================================================
--- original.js
+++ change.js
@@ -8,16 +8,19 @@
* Classes
****/
var WaveSystem = Container.expand(function () {
var self = Container.call(this);
- var NUM_POINTS = 40; // More points for smoother curve
+ var NUM_POINTS = 40;
var SCREEN_WIDTH = 2048;
var points = [];
- var baseY = 2732 * 0.7; // Base water level
+ var baseY = 2732 * 0.7;
var MIN_PITCH = 50;
- var MAX_PITCH = 500;
- var WAVE_HEIGHT = 2200; // Much higher maximum
+ var MAX_PITCH = 300; // Adjusted max pitch
+ var WAVE_HEIGHT = 2300; // Slightly more than needed to ensure we can hit top
var lastPitch = 0;
+ // Smoothing buffer
+ var heightBuffer = Array(10).fill(0); // Store last 10 height values
+ var bufferIndex = 0;
// Create a single continuous line
var lines = [];
for (var i = 0; i < NUM_POINTS - 1; i++) {
var line = self.attachAsset('wave_line', {
@@ -27,28 +30,36 @@
});
lines.push(line);
}
function gaussianCurve(x) {
- return Math.exp(-(x * x) / 0.5); // Wider, smoother bell curve
+ return Math.exp(-(x * x) / 0.8); // Wider spread (0.5 -> 0.8)
}
+ function getSmoothedHeight(newHeight) {
+ heightBuffer[bufferIndex] = newHeight;
+ bufferIndex = (bufferIndex + 1) % heightBuffer.length;
+ // Average the buffer
+ return heightBuffer.reduce(function (a, b) {
+ return a + b;
+ }) / heightBuffer.length;
+ }
self.update = function () {
- // Update pitch with more aggressive scaling
var targetPitch = 0;
if (facekit.volume > 0.15) {
var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH);
normalizedPitch = Math.max(0, Math.min(1, normalizedPitch));
- // Square the pitch to make high notes reach higher
- targetPitch = normalizedPitch * normalizedPitch;
+ targetPitch = normalizedPitch;
}
- lastPitch += (targetPitch - lastPitch) * 0.1;
- // Calculate curve points
+ // Smooth the pitch transition
+ lastPitch += (targetPitch - lastPitch) * 0.15;
+ // Get smoothed height
+ var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT);
points = [];
for (var i = 0; i < NUM_POINTS; i++) {
var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH;
- // Use gaussian curve for smooth bell shape
- var distanceFromCenter = (x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.3);
+ // Wider curve centered at 20% of screen
+ var distanceFromCenter = (x - SCREEN_WIDTH * 0.2) / (SCREEN_WIDTH * 0.4); // Increased spread
var heightFactor = gaussianCurve(distanceFromCenter);
- var y = baseY - lastPitch * WAVE_HEIGHT * heightFactor;
+ var y = baseY - smoothedHeight * heightFactor;
points.push({
x: x,
y: y
});
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