User prompt
when detecting player mouth open, make the runner (and ball) jump ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
show Ey Tilt only in debug mode, and change its fill to yellow
User prompt
angle goes from -3 to 3; it should be more angle between the line made by the two eyes and the horizontal axe
User prompt
add a text with the current eyes tilt angle
User prompt
Ok, add a range for 'zero' angle (center) and invert current left/right tilt angle
User prompt
use eyes line angle to tilt left/right ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
Use facekit for left/right control ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
ignore global down events while !songStarted
User prompt
also prevent BackgroundManager from updating while !songStarted
User prompt
prevent runner and gatemanager from updating while !songStarted
Code edit (1 edits merged)
Please save this source code
User prompt
create a class for start button; only start song when start button is pressed and has fade out ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a global songStarted = false;
Code edit (2 edits merged)
Please save this source code
User prompt
in spawnGateAtTime, take into account the time the gate need to reach the player position.
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'facekit.stop is not a function' in or related to this line: 'facekit.stop();' Line Number: 274
User prompt
facekit tracking should be off by default, and toggle on when pressing the camera icon ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
add a camera class; it shows the camera asset at top righ of screen; when pressed, it toggles camera (facekit) on ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (2 edits merged)
Please save this source code
User prompt
call `self.scaleX *= -1;` only every 60 ticks
Code edit (1 edits merged)
Please save this source code
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
/**** * 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; 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.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; } }; 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; // 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 (false && 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; }); /***********************************************************************************/ /******************************* 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 // 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 = songListV2[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 // Spawn a single gate at current time self.spawnGateAtTime = function () { // Get the current beat value var beatValue = null; if (self.currentNoteIndex < self.currentSong.songBeats.length) { beatValue = self.currentSong.songBeats[self.currentNoteIndex].beat; } // 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; // 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; } // 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; 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]; if (songElapsed >= nextBeat.time) { // 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].time; 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; }); /***********************************************************************************/ /********************************** 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 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; } }; 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); }); /**** * 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 center coordinates var centerX = 1024; var centerY = 1366; // 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" }] }]; var isDebug = false; 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; // 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); 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 gate manager gateManager = new GateManager(); game.addChild(gateManager); // 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; 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; sphere.rotate3D(rotationSpeedX, rotationSpeedY + currentRotationAngle, rotationSpeedZ); if (isDebug) { // FPS var now = Date.now(); frameCount++; if (now - lastTick >= 1000) { // Update every second fpsText.setText('FPS: ' + frameCount); frameCount = 0; lastTick = now; } } }; // 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 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 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 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); */
/****
* 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;
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.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;
}
};
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;
// 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 (false && 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;
});
/***********************************************************************************/
/******************************* 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
// 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 = songListV2[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
// Spawn a single gate at current time
self.spawnGateAtTime = function () {
// Get the current beat value
var beatValue = null;
if (self.currentNoteIndex < self.currentSong.songBeats.length) {
beatValue = self.currentSong.songBeats[self.currentNoteIndex].beat;
}
// 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;
// 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;
}
// 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;
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];
if (songElapsed >= nextBeat.time) {
// 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].time;
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;
});
/***********************************************************************************/
/********************************** 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 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;
}
};
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);
});
/****
* 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 center coordinates
var centerX = 1024;
var centerY = 1366;
// 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"
}]
}];
var isDebug = false;
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;
// 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);
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 gate manager
gateManager = new GateManager();
game.addChild(gateManager);
// 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;
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;
sphere.rotate3D(rotationSpeedX, rotationSpeedY + currentRotationAngle, rotationSpeedZ);
if (isDebug) {
// FPS
var now = Date.now();
frameCount++;
if (now - lastTick >= 1000) {
// Update every second
fpsText.setText('FPS: ' + frameCount);
frameCount = 0;
lastTick = now;
}
}
};
// 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 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 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 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);
*/
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