User prompt
Now use the new songListV3, given that beat values are: 1 : gate on right 2 : gate on left gate on center for values 0 and 3
Code edit (5 edits merged)
Please save this source code
User prompt
create only one global pair of ``` var centerX = 1024; var centerY = 1366; ``` remove all other local versions
User prompt
??? Please Analyze seriously : you create a local playerObj variable and move it and you are happy with your work ???!!! Review the version before sphere removal and fix that seriously
User prompt
After sphere removal, controls doesn't work anymore! they should work like before as instructed
User prompt
Remove the Sphere WITHOUT BREAKING ANYTHING, especially the runner, ball and player control should continue to work like currently
User prompt
currently movement hanldy primarly depends on the sphere; make it depend on the ball (because in a future step we gonna remove the sphere)
Code edit (1 edits merged)
Please save this source code
User prompt
remove properly Target and TargetManager
Code edit (1 edits merged)
Please save this source code
User prompt
remove properly Target and TargetManager
User prompt
I have add `songListV3` that utilize enhanced song features. The new format provides much richer data including intensity, pitch, and energy values for each beat: t: Timestamp in milliseconds b: Beat type (1, 2, 3) i: Intensity value ranging from 0 to approximately 30 p: Pitch frequency value ranging from approximately 1000 to 3700 e: Energy value ranging from 0 to approximately 0.5 d: Drum type (1, 2, 3) ✅ Add enhanced visual effects based on intensity values from songListV3 ✅ Update GateManager to use songListV3 format : Gate angles shoud reflect song rythm changes but stick with existing 'snap' angles ✅ Update spawnGateAtTime to use enhanced song data properties : when spawning a gate take into account the time that the gate requires to reach the player: this will alow player to feel the music features 'live' instead with a delay. ✅ Update GateManager checkSongEnd to use songListV3 time property ✅ Update GateManager update method to check time property correctly ✅ Update BackgroundManager to respond to energy levels ✅ Add particle effects on gates/ball collision ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
I have add `songListV3` that utilize enhanced song features. The new format provides much richer data including intensity, pitch, and energy values for each beat: t: Timestamp in milliseconds b: Beat type (1, 2, 3) i: Intensity value ranging from 0 to approximately 30 p: Pitch frequency value ranging from approximately 1000 to 3700 e: Energy value ranging from 0 to approximately 0.5 ✅ Add enhanced visual effects based on intensity values from songListV3 ✅ Update GateManager to use songListV3 format and apply pitch-based positioning ✅ Update spawnGateAtTime to use enhanced song data properties => gate angles shoud reflect song rythm changes ✅ Update GateManager checkSongEnd to use songListV3 time property ✅ Update GateManager update method to check time property correctly ✅ Update BackgroundManager to respond to energy levels ✅ Add particle effects on gates/ball collision ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
I have add `songListV3` that utilize enhanced song features. The new format provides much richer data including intensity, pitch, and energy values for each beat: t: Timestamp in milliseconds b: Beat type (1, 2, 3) i: Intensity value ranging from 0 to approximately 30 p: Pitch frequency value ranging from approximately 1000 to 3700 e: Energy value ranging from 0 to approximately 0.5 Required Modifications 1. Adapt the code to the new Data Structure Modify the song data loading mechanism to take into account the new properties 2. Enhance Visual Elements Based on New Properties Intensity-Based Enhancements Use the intensity value to dynamically scale visual elements gates Higher intensity should create more dramatic visual effects: Increase particle effects or visual feedback when hitting gates with high intensity Make gates with high intensity values more visually distinct (e.g., pulsating, glowing) Consider using intensity to control camera shake or screen effects during powerful beats Pitch-Based Enhancements Map the pitch value to vertical positioning of gates Use pitch to determine color variations (e.g., higher pitch = warmer colors, lower pitch = cooler colors) Energy-Based Enhancements Use the energy value to control the overall visual intensity of the scene Higher energy should create intense background animations Affect the tunnel/background visuals based on energy levels Control particle density or trail effects behind the player based on energy Consider using energy to modify the size of the play area or the speed of movement 3. Gameplay Mechanics Create difficulty variations based on the combination of intensity, pitch, and energy Add bonus scoring opportunities during high energy/intensity sections Consider creating special "power-up" gates that appear during specific combinations of these values 4. Audio-Visual Synchronization Improve the synchronization between visual effects and audio using the more detailed beat information Create more nuanced visual responses to the music by utilizing all three new properties simultaneously 5. Performance Optimization Ensure the enhanced visual effects don't cause performance issues Implement level-of-detail adjustments based on device capabilities Implementation Notes Maintain backward compatibility with the old beat format if needed Keep the core gameplay mechanics intact while enhancing the visual experience Use smooth transitions between different states to avoid jarring visual changes Consider creating a calibration system to normalize values across different songs ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
simplyfy the control more with this behaviour: tap on the left 1/2 of screen => move to left 'lane' tap on the right 1/2 of screen => move to right 'lane' release => return to center 'lane' ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
player movement between lanes is a bit too fast, please fix
User prompt
currently, when player is on the right 'lane' of the tube and taps on the left 1/3 then player move in a straight line to the left 'lane' => it should follow the 'pipe' shape by passing to the center 'lane' then to the left lane ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (2 edits merged)
Please save this source code
User prompt
simplify the move system by using this rule : tap on the left 1/3 of screen => move to to left 'lane' tap on the center 1/3 of screen => move to to center 'lane' tap on the right 1/3 of screen => move to to right 'lane' ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
in down() handler, replace the fixed 50 by a global moveDetectionThreshold; and current invert left and right moves
User prompt
replace dragging by a simple tap : tapping left or right to the sphere/ball/runner make it move to the snap on the left or the right (move between snap positions should be continuous) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
✅ Add magnetic snapping positions for left, center, and right ✅ Replace sphere movement logic with magnetic snapping behavior ✅ Add logic to move to other snap position depending on dragging threashold ✅ Initialize sphere/ball/runner at center snap position
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ /***********************************************************************************/ /******************************* UTILITY FUNCTIONS *********************************/ /***********************************************************************************/ var BackgroundManager = Container.expand(function () { var self = Container.call(this); // Create three background instances for smoother tunnel effect self.bg0 = self.attachAsset('background01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 2.4, scaleY: 2.4, alpha: 1 }); self.bg1 = self.attachAsset('background01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 1.1, scaleY: 1.1, alpha: 1 }); self.bg2 = self.attachAsset('background01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.5, scaleY: 0.5, alpha: 1 }); self.bg3 = self.attachAsset('background01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.22, scaleY: 0.22, alpha: 1 }); self.bg4 = self.attachAsset('background01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.11, scaleY: 0.11, alpha: 1 }); self.tore0 = self.attachAsset('tore', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 1.2, scaleY: 1.2, alpha: 0 }); self.tore1 = self.attachAsset('tore', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.6, scaleY: 0.6, alpha: 0 }); self.tore2 = self.attachAsset('tore', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.26, scaleY: 0.26, alpha: 0 }); self.tore3 = self.attachAsset('tore', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.12, scaleY: 0.12, alpha: 0 }); // Apply different tints in debug mode if (isDebug) { self.bg1.tint = 0xFF0000; // Red tint for first background self.tore1.tint = 0x00FF00; // Green tint for first tore self.bg2.tint = 0x00FFFF; // Cyan tint for second background self.tore2.tint = 0xFF00FF; // Magenta tint for second tore self.bg3.tint = 0xfff200; // Yellow tint for third background } // Animation properties self.bgAnimationSpeed = globalSpeed / 1000; //0.002; self.bgAnimationAcceleration = 2; // Add tore assets between backgrounds for animation self.backgrounds = [self.bg0, self.tore0, self.bg1, self.tore1, self.bg2, self.tore2, self.bg3, self.tore3, self.bg4]; //self.backgrounds = [self.bg0, self.bg1, self.bg2, self.bg3]; // Define initial scale for each background/torus (tore: 0.26, bg: 0.22) //self.bgInitialScales = [0.22, 0.22, 0.22, 0.22, 0.22]; //self.bgInitialScales = [0, 0, 0, 0, 0]; //self.bgInitialScales = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // Animation state: single startTime for all backgrounds/torus self.bgAnimStartTime = Date.now(); // Update method - handle background/torus scale animation self.update = function () { var now = Date.now(); var elapsed = now - self.bgAnimStartTime; var resetTriggered = false; // Get current energy level from gates var currentEnergy = 0.3; // Default energy if (gateManager && gateManager.gates.length > 0) { // Find the closest gate to player var closestGate = null; var closestScale = 0; for (var g = 0; g < gateManager.gates.length; g++) { var gate = gateManager.gates[g]; if (gate.gateAsset.scaleX > closestScale) { closestScale = gate.gateAsset.scaleX; closestGate = gate; } } if (closestGate && closestGate.energy) { currentEnergy = closestGate.energy; } } // Adjust animation speed based on energy var energyMultiplier = 1 + currentEnergy * 2; // Speed up to 3x based on energy for (var i = 0; i < self.backgrounds.length; i++) { var bg = self.backgrounds[i]; // Make the scale speed increase as the scale increases (e.g. exponential or quadratic growth) //var scaleMultiplier = bg.scaleX * self.bgAnimationAcceleration; //bg.scaleX += self.bgAnimationSpeed * scaleMultiplier; bg.scaleX += self.bgAnimationSpeed * bg.scaleX * energyMultiplier; bg.scaleY = bg.scaleX; if (bg.scaleX > 3.0) { bg.scaleX = 0.12; //self.bgInitialScales[i]; bg.scaleY = bg.scaleX; } //bg.alpha = Math.min(1, bg.scaleX + 0.66); // Tint based on energy level var energyTint = 0x1697b8; if (currentEnergy > 0.4) { // High energy - warmer color energyTint = 0xFF6B35; } else if (currentEnergy < 0.2) { // Low energy - cooler color energyTint = 0x0066CC; } bg.tint = energyTint; } }; return self; }); // Initialize the game; /***********************************************************************************/ /********************************** BALL CLASS *************************************/ /***********************************************************************************/ var Ball = Container.expand(function () { var self = Container.call(this); // Create and attach ball asset var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: currentColor, alpha: 1 }); // Initialize ball properties self.speedX = 0; self.speedY = 0; // Track last intersecting state for each gate self.lastIntersectingGates = {}; // Update method to follow sphere's position self.update = function () { // Make ball follow sphere's exact position if (sphere) { self.x = sphere.x; self.y = sphere.y; } // Check for collisions with gates if (gateManager && gateManager.gates) { // Iterate backwards to avoid index shifting issues when removing gates for (var i = gateManager.gates.length - 1; i >= 0; i--) { var gate = gateManager.gates[i]; var gateId = gate.gateId; // Initialize tracking if needed if (self.lastIntersectingGates[gateId] === undefined) { self.lastIntersectingGates[gateId] = false; } // Check intersection with bounding box instead of gate asset var currentIntersecting = self.intersects(gate.boundingBox); // Detect transition from not intersecting to intersecting if (!self.lastIntersectingGates[gateId] && currentIntersecting) { // Mark gate as being destroyed to prevent multiple triggers if (!gate.isDestroying) { gate.isDestroying = true; // Create particle burst effect var particleCount = 8 + Math.floor(gate.intensity / 5); // More particles for higher intensity for (var p = 0; p < particleCount; p++) { var particle = new Particle(); particle.x = gate.boundingBox.x; particle.y = gate.boundingBox.y; // Random velocity var angle = Math.PI * 2 / particleCount * p + Math.random() * 0.5; var speed = 5 + Math.random() * 5 + gate.energy * 10; // Faster for high energy particle.velocityX = Math.cos(angle) * speed; particle.velocityY = Math.sin(angle) * speed; // Set particle color to match gate particle.tint = gate.gateColor; // Add to game (temporary container would be better) game.addChild(particle); // Update particle in a simple way var updateParticle = function updateParticle(part) { var _tick = function tick() { if (!part.update()) { part.destroy(); } else { LK.setTimeout(_tick, 16); // ~60fps } }; _tick(); }; updateParticle(particle); } // Animate scale down tween(gate, { scaleX: 0, scaleY: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { // Request destruction from gate manager gateManager.destroyGate(gate); } }); } // Play the sound based on the gate's assigned key if (gate.noteKey) { // Extract the number from the key (e.g., "Key6" -> "6") var keyNumber = gate.noteKey.replace('Key', ''); var soundKey = 'key' + keyNumber; // Play the corresponding sound LK.getSound(soundKey).play(); } } // Update last intersecting state self.lastIntersectingGates[gateId] = currentIntersecting; } // No cleanup needed - gate IDs are unique and won't be reused } }; return self; }); /***********************************************************************************/ /********************************** CUBE CLASS ************************************/ /***********************************************************************************/ var Cube = Container.expand(function (wRatio, hRatio, dRatio) { var self = Container.call(this); wRatio = wRatio || 1; hRatio = hRatio || 1; dRatio = dRatio || 1; self.z = 0; self.baseSize = 100; // Initialize cube faces using SimpleFace class self.frontFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 0, dy: 0, dz: 1 * dRatio, rx: 0, ry: 0, rz: 0, ti: 0xFFFFFF }); self.backFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 0, dy: 0, dz: -1 * dRatio, rx: Math.PI, ry: 0, rz: 0, ti: 0xFFFFFF }); self.leftFace = new SimpleFace({ w: self.baseSize * dRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: -1 * wRatio / dRatio, dy: 0, dz: 0, rx: 0, ry: Math.PI / 2, rz: 0, ti: 0xFFFFFF }); self.rightFace = new SimpleFace({ w: self.baseSize * dRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 1 * wRatio / dRatio, dy: 0, dz: 0, rx: 0, ry: -Math.PI * 0.5, rz: 0, ti: 0xFFFFFF }); self.topFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * dRatio, d: self.baseSize, dx: 0, dy: -1 * hRatio / dRatio, dz: 0, rx: -Math.PI / 2, ry: 0, rz: 0, ti: 0xFFFFFF }); self.bottomFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * dRatio, d: self.baseSize, dx: 0, dy: 1 * hRatio / dRatio, dz: 0, rx: Math.PI / 2, ry: 0, rz: 0, ti: 0xFFFFFF }); self.faces = [self.frontFace, self.backFace, self.leftFace, self.rightFace, self.topFace, self.bottomFace]; self.faces.forEach(function (face) { self.addChild(face); }); self.speedX = 0; self.speedY = 0; self.speedZ = 0; // Rotate cube around its axes self.rotate3D = function (angleX, angleY, angleZ) { log("cube rotate3D "); self.rotation = angleZ; var zScaleFactor = 1 + self.z / 500; self.faces.forEach(function (face) { face.rotate3D(angleX, angleY, angleZ, zScaleFactor); }); }; }); /***********************************************************************************/ /********************************** CUBE MANAGER CLASS *****************************/ /***********************************************************************************/ var CubeManager = Container.expand(function () { var self = Container.call(this); // Array to hold all managed cubes self.cubes = []; // Configuration for spawning self.maxCubes = 3; // Maximum number of cubes // Spawn all cubes at once self.spawnAllCubes = function () { // Calculate spacing for equal distribution var screenWidth = 2048; var cubeSpacing = screenWidth / (self.maxCubes + 1); // Divide screen into equal sections var verticalCenter = 2732 / 2; // Vertical center of the screen // Prepare color assignment: one cube gets currentColor, others get two different neon colors (not currentColor) var colorIndices = []; for (var c = 0; c < neonColors.length; c++) { if (neonColors[c] !== currentColor) { colorIndices.push(c); } } // Shuffle colorIndices to randomize which two colors are picked for the other cubes for (var s = colorIndices.length - 1; s > 0; s--) { var j = Math.floor(Math.random() * (s + 1)); var temp = colorIndices[s]; colorIndices[s] = colorIndices[j]; colorIndices[j] = temp; } var cubeColors = [currentColor, neonColors[colorIndices[0]], neonColors[colorIndices[1]]]; // Shuffle cubeColors so currentColor is not always in the same position for (var s2 = cubeColors.length - 1; s2 > 0; s2--) { var j2 = Math.floor(Math.random() * (s2 + 1)); var temp2 = cubeColors[s2]; cubeColors[s2] = cubeColors[j2]; cubeColors[j2] = temp2; } for (var i = 0; i < self.maxCubes; i++) { // Create a new cube with equal dimensions (true cube, not rectangle) var cube = new Cube(1, 1, 1); // Set position - equally distributed horizontally at vertical center cube.x = cubeSpacing * (i + 1); // Distribute equally across the screen cube.y = verticalCenter; cube.z = 0; // Keep all cubes at same Z position // Set speeds to zero so cubes don't move cube.speedX = 0; cube.speedY = 0; cube.speedZ = 0; // Set random initial rotation cube.rotate3D(Math.random() * Math.PI * 2, Math.random() * Math.PI * 2, Math.random() * Math.PI * 2); // Assign color: one cube gets currentColor, others get two different neon colors var assignedTint = cubeColors[i % cubeColors.length]; cube.faces.forEach(function (face) { face.tint = assignedTint; }); // Add cube to the manager and the game self.cubes.push(cube); self.addChild(cube); } }; // Remove a cube from management self.removeCube = function (cube) { var index = self.cubes.indexOf(cube); if (index > -1) { self.cubes.splice(index, 1); cube.destroy(); } }; // Update all managed cubes self.updateCubes = function () { for (var i = self.cubes.length - 1; i >= 0; i--) { var cube = self.cubes[i]; // Cubes don't move, so no position updates needed // Rotate cube cube.z += 1; //cube.speedZ; cube.rotate3D(Math.PI * 0.01, Math.PI * 0.01, Math.PI * 0.01); } }; // Initialize by spawning all cubes at once self.spawnAllCubes(); // Update method called by the game loop self.update = function () { //self.updateCubes(); }; return self; }); /***********************************************************************************/ /******************************* FACE CLASS *********************************/ /***********************************************************************************/ var Face = Container.expand(function (options) { var self = Container.call(this); options = options || {}; var points = Math.max(2, Math.min(100, options.points || 4)); // Ensure points are between 2 and 10 self.baseSize = 100; self.w = options.w || self.baseSize; self.h = options.h || self.baseSize; self.d = options.d || self.baseSize; self.dx = options.dx || 0; self.dy = options.dy || 0; self.dz = options.dz || 0; self.rx = options.rx || 0; self.ry = options.ry || 0; self.rz = options.rz || 0; self.tint = options.ti || 0xFFFFFF; // Generate points for the face based on the number of points specified self.baseFaceCoordinates = []; for (var i = 0; i < points; i++) { var angle = 2 * Math.PI * (i / points); self.baseFaceCoordinates.push({ x: self.w / 2 * Math.cos(angle) + self.dx * self.w, y: self.h / 2 * Math.sin(angle) + self.dy * self.h, z: self.dz * self.d }); } self.baseFaceCoordinates.forEach(function (point) { // Update z of each face point coordinates depending on dz and rx, ry point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry); }); // Create a polygon face using the Shape class self.face = new Shape(self.baseFaceCoordinates, self.tint); // Attach the face to the Face container self.addChild(self.face); // Rotate in 3D: X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune self.rotate3D = function (angleX, angleY, angleZ, scale) { scale = scale || 1; self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) { var x = coord.x - self.dx * self.w, y = coord.y - self.dy * self.h, z = coord.z - self.dz * self.d; // Apply initial rotations (rx, ry, rz) var newY = y * Math.cos(self.rx) - z * Math.sin(self.rx); var newZ = y * Math.sin(self.rx) + z * Math.cos(self.rx); var newX = x * Math.cos(self.ry) + newZ * Math.sin(self.ry); newZ = -x * Math.sin(self.ry) + newZ * Math.cos(self.ry); x = newX * Math.cos(self.rz) - newY * Math.sin(self.rz); y = newX * Math.sin(self.rz) + newY * Math.cos(self.rz); // Apply X-axis rotation newY = y * Math.cos(angleX) - newZ * Math.sin(angleX); newZ = y * Math.sin(angleX) + newZ * Math.cos(angleX); // Apply Y-axis rotation newX = x * Math.cos(angleY) + newZ * Math.sin(angleY); newZ = -x * Math.sin(angleY) + newZ * Math.cos(angleY); // Apply Z-axis rotation x = newX * Math.cos(angleZ) - newY * Math.sin(angleZ); y = newX * Math.sin(angleZ) + newY * Math.cos(angleZ); return { x: (x + self.dx * self.w) * scale, y: (y + self.dy * self.h) * scale, z: (newZ + self.dz * self.d) * scale }; }); self.face.updateCoordinates(self.faceCoordinates); }; // Initialize face in 3D space self.rotate3D(0, 0, 0, 1); }); /***********************************************************************************/ /********************************** GATE CLASS *************************************/ /***********************************************************************************/ var Gate = Container.expand(function () { var self = Container.call(this); // Create gate asset with initial properties self.gateAsset = self.attachAsset('gate', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.26, // Start at same scale as tore2 scaleY: 0.26, alpha: 1, visible: false }); // Store direction angle for this gate self.directionAngle = 0; // Add bounding box for collision detection self.boundingBox = self.attachAsset('boundingBox', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2450, alpha: 1 // Invisible by default }); /* width: 200, heigh: 100, */ // Store the color for this gate self.gateColor = 0xFFFFFF; // Default white, will be set by manager // Store unique ID for this gate self.gateId = null; // Will be set by manager // Set the tint to match the gate color self.setColor = function (color) { self.gateColor = color; self.gateAsset.tint = color; // Show bounding box in debug mode //if (isDebug) { self.boundingBox.alpha = 0.8; self.boundingBox.tint = color; } }; // Update scale to match background animation self.updateScale = function (newScale) { /* self.scaleX = newScale; self.scaleY = newScale; self.alpha = Math.min(1, newScale + 0.66); */ self.gateAsset.scaleX = newScale; self.gateAsset.scaleY = newScale; self.gateAsset.alpha = Math.min(1, newScale + 0.66); // Scale bounding box proportionally self.boundingBox.scaleX = newScale; // 3 * newScale / 0.26; // Maintain 300px width relative to gate scale self.boundingBox.scaleY = newScale; //0.3 * newScale / 0.26; // Maintain 30px height relative to gate scale // Calculate boundingBox position using directionAngle and scale var centerX = 1024; var centerY = 1366; // Calculate distance from center based on scale var distance = (2450 - 1366) * newScale; // Use directionAngle to position boundingBox self.boundingBox.x = centerX + distance * Math.cos(self.directionAngle + Math.PI * 0.5); self.boundingBox.y = centerY + distance * Math.sin(self.directionAngle + Math.PI * 0.5); self.boundingBox.rotation = self.directionAngle; }; return self; }); /***********************************************************************************/ /********************************** GATE MANAGER CLASS *****************************/ /***********************************************************************************/ var GateManager = Container.expand(function () { var self = Container.call(this); // Array to hold gates self.gates = []; // Animation timing self.gateAnimStartTime = Date.now(); self.gateAnimationSpeed = globalSpeed / 1000; // Same as background // Song timing properties self.currentSong = songListV3[0]; self.songStartTime = Date.now(); self.currentNoteIndex = 0; self.noteSpawnScale = 0.12; // Initial scale for new gates matching smallest tore self.lastGateAngle = null; // Track last gate angle for path continuity // Time offset for gate travel (ms) - time for gate to reach player self.gateReachTime = 2500; // Approximately 2.5 seconds // Spawn a single gate at current time self.spawnGateAtTime = function () { // Get the current beat data var beatData = null; if (self.currentNoteIndex < self.currentSong.songBeats.length) { beatData = self.currentSong.songBeats[self.currentNoteIndex]; } // Get beat value and enhanced properties var beatValue = beatData ? beatData.b : 1; var intensity = beatData ? beatData.i : 10; var pitch = beatData ? beatData.p : 2000; var energy = beatData ? beatData.e : 0.3; // Map beat to key for color selection var keyNumber = parseInt(beatValue, 10) || 1; // Default to 1 if parse fails var noteKey = 'Key' + keyNumber; var keyColor = keyColorMap[noteKey] || currentColor; // Default to currentColor if key not found // Create a single gate with the key's color var gate = new Gate(); gate.setColor(keyColor); gate.updateScale(self.noteSpawnScale); // Store spawn time for tracking gate.spawnTime = Date.now(); gate.colorIndex = 0; // Assign unique ID to gate gate.gateId = getNextGateId(); // Store the note key for this gate gate.noteKey = noteKey; // Store enhanced properties gate.intensity = intensity; gate.pitch = pitch; gate.energy = energy; // Add rotation to the gate similar to sphere movement limits // Define three fixed positions: left, center, right var leftAngle = -Math.PI * 0.5 + gateLimitAngle; var centerAngle = -Math.PI * 0.5 + Math.PI / 2; var rightAngle = -Math.PI * 0.5 + Math.PI - gateLimitAngle; // Calculate gate angle based on beat and pitch var baseAngle = centerAngle; if (beatValue === 1) { baseAngle = leftAngle; } else if (beatValue === 2) { baseAngle = centerAngle; } else if (beatValue === 3) { baseAngle = rightAngle; } // Add slight variation based on pitch (higher pitch = slight clockwise rotation) var pitchVariation = (pitch - 2000) / 2000 * 0.1; // ±10% variation var fixedAngle = baseAngle + pitchVariation; // Ensure angle stays within bounds if (fixedAngle < leftAngle) fixedAngle = leftAngle; if (fixedAngle > rightAngle) fixedAngle = rightAngle; // Store this angle for the next gate self.lastGateAngle = fixedAngle; // Set the direction angle for this gate gate.directionAngle = fixedAngle; // Apply rotation to gate asset gate.gateAsset.rotation = fixedAngle; // Apply visual effects based on intensity var intensityScale = 1 + intensity / 30 * 0.3; // Scale up to 30% based on intensity gate.gateAsset.scaleX *= intensityScale; gate.gateAsset.scaleY *= intensityScale; // Apply glow effect based on energy var glowTint = 0xFFFFFF; if (energy > 0.4) { // High energy - brighter tint glowTint = 0xFFFFFF; gate.gateAsset.alpha = Math.min(1, gate.gateAsset.alpha + energy * 0.3); } self.gates.push(gate); self.addChild(gate); }; // Update gates animation self.update = function () { var now = Date.now(); var songElapsed = now - self.songStartTime; // Check if we need to spawn a new gate based on song timing if (self.currentNoteIndex < self.currentSong.songBeats.length) { var nextBeat = self.currentSong.songBeats[self.currentNoteIndex]; // Spawn gate early so it reaches player at the right time if (songElapsed >= nextBeat.t - self.gateReachTime) { // Spawn a new gate for this beat self.spawnGateAtTime(); self.currentNoteIndex++; } } // Animate existing gates for (var i = self.gates.length - 1; i >= 0; i--) { var gate = self.gates[i]; var currentScale = gate.gateAsset.scaleX; // Increase scale with acceleration var newScale = currentScale + self.gateAnimationSpeed * currentScale; // Remove gate when too large if (newScale > 3.0) { gate.destroy(); self.gates.splice(i, 1); } else { gate.updateScale(newScale); } } // Check if song has ended and needs restart self.checkSongEnd(); }; // Reset song when it ends self.resetSong = function () { self.songStartTime = Date.now(); self.currentNoteIndex = 0; self.lastGateAngle = null; // Reset angle tracking for new song }; // Check if song has ended and restart self.checkSongEnd = function () { if (self.currentNoteIndex >= self.currentSong.songBeats.length) { // All beats have been spawned, check if we should restart var lastBeatTime = self.currentSong.songBeats[self.currentSong.songBeats.length - 1].t; var songElapsed = Date.now() - self.songStartTime; // Wait a bit after the last beat before restarting if (songElapsed > lastBeatTime + 5000) { self.resetSong(); } } }; // Destroy a specific gate self.destroyGate = function (gate) { var index = self.gates.indexOf(gate); if (index > -1) { self.gates.splice(index, 1); gate.destroy(); } }; return self; }); /***********************************************************************************/ /********************************** PARTICLE CLASS *********************************/ /***********************************************************************************/ var Particle = Container.expand(function () { var self = Container.call(this); // Create particle asset var particleGraphics = self.attachAsset('trail', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, alpha: 1 }); // Initialize particle properties self.velocityX = 0; self.velocityY = 0; self.lifetime = 0; self.maxLifetime = 1000; // 1 second self.startTime = Date.now(); // Update particle self.update = function () { var elapsed = Date.now() - self.startTime; if (elapsed > self.maxLifetime) { return false; // Signal to remove particle } // Update position self.x += self.velocityX; self.y += self.velocityY; // Fade out over lifetime var progress = elapsed / self.maxLifetime; self.alpha = 1 - progress; // Scale down var scale = (1 - progress * 0.5) * 0.5; self.scaleX = scale; self.scaleY = scale; return true; // Still alive }; return self; }); /***********************************************************************************/ /********************************** RUNNER CLASS ***********************************/ /***********************************************************************************/ var Runner = Container.expand(function () { var self = Container.call(this); // Create and attach runner asset var runnerGraphics = self.attachAsset('runnerDir4_001', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF, //currentColor, alpha: 1 }); // Initialize runner properties self.speedX = 0; self.speedY = 0; // Track last intersecting state for each gate self.lastIntersectingGates = {}; // Update method to follow sphere's position self.update = function () { // Make runner follow sphere's exact position if (sphere) { self.x = sphere.x; self.y = sphere.y; // Calculate angle based on runner's position relative to center var centerX = 1024; var centerY = 1366; var angle = Math.atan2(self.y - centerY, self.x - centerX); // Apply rotation to runner self.rotation = angle - Math.PI * 0.5; // Add PI/2 to orient correctly } //if (LK.Ticks % 2) { self.scaleX *= -1; } /* // Check for collisions with gates if (gateManager && gateManager.gates) { for (var i = 0; i < gateManager.gates.length; i++) { var gate = gateManager.gates[i]; var gateId = gate.gateId; // Initialize tracking if needed if (self.lastIntersectingGates[gateId] === undefined) { self.lastIntersectingGates[gateId] = false; } // Check intersection with bounding box instead of gate asset var currentIntersecting = self.intersects(gate.boundingBox); // Detect transition from not intersecting to intersecting if (!self.lastIntersectingGates[gateId] && currentIntersecting) { // Play the sound based on the gate's assigned key if (gate.noteKey) { // Extract the number from the key (e.g., "Key6" -> "6") var keyNumber = gate.noteKey.replace('Key', ''); var soundKey = 'key' + keyNumber; // Play the corresponding sound LK.getSound(soundKey).play(); } } // Update last intersecting state self.lastIntersectingGates[gateId] = currentIntersecting; } // Clean up old gate tracking var currentGateIds = {}; for (var j = 0; j < gateManager.gates.length; j++) { var gate2 = gateManager.gates[j]; var gateId2 = gate2.gateId; currentGateIds[gateId2] = true; } for (var oldGateId in self.lastIntersectingGates) { if (!currentGateIds[oldGateId]) { delete self.lastIntersectingGates[oldGateId]; } } } // Check for collisions with targets if (targetManager && targetManager.targets) { for (var i = 0; i < targetManager.targets.length; i++) { var target = targetManager.targets[i]; var targetId = target.spawnTime + '_' + target.colorIndex; // Initialize tracking if needed if (self.lastIntersectingTargets === undefined) { self.lastIntersectingTargets = {}; } if (self.lastIntersectingTargets[targetId] === undefined) { self.lastIntersectingTargets[targetId] = false; } // Check intersection with target var currentIntersecting = self.intersects(target); // Detect transition from not intersecting to intersecting if (!self.lastIntersectingTargets[targetId] && currentIntersecting) { // Play the sound based on the target's assigned key if (target.noteKey) { // Extract the number from the key (e.g., "Key6" -> "6") var keyNumber = target.noteKey.replace('Key', ''); var soundKey = 'key' + keyNumber; // Play the corresponding sound LK.getSound(soundKey).play(); // Add score when hitting target LK.setScore(LK.getScore() + 10); } } // Update last intersecting state self.lastIntersectingTargets[targetId] = currentIntersecting; } // Clean up old target tracking var currentTargetIds = {}; for (var j = 0; j < targetManager.targets.length; j++) { var target2 = targetManager.targets[j]; var targetId2 = target2.spawnTime + '_' + target2.colorIndex; currentTargetIds[targetId2] = true; } for (var oldTargetId in self.lastIntersectingTargets) { if (!currentTargetIds[oldTargetId]) { delete self.lastIntersectingTargets[oldTargetId]; } } } */ }; return self; }); /***********************************************************************************/ /********************************** SHAPE CLASS ************************************/ /***********************************************************************************/ var Shape = Container.expand(function (coordinates, tint) { var self = Container.call(this); self.polygon = drawPolygon(coordinates, tint); // Function to create a polygon from a list of coordinates self.tint = tint; self.attachLines = function () { // Iterate through each line in the polygon and attach it to the shape self.polygon.forEach(function (line) { self.addChild(line); }); }; self.attachLines(); self.updateCoordinates = function (newCoordinates) { log("Shape updateCoordinates ", newCoordinates); // Ensure newCoordinates is an array and has the same length as the current polygon if (!Array.isArray(newCoordinates) || newCoordinates.length !== self.polygon.length) { error("Invalid newCoordinates length"); return; } // Update each line in the polygon with new coordinates self.polygon = updatePolygon(self.polygon, newCoordinates); }; }); /***********************************************************************************/ /******************************* SIMPLE FACE CLASS *********************************/ /***********************************************************************************/ var SimpleFace = Container.expand(function (options) { var self = Container.call(this); log("SimpleFAce init options =", options); self.baseSize = 100; options = options || {}; self.w = options.w || self.baseSize; self.h = options.h || self.baseSize; self.d = options.d || self.baseSize; self.dx = options.dx || 0; self.dy = options.dy || 0; self.dz = options.dz || 0; self.rx = options.rx || 0; self.ry = options.ry || 0; self.rz = options.rz || 0; self.tint = options.ti || 0xFFFFFF; // Define faceCoordinates property self.baseFaceCoordinates = [{ x: -self.w + self.dx * self.w, y: -self.h + self.dy * self.h, z: self.dz * self.d }, // Top-left { x: self.w + self.dx * self.w, y: -self.h + self.dy * self.h, z: self.dz * self.d }, // Top-right { x: self.w + self.dx * self.w, y: self.h + self.dy * self.h, z: self.dz * self.d }, // Bottom-right { x: -self.w + self.dx * self.w, y: self.h + self.dy * self.h, z: self.dz * self.d } // Bottom-left ]; log("SimpleFAce ready to init ...", self.baseFaceCoordinates, "DX=" + self.dx); self.baseFaceCoordinates.forEach(function (point) { // Update z of each face point coordinates depending on dz and rx, ry point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry); }); // Create a square face using the Shape class self.face = new Shape(self.baseFaceCoordinates, self.tint); // Attach the face to the SimpleFace container self.addChild(self.face); // Rotate in 3d : X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune self.rotate3D = function (angleX, angleY, angleZ, scale) { scale = scale || 1; log("SimpleFace rotate3D old coord=", self.faceCoordinates, Date.now()); self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) { return { x: coord.x, y: coord.y, z: coord.z }; }); // Apply rotation around X-axis // Adjust initial rotation parameters before applying new rotations self.faceCoordinates = self.faceCoordinates.map(function (coord) { // Apply initial rotation around Z-axis var xZ = coord.x * Math.cos(self.rz) - coord.y * Math.sin(self.rz); var yZ = coord.x * Math.sin(self.rz) + coord.y * Math.cos(self.rz); // Apply initial rotation around Y-axis var xY = xZ * Math.cos(self.ry) + coord.z * Math.sin(self.ry); var zY = coord.z * Math.cos(self.ry) - xZ * Math.sin(self.ry); // Apply initial rotation around X-axis var yX = yZ * Math.cos(self.rx) - zY * Math.sin(self.rx); var zX = yZ * Math.sin(self.rx) + zY * Math.cos(self.rx); return { x: xY, y: yX, z: zX }; }); // Apply new rotations // Calculate center of the face var centerX = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.x; }, 0) / self.faceCoordinates.length; var centerY = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.y; }, 0) / self.faceCoordinates.length; var centerZ = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.z; }, 0) / self.faceCoordinates.length; self.faceCoordinates = self.faceCoordinates.map(function (coord) { // Translate coordinates to rotate around the center including dy and dz adjustment var translatedY = (coord.y + self.dy * self.h - centerY) * Math.cos(angleX) - (coord.z + self.dz * self.d - centerZ) * Math.sin(angleX); var translatedZ = (coord.y + self.dy * self.h - centerY) * Math.sin(angleX) + (coord.z + self.dz * self.d - centerZ) * Math.cos(angleX); return { x: coord.x + self.dx * self.w - centerX, // Keep X unchanged but translate to rotate around center y: translatedY + centerY, z: translatedZ + centerZ }; }); self.faceCoordinates = self.faceCoordinates.map(function (coord) { var translatedX = (coord.z - centerZ) * Math.sin(angleY) + (coord.x - centerX) * Math.cos(angleY); var translatedZ = (coord.z - centerZ) * Math.cos(angleY) - (coord.x - centerX) * Math.sin(angleY); return { x: translatedX + centerX, y: coord.y, // Keep Y unchanged z: translatedZ + centerZ }; }); self.faceCoordinates = self.faceCoordinates.map(function (coord) { return { x: coord.x * scale, y: coord.y * scale, z: coord.z * scale }; }); log("SimpleFace rotate3D new coord=", self.faceCoordinates, Date.now()); self.face.updateCoordinates(self.faceCoordinates); }; // initialize face in 3D space self.rotate3D(0, 0, 0, 1); log("SimpleFace end init coord=", self.baseFaceCoordinates, Date.now()); }); /***********************************************************************************/ /********************************** SPHERE CLASS ***********************************/ /***********************************************************************************/ var Sphere = Container.expand(function () { var self = Container.call(this); self.z = 0; self.radius = 100; // Sphere radius // Initialize sphere as a collection of Face instances to simulate a 3D sphere self.faces = []; var segments = 5; // Number of segments to simulate the sphere for (var i = 0; i < segments; i++) { var angle = 2 * Math.PI / segments; // Create a circular segment as a face of the sphere var face = new Face({ points: 22, w: self.radius * 2, h: self.radius * 2, d: self.radius * 2, dx: 0, dy: 0, dz: 0, rx: 0, ry: i * angle, rz: 0, ti: currentColor // Use currentColor for sphere tint }); self.faces.push(face); self.addChild(face); } self.speedX = 0; self.speedY = 0; self.speedZ = 0; // Rotate sphere around its axes self.rotate3D = function (angleX, angleY, angleZ) { log("sphere rotate3D ", angleX, angleY, angleZ); self.rotation = angleZ; var zScaleFactor = 1 + self.z / 500; for (var i = 0; i < self.faces.length; i++) { self.faces[i].rotate3D(angleX, angleY, angleZ, zScaleFactor); } }; self.rotate3D(Math.PI * 0.5, Math.PI * 0.5, 0); }); /***********************************************************************************/ /********************************** TARGET CLASS ***********************************/ /***********************************************************************************/ var Target = Container.expand(function () { var self = Container.call(this); // Create target using ball asset self.targetAsset = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, alpha: 1 }); // Store the color for this target self.targetColor = 0xFFFFFF; // Default white, will be set by manager // Set the tint to match the target color self.setColor = function (color) { self.targetColor = color; self.targetAsset.tint = color; }; // Update scale to match animation self.updateScale = function (newScale) { self.targetAsset.scaleX = newScale; self.targetAsset.scaleY = newScale; self.targetAsset.alpha = Math.min(1, newScale * 2); }; return self; }); /***********************************************************************************/ /********************************** TARGET MANAGER CLASS ***************************/ /***********************************************************************************/ var TargetManager = Container.expand(function () { var self = Container.call(this); // Array to hold targets self.targets = []; // Animation timing self.targetAnimStartTime = Date.now(); self.targetAnimationSpeed = globalSpeed / 2000; // Slower than gates // Song timing properties self.currentSong = songsList[0]; self.songStartTime = Date.now(); self.currentNoteIndex = 0; self.noteSpawnScale = 0.2; // Initial scale for new targets self.lastTargetAngle = null; // Track last target angle for path continuity // Spawn a single target at current time self.spawnTargetAtTime = function () { // Get the current note's key var noteKey = null; if (self.currentNoteIndex < self.currentSong.songNotes.length) { noteKey = self.currentSong.songNotes[self.currentNoteIndex].key; } // Get the color for this key var keyColor = keyColorMap[noteKey] || currentColor; // Default to currentColor if key not found // Create a single target with the key's color var target = new Target(); target.setColor(keyColor); target.updateScale(self.noteSpawnScale); // Store spawn time for tracking target.spawnTime = Date.now(); target.colorIndex = 0; // Store the note key for this target target.noteKey = noteKey; // Add rotation to the target similar to gates var minAngle = Math.PI * 0.5; // + gateLimitAngle; var maxAngle = Math.PI * 0.5; // + Math.PI - gateLimitAngle; var randomAngle; // If this is the first target or no previous target exists, use random angle if (self.targets.length === 0 || !self.lastTargetAngle) { randomAngle = minAngle + Math.random() * (maxAngle - minAngle); } else { // For consecutive targets, generate angle close to the previous one var maxAngleChange = Math.PI * 0.15; // Maximum 15% of PI change between consecutive targets var angleChange = (Math.random() - 0.5) * 2 * maxAngleChange; // Random change between -maxAngleChange and +maxAngleChange randomAngle = self.lastTargetAngle + angleChange; // Clamp the angle to stay within bounds randomAngle = Math.max(minAngle, Math.min(maxAngle, randomAngle)); } // Store this angle for the next target self.lastTargetAngle = randomAngle; // Store the target angle for movement target.targetAngle = randomAngle; // Start targets at center of screen var centerX = 1024; var centerY = 1366; target.x = centerX; target.y = centerY; // Store progress for animation (0 = center, 1 = edge) target.progress = 0; self.targets.push(target); self.addChild(target); }; // Update targets animation self.update = function () { var now = Date.now(); var songElapsed = now - self.songStartTime; // Check if we need to spawn a new target based on song timing if (self.currentNoteIndex < self.currentSong.songNotes.length) { var nextNote = self.currentSong.songNotes[self.currentNoteIndex]; if (songElapsed >= nextNote.time) { // Spawn a new target for this note self.spawnTargetAtTime(); self.currentNoteIndex++; } } // Animate existing targets for (var i = self.targets.length - 1; i >= 0; i--) { var target = self.targets[i]; var currentScale = target.targetAsset.scaleX; // Increase scale with acceleration var newScale = currentScale + self.targetAnimationSpeed * currentScale; // Update target progress (movement from center to edge) target.progress += globalSpeed / 300; // Progress speed based on globalSpeed // Calculate position on ellipse path based on progress var centerX = 1024; var centerY = 1366; var radiusX = 924; var radiusY = 634; // Interpolate position from center to edge along the target angle target.x = centerX + radiusX * Math.cos(target.targetAngle) * target.progress; target.y = centerY + radiusY * Math.sin(target.targetAngle) * target.progress; // Remove target when it reaches the edge or becomes too large if (newScale > 1.5 || target.progress > 1.0) { target.destroy(); self.targets.splice(i, 1); } else { target.updateScale(newScale); } } // Check if song has ended and needs restart self.checkSongEnd(); }; // Reset song when it ends self.resetSong = function () { self.songStartTime = Date.now(); self.currentNoteIndex = 0; self.lastTargetAngle = null; // Reset angle tracking for new song }; // Check if song has ended and restart self.checkSongEnd = function () { if (self.currentNoteIndex >= self.currentSong.songNotes.length) { // All notes have been spawned, check if we should restart var lastNoteTime = self.currentSong.songNotes[self.currentSong.songNotes.length - 1].time; var songElapsed = Date.now() - self.songStartTime; // Wait a bit after the last note before restarting if (songElapsed > lastNoteTime + 5000) { self.resetSong(); } } }; return self; }); /**** * Initialize Game ****/ // Utility function to draw a polygon using drawLine var game = new LK.Game({ backgroundColor: 0xDDDDDD // Initialize game with a black background }); /**** * Game Code ****/ // Global array of 6 neon colors var neonColors = [0x39FF14, // Neon Green 0xFF073A, // Neon Red 0x00FFFF, // Neon Cyan 0xF3F315, // Neon Yellow 0xFF61F6, // Neon Pink 0xFF9900 // Neon Orange ]; // Map keys to colors - 15 keys (0-14) mapped to neon colors var keyColorMap = { 'Key0': 0x39FF14, // Neon Green 'Key1': 0xFF073A, // Neon Red 'Key2': 0x00FFFF, // Neon Cyan 'Key3': 0xF3F315, // Neon Yellow 'Key4': 0xFF61F6, // Neon Pink 'Key5': 0xFF9900, // Neon Orange 'Key6': 0x39FF14, // Neon Green (repeat) 'Key7': 0xFF073A, // Neon Red (repeat) 'Key8': 0x00FFFF, // Neon Cyan (repeat) 'Key9': 0xF3F315, // Neon Yellow (repeat) 'Key10': 0xFF61F6, // Neon Pink (repeat) 'Key11': 0xFF9900, // Neon Orange (repeat) 'Key12': 0x39FF14, // Neon Green (repeat) 'Key13': 0xFF073A, // Neon Red (repeat) 'Key14': 0x00FFFF // Neon Cyan (repeat) }; // Global currentColor, set to a random neon color var currentColor = neonColors[Math.floor(Math.random() * neonColors.length)]; /***********************************************************************************/ /******************************* UTILITY FUNCTIONS *********************************/ /***********************************************************************************/ function drawPolygon(coordinates, tint) { log("drawPolygon ", coordinates); var lines = []; for (var i = 0; i < coordinates.length; i++) { var startPoint = coordinates[i]; var endPoint = coordinates[(i + 1) % coordinates.length]; // Loop back to the first point var line = drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, tint); lines.push(line); } return lines; } function updatePolygon(lines, newCoordinates, scale) { log("updatePolygon ", lines, scale); // Ensure lines and newCoordinates have the same length if (lines.length !== newCoordinates.length) { error("updatePolygon error: lines and newCoordinates length mismatch"); return lines; } // Update each line with new coordinates for (var i = 0; i < lines.length; i++) { var startPoint = newCoordinates[i]; var endPoint = newCoordinates[(i + 1) % newCoordinates.length]; // Loop back to the first point for the last line updateLine(lines[i], startPoint.x, startPoint.y, endPoint.x, endPoint.y, scale); } return lines; } // Utility function to draw lines between two points function drawLine(x1, y1, x2, y2, tint) { log("drawLine ", x1, y1); var line = LK.getAsset('line', { anchorX: 0.0, anchorY: 0.0, x: x1, y: y1, tint: tint }); line.startX = x1; line.startY = y1; line.endX = x2; line.endY = y2; // Calculate the distance between the two points var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); // Set the width of the line to the distance between the points line.width = distance; // Calculate the angle between the two points var angle = Math.atan2(y2 - y1, x2 - x1); // Correct angle calculation for all quadrants line.rotation = angle; return line; } // Utility function to draw lines between two points function updateLine(line, newX1, newY1, newX2, newY2, scale) { log("updateLine ", line); scale = scale === undefined ? 1 : scale; // Calculate midpoint of the original line var midX = (newX1 + newX2) / 2; var midY = (newY1 + newY2) / 2; // Adjust start and end points based on scale newX1 = midX + (newX1 - midX) * scale; newY1 = midY + (newY1 - midY) * scale; newX2 = midX + (newX2 - midX) * scale; newY2 = midY + (newY2 - midY) * scale; // Update line start and end coordinates after scaling line.x = newX1; line.y = newY1; line.startX = newX1; line.startY = newY1; line.endX = newX2; line.endY = newY2; // Recalculate the distance between the new scaled points var distance = Math.sqrt(Math.pow(newX2 - newX1, 2) + Math.pow(newY2 - newY1, 2)); // Update the width of the line to the new distance line.width = distance; // Recalculate the angle between the new points var angle = Math.atan2(newY2 - newY1, newX2 - newX1); // Update the rotation of the line to the new angle line.rotation = angle; return line; } function log() { if (isDebug) { console.log(arguments); } } /***********************************************************************************/ /******************************* GAME VARIABLES*********************************/ /***********************************************************************************/ var songListV3 = [{ "title": "Imagine Dragons - Believer", "tempo": 123.046875, "duration": 226455.51020408163, "songBeats": [{ "t": 371, "b": 3, "i": 30.446378707885742, "p": 1880.3399790360063, "e": 0.43265214562416077, "d": 3 }, { "t": 859, "b": 3, "i": 3.6817479133605957, "p": 1740.3153891562984, "e": 0.3890908360481262, "d": 3 }, { "t": 1346, "b": 3, "i": 10.41525650024414, "p": 3102.039514232557, "e": 0.35598310828208923, "d": 3 }, { "t": 1834, "b": 3, "i": 10.242786407470703, "p": 1721.9514452648327, "e": 0.2169458270072937, "d": 3 }, { "t": 2298, "b": 3, "i": 3.9228432178497314, "p": 1684.7332415430665, "e": 0.4700264632701874, "d": 3 }, { "t": 2786, "b": 3, "i": 12.474764823913574, "p": 3212.6234077307636, "e": 0.06588377803564072, "d": 3 }, { "t": 3250, "b": 3, "i": 35.255943298339844, "p": 3603.3793917467315, "e": 0.27588167786598206, "d": 3 }, { "t": 3738, "b": 3, "i": 14.388938903808594, "p": 1777.5737919920282, "e": 0.19996532797813416, "d": 3 }, { "t": 4226, "b": 3, "i": 4.208749294281006, "p": 1509.0427276345422, "e": 0.47762441635131836, "d": 3 }, { "t": 4690, "b": 3, "i": 11.685361862182617, "p": 3190.1366806963006, "e": 0.06262288987636566, "d": 3 }, { "t": 5178, "b": 3, "i": 26.254247665405273, "p": 3424.506205060151, "e": 0.2841387093067169, "d": 3 }, { "t": 5665, "b": 3, "i": 11.800064086914062, "p": 1710.107429797511, "e": 0.2125183641910553, "d": 3 }, { "t": 6130, "b": 3, "i": 3.9539339542388916, "p": 1785.203667308902, "e": 0.4553563594818115, "d": 3 }, { "t": 6617, "b": 3, "i": 14.194070816040039, "p": 3212.461584859472, "e": 0.06456244736909866, "d": 3 }, { "t": 7082, "b": 3, "i": 32.14863586425781, "p": 3671.28640669982, "e": 0.2709011137485504, "d": 3 }, { "t": 7569, "b": 3, "i": 10.732184410095215, "p": 3236.648977147464, "e": 0.06220065429806709, "d": 3 }, { "t": 8010, "b": 3, "i": 23.347705841064453, "p": 1709.2272473648377, "e": 0.48125159740448, "d": 3 }, { "t": 8498, "b": 3, "i": 4.8173089027404785, "p": 1447.3625839206222, "e": 0.39073091745376587, "d": 3 }, { "t": 8986, "b": 3, "i": 7.058783531188965, "p": 2981.394273370924, "e": 0.3262585401535034, "d": 3 }, { "t": 9450, "b": 3, "i": 14.195202827453613, "p": 1740.5445369466502, "e": 0.20303501188755035, "d": 3 }, { "t": 9938, "b": 3, "i": 3.606639862060547, "p": 1441.3272412595936, "e": 0.48084256052970886, "d": 3 }, { "t": 10402, "b": 3, "i": 13.980183601379395, "p": 3183.8939987263075, "e": 0.06403025984764099, "d": 3 }, { "t": 10890, "b": 3, "i": 19.99871063232422, "p": 3381.977565087459, "e": 0.29312068223953247, "d": 3 }, { "t": 11377, "b": 3, "i": 9.857975006103516, "p": 1723.9076939420502, "e": 0.2172132432460785, "d": 3 }, { "t": 11842, "b": 3, "i": 4.251250267028809, "p": 1698.5589680455616, "e": 0.46955403685569763, "d": 3 }, { "t": 12329, "b": 3, "i": 11.91080093383789, "p": 3231.0480255167213, "e": 0.06551484763622284, "d": 3 }, { "t": 12794, "b": 3, "i": 35.79670333862305, "p": 3569.7288996249767, "e": 0.27101612091064453, "d": 3 }, { "t": 13281, "b": 3, "i": 14.564117431640625, "p": 1756.6969607605215, "e": 0.20073777437210083, "d": 3 }, { "t": 13769, "b": 3, "i": 4.11232852935791, "p": 1488.9941366748776, "e": 0.4761289060115814, "d": 3 }, { "t": 14233, "b": 3, "i": 12.285995483398438, "p": 3181.753256505366, "e": 0.06322480738162994, "d": 3 }, { "t": 14721, "b": 3, "i": 24.54972267150879, "p": 3425.5636598523415, "e": 0.2869971692562103, "d": 3 }, { "t": 15209, "b": 3, "i": 9.000603675842285, "p": 3303.502958267726, "e": 0.06430622935295105, "d": 3 }, { "t": 15650, "b": 3, "i": 23.4543514251709, "p": 1701.78216257234, "e": 0.48139435052871704, "d": 3 }, { "t": 16137, "b": 3, "i": 4.822584629058838, "p": 1449.2189168379577, "e": 0.3905656635761261, "d": 3 }, { "t": 16625, "b": 3, "i": 7.087540149688721, "p": 2972.24437370763, "e": 0.3264678120613098, "d": 3 }, { "t": 17089, "b": 3, "i": 14.195220947265625, "p": 1737.9576780395423, "e": 0.20293721556663513, "d": 3 }, { "t": 17577, "b": 3, "i": 3.614260673522949, "p": 1433.4195795757696, "e": 0.48118939995765686, "d": 3 }, { "t": 18041, "b": 3, "i": 13.948040962219238, "p": 3183.2698641598054, "e": 0.06418093293905258, "d": 3 }, { "t": 18529, "b": 3, "i": 20.11182975769043, "p": 3396.3034606702186, "e": 0.29333674907684326, "d": 3 }, { "t": 19017, "b": 3, "i": 9.892679214477539, "p": 1725.5826572625656, "e": 0.21711952984333038, "d": 3 }, { "t": 19481, "b": 3, "i": 4.228785037994385, "p": 1697.6311237264217, "e": 0.469436913728714, "d": 3 }, { "t": 19969, "b": 3, "i": 11.972678184509277, "p": 3231.6465049800936, "e": 0.06534923613071442, "d": 3 }, { "t": 20433, "b": 3, "i": 35.73525619506836, "p": 3582.35899622207, "e": 0.27113789319992065, "d": 3 }, { "t": 20921, "b": 3, "i": 14.537458419799805, "p": 1752.2240167854918, "e": 0.20077036321163177, "d": 3 }, { "t": 21408, "b": 3, "i": 4.116189002990723, "p": 1490.7644911214084, "e": 0.47697940468788147, "d": 3 }, { "t": 21873, "b": 3, "i": 12.22387409210205, "p": 3182.156933636188, "e": 0.06303219497203827, "d": 3 }, { "t": 22360, "b": 3, "i": 24.646350860595703, "p": 3434.916851008389, "e": 0.287105917930603, "d": 3 }, { "t": 22848, "b": 3, "i": 9.055337905883789, "p": 3307.069173740442, "e": 0.06429217010736465, "d": 3 }, { "t": 23266, "b": 3, "i": 34.97377395629883, "p": 1806.4532386510698, "e": 0.4514867067337036, "d": 3 }, { "t": 23754, "b": 3, "i": 4.661027431488037, "p": 1582.36279386049, "e": 0.39301303029060364, "d": 3 }, { "t": 24241, "b": 3, "i": 9.604907989501953, "p": 3034.4245434340974, "e": 0.343711793422699, "d": 3 }, { "t": 24706, "b": 3, "i": 11.533316612243652, "p": 1851.4837511648561, "e": 0.19654043018817902, "d": 3 }, { "t": 25193, "b": 3, "i": 4.1555938720703125, "p": 1572.2441623890104, "e": 0.4725814759731293, "d": 3 }, { "t": 25681, "b": 3, "i": 9.470974922180176, "p": 3219.348107385239, "e": 0.06626113504171371, "d": 3 }, { "t": 26145, "b": 3, "i": 37.85918045043945, "p": 3518.449848353399, "e": 0.28530699014663696, "d": 3 }, { "t": 26633, "b": 3, "i": 13.970437049865723, "p": 1733.6482126449673, "e": 0.20278066396713257, "d": 3 }, { "t": 27120, "b": 3, "i": 3.618770122528076, "p": 1438.2539901885914, "e": 0.47907716035842896, "d": 3 }, { "t": 27585, "b": 3, "i": 14.423442840576172, "p": 3197.142115280717, "e": 0.0635685995221138, "d": 3 }, { "t": 28049, "b": 3, "i": 25.65450096130371, "p": 3745.2865064281277, "e": 0.26460182666778564, "d": 3 }, { "t": 28537, "b": 3, "i": 9.55935001373291, "p": 1890.6229787886534, "e": 0.19327382743358612, "d": 3 }, { "t": 29024, "b": 3, "i": 4.381631374359131, "p": 1664.0541871370465, "e": 0.4685891568660736, "d": 3 }, { "t": 29512, "b": 3, "i": 11.24487590789795, "p": 3226.3559298355262, "e": 0.0654386505484581, "d": 3 }, { "t": 29976, "b": 3, "i": 36.88570785522461, "p": 3571.244879981357, "e": 0.2746467590332031, "d": 3 }, { "t": 30464, "b": 3, "i": 12.034771919250488, "p": 3265.7821435418236, "e": 0.06283161789178848, "d": 3 }, { "t": 30905, "b": 3, "i": 13.785469055175781, "p": 1999.4096393819664, "e": 0.4504010081291199, "d": 3 }, { "t": 31393, "b": 3, "i": 8.00468635559082, "p": 2594.4911146968752, "e": 0.33590424060821533, "d": 3 }, { "t": 31880, "b": 3, "i": 10.66857624053955, "p": 2948.830552926041, "e": 0.3497903048992157, "d": 3 }, { "t": 32345, "b": 3, "i": 10.862059593200684, "p": 2349.253625971622, "e": 0.2966122627258301, "d": 3 }, { "t": 32833, "b": 3, "i": 3.2366716861724854, "p": 2683.5798161508746, "e": 0.47248169779777527, "d": 3 }, { "t": 33320, "b": 3, "i": 8.047016143798828, "p": 2303.4214550863503, "e": 0.3699396550655365, "d": 3 }, { "t": 33785, "b": 3, "i": 9.104279518127441, "p": 3271.632705744787, "e": 0.33338290452957153, "d": 3 }, { "t": 34272, "b": 3, "i": 6.047511100769043, "p": 1944.6382591715358, "e": 0.30360743403434753, "d": 3 }, { "t": 34737, "b": 3, "i": 2.527599573135376, "p": 2053.5335265654917, "e": 0.4502394497394562, "d": 3 }, { "t": 35224, "b": 3, "i": 10.387797355651855, "p": 2242.536244626361, "e": 0.30193257331848145, "d": 3 }, { "t": 35712, "b": 3, "i": 8.243304252624512, "p": 2990.0776270630195, "e": 0.32883089780807495, "d": 3 }, { "t": 36199, "b": 3, "i": 4.493236064910889, "p": 1985.7163343955153, "e": 0.30671408772468567, "d": 3 }, { "t": 36664, "b": 3, "i": 4.534397602081299, "p": 1981.0892175100205, "e": 0.4518032371997833, "d": 3 }, { "t": 37151, "b": 3, "i": 2.9641361236572266, "p": 2054.5237965023407, "e": 0.2908525764942169, "d": 3 }, { "t": 37616, "b": 3, "i": 8.53003215789795, "p": 3240.860467196379, "e": 0.3607817590236664, "d": 3 }, { "t": 38103, "b": 3, "i": 4.905579566955566, "p": 2608.052615671376, "e": 0.2479238212108612, "d": 3 }, { "t": 38568, "b": 3, "i": 7.69426155090332, "p": 1992.380157113881, "e": 0.46075525879859924, "d": 3 }, { "t": 39079, "b": 3, "i": 3.078007459640503, "p": 1604.5747781626987, "e": 0.39549165964126587, "d": 3 }, { "t": 39543, "b": 3, "i": 10.555704116821289, "p": 2839.721718382691, "e": 0.379081666469574, "d": 3 }, { "t": 40031, "b": 3, "i": 6.055713653564453, "p": 1855.2649380833473, "e": 0.3446334898471832, "d": 3 }, { "t": 40495, "b": 3, "i": 4.431577682495117, "p": 1647.8443702811296, "e": 0.46302515268325806, "d": 3 }, { "t": 40983, "b": 3, "i": 6.834867477416992, "p": 3687.665825609274, "e": 0.24346399307250977, "d": 3 }, { "t": 41447, "b": 3, "i": 8.649918556213379, "p": 3302.510700550288, "e": 0.35849854350090027, "d": 3 }, { "t": 41935, "b": 3, "i": 7.3616228103637695, "p": 2269.9664408119825, "e": 0.2924383878707886, "d": 3 }, { "t": 42422, "b": 3, "i": 5.017187595367432, "p": 1572.4567023911816, "e": 0.48216620087623596, "d": 3 }, { "t": 42910, "b": 3, "i": 3.9820034503936768, "p": 2161.347239333498, "e": 0.2869057059288025, "d": 3 }, { "t": 43374, "b": 3, "i": 14.653194427490234, "p": 3176.265334859797, "e": 0.3155273497104645, "d": 3 }, { "t": 43862, "b": 3, "i": 7.4942193031311035, "p": 1703.7411533273905, "e": 0.3457912802696228, "d": 3 }, { "t": 44326, "b": 3, "i": 4.457066059112549, "p": 1650.0524473595021, "e": 0.4494290351867676, "d": 3 }, { "t": 44814, "b": 3, "i": 7.921112537384033, "p": 1971.3205617938158, "e": 0.2188158482313156, "d": 3 }, { "t": 45278, "b": 3, "i": 14.562458038330078, "p": 3601.074213644405, "e": 0.29894185066223145, "d": 3 }, { "t": 45766, "b": 3, "i": 7.872082710266113, "p": 2309.628634441997, "e": 0.14065134525299072, "d": 3 }, { "t": 46230, "b": 3, "i": 4.801090240478516, "p": 1839.5520118078543, "e": 0.4581151008605957, "d": 3 }, { "t": 46718, "b": 3, "i": 11.569972038269043, "p": 2261.4956790072356, "e": 0.3885508179664612, "d": 3 }, { "t": 47206, "b": 3, "i": 8.614166259765625, "p": 2897.6383810750526, "e": 0.3871225416660309, "d": 3 }, { "t": 47693, "b": 3, "i": 8.050575256347656, "p": 1753.3638971794232, "e": 0.3376626968383789, "d": 3 }, { "t": 48181, "b": 3, "i": 3.369157075881958, "p": 1757.943965692161, "e": 0.4728565216064453, "d": 3 }, { "t": 48645, "b": 3, "i": 6.176213264465332, "p": 1968.8941454719093, "e": 0.3789074122905731, "d": 3 }, { "t": 49133, "b": 3, "i": 9.195919036865234, "p": 3183.085741056015, "e": 0.332353413105011, "d": 3 }, { "t": 49621, "b": 3, "i": 4.214333534240723, "p": 1921.2261076048103, "e": 0.3006269931793213, "d": 3 }, { "t": 50085, "b": 3, "i": 4.664543151855469, "p": 1812.9690919325953, "e": 0.458882212638855, "d": 3 }, { "t": 50526, "b": 3, "i": 7.252250671386719, "p": 2302.0656728085314, "e": 0.3238920569419861, "d": 3 }, { "t": 51037, "b": 3, "i": 8.580676078796387, "p": 3273.839281504819, "e": 0.3368639349937439, "d": 3 }, { "t": 51501, "b": 3, "i": 4.069787502288818, "p": 2282.833854533076, "e": 0.3466281592845917, "d": 3 }, { "t": 51989, "b": 3, "i": 2.5763869285583496, "p": 2089.8880418129393, "e": 0.43311387300491333, "d": 3 }, { "t": 52477, "b": 3, "i": 3.8404831886291504, "p": 2581.1671770704584, "e": 0.2997276782989502, "d": 3 }, { "t": 52964, "b": 3, "i": 10.01322078704834, "p": 3169.633473686239, "e": 0.3287355601787567, "d": 3 }, { "t": 53452, "b": 3, "i": 4.925120830535889, "p": 2048.3383884349205, "e": 0.31630387902259827, "d": 3 }, { "t": 53916, "b": 3, "i": 5.597084999084473, "p": 3061.6813025143824, "e": 0.4517521262168884, "d": 3 }, { "t": 54404, "b": 3, "i": 4.655360221862793, "p": 1711.4524689282225, "e": 0.41625601053237915, "d": 3 }, { "t": 54868, "b": 3, "i": 14.155052185058594, "p": 3125.5346494816813, "e": 0.3876945376396179, "d": 3 }, { "t": 55356, "b": 3, "i": 6.764024257659912, "p": 1761.1588208571688, "e": 0.3442096710205078, "d": 3 }, { "t": 55843, "b": 3, "i": 4.132580757141113, "p": 1420.7889337043393, "e": 0.4717661440372467, "d": 3 }, { "t": 56308, "b": 3, "i": 5.256905555725098, "p": 2886.073956786187, "e": 0.2537829279899597, "d": 3 }, { "t": 56796, "b": 3, "i": 9.835262298583984, "p": 3076.157151407047, "e": 0.3453160524368286, "d": 3 }, { "t": 57283, "b": 3, "i": 6.038094997406006, "p": 1743.867920646153, "e": 0.31844431161880493, "d": 3 }, { "t": 57748, "b": 3, "i": 2.581868886947632, "p": 3071.8808689356774, "e": 0.45111316442489624, "d": 3 }, { "t": 58212, "b": 3, "i": 1.47910737991333, "p": 2115.053406736652, "e": 0.33867326378822327, "d": 3 }, { "t": 58700, "b": 3, "i": 11.52017879486084, "p": 3368.819534582304, "e": 0.35284191370010376, "d": 3 }, { "t": 59187, "b": 3, "i": 8.682441711425781, "p": 1707.9834790470682, "e": 0.3659251034259796, "d": 3 }, { "t": 59675, "b": 3, "i": 4.516438007354736, "p": 1449.9740322972095, "e": 0.45447197556495667, "d": 3 }, { "t": 60162, "b": 3, "i": 5.196836948394775, "p": 2070.0252945904044, "e": 0.14537116885185242, "d": 3 }, { "t": 60627, "b": 3, "i": 17.25079917907715, "p": 3434.872672429395, "e": 0.2984847128391266, "d": 3 }, { "t": 61114, "b": 3, "i": 5.494191646575928, "p": 2906.4887633613853, "e": 0.1432659775018692, "d": 3 }, { "t": 61602, "b": 3, "i": 7.47904109954834, "p": 1454.1442934823922, "e": 0.49041301012039185, "d": 3 }, { "t": 62090, "b": 3, "i": 1.442294716835022, "p": 1827.653679759852, "e": 0.30633243918418884, "d": 3 }, { "t": 62554, "b": 3, "i": 8.403895378112793, "p": 2922.9020911415223, "e": 0.3444417417049408, "d": 3 }, { "t": 63018, "b": 3, "i": 3.8509278297424316, "p": 2461.9559088225096, "e": 0.2630174458026886, "d": 3 }, { "t": 63506, "b": 3, "i": 3.432626485824585, "p": 1798.5756150308216, "e": 0.4566657841205597, "d": 3 }, { "t": 63994, "b": 3, "i": 3.276465892791748, "p": 2287.657978254267, "e": 0.3014110326766968, "d": 3 }, { "t": 64458, "b": 3, "i": 9.063994407653809, "p": 3318.919639777262, "e": 0.32887712121009827, "d": 3 }, { "t": 64946, "b": 3, "i": 5.313317775726318, "p": 1976.7826087090018, "e": 0.3184760510921478, "d": 3 }, { "t": 65433, "b": 3, "i": 3.8879945278167725, "p": 1667.9044806189963, "e": 0.4807576835155487, "d": 3 }, { "t": 65921, "b": 3, "i": 2.1509127616882324, "p": 2455.150853281942, "e": 0.24814960360527039, "d": 3 }, { "t": 66385, "b": 3, "i": 9.396177291870117, "p": 3194.5949175342466, "e": 0.3020530641078949, "d": 3 }, { "t": 66850, "b": 3, "i": 3.504487991333008, "p": 2138.1559372660167, "e": 0.28486064076423645, "d": 3 }, { "t": 67337, "b": 3, "i": 4.286209583282471, "p": 1733.7691251401748, "e": 0.43892544507980347, "d": 3 }, { "t": 67802, "b": 3, "i": 3.6873066425323486, "p": 2497.2879807931567, "e": 0.2459288090467453, "d": 3 }, { "t": 68289, "b": 3, "i": 13.604379653930664, "p": 3390.2841920546434, "e": 0.30889973044395447, "d": 3 }, { "t": 68777, "b": 3, "i": 5.461067199707031, "p": 2699.2025753403213, "e": 0.27193596959114075, "d": 3 }, { "t": 69241, "b": 3, "i": 3.6448559761047363, "p": 1863.7108217160433, "e": 0.4498606324195862, "d": 3 }, { "t": 69752, "b": 3, "i": 3.323578119277954, "p": 2711.068376737249, "e": 0.3082667589187622, "d": 3 }, { "t": 70217, "b": 3, "i": 14.9225435256958, "p": 3028.2416805831817, "e": 0.3333119750022888, "d": 3 }, { "t": 70681, "b": 3, "i": 3.86893630027771, "p": 2371.512670157643, "e": 0.2967955470085144, "d": 3 }, { "t": 71169, "b": 3, "i": 4.625463008880615, "p": 1778.7793829560721, "e": 0.4542461633682251, "d": 3 }, { "t": 71633, "b": 3, "i": 2.5753870010375977, "p": 2874.5200514609737, "e": 0.2237038016319275, "d": 3 }, { "t": 72121, "b": 3, "i": 10.503409385681152, "p": 3409.4570607856567, "e": 0.3334222137928009, "d": 3 }, { "t": 72608, "b": 3, "i": 7.159915924072266, "p": 2414.5520840346935, "e": 0.267256498336792, "d": 3 }, { "t": 73096, "b": 3, "i": 3.774451494216919, "p": 1645.3770911257534, "e": 0.4651409983634949, "d": 3 }, { "t": 73584, "b": 3, "i": 3.9380319118499756, "p": 3611.154555094807, "e": 0.17947125434875488, "d": 3 }, { "t": 74048, "b": 3, "i": 14.681280136108398, "p": 3053.0141199273885, "e": 0.34358665347099304, "d": 3 }, { "t": 74536, "b": 3, "i": 5.269817352294922, "p": 2598.2730785406384, "e": 0.2910471260547638, "d": 3 }, { "t": 75000, "b": 3, "i": 2.7629733085632324, "p": 2010.5608505570408, "e": 0.4474538266658783, "d": 3 }, { "t": 75488, "b": 3, "i": 4.16033411026001, "p": 2720.475578503464, "e": 0.24471907317638397, "d": 3 }, { "t": 75975, "b": 3, "i": 10.542248725891113, "p": 3325.1617167618037, "e": 0.28959211707115173, "d": 3 }, { "t": 76440, "b": 3, "i": 1.4551291465759277, "p": 2774.6531914378756, "e": 0.14466530084609985, "d": 3 }, { "t": 76904, "b": 2, "i": 0.49402689933776855, "p": 1601.4397544634628, "e": 0.4886834919452667, "d": 1 }, { "t": 77392, "b": 2, "i": 0.2728519141674042, "p": 1125.2924187389985, "e": 0.416696161031723, "d": 0 }, { "t": 77879, "b": 3, "i": 4.340192794799805, "p": 3248.406098675193, "e": 0.37540915608406067, "d": 3 }, { "t": 78367, "b": 3, "i": 1.8398116827011108, "p": 2719.0609801402034, "e": 0.3776046931743622, "d": 3 }, { "t": 78854, "b": 3, "i": 2.7698614597320557, "p": 2183.8254325067774, "e": 0.4844539165496826, "d": 3 }, { "t": 79342, "b": 3, "i": 1.935075044631958, "p": 2692.719882663137, "e": 0.34405717253685, "d": 3 }, { "t": 79806, "b": 3, "i": 8.89029598236084, "p": 3231.940345088082, "e": 0.37372419238090515, "d": 3 }, { "t": 80294, "b": 3, "i": 3.5478665828704834, "p": 2821.856248495584, "e": 0.3326568603515625, "d": 3 }, { "t": 80759, "b": 3, "i": 2.863417387008667, "p": 2221.5891602597494, "e": 0.47616541385650635, "d": 3 }, { "t": 81246, "b": 3, "i": 4.23590612411499, "p": 2815.9793870645535, "e": 0.3529652953147888, "d": 3 }, { "t": 81734, "b": 3, "i": 6.723094463348389, "p": 3264.924813261917, "e": 0.3604864180088043, "d": 3 }, { "t": 82198, "b": 3, "i": 8.441471099853516, "p": 3032.6191117185645, "e": 0.32474711537361145, "d": 3 }, { "t": 82686, "b": 3, "i": 2.6099348068237305, "p": 2088.287088097676, "e": 0.4773409962654114, "d": 3 }, { "t": 83150, "b": 3, "i": 4.0984416007995605, "p": 2817.8092414607263, "e": 0.35691964626312256, "d": 3 }, { "t": 83638, "b": 3, "i": 7.2008819580078125, "p": 3485.5075058058483, "e": 0.3529253602027893, "d": 3 }, { "t": 84125, "b": 3, "i": 4.9394330978393555, "p": 2963.1279248288047, "e": 0.3079707622528076, "d": 3 }, { "t": 84613, "b": 3, "i": 3.539022207260132, "p": 1873.9980927421993, "e": 0.4958662986755371, "d": 3 }, { "t": 85077, "b": 3, "i": 3.679263114929199, "p": 2910.112259062897, "e": 0.3630978465080261, "d": 3 }, { "t": 85565, "b": 3, "i": 5.040236473083496, "p": 3137.756052153044, "e": 0.3674646019935608, "d": 3 }, { "t": 86053, "b": 3, "i": 2.161818504333496, "p": 2454.791427623983, "e": 0.3554207384586334, "d": 3 }, { "t": 86517, "b": 3, "i": 3.340139389038086, "p": 1995.8669470013726, "e": 0.4764067232608795, "d": 3 }, { "t": 87005, "b": 3, "i": 4.342073917388916, "p": 2797.079015232852, "e": 0.35394662618637085, "d": 3 }, { "t": 87469, "b": 3, "i": 10.365707397460938, "p": 3276.4658484742104, "e": 0.35787832736968994, "d": 3 }, { "t": 87957, "b": 3, "i": 3.462547779083252, "p": 2812.7989456368346, "e": 0.29865360260009766, "d": 3 }, { "t": 88444, "b": 3, "i": 2.798032283782959, "p": 2257.875727919584, "e": 0.4812900424003601, "d": 3 }, { "t": 88909, "b": 3, "i": 4.210617542266846, "p": 2762.488392802291, "e": 0.3573935329914093, "d": 3 }, { "t": 89396, "b": 3, "i": 9.000475883483887, "p": 3315.07858267679, "e": 0.3741435110569, "d": 3 }, { "t": 89884, "b": 3, "i": 6.002879619598389, "p": 2548.3501697390575, "e": 0.3008982241153717, "d": 3 }, { "t": 90348, "b": 3, "i": 3.1414122581481934, "p": 2108.397395509134, "e": 0.4917939007282257, "d": 3 }, { "t": 90813, "b": 3, "i": 2.7145485877990723, "p": 2854.919886314143, "e": 0.3693385720252991, "d": 3 }, { "t": 91300, "b": 3, "i": 4.598633289337158, "p": 3543.3107237691665, "e": 0.3588566482067108, "d": 3 }, { "t": 91788, "b": 3, "i": 9.250518798828125, "p": 3366.611043469432, "e": 0.2952757179737091, "d": 3 }, { "t": 92252, "b": 3, "i": 8.084118843078613, "p": 2463.597342375404, "e": 0.47864431142807007, "d": 3 }, { "t": 92740, "b": 3, "i": 1.7300283908843994, "p": 2841.2339989324696, "e": 0.34648439288139343, "d": 3 }, { "t": 93228, "b": 3, "i": 3.676058053970337, "p": 3198.649723709048, "e": 0.36885395646095276, "d": 3 }, { "t": 93715, "b": 3, "i": 2.2013185024261475, "p": 2962.276792936015, "e": 0.3357134461402893, "d": 3 }, { "t": 94180, "b": 3, "i": 2.6001765727996826, "p": 2227.971256852502, "e": 0.4692618250846863, "d": 3 }, { "t": 94667, "b": 3, "i": 5.480765342712402, "p": 2575.834183177283, "e": 0.3599328100681305, "d": 3 }, { "t": 95155, "b": 3, "i": 4.6176371574401855, "p": 3247.986312808579, "e": 0.33906084299087524, "d": 3 }, { "t": 95619, "b": 3, "i": 3.7856452465057373, "p": 2897.8744004663995, "e": 0.35502925515174866, "d": 3 }, { "t": 96107, "b": 3, "i": 3.6500017642974854, "p": 1752.9406524197334, "e": 0.48490265011787415, "d": 3 }, { "t": 96595, "b": 3, "i": 2.0136656761169434, "p": 2573.8578726180176, "e": 0.3599143326282501, "d": 3 }, { "t": 97059, "b": 3, "i": 3.76104474067688, "p": 3257.869248326263, "e": 0.3591998815536499, "d": 3 }, { "t": 97523, "b": 3, "i": 2.2592976093292236, "p": 3160.9889019173497, "e": 0.322354257106781, "d": 3 }, { "t": 98011, "b": 3, "i": 3.111832857131958, "p": 2039.4941567215935, "e": 0.48389625549316406, "d": 3 }, { "t": 98499, "b": 3, "i": 4.05415153503418, "p": 2696.7787606414836, "e": 0.3499992787837982, "d": 3 }, { "t": 98986, "b": 3, "i": 4.299205780029297, "p": 3231.9629697002943, "e": 0.3524015247821808, "d": 3 }, { "t": 99451, "b": 3, "i": 3.0057754516601562, "p": 3035.776183945066, "e": 0.35691097378730774, "d": 3 }, { "t": 99938, "b": 2, "i": 0.6888871192932129, "p": 872.2887508868555, "e": 0.5314972996711731, "d": 2 }, { "t": 100426, "b": 2, "i": 0.5552940368652344, "p": 1178.28599942756, "e": 0.3982696235179901, "d": 1 }, { "t": 100890, "b": 3, "i": 3.630023717880249, "p": 3040.476517110666, "e": 0.3891071677207947, "d": 3 }, { "t": 101378, "b": 3, "i": 2.524402141571045, "p": 2861.7814251699556, "e": 0.35340577363967896, "d": 3 }, { "t": 101865, "b": 3, "i": 2.2954185009002686, "p": 2149.750562606625, "e": 0.47762179374694824, "d": 3 }, { "t": 102330, "b": 3, "i": 2.850925922393799, "p": 2873.7824540060515, "e": 0.34476685523986816, "d": 3 }, { "t": 102817, "b": 3, "i": 7.56580924987793, "p": 3245.262124459995, "e": 0.3567623794078827, "d": 3 }, { "t": 103305, "b": 3, "i": 2.8310718536376953, "p": 2823.5855352407966, "e": 0.3398870527744293, "d": 3 }, { "t": 103769, "b": 3, "i": 3.513338565826416, "p": 2266.11276193389, "e": 0.4809119701385498, "d": 3 }, { "t": 104257, "b": 3, "i": 3.9469151496887207, "p": 2759.381553018896, "e": 0.34191757440567017, "d": 3 }, { "t": 104721, "b": 3, "i": 9.609049797058105, "p": 3334.69648443183, "e": 0.3457067012786865, "d": 3 }, { "t": 105209, "b": 3, "i": 4.34903621673584, "p": 3086.1230582693033, "e": 0.29991811513900757, "d": 3 }, { "t": 105697, "b": 3, "i": 2.496082067489624, "p": 2088.5477328566913, "e": 0.48635390400886536, "d": 3 }, { "t": 106161, "b": 3, "i": 4.679708957672119, "p": 2985.2730832421084, "e": 0.35599467158317566, "d": 3 }, { "t": 106626, "b": 3, "i": 7.735520839691162, "p": 3542.529393266602, "e": 0.3381985127925873, "d": 3 }, { "t": 107113, "b": 3, "i": 5.278580188751221, "p": 3618.613012908048, "e": 0.27014726400375366, "d": 3 }, { "t": 107601, "b": 3, "i": 10.540114402770996, "p": 1921.3560760384235, "e": 0.4755784869194031, "d": 3 }, { "t": 108088, "b": 3, "i": 10.98853588104248, "p": 2293.213311093922, "e": 0.4061092436313629, "d": 3 }, { "t": 108553, "b": 3, "i": 14.189164161682129, "p": 3080.424886763154, "e": 0.37061718106269836, "d": 3 }, { "t": 109040, "b": 3, "i": 5.374248027801514, "p": 3430.345925436224, "e": 0.2715931534767151, "d": 3 }, { "t": 109505, "b": 3, "i": 4.8468732833862305, "p": 2180.934291813008, "e": 0.4343431890010834, "d": 3 }, { "t": 109992, "b": 3, "i": 6.3636298179626465, "p": 3361.039853761964, "e": 0.30841654539108276, "d": 3 }, { "t": 110480, "b": 3, "i": 9.82702350616455, "p": 3354.564470069246, "e": 0.3288325369358063, "d": 3 }, { "t": 110968, "b": 3, "i": 4.517523765563965, "p": 2005.2074190019734, "e": 0.31955477595329285, "d": 3 }, { "t": 111432, "b": 3, "i": 4.518334865570068, "p": 1697.0809617067023, "e": 0.4542435109615326, "d": 3 }, { "t": 111920, "b": 3, "i": 3.421456813812256, "p": 2445.163234910864, "e": 0.3261476159095764, "d": 3 }, { "t": 112407, "b": 3, "i": 4.157900810241699, "p": 3225.38006613367, "e": 0.3021165132522583, "d": 3 }, { "t": 112872, "b": 3, "i": 4.940915584564209, "p": 1904.719995793887, "e": 0.3505636751651764, "d": 3 }, { "t": 113359, "b": 3, "i": 2.9261457920074463, "p": 1495.3544161218247, "e": 0.46584972739219666, "d": 3 }, { "t": 113847, "b": 3, "i": 5.544820785522461, "p": 2298.5653156222506, "e": 0.2937290668487549, "d": 3 }, { "t": 114311, "b": 3, "i": 7.66672420501709, "p": 3578.952451624732, "e": 0.312049001455307, "d": 3 }, { "t": 114776, "b": 3, "i": 6.126560688018799, "p": 4376.986082132404, "e": 0.24285045266151428, "d": 3 }, { "t": 115263, "b": 3, "i": 10.558601379394531, "p": 1871.1996148048918, "e": 0.47619637846946716, "d": 3 }, { "t": 115751, "b": 3, "i": 8.16716480255127, "p": 1704.0376562457593, "e": 0.4062177240848541, "d": 3 }, { "t": 116215, "b": 3, "i": 11.037885665893555, "p": 3244.685628591794, "e": 0.4091634750366211, "d": 3 }, { "t": 116703, "b": 3, "i": 4.983636856079102, "p": 2134.5160155385674, "e": 0.33618277311325073, "d": 3 }, { "t": 117191, "b": 3, "i": 4.0722737312316895, "p": 1401.491092555692, "e": 0.46718889474868774, "d": 3 }, { "t": 117655, "b": 3, "i": 3.432715892791748, "p": 3734.462414759554, "e": 0.27205580472946167, "d": 3 }, { "t": 118143, "b": 3, "i": 6.348236083984375, "p": 3440.1207852330285, "e": 0.3160126805305481, "d": 3 }, { "t": 118607, "b": 3, "i": 6.898758411407471, "p": 2059.579452743987, "e": 0.33978354930877686, "d": 3 }, { "t": 119095, "b": 3, "i": 5.0398759841918945, "p": 1913.7228755367073, "e": 0.46518564224243164, "d": 3 }, { "t": 119582, "b": 3, "i": 5.298794269561768, "p": 2211.5037945471386, "e": 0.32845574617385864, "d": 3 }, { "t": 120070, "b": 3, "i": 9.356515884399414, "p": 3412.5525395178765, "e": 0.3180679678916931, "d": 3 }, { "t": 120534, "b": 3, "i": 4.801382541656494, "p": 2010.7343610008738, "e": 0.3016379773616791, "d": 3 }, { "t": 121022, "b": 3, "i": 5.442180633544922, "p": 1662.085927746498, "e": 0.44422447681427, "d": 3 }, { "t": 121510, "b": 3, "i": 5.005443096160889, "p": 1717.2933507646624, "e": 0.24463969469070435, "d": 3 }, { "t": 121974, "b": 3, "i": 10.617692947387695, "p": 3569.2235920927815, "e": 0.2962591052055359, "d": 3 }, { "t": 122438, "b": 3, "i": 2.9106879234313965, "p": 2961.1364549287377, "e": 0.19733752310276031, "d": 3 }, { "t": 122926, "b": 3, "i": 5.237730026245117, "p": 2827.018351481418, "e": 0.4289391040802002, "d": 3 }, { "t": 123414, "b": 3, "i": 3.665386199951172, "p": 3080.924891174962, "e": 0.36292436718940735, "d": 3 }, { "t": 123901, "b": 3, "i": 8.891609191894531, "p": 3053.5183089307884, "e": 0.35395553708076477, "d": 3 }, { "t": 124389, "b": 3, "i": 5.127439022064209, "p": 2876.334752045882, "e": 0.3078153431415558, "d": 3 }, { "t": 124853, "b": 3, "i": 5.678999423980713, "p": 2184.540935362492, "e": 0.45032167434692383, "d": 3 }, { "t": 125341, "b": 3, "i": 6.993736267089844, "p": 3675.6425215021413, "e": 0.2262178361415863, "d": 3 }, { "t": 125782, "b": 3, "i": 8.219512939453125, "p": 3673.1104429662746, "e": 0.30615857243537903, "d": 3 }, { "t": 126270, "b": 3, "i": 2.994614601135254, "p": 2911.577079024249, "e": 0.28342804312705994, "d": 3 }, { "t": 126757, "b": 3, "i": 4.4797492027282715, "p": 2688.354820255312, "e": 0.4332387149333954, "d": 3 }, { "t": 127245, "b": 3, "i": 4.044731140136719, "p": 4254.935413360621, "e": 0.22322885692119598, "d": 3 }, { "t": 127732, "b": 3, "i": 9.585989952087402, "p": 3285.3811196328984, "e": 0.3147159218788147, "d": 3 }, { "t": 128197, "b": 3, "i": 3.0270323753356934, "p": 3128.995555949108, "e": 0.3072300851345062, "d": 3 }, { "t": 128684, "b": 3, "i": 3.923283576965332, "p": 2576.317233624398, "e": 0.4293392300605774, "d": 3 }, { "t": 129172, "b": 3, "i": 3.7185733318328857, "p": 3880.9209234971263, "e": 0.1908929944038391, "d": 3 }, { "t": 129637, "b": 3, "i": 9.210668563842773, "p": 3535.8763532347075, "e": 0.31839272379875183, "d": 3 }, { "t": 130124, "b": 3, "i": 4.956582069396973, "p": 4112.443055754855, "e": 0.21753904223442078, "d": 3 }, { "t": 130612, "b": 3, "i": 7.448738098144531, "p": 2223.4277096344654, "e": 0.4665864408016205, "d": 3 }, { "t": 131099, "b": 3, "i": 7.765573024749756, "p": 2418.1668365773066, "e": 0.3613411784172058, "d": 3 }, { "t": 131564, "b": 3, "i": 11.318268775939941, "p": 3147.7886824208535, "e": 0.35825303196907043, "d": 3 }, { "t": 132028, "b": 3, "i": 5.229734420776367, "p": 3101.2840763167314, "e": 0.28797343373298645, "d": 3 }, { "t": 132516, "b": 3, "i": 4.434244155883789, "p": 2565.240843293599, "e": 0.4459458291530609, "d": 3 }, { "t": 133003, "b": 3, "i": 3.812349796295166, "p": 3265.1290519178933, "e": 0.2657856345176697, "d": 3 }, { "t": 133491, "b": 3, "i": 5.167307376861572, "p": 3317.399420074308, "e": 0.302765429019928, "d": 3 }, { "t": 133955, "b": 3, "i": 5.3084821701049805, "p": 2935.0542551358762, "e": 0.2906770408153534, "d": 3 }, { "t": 134443, "b": 3, "i": 4.913743495941162, "p": 2019.2464443373983, "e": 0.4626278281211853, "d": 3 }, { "t": 134931, "b": 3, "i": 4.381960391998291, "p": 3103.8761847059263, "e": 0.23391756415367126, "d": 3 }, { "t": 135395, "b": 3, "i": 9.772457122802734, "p": 3558.9075509728304, "e": 0.2689124047756195, "d": 3 }, { "t": 135883, "b": 3, "i": 5.143517971038818, "p": 2837.097252832722, "e": 0.30509626865386963, "d": 3 }, { "t": 136370, "b": 3, "i": 4.1390700340271, "p": 1673.1362393343832, "e": 0.4786039888858795, "d": 3 }, { "t": 136858, "b": 3, "i": 2.8137030601501465, "p": 1661.7938759439846, "e": 0.3136492371559143, "d": 3 }, { "t": 137322, "b": 3, "i": 3.9427096843719482, "p": 3410.2031204236637, "e": 0.3319098651409149, "d": 3 }, { "t": 137787, "b": 3, "i": 1.4312927722930908, "p": 2603.323421620026, "e": 0.23010779917240143, "d": 3 }, { "t": 138251, "b": 3, "i": 1.1068265438079834, "p": 1651.7642772665272, "e": 0.5025862455368042, "d": 2 }, { "t": 138739, "b": 2, "i": 0.41466766595840454, "p": 1124.131534517879, "e": 0.4088018238544464, "d": 1 }, { "t": 139226, "b": 3, "i": 4.295785427093506, "p": 3309.817806155503, "e": 0.377816379070282, "d": 3 }, { "t": 139714, "b": 3, "i": 1.7516098022460938, "p": 2949.555469181624, "e": 0.3756163716316223, "d": 3 }, { "t": 140202, "b": 3, "i": 3.112244129180908, "p": 2232.5232687980547, "e": 0.48150086402893066, "d": 3 }, { "t": 140689, "b": 3, "i": 2.123807191848755, "p": 2727.3778448949743, "e": 0.3331540524959564, "d": 3 }, { "t": 141154, "b": 3, "i": 8.417805671691895, "p": 3260.3888763903124, "e": 0.36515742540359497, "d": 3 }, { "t": 141641, "b": 3, "i": 3.353924036026001, "p": 2949.8733509490294, "e": 0.33298182487487793, "d": 3 }, { "t": 142129, "b": 3, "i": 2.51557993888855, "p": 2268.368351388867, "e": 0.48542308807373047, "d": 3 }, { "t": 142593, "b": 3, "i": 4.639743804931641, "p": 2917.984310590632, "e": 0.35004502534866333, "d": 3 }, { "t": 143081, "b": 3, "i": 6.513289928436279, "p": 3315.0602140870806, "e": 0.36224043369293213, "d": 3 }, { "t": 143545, "b": 3, "i": 4.379275321960449, "p": 3228.7897213552706, "e": 0.31071147322654724, "d": 3 }, { "t": 144033, "b": 3, "i": 2.7236666679382324, "p": 2179.154083672481, "e": 0.48184722661972046, "d": 3 }, { "t": 144497, "b": 3, "i": 3.4226391315460205, "p": 3129.2366212348625, "e": 0.35273030400276184, "d": 3 }, { "t": 144985, "b": 3, "i": 6.842189311981201, "p": 3553.201274487956, "e": 0.3550393879413605, "d": 3 }, { "t": 145473, "b": 3, "i": 4.040596008300781, "p": 2920.8967915556395, "e": 0.32556667923927307, "d": 3 }, { "t": 145960, "b": 3, "i": 3.8973548412323, "p": 1892.922903211475, "e": 0.4982769191265106, "d": 3 }, { "t": 146448, "b": 3, "i": 3.025285482406616, "p": 2399.677575472888, "e": 0.3358425498008728, "d": 3 }, { "t": 146912, "b": 3, "i": 5.467766284942627, "p": 3161.390191327281, "e": 0.36376428604125977, "d": 3 }, { "t": 147377, "b": 3, "i": 2.084146499633789, "p": 2880.8799135612, "e": 0.35223841667175293, "d": 3 }, { "t": 147864, "b": 3, "i": 3.5292205810546875, "p": 2164.1870806691554, "e": 0.4811455309391022, "d": 3 }, { "t": 148352, "b": 3, "i": 4.9846978187561035, "p": 2851.7993435875082, "e": 0.34447184205055237, "d": 3 }, { "t": 148816, "b": 3, "i": 8.865364074707031, "p": 3333.398984317203, "e": 0.36288341879844666, "d": 3 }, { "t": 149304, "b": 3, "i": 3.0564351081848145, "p": 2932.498312509487, "e": 0.3093920350074768, "d": 3 }, { "t": 149791, "b": 3, "i": 3.045043468475342, "p": 2256.412470402174, "e": 0.4874171018600464, "d": 3 }, { "t": 150256, "b": 3, "i": 4.077378273010254, "p": 2928.7954152069597, "e": 0.3576635420322418, "d": 3 }, { "t": 150743, "b": 3, "i": 8.158903121948242, "p": 3344.6816697690697, "e": 0.3563380241394043, "d": 3 }, { "t": 151208, "b": 3, "i": 3.8512463569641113, "p": 3403.7164625735104, "e": 0.3125809133052826, "d": 3 }, { "t": 151695, "b": 3, "i": 3.1787562370300293, "p": 2286.519165242151, "e": 0.4766263961791992, "d": 3 }, { "t": 152183, "b": 3, "i": 3.293024778366089, "p": 2885.8307624648914, "e": 0.3736293613910675, "d": 3 }, { "t": 152647, "b": 3, "i": 4.514618396759033, "p": 3547.5576964455777, "e": 0.3571072816848755, "d": 3 }, { "t": 153135, "b": 3, "i": 5.094784736633301, "p": 3404.7433856210655, "e": 0.3014254570007324, "d": 3 }, { "t": 153600, "b": 3, "i": 6.995543003082275, "p": 2539.529290747539, "e": 0.48440441489219666, "d": 3 }, { "t": 154087, "b": 3, "i": 1.4882550239562988, "p": 2976.8683854856813, "e": 0.35014817118644714, "d": 3 }, { "t": 154575, "b": 3, "i": 3.2474515438079834, "p": 3238.833263221879, "e": 0.3568834364414215, "d": 3 }, { "t": 155062, "b": 3, "i": 2.04535174369812, "p": 3001.5949897970127, "e": 0.3395945429801941, "d": 3 }, { "t": 155527, "b": 3, "i": 2.368849754333496, "p": 2428.8969359584435, "e": 0.4694775938987732, "d": 3 }, { "t": 156014, "b": 3, "i": 5.999950885772705, "p": 2808.576625110348, "e": 0.34786078333854675, "d": 3 }, { "t": 156502, "b": 3, "i": 4.809159755706787, "p": 3267.9767673763545, "e": 0.33948448300361633, "d": 3 }, { "t": 156966, "b": 3, "i": 3.5236613750457764, "p": 3029.9894654194413, "e": 0.3474297523498535, "d": 3 }, { "t": 157454, "b": 3, "i": 4.247496604919434, "p": 1828.4767981703526, "e": 0.4900107681751251, "d": 3 }, { "t": 157942, "b": 3, "i": 2.0332961082458496, "p": 2583.653671916922, "e": 0.34585657715797424, "d": 3 }, { "t": 158406, "b": 3, "i": 3.2660114765167236, "p": 3256.690051396184, "e": 0.3384650945663452, "d": 3 }, { "t": 158894, "b": 3, "i": 2.4815666675567627, "p": 3032.1681447362685, "e": 0.3244231045246124, "d": 3 }, { "t": 159381, "b": 3, "i": 3.0530917644500732, "p": 1810.1388719425645, "e": 0.5091697573661804, "d": 3 }, { "t": 159846, "b": 3, "i": 3.8156917095184326, "p": 2867.5485399699155, "e": 0.3420235514640808, "d": 3 }, { "t": 160333, "b": 3, "i": 4.371726036071777, "p": 3234.912689508289, "e": 0.35412418842315674, "d": 3 }, { "t": 160798, "b": 3, "i": 3.3492701053619385, "p": 3097.763275278035, "e": 0.35885417461395264, "d": 3 }, { "t": 161285, "b": 3, "i": 2.4332005977630615, "p": 1280.0557970487662, "e": 0.4914645850658417, "d": 3 }, { "t": 161773, "b": 2, "i": 0.8467485904693604, "p": 1153.727014767308, "e": 0.4077070355415344, "d": 2 }, { "t": 162237, "b": 3, "i": 3.5400819778442383, "p": 3226.876693694433, "e": 0.37842506170272827, "d": 3 }, { "t": 162725, "b": 3, "i": 1.8970476388931274, "p": 2887.5244698122333, "e": 0.3569037914276123, "d": 3 }, { "t": 163213, "b": 3, "i": 2.44291615486145, "p": 2067.2030954917655, "e": 0.4811573624610901, "d": 3 }, { "t": 163677, "b": 3, "i": 1.9426788091659546, "p": 3057.2530884051794, "e": 0.33631715178489685, "d": 3 }, { "t": 164165, "b": 3, "i": 6.205290794372559, "p": 3231.7515900664675, "e": 0.35052284598350525, "d": 3 }, { "t": 164652, "b": 3, "i": 2.3711555004119873, "p": 2824.7450537058075, "e": 0.3460383713245392, "d": 3 }, { "t": 165117, "b": 3, "i": 3.107652187347412, "p": 2311.0981289794936, "e": 0.4803580045700073, "d": 3 }, { "t": 165604, "b": 3, "i": 2.9591012001037598, "p": 2820.4808920892306, "e": 0.3535047173500061, "d": 3 }, { "t": 166069, "b": 3, "i": 6.655457973480225, "p": 3389.970364104186, "e": 0.3461506962776184, "d": 3 }, { "t": 166556, "b": 3, "i": 3.9248647689819336, "p": 3163.1078466063436, "e": 0.32097792625427246, "d": 3 }, { "t": 167044, "b": 3, "i": 2.68183970451355, "p": 2074.1613740606617, "e": 0.48557937145233154, "d": 3 }, { "t": 167508, "b": 3, "i": 4.22308874130249, "p": 3121.5380159445776, "e": 0.36369457840919495, "d": 3 }, { "t": 167996, "b": 3, "i": 5.115701675415039, "p": 3663.2005645867857, "e": 0.32685065269470215, "d": 3 }, { "t": 168483, "b": 3, "i": 4.030178070068359, "p": 3014.350346950824, "e": 0.2736246883869171, "d": 3 }, { "t": 168948, "b": 3, "i": 2.4888157844543457, "p": 2180.188822862961, "e": 0.3661220669746399, "d": 3 }, { "t": 169412, "b": 3, "i": 8.882022857666016, "p": 2158.0249205469777, "e": 0.3215053081512451, "d": 3 }, { "t": 169900, "b": 3, "i": 3.366628408432007, "p": 2433.341504156304, "e": 0.3276776969432831, "d": 3 }, { "t": 170364, "b": 3, "i": 10.073043823242188, "p": 1839.9691684289187, "e": 0.30427801609039307, "d": 3 }, { "t": 170852, "b": 3, "i": 11.765978813171387, "p": 2691.5842361602995, "e": 0.31375303864479065, "d": 3 }, { "t": 171340, "b": 3, "i": 9.434046745300293, "p": 2197.7873333664543, "e": 0.33983051776885986, "d": 3 }, { "t": 171850, "b": 3, "i": 4.096007823944092, "p": 2248.296189032127, "e": 0.32024770975112915, "d": 3 }, { "t": 172315, "b": 3, "i": 6.502973556518555, "p": 2584.7111243103627, "e": 0.2911781370639801, "d": 3 }, { "t": 172779, "b": 3, "i": 5.698068141937256, "p": 1391.2112300040235, "e": 0.30902430415153503, "d": 3 }, { "t": 173267, "b": 3, "i": 3.408581256866455, "p": 2263.304307956982, "e": 0.27232825756073, "d": 3 }, { "t": 173754, "b": 3, "i": 9.245026588439941, "p": 2357.492070742451, "e": 0.25767022371292114, "d": 3 }, { "t": 174219, "b": 3, "i": 5.489374160766602, "p": 2313.0767576013122, "e": 0.2929079234600067, "d": 3 }, { "t": 174706, "b": 3, "i": 6.128178596496582, "p": 2899.538286342352, "e": 0.24913643300533295, "d": 3 }, { "t": 175194, "b": 3, "i": 3.3845720291137695, "p": 2338.6334417691232, "e": 0.2920881509780884, "d": 3 }, { "t": 175682, "b": 3, "i": 8.586904525756836, "p": 2002.6605076654796, "e": 0.2836780846118927, "d": 3 }, { "t": 176146, "b": 3, "i": 2.9050533771514893, "p": 3807.961874775162, "e": 0.23057414591312408, "d": 3 }, { "t": 176610, "b": 3, "i": 8.866110801696777, "p": 2443.9444119976647, "e": 0.2486984133720398, "d": 3 }, { "t": 177098, "b": 3, "i": 5.981752395629883, "p": 2101.213782721783, "e": 0.32863086462020874, "d": 3 }, { "t": 177586, "b": 3, "i": 8.890477180480957, "p": 1496.1988253860477, "e": 0.31333470344543457, "d": 3 }, { "t": 178050, "b": 2, "i": 0.9796077013015747, "p": 1533.3320486048422, "e": 0.36560922861099243, "d": 3 }, { "t": 178515, "b": 3, "i": 1.1402055025100708, "p": 1254.6319212290252, "e": 0.3502257466316223, "d": 3 }, { "t": 178979, "b": 3, "i": 5.382186412811279, "p": 3544.9859489760343, "e": 0.276201456785202, "d": 3 }, { "t": 179490, "b": 3, "i": 8.798264503479004, "p": 1782.9649538815647, "e": 0.3131880462169647, "d": 3 }, { "t": 179977, "b": 3, "i": 3.2025680541992188, "p": 2854.4840232102783, "e": 0.24114996194839478, "d": 3 }, { "t": 180442, "b": 3, "i": 8.827409744262695, "p": 2001.1563540160578, "e": 0.3194652199745178, "d": 3 }, { "t": 180929, "b": 3, "i": 3.521442413330078, "p": 2067.0317493355396, "e": 0.27951860427856445, "d": 3 }, { "t": 181417, "b": 3, "i": 7.9667439460754395, "p": 1548.120086556327, "e": 0.25426897406578064, "d": 3 }, { "t": 181881, "b": 3, "i": 1.0105844736099243, "p": 1295.0502993043208, "e": 0.3704873025417328, "d": 3 }, { "t": 182369, "b": 3, "i": 1.2575035095214844, "p": 1531.7506821352963, "e": 0.3148230314254761, "d": 3 }, { "t": 182857, "b": 3, "i": 1.3544456958770752, "p": 1119.2488640548788, "e": 0.23186488449573517, "d": 3 }, { "t": 183344, "b": 3, "i": 2.979818344116211, "p": 1279.1246402170148, "e": 0.14189721643924713, "d": 3 }, { "t": 183809, "b": 3, "i": 3.372346878051758, "p": 950.3650564952405, "e": 0.18409401178359985, "d": 3 }, { "t": 184296, "b": 3, "i": 4.639944076538086, "p": 2122.8431742384373, "e": 0.3558056950569153, "d": 3 }, { "t": 184784, "b": 3, "i": 4.746321678161621, "p": 2138.201054556548, "e": 0.30984824895858765, "d": 3 }, { "t": 185272, "b": 3, "i": 7.610533714294434, "p": 1920.5862737027796, "e": 0.31628838181495667, "d": 3 }] }]; var songListV2 = [{ "name": "Imagine Dragons - Believer", "songBeats": [{ "time": 347, "beat": "2" }, { "time": 661, "beat": "1" }, { "time": 987, "beat": "1" }, { "time": 1301, "beat": "3" }, { "time": 1787, "beat": "1" }, { "time": 2107, "beat": "2" }, { "time": 2411, "beat": "1" }, { "time": 2736, "beat": "1" }, { "time": 3221, "beat": "1" }, { "time": 3563, "beat": "1" }, { "time": 3888, "beat": "2" }, { "time": 4197, "beat": "3" }, { "time": 4656, "beat": "1" }, { "time": 5136, "beat": "1" }, { "time": 5616, "beat": "1" }, { "time": 5920, "beat": "2" }, { "time": 6229, "beat": "1" }, { "time": 6571, "beat": "1" }, { "time": 7056, "beat": "1" }, { "time": 7403, "beat": "1" }, { "time": 7968, "beat": "1" }, { "time": 8288, "beat": "1" }, { "time": 8613, "beat": "3" }, { "time": 8928, "beat": "3" }, { "time": 9408, "beat": "1" }, { "time": 9712, "beat": "2" }, { "time": 10021, "beat": "1" }, { "time": 10363, "beat": "1" }, { "time": 10848, "beat": "2" }, { "time": 11195, "beat": "1" }, { "time": 11531, "beat": "1" }, { "time": 11840, "beat": "2" }, { "time": 12181, "beat": "1" }, { "time": 12763, "beat": "1" }, { "time": 13243, "beat": "1" }, { "time": 13547, "beat": "2" }, { "time": 13856, "beat": "1" }, { "time": 14197, "beat": "1" }, { "time": 14683, "beat": "2" }, { "time": 15163, "beat": "1" }, { "time": 15611, "beat": "2" }, { "time": 15925, "beat": "1" }, { "time": 16251, "beat": "1" }, { "time": 16565, "beat": "3" }, { "time": 17051, "beat": "1" }, { "time": 17371, "beat": "2" }, { "time": 17675, "beat": "1" }, { "time": 18000, "beat": "1" }, { "time": 18485, "beat": "1" }, { "time": 18827, "beat": "1" }, { "time": 19131, "beat": "2" }, { "time": 19435, "beat": "1" }, { "time": 19744, "beat": "1" }, { "time": 20400, "beat": "1" }, { "time": 20885, "beat": "1" }, { "time": 21205, "beat": "2" }, { "time": 21509, "beat": "1" }, { "time": 21835, "beat": "1" }, { "time": 22320, "beat": "1" }, { "time": 22661, "beat": "1" }, { "time": 23237, "beat": "2" }, { "time": 23552, "beat": "1" }, { "time": 23877, "beat": "2" }, { "time": 24192, "beat": "3" }, { "time": 24672, "beat": "1" }, { "time": 24976, "beat": "2" }, { "time": 25285, "beat": "1" }, { "time": 25627, "beat": "1" }, { "time": 26112, "beat": "2" }, { "time": 26459, "beat": "1" }, { "time": 26795, "beat": "1" }, { "time": 27104, "beat": "2" }, { "time": 27445, "beat": "1" }, { "time": 28027, "beat": "1" }, { "time": 28507, "beat": "1" }, { "time": 28811, "beat": "2" }, { "time": 29120, "beat": "1" }, { "time": 29461, "beat": "1" }, { "time": 29947, "beat": "2" }, { "time": 30293, "beat": "1" }, { "time": 30821, "beat": "1" }, { "time": 31136, "beat": "1" }, { "time": 31451, "beat": "2" }, { "time": 31765, "beat": "1" }, { "time": 32069, "beat": "2" }, { "time": 32373, "beat": "3" }, { "time": 32683, "beat": "3" }, { "time": 32997, "beat": "1" }, { "time": 33312, "beat": "2" }, { "time": 33621, "beat": "2" }, { "time": 33941, "beat": "2" }, { "time": 34256, "beat": "1" }, { "time": 34560, "beat": "3" }, { "time": 34869, "beat": "1" }, { "time": 35179, "beat": "2" }, { "time": 35493, "beat": "1" }, { "time": 35797, "beat": "1" }, { "time": 36101, "beat": "2" }, { "time": 36405, "beat": "1" }, { "time": 36741, "beat": "1" }, { "time": 37045, "beat": "2" }, { "time": 37349, "beat": "1" }, { "time": 37653, "beat": "1" }, { "time": 37973, "beat": "2" }, { "time": 38325, "beat": "1" }, { "time": 38629, "beat": "3" }, { "time": 38949, "beat": "1" }, { "time": 39253, "beat": "3" }, { "time": 39573, "beat": "2" }, { "time": 39883, "beat": "3" }, { "time": 40251, "beat": "1" }, { "time": 40560, "beat": "2" }, { "time": 40869, "beat": "1" }, { "time": 41173, "beat": "1" }, { "time": 41515, "beat": "2" }, { "time": 41824, "beat": "1" }, { "time": 42144, "beat": "1" }, { "time": 42475, "beat": "2" }, { "time": 42779, "beat": "2" }, { "time": 43099, "beat": "1" }, { "time": 43429, "beat": "2" }, { "time": 43765, "beat": "3" }, { "time": 44101, "beat": "2" }, { "time": 44411, "beat": "1" }, { "time": 44720, "beat": "3" }, { "time": 45035, "beat": "1" }, { "time": 45339, "beat": "1" }, { "time": 45643, "beat": "3" }, { "time": 45984, "beat": "1" }, { "time": 46299, "beat": "3" }, { "time": 46624, "beat": "3" }, { "time": 46955, "beat": "1" }, { "time": 47259, "beat": "2" }, { "time": 47568, "beat": "1" }, { "time": 47883, "beat": "1" }, { "time": 48245, "beat": "2" }, { "time": 48565, "beat": "1" }, { "time": 48880, "beat": "1" }, { "time": 49205, "beat": "1" }, { "time": 49547, "beat": "1" }, { "time": 49861, "beat": "1" }, { "time": 50171, "beat": "1" }, { "time": 50480, "beat": "1" }, { "time": 50805, "beat": "1" }, { "time": 51157, "beat": "1" }, { "time": 51467, "beat": "2" }, { "time": 51781, "beat": "3" }, { "time": 52096, "beat": "2" }, { "time": 52400, "beat": "1" }, { "time": 52704, "beat": "2" }, { "time": 53008, "beat": "1" }, { "time": 53312, "beat": "1" }, { "time": 53621, "beat": "1" }, { "time": 53925, "beat": "3" }, { "time": 54229, "beat": "2" }, { "time": 54555, "beat": "2" }, { "time": 54875, "beat": "3" }, { "time": 55179, "beat": "3" }, { "time": 55531, "beat": "2" }, { "time": 55835, "beat": "3" }, { "time": 56144, "beat": "3" }, { "time": 56459, "beat": "2" }, { "time": 56773, "beat": "3" }, { "time": 57088, "beat": "3" }, { "time": 57397, "beat": "3" }, { "time": 57701, "beat": "1" }, { "time": 58021, "beat": "1" }, { "time": 58325, "beat": "2" }, { "time": 58651, "beat": "1" }, { "time": 58955, "beat": "3" }, { "time": 59280, "beat": "2" }, { "time": 59589, "beat": "2" }, { "time": 59904, "beat": "1" }, { "time": 60208, "beat": "1" }, { "time": 60517, "beat": "3" }, { "time": 60827, "beat": "1" }, { "time": 61136, "beat": "1" }, { "time": 61445, "beat": "1" }, { "time": 61776, "beat": "1" }, { "time": 62085, "beat": "1" }, { "time": 62400, "beat": "2" }, { "time": 62757, "beat": "1" }, { "time": 63061, "beat": "2" }, { "time": 63403, "beat": "1" }, { "time": 63707, "beat": "1" }, { "time": 64059, "beat": "1" }, { "time": 64363, "beat": "3" }, { "time": 64672, "beat": "1" }, { "time": 64987, "beat": "3" }, { "time": 65333, "beat": "1" }, { "time": 65637, "beat": "1" }, { "time": 65963, "beat": "1" }, { "time": 66277, "beat": "1" }, { "time": 66581, "beat": "3" }, { "time": 66912, "beat": "1" }, { "time": 67253, "beat": "1" }, { "time": 67573, "beat": "3" }, { "time": 67877, "beat": "1" }, { "time": 68187, "beat": "2" }, { "time": 68496, "beat": "3" }, { "time": 68816, "beat": "1" }, { "time": 69120, "beat": "2" }, { "time": 69445, "beat": "1" }, { "time": 69760, "beat": "3" }, { "time": 70064, "beat": "2" }, { "time": 70368, "beat": "2" }, { "time": 70699, "beat": "1" }, { "time": 71008, "beat": "3" }, { "time": 71344, "beat": "1" }, { "time": 71659, "beat": "2" }, { "time": 71984, "beat": "1" }, { "time": 72320, "beat": "1" }, { "time": 72640, "beat": "1" }, { "time": 72944, "beat": "3" }, { "time": 73285, "beat": "1" }, { "time": 73595, "beat": "2" }, { "time": 73920, "beat": "1" }, { "time": 74229, "beat": "2" }, { "time": 74539, "beat": "2" }, { "time": 74843, "beat": "3" }, { "time": 75147, "beat": "3" }, { "time": 75451, "beat": "2" }, { "time": 75760, "beat": "3" }, { "time": 76064, "beat": "1" }, { "time": 76373, "beat": "1" }, { "time": 76688, "beat": "3" }, { "time": 76992, "beat": "1" }, { "time": 77296, "beat": "1" }, { "time": 77605, "beat": "3" }, { "time": 77920, "beat": "3" }, { "time": 78235, "beat": "3" }, { "time": 78544, "beat": "3" }, { "time": 78848, "beat": "3" }, { "time": 79163, "beat": "3" }, { "time": 79477, "beat": "3" }, { "time": 79787, "beat": "3" }, { "time": 80107, "beat": "3" }, { "time": 80411, "beat": "3" }, { "time": 80731, "beat": "3" }, { "time": 81040, "beat": "2" }, { "time": 81349, "beat": "3" }, { "time": 81669, "beat": "3" }, { "time": 81989, "beat": "2" }, { "time": 82293, "beat": "2" }, { "time": 82597, "beat": "2" }, { "time": 82955, "beat": "2" }, { "time": 83275, "beat": "3" }, { "time": 83595, "beat": "3" }, { "time": 83909, "beat": "2" }, { "time": 84213, "beat": "3" }, { "time": 84523, "beat": "2" }, { "time": 84843, "beat": "2" }, { "time": 85152, "beat": "2" }, { "time": 85477, "beat": "3" }, { "time": 85787, "beat": "3" }, { "time": 86112, "beat": "3" }, { "time": 86432, "beat": "2" }, { "time": 86752, "beat": "1" }, { "time": 87061, "beat": "2" }, { "time": 87387, "beat": "2" }, { "time": 87696, "beat": "1" }, { "time": 88021, "beat": "2" }, { "time": 88341, "beat": "3" }, { "time": 88661, "beat": "2" }, { "time": 88965, "beat": "3" }, { "time": 89275, "beat": "2" }, { "time": 89595, "beat": "2" }, { "time": 89899, "beat": "2" }, { "time": 90240, "beat": "3" }, { "time": 90560, "beat": "2" }, { "time": 90885, "beat": "3" }, { "time": 91195, "beat": "3" }, { "time": 91515, "beat": "2" }, { "time": 91835, "beat": "2" }, { "time": 92139, "beat": "3" }, { "time": 92448, "beat": "3" }, { "time": 92757, "beat": "3" }, { "time": 93109, "beat": "3" }, { "time": 93413, "beat": "2" }, { "time": 93728, "beat": "3" }, { "time": 94043, "beat": "3" }, { "time": 94352, "beat": "1" }, { "time": 94661, "beat": "3" }, { "time": 94965, "beat": "2" }, { "time": 95280, "beat": "2" }, { "time": 95605, "beat": "3" }, { "time": 95909, "beat": "3" }, { "time": 96224, "beat": "3" }, { "time": 96528, "beat": "3" }, { "time": 96837, "beat": "3" }, { "time": 97141, "beat": "2" }, { "time": 97461, "beat": "3" }, { "time": 97771, "beat": "3" }, { "time": 98080, "beat": "3" }, { "time": 98389, "beat": "2" }, { "time": 98699, "beat": "2" }, { "time": 99008, "beat": "3" }, { "time": 99323, "beat": "2" }, { "time": 99627, "beat": "3" }, { "time": 99931, "beat": "3" }, { "time": 100240, "beat": "1" }, { "time": 100565, "beat": "1" }, { "time": 100885, "beat": "3" }, { "time": 101200, "beat": "3" }, { "time": 101520, "beat": "3" }, { "time": 101824, "beat": "3" }, { "time": 102128, "beat": "1" }, { "time": 102432, "beat": "3" }, { "time": 102752, "beat": "2" }, { "time": 103067, "beat": "1" }, { "time": 103381, "beat": "2" }, { "time": 103685, "beat": "2" }, { "time": 103995, "beat": "1" }, { "time": 104299, "beat": "3" }, { "time": 104608, "beat": "3" }, { "time": 104912, "beat": "2" }, { "time": 105221, "beat": "3" }, { "time": 105536, "beat": "3" }, { "time": 105845, "beat": "3" }, { "time": 106155, "beat": "3" }, { "time": 106464, "beat": "3" }, { "time": 106773, "beat": "2" }, { "time": 107077, "beat": "2" }, { "time": 107392, "beat": "3" }, { "time": 107701, "beat": "2" }, { "time": 108005, "beat": "3" }, { "time": 108309, "beat": "1" }, { "time": 108619, "beat": "2" }, { "time": 108928, "beat": "1" }, { "time": 109237, "beat": "1" }, { "time": 109595, "beat": "1" }, { "time": 109899, "beat": "1" }, { "time": 110203, "beat": "2" }, { "time": 110507, "beat": "1" }, { "time": 110811, "beat": "2" }, { "time": 111115, "beat": "1" }, { "time": 111429, "beat": "3" }, { "time": 111749, "beat": "1" }, { "time": 112080, "beat": "2" }, { "time": 112400, "beat": "2" }, { "time": 112715, "beat": "1" }, { "time": 113019, "beat": "2" }, { "time": 113328, "beat": "2" }, { "time": 113637, "beat": "2" }, { "time": 113947, "beat": "2" }, { "time": 114267, "beat": "1" }, { "time": 114571, "beat": "2" }, { "time": 114901, "beat": "2" }, { "time": 115211, "beat": "3" }, { "time": 115520, "beat": "3" }, { "time": 115840, "beat": "3" }, { "time": 116149, "beat": "1" }, { "time": 116475, "beat": "1" }, { "time": 116779, "beat": "3" }, { "time": 117083, "beat": "2" }, { "time": 117387, "beat": "2" }, { "time": 117696, "beat": "2" }, { "time": 118021, "beat": "1" }, { "time": 118347, "beat": "1" }, { "time": 118661, "beat": "2" }, { "time": 118965, "beat": "3" }, { "time": 119269, "beat": "2" }, { "time": 119573, "beat": "2" }, { "time": 119904, "beat": "1" }, { "time": 120229, "beat": "2" }, { "time": 120533, "beat": "2" }, { "time": 120837, "beat": "3" }, { "time": 121147, "beat": "3" }, { "time": 121451, "beat": "3" }, { "time": 121760, "beat": "1" }, { "time": 122064, "beat": "1" }, { "time": 122379, "beat": "3" }, { "time": 122699, "beat": "1" }, { "time": 123008, "beat": "2" }, { "time": 123312, "beat": "3" }, { "time": 123616, "beat": "3" }, { "time": 123925, "beat": "2" }, { "time": 124229, "beat": "1" }, { "time": 124549, "beat": "1" }, { "time": 124853, "beat": "3" }, { "time": 125173, "beat": "1" }, { "time": 125477, "beat": "2" }, { "time": 125808, "beat": "2" }, { "time": 126123, "beat": "1" }, { "time": 126491, "beat": "1" }, { "time": 126795, "beat": "3" }, { "time": 127115, "beat": "1" }, { "time": 127419, "beat": "1" }, { "time": 127728, "beat": "2" }, { "time": 128069, "beat": "1" }, { "time": 128400, "beat": "1" }, { "time": 128709, "beat": "3" }, { "time": 129013, "beat": "1" }, { "time": 129317, "beat": "1" }, { "time": 129643, "beat": "2" }, { "time": 129957, "beat": "1" }, { "time": 130277, "beat": "1" }, { "time": 130581, "beat": "3" }, { "time": 130885, "beat": "2" }, { "time": 131205, "beat": "1" }, { "time": 131520, "beat": "3" }, { "time": 131829, "beat": "3" }, { "time": 132139, "beat": "1" }, { "time": 132459, "beat": "1" }, { "time": 132768, "beat": "2" }, { "time": 133083, "beat": "3" }, { "time": 133403, "beat": "1" }, { "time": 133717, "beat": "1" }, { "time": 134032, "beat": "2" }, { "time": 134352, "beat": "1" }, { "time": 134672, "beat": "2" }, { "time": 134997, "beat": "1" }, { "time": 135301, "beat": "1" }, { "time": 135605, "beat": "2" }, { "time": 135931, "beat": "1" }, { "time": 136245, "beat": "2" }, { "time": 136549, "beat": "1" }, { "time": 136859, "beat": "1" }, { "time": 137168, "beat": "3" }, { "time": 137477, "beat": "1" }, { "time": 137787, "beat": "1" }, { "time": 138091, "beat": "3" }, { "time": 138400, "beat": "1" }, { "time": 138709, "beat": "1" }, { "time": 139019, "beat": "2" }, { "time": 139328, "beat": "3" }, { "time": 139637, "beat": "3" }, { "time": 139947, "beat": "3" }, { "time": 140267, "beat": "2" }, { "time": 140571, "beat": "2" }, { "time": 140880, "beat": "3" }, { "time": 141205, "beat": "3" }, { "time": 141531, "beat": "2" }, { "time": 141856, "beat": "2" }, { "time": 142192, "beat": "2" }, { "time": 142496, "beat": "2" }, { "time": 142800, "beat": "3" }, { "time": 143115, "beat": "2" }, { "time": 143429, "beat": "2" }, { "time": 143733, "beat": "2" }, { "time": 144037, "beat": "3" }, { "time": 144341, "beat": "3" }, { "time": 144645, "beat": "3" }, { "time": 144987, "beat": "3" }, { "time": 145296, "beat": "3" }, { "time": 145605, "beat": "2" }, { "time": 145920, "beat": "3" }, { "time": 146229, "beat": "3" }, { "time": 146533, "beat": "3" }, { "time": 146843, "beat": "3" }, { "time": 147157, "beat": "3" }, { "time": 147461, "beat": "3" }, { "time": 147776, "beat": "1" }, { "time": 148101, "beat": "1" }, { "time": 148411, "beat": "2" }, { "time": 148736, "beat": "2" }, { "time": 149045, "beat": "1" }, { "time": 149349, "beat": "3" }, { "time": 149691, "beat": "2" }, { "time": 149995, "beat": "2" }, { "time": 150315, "beat": "3" }, { "time": 150624, "beat": "2" }, { "time": 150944, "beat": "2" }, { "time": 151248, "beat": "2" }, { "time": 151616, "beat": "2" }, { "time": 151931, "beat": "3" }, { "time": 152245, "beat": "3" }, { "time": 152565, "beat": "2" }, { "time": 152885, "beat": "1" }, { "time": 153189, "beat": "2" }, { "time": 153504, "beat": "2" }, { "time": 153808, "beat": "3" }, { "time": 154128, "beat": "3" }, { "time": 154459, "beat": "3" }, { "time": 154763, "beat": "2" }, { "time": 155077, "beat": "3" }, { "time": 155392, "beat": "3" }, { "time": 155701, "beat": "1" }, { "time": 156011, "beat": "3" }, { "time": 156315, "beat": "2" }, { "time": 156624, "beat": "2" }, { "time": 156928, "beat": "3" }, { "time": 157237, "beat": "2" }, { "time": 157541, "beat": "3" }, { "time": 157851, "beat": "3" }, { "time": 158165, "beat": "3" }, { "time": 158475, "beat": "2" }, { "time": 158789, "beat": "3" }, { "time": 159093, "beat": "2" }, { "time": 159413, "beat": "3" }, { "time": 159723, "beat": "3" }, { "time": 160043, "beat": "3" }, { "time": 160357, "beat": "3" }, { "time": 160672, "beat": "2" }, { "time": 160976, "beat": "2" }, { "time": 161280, "beat": "3" }, { "time": 161589, "beat": "1" }, { "time": 161915, "beat": "1" }, { "time": 162235, "beat": "3" }, { "time": 162560, "beat": "3" }, { "time": 162875, "beat": "3" }, { "time": 163189, "beat": "3" }, { "time": 163520, "beat": "3" }, { "time": 163824, "beat": "3" }, { "time": 164165, "beat": "3" }, { "time": 164469, "beat": "3" }, { "time": 164773, "beat": "3" }, { "time": 165088, "beat": "3" }, { "time": 165397, "beat": "3" }, { "time": 165701, "beat": "3" }, { "time": 166016, "beat": "1" }, { "time": 166320, "beat": "1" }, { "time": 166640, "beat": "2" }, { "time": 166944, "beat": "2" }, { "time": 167253, "beat": "3" }, { "time": 167573, "beat": "3" }, { "time": 167883, "beat": "2" }, { "time": 168203, "beat": "2" }, { "time": 168523, "beat": "1" }, { "time": 168832, "beat": "2" }, { "time": 169168, "beat": "1" }, { "time": 169488, "beat": "2" }, { "time": 169808, "beat": "1" }, { "time": 170117, "beat": "1" }, { "time": 170421, "beat": "2" }, { "time": 170736, "beat": "2" }, { "time": 171045, "beat": "1" }, { "time": 171365, "beat": "2" }, { "time": 171680, "beat": "1" }, { "time": 172000, "beat": "2" }, { "time": 172309, "beat": "2" }, { "time": 172613, "beat": "2" }, { "time": 172923, "beat": "1" }, { "time": 173237, "beat": "1" }, { "time": 173541, "beat": "2" }, { "time": 173856, "beat": "1" }, { "time": 174187, "beat": "1" }, { "time": 174533, "beat": "1" }, { "time": 174837, "beat": "2" }, { "time": 175141, "beat": "2" }, { "time": 175451, "beat": "2" }, { "time": 175765, "beat": "2" }, { "time": 176080, "beat": "1" }, { "time": 176405, "beat": "2" }, { "time": 176720, "beat": "1" }, { "time": 177051, "beat": "1" }, { "time": 177371, "beat": "1" }, { "time": 177680, "beat": "3" }, { "time": 177989, "beat": "3" }, { "time": 178309, "beat": "3" }, { "time": 178619, "beat": "1" }, { "time": 178928, "beat": "1" }, { "time": 179243, "beat": "2" }, { "time": 179557, "beat": "2" }, { "time": 179861, "beat": "2" }, { "time": 180176, "beat": "1" }, { "time": 180480, "beat": "2" }, { "time": 180795, "beat": "3" }, { "time": 181136, "beat": "1" }, { "time": 181445, "beat": "2" }, { "time": 181771, "beat": "3" }, { "time": 182080, "beat": "2" }, { "time": 182384, "beat": "3" }, { "time": 182704, "beat": "2" }, { "time": 183008, "beat": "2" }, { "time": 183328, "beat": "1" }, { "time": 183659, "beat": "2" }, { "time": 184005, "beat": "1" }, { "time": 184315, "beat": "3" }, { "time": 184624, "beat": "2" }, { "time": 184944, "beat": "2" }, { "time": 185248, "beat": "2" }, { "time": 185573, "beat": "2" }, { "time": 185883, "beat": "2" }, { "time": 186208, "beat": "2" }, { "time": 186512, "beat": "2" }, { "time": 186827, "beat": "2" }, { "time": 187131, "beat": "2" }, { "time": 187435, "beat": "3" }, { "time": 187749, "beat": "2" }, { "time": 188059, "beat": "3" }, { "time": 188363, "beat": "3" }, { "time": 188667, "beat": "2" }, { "time": 188976, "beat": "2" }, { "time": 189285, "beat": "2" }, { "time": 189605, "beat": "2" }, { "time": 189909, "beat": "3" }, { "time": 190240, "beat": "1" }, { "time": 190549, "beat": "3" }, { "time": 190859, "beat": "2" }, { "time": 191184, "beat": "1" }, { "time": 191488, "beat": "2" }, { "time": 191824, "beat": "1" }, { "time": 192139, "beat": "1" }, { "time": 192459, "beat": "2" }, { "time": 192784, "beat": "2" }, { "time": 193093, "beat": "3" }, { "time": 193397, "beat": "2" }, { "time": 193712, "beat": "3" }, { "time": 194016, "beat": "3" }, { "time": 194331, "beat": "3" }, { "time": 194640, "beat": "3" }, { "time": 194971, "beat": "2" }, { "time": 195285, "beat": "3" }, { "time": 195600, "beat": "3" }, { "time": 195909, "beat": "3" }, { "time": 196229, "beat": "3" }, { "time": 196539, "beat": "2" }, { "time": 196848, "beat": "2" }, { "time": 197152, "beat": "1" }, { "time": 197461, "beat": "2" }, { "time": 197771, "beat": "3" }, { "time": 198075, "beat": "3" }, { "time": 198389, "beat": "3" }, { "time": 198693, "beat": "2" }, { "time": 199003, "beat": "3" }, { "time": 199312, "beat": "2" }, { "time": 199616, "beat": "3" }, { "time": 199941, "beat": "2" }, { "time": 200251, "beat": "3" }, { "time": 200555, "beat": "3" }, { "time": 200859, "beat": "3" }, { "time": 201163, "beat": "3" }, { "time": 201472, "beat": "2" }, { "time": 201787, "beat": "1" }, { "time": 202091, "beat": "2" }, { "time": 202400, "beat": "2" }, { "time": 202704, "beat": "2" }, { "time": 203008, "beat": "2" }, { "time": 203312, "beat": "3" }, { "time": 203627, "beat": "3" }, { "time": 203947, "beat": "3" }, { "time": 204256, "beat": "3" }, { "time": 204565, "beat": "2" }, { "time": 204885, "beat": "3" }, { "time": 205189, "beat": "3" }, { "time": 205493, "beat": "3" }, { "time": 205808, "beat": "3" }, { "time": 206112, "beat": "2" }, { "time": 206432, "beat": "3" }, { "time": 206736, "beat": "2" }, { "time": 207045, "beat": "1" }, { "time": 207365, "beat": "3" }, { "time": 207669, "beat": "3" }, { "time": 207973, "beat": "3" }, { "time": 208283, "beat": "3" }, { "time": 208597, "beat": "3" }, { "time": 208912, "beat": "3" }, { "time": 209221, "beat": "3" }, { "time": 209531, "beat": "2" }, { "time": 209840, "beat": "2" }, { "time": 210155, "beat": "3" }, { "time": 210469, "beat": "2" }, { "time": 210779, "beat": "3" }, { "time": 211083, "beat": "3" }, { "time": 211387, "beat": "3" }, { "time": 211701, "beat": "3" }, { "time": 212016, "beat": "3" }, { "time": 212320, "beat": "2" }, { "time": 212624, "beat": "2" }, { "time": 212944, "beat": "2" }, { "time": 213264, "beat": "1" }, { "time": 213573, "beat": "3" }, { "time": 213893, "beat": "2" }, { "time": 214197, "beat": "3" }, { "time": 214501, "beat": "3" }, { "time": 214811, "beat": "3" }, { "time": 215131, "beat": "1" }, { "time": 215445, "beat": "1" }, { "time": 215749, "beat": "1" }, { "time": 216053, "beat": "3" }, { "time": 216357, "beat": "3" }, { "time": 216672, "beat": "3" }, { "time": 216987, "beat": "2" }, { "time": 217291, "beat": "3" }, { "time": 217611, "beat": "3" }, { "time": 217931, "beat": "2" }, { "time": 218235, "beat": "3" }, { "time": 218539, "beat": "2" }, { "time": 218859, "beat": "3" }, { "time": 219168, "beat": "3" }, { "time": 219488, "beat": "3" }, { "time": 219803, "beat": "2" }, { "time": 220112, "beat": "2" }, { "time": 220432, "beat": "2" }, { "time": 220773, "beat": "3" }, { "time": 221125, "beat": "1" }, { "time": 221467, "beat": "1" }, { "time": 221781, "beat": "2" }, { "time": 222091, "beat": "3" }, { "time": 222395, "beat": "1" }, { "time": 222709, "beat": "1" }, { "time": 223099, "beat": "1" }] }]; var songsList = [{ "name": "Ode to Joy\r\nBeethoven", "bpm": 220, "pitchLevel": 0, "bitsPerPage": 16, "isComposed": false, "songNotes": [{ "time": 1432, "key": "Key6" }, { "time": 1855, "key": "Key6" }, { "time": 2305, "key": "Key7" }, { "time": 2788, "key": "Key8" }, { "time": 3216, "key": "Key8" }, { "time": 3666, "key": "Key7" }, { "time": 4122, "key": "Key6" }, { "time": 4567, "key": "Key5" }, { "time": 5027, "key": "Key4" }, { "time": 5479, "key": "Key4" }, { "time": 5937, "key": "Key5" }, { "time": 6397, "key": "Key6" }, { "time": 6864, "key": "Key6" }, { "time": 7583, "key": "Key5" }, { "time": 7820, "key": "Key5" }, { "time": 8816, "key": "Key6" }, { "time": 9289, "key": "Key6" }, { "time": 9778, "key": "Key7" }, { "time": 10205, "key": "Key8" }, { "time": 10672, "key": "Key8" }, { "time": 11108, "key": "Key7" }, { "time": 11564, "key": "Key6" }, { "time": 12000, "key": "Key5" }, { "time": 12455, "key": "Key4" }, { "time": 12911, "key": "Key4" }, { "time": 13339, "key": "Key5" }, { "time": 13785, "key": "Key6" }, { "time": 14370, "key": "Key5" }, { "time": 15131, "key": "Key4" }, { "time": 15341, "key": "Key4" }, { "time": 16318, "key": "Key5" }, { "time": 16760, "key": "Key5" }, { "time": 17243, "key": "Key6" }, { "time": 17711, "key": "Key4" }, { "time": 18164, "key": "Key5" }, { "time": 18607, "key": "Key6" }, { "time": 18840, "key": "Key7" }, { "time": 19107, "key": "Key6" }, { "time": 19556, "key": "Key4" }, { "time": 20007, "key": "Key5" }, { "time": 20428, "key": "Key6" }, { "time": 20634, "key": "Key7" }, { "time": 20915, "key": "Key6" }, { "time": 21375, "key": "Key5" }, { "time": 21859, "key": "Key4" }, { "time": 22325, "key": "Key5" }, { "time": 22818, "key": "Key1" }, { "time": 23809, "key": "Key6" }, { "time": 24259, "key": "Key6" }, { "time": 24725, "key": "Key7" }, { "time": 25156, "key": "Key8" }, { "time": 25597, "key": "Key8" }, { "time": 26039, "key": "Key7" }, { "time": 26496, "key": "Key6" }, { "time": 26950, "key": "Key5" }, { "time": 27413, "key": "Key4" }, { "time": 27882, "key": "Key4" }, { "time": 28309, "key": "Key5" }, { "time": 28830, "key": "Key6" }, { "time": 29319, "key": "Key5" }, { "time": 30092, "key": "Key4" }, { "time": 30343, "key": "Key4" }], "fromLibrary": true }]; var isDebug = false; var cube; var sphere; var face1; var face2; var face3; var globalSpeed = 20; var rotationSpeedX = 0; var rotationSpeedY = 0; var rotationSpeedZ = 0; var currentRotationAngle = 0; var fullLog = []; var fpsText; var lastTick; var frameCount; var debugText; var cubeManager; // Removed drag-related variables - using tap controls now var backgroundManager; var gateManager; var targetManager; var ball; var runner; var borderLimitAngle = Math.PI * 0.08; var gateLimitAngle = Math.PI * 0.2; var gateUniqueId = 0; // Function to get next gate ID function getNextGateId() { return gateUniqueId++; } /***********************************************************************************/ /***************************** GAME INITIALIZATION *********************************/ /***********************************************************************************/ function gameInitialize() { // Initialize background manager first (so it's behind other elements) backgroundManager = new BackgroundManager(); game.addChild(backgroundManager); cube = new Cube(1, 1, 1); cube.x = 2048 * 0.5; // Center horizontally cube.y = 2732 / 2; // Center vertically cube.z = 0; cube.visible = false; game.addChild(cube); cube.rotate3D(Math.PI * 0.125, -Math.PI * 0.125, 0); sphere = new Sphere(); sphere.z = 0; sphere.alpha = 0; // Set speeds to zero to stop movement sphere.speedX = 0; sphere.speedY = 0; sphere.speedZ = 0; game.addChild(sphere); // Initialize sphere at center position updateSphereSnapPosition(snapPositions.center); // Initialize cube manager cubeManager = new CubeManager(); //game.addChild(cubeManager); // Initialize gate manager gateManager = new GateManager(); game.addChild(gateManager); // Initialize target manager targetManager = new TargetManager(); //game.addChild(targetManager); // Create and position ball ball = new Ball(); ball.x = 1024; ball.y = 2000; ball.alpha = true; game.addChild(ball); runner = new Runner(); runner.x = 1024; runner.y = 2000; game.addChild(runner); if (isDebug) { var debugMarker = LK.getAsset('debugMarker', { anchorX: 0.5, anchorY: 0.5, x: 2048 * 0.5, y: 2732 / 2 }); game.addChild(debugMarker); fpsText = new Text2('FPS: 0', { size: 50, fill: 0xFFFFFF }); // Position FPS text at the bottom-right corner fpsText.anchor.set(1, 1); // Anchor to the bottom-right LK.gui.bottomRight.addChild(fpsText); // Update FPS display every second lastTick = Date.now(); frameCount = 0; // Debug text to display cube information debugText = new Text2('Debug Info', { size: 50, fill: 0xFFFFFF }); debugText.anchor.set(0.5, 0); // Anchor to the bottom-right LK.gui.top.addChild(debugText); // Create sound test button var soundTestButton = new Container(); var buttonBg = LK.getAsset('line', { anchorX: 0.5, anchorY: 0.5, scaleX: 50, scaleY: 15, tint: 0x333333 }); soundTestButton.addChild(buttonBg); var buttonText = new Text2('SOUND TEST', { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); soundTestButton.addChild(buttonText); // Position at top right soundTestButton.x = -100; soundTestButton.y = 50; LK.gui.topRight.addChild(soundTestButton); // Add click handler soundTestButton.down = function () { // Play all key sounds with 600ms delay for (var i = 0; i <= 14; i++) { (function (index) { LK.setTimeout(function () { LK.getSound('key' + index).play(); }, index * 600); })(i); } }; } } /***********************************************************************************/ /******************************** MAIN GAME LOOP ***********************************/ /***********************************************************************************/ game.update = function () { // Rotate simpleFace in 3D on each game update rotationSpeedX += globalSpeed * Math.PI * 0.006; rotationSpeedY += 0 * Math.PI * 0.125 * 0.02; rotationSpeedZ += 0 * Math.PI * 0.125 * 0.02; // Original cube movement commented out - now handled by cubeManager // cube.x += cube.speedX; // cube.y += cube.speedY; // cube.z += cube.speedZ; // if (cube.x <= 100 || cube.x >= 2048 - 100) { // cube.speedX *= -1; // } // if (cube.z <= -250 || cube.z >= 1000) { // cube.speedZ *= -1; // } // if (cube.y <= 100 || cube.y >= 2732 - 100) { // cube.speedY *= -1; // } sphere.rotate3D(rotationSpeedX, rotationSpeedY + currentRotationAngle, rotationSpeedZ); if (isDebug) { debugText.setText("X: " + Math.round(cube.x) + ", Y: " + Math.round(cube.y) + ", Z: " + Math.round(cube.z) + ", R: " + cube.rotation.toFixed(2)); // FPS var now = Date.now(); frameCount++; if (now - lastTick >= 1000) { // Update every second fpsText.setText('FPS: ' + frameCount); frameCount = 0; lastTick = now; } } // Update cube manager //cubeManager.update(); // Update background manager //backgroundManager.update(); // Update gate manager //gateManager.update(); // Update target manager //targetManager.update(); }; // Define magnetic snap positions var snapPositions = { left: 0, center: 1, right: 2 }; // Current snap position (start at center) var currentSnapPosition = snapPositions.center; // Snap threshold for switching positions (percentage of screen width) var snapThreshold = 0.15; // 15% of screen width // Function to update sphere position based on snap function updateSphereSnapPosition(snapPos) { currentSnapPosition = snapPos; // Define three fixed positions: left, center, right var leftAngle = -Math.PI * 0.5 + gateLimitAngle; var centerAngle = -Math.PI * 0.5 + Math.PI / 2; var rightAngle = -Math.PI * 0.5 + Math.PI - gateLimitAngle; var targetAngle = centerAngle; if (snapPos === snapPositions.left) { targetAngle = leftAngle; } else if (snapPos === snapPositions.center) { targetAngle = centerAngle; } else if (snapPos === snapPositions.right) { targetAngle = rightAngle; } // Calculate position on the ellipse path var centerX = 1024; var centerY = 1366; var radiusX = 924; var radiusY = 634; // Calculate new position sphere.x = centerX + radiusX * Math.cos(targetAngle + Math.PI * 0.5); sphere.y = centerY + radiusY * Math.sin(targetAngle + Math.PI * 0.5); // Apply rotation based on position var rotationMap = { 0: -0.5, // left 1: 0, // center 2: 0.5 // right }; currentRotationAngle = rotationMap[snapPos] * Math.PI * 0.5; sphere.rotate3D(Math.PI * 0.5, Math.PI * 0.5 + currentRotationAngle, 0); } // Function to animate sphere to new snap position function animateToSnapPosition(snapPos) { // Check if we need to pass through center (moving from left to right or right to left) var needsIntermediateStep = false; if (currentSnapPosition === snapPositions.left && snapPos === snapPositions.right || currentSnapPosition === snapPositions.right && snapPos === snapPositions.left) { needsIntermediateStep = true; } // If we need intermediate step, first move to center if (needsIntermediateStep) { // Define three fixed positions: left, center, right var leftAngle = -Math.PI * 0.5 + gateLimitAngle; var centerAngle = -Math.PI * 0.5 + Math.PI / 2; var rightAngle = -Math.PI * 0.5 + Math.PI - gateLimitAngle; // Calculate position on the ellipse path var centerX = 1024; var centerY = 1366; var radiusX = 924; var radiusY = 634; // Calculate center position (intermediate step) var centerPosX = centerX + radiusX * Math.cos(centerAngle + Math.PI * 0.5); var centerPosY = centerY + radiusY * Math.sin(centerAngle + Math.PI * 0.5); // Animate to center first tween(sphere, { x: centerPosX, y: centerPosY }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { // After reaching center, continue to final destination performSnapAnimation(snapPos); } }); // Update rotation for center position currentRotationAngle = 0; } else { // Direct movement (no intermediate step needed) performSnapAnimation(snapPos); } } // Helper function to perform the actual snap animation function performSnapAnimation(snapPos) { currentSnapPosition = snapPos; // Define three fixed positions: left, center, right var leftAngle = -Math.PI * 0.5 + gateLimitAngle; var centerAngle = -Math.PI * 0.5 + Math.PI / 2; var rightAngle = -Math.PI * 0.5 + Math.PI - gateLimitAngle; var targetAngle = centerAngle; if (snapPos === snapPositions.left) { targetAngle = rightAngle; } else if (snapPos === snapPositions.center) { targetAngle = centerAngle; } else if (snapPos === snapPositions.right) { targetAngle = leftAngle; } // Calculate position on the ellipse path var centerX = 1024; var centerY = 1366; var radiusX = 924; var radiusY = 634; // Calculate target position var targetX = centerX + radiusX * Math.cos(targetAngle + Math.PI * 0.5); var targetY = centerY + radiusY * Math.sin(targetAngle + Math.PI * 0.5); // Apply rotation based on position var rotationMap = { 0: -0.5, // left 1: 0, // center 2: 0.5 // right }; var targetRotation = rotationMap[snapPos] * Math.PI * 0.5; // Animate sphere position tween(sphere, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeInOut }); // Update rotation angle for continuous rotation currentRotationAngle = targetRotation; } // Add game event handlers for sphere control game.down = function (x, y, obj) { // Divide screen into halves var screenWidth = 2048; var screenCenter = screenWidth / 2; // Check which half of the screen was tapped if (x < screenCenter) { // Tapped left half - move to left lane animateToSnapPosition(snapPositions.left); } else { // Tapped right half - move to right lane animateToSnapPosition(snapPositions.right); } }; game.move = function (x, y, obj) { // Empty - no longer needed for tap controls }; game.up = function (x, y, obj) { // On release, return to center lane animateToSnapPosition(snapPositions.center); }; gameInitialize(); // Play track_001 music when game starts LK.playMusic('track_01'); // test gate /* var testGate = new Gate(); var newScale = 1; testGate.scaleX = newScale; testGate.scaleY = newScale; testGate.gateAsset.scaleX = newScale; testGate.gateAsset.scaleY = newScale; testGate.boundingBox.scaleX = newScale; testGate.boundingBox.scaleY = newScale; testGate.boundingBox.alpha = 0.3; game.addChild(testGate); */
===================================================================
--- original.js
+++ change.js
@@ -117,21 +117,49 @@
self.update = function () {
var now = Date.now();
var elapsed = now - self.bgAnimStartTime;
var resetTriggered = false;
+ // Get current energy level from gates
+ var currentEnergy = 0.3; // Default energy
+ if (gateManager && gateManager.gates.length > 0) {
+ // Find the closest gate to player
+ var closestGate = null;
+ var closestScale = 0;
+ for (var g = 0; g < gateManager.gates.length; g++) {
+ var gate = gateManager.gates[g];
+ if (gate.gateAsset.scaleX > closestScale) {
+ closestScale = gate.gateAsset.scaleX;
+ closestGate = gate;
+ }
+ }
+ if (closestGate && closestGate.energy) {
+ currentEnergy = closestGate.energy;
+ }
+ }
+ // Adjust animation speed based on energy
+ var energyMultiplier = 1 + currentEnergy * 2; // Speed up to 3x based on energy
for (var i = 0; i < self.backgrounds.length; i++) {
var bg = self.backgrounds[i];
// Make the scale speed increase as the scale increases (e.g. exponential or quadratic growth)
//var scaleMultiplier = bg.scaleX * self.bgAnimationAcceleration;
//bg.scaleX += self.bgAnimationSpeed * scaleMultiplier;
- bg.scaleX += self.bgAnimationSpeed * bg.scaleX;
+ bg.scaleX += self.bgAnimationSpeed * bg.scaleX * energyMultiplier;
bg.scaleY = bg.scaleX;
if (bg.scaleX > 3.0) {
bg.scaleX = 0.12; //self.bgInitialScales[i];
bg.scaleY = bg.scaleX;
}
//bg.alpha = Math.min(1, bg.scaleX + 0.66);
- bg.tint = 0x1697b8; // 0x33FF33;
+ // Tint based on energy level
+ var energyTint = 0x1697b8;
+ if (currentEnergy > 0.4) {
+ // High energy - warmer color
+ energyTint = 0xFF6B35;
+ } else if (currentEnergy < 0.2) {
+ // Low energy - cooler color
+ energyTint = 0x0066CC;
+ }
+ bg.tint = energyTint;
}
};
return self;
});
@@ -176,8 +204,36 @@
if (!self.lastIntersectingGates[gateId] && currentIntersecting) {
// Mark gate as being destroyed to prevent multiple triggers
if (!gate.isDestroying) {
gate.isDestroying = true;
+ // Create particle burst effect
+ var particleCount = 8 + Math.floor(gate.intensity / 5); // More particles for higher intensity
+ for (var p = 0; p < particleCount; p++) {
+ var particle = new Particle();
+ particle.x = gate.boundingBox.x;
+ particle.y = gate.boundingBox.y;
+ // Random velocity
+ var angle = Math.PI * 2 / particleCount * p + Math.random() * 0.5;
+ var speed = 5 + Math.random() * 5 + gate.energy * 10; // Faster for high energy
+ particle.velocityX = Math.cos(angle) * speed;
+ particle.velocityY = Math.sin(angle) * speed;
+ // Set particle color to match gate
+ particle.tint = gate.gateColor;
+ // Add to game (temporary container would be better)
+ game.addChild(particle);
+ // Update particle in a simple way
+ var updateParticle = function updateParticle(part) {
+ var _tick = function tick() {
+ if (!part.update()) {
+ part.destroy();
+ } else {
+ LK.setTimeout(_tick, 16); // ~60fps
+ }
+ };
+ _tick();
+ };
+ updateParticle(particle);
+ }
// Animate scale down
tween(gate, {
scaleX: 0,
scaleY: 0
@@ -190,9 +246,9 @@
}
});
}
// Play the sound based on the gate's assigned key
- if (false && gate.noteKey) {
+ if (gate.noteKey) {
// Extract the number from the key (e.g., "Key6" -> "6")
var keyNumber = gate.noteKey.replace('Key', '');
var soundKey = 'key' + keyNumber;
// Play the corresponding sound
@@ -544,20 +600,27 @@
// Animation timing
self.gateAnimStartTime = Date.now();
self.gateAnimationSpeed = globalSpeed / 1000; // Same as background
// Song timing properties
- self.currentSong = songListV2[0];
+ self.currentSong = songListV3[0];
self.songStartTime = Date.now();
self.currentNoteIndex = 0;
self.noteSpawnScale = 0.12; // Initial scale for new gates matching smallest tore
self.lastGateAngle = null; // Track last gate angle for path continuity
+ // Time offset for gate travel (ms) - time for gate to reach player
+ self.gateReachTime = 2500; // Approximately 2.5 seconds
// Spawn a single gate at current time
self.spawnGateAtTime = function () {
- // Get the current beat value
- var beatValue = null;
+ // Get the current beat data
+ var beatData = null;
if (self.currentNoteIndex < self.currentSong.songBeats.length) {
- beatValue = self.currentSong.songBeats[self.currentNoteIndex].beat;
+ beatData = self.currentSong.songBeats[self.currentNoteIndex];
}
+ // Get beat value and enhanced properties
+ var beatValue = beatData ? beatData.b : 1;
+ var intensity = beatData ? beatData.i : 10;
+ var pitch = beatData ? beatData.p : 2000;
+ var energy = beatData ? beatData.e : 0.3;
// Map beat to key for color selection
var keyNumber = parseInt(beatValue, 10) || 1; // Default to 1 if parse fails
var noteKey = 'Key' + keyNumber;
var keyColor = keyColorMap[noteKey] || currentColor; // Default to currentColor if key not found
@@ -571,29 +634,49 @@
// Assign unique ID to gate
gate.gateId = getNextGateId();
// Store the note key for this gate
gate.noteKey = noteKey;
+ // Store enhanced properties
+ gate.intensity = intensity;
+ gate.pitch = pitch;
+ gate.energy = energy;
// Add rotation to the gate similar to sphere movement limits
// Define three fixed positions: left, center, right
var leftAngle = -Math.PI * 0.5 + gateLimitAngle;
var centerAngle = -Math.PI * 0.5 + Math.PI / 2;
var rightAngle = -Math.PI * 0.5 + Math.PI - gateLimitAngle;
- // Determine gate position based on beat value (1=left, 2=center, 3=right)
- var gatePosition = keyNumber - 1; // Convert beat (1,2,3) to position (0,1,2)
- var fixedAngle = centerAngle;
- if (gatePosition === 0) {
- fixedAngle = leftAngle;
- } else if (gatePosition === 1) {
- fixedAngle = centerAngle;
- } else if (gatePosition === 2) {
- fixedAngle = rightAngle;
+ // Calculate gate angle based on beat and pitch
+ var baseAngle = centerAngle;
+ if (beatValue === 1) {
+ baseAngle = leftAngle;
+ } else if (beatValue === 2) {
+ baseAngle = centerAngle;
+ } else if (beatValue === 3) {
+ baseAngle = rightAngle;
}
+ // Add slight variation based on pitch (higher pitch = slight clockwise rotation)
+ var pitchVariation = (pitch - 2000) / 2000 * 0.1; // ±10% variation
+ var fixedAngle = baseAngle + pitchVariation;
+ // Ensure angle stays within bounds
+ if (fixedAngle < leftAngle) fixedAngle = leftAngle;
+ if (fixedAngle > rightAngle) fixedAngle = rightAngle;
// Store this angle for the next gate
self.lastGateAngle = fixedAngle;
// Set the direction angle for this gate
gate.directionAngle = fixedAngle;
// Apply rotation to gate asset
gate.gateAsset.rotation = fixedAngle;
+ // Apply visual effects based on intensity
+ var intensityScale = 1 + intensity / 30 * 0.3; // Scale up to 30% based on intensity
+ gate.gateAsset.scaleX *= intensityScale;
+ gate.gateAsset.scaleY *= intensityScale;
+ // Apply glow effect based on energy
+ var glowTint = 0xFFFFFF;
+ if (energy > 0.4) {
+ // High energy - brighter tint
+ glowTint = 0xFFFFFF;
+ gate.gateAsset.alpha = Math.min(1, gate.gateAsset.alpha + energy * 0.3);
+ }
self.gates.push(gate);
self.addChild(gate);
};
// Update gates animation
@@ -602,9 +685,10 @@
var songElapsed = now - self.songStartTime;
// Check if we need to spawn a new gate based on song timing
if (self.currentNoteIndex < self.currentSong.songBeats.length) {
var nextBeat = self.currentSong.songBeats[self.currentNoteIndex];
- if (songElapsed >= nextBeat.time) {
+ // Spawn gate early so it reaches player at the right time
+ if (songElapsed >= nextBeat.t - self.gateReachTime) {
// Spawn a new gate for this beat
self.spawnGateAtTime();
self.currentNoteIndex++;
}
@@ -635,9 +719,9 @@
// Check if song has ended and restart
self.checkSongEnd = function () {
if (self.currentNoteIndex >= self.currentSong.songBeats.length) {
// All beats have been spawned, check if we should restart
- var lastBeatTime = self.currentSong.songBeats[self.currentSong.songBeats.length - 1].time;
+ var lastBeatTime = self.currentSong.songBeats[self.currentSong.songBeats.length - 1].t;
var songElapsed = Date.now() - self.songStartTime;
// Wait a bit after the last beat before restarting
if (songElapsed > lastBeatTime + 5000) {
self.resetSong();
@@ -654,8 +738,47 @@
};
return self;
});
/***********************************************************************************/
+/********************************** PARTICLE CLASS *********************************/
+/***********************************************************************************/
+var Particle = Container.expand(function () {
+ var self = Container.call(this);
+ // Create particle asset
+ var particleGraphics = self.attachAsset('trail', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ alpha: 1
+ });
+ // Initialize particle properties
+ self.velocityX = 0;
+ self.velocityY = 0;
+ self.lifetime = 0;
+ self.maxLifetime = 1000; // 1 second
+ self.startTime = Date.now();
+ // Update particle
+ self.update = function () {
+ var elapsed = Date.now() - self.startTime;
+ if (elapsed > self.maxLifetime) {
+ return false; // Signal to remove particle
+ }
+ // Update position
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ // Fade out over lifetime
+ var progress = elapsed / self.maxLifetime;
+ self.alpha = 1 - progress;
+ // Scale down
+ var scale = (1 - progress * 0.5) * 0.5;
+ self.scaleX = scale;
+ self.scaleY = scale;
+ return true; // Still alive
+ };
+ return self;
+});
+/***********************************************************************************/
/********************************** RUNNER CLASS ***********************************/
/***********************************************************************************/
var Runner = Container.expand(function () {
var self = Container.call(this);
remove background
remove background
Futuristic speaker in the shape of a white orb. Face view
white video camera icon
landscape of a furturistic world by night
a white music note
white sparkles emiting from the center. back background
clean red-violet beam from above
button in the shape of a protorealistic holographic futuristc Rectangle . Front view.
above the clouds by a bright night, no visible moon Photorealistic
White Clef de sol
A 20 nodes straight metalic lock chain. High definition. In-Game asset. 2d. High contrast. No shadows
a closed metalic padlock. No visible key hole.
white menu icon
in white