User prompt
Remove the purple and pink hex codes from inside the displayed text in the tutorial. That is, do not include it in the displayed text. Only use it within the code itself.
User prompt
Modify the tutorial screen so that the shown synced notes and synced hold notes are not on top of the text.
User prompt
Create a short tutorial that explains the zones, controls, tap notes, hold notes and synced holds and synced taps and the colors associated with all of them and is accessible from the bottom of the song selection screen.
User prompt
When song is selected, pulse scale of song selection for tap feedback and remove song selection screen in a short timeout to allow pulse scale to complete and then go to countdown. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Adjust vertical spacing for song selection so that text isn’t overlapping
User prompt
Center songs on x axis on song selection screen and increase font size by25%
User prompt
Remove generated song from song selection
User prompt
After a song is over, stop playback and scanner and display results with a tap bringing player back to song select screen.
Code edit (1 edits merged)
Please save this source code
User prompt
increase the velocity of the yellow explosion particles and decrease the size ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
yellow particles in the explosion are appearing all on one side, they need to be interspersed through the entire explosion radius
User prompt
the yellow particles should be mixed evenly throughout the explosion particles and be smaller than the regular colored particles. add more yellow ones as well ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add some more explosion particles and color the new ones yellow
User prompt
increase the velocity of explosion particles and add varied scale ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
slow down the alpha fade of explosion particles and slightly increase velocity
User prompt
increase lifetime of note explosion particles
User prompt
both the start and end note of holds should explode in particles
User prompt
scanline should be on a layer higher than the all the notes
Code edit (1 edits merged)
Please save this source code
User prompt
Remove glowring initialization from note and hold notes
User prompt
Increase hold particle size
User prompt
Give notes a scale pulse to the beat after they reach full scale from scaling in. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a slight sine wave to stars upwards travel. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make it faster. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the star particle alpha pulse faster ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BackgroundParticle = Container.expand(function () { var self = Container.call(this); self.particleGraphics = null; self.speed = 0; self.initialScale = 1; self.baseAlpha = 0.1; self.initialX = 0; self.sineAmplitude = 0; self.sineFrequency = 0; self._startTwinkleAnimation = function () { tween.stop(self, { alpha: true }); var currentAlpha = self.alpha; var pulseDelta = self.baseAlpha * 0.4; var targetMinAlpha = Math.max(0.05, self.baseAlpha - pulseDelta); var targetMaxAlpha = Math.min(1.0, self.baseAlpha + pulseDelta); if (targetMaxAlpha - targetMinAlpha < 0.05) { if (self.baseAlpha < 0.15) { targetMaxAlpha = Math.min(1.0, self.baseAlpha + 0.1); } else if (self.baseAlpha > 0.85) { targetMinAlpha = Math.max(0.05, self.baseAlpha - 0.1); } if (targetMaxAlpha - targetMinAlpha < 0.05) { return; } } var nextTargetAlpha; if (self.alpha === self.baseAlpha || Math.abs(currentAlpha - targetMaxAlpha) < Math.abs(currentAlpha - targetMinAlpha)) { nextTargetAlpha = targetMinAlpha; } else { nextTargetAlpha = targetMaxAlpha; } var pulseDuration = 300 + Math.random() * 400; tween(self, { alpha: nextTargetAlpha }, { duration: pulseDuration, easing: tween.easeInOut, onFinish: function onFinish() { if (self && self._startTwinkleAnimation) { self._startTwinkleAnimation(); } } }); }; self.init = function () { tween.stop(self, { alpha: true }); var scale = 0.312 + Math.random() * 1.248; self.initialScale = scale; self.scale.set(scale); var colors = [0xff00ff, 0x00ffff, 0xffff00, 0xff0000, 0x00ff00, 0x0000ff, 0xffa500, 0xda70d6]; var color = colors[Math.floor(Math.random() * colors.length)]; if (self.particleGraphics) { self.particleGraphics.destroy(); } self.particleGraphics = self.attachAsset('starParticle', { anchorX: 0.5, anchorY: 0.5 }); self.particleGraphics.tint = color; self.speed = (0.5 + Math.random() * 1.5) * scale; self.x = Math.random() * GAME_WIDTH; self.initialX = self.x; self.sineAmplitude = 20 + Math.random() * 60; self.sineFrequency = 0.0015 + Math.random() * 0.003; self.y = GAME_HEIGHT + Math.random() * 100 + self.particleGraphics.height * scale; self.baseAlpha = 0.1 + Math.random() * 0.7; self.alpha = self.baseAlpha; self._startTwinkleAnimation(); }; self.updateParticle = function () { self.y -= self.speed; var yProgress = GAME_HEIGHT - self.y; var sineOffset = self.sineAmplitude * Math.sin(self.sineFrequency * yProgress); self.x = self.initialX + sineOffset; if (self.y < -self.particleGraphics.height * self.initialScale) { self.init(); self.y = GAME_HEIGHT + Math.random() * 50 + self.particleGraphics.height * self.initialScale; } }; self.init(); return self; }); var Note = Container.expand(function (noteData, spawnTime) { var self = Container.call(this); self.noteData = noteData; self.type = noteData.type; self.targetX = noteData.x; self.targetY = noteData.y; self.hitTime = noteData.time; self.duration = noteData.duration || 0; self.spawnTime = spawnTime; self.zone = noteData.x < GAME_WIDTH / 2 ? 'left' : 'right'; if (noteData.color && noteData.color === SYNC_NOTE_COLOR) { if (self.type === 'tap') { self.color = COLOR_SYNC_TAP; } else if (self.type === 'hold') { self.color = COLOR_SYNC_HOLD; } else { self.color = self.zone === 'left' ? COLOR_LEFT_ZONE : COLOR_RIGHT_ZONE; } } else { self.color = self.zone === 'left' ? COLOR_LEFT_ZONE : COLOR_RIGHT_ZONE; } self.active = true; self.isHit = false; self.isMissed = false; self.isSpawning = true; self.isHolding = false; self.holdSuccessfullyCompleted = false; self.holdParticles = []; self.lastParticleEmissionTime = 0; self.PARTICLE_EMISSION_INTERVAL = 50; self.holdStarted = false; self.beatPulseInterval = null; var assetName = self.type === 'hold' ? 'holdNoteCore' : 'noteCore'; self.noteGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.noteGraphics.tint = self.color; self._startBeatPulseAnimation = function () { if (!self || !self.active || self.isHit || self.isMissed || self.isSpawning) { tween.stop(self, { scaleX: true, scaleY: true }); return; } tween.stop(self, { scaleX: true, scaleY: true }); tween(self, { scaleX: 1.15, scaleY: 1.15 }, { duration: BEAT_DURATION_MS * 0.2, easing: tween.easeOut, onFinish: function onFinish() { if (self && self.active && !self.isHit && !self.isMissed && !self.isSpawning) { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: BEAT_DURATION_MS * 0.2, easing: tween.easeIn }); } } }); }; self._clearBeatPulseLoop = function () { if (self.beatPulseInterval) { LK.clearInterval(self.beatPulseInterval); self.beatPulseInterval = null; } tween.stop(self, { scaleX: true, scaleY: true }); }; self._initiateBeatPulseLoop = function () { self._clearBeatPulseLoop(); if (self && self.active && !self.isHit && !self.isMissed && !self.isSpawning) { self._startBeatPulseAnimation(); self.beatPulseInterval = LK.setInterval(function () { if (self && self.active && !self.isHit && !self.isMissed && !self.isSpawning) { self._startBeatPulseAnimation(); } else { self._clearBeatPulseLoop(); } }, BEAT_DURATION_MS); } }; self.x = self.targetX; self.y = self.targetY; self.alpha = 0; self.scaleX = 0.1; self.scaleY = 0.1; self.createHoldTrail = function () { var cycleTime = self.hitTime % SCANNER_CYCLE_DURATION; var scannerMovingUp = cycleTime < SCANNER_HALF_CYCLE; var direction = scannerMovingUp ? -1 : 1; var originalRequestedDuration = self.duration; var maxPossibleTrailPixelLength = originalRequestedDuration / SCANNER_HALF_CYCLE * PLAY_AREA_HEIGHT; var actualTrailPixelLength = maxPossibleTrailPixelLength; if (direction === -1) { if (self.y - actualTrailPixelLength < SCANNER_Y_MIN) { actualTrailPixelLength = self.y - SCANNER_Y_MIN; } } else { if (self.y + actualTrailPixelLength > SCANNER_Y_MAX) { actualTrailPixelLength = SCANNER_Y_MAX - self.y; } } actualTrailPixelLength = Math.max(0, actualTrailPixelLength); if (actualTrailPixelLength < maxPossibleTrailPixelLength) { if (PLAY_AREA_HEIGHT > 0 && SCANNER_HALF_CYCLE > 0) { self.duration = actualTrailPixelLength / PLAY_AREA_HEIGHT * SCANNER_HALF_CYCLE; } else if (actualTrailPixelLength === 0) { self.duration = 0; } } self.duration = Math.max(0, self.duration); var trailLine = self.attachAsset('holdTrail', { anchorX: 0.5, anchorY: 0 }); trailLine.tint = self.color; trailLine.alpha = 0.6; trailLine.height = actualTrailPixelLength; if (direction === -1) { trailLine.y = -actualTrailPixelLength; } else { trailLine.y = 0; } self.holdTrails.push(trailLine); self.endNote = self.attachAsset('noteCore', { anchorX: 0.5, anchorY: 0.5 }); self.endNote.tint = self.color; self.endNote.alpha = 0.8; self.endNote.scaleX = 0.7; self.endNote.scaleY = 0.7; self.endNote.y = actualTrailPixelLength * direction; self.endGlow = self.attachAsset('glowRing', { anchorX: 0.5, anchorY: 0.5 }); self.endGlow.tint = self.color; self.endGlow.alpha = 0.3; self.endGlow.scaleX = 0.5; self.endGlow.scaleY = 0.5; self.endGlow.y = actualTrailPixelLength * direction; }; self.holdTrails = []; if (self.type === 'hold' && self.duration > 0) { self.createHoldTrail(); } self.spawnIn = function () { self.isSpawning = true; tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.isSpawning = false; self._initiateBeatPulseLoop(); } }); }; self.showHitEffect = function () { self._clearBeatPulseLoop(); LK.getSound('hitSound').play(); self.explodeIntoParticles(); tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.active = false; self._clearBeatPulseLoop(); } }); }; self.startHoldEffect = function () { self._clearBeatPulseLoop(); LK.getSound('hitSound').play(); tween(self.noteGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(self.noteGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; self.showMissEffect = function () { self._clearBeatPulseLoop(); LK.getSound('missSound').play(); tween(self.noteGraphics, { tint: 0xff0000 }, { duration: 150, onFinish: function onFinish() { tween(self, { alpha: 0.3 }, { duration: 300, onFinish: function onFinish() { self.active = false; self._clearBeatPulseLoop(); } }); } }); }; self.explodeIntoParticles = function () { var regularParticleCount = 10; var yellowParticleCount = 15; var totalParticles = regularParticleCount + yellowParticleCount; var particleSpecs = []; for (var r_idx = 0; r_idx < regularParticleCount; r_idx++) { particleSpecs.push({ color: self.color, finalScaleMin: 0.2, finalScaleRandom: 0.3, speedBase: 220, speedRandom: 160, tweenDuration: 1200 }); } for (var y_idx = 0; y_idx < yellowParticleCount; y_idx++) { particleSpecs.push({ color: 0xffff00, finalScaleMin: 0.0075, finalScaleRandom: 0.01, speedBase: 300, speedRandom: 200, tweenDuration: 1100 }); } for (var i = particleSpecs.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = particleSpecs[i]; particleSpecs[i] = particleSpecs[j]; particleSpecs[j] = temp; } for (var i = 0; i < totalParticles; i++) { var spec = particleSpecs[i]; var particle = game.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); particle.tint = spec.color; particle.x = self.x; particle.y = self.y; var angle = i / totalParticles * Math.PI * 2; var speed = spec.speedBase + Math.random() * spec.speedRandom; var targetX = self.x + Math.cos(angle) * speed; var targetY = self.y + Math.sin(angle) * speed; var finalParticleScale = spec.finalScaleMin + Math.random() * spec.finalScaleRandom; tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: finalParticleScale, scaleY: finalParticleScale }, { duration: spec.tweenDuration, easing: tween.easeOut, onFinish: function (p_to_destroy) { return function () { if (p_to_destroy && p_to_destroy.destroy) { p_to_destroy.destroy(); } }; }(particle) }); } }; self.explodeEndNoteParticles = function () { if (!self.endNote) { return; } var regularParticleCount = 10; var yellowParticleCount = 15; var totalParticles = regularParticleCount + yellowParticleCount; var endNoteGlobalX = self.x; var endNoteGlobalY = self.y + self.endNote.y; var particleSpecs = []; for (var r_idx = 0; r_idx < regularParticleCount; r_idx++) { particleSpecs.push({ color: self.color, finalScaleMin: 0.2, finalScaleRandom: 0.3, speedBase: 220, speedRandom: 160, tweenDuration: 1200 }); } for (var y_idx = 0; y_idx < yellowParticleCount; y_idx++) { particleSpecs.push({ color: 0xffff00, finalScaleMin: 0.05, finalScaleRandom: 0.15, speedBase: 250, speedRandom: 180, tweenDuration: 1100 }); } for (var i = particleSpecs.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = particleSpecs[i]; particleSpecs[i] = particleSpecs[j]; particleSpecs[j] = temp; } for (var i = 0; i < totalParticles; i++) { var spec = particleSpecs[i]; var particle = game.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); particle.tint = spec.color; particle.x = endNoteGlobalX; particle.y = endNoteGlobalY; var angle = i / totalParticles * Math.PI * 2; var speed = spec.speedBase + Math.random() * spec.speedRandom; var targetX = endNoteGlobalX + Math.cos(angle) * speed; var targetY = endNoteGlobalY + Math.sin(angle) * speed; var finalParticleScale = spec.finalScaleMin + Math.random() * spec.finalScaleRandom; tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: finalParticleScale, scaleY: finalParticleScale }, { duration: spec.tweenDuration, easing: tween.easeOut, onFinish: function (p_to_destroy) { return function () { if (p_to_destroy && p_to_destroy.destroy) { p_to_destroy.destroy(); } }; }(particle) }); } }; self.updateHoldEffects = function (scannerCurrentY) { if (self.type === 'hold' && self.isHolding && self.active && !self.holdSuccessfullyCompleted && !self.isMissed) { var currentTime = Date.now(); if (currentTime - self.lastParticleEmissionTime > self.PARTICLE_EMISSION_INTERVAL) { self.lastParticleEmissionTime = currentTime; var trailStartY = self.y; var trailEndY = self.y + (self.endNote ? self.endNote.y : 0); var scannerIsOverTrail = self.endNote && scannerCurrentY >= Math.min(trailStartY, trailEndY) && scannerCurrentY <= Math.max(trailStartY, trailEndY); if (scannerIsOverTrail) { var particle = game.attachAsset('holdConnectionParticle', { anchorX: 0.5, anchorY: 0.5 }); particle.x = self.x; particle.y = scannerCurrentY; particle.tint = self.color; particle.alpha = 0.8; self.holdParticles.push(particle); tween(particle, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { if (particle && particle.destroy) { particle.destroy(); } var index = self.holdParticles.indexOf(particle); if (index > -1) { self.holdParticles.splice(index, 1); } } }); } } } }; self.cleanupHoldVisuals = function () { self.holdParticles.forEach(function (p) { if (p && p.destroy) { p.destroy(); } }); self.holdParticles = []; if (self.endNote && self.endNote.destroy) { self.endNote.destroy(); } if (self.endGlow && self.endGlow.destroy) { self.endGlow.destroy(); } self.endNote = null; self.endGlow = null; self.holdTrails.forEach(function (trail) { if (trail && trail.destroy) { trail.destroy(); } }); self.holdTrails = []; }; self.completeHold = function () { if (self.holdSuccessfullyCompleted || self.isMissed) { return; } self._clearBeatPulseLoop(); self.holdSuccessfullyCompleted = true; self.isHolding = false; self.explodeIntoParticles(); if (self.type === 'hold') { self.explodeEndNoteParticles(); } self.cleanupHoldVisuals(); tween(self, { alpha: 0 }, { duration: 100, delay: 100, onFinish: function onFinish() { self.active = false; self._clearBeatPulseLoop(); } }); }; self.failHold = function () { if (self.isMissed || self.holdSuccessfullyCompleted) { return; } self._clearBeatPulseLoop(); self.isMissed = true; self.isHolding = false; self.showMissEffect(); self.cleanupHoldVisuals(); }; return self; }); var Scanner = Container.expand(function () { var self = Container.call(this); self.glow = self.attachAsset('scannerGlow', { anchorX: 0, anchorY: 0.5 }); self.glow.alpha = 0.2; self.line = self.attachAsset('scannerLine', { anchorX: 0, anchorY: 0.5 }); self.x = 0; self.isMovingUp = true; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var SAFETY_MARGIN_TOP_PERCENT = 0.05; var SAFETY_MARGIN_BOTTOM_PERCENT = 0.15; var SAFETY_MARGIN_SIDES_PERCENT = 0.10; var BPM = 120; var BEAT_DURATION_MS = 60 / BPM * 1000; var SCANNER_Y_MIN = GAME_HEIGHT * SAFETY_MARGIN_TOP_PERCENT; var SCANNER_Y_MAX = GAME_HEIGHT * (1 - SAFETY_MARGIN_BOTTOM_PERCENT); var PLAY_AREA_HEIGHT = SCANNER_Y_MAX - SCANNER_Y_MIN; var NOTE_SPAWN_AHEAD_MS = 800; var PERFECT_HIT_RATIO = 0.4; var POINTS_PERFECT_TAP = 30; var POINTS_GOOD_TAP = 15; var POINTS_PERFECT_HOLD_START = 10; var POINTS_GOOD_HOLD_START = 5; var ACCURACY_POPUP_DURATION = 750; var ACCURACY_POPUP_Y_OFFSET = -100; var ACCURACY_POPUP_FONT_SIZE = 80; var PERFECT_POPUP_COLOR = 0x00FF00; var GOOD_POPUP_COLOR = 0xFFFF00; var SCANNER_CYCLE_DURATION = 4000; var SCANNER_HALF_CYCLE = SCANNER_CYCLE_DURATION / 2; var HIT_TOLERANCE_PX_FOR_HOLD_END = 100; var HOLD_END_GRACE_PERIOD_MS = 250; var GAME_STATE_TITLE = 'title'; var GAME_STATE_SONG_SELECT = 'songSelect'; var GAME_STATE_PLAYING = 'playing'; var GAME_STATE_RESULTS = 'results'; var currentGameState = GAME_STATE_TITLE; var resultsScreen = {}; var activeHoldNotes = {}; var scoreTxt; var countdownTxt; var scanner; var scannerIsMovingUp = true; var gameStartTime; var gameStarted = false; var notes = []; var currentSongData; var spawnedNotes = []; var leftZone, rightZone; var isDragging = false; var dragStartX, dragStartY; var currentTrail = []; var backgroundParticles = []; var NUM_BACKGROUND_PARTICLES = 100; var titleScreen = {}; var songSelectScreen = {}; var songSelectScrollY = 0; var maxScrollY = 0; var isDraggingSongList = false; var dragStartYSongList = 0; var SONG_ITEM_HEIGHT = 200; var COLOR_LEFT_ZONE = 0x0077FF; var COLOR_RIGHT_ZONE = 0xFF3333; var COLOR_SYNC_TAP = 0xFF69B4; var COLOR_SYNC_HOLD = 0x9370DB; var SYNC_NOTE_COLOR = 0xFFA500; var PatternTemplates = { tapLeft: function tapLeft(startTime) { return [{ time: startTime, type: 'tap', zone: 'left' }]; }, tapRight: function tapRight(startTime) { return [{ time: startTime, type: 'tap', zone: 'right' }]; }, syncTap: function syncTap(startTime) { return [{ time: startTime, type: 'tap', zone: 'left' }, { time: startTime, type: 'tap', zone: 'right' }]; }, leftRightTaps: function leftRightTaps(startTime, spacing) { spacing = spacing || 500; return [{ time: startTime, type: 'tap', zone: 'left' }, { time: startTime + spacing, type: 'tap', zone: 'right' }]; }, rightLeftTaps: function rightLeftTaps(startTime, spacing) { spacing = spacing || 500; return [{ time: startTime, type: 'tap', zone: 'right' }, { time: startTime + spacing, type: 'tap', zone: 'left' }]; }, holdLeft: function holdLeft(startTime, duration) { duration = duration || 1000; return [{ time: startTime, type: 'hold', zone: 'left', duration: duration }]; }, holdRight: function holdRight(startTime, duration) { duration = duration || 1000; return [{ time: startTime, type: 'hold', zone: 'right', duration: duration }]; }, syncHold: function syncHold(startTime, duration) { duration = duration || 1000; return [{ time: startTime, type: 'hold', zone: 'left', duration: duration }, { time: startTime, type: 'hold', zone: 'right', duration: duration }]; }, tripletTaps: function tripletTaps(startTime, zone, spacing) { spacing = spacing || 167; return [{ time: startTime, type: 'tap', zone: zone }, { time: startTime + spacing, type: 'tap', zone: zone }, { time: startTime + spacing * 2, type: 'tap', zone: zone }]; }, alternatingTriplets: function alternatingTriplets(startTime, spacing) { spacing = spacing || 167; return [{ time: startTime, type: 'tap', zone: 'left' }, { time: startTime + spacing, type: 'tap', zone: 'right' }, { time: startTime + spacing * 2, type: 'tap', zone: 'left' }]; }, buildUp: function buildUp(startTime) { return [{ time: startTime, type: 'tap', zone: 'left' }, { time: startTime + 250, type: 'tap', zone: 'right' }, { time: startTime + 500, type: 'tap', zone: 'left' }, { time: startTime + 625, type: 'tap', zone: 'right' }, { time: startTime + 750, type: 'tap', zone: 'left' }, { time: startTime + 875, type: 'tap', zone: 'right' }]; } }; var SongGenerator = { generateSong: function generateSong(config) { var notes = []; var totalLength = config.totalLength || 202136; var startTime = config.startDelay || 2000; notes = this.generateZoneAwareSong(startTime, totalLength); notes.sort(function (a, b) { return a.time - b.time; }); return notes; }, generateZoneAwareSong: function generateZoneAwareSong(startTime, songTotalLength) { var notes = []; var currentTime = startTime; var zoneFreeTime = { left: startTime, right: startTime }; var MIN_SAME_ZONE_SPACING = 400; var MIN_DIFFERENT_ZONE_SPACING = 200; var MIN_SYNC_SPACING = 1000; var lastSyncTime = startTime - MIN_SYNC_SPACING; var sections = [{ start: 0, end: 16000, complexity: 'simple' }, { start: 16000, end: 48000, complexity: 'medium' }, { start: 48000, end: 72000, complexity: 'medium' }, { start: 72000, end: 104000, complexity: 'medium' }, { start: 104000, end: 128000, complexity: 'complex' }, { start: 128000, end: 160000, complexity: 'medium' }, { start: 160000, end: 184000, complexity: 'complex' }, { start: 184000, end: songTotalLength, complexity: 'simple' }]; for (var s = 0; s < sections.length; s++) { var section = sections[s]; var sectionStartTime = startTime + section.start; var sectionEndTime = startTime + section.end; if (sectionEndTime > startTime + songTotalLength) { sectionEndTime = startTime + songTotalLength; } if (sectionStartTime >= sectionEndTime) { continue; } currentTime = Math.max(currentTime, sectionStartTime); while (currentTime < sectionEndTime - 1000) { var pattern = this.selectPattern(section.complexity, zoneFreeTime, currentTime, lastSyncTime); var patternResult = this.placePattern(pattern, currentTime, zoneFreeTime, MIN_SAME_ZONE_SPACING, MIN_DIFFERENT_ZONE_SPACING, sectionEndTime); if (patternResult.notes.length > 0) { var allNotesFit = true; for (var ni = 0; ni < patternResult.notes.length; ni++) { if (patternResult.notes[ni].time + (patternResult.notes[ni].duration || 0) > sectionEndTime - 200) { allNotesFit = false; break; } } if (allNotesFit) { notes = notes.concat(patternResult.notes); currentTime = patternResult.nextTime; if (pattern.type === 'sync' || pattern.type === 'syncHold') { lastSyncTime = patternResult.notes[0].time; } } else { currentTime += 300; } } else { currentTime += 300; } if (currentTime >= sectionEndTime - 1000) { break; } } } return notes; }, selectPattern: function selectPattern(complexity, zoneFreeTime, currentTime, lastSyncTime) { var patterns = []; var MIN_SYNC_SPACING_FOR_SELECTION = 1000; if (complexity === 'simple') { patterns = [{ type: 'single', zone: 'left', duration: 800 }, { type: 'single', zone: 'right', duration: 800 }, { type: 'rest', duration: 1200 }, { type: 'rest', duration: 1200 }]; if (currentTime - lastSyncTime >= MIN_SYNC_SPACING_FOR_SELECTION + 200) { patterns.push({ type: 'sync', duration: 1000 }); } } else if (complexity === 'medium') { patterns = [{ type: 'hold', zone: 'right', holdDuration: 1000, duration: 700 }, { type: 'single', zone: 'left', duration: 600 }, { type: 'single', zone: 'right', duration: 600 }, { type: 'single', zone: 'left', duration: 600 }, { type: 'single', zone: 'right', duration: 600 }, { type: 'alternating', duration: 750 }, { type: 'rest', duration: 1000 }]; if (currentTime - lastSyncTime >= MIN_SYNC_SPACING_FOR_SELECTION) { patterns.push({ type: 'sync', duration: 800 }); patterns.push({ type: 'sync', duration: 800 }); } } else { patterns = [{ type: 'hold', zone: 'right', holdDuration: 1200, duration: 800 }, { type: 'alternating', duration: 800 }, { type: 'alternating', duration: 800 }, { type: 'single', zone: 'left', duration: 700 }, { type: 'single', zone: 'right', duration: 700 }, { type: 'single', zone: 'left', duration: 700 }, { type: 'single', zone: 'right', duration: 700 }]; if (currentTime - lastSyncTime >= MIN_SYNC_SPACING_FOR_SELECTION - 200) { patterns.push({ type: 'sync', duration: 600 }); patterns.push({ type: 'sync', duration: 600 }); patterns.push({ type: 'syncHold', holdDuration: 1200, duration: 900 }); } } return patterns[Math.floor(Math.random() * patterns.length)]; }, placePattern: function placePattern(pattern, requestedTime, zoneFreeTime, minSameZoneSpacing, minDiffZoneSpacing, sectionEndTime) { var notes = []; var earliestTime = requestedTime; var nextTimeAdvance = pattern.duration || 500; if (pattern.type === 'single') { earliestTime = Math.max(requestedTime, zoneFreeTime[pattern.zone]); if (earliestTime + (pattern.duration || 0) < sectionEndTime) { notes.push({ time: earliestTime, type: 'tap', zone: pattern.zone }); zoneFreeTime[pattern.zone] = earliestTime + minSameZoneSpacing; return { notes: notes, nextTime: earliestTime + nextTimeAdvance }; } } else if (pattern.type === 'sync') { earliestTime = Math.max(requestedTime, zoneFreeTime.left, zoneFreeTime.right); if (earliestTime + (pattern.duration || 0) < sectionEndTime) { notes.push({ time: earliestTime, type: 'tap', zone: 'left', color: SYNC_NOTE_COLOR }); notes.push({ time: earliestTime, type: 'tap', zone: 'right', color: SYNC_NOTE_COLOR }); zoneFreeTime.left = earliestTime + minSameZoneSpacing; zoneFreeTime.right = earliestTime + minSameZoneSpacing; return { notes: notes, nextTime: earliestTime + nextTimeAdvance }; } } else if (pattern.type === 'alternating') { var firstZone = Math.random() < 0.5 ? 'left' : 'right'; var secondZone = firstZone === 'left' ? 'right' : 'left'; var t1 = Math.max(requestedTime, zoneFreeTime[firstZone]); var t2 = Math.max(t1 + minDiffZoneSpacing, zoneFreeTime[secondZone]); if (t2 + (pattern.duration || 0) - (t2 - t1) < sectionEndTime) { notes.push({ time: t1, type: 'tap', zone: firstZone }); notes.push({ time: t2, type: 'tap', zone: secondZone }); zoneFreeTime[firstZone] = t1 + minSameZoneSpacing; zoneFreeTime[secondZone] = t2 + minSameZoneSpacing; return { notes: notes, nextTime: t1 + nextTimeAdvance }; } } else if (pattern.type === 'syncHold') { earliestTime = Math.max(requestedTime, zoneFreeTime.left, zoneFreeTime.right); var holdDuration = pattern.holdDuration || 1200; if (earliestTime + holdDuration < sectionEndTime) { notes.push({ time: earliestTime, type: 'hold', zone: 'left', duration: holdDuration, color: SYNC_NOTE_COLOR }); notes.push({ time: earliestTime, type: 'hold', zone: 'right', duration: holdDuration, color: SYNC_NOTE_COLOR }); zoneFreeTime.left = earliestTime + holdDuration + 200; zoneFreeTime.right = earliestTime + holdDuration + 200; return { notes: notes, nextTime: earliestTime + (pattern.duration || 800) }; } } else if (pattern.type === 'hold') { earliestTime = Math.max(requestedTime, zoneFreeTime[pattern.zone]); var holdDuration = pattern.holdDuration || 1500; if (earliestTime + holdDuration < sectionEndTime) { notes.push({ time: earliestTime, type: 'hold', zone: pattern.zone, duration: holdDuration }); var otherZone = pattern.zone === 'left' ? 'right' : 'left'; zoneFreeTime[pattern.zone] = earliestTime + holdDuration + 200; zoneFreeTime[otherZone] = Math.max(zoneFreeTime[otherZone], earliestTime + holdDuration + minDiffZoneSpacing); return { notes: notes, nextTime: earliestTime + nextTimeAdvance }; } } else if (pattern.type === 'rest') { return { notes: [], nextTime: requestedTime + (pattern.duration || 500) }; } return { notes: [], nextTime: requestedTime + 100 }; } }; var SongDatabase = { 'Pixel Paradise': { bpm: 117, scannerCycleDuration: 4000, totalLength: 202106, highScore: 0, notes: [{ "time": 8707, "type": "tap", "zone": "right" }, { "time": 9218, "type": "tap", "zone": "left" }, { "time": 9705, "type": "tap", "zone": "right" }, { "time": 10216, "type": "tap", "zone": "left" }, { "time": 10704, "type": "tap", "zone": "right" }, { "time": 11215, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 12701, "type": "tap", "zone": "right" }, { "time": 13212, "type": "tap", "zone": "left" }, { "time": 13699, "type": "tap", "zone": "right" }, { "time": 14210, "type": "tap", "zone": "left" }, { "time": 14610, "type": "tap", "zone": "right" }, { "time": 15209, "type": "tap", "zone": "left" }, { "time": 15696, "type": "tap", "zone": "right" }, { "time": 16207, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 16207, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 18204, "type": "tap", "zone": "left" }, { "time": 18692, "type": "tap", "zone": "right" }, { "time": 19202, "type": "tap", "zone": "left" }, { "time": 19690, "type": "tap", "zone": "right" }, { "time": 20201, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 20201, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 20712, "type": "tap", "zone": "right" }, { "time": 21199, "type": "tap", "zone": "left" }, { "time": 22198, "type": "tap", "zone": "left" }, { "time": 22709, "type": "tap", "zone": "right" }, { "time": 23196, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 24682, "type": "tap", "zone": "right" }, { "time": 25193, "type": "tap", "zone": "left" }, { "time": 25704, "type": "tap", "zone": "right" }, { "time": 26215, "type": "tap", "zone": "left" }, { "time": 26702, "type": "tap", "zone": "right" }, { "time": 27213, "type": "tap", "zone": "left" }, { "time": 27701, "type": "tap", "zone": "right" }, { "time": 28212, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 28212, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 28699, "type": "tap", "zone": "right" }, { "time": 29210, "type": "tap", "zone": "left" }, { "time": 29698, "type": "tap", "zone": "right" }, { "time": 30209, "type": "tap", "zone": "left" }, { "time": 30609, "type": "tap", "zone": "right" }, { "time": 31161, "type": "tap", "zone": "left" }, { "time": 31672, "type": "tap", "zone": "right" }, { "time": 32182, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 32182, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 34202, "type": "tap", "zone": "left" }, { "time": 34602, "type": "tap", "zone": "right" }, { "time": 35201, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 36710, "type": "tap", "zone": "right" }, { "time": 37198, "type": "tap", "zone": "left" }, { "time": 37709, "type": "tap", "zone": "right" }, { "time": 38196, "type": "tap", "zone": "left" }, { "time": 38707, "type": "tap", "zone": "right" }, { "time": 39195, "type": "tap", "zone": "left" }, { "time": 39682, "type": "tap", "zone": "right" }, { "time": 40216, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 40216, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 40704, "type": "tap", "zone": "right" }, { "time": 41215, "type": "hold", "zone": "right", "duration": 1000 }, { "time": 43212, "type": "tap", "zone": "left" }, { "time": 43699, "type": "tap", "zone": "right" }, { "time": 44721, "type": "tap", "zone": "right" }, { "time": 45209, "type": "tap", "zone": "left" }, { "time": 45696, "type": "tap", "zone": "right" }, { "time": 46207, "type": "tap", "zone": "left" }, { "time": 46718, "type": "tap", "zone": "right" }, { "time": 47693, "type": "tap", "zone": "right" }, { "time": 48204, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 48204, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 48715, "type": "tap", "zone": "right" }, { "time": 49203, "type": "tap", "zone": "left" }, { "time": 49713, "type": "tap", "zone": "right" }, { "time": 50201, "type": "tap", "zone": "left" }, { "time": 50712, "type": "tap", "zone": "right" }, { "time": 51200, "type": "tap", "zone": "left" }, { "time": 51710, "type": "tap", "zone": "right" }, { "time": 52221, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 52221, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 52709, "type": "tap", "zone": "right" }, { "time": 53220, "type": "hold", "zone": "right", "duration": 1000 }, { "time": 54706, "type": "tap", "zone": "right" }, { "time": 55217, "type": "tap", "zone": "left" }, { "time": 55704, "type": "tap", "zone": "right" }, { "time": 56192, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 56192, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 56703, "type": "tap", "zone": "right" }, { "time": 57190, "type": "tap", "zone": "left" }, { "time": 57701, "type": "tap", "zone": "right" }, { "time": 58212, "type": "tap", "zone": "left" }, { "time": 58700, "type": "tap", "zone": "right" }, { "time": 59210, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 60696, "type": "tap", "zone": "right" }, { "time": 61207, "type": "tap", "zone": "left" }, { "time": 61695, "type": "tap", "zone": "right" }, { "time": 62183, "type": "tap", "zone": "left" }, { "time": 62693, "type": "tap", "zone": "right" }, { "time": 63204, "type": "tap", "zone": "left" }, { "time": 63715, "type": "tap", "zone": "right" }, { "time": 64203, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 64203, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 64714, "type": "tap", "zone": "right" }, { "time": 65201, "type": "hold", "zone": "right", "duration": 1000 }, { "time": 66710, "type": "tap", "zone": "right" }, { "time": 67198, "type": "tap", "zone": "left" }, { "time": 67709, "type": "tap", "zone": "right" }, { "time": 68220, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 68220, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 68707, "type": "tap", "zone": "right" }, { "time": 69195, "type": "tap", "zone": "left" }, { "time": 69706, "type": "tap", "zone": "right" }, { "time": 70217, "type": "tap", "zone": "left" }, { "time": 70617, "type": "tap", "zone": "right" }, { "time": 71215, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 72701, "type": "tap", "zone": "right" }, { "time": 73189, "type": "tap", "zone": "left" }, { "time": 73700, "type": "tap", "zone": "right" }, { "time": 74210, "type": "tap", "zone": "left" }, { "time": 74698, "type": "tap", "zone": "right" }, { "time": 75209, "type": "tap", "zone": "left" }, { "time": 75697, "type": "tap", "zone": "right" }, { "time": 76207, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 76207, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 76695, "type": "tap", "zone": "right" }, { "time": 77206, "type": "hold", "zone": "right", "duration": 1000 }, { "time": 78692, "type": "tap", "zone": "right" }, { "time": 79203, "type": "tap", "zone": "left" }, { "time": 79690, "type": "tap", "zone": "right" }, { "time": 80201, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 80201, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 80689, "type": "tap", "zone": "right" }, { "time": 81200, "type": "tap", "zone": "left" }, { "time": 81711, "type": "tap", "zone": "right" }, { "time": 82221, "type": "tap", "zone": "left" }, { "time": 82709, "type": "tap", "zone": "right" }, { "time": 83197, "type": "tap", "zone": "left" }, { "time": 83707, "type": "tap", "zone": "right" }, { "time": 84218, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 84218, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 84706, "type": "tap", "zone": "right" }, { "time": 85217, "type": "tap", "zone": "left" }, { "time": 85704, "type": "tap", "zone": "right" }, { "time": 86215, "type": "tap", "zone": "left" }, { "time": 86615, "type": "tap", "zone": "right" }, { "time": 87167, "type": "tap", "zone": "left" }, { "time": 87678, "type": "tap", "zone": "right" }, { "time": 88166, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 88166, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 90209, "type": "tap", "zone": "left" }, { "time": 90609, "type": "tap", "zone": "right" }, { "time": 91184, "type": "tap", "zone": "left" }, { "time": 91695, "type": "tap", "zone": "right" }, { "time": 92206, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 92206, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 92694, "type": "tap", "zone": "right" }, { "time": 93204, "type": "tap", "zone": "left" }, { "time": 93692, "type": "tap", "zone": "right" }, { "time": 94203, "type": "tap", "zone": "left" }, { "time": 94714, "type": "tap", "zone": "right" }, { "time": 95201, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 96711, "type": "tap", "zone": "right" }, { "time": 97221, "type": "tap", "zone": "left" }, { "time": 97709, "type": "tap", "zone": "right" }, { "time": 98197, "type": "tap", "zone": "left" }, { "time": 98708, "type": "tap", "zone": "right" }, { "time": 99195, "type": "tap", "zone": "left" }, { "time": 100217, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 100217, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 100704, "type": "tap", "zone": "right" }, { "time": 101703, "type": "tap", "zone": "right" }, { "time": 102214, "type": "tap", "zone": "left" }, { "time": 103212, "type": "tap", "zone": "left" }, { "time": 103700, "type": "tap", "zone": "right" }, { "time": 104211, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 104211, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 106208, "type": "tap", "zone": "left" }, { "time": 106608, "type": "tap", "zone": "right" }, { "time": 107206, "type": "tap", "zone": "left" }, { "time": 107694, "type": "tap", "zone": "right" }, { "time": 108204, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 108204, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 108692, "type": "tap", "zone": "right" }, { "time": 109203, "type": "tap", "zone": "left" }, { "time": 109691, "type": "tap", "zone": "right" }, { "time": 110201, "type": "tap", "zone": "left" }, { "time": 110601, "type": "tap", "zone": "right" }, { "time": 111200, "type": "tap", "zone": "left" }, { "time": 111711, "type": "tap", "zone": "right" }, { "time": 112198, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 112198, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 114195, "type": "tap", "zone": "left" }, { "time": 114595, "type": "tap", "zone": "right" }, { "time": 115194, "type": "tap", "zone": "left" }, { "time": 115705, "type": "tap", "zone": "right" }, { "time": 116215, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 116215, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 116703, "type": "tap", "zone": "right" }, { "time": 117191, "type": "tap", "zone": "left" }, { "time": 117701, "type": "tap", "zone": "right" }, { "time": 118189, "type": "tap", "zone": "left" }, { "time": 118700, "type": "tap", "zone": "right" }, { "time": 119698, "type": "tap", "zone": "right" }, { "time": 120209, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 120209, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 122206, "type": "tap", "zone": "left" }, { "time": 122606, "type": "tap", "zone": "right" }, { "time": 123205, "type": "tap", "zone": "left" }, { "time": 123715, "type": "tap", "zone": "right" }, { "time": 124203, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 124203, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 124714, "type": "tap", "zone": "right" }, { "time": 125201, "type": "tap", "zone": "left" }, { "time": 125712, "type": "tap", "zone": "right" }, { "time": 126200, "type": "tap", "zone": "left" }, { "time": 126600, "type": "tap", "zone": "right" }, { "time": 127198, "type": "tap", "zone": "left" }, { "time": 127709, "type": "tap", "zone": "right" }, { "time": 128684, "type": "tap", "zone": "right" }, { "time": 129195, "type": "tap", "zone": "left" }, { "time": 130217, "type": "tap", "zone": "left" }, { "time": 130705, "type": "tap", "zone": "right" }, { "time": 131750, "type": "tap", "zone": "right" }, { "time": 132260, "type": "tap", "zone": "left" }, { "time": 133189, "type": "tap", "zone": "left" }, { "time": 133677, "type": "tap", "zone": "right" }, { "time": 134675, "type": "tap", "zone": "right" }, { "time": 135186, "type": "tap", "zone": "left" }, { "time": 136208, "type": "tap", "zone": "left" }, { "time": 136719, "type": "tap", "zone": "right" }, { "time": 137717, "type": "tap", "zone": "right" }, { "time": 138228, "type": "tap", "zone": "left" }, { "time": 139226, "type": "tap", "zone": "left" }, { "time": 139714, "type": "tap", "zone": "right" }, { "time": 140202, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 140202, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 140712, "type": "tap", "zone": "right" }, { "time": 141223, "type": "tap", "zone": "left" }, { "time": 142222, "type": "tap", "zone": "left" }, { "time": 142709, "type": "tap", "zone": "right" }, { "time": 143708, "type": "tap", "zone": "right" }, { "time": 144195, "type": "tap", "zone": "left" }, { "time": 145194, "type": "tap", "zone": "left" }, { "time": 145705, "type": "tap", "zone": "right" }, { "time": 146216, "type": "tap", "zone": "left" }, { "time": 146703, "type": "tap", "zone": "right" }, { "time": 147214, "type": "tap", "zone": "left" }, { "time": 147702, "type": "tap", "zone": "right" }, { "time": 148212, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 148212, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 148700, "type": "tap", "zone": "right" }, { "time": 149699, "type": "tap", "zone": "right" }, { "time": 150209, "type": "tap", "zone": "left" }, { "time": 151208, "type": "tap", "zone": "left" }, { "time": 151695, "type": "tap", "zone": "right" }, { "time": 152206, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 152206, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 154203, "type": "tap", "zone": "left" }, { "time": 154714, "type": "tap", "zone": "right" }, { "time": 155202, "type": "tap", "zone": "left" }, { "time": 155713, "type": "tap", "zone": "right" }, { "time": 156200, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 156200, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 157222, "type": "tap", "zone": "left" }, { "time": 157709, "type": "tap", "zone": "right" }, { "time": 158220, "type": "tap", "zone": "left" }, { "time": 158708, "type": "tap", "zone": "right" }, { "time": 159219, "type": "tap", "zone": "left" }, { "time": 159706, "type": "tap", "zone": "right" }, { "time": 160217, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 160217, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 160728, "type": "tap", "zone": "right" }, { "time": 161726, "type": "tap", "zone": "right" }, { "time": 162214, "type": "tap", "zone": "left" }, { "time": 163213, "type": "tap", "zone": "left" }, { "time": 163700, "type": "tap", "zone": "right" }, { "time": 164211, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 164211, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 164699, "type": "tap", "zone": "right" }, { "time": 165209, "type": "tap", "zone": "left" }, { "time": 165697, "type": "tap", "zone": "right" }, { "time": 166208, "type": "tap", "zone": "left" }, { "time": 166608, "type": "tap", "zone": "right" }, { "time": 167206, "type": "tap", "zone": "left" }, { "time": 167717, "type": "tap", "zone": "right" }, { "time": 168205, "type": "hold", "zone": "left", "duration": 1500, "color": 16753920 }, { "time": 168205, "type": "hold", "zone": "right", "duration": 1500, "color": 16753920 }, { "time": 170202, "type": "tap", "zone": "left" }, { "time": 170602, "type": "tap", "zone": "right" }, { "time": 171200, "type": "tap", "zone": "left" }, { "time": 171711, "type": "tap", "zone": "right" }, { "time": 172199, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 172199, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 172710, "type": "tap", "zone": "right" }, { "time": 173197, "type": "tap", "zone": "left" }, { "time": 173708, "type": "tap", "zone": "right" }, { "time": 174196, "type": "tap", "zone": "left" }, { "time": 175217, "type": "tap", "zone": "left" }, { "time": 175705, "type": "tap", "zone": "right" }, { "time": 176216, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 176216, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 176703, "type": "tap", "zone": "right" }, { "time": 177214, "type": "tap", "zone": "left" }, { "time": 177702, "type": "tap", "zone": "right" }, { "time": 178213, "type": "tap", "zone": "left" }, { "time": 178700, "type": "tap", "zone": "right" }, { "time": 179211, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 180697, "type": "tap", "zone": "right" }, { "time": 181208, "type": "tap", "zone": "left" }, { "time": 181719, "type": "tap", "zone": "right" }, { "time": 182206, "type": "tap", "zone": "left" }, { "time": 182606, "type": "tap", "zone": "right" }, { "time": 183205, "type": "tap", "zone": "left" }, { "time": 183716, "type": "tap", "zone": "right" }, { "time": 184203, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 184203, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 184714, "type": "tap", "zone": "right" }, { "time": 185202, "type": "hold", "zone": "right", "duration": 1000 }, { "time": 186711, "type": "tap", "zone": "right" }, { "time": 187222, "type": "tap", "zone": "left" }, { "time": 187710, "type": "tap", "zone": "right" }, { "time": 188197, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 188197, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 188708, "type": "tap", "zone": "right" }, { "time": 189219, "type": "tap", "zone": "left" }, { "time": 189823, "type": "tap", "zone": "right" }, { "time": 190403, "type": "tap", "zone": "left" }, { "time": 190803, "type": "tap", "zone": "right" }, { "time": 191448, "type": "hold", "zone": "left", "duration": 1000 }, { "time": 193468, "type": "tap", "zone": "left" }, { "time": 193956, "type": "tap", "zone": "right" }, { "time": 194954, "type": "tap", "zone": "right" }, { "time": 195465, "type": "tap", "zone": "left" }, { "time": 196464, "type": "tap", "zone": "left", "color": 16753920 }, { "time": 196464, "type": "tap", "zone": "right", "color": 16753920 }, { "time": 196974, "type": "tap", "zone": "right" }, { "time": 197973, "type": "tap", "zone": "right" }, { "time": 198460, "type": "tap", "zone": "left" }, { "time": 198971, "type": "tap", "zone": "right" }] } }; function getSongLength(songName) { var song = SongDatabase[songName]; if (!song) { return "0:00"; } var totalSeconds = Math.floor(song.totalLength / 1000); var minutes = Math.floor(totalSeconds / 60); var seconds = totalSeconds % 60; return minutes + ":" + (seconds < 10 ? "0" : "") + seconds; } function updateHighScore(songName, score) { if (SongDatabase[songName] && score > SongDatabase[songName].highScore) { SongDatabase[songName].highScore = score; return true; } return false; } function calculateNotePosition(noteTime) { var cycleTime = noteTime % SCANNER_CYCLE_DURATION; var y; if (cycleTime < SCANNER_HALF_CYCLE) { var progress = cycleTime / SCANNER_HALF_CYCLE; y = SCANNER_Y_MAX - progress * PLAY_AREA_HEIGHT; } else { var progress = (cycleTime - SCANNER_HALF_CYCLE) / SCANNER_HALF_CYCLE; y = SCANNER_Y_MIN + progress * PLAY_AREA_HEIGHT; } return y; } function calculateZoneX(zone) { var sideMargin = GAME_WIDTH * SAFETY_MARGIN_SIDES_PERCENT; var randomSpan = GAME_WIDTH / 2 - 2 * sideMargin; if (randomSpan < 0) { randomSpan = 0; } if (zone === 'left') { return sideMargin + Math.random() * randomSpan; } else { return GAME_WIDTH / 2 + sideMargin + Math.random() * randomSpan; } } function createZoneIndicators() { leftZone = game.attachAsset('zoneIndicator', { anchorX: 0, anchorY: 0 }); leftZone.x = 0; leftZone.y = 0; leftZone.width = GAME_WIDTH / 2; leftZone.alpha = 0.1; leftZone.tint = 0x00ffff; rightZone = game.attachAsset('zoneIndicator', { anchorX: 0, anchorY: 0 }); rightZone.x = GAME_WIDTH / 2; rightZone.y = 0; rightZone.width = GAME_WIDTH / 2; rightZone.alpha = 0.1; rightZone.tint = 0xff00ff; } function showAccuracyPopup(text, x, y, color) { var popup = new Text2(text, { size: ACCURACY_POPUP_FONT_SIZE, fill: color, stroke: 0x000000, strokeThickness: 4 }); popup.anchor.set(0.5, 0.5); popup.x = x; popup.y = y + ACCURACY_POPUP_Y_OFFSET; popup.alpha = 0; game.addChild(popup); var initialY = popup.y; tween(popup, { alpha: 1, y: initialY - 30 }, { duration: ACCURACY_POPUP_DURATION * 0.25, easing: tween.easeOut, onFinish: function onFinish() { tween(popup, { alpha: 0, y: initialY - 130 }, { duration: ACCURACY_POPUP_DURATION * 0.75, easing: tween.easeIn, onFinish: function onFinish() { if (popup && popup.destroy) { popup.destroy(); } } }); } }); } function initializeTitleScreen() { titleScreen.container = new Container(); game.addChild(titleScreen.container); titleScreen.title = new Text2('PULSAR', { size: 300, fill: 0xFFFFFF, stroke: 0x00FFFF, strokeThickness: 8 }); titleScreen.title.anchor.set(0.5, 0.5); titleScreen.title.x = GAME_WIDTH / 2; titleScreen.title.y = GAME_HEIGHT / 2 - 200; titleScreen.container.addChild(titleScreen.title); titleScreen.subtitle = new Text2('Press to Start', { size: 100, fill: 0xCCCCCC }); titleScreen.subtitle.anchor.set(0.5, 0.5); titleScreen.subtitle.x = GAME_WIDTH / 2; titleScreen.subtitle.y = GAME_HEIGHT / 2 + 100; titleScreen.container.addChild(titleScreen.subtitle); var pulseScale = 1; var pulseDirection = 1; titleScreen.pulseInterval = LK.setInterval(function () { pulseScale += pulseDirection * 0.02; if (pulseScale > 1.1) { pulseScale = 1.1; pulseDirection = -1; } else if (pulseScale < 0.9) { pulseScale = 0.9; pulseDirection = 1; } titleScreen.subtitle.scale.set(pulseScale); }, 50); } function initializeSongSelectScreen() { songSelectScreen.container = new Container(); game.addChild(songSelectScreen.container); songSelectScreen.container.visible = false; songSelectScreen.title = new Text2('Select Song', { size: 150, fill: 0xFFFFFF }); songSelectScreen.title.anchor.set(0.5, 0); songSelectScreen.title.x = GAME_WIDTH / 2; songSelectScreen.title.y = 100; songSelectScreen.container.addChild(songSelectScreen.title); songSelectScreen.scrollContainer = new Container(); songSelectScreen.scrollContainer.x = 0; songSelectScreen.scrollContainer.y = 300; songSelectScreen.container.addChild(songSelectScreen.scrollContainer); createSongItems(); updateScrollLimits(); } function createSongItems() { songSelectScreen.items = []; var songNames = Object.keys(SongDatabase); for (var i = 0; i < songNames.length; i++) { var songName = songNames[i]; var song = SongDatabase[songName]; var yPos = i * (SONG_ITEM_HEIGHT + 50); var itemContainer = new Container(); itemContainer.x = 100; itemContainer.y = yPos; itemContainer.songName = songName; var bg = game.attachAsset('zoneIndicator', { anchorX: 0, anchorY: 0 }); bg.width = GAME_WIDTH - 200; bg.height = SONG_ITEM_HEIGHT; bg.alpha = 0.2; bg.tint = 0x333333; itemContainer.addChild(bg); var titleText = new Text2(songName, { size: 100, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); // Center horizontally, align top vertically titleText.x = (GAME_WIDTH - 200) / 2; // Center within the background width titleText.y = 30; itemContainer.addChild(titleText); var infoText = new Text2('BPM: ' + song.bpm + ' | Length: ' + getSongLength(songName), { size: 62.5, fill: 0xCCCCCC }); infoText.anchor.set(0.5, 0); // Center horizontally, align top vertically infoText.x = (GAME_WIDTH - 200) / 2; // Center within the background width infoText.y = 100; itemContainer.addChild(infoText); var scoreText = new Text2('High Score: ' + song.highScore, { size: 62.5, fill: 0xFFDD00 }); scoreText.anchor.set(0.5, 0); // Center horizontally, align top vertically scoreText.x = (GAME_WIDTH - 200) / 2; // Center within the background width scoreText.y = 150; itemContainer.addChild(scoreText); songSelectScreen.scrollContainer.addChild(itemContainer); songSelectScreen.items.push(itemContainer); } } function updateScrollLimits() { var totalHeight = songSelectScreen.items.length * (SONG_ITEM_HEIGHT + 50); var containerHeight = GAME_HEIGHT - 400; maxScrollY = Math.max(0, totalHeight - containerHeight); } function showTitleScreen() { currentGameState = GAME_STATE_TITLE; if (titleScreen.container) titleScreen.container.visible = true; if (songSelectScreen.container) songSelectScreen.container.visible = false; if (resultsScreen.container) resultsScreen.container.visible = false; hideGameplayUI(); } function showSongSelectScreen() { currentGameState = GAME_STATE_SONG_SELECT; if (titleScreen.container) titleScreen.container.visible = false; if (songSelectScreen.container) songSelectScreen.container.visible = true; if (resultsScreen.container) resultsScreen.container.visible = false; hideGameplayUI(); songSelectScrollY = 0; songSelectScreen.scrollContainer.y = 300; } function hideGameplayUI() { if (scoreTxt) { scoreTxt.visible = false; } if (leftZone) { leftZone.visible = false; } if (rightZone) { rightZone.visible = false; } if (scanner) { scanner.visible = false; } } function showGameplayUI() { if (scoreTxt) { scoreTxt.visible = true; } if (leftZone) { leftZone.visible = true; } if (rightZone) { rightZone.visible = true; } if (scanner) { scanner.visible = true; } titleScreen.container.visible = false; songSelectScreen.container.visible = false; } function startCountdown() { countdownTxt = new Text2('3', { size: 200, fill: 0xFFFFFF }); countdownTxt.anchor.set(0.5, 0.5); countdownTxt.x = GAME_WIDTH / 2; countdownTxt.y = GAME_HEIGHT / 2; game.addChild(countdownTxt); var count = 3; var countdownInterval = LK.setInterval(function () { count--; if (count > 0) { countdownTxt.setText(count.toString()); } else if (count === 0) { countdownTxt.setText('GO!'); } else { LK.clearInterval(countdownInterval); if (countdownTxt && countdownTxt.destroy) { countdownTxt.destroy(); } startGame(); } }, 1000); } function showResultsScreen() { currentGameState = GAME_STATE_RESULTS; if (titleScreen.container) titleScreen.container.visible = false; if (songSelectScreen.container) songSelectScreen.container.visible = false; if (resultsScreen.container) resultsScreen.container.visible = true; hideGameplayUI(); } function startGame() { currentGameState = GAME_STATE_PLAYING; gameStarted = true; gameStartTime = Date.now(); showGameplayUI(); moveScanner(); LK.playMusic('gameMusic', { loop: true }); } function moveScanner() { if (!scanner || !gameStarted || currentGameState !== GAME_STATE_PLAYING) { return; } tween.stop(scanner); var targetY = scannerIsMovingUp ? SCANNER_Y_MIN : SCANNER_Y_MAX; tween(scanner, { y: targetY }, { duration: SCANNER_CYCLE_DURATION / 2, easing: tween.linear, onFinish: function onFinish() { scannerIsMovingUp = !scannerIsMovingUp; moveScanner(); } }); } function spawnNotesForCurrentTime(currentTime) { if (!currentSongData) { return; } currentSongData.notes.forEach(function (noteData, index) { var noteKey = index + '_' + noteData.time; var alreadySpawned = false; for (var i = 0; i < spawnedNotes.length; i++) { if (spawnedNotes[i] === noteKey) { alreadySpawned = true; break; } } if (!alreadySpawned && currentTime >= noteData.time - NOTE_SPAWN_AHEAD_MS && currentTime <= noteData.time - NOTE_SPAWN_AHEAD_MS + 100) { var calculatedY = calculateNotePosition(noteData.time); var calculatedX = calculateZoneX(noteData.zone); var processedNoteData = { time: noteData.time, type: noteData.type, x: calculatedX, y: calculatedY, color: noteData.color, duration: noteData.duration }; var note = new Note(processedNoteData, currentTime); notes.push(note); game.addChild(note); note.spawnIn(); spawnedNotes.push(noteKey); } }); } function setupGame(songName) { LK.setScore(0); gameStarted = false; if (scoreTxt && scoreTxt.destroy) { scoreTxt.destroy(); } scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.setText(LK.getScore()); createZoneIndicators(); if (scanner && scanner.destroy) { scanner.destroy(); } scanner = new Scanner(); scanner.y = SCANNER_Y_MAX; game.addChild(scanner); notes.forEach(function (note) { if (note && note.destroy) { note.destroy(); } }); notes = []; spawnedNotes = []; currentSongData = SongDatabase[songName]; BPM = currentSongData.bpm; BEAT_DURATION_MS = 60 / BPM * 1000; SCANNER_CYCLE_DURATION = currentSongData.scannerCycleDuration; SCANNER_HALF_CYCLE = SCANNER_CYCLE_DURATION / 2; scannerIsMovingUp = true; startCountdown(); if (backgroundParticles.length === 0) { for (var i = 0; i < NUM_BACKGROUND_PARTICLES; i++) { var particle = new BackgroundParticle(); particle.y = Math.random() * GAME_HEIGHT; backgroundParticles.push(particle); game.addChildAt(particle, 0); } } else { backgroundParticles.forEach(function (p) { p.init(); p.y = Math.random() * GAME_HEIGHT; }); } } function checkZoneHit(x, y) { var hitZone = x < GAME_WIDTH / 2 ? 'left' : 'right'; var currentTime = Date.now() - gameStartTime; for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; if (!note || !note.active || note.isHit || note.isSpawning || !note.noteGraphics) { continue; } if (note.zone === hitZone) { var noteCoreHeight = note.noteGraphics.height; var noteCenterY = note.y; var scannerY = scanner.y; var perfectHitRadius = noteCoreHeight * PERFECT_HIT_RATIO / 2; var goodHitRadius = noteCoreHeight / 2; var perfectHitTop = noteCenterY - perfectHitRadius; var perfectHitBottom = noteCenterY + perfectHitRadius; var goodHitTop = noteCenterY - goodHitRadius; var goodHitBottom = noteCenterY + goodHitRadius; var accuracyText = null; var hitPoints = 0; var popupColor = 0xFFFFFF; if (scannerY >= perfectHitTop && scannerY <= perfectHitBottom) { accuracyText = "PERFECT"; popupColor = PERFECT_POPUP_COLOR; if (note.type === 'tap') { hitPoints = POINTS_PERFECT_TAP; } else if (note.type === 'hold') { hitPoints = POINTS_PERFECT_HOLD_START; } } else if (scannerY >= goodHitTop && scannerY <= goodHitBottom) { accuracyText = "GOOD"; popupColor = GOOD_POPUP_COLOR; if (note.type === 'tap') { hitPoints = POINTS_GOOD_TAP; } else if (note.type === 'hold') { hitPoints = POINTS_GOOD_HOLD_START; } } if (accuracyText) { note.isHit = true; showAccuracyPopup(accuracyText, note.x, note.y, popupColor); if (note.type === 'tap') { note.showHitEffect(); } else if (note.type === 'hold') { note.startHoldEffect(); } if (hitPoints > 0) { LK.setScore(LK.getScore() + hitPoints); scoreTxt.setText(LK.getScore()); } break; } } } } function handleSongItemClick(x, y) { for (var i = 0; i < songSelectScreen.items.length; i++) { var item = songSelectScreen.items[i]; var itemX = item.x; var itemY = item.y + songSelectScreen.scrollContainer.y; if (x >= itemX && x <= itemX + (GAME_WIDTH - 200) && y >= itemY && y <= itemY + SONG_ITEM_HEIGHT) { setupGame(item.songName); return true; } } return false; } function initializeResultsScreen() { resultsScreen.container = new Container(); game.addChild(resultsScreen.container); resultsScreen.container.visible = false; resultsScreen.title = new Text2('Results', { size: 180, fill: 0xFFFFFF, stroke: 0x00FFFF, strokeThickness: 6 }); resultsScreen.title.anchor.set(0.5, 0.5); resultsScreen.title.x = GAME_WIDTH / 2; resultsScreen.title.y = GAME_HEIGHT / 2 - 350; resultsScreen.container.addChild(resultsScreen.title); resultsScreen.scoreText = new Text2('Final Score: 0', { size: 100, fill: 0xFFFFFF }); resultsScreen.scoreText.anchor.set(0.5, 0.5); resultsScreen.scoreText.x = GAME_WIDTH / 2; resultsScreen.scoreText.y = GAME_HEIGHT / 2 - 150; resultsScreen.container.addChild(resultsScreen.scoreText); resultsScreen.highScoreText = new Text2('High Score: 0', { size: 80, fill: 0xFFDD00 }); resultsScreen.highScoreText.anchor.set(0.5, 0.5); resultsScreen.highScoreText.x = GAME_WIDTH / 2; resultsScreen.highScoreText.y = GAME_HEIGHT / 2 - 50; resultsScreen.container.addChild(resultsScreen.highScoreText); resultsScreen.continueText = new Text2('Tap to Continue', { size: 90, fill: 0xCCCCCC }); resultsScreen.continueText.anchor.set(0.5, 0.5); resultsScreen.continueText.x = GAME_WIDTH / 2; resultsScreen.continueText.y = GAME_HEIGHT / 2 + 100; resultsScreen.container.addChild(resultsScreen.continueText); if (resultsScreen.pulseInterval) { LK.clearInterval(resultsScreen.pulseInterval); } resultsScreen.pulseInterval = LK.setInterval(function () { if (currentGameState === GAME_STATE_RESULTS && resultsScreen.continueText) { var pulseScale = resultsScreen.continueText.scale.x; var pulseDirection = resultsScreen.continueText.pulseDirection || 1; pulseScale += pulseDirection * 0.02; if (pulseScale > 1.1) { pulseScale = 1.1; pulseDirection = -1; } else if (pulseScale < 0.9) { pulseScale = 0.9; pulseDirection = 1; } resultsScreen.continueText.scale.set(pulseScale); resultsScreen.continueText.pulseDirection = pulseDirection; } }, 50); } initializeTitleScreen(); initializeSongSelectScreen(); initializeResultsScreen(); for (var i = 0; i < NUM_BACKGROUND_PARTICLES; i++) { var particle = new BackgroundParticle(); particle.y = Math.random() * GAME_HEIGHT; backgroundParticles.push(particle); game.addChildAt(particle, 0); } showTitleScreen(); game.down = function (x, y, obj) { if (currentGameState === GAME_STATE_TITLE) { showSongSelectScreen(); return; } if (currentGameState === GAME_STATE_RESULTS) { showSongSelectScreen(); return; } if (currentGameState === GAME_STATE_SONG_SELECT) { if (handleSongItemClick(x, y)) { return; } isDraggingSongList = true; dragStartYSongList = y; return; } if (currentGameState === GAME_STATE_PLAYING && gameStarted) { checkZoneHit(x, y); var hitZoneForDown = x < GAME_WIDTH / 2 ? 'left' : 'right'; for (var i = 0; i < notes.length; i++) { var note = notes[i]; if (!note.active || note.isSpawning || note.holdSuccessfullyCompleted || note.isMissed) { continue; } if (note.zone === hitZoneForDown && note.isHit) { if (note.type === 'hold' && !note.isHolding) { note.isHolding = true; activeHoldNotes[note.zone] = note; } } } isDragging = true; dragStartX = x; dragStartY = y; } }; game.move = function (x, y, obj) { if (currentGameState === GAME_STATE_SONG_SELECT && isDraggingSongList) { var deltaY = y - dragStartYSongList; songSelectScrollY = Math.max(0, Math.min(maxScrollY, songSelectScrollY - deltaY)); songSelectScreen.scrollContainer.y = 300 - songSelectScrollY; dragStartYSongList = y; } if (currentGameState === GAME_STATE_PLAYING && isDragging && gameStarted) {} }; game.up = function (x, y, obj) { if (currentGameState === GAME_STATE_SONG_SELECT) { isDraggingSongList = false; return; } if (currentGameState === GAME_STATE_PLAYING && gameStarted) { var releasedZone = x < GAME_WIDTH / 2 ? 'left' : 'right'; var heldNote = activeHoldNotes[releasedZone]; if (heldNote && heldNote.isHolding) { heldNote.isHolding = false; delete activeHoldNotes[releasedZone]; var currentTimeMs = Date.now() - gameStartTime; var noteExpectedEndTimeMs = heldNote.hitTime + heldNote.duration; var absoluteEndNoteY = heldNote.y + (heldNote.endNote ? heldNote.endNote.y : 0); var hitTimeCycle = heldNote.hitTime % SCANNER_CYCLE_DURATION; var noteScannerMovingUp = hitTimeCycle < SCANNER_HALF_CYCLE; var trailDirection = noteScannerMovingUp ? -1 : 1; var scannerAtEnd; if (trailDirection === -1) { scannerAtEnd = scanner.y <= absoluteEndNoteY + HIT_TOLERANCE_PX_FOR_HOLD_END && scanner.y >= absoluteEndNoteY - HIT_TOLERANCE_PX_FOR_HOLD_END / 2; } else { scannerAtEnd = scanner.y >= absoluteEndNoteY - HIT_TOLERANCE_PX_FOR_HOLD_END && scanner.y <= absoluteEndNoteY + HIT_TOLERANCE_PX_FOR_HOLD_END / 2; } var timeReachedOrPassedEnd = currentTimeMs >= noteExpectedEndTimeMs - HOLD_END_GRACE_PERIOD_MS; var timeNotTooLate = currentTimeMs <= noteExpectedEndTimeMs + HOLD_END_GRACE_PERIOD_MS + 200; if (scannerAtEnd && timeReachedOrPassedEnd && timeNotTooLate) { heldNote.completeHold(); LK.setScore(LK.getScore() + 50); scoreTxt.setText(LK.getScore()); } else { heldNote.failHold(); } } isDragging = false; } }; game.update = function () { backgroundParticles.forEach(function (particle) { particle.updateParticle(); }); if (currentGameState !== GAME_STATE_PLAYING || !gameStarted) { return; } var currentTime = Date.now() - gameStartTime; spawnNotesForCurrentTime(currentTime); for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; if (!note) { notes.splice(i, 1); continue; } if (note.type === 'hold' && note.isHolding && note.active && !note.holdSuccessfullyCompleted && !note.isMissed) { note.updateHoldEffects(scanner.y); var currentTimeMsForUpdate = Date.now() - gameStartTime; var noteExpectedEndTimeMsForUpdate = note.hitTime + note.duration; if (currentTimeMsForUpdate > noteExpectedEndTimeMsForUpdate + HOLD_END_GRACE_PERIOD_MS + 500) { if (activeHoldNotes[note.zone] === note) { note.failHold(); delete activeHoldNotes[note.zone]; } } } if (note.active && !note.isHit && !note.isMissed && !note.isSpawning) { var timeDiff = currentTime - note.hitTime; var scannerPassed = false; if (scannerIsMovingUp && scanner.y < note.y - 50) { scannerPassed = true; } else if (!scannerIsMovingUp && scanner.y > note.y + 50) { scannerPassed = true; } if (scannerPassed && timeDiff > 300) { note.isMissed = true; note.showMissEffect(); } } if (!note.active) { notes.splice(i, 1); if (game.children.indexOf(note) > -1) { game.removeChild(note); } if (note.destroy) { note.destroy(); } } } if (currentSongData && currentTime > currentSongData.totalLength + 3000 && currentGameState === GAME_STATE_PLAYING) { LK.stopMusic(); gameStarted = false; if (scanner) { tween.stop(scanner); } var finalScore = LK.getScore(); var songName = null; for (var key in SongDatabase) { if (SongDatabase[key] === currentSongData) { songName = key; break; } } if (songName) { var isNewHighScore = updateHighScore(songName, finalScore); if (isNewHighScore) { // Update songSelectScreen items if they are already created if (songSelectScreen.items) { for (var j = 0; j < songSelectScreen.items.length; j++) { var item = songSelectScreen.items[j]; if (item.songName === songName) { // Assuming scoreText is the 4th child (index 3) var scoreTextDisplay = item.children[3]; if (scoreTextDisplay && scoreTextDisplay.setText) { scoreTextDisplay.setText('High Score: ' + finalScore); } break; } } } } if (resultsScreen.highScoreText) { resultsScreen.highScoreText.setText("High Score: " + SongDatabase[songName].highScore); } } if (resultsScreen.scoreText) { resultsScreen.scoreText.setText("Final Score: " + finalScore); } showResultsScreen(); } if (scanner && game.children.indexOf(scanner) > -1) { game.removeChild(scanner); game.addChild(scanner); } };
===================================================================
--- original.js
+++ change.js
@@ -2720,26 +2720,29 @@
bg.alpha = 0.2;
bg.tint = 0x333333;
itemContainer.addChild(bg);
var titleText = new Text2(songName, {
- size: 80,
+ size: 100,
fill: 0xFFFFFF
});
- titleText.x = 50;
+ titleText.anchor.set(0.5, 0); // Center horizontally, align top vertically
+ titleText.x = (GAME_WIDTH - 200) / 2; // Center within the background width
titleText.y = 30;
itemContainer.addChild(titleText);
var infoText = new Text2('BPM: ' + song.bpm + ' | Length: ' + getSongLength(songName), {
- size: 50,
+ size: 62.5,
fill: 0xCCCCCC
});
- infoText.x = 50;
+ infoText.anchor.set(0.5, 0); // Center horizontally, align top vertically
+ infoText.x = (GAME_WIDTH - 200) / 2; // Center within the background width
infoText.y = 100;
itemContainer.addChild(infoText);
var scoreText = new Text2('High Score: ' + song.highScore, {
- size: 50,
+ size: 62.5,
fill: 0xFFDD00
});
- scoreText.x = 50;
+ scoreText.anchor.set(0.5, 0); // Center horizontally, align top vertically
+ scoreText.x = (GAME_WIDTH - 200) / 2; // Center within the background width
scoreText.y = 150;
itemContainer.addChild(scoreText);
songSelectScreen.scrollContainer.addChild(itemContainer);
songSelectScreen.items.push(itemContainer);
The word 'Pulsar' in a glowing neon SVG in futuristic font. The word is half blue on the left and half red on the right. In-Game asset. 2d. High contrast. No shadows
Remove the background.
A thin expanding ring with energy distortion ``` - Outer ring: 4-6 pixels thick, bright cyan (#00FFFF) - Inner ring: 2-3 pixels thick, white (#FFFFFF) - Ring thickness: Tapers from thick to thin as it expands - Transparency: Ring itself at 80% opacity - Background: Completely transparent - Edge treatment: Soft anti-aliased edges, slight glow effect - Optional: Subtle "energy crackle" texture within the ring. In-Game asset. 2d. High contrast. No shadows
Soft, lingering light effect ``` - Center: Warm orange (#FF6600) at 40% opacity - Middle: Yellow (#FFAA00) at 25% opacity - Edge: Transparent - Shape: Perfect circle with very soft, wide falloff. In-Game asset. 2d. High contrast. No shadows