diff --git a/README.md b/README.md index 07b491ad..664bb883 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ - **Main Menu** - A mostly fully working main menu with all 2.1 levels. - **Online Levels** - You can play online levels, and even upload your own! - **Icon Kit** - A working Icon Kit with different colors and icons to choose from! -- **Different Gamemodes** - Multiple working gamemodes such as the Ball, Wave, Cube, UFO, Mini portals and Speed portals! +- **Different Gamemodes** - Multiple working gamemodes such as the Ball, Wave, Cube, UFO, Swing, Spider, Robot, Ship, Mini portals and Speed portals! - **Extra Settings** - You can enable and disable Noclip or Show Hitboxes from the pause menu in a level, along with other settings, like the level percentage! - **Account System** - You can save/load all level progress, and upload it to the cloud to keep your progress on different devices! diff --git a/assets/scripts/core/game-scene.js b/assets/scripts/core/game-scene.js index ab60fb24..13bfb826 100644 --- a/assets/scripts/core/game-scene.js +++ b/assets/scripts/core/game-scene.js @@ -1,10621 +1,10672 @@ -class PracticeMode { - constructor() { - this.checkpoints = []; - this.practiceMode = false; - this.checkpointSprites = []; - } - togglePracticeMode() { - this.practiceMode = !this.practiceMode; - if (!this.practiceMode) { - this.clearCheckpoints(); - } - return this.practiceMode; - } - saveCheckpoint(playerState, playerWorldX, cameraX, scene) { - if (!this.practiceMode) return false; - const checkpoint = { - x: playerWorldX, - y: playerState.y, - yVelocity: playerState.yVelocity, - gravityFlipped: playerState.gravityFlipped, - isMini: playerState.isMini, - isCube: playerState.isCube, - isShip: playerState.isShip, - isBall: playerState.isBall, - isUfo: playerState.isUfo, - isWave: playerState.isWave, - isSpider: playerState.isSpider, - isBird: playerState.isBird, - isDart: playerState.isDart, - isRobot: playerState.isRobot, - isSwing: playerState.isSwing, - isJetpack: playerState.isJetpack, - isFlying: playerState.isFlying, - isJumping: playerState.isJumping, - onGround: playerState.onGround, - canJump: playerState.canJump, - wasBoosted: playerState.wasBoosted, - rotation: playerState.rotation, - gravity: playerState.gravity, - jumpPower: playerState.jumpPower, - mirrored: playerState.mirrored, - isDashing: playerState.isDashing, - dashYVelocity: playerState.dashYVelocity, - ballShouldRotate: playerState.ballShouldRotate, - ballRotateOpposite: playerState.ballRotateOpposite, - ballNormalRotate: playerState.ballNormalRotate, - ballHitPad: playerState.ballHitPad, - robotHold: !!playerState._robotHold, - robotHoldTimer: playerState._robotHoldTimer || 0, - cameraX: cameraX, - flyFloorY: scene._level._flyFloorY, - flyCeilingY: scene._level._flyCeilingY, - flyGroundActive: scene._level._flyGroundActive, - flyVisualOnly: scene._level._flyVisualOnly, - flyVisualFloorInset: scene._level._flyVisualFloorInset, - flyVisualCeilingInset: scene._level._flyVisualCeilingInset, - groundTargetValue: scene._level._groundTargetValue, - flyCameraTarget: scene._level.flyCameraTarget, - groundAnimating: scene._level._groundAnimating, - groundAnimFrom: scene._level._groundAnimFrom, - groundAnimTo: scene._level._groundAnimTo, - groundAnimTime: scene._level._groundAnimTime, - groundAnimDuration: scene._level._groundAnimDuration, - cameraY: scene._cameraY, - groundStartScreenY: scene._level._groundStartScreenY, - ceilingStartScreenY: scene._level._ceilingStartScreenY, - groundY: scene._level._groundY, - ceilingY: scene._level._ceilingY, - speed: playerSpeed, - physicsFrame: scene._physicsFrame, - dualMode: !!scene._isDual, - dualGameMode: scene?._getDualModeId ? scene._getDualModeId(scene._state2) : null, - dualIsMini: !!scene._state2?.isMini, - dualY: scene._state2?.y, - dualYVelocity: scene._state2?.yVelocity, - dualGravityFlipped: scene._state2?.gravityFlipped, - dualOnGround: scene._state2?.onGround, - dualOnCeiling: scene._state2?.onCeiling, - dualCanJump: scene._state2?.canJump, - dualIsJumping: scene._state2?.isJumping, - timestamp: Date.now() - }; - this.checkpoints.push(checkpoint); - const checkpointSprite = scene.add.image(playerWorldX, b(playerState.y), "GJ_GameSheet02", "checkpoint_01_001.png") - .setOrigin(0.5, 0.5) - .setScrollFactor(1) - .setDepth(15) - .setScale(1.0); - scene._level.topContainer.add(checkpointSprite); - this.checkpointSprites.push(checkpointSprite); - return true; - } - deleteLastCheckpoint() { - if (this.checkpoints.length > 0) { - this.checkpoints.pop(); - if (this.checkpointSprites.length > 0) { - const lastSprite = this.checkpointSprites.pop(); - if (lastSprite && lastSprite.destroy) { - lastSprite.destroy(); - } - } - return true; - } - return false; - } - clearCheckpoints() { - this.checkpoints = []; - for (const sprite of this.checkpointSprites) { - if (sprite && sprite.destroy) { - sprite.destroy(); - } - } - this.checkpointSprites = []; - } - loadLastCheckpoint() { - if (this.checkpoints.length > 0) { - return this.checkpoints[this.checkpoints.length - 1]; - } - return null; - } -} - -class MacroBot { - constructor(scene) { - this.scene = scene; - this.resetAll(); - } - - resetAll() { - this.recording = false; - this.playing = false; - - this.cursor = 0; - this.isDown = false; - - this.inputs = []; - - this.meta = { - author: "Web Dashers", - level: "", // ill fix ts later - version: 1 - }; - } - - startRecording(meta = {}) { - this.resetAll(); - this.recording = true; - this.meta = { ...meta }; - } - - stopRecording() { - this.recording = false; - return this.exportObject(); - } - - clearRecording() { - this.inputs = []; - this.cursor = 0; - this.isDown = false; - } - - rollbackRecording(currentFrame) { - this.inputs = this.inputs.filter(ev => (ev.frame ?? 0) <= currentFrame); - this.cursor = 0; - this.isDown = false; - } - - clearPlayback() { - this.cursor = 0; - this.isDown = false; - } - - rollbackPlayback(currentFrame) { - if (!this.inputs.length) return; - - this.cursor = 0; - this.isDown = false; - - this.scene._releaseButton(true); - - while ( - this.cursor < this.inputs.length && - (this.inputs[this.cursor].frame ?? 0) <= currentFrame - ) { - const ev = this.inputs[this.cursor++]; - - if (ev.down) { - this.scene._pushButton(true); - this.isDown = true; - } else { - this.scene._releaseButton(true); - this.isDown = false; - } - } - } - - startPlayback(macroData) { - const macro = typeof macroData === "string" ? JSON.parse(macroData) : macroData; - - this.resetAll(); - this.playing = true; - - this.meta = { - ...this.meta, - ...(macro || {}) - }; - - this.inputs = Array.isArray(macro?.inputs) ? macro.inputs.slice() : []; - this.inputs.sort((a, b) => (a.frame ?? 0) - (b.frame ?? 0)); - - this.cursor = 0; - this.isDown = false; - } - - stopPlayback() { - this.playing = false; - this.cursor = 0; - this.isDown = false; - } - - recordEdge(down, currentFrame) { - if (!this.recording) return; - - const last = this.inputs[this.inputs.length - 1]; - if (last && last.down === !!down && last.frame === currentFrame) { - return; - } - - this.inputs.push({ - frame: currentFrame, - down: !!down - }); - - this.isDown = !!down; - } - - step(currentFrame) { - if (!this.playing) return; - - while ( - this.cursor < this.inputs.length && - (this.inputs[this.cursor].frame ?? 0) <= currentFrame - ) { - const ev = this.inputs[this.cursor++]; - - if (ev.down) { - if (!this.isDown) { - this.scene._pushButton(true); - this.isDown = true; - } - } else { - if (this.isDown) { - this.scene._releaseButton(true); - this.isDown = false; - } - } - } - } - - exportObject() { - return { - meta: this.meta, - inputs: this.inputs.slice() - }; - } - - exportString(pretty = false) { - return JSON.stringify(this.exportObject(), null, pretty ? 2 : 0); - } - - download(filename = "macro.wbgdr") { - const blob = new Blob([this.exportString(true)], { type: "application/json" }); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - a.remove(); - URL.revokeObjectURL(url); - } - - importFile(file) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = (event) => { - try { - const text = String(event.target.result || ""); - const macro = JSON.parse(text); - resolve(macro); - } catch (err) { - reject(err); - } - }; - reader.onerror = () => reject(reader.error || new Error("Failed to read macro file")); - reader.readAsText(file); - }); - } -} - -class GameScene extends Phaser.Scene { - constructor() { - super({ - key: "GameScene" - }); - } - create() { - this._bgSpeedX = 0.1; - this._bgSpeedY = 0.1; - this._menuCameraX = -centerX; - this._prevCameraX = -centerX; - this._bg = this.add.tileSprite(0, 0, screenWidth, screenHeight, "game_bg_01").setOrigin(0, 0).setScrollFactor(0).setDepth(-10); - this._applyMirroredBackgroundTexture("game_bg_01"); - this._cameraX = -centerX; - this._cameraY = 0; - this._cameraXRef = { - get value() { - return this._v; - }, - _v: -centerX - }; - this._state = new PlayerState(); - this._level = new window.LevelObject(this, this._cameraXRef); - this._levelEditor = new window.LevelEditor(this); - this._orbGfx = null; - this._orbGfxTimer = 0; - this._player = new PlayerObject(this, this._state, this._level); - this._player._activationKey = "main"; - this._state2 = new PlayerState(); - this._player2 = new PlayerObject(this, this._state2, this._level); - this._player2._activationKey = "dual"; - this._player2.setInvertedColors?.(true); - this._isDual = false; - this._player2.setCubeVisible(false); - this._player2.setShipVisible(false); - this._player2.setBallVisible(false); - this._player2.setWaveVisible(false); - this._player2.setBirdVisible?.(false); - this._player2.setSpiderVisible(false); - this._player2.setRobotVisible(false); - this._colorManager = new ColorManager(); - this._practicedMode = new PracticeMode(); - if (this._audio == null) { - this._audio = new AudioManager(this); - } - if (window._onlineLevelString && window._onlineLevelId && - window.currentlevel[2] === window._onlineLevelId) { - try { - this.cache.text.entries.set(window._onlineLevelId, window._onlineLevelString); - } catch(e) {} - } - let _0x591888 = this.cache.text.get(window.currentlevel[2]); - if (!_0x591888 && window._onlineLevelString && window.currentlevel[2] === window._onlineLevelId) { - _0x591888 = window._onlineLevelString; - } - if (_0x591888) { - this._level.loadLevel(_0x591888); - } - const _resolveGdArtId = (key, fallback = 1) => { - const raw = window.settingsMap?.[key]; - const parsed = parseInt(raw ?? fallback, 10); - return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; - }; - - const _bgGdId = _resolveGdArtId("kA6", parseInt(window._backgroundId || "01", 10) || 1); - window._backgroundId = String(_bgGdId).padStart(2, "0"); - - const _groundRaw = window.settingsMap?.["kA7"] ?? ((parseInt(window._groundId || "00", 10) || 0) + 1); - window._groundId = getGroundTextureId(_groundRaw); - - const _bgKey = "game_bg_" + getBackgroundTextureIndex(_bgGdId); - if (this.textures.exists(_bgKey)) { - this._applyMirroredBackgroundTexture(_bgKey); - } - this._level.applyGroundTexture(); - if (this._level._initialColors) { - for (let chId in this._level._initialColors) { - let col = this._level._initialColors[chId]; - this._colorManager.setInitialColor(parseInt(chId, 10), col); - } - } - this._level.createEndPortal(this); - this._glitterCenterX = 0; - this._glitterCenterY = T; - this._glitterEmitter = this.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - speed: 0, - scale: { - start: 0.375, - end: 0 - }, - alpha: { - start: 1, - end: 0 - }, - lifespan: { - min: 200, - max: 1800 - }, - frequency: 60, - blendMode: S, - tint: window.mainColor, - emitting: false, - emitCallback: _0x3c2a3e => { - _0x3c2a3e.x = this._glitterCenterX + (Math.random() * 2 - 1) * (screenWidth / 1.8); - _0x3c2a3e.y = this._glitterCenterY + (Math.random() * 2 - 1) * 320; - } - }); - this._level.additiveContainer.add(this._glitterEmitter); - this._bg.setTint(this._colorManager.getHex(fs)); - this._level.setGroundColor(this._colorManager.getHex(gs)); - this._level.setGround2Color?.(this._colorManager.getHex(1009)); - this._level.additiveContainer.setVisible(false); - this._level.container.setVisible(false); - this._level.topContainer.setVisible(false); - this._attempts = parseInt(localStorage.getItem("gd_totalAttempts") || "1", 10); - this._bestPercent = 0; - this._lastPercent = 0; - this._practiceBestPercent = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); - this._endPortalGameY = 240; - this._resetGameplayState(); - this._totalJumps = parseInt(localStorage.getItem("gd_totalJumps") || "0", 10); - this._totalDeaths = parseInt(localStorage.getItem("gd_totalDeaths") || "0", 10); - window._completedLevels = parseInt(localStorage.getItem("gd_completedLevels") || "0", 10); - this._playTime = 0; - this._menuActive = true; - this._slideIn = false; - this._slideGroundX = null; - this._firstPlay = true; - this._player.setCubeVisible(false); - this._player.setShipVisible(false); - this._player.setBallVisible(false); - this._logo = this.add.image(0, 100, "GJ_WebSheet", "GJ_logo_001.png").setScrollFactor(0).setDepth(30).setScale(1.2); - this._robLogo = this.add.image(110, 595, "GJ_WebSheet", "RobTopLogoBig_001.png").setScrollFactor(0).setDepth(30).setScale(0.525).setInteractive(); - this._makeBouncyButton(this._robLogo, 0.525, () => { - window.open("https://geometrydash.com", "_blank"); - }, () => this._menuActive); - const _socialIconDefs = [ - {frame: "", url: "", angle: 0, row: 0, col: 0 }, - {frame: "", url: "", angle: 0, row: 0, col: 1 }, - {frame: "", url: "", angle: 0, row: 0, col: 2 }, - {frame: "", url: "", angle: 0, row: 0, col: 3 }, - - { frame: "gj_twIcon_001.png", url: "https://x.com/rohanis0000gd", angle: 0, flipX: false, row: 1, col: 0 }, - { frame: "gj_ytIcon_001.png", url: "https://www.youtube.com/@rohanis0000gd", angle: 0, row: 1, col: 1 }, - { frame: "gj_tiktokIcon_001.png", url: "https://www.tiktok.com/@rohanis00000", angle: 0, flipX: false, row: 1, col: 2 }, - { frame: "gj_githubIcon_001.png", url: "https://github.com/web-dashers/web-dashers.github.io", angle: 0, row: 1, col: 3 }, - - {frame: "", url: "", angle: 0, row: 2, col: 0 }, - {frame: "", url: "", angle: 0, row: 2, col: 1 }, - {frame: "", url: "", angle: 0, row: 2, col: 2 }, - { frame: "gj_discordIcon_001.png", url: "https://discord.gg/TfEzAVWPSJ", angle: 0, row: 2, col: 3 }, - - - //{ frame: "gj_instaIcon_001.png", url: "https://www.instagram.com/", angle: -90, flipX: true, row: 1, col: 3 }, - //{ frame: "gj_twitchIcon_001.png", url: "https://www.twitch.tv/", angle: -90, flipX: true, row: 0, col: 0 }, - //{ frame: "gj_fbIcon_001.png", url: "https://www.facebook.com/", angle: 0, row: 0, col: 0 }, - //{ frame: "gj_rdIcon_001.png", url: "https://www.reddit.com/r/geometrydash/", angle: -90, flipX: true, row: 0, col: 0 }, - - ]; - const _socialScale = 0.75; - this._socialIcons = _socialIconDefs.map((def, index) => { - const icon = this.add.image(0, 0, "GJ_GameSheet03", def.frame) - .setScrollFactor(0) - .setDepth(30) - .setScale(_socialScale) - .setAngle(def.angle) - .setFlipX(!!def.flipX); - - if (!def.frame || def.frame.trim() === "") { - icon.setVisible(false); - icon.setActive(false); - return icon; - } - icon.setInteractive(); - this._makeBouncyButton(icon, _socialScale, () => { - window.open(def.url, "_blank"); - }, () => this._menuActive); - - return icon; - }); - - this._copyrightText = this.add.text(0, 625, "© 2026 RobTop Games · geometrydash.com", { - fontSize: "14px", - color: "#ffffff", - fontFamily: "Arial" - }).setOrigin(1, 1).setScrollFactor(0).setDepth(30).setAlpha(0.3); - this._tryMeImg = this.add.image(0, 150, "GJ_MenuBeta").setScrollFactor(0).setDepth(30).setScale(0.75); - this._downloadBtns = []; - const _0x4fc67f = [{ - key: "downloadSteam_001", - url: "https://github.com/web-dashers/web-dashers.github.io" - }, - { - key: "downloadApple_001", - url: "https://discord.gg/TfEzAVWPSJ" - }]; - for (let _0xfeaf5c = 0; _0xfeaf5c < _0x4fc67f.length; _0xfeaf5c++) { - const _0x1ce2a6 = _0x4fc67f[_0xfeaf5c]; - const _0x6bf69f = 1 / 1.5; - const _0x1d293f = this.add.image(0, 0, "GJ_WebSheet", _0x1ce2a6.key + ".png").setScrollFactor(0).setDepth(30).setScale(_0x6bf69f).setInteractive(); - this._makeBouncyButton(_0x1d293f, _0x6bf69f, () => window.open(_0x1ce2a6.url, "_blank"), () => this._menuActive); - this._downloadBtns.push(_0x1d293f); - } - const _0x28fa5b = this.scale.isFullscreen; -this._menuFsBtn = this.add.image(33, 33, "GJ_WebSheet", _0x28fa5b ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setAlpha(0.8).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); - this._expandHitArea(this._menuFsBtn, 1.5); - this._makeBouncyButton(this._menuFsBtn, 0.64, () => { - const _0x26b7c = !this.scale.isFullscreen; - this._menuFsBtn.setTexture("GJ_WebSheet", _0x26b7c ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png"); - this._expandHitArea(this._menuFsBtn, 1.5); - this._toggleFullscreen(); - }, () => this._menuActive); - this._menuInfoBtn = this.add.image(screenWidth + 20, 33, "GJ_GameSheet03", "communityCreditsBtn_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); - this._expandHitArea(this._menuInfoBtn, 1.5); - this._makeBouncyButton(this._menuInfoBtn, 0.64, () => { - this._buildInfoPopup(); - }, () => this._menuActive && !this._infoPopup); -this._menuUpdateLogBtn = this.add.image(screenWidth - 30 - 50, 33, "GJ_WebSheet", "GJ_infoIcon_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); - this._expandHitArea(this._menuUpdateLogBtn, 1.5); - this._makeBouncyButton(this._menuUpdateLogBtn, 0.64, () => { - this._buildUpdateLogPopup(); - }, () => this._menuActive && !this._updateLogPopup); - this._menuSettingsBtn = this.add.image(centerX + 92, screenHeight - 90, "GJ_GameSheet03", "GJ_optionsBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); - this._expandHitArea(this._menuSettingsBtn, 1); - this._makeBouncyButton(this._menuSettingsBtn, 1, () => { - this._showSettingsScreen(); - }, () => this._menuActive && !this._settingsPopup); - this._menuStatsBtn = this.add.image(centerX + 202, screenHeight - 90, "GJ_GameSheet03", "GJ_statsBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); - this._expandHitArea(this._menuStatsBtn, 1); - this._makeBouncyButton(this._menuStatsBtn, 1, () => { - this._showStatsScreen(); - }, () => this._menuActive); - this._menuAchievementsBtn = this.add.image(centerX - 12, screenHeight - 90, "GJ_GameSheet03", "GJ_achBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setTint(0x666666); - this._expandHitArea(this._menuAchievementsBtn, 1); - this._makeBouncyButton(this._menuAchievementsBtn, 1, () => { - }, () => this._menuActive); - this._menuNewgroundsBtn = this.add.image(centerX + 312, screenHeight - 90, "GJ_GameSheet03", "GJ_ngBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); - this._expandHitArea(this._menuNewgroundsBtn, 1); - this._makeBouncyButton(this._menuNewgroundsBtn, 1, () => { - this._buildNewgroundsPopup(); - }, () => this._menuActive && !this._newgroundsPopup); - this._menuGlitter = this.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - speed: 0, - scale: { - start: 0.5, - end: 0 - }, - alpha: { - start: 0.6, - end: 0.2 - }, - lifespan: { - min: 1000, - max: 2000 - }, - frequency: 35, - blendMode: S, - tint: 20670, - x: { - min: -130, - max: 130 - }, - y: { - min: -100, - max: 100 - } - }).setScrollFactor(0).setDepth(29); - this._playBtn = this.add.image(0, 0, "GJ_GameSheet04", "GJ_playBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); - this._playBtnPressed = false; - this._makeBouncyButton(this._playBtn, 1, () => { - this._openLevelSelect(); - }, () => this._menuActive && !this._playBtnPressed && !this._levelSelectOverlay); - // creator stuff - this._creatorBtn = this.add.image(0, 0, "GJ_GameSheet04", "GJ_creatorBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setScale(1); - this._creatorOverlay = null; - this._creatorOverlayObjects = null; - - this._openCreatorMenu = () => { - if (this._creatorOverlay) return; - this._creatorMenuOpen = true; - - const sw = screenWidth; - const sh = screenHeight; - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - - const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x00 + (0x01 - 0x00) * t); - const g1 = Math.round(0x65 + (0x2c - 0x65) * t); - const b1 = Math.round(0xff + (0x71 - 0xff) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - const bandY = Math.floor(gi * sh / gradientSteps); - const bandH = Math.ceil(sh / gradientSteps) + 1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, bandY, sw, bandH); - } - this._creatorOverlay = overlay; - - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) - .setScrollFactor(0).setDepth(101).setInteractive(); - - const cornerTL = this.add.image(0, 0, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(100).setOrigin(0, 0).setFlipY(true) - const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(152).setOrigin(0, 1).setFlipX(false) - - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true) - .setRotation(Math.PI).setInteractive(); - this._makeBouncyButton(backBtn, 1, () => this._closeCreatorMenu()); - - this._creatorOverlayObjects = [overlay, blocker, cornerTL, cornerBL, backBtn]; - - const menuButtons = [ - "GJ_createBtn_001.png", - "GJ_savedBtn_001.png", - "GJ_highscoreBtn_001.png", - "GJ_challengeBtn_001.png", - "GJ_versusBtn_001.png", - "GJ_mapBtn_001.png", - "GJ_dailyBtn_001.png", - "GJ_weeklyBtn_001.png", - "GJ_eventBtn_001.png", - "GJ_gauntletsBtn_001.png", - "GJ_featuredBtn_001.png", - "GJ_listsBtn_001.png", - "GJ_pathsBtn_001.png", - "GJ_mapPacksBtn_001.png", - "GJ_searchBtn_001.png", - ]; - - const cols = 5; - const btnScale = 0.77; - const btnSize = 209 * btnScale; - const gapX = 18; - const gapY = 18; - const gridW = cols * btnSize + (cols - 1) * gapX; - const gridStartX = sw / 2 - gridW / 2 + btnSize / 2; - const rows = Math.ceil(menuButtons.length / cols); - const gridH = rows * btnSize + (rows - 1) * gapY; - const gridStartY = sh / 2 - gridH / 2 + btnSize / 2; - menuButtons.forEach((frame, idx) => { - const col = idx % cols; - const row = Math.floor(idx / cols); - const bx = gridStartX + col * (btnSize + gapX); - const by = gridStartY + row * (btnSize + gapY); - const btn = this.add.image(bx, by, "GJ_GameSheet04", frame) - .setScrollFactor(0).setDepth(104).setScale(btnScale); - const isSearchButton = frame === "GJ_searchBtn_001.png"; - const isFeaturedButton = frame === "GJ_featuredBtn_001.png"; - const isEditorButton = frame === "GJ_createBtn_001.png"; - const isSavedButton = frame === "GJ_savedBtn_001.png"; - if (isSearchButton) { - btn.setInteractive(); - this._makeBouncyButton(btn, btnScale, () => { - this._closeCreatorMenu(true); - this._openSearchMenu(); - }, () => true); - } else if (isFeaturedButton) { - btn.setInteractive(); - this._makeBouncyButton(btn, btnScale, () => { - this._closeCreatorMenu(true); - this._openOnlineLevelsScene({ type: 6 }); - }, () => true); - } else if (isEditorButton) { - btn.setInteractive(); - this._makeBouncyButton(btn, btnScale, () => { - this._closeCreatorMenu(true); - this._openEditorMenu(); - }, () => true); - } else if (isSavedButton) { - btn.setInteractive(); - this._makeBouncyButton(btn, btnScale, () => { - this._closeCreatorMenu(true); - this._openSavedLevelsScene(); - }, () => true); - } else { - btn.setTint(0x666666); - } - this._creatorOverlayObjects.push(btn); - }); - }; - this._searchOverlay = null; - this._searchOverlayObjects = []; - this._playOverlay = null; - this._playOverlayObjects = []; - this._saveOnlineLevelToSavedList = (lvl) => { - if (!lvl || !lvl.id) return; - try { - const _savedKey = "gd_saved_online_levels"; - let _savedLevels = JSON.parse(localStorage.getItem(_savedKey) || "[]"); - const numericId = String(lvl.id); - const _alreadySaved = _savedLevels.some(sl => String(sl.id) === numericId); - if (!_alreadySaved) { - _savedLevels.unshift({ - id: numericId, - name: lvl.name || "Online Level", - author: lvl.author || "Unknown", - customSongID: lvl.customSongID || null, - songName: lvl.songName || "Unknown", - difficulty: lvl.difficulty || 0, - downloads: lvl.downloads || 0, - likes: lvl.likes || 0, - stars: lvl.stars || 0, - coins: lvl.coins || 0, - coinsVerified: lvl.coinsVerified || false, - length: lvl.length || 0, - featured: !!lvl.featured, - epic: lvl.epic || 0, - savedAt: Date.now() - }); - localStorage.setItem(_savedKey, JSON.stringify(_savedLevels)); - } - } catch (_e) {} - }; - this._openPlayMenu = (onBack = null) => { - if (this._playOverlay) return; - const sw = screenWidth; - const sh = screenHeight; - this._playMenuBackTarget = onBack || (() => this._openCreatorMenu()); - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(600); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - - const overlay = this.add.graphics().setScrollFactor(0).setDepth(500); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x00 + (0x01 - 0x00) * t); - const g1 = Math.round(0x65 + (0x2c - 0x65) * t); - const b1 = Math.round(0xff + (0x71 - 0xff) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - const bandY = Math.floor(gi * sh / gradientSteps); - const bandH = Math.ceil(sh / gradientSteps) + 1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, bandY, sw, bandH); - } - this._playOverlay = overlay; - - const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(502).setOrigin(0, 1).setFlipY(false); - const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(502).setOrigin(1, 1).setFlipX(true); - - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh).setScrollFactor(0).setDepth(501).setInteractive(); - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(504).setFlipX(true).setFlipY(true) - .setRotation(Math.PI).setInteractive(); - this._makeBouncyButton(backBtn, 1, () => { this._closePlayMenu(false, () => this._playMenuBackTarget()); }); - - this._playOverlayObjects.push(overlay, blocker, backBtn, cornerBL, cornerBR); - const lvl = window._selectedLevelData || {}; - if (lvl.id) localStorage.setItem("viewedLevel_" + lvl.id, "1"); - this._saveOnlineLevelToSavedList(lvl); - const centerX = sw / 2; - - const _diffFrames = [ - "difficulty_00_btn_001.png", "difficulty_01_btn_001.png", "difficulty_02_btn_001.png", - "difficulty_03_btn_001.png", "difficulty_04_btn_001.png", "difficulty_05_btn_001.png", - "difficulty_06_btn2_001.png", "difficulty_07_btn2_001.png", "difficulty_08_btn2_001.png", - "difficulty_09_btn2_001.png", "difficulty_10_btn2_001.png", "difficulty_auto_btn_001.png" - ]; - const _diffSizes = { - "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, - "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, - "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, - "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, - "difficulty_06_btn2_001.png": { w: 72, h: 88, rotated: false }, - "difficulty_07_btn2_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_08_btn2_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_09_btn2_001.png": { w: 74, h: 88, rotated: false }, - "difficulty_10_btn2_001.png": { w: 80, h: 91, rotated: false }, - "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, - }; - const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, lvl.difficulty || 0)); - const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; - const _targetH = 100, _maxW = 105; - const _scaleW = _diffMeta ? _diffMeta.w : 90; - const _scaleH = _diffMeta ? _diffMeta.h : 85; - const _iconScale = Math.min(_targetH / _scaleH, _maxW / _scaleW); - - const nameText = this.add.bitmapText(centerX, sh * 0.11 - 30, "bigFont", lvl.name || "Unknown", 50) - .setScrollFactor(0).setDepth(503).setOrigin(0.5); - this._fitBitmapText(nameText, sw * 0.7); - this._playOverlayObjects.push(nameText); - - const authorText = this.add.bitmapText(centerX, nameText.y + 42, "goldFont", "By " + (lvl.author || "Unknown"), 36) - .setScrollFactor(0).setDepth(503).setOrigin(0.5); - this._fitBitmapText(authorText, sw * 0.6); - this._playOverlayObjects.push(authorText); - - const playBtnY = sh * 0.36 - 15; - const playBtn2 = this.add.image(centerX, playBtnY, "GJ_GameSheet03", "GJ_playBtn2_001.png") - .setScrollFactor(0).setDepth(504).setInteractive(); - let playBtnLoading = false; - this._makeBouncyButton(playBtn2, 1, async () => { - if (playBtnLoading) return; - playBtnLoading = true; - this._audio.playEffect("playSound_01", { volume: 1 }); - playBtn2.setTint(0x666666); - playBtn2.disableInteractive(); - - let started = false; - try { - started = await this._playSelectedOnlineLevel(lvl); - } catch (err) { - console.warn("Failed to start selected online level", err); - } - - if (!started && playBtn2.scene) { - playBtnLoading = false; - playBtn2.clearTint(); - playBtn2.setInteractive(); - } - }, () => !playBtnLoading); - this._playOverlayObjects.push(playBtn2); - - const _playStatDefs = [ - { icon: "GJ_downloadsIcon_001.png", value: (Number(lvl.downloads) || 0).toLocaleString("en-US"), scale: 0.9 }, - { icon: "GJ_sLikeIcon_001.png", value: (Number(lvl.likes) || 0).toLocaleString("en-US"), scale: 1.3 }, - { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(lvl.length), scale: 0.9 } - ]; - const _playStatX = centerX + (playBtn2.displayWidth / 2) + 100; - const _playStatGap = 57; - const _playStatY0 = playBtnY - _playStatGap; - const _playStatMaxTextW = (sw - 30) - (_playStatX + 60); - _playStatDefs.forEach((stat, i) => { - const _statY = _playStatY0 + i * _playStatGap; - const statIcon = this.add.image(_playStatX, _statY, "GJ_GameSheet03", stat.icon) - .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(stat.scale); - this._playOverlayObjects.push(statIcon); - const statText = this.add.bitmapText(_playStatX + statIcon.displayWidth / 2 + 12, _statY, "bigFont", stat.value, 30) - .setScrollFactor(0).setDepth(503).setOrigin(0, 0.5); - this._fitBitmapText(statText, _playStatMaxTextW); - this._playOverlayObjects.push(statText); - }); - - const diffIconX = centerX - (playBtn2.displayWidth / 2) - 100; - const diffIconY = playBtnY; - const diffIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", _diffFrames[diffIdx]) - .setScrollFactor(0).setDepth(503).setOrigin(0.5) - if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); - this._playOverlayObjects.push(diffIcon); - - let coinIcon = null; - if (lvl.epic >= 3) { - coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin3_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); - } else if (lvl.epic === 2) { - coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin2_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); - } else if (lvl.epic === 1) { - coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); - } else if (lvl.featured) { - coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_featuredCoin_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); - } - if (coinIcon) this._playOverlayObjects.push(coinIcon); - - const _progressKeyId = "online_" + (lvl.id || "0"); - const _bestNormal = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); - const _bestPractice = parseFloat(localStorage.getItem("practiceBestPercent_" + _progressKeyId) || "0"); - - const _barFrame = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); - const _barW = _barFrame ? _barFrame.width : 680; - const _barH = _barFrame ? _barFrame.height : 40; - - const normalBarY = sh * 0.58 - 15; - const normalLabel = this.add.bitmapText(centerX, normalBarY - 30, "bigFont", "Normal Mode", 32) - .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(0.78); - const normalBarBg = this.add.image(centerX, normalBarY, "GJ_WebSheet", "GJ_progressBar_001.png") - .setScrollFactor(0).setDepth(503).setTint(0).setAlpha(125 / 255).setScale(0.7, 0.69); - const normalFillW = Math.max(1, Math.floor(_barW * (_bestNormal / 100))); - const normalBarFg = this.add.image(centerX - _barW * 0.695 / 2, normalBarY, "GJ_WebSheet", "GJ_progressBar_001.png") - .setScrollFactor(0).setDepth(503).setTint(0x00ff00).setScale(0.695, 0.57).setOrigin(0, 0.5) - .setCrop(0, 0, normalFillW, _barH); - const normalPctText = this.add.bitmapText(centerX, normalBarY, "bigFont", _bestNormal + "%", 30) - .setScrollFactor(0).setDepth(504).setOrigin(0.5).setScale(0.7); - this._playOverlayObjects.push(normalLabel, normalBarBg, normalBarFg, normalPctText); - - const practiceBarY = sh * 0.70 - 25; - const practiceLabel = this.add.bitmapText(centerX, practiceBarY - 30, "bigFont", "Practice Mode", 32) - .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(0.78); - const practiceBarBg = this.add.image(centerX, practiceBarY, "GJ_WebSheet", "GJ_progressBar_001.png") - .setScrollFactor(0).setDepth(503).setTint(0).setAlpha(125 / 255).setScale(0.7, 0.7); - const practiceFillW = Math.max(1, Math.floor(_barW * (_bestPractice / 100))); - const practiceBarFg = this.add.image(centerX - _barW * 0.695 / 2, practiceBarY, "GJ_WebSheet", "GJ_progressBar_001.png") - .setScrollFactor(0).setDepth(503).setTint(0x00ffff).setScale(0.695, 0.57).setOrigin(0, 0.5) - .setCrop(0, 0, practiceFillW, _barH); - const practicePctText = this.add.bitmapText(centerX, practiceBarY, "bigFont", _bestPractice + "%", 30) - .setScrollFactor(0).setDepth(504).setOrigin(0.5).setScale(0.7); - this._playOverlayObjects.push(practiceLabel, practiceBarBg, practiceBarFg, practicePctText); - const sideBtnX = sw - 55; - const sideBtnGap = sh * 0.16; - const sideBtnY0 = sh * 0.08 - 100; - const sideBtnScale = 1; - - const rateLockBtn = this.add.image(55, sideBtnY0 + 350, "GJ_GameSheet03", "GJ_duplicateBtn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); - this._makeBouncyButton(rateLockBtn, sideBtnScale, () => { - this._duplicateOnlineLevelToEditor(lvl); - }); - - const closeBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap, "GJ_GameSheet03", "GJ_deleteBtn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); - this._makeBouncyButton(closeBtn, sideBtnScale, () => { - this._closePlayMenu(false, () => this._playMenuBackTarget()); - }); - - const refreshBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 2, "GJ_GameSheet03", "GJ_updateBtn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); - this._makeBouncyButton(refreshBtn, sideBtnScale, () => { - const backTarget = this._playMenuBackTarget; - this._closePlayMenu(true, () => this._openPlayMenu(backTarget)); - }); - - const infoBtn2 = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 3, "GJ_GameSheet03", "GJ_infoBtn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); - this._makeBouncyButton(infoBtn2, sideBtnScale, () => { - }); - - const leaderboardBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 4, "GJ_GameSheet03", "GJ_levelLeaderboardBtn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); - this._makeBouncyButton(leaderboardBtn, sideBtnScale, () => { - }); - - const likeBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 5, "GJ_GameSheet03", "GJ_like2Btn_001.png") - .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); - this._makeBouncyButton(likeBtn, sideBtnScale, () => { - }); - - this._playOverlayObjects.push(rateLockBtn, closeBtn, refreshBtn, infoBtn2, leaderboardBtn, likeBtn); - const songBoxW = sw * 0.55; - const songBoxH = 190; - const songBoxY = sh - 95; - const _squareCorner = 0.325 * this.textures.get("GJ_square01").source[0].width; - const songBox = this.add.nineslice(centerX, songBoxY, "GJ_square01", null, songBoxW, songBoxH, _squareCorner, _squareCorner, _squareCorner, _squareCorner) - .setScrollFactor(0).setDepth(503).setOrigin(0.5); - this._playOverlayObjects.push(songBox); - - const songNameText = this.add.bitmapText(centerX - songBoxW / 2 + 20, songBoxY - 60, "bigFont", lvl.songName || "Unknown", 50) - .setScrollFactor(0).setDepth(504).setOrigin(0, 0.5) - this._fitBitmapText(songNameText, songBoxW - 100); - this._playOverlayObjects.push(songNameText); - let songAuthor = "Unknown"; - - const songAuthorText = this.add.bitmapText(centerX - songBoxW / 2 + 20, songBoxY - 15, "goldFont", "By: " + songAuthor, 36) - .setScrollFactor(0).setDepth(504).setOrigin(0, 0.5) - this._fitBitmapText(songAuthorText, songBoxW - 100); - this._playOverlayObjects.push(songAuthorText); - - if (lvl.customSongID) { - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - if (!PROXY_BASE) { - console.warn("Play menu song author: window._gdProxyUrl is not configured"); - } else { - fetch(`${PROXY_BASE}/getGJSongInfo.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `songID=${lvl.customSongID}&secret=Wmfd2893gb7` - }) - .then(res => (res.ok ? res.text() : "-1")) - .then(ngText => { - if (!ngText || ngText === "-1") return; - const ngParts = ngText.split("~|~"); - const ngMap = {}; - for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; - - const artistName = (ngMap["4"] || "Unknown").trim(); - if (artistName) { - songAuthor = artistName; - songAuthorText.setText("By: " + songAuthor); - this._fitBitmapText(songAuthorText, songBoxW - 100); - } - }) - .catch(err => { - console.warn("Failed to fetch song author:", err); - }); - } - } - }; - this._closePlayMenu = (silent = false, onComplete = null) => { - if (!this._playOverlay) return; - const destroy = () => { - for (const obj of this._playOverlayObjects) { - if (obj && obj.destroy) obj.destroy(); - } - this._playOverlayObjects = []; - this._playOverlay = null; - }; - if (silent) { destroy(); if (onComplete) onComplete(); return; } - const sw = screenWidth, sh = screenHeight; - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(600).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ - targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", - onComplete: () => { - destroy(); - if (onComplete) onComplete(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._playSelectedOnlineLevel = async (lvl) => { - if (!lvl || !lvl.id) return false; - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - if (!PROXY_BASE) { console.warn("Play online level: window._gdProxyUrl is not configured"); return false; } - try { - const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `levelID=${lvl.id}&secret=Wmfd2893gb7` - }); - if (!res.ok) throw new Error(`Proxy returned ${res.status}`); - const rawResponse = await res.text(); - if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) return false; - - const lvlParts = rawResponse.split("#")[0].split(":"); - const m = {}; - for (let i = 0; i + 1 < lvlParts.length; i += 2) m[lvlParts[i]] = lvlParts[i + 1]; - - const levelString = m["4"] || null; - const officialSong = parseInt(m["12"]) || 0; - const customSongID = (m["35"] || "").trim(); - const isCustomSong = !!customSongID && customSongID !== "0"; - const offset = parseFloat(m["45"] || "0") || 0; - - window._onlineLevelId = "online_" + lvl.id; - window._onlineLevelString = levelString; - window._onlineLevelName = lvl.name || "Online Level"; - window._onlineSongOffset = offset; - window._onlineSongBuffer = null; - window._onlineSongKey = null; - - let songKey = (window.allLevels && window.allLevels[officialSong]) ? window.allLevels[officialSong][0] : `ng_song_${customSongID}`; - let songArtist = "Unknown"; - let songTitle = null; - - if (isCustomSong) { - songKey = `ng_song_${customSongID}`; - try { - const ngRes = await fetch(`${PROXY_BASE}/getGJSongInfo.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `songID=${customSongID}&secret=Wmfd2893gb7` - }); - const ngText = ngRes.ok ? await ngRes.text() : "-1"; - if (ngText && ngText !== "-1") { - const ngParts = ngText.split("~|~"); - const ngMap = {}; - for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; - const songUrl = decodeURIComponent((ngMap["10"] || "").trim()); - songArtist = (ngMap["4"] || "Unknown").replace(/:$/, "").trim(); - songTitle = (ngMap["2"] || "").trim() || null; - if (songUrl) { - const audioCtx = this.game.sound.context; - if (audioCtx.state === "suspended") await audioCtx.resume(); - const proxiedUrl = songUrl.includes("geometrydashfiles.b-cdn.net") - ? songUrl - : `${PROXY_BASE}/audio-proxy?url=${encodeURIComponent(songUrl)}`; - const audioRes = await fetch(proxiedUrl); - const arrayBuf = await audioRes.arrayBuffer(); - const decoded = await audioCtx.decodeAudioData(arrayBuf); - window._onlineSongBuffer = decoded; - window._onlineSongKey = songKey; - } - } - } catch (err) { - console.warn("Failed to load custom song for online level", err); - } - } else if (window.allLevels && window.allLevels[officialSong]) { - songArtist = window.allLevels[officialSong][3] || "Unknown"; - } - window.currentlevel = [songKey, window._onlineLevelName, window._onlineLevelId, ["Online", songArtist]]; - this.game.registry.set("autoStartGame", true); - window._onlineReturnToPlayMenu = { lvl, backTarget: this._playMenuBackTarget }; - this._closePlayMenu(false, () => this.scene.restart()); - return true; - } catch (err) { - console.warn("Failed to start online level", err); - return false; - } - }; - this._duplicateOnlineLevelToEditor = async (lvl) => { - if (!lvl || !lvl.id) return; - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - if (!PROXY_BASE) { console.warn("Duplicate level: window._gdProxyUrl is not configured"); return; } - try { - const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `levelID=${lvl.id}&secret=Wmfd2893gb7` - }); - if (!res.ok) throw new Error(`Proxy returned ${res.status}`); - const rawResponse = await res.text(); - if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) return; - - const lvlParts = rawResponse.split("#")[0].split(":"); - const m = {}; - for (let i = 0; i + 1 < lvlParts.length; i += 2) m[lvlParts[i]] = lvlParts[i + 1]; - - const levelString = m["4"] || ""; - if (!levelString) { console.warn("Duplicate level: no level data in response"); return; } - - const officialSong = parseInt(m["12"]) || 0; - const customSongID = (m["35"] || "").trim(); - const isCustomSong = !!customSongID && customSongID !== "0"; - const levelVersion = parseInt(m["16"]) || 1; - - let songName, songId; - if (isCustomSong) { - songId = parseInt(customSongID) || 0; - songName = lvl.songName || `NG#${customSongID}`; - } else { - songId = -officialSong - 1; - try { songName = window.allLevels[officialSong][1]; } catch (e) { songName = lvl.songName || "Unknown"; } - } - - const rawLevels = localStorage.getItem("created_levels"); - const createdLevels = rawLevels ? JSON.parse(rawLevels) : []; - - const newLevel = { - levelName: lvl.name || "Unknown", - song: songName, - songId: songId, - levelId: lvl.id, - levelString: levelString, - levelLength: lvl.length || 0, - normalBest: 0, - practiceBest: 0, - description: lvl.description || "", - version: levelVersion, - status: "Unverified", - createdId: this._getNextLocalId() - }; - - createdLevels.push(newLevel); - localStorage.setItem("created_levels", JSON.stringify(createdLevels)); - - this._audio.playEffect("build_01"); - this._closePlayMenu(false, () => this._openLevelView(newLevel)); - } catch (err) { - console.warn("Failed to duplicate level to editor:", err); - } - }; - this._openEditorMenu = () => { - if (this._editorOverlay) return; - const sw = screenWidth; - const sh = screenHeight; - const centerX = sw / 2; - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - - const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x00 + (0x01 - 0x00) * t); - const g1 = Math.round(0x65 + (0x2c - 0x65) * t); - const b1 = Math.round(0xff + (0x71 - 0xff) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, Math.floor(gi * sh / gradientSteps), sw, Math.ceil(sh / gradientSteps) + 1); - } - this._editorOverlay = overlay; - - const blocker = this.add.zone(centerX, sh / 2, sw, sh).setScrollFactor(0).setDepth(101).setInteractive(); - const container = this.add.container(0, 0).setScrollFactor(0).setDepth(102); - - const tableW = 712; - const tableH = 460; - const tableX = (sw - tableW) / 2; - const tableY = 85; - - const rawData = localStorage.getItem("created_levels"); - const createdLevels = rawData ? JSON.parse(rawData) : []; - - createdLevels.sort((a, b) => { - const idA = parseInt(a.createdId.replace("local_", "")) || 0; - const idB = parseInt(b.createdId.replace("local_", "")) || 0; - return idB - idA; - }); - - const nameCounts = {}; - const levelRevisions = {}; - - createdLevels.forEach(lvl => { - const name = lvl.levelName; - if (!nameCounts[name]) { - nameCounts[name] = 1; - levelRevisions[lvl.createdId] = ""; - } else { - levelRevisions[lvl.createdId] = `Rev. ${nameCounts[name]}`; - nameCounts[name]++; - } - }); - - const lengthValues = ["Tiny", "Short", "Medium", "Long", "XL", "Plat."] - - const listContainer = this.add.container(0, 0); - const maskShape = this.add.graphics().fillStyle(0xffffff).fillRect(tableX, tableY, tableW, tableH).setVisible(false); - const mask = maskShape.createGeometryMask(); - listContainer.setMask(mask); - container.add(this.add.graphics().setScrollFactor(0).setDepth(90).fillStyle(0xc2723e, 1).fillRect(tableX, tableY, tableW, tableH)); - container.add(listContainer); - - createdLevels.forEach((level, index) => { - const spacing = 100; - const slotY = (index * spacing) + (spacing / 2); - - const isOdd = index % 2 !== 0; - const stripeColor = isOdd ? 0xc2723e : 0xa1582c; - - const bgStripe = this.add.rectangle(centerX, slotY, tableW - 10, spacing, stripeColor, 1); - const separator = this.add.rectangle(centerX, slotY + (spacing / 2), tableW - 10, 1, 0x502c16, 1); - const nameTxt = this.add.bitmapText(tableX + 20, slotY - 22, "bigFont", level.levelName, 32).setOrigin(0, 0.5); - const revLabel = levelRevisions[level.createdId]; - const revText = this.add.bitmapText( - nameTxt.x + nameTxt.width + 10, - nameTxt.y + 5, - "goldFont", - revLabel, - 20 - ).setOrigin(0, 0.5); - const infoY = slotY + 18; - const lenIcon = this.add.image(tableX + 35, infoY, "GJ_GameSheet03", "GJ_timeIcon_001.png").setScale(0.65); - const lenTxt = this.add.bitmapText(lenIcon.x + 22, infoY, "bigFont", lengthValues[parseInt(level.levelLength, 10)] || "Tiny", 18).setOrigin(0, 0.5); - const songIcon = this.add.image(tableX + 150, infoY, "GJ_GameSheet03", "GJ_musicIcon_001.png").setScale(0.65); - const songTxt = this.add.bitmapText(songIcon.x + 22, infoY, "bigFont", level.song, 18).setOrigin(0, 0.5); - const statusIcon = this.add.image(tableX + 380, infoY, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScale(0.65); - const songTxtMaxW = Math.max(20, (statusIcon.x - 25) - songTxt.x); - songTxt.setScale(1); - if (songTxt.width > songTxtMaxW) { - songTxt.setScale(songTxtMaxW / songTxt.width); - } - const statusTxt = this.add.bitmapText(statusIcon.x + 22, infoY, "bigFont", level.status, 18).setOrigin(0, 0.5); - - const viewBtn = this.add.nineslice(tableX + tableW - 80, slotY, "GJ_button01", null, 120, 60, 24, 24, 24, 24 ).setScale(0.75).setInteractive(); - const viewTxt = this.add.bitmapText(viewBtn.x - 2, viewBtn.y - 1, "bigFont", "View", 32).setOrigin(0.5).setScale(0.8); - - this._makeCompositeBouncyButton(viewBtn, [viewBtn, viewTxt], 0.75, () => { - this._closeEditorMenu(false); - this._openLevelView(level); - }); - - listContainer.add([bgStripe, separator, nameTxt, revText, lenIcon, lenTxt, songIcon, songTxt, statusIcon, statusTxt, viewBtn, viewTxt]); - }); - if (createdLevels.length === 0) { - container.add(this.add.bitmapText(centerX, tableY + (tableH/2), "bigFont", "No Levels", 30).setOrigin(0.5).setAlpha(0.5)); - } - const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const sideScaleY = tableH / sideFrame.height; - container.add(this.add.image(tableX - 40, tableY, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, sideScaleY)); - container.add(this.add.image(tableX + tableW + 40, tableY, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY)); - container.add(this.add.image(centerX, tableY - 10, "GJ_WebSheet", "GJ_table_top_001.png")); - container.add(this.add.image(centerX, tableY + tableH + 20, "GJ_WebSheet", "GJ_table_bottom_001.png")); - container.add(this.add.bitmapText(centerX, tableY - 15, "bigFont", "My Levels", 42).setOrigin(0.5).setScale(1.1)); - - let startY = tableY; - const listHeight = createdLevels.length * 100; - const minY = tableY - Math.max(0, listHeight - tableH) - 10; - const maxY = tableY + 22; - - listContainer.y = maxY; - this._scrollTargetY = maxY; - this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => { - if (!this._editorOverlay) return; - this._scrollTargetY -= deltaY; - this._scrollTargetY = Phaser.Math.Clamp(this._scrollTargetY, minY, maxY); - - this.tweens.add({ - targets: listContainer, - y: this._scrollTargetY, - duration: 250, - ease: 'Power2', - overwrite: true - }); - }); - blocker.on('pointerdown', (pointer) => { - startY = pointer.y - listContainer.y; - }); - - blocker.on('pointermove', (pointer) => { - if (pointer.isDown) { - listContainer.y = pointer.y - startY; - listContainer.y = Phaser.Math.Clamp(listContainer.y, minY, maxY); - } - }); - - const newBtnX = sw - 60; - const newBtnY = sh - 55; - const newBtn = this.add.image(newBtnX, newBtnY, "GJ_GameSheet03", "GJ_newBtn_001.png") - .setScale(0.9) - .setInteractive(); - - this._makeBouncyButton(newBtn, 0.9, () => { - const rawData = localStorage.getItem("created_levels"); - let createdLevels = rawData ? JSON.parse(rawData) : []; - - let counter = 0; - while (createdLevels.some(lvl => lvl.levelName === "Unnamed " + counter)) { - counter++; - } - const newName = "Unnamed " + counter; - - const newLevel = { - levelName: newName, - song: "Stereo Madness", - songId: -1, - levelId: null, - levelString: "H4sIAAAAAAAACq1QwRHDMAhbyO0hwIlzfWWGDsAAXaHD10Z-9Ff3Ln4gG4GMeD2tFYRLaEBrWGitARCUwKTHDbEFRCT2wF3yBOrXvYVEC7wRKSi6JoirBY8FwdHB9iVJjZ5ckP1rlf19taIv7pLGh-wP43XROPq9z9mOtX1uS7LldcKKzPx41ZKwEbz0yPueUSfPF9qApx3kMlrGJE7PSBbCIlYpy5QVuheMciE0AgiaoFRUihk5I2ec0Knp1PTK9slxYDM2OIFmjL8bv-1mBmB6YrvO4UErHR4fJXMaP9sDAAA=", - levelLength: 0, - normalBest: 0, - practiceBest: 0, - description: "", - version: 1, - status: "Unverified", - createdId: this._getNextLocalId() - }; - - createdLevels.push(newLevel); - localStorage.setItem("created_levels", JSON.stringify(createdLevels)); - - this._closeEditorMenu(); - this._openLevelView(newLevel); - - this._audio.playEffect("build_01"); - }); - container.add(newBtn); - - const importBtn = this.add.image(newBtnX, newBtnY - 90, "import").setScale(0.3).setInteractive(); - this._makeBouncyButton(importBtn, 0.3, () => { - this._importGMD(); - }); - container.add(importBtn); - - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true).setRotation(Math.PI).setInteractive(); - - this._makeBouncyButton(backBtn, 1, () => { - this._closeEditorMenu(); - this._openCreatorMenu(); - }); - - this._editorObjects = [overlay, blocker, container, backBtn, maskShape]; - }; - this._importGMD = () => { - const fileInput = document.createElement('input'); - fileInput.type = 'file'; - fileInput.accept = '.gmd'; - - fileInput.onchange = (e) => { - const file = e.target.files[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = (event) => { - const content = event.target.result; - try { - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(content, "text/xml"); - const keys = xmlDoc.querySelectorAll("key, k"); - - let extracted = { - name: "Imported Level", - data: "", - version: 1, - length: 0, - id: "NA", - desc: "", - officialSongId: 0, - customSongId: 0 - }; - - keys.forEach(keyNode => { - const k = keyNode.textContent; - const v = keyNode.nextElementSibling; - if (!v) return; - const val = v.textContent; - - if (k === "k2") extracted.name = val; - if (k === "k4") extracted.data = val; - if (k === "k1") extracted.id = val; - if (k === "k23") extracted.length = parseInt(val) || 0; - if (k === "k16") extracted.version = parseInt(val) || 1; - if (k === "k8") extracted.officialSongId = parseInt(val) || 0; - if (k === "k45") extracted.customSongId = parseInt(val) || 0; - if (k === "k3") { - try { extracted.desc = atob(val); } catch(e) { extracted.desc = val; } - } - }); - - if (!extracted.data) throw new Error("No level string found."); - - let finalSongName = "Stereo Madness"; - let finalSongId = -1; - - if (extracted.customSongId > 0) { - finalSongId = extracted.customSongId; - finalSongName = `NG#${extracted.customSongId}`; - } else { - finalSongId = -extracted.officialSongId -1; - try { - finalSongName = window.allLevels[extracted.officialSongId][1]; - } catch(e) { - finalSongName = "Unknown"; - } - } - - const rawLevels = localStorage.getItem("created_levels"); - let createdLevels = rawLevels ? JSON.parse(rawLevels) : []; - - const newLevel = { - levelName: extracted.name, - song: finalSongName, - songId: finalSongId, - levelId: (extracted.id === "0" || !extracted.id) ? "NA" : extracted.id, - levelString: extracted.data, - levelLength: extracted.length, - normalBest: 0, - practiceBest: 0, - description: extracted.desc || "", - version: extracted.version, - status: "Unverified", - createdId: this._getNextLocalId() - }; - - createdLevels.push(newLevel); - localStorage.setItem("created_levels", JSON.stringify(createdLevels)); - - this._closeEditorMenu(false); - this._openLevelView(newLevel); - - } catch (err) { - console.error("GMD Import Error:", err); - alert("Failed to parse .gmd: " + err.message); - } - }; - reader.readAsText(file); - }; - - fileInput.click(); - }; - this._escapeXml = (value) => { - return String(value ?? "") - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); - }; - this._decodeWebLevelStringForGMD = (levelString) => { - if (!levelString) return ""; - try { - let base64 = String(levelString) - .trim() - .replace(/-/g, "+") - .replace(/_/g, "/"); - - while (base64.length % 4 !== 0) { - base64 += "="; - } - const binary = atob(base64); - const bytes = new Uint8Array(binary.length); - for (let i = 0; i < binary.length; i++) { - bytes[i] = binary.charCodeAt(i); - } - return pako.inflate(bytes, { to: "string" }); - } catch (err) { - console.warn("Why the fuck didnt it work", err); - return String(levelString); - } - }; - this._exportGMD = (level) => { - const encodedDesc = btoa(unescape(encodeURIComponent(level.description || ""))); - const authorName = "Web Dashers"; - const officialSong = level.songId < 0 ? Math.abs(level.songId) : 0; - const customSong = level.songId > 0 ? level.songId : 0; - const rawLevelData = this._decodeWebLevelStringForGMD(level.levelString); - const safeName = this._escapeXml(level.levelName || "Unnamed"); - const safeDesc = this._escapeXml(encodedDesc); - const safeAuthor = this._escapeXml(authorName); - const safeLevelData = this._escapeXml(rawLevelData); - - let xml = ""; - xml += ''; - xml += ''; - xml += ''; - xml += 'kCEK4'; - xml += `k1${ - level.levelId && level.levelId !== "NA" - ? String(level.levelId).replace(/\D/g, "") - : 0 - }`; - xml += `k2${safeName}`; - xml += `k3${safeDesc}`; - xml += `k4${safeLevelData}`; - xml += `k5${safeAuthor}`; - xml += `k8${officialSong - 1}`; - xml += `k45${customSong}`; - xml += `k16${level.version || 1}`; - xml += `k18${level.levelLength || 0}`; - xml += `k23${level.levelLength || 0}`; - xml += 'k13'; - xml += 'k212'; - xml += 'k5047'; - xml += 'k1010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0'; - xml += 'kI10'; - xml += 'kI20'; - xml += 'kI30.1'; - xml += 'kI6'; - xml += '00102030'; - xml += '40506070'; - xml += '8090100110'; - xml += '120130'; - xml += ''; - xml += ''; - xml += ''; - - const blob = new Blob([xml], { type: "text/xml" }); - const url = window.URL.createObjectURL(blob); - const link = document.createElement("a"); - const fileName = `${String(level.levelName || "Unnamed").replace(/[^a-z0-9]/gi, "_")}.gmd`; - - link.href = url; - link.download = fileName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - window.URL.revokeObjectURL(url); - }; - this._getNextLocalId = () => { - const rawData = localStorage.getItem("created_levels"); - const levels = rawData ? JSON.parse(rawData) : []; - let maxId = 0; - levels.forEach(l => { - if (l.createdId && typeof l.createdId === "string") { - const idNum = parseInt(l.createdId.split('_')[1]); - if (!isNaN(idNum) && idNum > maxId) { - maxId = idNum; - } - } - }); - return "local_" + (maxId + 1); - }; - this._openLevelView = (level) => { - const sw = screenWidth; - const sh = screenHeight; - const centerX = sw / 2; - const saveToLS = (key, val) => { - const rawData = localStorage.getItem("created_levels"); - let levels = rawData ? JSON.parse(rawData) : []; - const idx = levels.findIndex(l => l.createdId === level.createdId); - if (idx !== -1) { - levels[idx][key] = val; - localStorage.setItem("created_levels", JSON.stringify(levels)); - } - }; - const deleteLevel = () => { - if (!confirm(`Are you sure you want to delete ${level.levelName}?`)) return; - const rawData = localStorage.getItem("created_levels"); - let levels = rawData ? JSON.parse(rawData) : []; - levels = levels.filter(l => l.createdId !== level.createdId); - localStorage.setItem("created_levels", JSON.stringify(levels)); - cleanup(); - this._openEditorMenu(); - }; - this._activeInput = null; - let cursorVisible = true; - - const blocker = this.add.zone(centerX, sh / 2, sw, sh) - .setOrigin(0.5).setDepth(101).setInteractive(); - blocker.on('pointerdown', () => { this._activeInput = null; }); - const overlay = this.add.graphics().setScrollFactor(0).setDepth(102); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x00 + (0x01 - 0x00) * t); - const g1 = Math.round(0x65 + (0x2c - 0x65) * t); - const b1 = Math.round(0xff + (0x71 - 0xff) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, Math.floor(gi * sh / gradientSteps), sw, Math.ceil(sh / gradientSteps) + 1); - } - - const container = this.add.container(0, 0).setDepth(150); - const boxWidth = sw * 0.6; - const cornerRad = 18; - - const nameY = 50; - const nameBox = this.add.graphics().setDepth(151).setInteractive(new Phaser.Geom.Rectangle(centerX - (boxWidth / 2), nameY - 28, boxWidth, 70), Phaser.Geom.Rectangle.Contains); - nameBox.fillStyle(0x000000, 0.3).fillRoundedRect(centerX - (boxWidth / 2), nameY - 28, boxWidth, 70, cornerRad); - const titleText = this.add.bitmapText(centerX, nameY + 5, "bigFont", level.levelName, 45).setOrigin(0.5).setDepth(152); - const titleCursor = this.add.bitmapText(0, nameY + 5, "bigFont", "|", 45).setOrigin(0, 0.5).setDepth(153).setVisible(false); - - const descY = 180; - const descH = 120; - const descBox = this.add.graphics().setDepth(151).setInteractive(new Phaser.Geom.Rectangle(centerX - (boxWidth / 2), descY - (descH / 2), boxWidth, descH), Phaser.Geom.Rectangle.Contains); - descBox.fillStyle(0x000000, 0.3).fillRoundedRect(centerX - (boxWidth / 2), descY - (descH / 2), boxWidth, descH, cornerRad); - const descText = this.add.text(centerX, descY, level.description || "Description [Optional]", { - fontFamily: "Helvetica, Arial, sans-serif", - fontSize: "22px", - color: "#ffffff", - align: "center", - lineSpacing: 4, - wordWrap: { width: boxWidth - 40, useAdvancedWrap: true } - }).setOrigin(0.5).setDepth(152); - const descCursor = this.add.text(0, 0, "|", { fontFamily: "Helvetica", fontSize: "18px", color: "#ffffff" }) - .setOrigin(0.5).setDepth(153).setVisible(false); - - const updateDisplay = () => { - titleText.setText(level.levelName); - if (this._activeInput === 'title') { - titleCursor.setPosition(titleText.x + (titleText.width / 2) + 2, nameY + 5).setVisible(cursorVisible); - descCursor.setVisible(false); - } - else if (this._activeInput === 'desc') { - descText.setText(level.description || ""); - titleCursor.setVisible(false); - - const lines = descText.getWrappedText(level.description || ""); - const lineCount = lines.length; - const lastLine = lines[lineCount - 1] || ""; - const metrics = descText.canvas.getContext('2d').measureText(lastLine); - const lastLineWidth = metrics.width; - - const size = 22; - const spacing = 4; - const fullLineHeight = size + spacing; - const totalHeight = (lineCount * fullLineHeight) - spacing; - - const topOfText = descY - (totalHeight / 2); - const cursorY = topOfText + ((lineCount - 1) * fullLineHeight) + (size / 2); - - descCursor.setPosition(centerX + (lastLineWidth / 2) + 2, cursorY).setVisible(cursorVisible); - } else { - descText.setText(level.description || "Description [Optional]"); - titleCursor.setVisible(false); - descCursor.setVisible(false); - } - }; - - const cursorInterval = setInterval(() => { - cursorVisible = !cursorVisible; - updateDisplay(); - }, 500); - - const keyHandler = (event) => { - if (!this._activeInput) return; - if (event.key === "Backspace") { - if (this._activeInput === 'title') level.levelName = level.levelName.slice(0, -1); - else level.description = (level.description || "").slice(0, -1); - } else if (event.key === "Enter") { - this._activeInput = null; - } else if (event.key.length === 1) { - if (this._activeInput === 'title' && level.levelName.length < 20) { - level.levelName += event.key; - } else if (this._activeInput === 'desc' && (level.description || "").length < 150) { - level.description = (level.description || "") + event.key; - } - } - saveToLS(this._activeInput === 'title' ? "levelName" : "description", - this._activeInput === 'title' ? level.levelName : level.description); - cursorVisible = true; - updateDisplay(); - }; - - window.addEventListener('keydown', keyHandler); - nameBox.on('pointerdown', () => { this._activeInput = 'title'; updateDisplay(); }); - descBox.on('pointerdown', () => { this._activeInput = 'desc'; updateDisplay(); }); - - const cleanup = () => { - clearInterval(cursorInterval); - window.removeEventListener('keydown', keyHandler); - container.destroy(); - overlay.destroy(); - blocker.destroy(); - this._levelViewOverlay = null; - this._closeLevelView = null; - }; - this._levelViewOverlay = overlay; - this._closeLevelView = () => { cleanup(); this._openEditorMenu(); }; - - const btnY = sh * 0.58; - const editBtn = this.add.image(centerX - 220, btnY, "GJ_GameSheet03", "GJ_editBtn_001.png").setInteractive().setScale(1.1); - this._makeBouncyButton(editBtn, 1.1, () => { cleanup(); this._startCreatedLevel(level, true); }); - const playBtn = this.add.image(centerX, btnY, "GJ_GameSheet03", "GJ_playBtn2_001.png").setInteractive().setScale(1.1); - let playBtnLoading = false; - this._makeBouncyButton(playBtn, 1.1, async () => { - if (playBtnLoading) return; - playBtnLoading = true; - this._audio.playEffect("playSound_01", { volume: 1 }); - playBtn.setTint(0x666666); - playBtn.disableInteractive(); - - let started = false; - try { - started = await this._startCreatedLevel(level, false, cleanup); - } catch (err) { - console.warn("Failed to start saved level", err); - } - - if (!started && playBtn.scene) { - playBtnLoading = false; - playBtn.clearTint(); - playBtn.setInteractive(); - } - }, () => !playBtnLoading); - const shareBtn = this.add.image(centerX + 220, btnY, "GJ_GameSheet03", "GJ_shareBtn_001.png").setInteractive().setScale(1.1); - this._makeBouncyButton(shareBtn, 1.1, () => { this._exportGMD(level); }); - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png").setFlipX(true).setFlipY(true).setRotation(Math.PI).setInteractive(); - this._makeBouncyButton(backBtn, 1, () => { this._closeLevelView(); }); - const deleteBtn = this.add.image(sw - 50, 48, "GJ_GameSheet03", "GJ_deleteBtn_001.png").setInteractive().setScale(0.8); - this._makeBouncyButton(deleteBtn, 0.8, () => { deleteLevel(); }); - - const footerY = sh - 100; - const subFooterY = sh - 30; - const lengthValues = ["Tiny", "Short", "Medium", "Long", "XL", "Plat."] - - const lengthIcon = this.add.image(centerX - 350, footerY, "GJ_GameSheet03", "GJ_timeIcon_001.png").setScale(1).setDepth(152); - const lengthLabel = this.add.bitmapText(centerX - 310, footerY, "bigFont", lengthValues[parseInt(level.levelLength, 10)] || "Tiny", 33).setOrigin(0, 0.5).setDepth(152); - const songIcon = this.add.image(centerX - 160, footerY, "GJ_GameSheet03", "GJ_musicIcon_001.png").setScale(1).setDepth(152); - const songLabel = this.add.bitmapText(centerX - 115, footerY, "bigFont", level.song, 29).setOrigin(0, 0.5).setDepth(152); - const statusIcon = this.add.image(centerX + 200, footerY, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScale(1).setDepth(152); - const songLabelMaxW = Math.max(40, (statusIcon.x - 30) - songLabel.x); - songLabel.setScale(1); - if (songLabel.width > songLabelMaxW) { - songLabel.setScale(songLabelMaxW / songLabel.width); - } - const statusLabel = this.add.bitmapText(centerX + 245, footerY, "bigFont", level.status, 33).setOrigin(0, 0.5).setDepth(152); - const versionText = this.add.bitmapText(centerX - 180, subFooterY, "goldFont", `Version: ${level.version || 1}`, 30).setOrigin(0.5).setDepth(152); - const idText = this.add.bitmapText(centerX + 180, subFooterY, "goldFont", `ID: ${level.levelId || "na"}`, 30).setOrigin(0.5).setDepth(152); - - container.add([nameBox, titleText, titleCursor, descBox, descText, descCursor, playBtn, editBtn, shareBtn, backBtn, deleteBtn, lengthIcon, lengthLabel, songIcon, songLabel, statusIcon, statusLabel, versionText, idText]); - }; - this._startCreatedLevel = async (level, isEditor, onBeforeRestart = null) => { - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - window._onlineLevelString = level.levelString; - window._onlineLevelName = level.levelName; - window._onlineLevelId = level.createdId; - if (!isEditor) { - window._createdLevelReturnToView = { - createdId: level.createdId, - snapshot: { ...level } - }; - } - window._onlineSongBuffer = null; - window._onlineSongKey = null; - window._onlineSongOffset = 0; - window.isEditor = !!isEditor; - this.game.registry.set("autoStartGame", true); - window.currentlevel = [ - "Placeholder", - level.levelName, - level.createdId, - ["Local", "SongAuthor"] - ]; - if (level.songId < 0){ - window.currentlevel[0] = window.allLevels[Math.abs(level.songId) - 1][0]; - window.currentlevel[3] = ["Local", window.allLevels[Math.abs(level.songId) - 1][3]] - } else { - const songId = level.songId; - const songKey = `ng_song_${songId}`; - window.currentlevel[0] = songKey; - - if (PROXY_BASE && songId > 0) { - try { - const ngRes = await fetch(`${PROXY_BASE}/getGJSongInfo.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `songID=${songId}&secret=Wmfd2893gb7` - }); - - const ngText = ngRes.ok ? await ngRes.text() : "-1"; - if (ngText && ngText !== "-1") { - const ngParts = ngText.split("~|~"); - const ngMap = {}; - for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; - - const songUrl = decodeURIComponent((ngMap["10"] || "").trim()); - const songArtist = (ngMap["4"] || "Unknown").replace(/:$/, "").trim(); - const songTitle = (ngMap["2"] || `Song #${songId}`).replace(/:$/, "").trim(); - - if (songUrl) { - const audioCtx = this.game.sound.context; - if (audioCtx.state === "suspended") await audioCtx.resume(); - const proxiedUrl = songUrl.includes("geometrydashfiles.b-cdn.net") - ? songUrl - : `${PROXY_BASE}/audio-proxy?url=${encodeURIComponent(songUrl)}`; - const audioRes = await fetch(proxiedUrl); - const arrayBuf = await audioRes.arrayBuffer(); - const decoded = await audioCtx.decodeAudioData(arrayBuf); - window._onlineSongBuffer = decoded; - window._onlineSongKey = songKey; - window._onlineSongTitle = songTitle; - window._onlineSongArtist = songArtist; - - window.currentlevel[3] = ["Local", window._onlineSongArtist] - } - } - } catch (err) { - console.warn("Failed to load custom song", err); - } - } - } - if (onBeforeRestart) onBeforeRestart(); - this.scene.restart(); - return true; - }; - this._closeEditorMenu = () => { - if (this._editorObjects) { - this._editorObjects.forEach(obj => obj.destroy()); - } - this._editorOverlay = null; - this._editorObjects = null; - }; - this._openSearchMenu = () => { - if (this._searchOverlay) return; - const sw = screenWidth; - const sh = screenHeight; - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x00 + (0x01 - 0x00) * t); - const g1 = Math.round(0x65 + (0x2c - 0x65) * t); - const b1 = Math.round(0xff + (0x71 - 0xff) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - const bandY = Math.floor(gi * sh / gradientSteps); - const bandH = Math.ceil(sh / gradientSteps) + 1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, bandY, sw, bandH); - } - this._searchOverlay = overlay; - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh).setScrollFactor(0).setDepth(101).setInteractive(); - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true) - .setRotation(Math.PI).setInteractive(); - this._makeBouncyButton(backBtn, 1, () => { this._closeSearchMenu(false, () => this._openCreatorMenu()); }); - - const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); - const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1); - const panelMarginX = sw * 0.18; - const panelLeft = panelMarginX; - const panelRight = sw - panelMarginX; - const panelW = panelRight - panelLeft; - const panelRadius = 10; - const panelColor = 0x002e75; - const topPanelColor = 0x00388d; - const innerPanelColor = 0x002762; - const filtersPanelColor = 0x00245b; - const extraPanelColor = 0x001f4f; - const panelAlpha = 0.7; - const labelSize = 32; - const labelColor = 0xffffff; - const gfx = this.add.graphics().setScrollFactor(0).setDepth(104); - const topPanelY = sh * 0.10 - 40; - const topPanelH = sh * 0.12; - gfx.fillStyle(topPanelColor, panelAlpha); - gfx.fillRoundedRect(panelLeft, topPanelY, panelW, topPanelH, panelRadius); - const innerPanelY = topPanelY + 10; - const innerPanelX = panelLeft + 10; - const innerPanelW = panelW * 0.57; - const innerPanelH = topPanelH - 20; - gfx.fillStyle(innerPanelColor, panelAlpha); - gfx.fillRoundedRect(innerPanelX, innerPanelY, innerPanelW, innerPanelH, panelRadius); - - const innerBtnX = innerPanelX + innerPanelW + 20; - const innerBtnY = innerPanelY + (innerPanelH / 2); - - const innerBtn2 = this.add.image(innerBtnX + 137, innerBtnY, "GJ_GameSheet03", "GJ_longBtn05_001.png") - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); - this._makeBouncyButton(innerBtn2, 1, () => {}); - const innerBtn1 = this.add.image(innerBtnX + 47, innerBtnY, "GJ_GameSheet03", "GJ_longBtn06_001.png") - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); - this._makeBouncyButton(innerBtn1, 1, () => { _doSearch(); }); - - const innerBtn3 = this.add.image(innerBtnX + 231, innerBtnY, "GJ_GameSheet03", "GJ_longBtn07_001.png") - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); - this._makeBouncyButton(innerBtn3, 1, () => { inputText = ""; _updateInputDisplay(); }); - - const allowedChars = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - const inputMaxLen = 64; - const inputCX = innerPanelX + innerPanelW / 2; - const inputCY = innerPanelY + innerPanelH / 2; - - let inputText = ""; - let inputFocused = false; - let cursorVisible = false; - let cursorTimer = null; - const placeholderLabel = this.add.bitmapText(inputCX - 5, inputCY, "bigFont", "Enter a level, user or id", 28) - .setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5) - .setTint(0x6c99d8).setAlpha(0.85); - const typedLabel = this.add.bitmapText(innerPanelX + 10, inputCY, "bigFont", "", 46) - .setScrollFactor(0).setDepth(106).setOrigin(0, 0.5) - .setTint(0xffffff).setVisible(false); - const inputCursor = this.add.text(0, inputCY, "|", { - fontSize: "33px", fontFamily: "Arial", color: "#92a7c0" - }).setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false); - - const _updateInputDisplay = () => { - if (inputText === "") { - typedLabel.setVisible(false); - placeholderLabel.setVisible(true); - } else { - placeholderLabel.setVisible(false); - typedLabel.setText(inputText).setVisible(true); - } - if (inputFocused) { - const textW = inputText === "" ? 0 : typedLabel.width; - const textLeft = innerPanelX + 10; - inputCursor.x = textLeft + textW + 2; - inputCursor.setVisible(cursorVisible); - } else { - inputCursor.setVisible(false); - } - }; - - const _startCursorBlink = () => { - cursorVisible = true; - _updateInputDisplay(); - if (cursorTimer) cursorTimer.remove(); - cursorTimer = null; - }; - - const _stopCursorBlink = () => { - if (cursorTimer) { cursorTimer.remove(); cursorTimer = null; } - cursorVisible = false; - inputCursor.setVisible(false); - }; - - const _focusInput = () => { - inputFocused = true; - _startCursorBlink(); - }; - - const _blurInput = () => { - inputFocused = false; - _stopCursorBlink(); - _updateInputDisplay(); - }; - const inputHitZone = this.add.zone( - innerPanelX + innerPanelW / 2, innerPanelY + innerPanelH / 2, - innerPanelW, innerPanelH - ).setScrollFactor(0).setDepth(107).setInteractive(); - inputHitZone.on("pointerdown", () => _focusInput()); - - blocker.on("pointerdown", () => { if (inputFocused) _blurInput(); }); - const _onKeyDown = (event) => { - if (!inputFocused) return; - event.stopPropagation(); - if (event.key === "Backspace") { - if (inputText.length > 0) { - inputText = inputText.slice(0, -1); - _updateInputDisplay(); - } - } else if (event.key === "Enter") { - _doSearch(); - } else if (event.ctrlKey || event.metaKey) { - if (event.key === "c" || event.key === "C") { - event.preventDefault(); - navigator.clipboard.writeText(inputText); - } else if (event.key === "v" || event.key === "V") { - event.preventDefault(); - navigator.clipboard.readText().then(pastedText => { - const filtered = pastedText.split('').filter(c => allowedChars.includes(c)).join(''); - if (filtered.length > 0) { - const availableSpace = inputMaxLen - inputText.length; - inputText += filtered.slice(0, availableSpace); - _updateInputDisplay(); - } - }).catch(() => {}); - } else if (event.key === "a" || event.key === "A") { - event.preventDefault(); - } - } else if (event.key.length === 1 && allowedChars.includes(event.key) && !event.ctrlKey) { - if (inputText.length < inputMaxLen) { - inputText += event.key; - _updateInputDisplay(); - } - } - }; - window.addEventListener("keydown", _onKeyDown); - - const htmlInput = { - remove: () => { - window.removeEventListener("keydown", _onKeyDown); - window.removeEventListener("keydown", _onEnterKeydown); - window.removeEventListener("keyup", _onKeyUpStop); - window.removeEventListener("keypress", _onKeyPressStop); - _blurInput(); - }, - get value() { return inputText; }, - }; - const _onEnterKeydown = (e) => { - if (e.key === "Enter") _doSearch(); - e.stopPropagation(); - }; - const _onKeyUpStop = (e) => e.stopPropagation(); - const _onKeyPressStop = (e) => e.stopPropagation(); - window.addEventListener("keydown", _onEnterKeydown); - window.addEventListener("keyup", _onKeyUpStop); - window.addEventListener("keypress", _onKeyPressStop); - const _repositionInput = () => {}; - const qsLabelY = sh * 0.195; - const qsPanelY = qsLabelY + 25; - const qsPanelH = sh * 0.36; - const qsLabel = this.add.bitmapText(sw / 2, qsLabelY, "bigFont", "Quick Search", labelSize) - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(labelColor); - - gfx.fillStyle(panelColor, panelAlpha); - gfx.fillRoundedRect(panelLeft, qsPanelY, panelW, qsPanelH, panelRadius); - const gridRows = 3; - const gridCols = 3; - const qsPadX = 14; - const qsPadY = 14.5; - const qsGapX = 10; - const qsGapY = 12; - const totalBtnW = panelW - qsPadX * 2; - const totalBtnH = qsPanelH - qsPadY * 2; - const btnW = (totalBtnW - qsGapX * (gridCols - 1)) / gridCols; - const btnH = (totalBtnH - qsGapY * (gridRows - 1)) / gridRows; - - const lbFrame = this.textures.getFrame("GJ_GameSheet03", "GJ_longBtn01_001.png"); - const lbBorder = Math.round(lbFrame.height * 0.28); - - for (let row = 0; row < gridRows; row++) { - for (let col = 0; col < gridCols; col++) { - const btnCX = panelLeft + qsPadX + col * (btnW + qsGapX) + btnW / 2; - const btnCY = qsPanelY + qsPadY + row * (btnH + qsGapY) + btnH / 2; - - const atlas = this.textures.get("GJ_GameSheet03"); - const frameX = lbFrame.cutX; - const frameY = lbFrame.cutY; - const frameW = lbFrame.cutWidth; - const frameH = lbFrame.cutHeight; - const midW = btnW - lbBorder * 2; - const midH = btnH - lbBorder * 2; - const tag = `_lbqs_${row}_${col}`; - - const pieces = [ - { sx: frameX, sy: frameY, sw: lbBorder, sh: lbBorder, dx: -btnW/2, dy: -btnH/2, dw: lbBorder, dh: lbBorder }, - { sx: frameX + lbBorder, sy: frameY, sw: frameW-lbBorder*2, sh: lbBorder, dx: -btnW/2 + lbBorder, dy: -btnH/2, dw: midW, dh: lbBorder }, - { sx: frameX + frameW - lbBorder, sy: frameY, sw: lbBorder, sh: lbBorder, dx: btnW/2 - lbBorder, dy: -btnH/2, dw: lbBorder, dh: lbBorder }, - { sx: frameX, sy: frameY + lbBorder, sw: lbBorder, sh: frameH-lbBorder*2, dx: -btnW/2, dy: -btnH/2 + lbBorder, dw: lbBorder, dh: midH }, - { sx: frameX + lbBorder, sy: frameY + lbBorder, sw: frameW-lbBorder*2, sh: frameH-lbBorder*2, dx: -btnW/2 + lbBorder, dy: -btnH/2 + lbBorder, dw: midW, dh: midH }, - { sx: frameX + frameW - lbBorder, sy: frameY + lbBorder, sw: lbBorder, sh: frameH-lbBorder*2, dx: btnW/2 - lbBorder, dy: -btnH/2 + lbBorder, dw: lbBorder, dh: midH }, - { sx: frameX, sy: frameY + frameH - lbBorder, sw: lbBorder, sh: lbBorder, dx: -btnW/2, dy: btnH/2 - lbBorder, dw: lbBorder, dh: lbBorder }, - { sx: frameX + lbBorder, sy: frameY + frameH - lbBorder, sw: frameW-lbBorder*2, sh: lbBorder, dx: -btnW/2 + lbBorder, dy: btnH/2 - lbBorder, dw: midW, dh: lbBorder }, - { sx: frameX + frameW - lbBorder, sy: frameY + frameH - lbBorder, sw: lbBorder, sh: lbBorder, dx: btnW/2 - lbBorder, dy: btnH/2 - lbBorder, dw: lbBorder, dh: lbBorder }, - ]; - - const btnContainer = this.add.container(btnCX, btnCY).setScrollFactor(0).setDepth(105); - const bgPieces = []; - pieces.forEach((p, i) => { - const frameKey = `${tag}_p${i}`; - if (!atlas.has(frameKey)) { - atlas.add(frameKey, 0, p.sx, p.sy, p.sw, p.sh); - } - const bgPiece = this.add.image(p.dx, p.dy, "GJ_GameSheet03", frameKey) - .setOrigin(0, 0).setDisplaySize(p.dw, p.dh); - bgPieces.push(bgPiece); - btnContainer.add(bgPiece); - }); - - const hitZone = this.add.zone(0, 0, btnW, btnH).setInteractive(); - btnContainer.add(hitZone); - - const qsLabels = [ - ["Downloads", "Likes", "Sent" ], - ["Trending", "Recent", "Magic" ], - ["Awarded", "Followed", "Friends"], - ]; - const qsIcons = [ - ["GJ_sDownloadIcon_001.png", "GJ_sLikeIcon_001.png", "GJ_sModIcon_001.png" ], - ["GJ_sTrendingIcon_001.png", "GJ_sRecentIcon_001.png", "GJ_sMagicIcon_001.png" ], - ["GJ_sStarsIcon_001.png", "GJ_sFollowedIcon_001.png", "GJ_sFriendsIcon_001.png"], - ]; - const labelStr = qsLabels[row][col]; - const iconFrame = qsIcons[row][col]; - const fontSize = labelStr === "Downloads" ? 26 : 32; - - const iconSize = btnH * 0.54; - const gap = 10; - const tmpLbl = this.add.bitmapText(0, -9999, "bigFont", labelStr, fontSize).setOrigin(0, 0.5); - const measuredW = tmpLbl.width; - tmpLbl.destroy(); - - const groupW = measuredW + gap + iconSize; - const groupLeft = -groupW / 2; - - const lbl = this.add.bitmapText(groupLeft, -1, "bigFont", labelStr, fontSize) - .setOrigin(0, 0.5).setScrollFactor(0).setDepth(106); - btnContainer.add(lbl); - - const qsIconSizes = { - "GJ_sDownloadIcon_001.png": { w: 30, h: 30, scale: 1 }, - "GJ_sLikeIcon_001.png": { w: 31, h: 37, scale: 1 }, - "GJ_sModIcon_001.png": { w: 31, h: 31, scale: 1 }, - "GJ_sTrendingIcon_001.png": { w: 33, h: 25, scale: 1 }, - "GJ_sRecentIcon_001.png": { w: 31, h: 29, scale: 1 }, - "GJ_sMagicIcon_001.png": { w: 33, h: 30, scale: 1 }, - "GJ_sStarsIcon_001.png": { w: 30, h: 29, scale: 1 }, - "GJ_sFollowedIcon_001.png": { w: 31, h: 29, scale: 1 }, - "GJ_sFriendsIcon_001.png": { w: 35, h: 29, scale: 1 }, - }; - const iconConfig = qsIconSizes[iconFrame]; - const iconScale = iconConfig.scale; - const iconW = iconConfig.w * iconScale; - const iconH = iconConfig.h * iconScale; - const iconCX = groupLeft + measuredW + gap + iconW / 2 + 5; - const iconY = iconFrame === "GJ_sLikeIcon_001.png" ? 2 : (labelStr === "Downloads" ? -2 : -1); - const icon = this.add.image(iconCX, iconY, "GJ_GameSheet03", iconFrame) - .setOrigin(0.5, 0.5).setScrollFactor(0).setDepth(106) - .setScale(iconScale); - btnContainer.add(icon); - const buttonTypes = { - "Downloads": 1, - "Likes": 2, - "Trending": 3, - "Recent": 4, - "Magic": 7, - "Awarded": 11, - }; - const type = buttonTypes[labelStr]; - if (!type) { - const disabledTint = 0x666666; - lbl.setTint(disabledTint); - icon.setTint(disabledTint); - bgPieces.forEach(p => p.setTint(disabledTint)); - } - if (type) { - const baseScale = 1; - const pressedScale = baseScale * 1.26; - hitZone.on("pointerdown", () => { - hitZone._pressed = true; - this.tweens.killTweensOf(btnContainer, "scale"); - this.tweens.add({ targets: btnContainer, scale: pressedScale, duration: 300, ease: "Bounce.Out" }); - }); - hitZone.on("pointerout", () => { - if (hitZone._pressed) { - hitZone._pressed = false; - this.tweens.killTweensOf(btnContainer, "scale"); - this.tweens.add({ targets: btnContainer, scale: baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - hitZone.on("pointerup", () => { - if (hitZone._pressed) { - hitZone._pressed = false; - this.tweens.killTweensOf(btnContainer, "scale"); - btnContainer.setScale(baseScale); - this._closeSearchMenu(true); - const searchParams = { type }; - const diffParam = _getActiveDiffParam(); - if (diffParam) { - searchParams.diff = diffParam; - const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; - if (demonIcon && demonIcon._diffFilterActive && this._selectedDemonTier) { - searchParams.demonFilter = this._selectedDemonTier; - } - } - this._openOnlineLevelsScene(searchParams); - } - }); - } else { - this._makeBouncyButton(hitZone, 1, () => {}); - } - this._searchOverlayObjects.push(btnContainer); - } - } - const filtersLabelY = qsPanelY + qsPanelH + 24; - const filtersPanelY = filtersLabelY + 20; - const filtersPanelH = sh * 0.16; - const filtersLabel = this.add.bitmapText(sw / 2, filtersLabelY, "bigFont", "Filters", labelSize) - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(labelColor); - - gfx.fillStyle(filtersPanelColor, panelAlpha); - gfx.fillRoundedRect(panelLeft, filtersPanelY, panelW, filtersPanelH, panelRadius); - const _diffFilterFrames = [ - "difficulty_00_btn_001.png", "difficulty_01_btn_001.png", "difficulty_02_btn_001.png", - "difficulty_03_btn_001.png", "difficulty_04_btn_001.png", "difficulty_05_btn_001.png", - "difficulty_06_btn_001.png", "difficulty_auto_btn_001.png" - ]; - const _diffFilterCount = _diffFilterFrames.length; - const _diffFilterSlotW = panelW / _diffFilterCount; - const _diffFilterIconY = filtersPanelY + filtersPanelH / 2; - this._diffFilterIcons = []; - const _diffFilterInactiveTint = 0x666666; - const _diffFilterBaseScale = 0.85; - const _diffFilterPressScale = 1; - const _diffFilterExclusiveIdx = [0, 6, 7]; - _diffFilterFrames.forEach((frame, i) => { - const cx = panelLeft + _diffFilterSlotW * i + _diffFilterSlotW / 2; - const icon = this.add.image(cx, _diffFilterIconY, "GJ_GameSheet03", frame) - .setScrollFactor(0).setDepth(105).setOrigin(0.5) - .setScale(_diffFilterBaseScale) - .setInteractive() - .setTint(_diffFilterInactiveTint); - icon._diffFilterActive = false; - icon._diffFilterExclusive = _diffFilterExclusiveIdx.includes(i); - this._diffFilterIcons.push(icon); - - icon.on("pointerdown", () => { - icon._pressed = true; - this.tweens.killTweensOf(icon, "scale"); - this.tweens.add({ targets: icon, scale: _diffFilterPressScale, duration: 300, ease: "Bounce.Out" }); - }); - icon.on("pointerout", () => { - if (icon._pressed) { - icon._pressed = false; - this.tweens.killTweensOf(icon, "scale"); - this.tweens.add({ targets: icon, scale: _diffFilterBaseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - icon.on("pointerup", () => { - if (!icon._pressed) return; - icon._pressed = false; - this.tweens.killTweensOf(icon, "scale"); - icon.setScale(_diffFilterBaseScale); - const wasActive = icon._diffFilterActive; - if (icon._diffFilterExclusive) { - this._diffFilterIcons.forEach(other => { - other.setTint(_diffFilterInactiveTint); - other._diffFilterActive = false; - }); - if (!wasActive) { - icon.clearTint(); - icon._diffFilterActive = true; - } - } else { - this._diffFilterIcons.forEach(other => { - if (other._diffFilterExclusive && other._diffFilterActive) { - other.setTint(_diffFilterInactiveTint); - other._diffFilterActive = false; - } - }); - if (wasActive) { - icon.setTint(_diffFilterInactiveTint); - icon._diffFilterActive = false; - } else { - icon.clearTint(); - icon._diffFilterActive = true; - } - } - this._refreshDemonFilterPlus(); - }); - this._searchOverlayObjects.push(icon); - }); - const _demonPlusX = panelRight + 42; - const _demonPlusY = filtersPanelY + filtersPanelH / 2; - const demonPlusBtn = this.add.image(_demonPlusX, _demonPlusY, "GJ_GameSheet03", "GJ_plus2Btn_001.png") - .setScrollFactor(0).setDepth(105).setOrigin(0.5) - .setInteractive().setVisible(false); - this._demonFilterPlusBtn = demonPlusBtn; - this._makeBouncyButton(demonPlusBtn, 1, () => { this._buildDemonFilterPopup(); }, () => demonPlusBtn.visible); - this._searchOverlayObjects.push(demonPlusBtn); - - this._refreshDemonFilterPlus = () => { - const demonIcon = this._diffFilterIcons[6]; - if (demonPlusBtn && demonPlusBtn.scene) { - demonPlusBtn.setVisible(!!(demonIcon && demonIcon._diffFilterActive)); - } - }; - this._refreshDemonFilterPlus(); - - const extraPanelY = filtersPanelY + filtersPanelH + 18; - const extraPanelH = sh * 0.11; - gfx.fillStyle(extraPanelColor, panelAlpha); - gfx.fillRoundedRect(panelLeft, extraPanelY, panelW, extraPanelH, panelRadius); - - const extraComingSoon = this.add.bitmapText(sw / 2, extraPanelY + extraPanelH / 2, "bigFont", "Coming Soon!", 42) - .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(0xadd8e6).setAlpha(0.75); - - this._searchOverlayObjects.push(gfx, qsLabel, filtersLabel, cornerBR, cornerBL, - placeholderLabel, typedLabel, inputCursor, inputHitZone, innerBtn1, innerBtn2, innerBtn3, - extraComingSoon); - - let _loading = false; - const _diffFilterCodeMap = [-1, 1, 2, 3, 4, 5, -2, -3]; - const _getActiveDiffParam = () => { - const icons = this._diffFilterIcons || []; - const activeCodes = []; - icons.forEach((icon, idx) => { - if (icon._diffFilterActive) activeCodes.push(_diffFilterCodeMap[idx]); - }); - return activeCodes.length ? activeCodes.join(",") : null; - }; - const _doSearch = async () => { - if (_loading) return; - const rawInput = htmlInput.value.trim(); - if (rawInput && /^\d+$/.test(rawInput)) { - const levelId = rawInput; - _loading = true; - try { - await _doSearchInner(levelId); - } catch (err) { - } finally { - _loading = false; - } - return; - } - htmlInput.remove(); - window.removeEventListener("resize", _repositionInput); - this._closeSearchMenu(true); - const diffParam = _getActiveDiffParam(); - const searchParams = rawInput ? { type: 0, str: rawInput } : { type: 2 }; - if (diffParam) { - searchParams.diff = diffParam; - const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; - if (demonIcon && demonIcon._diffFilterActive && this._selectedDemonTier) { - searchParams.demonFilter = this._selectedDemonTier; - } - } - this._openOnlineLevelsScene(searchParams); - }; - const _doSearchInner = async (levelId) => { - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - if (!PROXY_BASE) { console.warn("Level search: window._gdProxyUrl is not configured"); return; } - const formBody = `levelID=${levelId}&secret=Wmfd2893gb7`; - const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: formBody - }); - if (!res.ok) throw new Error(`Proxy returned ${res.status}`); - const rawResponse = await res.text(); - if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) { - return; - } - - const responseSegments = rawResponse.split("#"); - const lvlParts = responseSegments[0].split(":"); - const lvlMap = {}; - for (let i = 0; i + 1 < lvlParts.length; i += 2) { - lvlMap[lvlParts[i]] = lvlParts[i + 1]; - } - - const levelData = { - // Core Level Info - id: lvlMap["1"] || levelId, - title: (lvlMap["2"] || "Online Level").trim(), - description: lvlMap["3"] ? atob(lvlMap["3"].replace(/-/g, '+').replace(/_/g, '/')) : "", // Base64 decoded - string: lvlMap["4"] || null, // The raw level data string - version: parseInt(lvlMap["5"]) || 1, - - // User / Author Info - playerID: lvlMap["6"] || null, - accountID: lvlMap["57"] || null, // The author's accountID returned by the server - - // Song Info - officialSong: lvlMap["12"] || "0", - customSongID: (lvlMap["35"] || "").trim(), - isCustomSong: !!(lvlMap["35"] || "").trim() && (lvlMap["35"] || "").trim() !== "0", - isLibrarySong: !!(lvlMap["35"] || "").trim() && (lvlMap["35"] || "").trim() !== "0" && parseInt((lvlMap["35"] || "").trim()) >= 1000000, - offset: parseFloat(lvlMap["45"] || "0") || 0, - - // Gameplay Details - difficulty: (() => { - const isDemon = parseInt(lvlMap["17"]) === 1; - const isAuto = parseInt(lvlMap["25"]) === 1; - if (isAuto) return 11; - if (isDemon) { - const d9 = parseInt(lvlMap["9"]); - const d43 = parseInt(lvlMap["43"]); - if (!isNaN(d9) && d9 >= 1 && d9 <= 5) { - return [7, 8, 6, 9, 10][d9 - 1] ?? 8; - } else if (!isNaN(d43)) { - const demonMap43 = { 3: 7, 4: 8, 0: 6, 5: 9, 6: 10 }; - return demonMap43.hasOwnProperty(d43) ? demonMap43[d43] : 8; - } - return 8; - } - return Math.min(5, Math.max(0, Math.round((parseInt(lvlMap["9"]) || 0) / 10))); - })(), // Auto, Easy, Normal, Hard, Harder, Insane, Demons - stars: parseInt(lvlMap["18"]) || 0, - diamonds: parseInt(lvlMap["46"]) || 0, - orbs: parseInt(lvlMap["48"]) || 0, - length: parseInt(lvlMap["15"]) || 0, // 0=Tiny, 1=Small, 2=Medium, 3=Long, 4=XL, 5=Platformer - featured: (parseInt(lvlMap["19"]) || 0) > 0, // Featured score > 0 means the level is Featured - epic: parseInt(lvlMap["42"]) || 0, // 0=Original/Featured (see 'featured' flag), 1=Epic, 2=Mythic, 3+=Legendary - gameVersion: parseInt(lvlMap["13"]) || 22, // The game version the level was created in (e.g. 22 = 2.2) - binaryVersion: parseInt(lvlMap["52"]) || 0, // The build version used to upload - - // Meta / Social Counters - downloads: parseInt(lvlMap["10"]) || 0, - likes: parseInt(lvlMap["14"]) || 0, - objects: parseInt(lvlMap["45"]) || 0, // Object count (Note: 45 can double as audio offset or object count depending on context) - ts: lvlMap["28"] || null, // Upload/Update timestamp hint - - // Technical / Security Verification keys sent back by server - chk: lvlMap["chk"] || null, - rs: lvlMap["rs"] || null - }; - console.groupCollapsed("level data"); - const { string, ...tableFriendlyData } = levelData; - console.table(tableFriendlyData); - console.groupEnd(); - - let authorName = "Unknown"; - let songNameForCell = levelData.isCustomSong - ? ("Song #" + levelData.customSongID) - : (window.allLevels && window.allLevels[levelData.officialSong] ? window.allLevels[levelData.officialSong][1] : "Unknown"); - try { - const infoRes = await fetch(`https://gdbrowser.com/api/level/${levelData.id}`); - if (infoRes.ok) { - const infoData = await infoRes.json(); - if (infoData) { - if (infoData.author) authorName = infoData.author; - if (infoData.songName) songNameForCell = infoData.songName; - } - } - } catch (_e) {} - - const cellData = { - ...levelData, - name: levelData.title, - author: authorName, - songName: songNameForCell - }; - - htmlInput.remove(); - window.removeEventListener("resize", _repositionInput); - this._closeSearchMenu(true); - this._openSearchResultScene(cellData); - }; - this._searchOverlayObjects.push(overlay, blocker, backBtn); - if (window.levelID && !window.alreadydownloaded) { // if there's an ID parameter, load it directly - window.alreadydownloaded = true; - htmlInput.remove(); - const loadingBg = this.add.graphics().setScrollFactor(0).setDepth(1000); - loadingBg.fillStyle(0x000000, 1); - loadingBg.fillRect(0, 0, sw, sh); - const loadingText = this.add.bitmapText(sw / 2, sh / 2, "bigFont", "Loading level...", 30) - .setScrollFactor(0).setDepth(1001).setOrigin(0.5); - this._searchOverlayObjects.push(loadingBg, loadingText); - _doSearchInner(window.levelID); - } - this._searchHtmlInput = htmlInput; - this._searchInputResizeFn = _repositionInput; - }; - this._closeSearchMenu = (silent = false, onComplete = null) => { - if (!this._searchOverlay) return; - if (this._searchHtmlInput) { - this._searchHtmlInput.remove(); - this._searchHtmlInput = null; - } - if (this._searchInputResizeFn) { - window.removeEventListener("resize", this._searchInputResizeFn); - this._searchInputResizeFn = null; - } - const destroy = () => { - for (const obj of this._searchOverlayObjects) { - if (obj && obj.destroy) obj.destroy(); - } - this._searchOverlayObjects = []; - this._searchOverlay = null; - }; - if (silent) { destroy(); if (onComplete) onComplete(); return; } - const sw = screenWidth, sh = screenHeight; - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ - targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", - onComplete: () => { - destroy(); - if (onComplete) onComplete(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._makeBouncyButton(this._creatorBtn, 1, () => { - this._openCreatorMenu(); - }, () => this._menuActive && !this._levelSelectOverlay); - //icon stufff - this._iconBtn = this.add.image(0, 0, "GJ_GameSheet03", "GJ_garageBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setScale(1); - this._iconBtnSelected = false; - this._makeBouncyButton(this._iconBtn, 1, () => { - this._openIconSelector(); - }, () => this._menuActive && !this._levelSelectOverlay); - - this._iconOverlay = null; - - const _iconFrameSets = { - icon: [ -"player_01_001.png", "player_02_001.png", "player_03_001.png", "player_04_001.png", "player_05_001.png", "player_06_001.png", "player_07_001.png", "player_08_001.png", "player_09_001.png", "player_10_001.png", -"player_11_001.png", "player_12_001.png", "player_13_001.png", "player_14_001.png", "player_15_001.png", "player_16_001.png", "player_17_001.png", "player_18_001.png", "player_19_001.png", "player_20_001.png", -"player_21_001.png", "player_22_001.png", "player_23_001.png", "player_24_001.png", "player_25_001.png", "player_26_001.png", "player_27_001.png", "player_28_001.png", "player_29_001.png", "player_30_001.png", -"player_31_001.png", "player_32_001.png", "player_33_001.png", "player_34_001.png", "player_35_001.png", "player_36_001.png", "player_37_001.png", "player_38_001.png", "player_39_001.png", "player_40_001.png", -"player_41_001.png", "player_42_001.png", "player_43_001.png", "player_44_001.png", "player_45_001.png", "player_46_001.png", "player_47_001.png", "player_48_001.png", "player_49_001.png", "player_50_001.png", -"player_51_001.png", "player_52_001.png", "player_53_001.png", "player_54_001.png", "player_55_001.png", "player_56_001.png", "player_57_001.png", "player_58_001.png", "player_59_001.png", "player_60_001.png", -"player_61_001.png", "player_62_001.png", "player_63_001.png", "player_64_001.png", "player_65_001.png", "player_66_001.png", "player_67_001.png", "player_68_001.png", "player_69_001.png", "player_70_001.png", -"player_71_001.png", "player_72_001.png", "player_73_001.png", "player_74_001.png", "player_75_001.png", "player_76_001.png", "player_77_001.png", "player_78_001.png", "player_79_001.png", "player_80_001.png", -"player_81_001.png", "player_82_001.png", "player_83_001.png", "player_84_001.png", "player_85_001.png", "player_86_001.png", "player_87_001.png", "player_88_001.png", "player_89_001.png", "player_90_001.png", -"player_91_001.png", "player_92_001.png", "player_93_001.png", "player_94_001.png", "player_95_001.png", "player_96_001.png", "player_97_001.png", "player_98_001.png", "player_99_001.png", "player_100_001.png", -"player_101_001.png", "player_102_001.png", "player_103_001.png", "player_104_001.png", "player_105_001.png", "player_106_001.png", "player_107_001.png", "player_108_001.png", "player_109_001.png", "player_110_001.png", -"player_111_001.png", "player_112_001.png", "player_113_001.png", "player_114_001.png", "player_115_001.png", "player_116_001.png", "player_117_001.png", "player_118_001.png", "player_119_001.png", "player_120_001.png", -"player_121_001.png", "player_122_001.png", "player_123_001.png", "player_124_001.png", "player_125_001.png", "player_126_001.png", "player_127_001.png", "player_128_001.png", "player_129_001.png", "player_130_001.png", -"player_131_001.png", "player_132_001.png", "player_133_001.png", "player_134_001.png", "player_135_001.png", "player_136_001.png", "player_137_001.png", "player_138_001.png", "player_139_001.png", "player_140_001.png", -"player_141_001.png", "player_142_001.png", "player_143_001.png", "player_144_001.png", "player_145_001.png", "player_146_001.png", "player_147_001.png", "player_148_001.png", "player_149_001.png", "player_150_001.png", -"player_151_001.png", "player_152_001.png", "player_153_001.png", "player_154_001.png", "player_155_001.png", "player_156_001.png", "player_157_001.png", "player_158_001.png", "player_159_001.png", "player_160_001.png", -"player_161_001.png", "player_162_001.png", "player_163_001.png", "player_164_001.png", "player_165_001.png", "player_166_001.png", "player_167_001.png", "player_168_001.png", "player_169_001.png", "player_170_001.png", -"player_171_001.png", "player_172_001.png", "player_173_001.png", "player_174_001.png", "player_175_001.png", "player_176_001.png", "player_177_001.png", "player_178_001.png", "player_179_001.png", "player_180_001.png", -"player_181_001.png", "player_182_001.png", "player_183_001.png", "player_184_001.png", "player_185_001.png", "player_186_001.png", "player_187_001.png", "player_188_001.png", "player_189_001.png", "player_190_001.png", -"player_191_001.png", "player_192_001.png", -"player_193_001.png", "player_194_001.png", "player_195_001.png", "player_196_001.png", "player_197_001.png", "player_198_001.png", "player_199_001.png", "player_200_001.png", "player_201_001.png", "player_202_001.png", -"player_203_001.png", "player_204_001.png", "player_205_001.png", "player_206_001.png", "player_207_001.png", "player_208_001.png", "player_209_001.png", "player_210_001.png", "player_211_001.png", "player_212_001.png", -"player_213_001.png", "player_214_001.png", "player_215_001.png", "player_216_001.png", "player_217_001.png", "player_218_001.png", "player_219_001.png", "player_220_001.png", "player_221_001.png", "player_222_001.png", -"player_223_001.png", "player_224_001.png", "player_225_001.png", "player_226_001.png", "player_227_001.png", "player_228_001.png", "player_229_001.png", "player_230_001.png", "player_231_001.png", "player_232_001.png", -"player_233_001.png", "player_234_001.png", "player_235_001.png", "player_236_001.png", "player_237_001.png", "player_238_001.png", "player_239_001.png", "player_240_001.png", "player_241_001.png", "player_242_001.png", -"player_243_001.png", "player_244_001.png", "player_245_001.png", "player_246_001.png", "player_247_001.png", "player_248_001.png" - ], - ship: [ - "ship_01_001.png", "ship_02_001.png", "ship_03_001.png", "ship_04_001.png", "ship_05_001.png", "ship_06_001.png", "ship_07_001.png", "ship_08_001.png", "ship_09_001.png", "ship_10_001.png", -"ship_11_001.png", "ship_12_001.png", "ship_13_001.png", "ship_14_001.png", "ship_15_001.png", "ship_16_001.png", "ship_17_001.png", "ship_18_001.png", "ship_19_001.png", "ship_20_001.png", -"ship_21_001.png", "ship_22_001.png", "ship_23_001.png", "ship_24_001.png", "ship_25_001.png", "ship_26_001.png", "ship_27_001.png", "ship_28_001.png", "ship_29_001.png", "ship_30_001.png", -"ship_31_001.png", "ship_32_001.png", "ship_33_001.png", "ship_34_001.png", "ship_35_001.png", "ship_36_001.png", "ship_37_001.png", "ship_38_001.png", "ship_39_001.png", "ship_40_001.png", -"ship_41_001.png", "ship_42_001.png", "ship_43_001.png", "ship_44_001.png", "ship_45_001.png", "ship_46_001.png", "ship_47_001.png", "ship_48_001.png", "ship_49_001.png", "ship_50_001.png", -"ship_51_001.png", "ship_52_001.png", "ship_53_001.png", "ship_54_001.png", "ship_55_001.png", "ship_56_001.png", "ship_57_001.png", "ship_58_001.png", "ship_59_001.png", "ship_60_001.png", -"ship_61_001.png", "ship_62_001.png", "ship_63_001.png", "ship_64_001.png", "ship_65_001.png", "ship_66_001.png", "ship_67_001.png", "ship_68_001.png", "ship_69_001.png", "ship_70_001.png", -"ship_71_001.png", "ship_72_001.png", "ship_73_001.png", "ship_74_001.png", "ship_75_001.png", "ship_76_001.png", "ship_77_001.png", "ship_78_001.png", "ship_79_001.png" - ], - ball: [ - "player_ball_01_001.png", "player_ball_02_001.png", "player_ball_03_001.png", "player_ball_04_001.png", "player_ball_05_001.png", "player_ball_06_001.png", "player_ball_07_001.png", "player_ball_08_001.png", "player_ball_09_001.png", "player_ball_10_001.png", - "player_ball_11_001.png", "player_ball_12_001.png", "player_ball_13_001.png", "player_ball_14_001.png", "player_ball_15_001.png", "player_ball_16_001.png", "player_ball_17_001.png", "player_ball_18_001.png", "player_ball_19_001.png", "player_ball_20_001.png", - "player_ball_21_001.png", "player_ball_22_001.png", "player_ball_23_001.png", "player_ball_24_001.png", "player_ball_25_001.png", "player_ball_26_001.png", "player_ball_27_001.png", "player_ball_28_001.png", "player_ball_29_001.png", "player_ball_30_001.png", - - "player_ball_31_001.png", "player_ball_32_001.png", "player_ball_33_001.png", "player_ball_34_001.png", "player_ball_35_001.png", "player_ball_36_001.png", "player_ball_37_001.png", "player_ball_38_001.png", "player_ball_39_001.png", "player_ball_40_001.png", - "player_ball_41_001.png", "player_ball_42_001.png", "player_ball_43_001.png", "player_ball_44_001.png", "player_ball_45_001.png", "player_ball_46_001.png", "player_ball_47_001.png", "player_ball_48_001.png", "player_ball_49_001.png", "player_ball_50_001.png", - "player_ball_51_001.png", "player_ball_52_001.png", - ], - wave: [ - "dart_01_001.png", "dart_02_001.png", "dart_03_001.png", "dart_04_001.png", "dart_05_001.png", - "dart_06_001.png", "dart_07_001.png", "dart_08_001.png", "dart_09_001.png", "dart_10_001.png", - "dart_11_001.png", "dart_12_001.png", "dart_13_001.png", "dart_14_001.png", "dart_15_001.png", - "dart_16_001.png", "dart_17_001.png", "dart_18_001.png", "dart_19_001.png", "dart_20_001.png", - "dart_21_001.png", "dart_22_001.png", "dart_23_001.png", "dart_24_001.png", "dart_25_001.png", - "dart_26_001.png", "dart_27_001.png", "dart_28_001.png", "dart_29_001.png", "dart_30_001.png", - "dart_31_001.png", "dart_32_001.png", "dart_33_001.png", "dart_34_001.png", "dart_35_001.png", - ], - ufo: [ - "bird_01_001.png", "bird_02_001.png", "bird_03_001.png", "bird_04_001.png", "bird_05_001.png", - "bird_06_001.png", "bird_07_001.png", "bird_08_001.png", "bird_09_001.png", "bird_10_001.png", - "bird_11_001.png", "bird_12_001.png", "bird_13_001.png", "bird_14_001.png", "bird_15_001.png", - "bird_16_001.png", "bird_17_001.png", "bird_18_001.png", "bird_19_001.png", "bird_20_001.png", - "bird_21_001.png", "bird_22_001.png", "bird_23_001.png", "bird_24_001.png", "bird_25_001.png", - "bird_26_001.png", "bird_27_001.png", "bird_28_001.png", "bird_29_001.png", "bird_30_001.png", - "bird_31_001.png", "bird_32_001.png", "bird_33_001.png", "bird_34_001.png", "bird_35_001.png", - "bird_36_001.png", "bird_37_001.png", "bird_38_001.png", "bird_39_001.png", "bird_40_001.png", - "bird_41_001.png", "bird_42_001.png", "bird_43_001.png", "bird_44_001.png", "bird_45_001.png", - "bird_46_001.png", "bird_47_001.png", "bird_48_001.png", "bird_49_001.png", "bird_50_001.png", - "bird_51_001.png", - ], - }; - - - const _selectorParseAnimPair = (value, fallbackX = 0, fallbackY = 0) => { - const match = String(value ?? "").match(/\{\s*([-+]?\d*\.?\d+)\s*,\s*([-+]?\d*\.?\d+)\s*\}/); - if (!match) return { x: fallbackX, y: fallbackY }; - const x = parseFloat(match[1]); - const y = parseFloat(match[2]); - return { - x: Number.isFinite(x) ? x : fallbackX, - y: Number.isFinite(y) ? y : fallbackY - }; - }; - - const _selectorVariantFrameName = (frameName, variant) => { - if (!frameName) return frameName; - if (variant === "glow") return frameName.replace(/_001\.png$/, "_glow_001.png"); - if (variant === "overlay") return frameName.replace(/_001\.png$/, "_2_001.png"); - if (variant === "extra") return frameName.replace(/_001\.png$/, "_extra_001.png"); - return frameName; - }; - - const _segmentedIconConfig = { - spider: { - prop: "currentSpider", - prefix: "spider", - descKey: "Spider_AnimDesc", - fallbackBase: "spider_01", - idlePatterns: [/^Spider_idle01_001\.png$/, /^Spider_idle01_\d+\.png$/, /^Spider_idle02_\d+\.png$/, /^Spider_idle_\d+\.png$/, /^Spider_walk_\d+\.png$/], - defaultEntries: [ - { tag: "0", texture: "spider_01_02_001.png" }, - { tag: "1", texture: "spider_01_02_001.png" }, - { tag: "2", texture: "spider_01_04_001.png" }, - { tag: "3", texture: "spider_01_01_001.png" }, - { tag: "4", texture: "spider_01_03_001.png" }, - { tag: "5", texture: "spider_01_02_001.png" } - ] - }, - robot: { - prop: "currentRobot", - prefix: "robot", - descKey: "Robot_AnimDesc", - fallbackBase: "robot_01", - idlePatterns: [/^Robot_idle_001\.png$/, /^Robot_idle_\d+\.png$/, /^Robot_idle01_\d+\.png$/, /^Robot_idle02_\d+\.png$/, /^Robot_run_001\.png$/, /^Robot_run_\d+\.png$/], - defaultEntries: [ - { tag: "0", texture: "robot_01_03_001.png" }, - { tag: "1", texture: "robot_01_02_001.png" }, - { tag: "2", texture: "robot_01_04_001.png" }, - { tag: "3", texture: "robot_01_01_001.png" }, - { tag: "4", texture: "robot_01_03_001.png" }, - { tag: "5", texture: "robot_01_02_001.png" }, - { tag: "6", texture: "robot_01_04_001.png" } - ] - } - }; - - const _isSegmentedIconTab = (tab) => !!_segmentedIconConfig[tab]; - - const _getSegmentedAnimDesc = (tab) => { - const cfg = _segmentedIconConfig[tab]; - if (!cfg) return null; - let data = null; - try { data = this.cache?.json?.get?.(cfg.descKey) || null; } catch (e) { data = null; } - if (!data && typeof window !== "undefined") data = window[cfg.descKey] || null; - return data && data.animationContainer ? data : null; - }; - - const _getSegmentedIdleFrame = (tab) => { - const cfg = _segmentedIconConfig[tab]; - const desc = _getSegmentedAnimDesc(tab); - if (!cfg || !desc?.animationContainer) return null; - const keys = Object.keys(desc.animationContainer).sort((a, b) => { - const aa = parseInt((String(a).match(/_(\d+)\.png$/) || [0, 0])[1], 10) || 0; - const bb = parseInt((String(b).match(/_(\d+)\.png$/) || [0, 0])[1], 10) || 0; - return aa - bb; - }); - for (const pattern of cfg.idlePatterns) { - const match = keys.find(key => pattern.test(key)); - if (match) return desc.animationContainer[match]; - } - return desc.animationContainer[keys[0]] || null; - }; - - const _replaceSegmentedBase = (tab, textureName, baseName) => { - const cfg = _segmentedIconConfig[tab]; - if (!cfg) return textureName; - return String(textureName || "").replace(new RegExp("^" + cfg.prefix + "_\\d+"), baseName); - }; - - const _makeSegmentedIconFrames = (tab, max = 120) => { - const cfg = _segmentedIconConfig[tab]; - if (!cfg) return []; - const desc = _getSegmentedAnimDesc(tab); - const entries = desc?.usedTextures - ? Object.values(desc.usedTextures).slice().sort((a, b) => (parseInt(a.tag || "0", 10) || 0) - (parseInt(b.tag || "0", 10) || 0)) - : cfg.defaultEntries; - const frames = []; - for (let i = 1; i <= max; i++) { - const baseName = `${cfg.prefix}_${String(i).padStart(2, "0")}`; - const hasAnyPart = entries.some(entry => { - const frameName = _replaceSegmentedBase(tab, entry.texture, baseName); - return typeof getAtlasFrame === "function" && !!getAtlasFrame(this, frameName); - }); - if (hasAnyPart) frames.push(`${baseName}_001.png`); - } - return frames.length ? frames : [`${cfg.fallbackBase}_001.png`]; - }; - - window.currentSpider = window.currentSpider || localStorage.getItem("iconCurrentSpider") || "spider_01"; - window.currentRobot = window.currentRobot || localStorage.getItem("iconCurrentRobot") || "robot_01"; - _iconFrameSets.spider = _makeSegmentedIconFrames("spider"); - _iconFrameSets.robot = _makeSegmentedIconFrames("robot"); - - - const _iconWindowProps = { - icon: "currentPlayer", - ship: "currentShip", - ball: "currentBall", - wave: "currentWave", - ufo: "currentBird", - robot: "currentRobot", - spider: "currentSpider", - }; - - const _iconAtlas = { - icon: "GJ_GameSheetIcons", - ship: "GJ_GameSheetIcons", - ball: "GJ_GameSheetIcons", - wave: "GJ_GameSheetIcons", - ufo: "GJ_GameSheetIcons", - robot: "GJ_GameSheetIcons", - spider: "GJ_GameSheetIcons", - }; - - const _tabBtnFrames = { - icon: { on: "gj_iconBtn_on_001.png", off: "gj_iconBtn_off_001.png" }, - ship: { on: "gj_shipBtn_on_001.png", off: "gj_shipBtn_off_001.png" }, - ball: { on: "gj_ballBtn_on_001.png", off: "gj_ballBtn_off_001.png" }, - wave: { on: "gj_dartBtn_on_001.png", off: "gj_dartBtn_off_001.png" }, - ufo: { on: "gj_birdBtn_on_001.png", off: "gj_birdBtn_off_001.png" }, - robot:{ on: "gj_robotBtn_on_001.png", off: "gj_robotBtn_off_001.png" }, - spider:{ on: "gj_spiderBtn_on_001.png", off: "gj_spiderBtn_off_001.png" }, - }; - - const _safeTabBtnFrame = (tab, state) => { - const frame = _tabBtnFrames[tab]?.[state] || _tabBtnFrames.icon[state]; - return (typeof getAtlasFrame === "function" && getAtlasFrame(this, frame)) ? frame : _tabBtnFrames.icon[state]; - }; - - this._openIconSelector = (startTab = "icon") => { - if (this._iconOverlay) return; - - const sw = screenWidth; - const sh = screenHeight; - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - - const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); - const gradientSteps = 80; - for (let gi = 0; gi < gradientSteps; gi++) { - const t = gi / (gradientSteps - 1); - const r1 = Math.round(0x92 + (0x3a - 0x92) * t); - const g1 = Math.round(0x92 + (0x3a - 0x92) * t); - const b1 = Math.round(0x92 + (0x3a - 0x92) * t); - const bandColor = (r1 << 16) | (g1 << 8) | b1; - const bandY = Math.floor(gi * sh / gradientSteps); - const bandH = Math.ceil(sh / gradientSteps) + 1; - overlay.fillStyle(bandColor, 1); - overlay.fillRect(0, bandY, sw, bandH); - } - this._iconOverlay = overlay; - - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) - .setScrollFactor(0).setDepth(101).setInteractive(); - - const titleTxt = this.add.bitmapText(sw / 2, 60, "goldFont", "Icon Selector", 32) - .setOrigin(0.5, 0.5).setScrollFactor(0).setDepth(105); - - this._iconOverlayObjects = [overlay, blocker, titleTxt]; - - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(104).setFlipY(true) - .setFlipX(true) - .setRotation(Math.PI).setInteractive(); - this._iconOverlayObjects.push(backBtn); - this._makeBouncyButton(backBtn, 1, () => this._closeIconSelector()); - - const topBarHeight = 100; - const lineY = topBarHeight + 100; - const linePadding = 230; - const topBar = this.add.graphics().setScrollFactor(0).setDepth(102); - const lineSegments = 40; - const lineStart = linePadding; - const lineEnd = sw - linePadding; - const lineWidth = lineEnd - lineStart; - const fadeZone = lineWidth * 0.25; - for (let li = 0; li < lineSegments; li++) { - const t0 = li / lineSegments; - const t1 = (li + 1) / lineSegments; - const x0 = lineStart + t0 * lineWidth; - const x1 = lineStart + t1 * lineWidth; - const mid = (t0 + t1) / 2 * lineWidth; - let alpha; - if (mid < fadeZone) { - alpha = mid / fadeZone; - } else if (mid > lineWidth - fadeZone) { - alpha = (lineWidth - mid) / fadeZone; - } else { - alpha = 1; - } - topBar.lineStyle(3, 0xFFFFFF, alpha); - topBar.beginPath(); - topBar.moveTo(x0, lineY); - topBar.lineTo(x1, lineY); - topBar.strokePath(); - } - this._iconOverlayObjects.push(topBar); - - const cols = 12; - const iconSize = 60; - const padding = 2; - const containerPadding = 10; - const rows = 3; - const containerWidth = cols * iconSize + (cols - 1) * padding + 12; - const containerHeight = rows * iconSize + (rows - 1) * padding + 12; - const containerX = sw / 2 - containerWidth / 2; - const containerY = sh - containerHeight - containerPadding - 150; - const startX = containerX + 6 + iconSize / 2; - const startY = containerY + 6 + iconSize / 2; - - const gridBg = this.add.graphics().setScrollFactor(0).setDepth(102); - gridBg.fillStyle(0x454444, 1); - gridBg.fillRoundedRect(containerX, containerY, containerWidth, containerHeight, 10); - this._iconOverlayObjects.push(gridBg); - - const cornerTL = this.add.image(0, 0, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(100).setOrigin(0, 0).setFlipY(true) - const cornerTR = this.add.image(sw, 0, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(103).setOrigin(1, 0).setFlipY(true).setFlipX(true); - const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); - const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1); - this._iconOverlayObjects.push(cornerTL, cornerTR, cornerBR, cornerBL); - - const navDotSpacing = 35; - const navDotY = containerY + containerHeight + 30; - const navDot1 = this.add.image(sw / 2 - navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_on_001.png").setScrollFactor(0).setDepth(104).setScale(0.75); - const navDot2 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75); - const navDot3 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot4 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot5 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot6 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot7 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot8 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - const navDot9 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); - this._iconOverlayObjects.push(navDot1, navDot2, navDot3, navDot4, navDot5, navDot6, navDot7, navDot8, navDot9); - const _updateNavDots = (page, tab) => { - const maxPages = Math.max(1, _getMaxPages(tab)); - const dots = [navDot1, navDot2, navDot3, navDot4, navDot5, navDot6, navDot7, navDot8, navDot9]; - dots.forEach(dot => dot.setVisible(false)); - const totalDotsToShow = Math.min(maxPages, dots.length); - const totalWidth = (totalDotsToShow - 1) * navDotSpacing; - const dotStartX = sw / 2 - totalWidth / 2; - for (let i = 0; i < totalDotsToShow; i++) { - dots[i].setPosition(dotStartX + i * navDotSpacing, navDotY).setVisible(true); - dots[i].setTexture("GJ_GameSheet03", page === i ? "gj_navDotBtn_on_001.png" : "gj_navDotBtn_off_001.png"); - } - }; - - const rainbowColors = [ - 0xFF0000, 0xFF4500, 0xFF7F00, 0xFFAA00, 0xFFD700, - 0xFFFF00, 0xAAFF00, 0x00FF00, 0x00FF7F, 0x00FFFF, - 0x007FFF, 0x0000FF, 0x7F00FF, 0xFF00FF, 0xFF007F, - 0xFFFFFF, 0xC0C0C0, 0x808080, 0x404040, 0x000000, - ]; - - const colorBtnSize = 35; - const colorPadding = 6; - const colorRowWidth = rainbowColors.length * (colorBtnSize + colorPadding) - colorPadding; - const colorRow1Y = containerY + containerHeight + 88; - const colorRow2Y = colorRow1Y + colorBtnSize + 10; - const colorRowStartX = sw / 2 - colorRowWidth / 2 + colorBtnSize / 2; - - const colorLabel1 = this.add.text(sw / 2 - colorRowWidth / 2, colorRow1Y - 14, "", { - fontSize: "11px", color: "#ffffff", fontFamily: "Arial"}).setScrollFactor(0).setDepth(104).setOrigin(0, 0.5).setAlpha(1); - this._iconOverlayObjects.push(colorLabel1); - - const colorLabel2 = this.add.text(sw / 2 - colorRowWidth / 2, colorRow2Y - 14, "", { - fontSize: "11px", color: "#ffffff", fontFamily: "Arial"}).setScrollFactor(0).setDepth(104).setOrigin(0, 0.5).setAlpha(1); - this._iconOverlayObjects.push(colorLabel2); - - const colorBoxWidth = sw; - const colorBoxHeight = colorBtnSize * 2 + 10 + 20; - const colorBoxX = 0; - const colorBoxY = colorRow1Y - colorBtnSize / 2 - 10; - const colorBox = this.add.graphics().setScrollFactor(0).setDepth(101); - colorBox.fillStyle(0x000000, 0.5); - colorBox.fillRect(colorBoxX, colorBoxY, colorBoxWidth, colorBoxHeight); - this._iconOverlayObjects.push(colorBox); - - const color1SelLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false).setScale(0.6); - const color2SelLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false).setScale(0.6); - this._iconOverlayObjects.push(color1SelLabel, color2SelLabel); - - const _moveColorSelect = (label, color, rowY) => { - const idx = rainbowColors.indexOf(color); - if (idx === -1) { - label.setVisible(false); - return; - } - - label.setPosition(colorRowStartX + idx * (colorBtnSize + colorPadding), rowY).setVisible(true); - }; - - _moveColorSelect(color1SelLabel, window.mainColor, colorRow1Y); - _moveColorSelect(color2SelLabel, window.secondaryColor, colorRow2Y); - - for (let ci = 0; ci < rainbowColors.length; ci++) { - const cx = colorRowStartX + ci * (colorBtnSize + colorPadding); - - const btn1AtlasInfo = getAtlasFrame(this, "GJ_colorBtn_001.png"); - let btn1; - btn1 = this.add.rectangle(cx, colorRow1Y, colorBtnSize, colorBtnSize, rainbowColors[ci]).setScrollFactor(0).setDepth(104).setInteractive(); - this._iconOverlayObjects.push(btn1); - - const btn2AtlasInfo = getAtlasFrame(this, "GJ_colorBtn_001.png"); - let btn2; - btn2 = this.add.rectangle(cx, colorRow2Y, colorBtnSize, colorBtnSize, rainbowColors[ci]).setScrollFactor(0).setDepth(104).setInteractive(); - this._iconOverlayObjects.push(btn2); - - ((color, b1, b2) => { - this._makeBouncyButton(b1, 1.0, () => { - window.mainColor = color; - localStorage.setItem("iconMainColor", hexadecimalToHex(color)); - _moveColorSelect(color1SelLabel, color, colorRow1Y); - if (this._player) { - const safeSetTint = (sprite, color) => { - if (sprite && sprite.setTint) { - try { - sprite.setTint(color); - if (this.renderer.type === Phaser.CANVAS && sprite.tintTopLeft !== undefined) { - if (sprite.tintTopLeft === 0xffffff && color !== 0xffffff) { - } - } - } catch (e) { - } - } - }; - - safeSetTint(this._player._playerSpriteLayer?.sprite, color); - safeSetTint(this._player._shipSpriteLayer?.sprite, color); - safeSetTint(this._player._ballSpriteLayer?.sprite, color); - safeSetTint(this._player._waveSpriteLayer?.sprite, color); - for (const layer of this._player._robotLayers || []) safeSetTint(layer?.sprite, color); - for (const layer of this._player._spiderLayers || []) safeSetTint(layer?.sprite, color); - if (this._player._particleEmitter) { - try { - this._player._particleEmitter.tint = color; - } catch (e) { - } - } - } - selectedIcon.setTint(color); - _refreshPreview(_currentTab, _getPreviewFrame(_currentTab)); - }); - this._makeBouncyButton(b2, 1.0, () => { - window.secondaryColor = color; - localStorage.setItem("iconSecondaryColor", hexadecimalToHex(color)); - _moveColorSelect(color2SelLabel, color, colorRow2Y); - if (this._player) { - const safeSetTint = (sprite, color) => { - if (sprite && sprite.setTint) { - try { - sprite.setTint(color); - } catch (e) { - } - } - }; - - safeSetTint(this._player._playerGlowLayer?.sprite, color); - safeSetTint(this._player._playerOverlayLayer?.sprite, color); - safeSetTint(this._player._shipGlowLayer?.sprite, color); - safeSetTint(this._player._shipOverlayLayer?.sprite, color); - safeSetTint(this._player._ballGlowLayer?.sprite, color); - safeSetTint(this._player._ballOverlayLayer?.sprite, color); - safeSetTint(this._player._waveGlowLayer?.sprite, color); - safeSetTint(this._player._waveOverlayLayer?.sprite, color); - for (const layer of this._player._robotLayers || []) safeSetTint(layer?.sprite, color); - for (const layer of this._player._spiderLayers || []) safeSetTint(layer?.sprite, color); - if (this._player._streak) { - try { - this._player._streak._color = color; - } catch (e) { - } - } - } - selectedIconExtra.setTint(window.secondaryColor); - _refreshPreview(_currentTab, _getPreviewFrame(_currentTab)); - }); - })(rainbowColors[ci], btn1, btn2); - } - - const previewY = lineY - 35; - const selectedIconExtra = this.add.image(sw / 2, previewY, _iconAtlas[startTab], null).setScrollFactor(0).setDepth(102).setVisible(false); - const selectedIcon = this.add.image(sw / 2, previewY, _iconAtlas[startTab], null).setScrollFactor(0).setDepth(103); - let selectedSegmentedPreview = null; - - const _destroySegmentedPreview = () => { - if (selectedSegmentedPreview?.destroy) selectedSegmentedPreview.destroy(true); - selectedSegmentedPreview = null; - }; - - const _createSegmentedIconComposite = (tab, pseudoFrame, x, y, maxSize, depth, muted = false) => { - const cfg = _segmentedIconConfig[tab]; - const idleFrame = _getSegmentedIdleFrame(tab); - if (!cfg || !idleFrame) return null; - const baseName = String(pseudoFrame || `${cfg.fallbackBase}_001.png`).replace(/_001\.png$/, ""); - const container = this.add.container(x, y).setScrollFactor(0).setDepth(depth); - const parts = []; - for (const spriteKey of Object.keys(idleFrame)) { - if (!spriteKey.startsWith("sprite_")) continue; - const spriteData = idleFrame[spriteKey]; - const tag = parseInt(spriteData.tag || "0", 10) || 0; - const pos = _selectorParseAnimPair(spriteData.position, 0, 0); - const sc = _selectorParseAnimPair(spriteData.scale, 1, 1); - const fl = _selectorParseAnimPair(spriteData.flipped, 0, 0); - const zValue = parseFloat(spriteData.zValue || tag || "0") || 0; - const rotDeg = parseFloat(spriteData.rotation || "0") || 0; - const sourceTexture = _replaceSegmentedBase(tab, spriteData.texture || `${cfg.fallbackBase}_01_001.png`, baseName); - const isSpiderLegTag = tab === "spider" && [0, 1, 4, 5].includes(tag); - const isRobotLegTag = tab === "robot" && [0, 2, 4, 6].includes(tag); - const isRobotArmTag = tab === "robot" && [1, 5].includes(tag); - const localYOffset = tab === "spider" - ? (tag === 3 ? 5 : (isSpiderLegTag ? -9 : 0)) - : (tag === 3 ? 5 : (isRobotArmTag ? -1 : (isRobotLegTag ? -9 : 0))); - const localXScale = tab === "spider" - ? (isSpiderLegTag ? 1.8 : 1) - : ((isRobotLegTag || isRobotArmTag) ? 1.8 : 1); - const variants = [ - { kind: "base", frame: sourceTexture, tint: muted ? 0xAFAFAF : window.mainColor, z: zValue * 0.1 }, - { kind: "overlay", frame: _selectorVariantFrameName(sourceTexture, "overlay"), tint: muted ? 0xffffff : window.secondaryColor, z: zValue * 0.1 + 0.04 }, - { kind: "extra", frame: _selectorVariantFrameName(sourceTexture, "extra"), tint: null, z: zValue * 0.1 + 0.08 } - ]; - for (const variant of variants) { - if (typeof getAtlasFrame !== "function" || !getAtlasFrame(this, variant.frame)) continue; - const img = this.add.image(pos.x * localXScale, -(pos.y + localYOffset), "GJ_GameSheetIcons", variant.frame); - img.rotation = rotDeg * Math.PI / 180; - img.scaleX = sc.x * (fl.x ? -1 : 1); - img.scaleY = sc.y * (fl.y ? -1 : 1); - if (variant.tint !== null && variant.tint !== undefined) img.setTint(variant.tint); - img._selectorZ = variant.z; - parts.push(img); - } - } - parts.sort((a, b) => (a._selectorZ || 0) - (b._selectorZ || 0)); - parts.forEach(part => container.add(part)); - if (!parts.length) { - container.destroy(true); - return null; - } - let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - for (const img of parts) { - const w = Math.abs((img.width || 1) * (img.scaleX || 1)); - const h = Math.abs((img.height || 1) * (img.scaleY || 1)); - minX = Math.min(minX, img.x - w / 2); - maxX = Math.max(maxX, img.x + w / 2); - minY = Math.min(minY, img.y - h / 2); - maxY = Math.max(maxY, img.y + h / 2); - } - const width = Math.max(1, maxX - minX); - const height = Math.max(1, maxY - minY); - const fitScale = muted ? (maxSize / height) : Math.min(maxSize / width, maxSize / height); - container.setScale(fitScale); - container._selectorBaseScale = fitScale; - return container; - }; - - const _getPreviewFrame = (tab) => { - const prop = _iconWindowProps[tab]; - const frames = _iconFrameSets[tab] || []; - const currentValue = String(window[prop] || ""); - const match = frames.find(f => f.replace("_001.png", "") === currentValue); - return match || frames[0]; - }; - - const _refreshPreview = (tab, frame) => { - if (_isSegmentedIconTab(tab)) { - _destroySegmentedPreview(); - selectedIcon.setVisible(false); - selectedIconExtra.setVisible(false); - selectedSegmentedPreview = _createSegmentedIconComposite(tab, frame, sw / 2, previewY, 82, 103, false); - if (selectedSegmentedPreview) this._iconOverlayObjects.push(selectedSegmentedPreview); - return; - } - _destroySegmentedPreview(); - selectedIcon.setVisible(true); - selectedIcon.setTexture(_iconAtlas[tab], frame); - const s = Math.min(80 / (selectedIcon.width || 80), 80 / (selectedIcon.height || 80)) * 0.85; - selectedIcon.setScale(s); - selectedIcon.setTint(window.mainColor); - const extraFrame = frame.replace("_001.png", "_2_001.png"); - const extraInfo = getAtlasFrame(this, extraFrame); - if (extraInfo) { - selectedIconExtra.setTexture(extraInfo.atlas, extraInfo.frame).setVisible(true).setScale(s).setTint(window.secondaryColor); - } else { - selectedIconExtra.setVisible(false); - } - }; - - _refreshPreview(startTab, _getPreviewFrame(startTab)); - this._iconOverlayObjects.push(selectedIconExtra, selectedIcon); - - const tabBtnY = containerY - 40; - const tabKeys = ["icon", "ship", "ball", "ufo", "wave", "robot", "spider"]; - const tabSpacing = 58; - const tabOffsets = { - icon: -tabSpacing * 3, - ship: -tabSpacing * 2, - ball: -tabSpacing, - ufo: 0, - wave: tabSpacing, - robot: tabSpacing * 2, - spider: tabSpacing * 3, - }; - const tabRotations = { icon: -Math.PI/2, ship: 0, ball: -Math.PI/2, ufo: Math.PI/2, wave: Math.PI/2, robot: 0, spider: 0 }; - const tabFlipXStates = { icon: true, ship: false, ball: true, ufo: false, wave: false, robot: false, spider: false }; - const tabFlipYStates = { icon: false, ship: false, ball: false, ufo: true, wave: true, robot: false, spider: false }; - const tabBtnSprites = {}; - - const _switchTab = (tab) => { - for (const k of tabKeys) { - if (tabBtnSprites[k]) { - tabBtnSprites[k].setTexture("GJ_GameSheet03", - _safeTabBtnFrame(k, k === tab ? "on" : "off")); - } - } - _refreshPreview(tab, _getPreviewFrame(tab)); - _buildGrid(tab); - }; - - tabKeys.forEach((tab, i) => { - const isActive = tab === startTab; - const btn = this.add.image(sw / 2 + tabOffsets[tab], tabBtnY, "GJ_GameSheet03", - _safeTabBtnFrame(tab, isActive ? "on" : "off")) - .setScrollFactor(0).setDepth(104).setScale(0.75) - - .setInteractive(); - tabBtnSprites[tab] = btn; - this._iconOverlayObjects.push(btn); - this._makeBouncyButton(btn, 0.75, () => _switchTab(tab)); - }); - - this._iconGridObjects = []; - - const selLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false); - this._iconOverlayObjects.push(selLabel); - - const iconsPerPage = cols * rows; - let currentPage = 0; - - const arrowY = containerY + containerHeight / 2; - const arrowMargin = 54; - - const prevArrow = this.add.image(containerX - arrowMargin, arrowY, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(106).setScale(0.8).setFlipX(false).setInteractive(); - const nextArrow = this.add.image(containerX + containerWidth + arrowMargin, arrowY, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(106).setScale(0.8).setInteractive().setFlipX(true); - - //bouncy buttons for arrows - const _getMaxPages = (tab) => { - return Math.ceil(_iconFrameSets[tab].length / iconsPerPage); - }; - const _prevPage = () => { - const maxPages = _getMaxPages(_currentTab); - currentPage = (currentPage - 1 + maxPages) % maxPages; - _updateNavDots(currentPage, _currentTab); - _buildGrid(_currentTab, currentPage); - }; - const _nextPage = () => { - const maxPages = _getMaxPages(_currentTab); - currentPage = (currentPage + 1) % maxPages; - _updateNavDots(currentPage, _currentTab); - _buildGrid(_currentTab, currentPage); - }; - this._makeBouncyButton(prevArrow, 0.8, _prevPage); - this._makeBouncyButton(nextArrow, 0.8, _nextPage); - this._iconOverlayObjects.push(prevArrow, nextArrow); - const _buildGrid = (tab, page = 0) => { - for (const o of this._iconGridObjects) { - if (o && o.destroy) o.destroy(); - } - this._iconGridObjects = []; - selLabel.setVisible(false); - const allFrames = _iconFrameSets[tab]; - const frames = allFrames.slice(page * iconsPerPage, (page + 1) * iconsPerPage); - const atlas = _iconAtlas[tab]; - const prop = _iconWindowProps[tab]; - frames.forEach((frame, idx) => { - const col = idx % cols; - const row = Math.floor(idx / cols); - const ix = startX + col * (iconSize + padding); - const iy = startY + row * (iconSize + padding); - const hitRect = this.add.rectangle(ix, iy, iconSize, iconSize, 0x000000, 0).setScrollFactor(0).setDepth(104).setInteractive(); - let iconImg; - let extraImg = null; - let origScale; - if (_isSegmentedIconTab(tab)) { - iconImg = _createSegmentedIconComposite(tab, frame, ix, iy, iconSize * 0.76, 103, true); - if (!iconImg) { - iconImg = this.add.image(ix, iy, "GJ_GameSheetIcons", frame).setScrollFactor(0).setDepth(103).setTint(0xAFAFAF); - origScale = Math.min(iconSize / (iconImg.width || iconSize), iconSize / (iconImg.height || iconSize)) * 0.7; - iconImg.setScale(origScale); - } else { - origScale = iconImg._selectorBaseScale || iconImg.scaleX || 1; - } - } else { - iconImg = this.add.image(ix, iy, atlas, frame).setScrollFactor(0).setDepth(103).setTint(0xAFAFAF); - origScale = Math.min( - iconSize / (iconImg.width || iconSize), - iconSize / (iconImg.height || iconSize) - ) * 0.7; - iconImg.setScale(origScale); - const extraFrame = frame.replace("_001.png", "_2_001.png"); - const extraInfo = getAtlasFrame(this, extraFrame); - extraImg = extraInfo - ? this.add.image(ix, iy, extraInfo.atlas, extraInfo.frame).setScrollFactor(0).setDepth(102).setScale(origScale) - : null; - } - if (extraImg) this._iconGridObjects.push(extraImg); - this._iconGridObjects.push(iconImg, hitRect); - if (frame.replace("_001.png", "") === window[prop]) { - selLabel.setPosition(ix, iy).setScale(0.75).setVisible(true); - } - - ((capturedFrame, capturedImg, capturedExtra, capturedOrigScale) => { - const bouncedScale = capturedOrigScale * 1.26; - const iconTargets = capturedExtra ? [capturedImg, capturedExtra] : [capturedImg]; - hitRect.on("pointerdown", () => { - hitRect._pressed = true; - iconTargets.forEach(t => this.tweens.killTweensOf(t, "scale")); - iconTargets.forEach(t => this.tweens.add({ targets: t, scale: bouncedScale, duration: 300, ease: "Bounce.Out" })); - }); - hitRect.on("pointerout", () => { - if (hitRect._pressed) { - hitRect._pressed = false; - iconTargets.forEach(t => this.tweens.killTweensOf(t, "scale")); - iconTargets.forEach(t => this.tweens.add({ targets: t, scale: capturedOrigScale, duration: 400, ease: "Bounce.Out" })); - } - }); - hitRect.on("pointerup", () => { - hitRect._pressed = false; - iconTargets.forEach(t => { this.tweens.killTweensOf(t); t.setScale(capturedOrigScale); }); - if (!this._iconOverlay) return; - - selLabel.setPosition(capturedImg.x, capturedImg.y).setScale(0.75).setVisible(true); - - window[prop] = capturedFrame.replace("_001.png", ""); - localStorage.setItem("icon" + prop.charAt(0).toUpperCase() + prop.slice(1), window[prop]); - - if (tab === "icon" && this._player) { - const layerMap = [ - { lp: "_playerSpriteLayer", suffix: "_001.png", tint: window.mainColor }, - { lp: "_playerGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, - { lp: "_playerOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - { lp: "_playerExtraLayer", suffix: "_extra_001.png", tint: window.mainColor }, - ]; - for (const { lp, suffix, tint } of layerMap) { - const layer = this._player[lp]; - if (!layer || !layer.sprite) continue; - const found = getAtlasFrame(this, `${window.currentPlayer}${suffix}`); - if (found) { - layer.sprite.setTexture(found.atlas, found.frame); - if (tint !== null) layer.sprite.setTint(tint); - } - } - } - if (tab === "ship" && this._player) { - const layerMap = [ - { lp: "_shipSpriteLayer", suffix: "_001.png", tint: window.mainColor }, - { lp: "_shipGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, - { lp: "_shipOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - { lp: "_shipExtraLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - ]; - for (const { lp, suffix, tint } of layerMap) { - const layer = this._player[lp]; - if (!layer || !layer.sprite) continue; - const found = getAtlasFrame(this, `${window.currentShip}${suffix}`); - if (found) { - layer.sprite.setTexture(found.atlas, found.frame); - if (tint !== null) layer.sprite.setTint(tint); - } - } - } - if (tab === "ball" && this._player) { - const layerMap = [ - { lp: "_ballSpriteLayer", suffix: "_001.png", tint: window.mainColor }, - { lp: "_ballGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, - { lp: "_ballOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - ]; - for (const { lp, suffix, tint } of layerMap) { - const layer = this._player[lp]; - if (!layer || !layer.sprite) continue; - const found = getAtlasFrame(this, `${window.currentBall}${suffix}`); - if (found) { - layer.sprite.setTexture(found.atlas, found.frame); - layer.sprite.setTint(tint); - } - } - } - if (tab === "wave" && this._player) { - const layerMap = [ - { lp: "_waveSpriteLayer", suffix: "_001.png", tint: window.mainColor }, - { lp: "_waveGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, - { lp: "_waveOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - ]; - for (const { lp, suffix, tint } of layerMap) { - const layer = this._player[lp]; - if (!layer || !layer.sprite) continue; - const found = getAtlasFrame(this, `${window.currentWave}${suffix}`); - if (found) { - layer.sprite.setTexture(found.atlas, found.frame); - if (tint !== null) layer.sprite.setTint(tint); - } - } - } - if (tab === "ufo" && this._player) { - const layerMap = [ - { lp: "_birdSpriteLayer", suffix: "_001.png", tint: window.mainColor }, - { lp: "_birdGlowLayer", suffix: "_2_001.png", tint: window.secondaryColor }, - { lp: "_birdOverlayLayer", suffix: "_3_001.png", tint: window.secondaryColor }, - { lp: "_birdExtraLayer", suffix: "_extra_001.png",tint: window.mainColor }, - ]; - for (const { lp, suffix, tint } of layerMap) { - const layer = this._player[lp]; - if (!layer || !layer.sprite) continue; - const found = getAtlasFrame(this, `${window.currentBird}${suffix}`); - if (found) { - layer.sprite.setTexture(found.atlas, found.frame); - if (tint !== null) layer.sprite.setTint(tint); - } - } - } - - _refreshPreview(tab, capturedFrame); - }); - })(frame, iconImg, extraImg, origScale); - }); - }; - - let _currentTab = startTab; - - const _switchTabOrig = _switchTab; - const _switchTabPaged = (tab) => { - _currentTab = tab; - currentPage = 0; - _updateNavDots(0, tab); - for (const k of tabKeys) { - if (tabBtnSprites[k]) { - tabBtnSprites[k].setTexture("GJ_GameSheet03", - _safeTabBtnFrame(k, k === tab ? "on" : "off")); - } - } - _refreshPreview(tab, _getPreviewFrame(tab)); - _buildGrid(tab, 0); - }; - tabKeys.forEach(tab => { - const btn = tabBtnSprites[tab]; - if (btn) { - btn.removeAllListeners("pointerup"); - btn.removeAllListeners("pointerdown"); - btn.removeAllListeners("pointerout"); - this._makeBouncyButton(btn, 0.75, () => _switchTabPaged(tab)); - } - }); - - _updateNavDots(0, startTab); - _buildGrid(startTab, 0); - }; - - this._closeIconSelector = (silent = false) => { - if (!this._iconOverlay) return; - const destroy = () => { - if (this._iconGridObjects) { - for (const obj of this._iconGridObjects) { - if (obj && obj.destroy) obj.destroy(); - } - this._iconGridObjects = null; - } - if (this._iconOverlayObjects) { - for (const obj of this._iconOverlayObjects) { - if (obj && obj.destroy) obj.destroy(); - } - this._iconOverlayObjects = null; - } - this._iconOverlay = null; - }; - if (silent) { destroy(); return; } - const sw = screenWidth; - const sh = screenHeight; - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ - targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", - onComplete: () => { - destroy(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._closeCreatorMenu = (silent = false) => { - if (!this._creatorOverlay) return; - if (silent == false) this._creatorMenuOpen = false; - const destroy = () => { - if (this._creatorOverlayObjects) { - for (const obj of this._creatorOverlayObjects) { - if (obj && obj.destroy) obj.destroy(); - } - this._creatorOverlayObjects = null; - } - this._creatorOverlay = null; - }; - if (silent) { destroy(); return; } - const sw = screenWidth; - const sh = screenHeight; - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ - targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", - onComplete: () => { - destroy(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._positionMenuItems(); - //icon stuff sequel - if (this._iconBtn) { - this._iconBtn.x = (screenWidth / 2) - this._playBtn.width / 2 - 50 - (this._iconBtn.width * this._iconBtn.scaleX) / 2; - this.tweens.killTweensOf(this._iconBtn, "y"); - this._iconBtn.y = 320; - if (this._chrSelDecor) this._chrSelDecor.destroy(); - this._chrSelDecor = this.add.image(this._iconBtn.x - 110, this._iconBtn.y - (this._iconBtn.height * this._iconBtn.scaleY) / 2 + 160, "GJ_GameSheet03", "GJ_chrSel_001.png").setScrollFactor(0).setDepth(31); -} - if (this._creatorBtn) { - this._creatorBtn.x = (screenWidth / 2) + this._playBtn.width / 2 + 50 + (this._creatorBtn.width * this._creatorBtn.scaleX) / 2; - this.tweens.killTweensOf(this._creatorBtn, "y"); - this._creatorBtn.y = 320; - if (this._lvlEditDecor) this._lvlEditDecor.destroy(); - this._lvlEditDecor = this.add.image(this._creatorBtn.x + 110, this._creatorBtn.y - (this._creatorBtn.height * this._creatorBtn.scaleY) / 2 + 160, "GJ_GameSheet03", "GJ_lvlEdit_001.png").setScrollFactor(0).setDepth(31); -} - this._spaceWasDown = false; - this._spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); - this._upKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP); - this._wKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W); - this._lKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.L); - this._leftKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT); - this._rightKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT); - this._aKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A); - this._dKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D); - - this._startPosIndex = -1; - - this.input.keyboard.on('keydown-Q', () => { - if (!window.startPosSwitcher) return; - this.changeStartPos(-1); - }); - - this.input.keyboard.on('keydown-E', () => { - if (!window.startPosSwitcher) return; - this.changeStartPos(1); - }); - - this._percentageLabel = this.add.bitmapText(screenWidth / 2, 20, "bigFont", "0%", 30).setOrigin(0.5, 0.5); - this._percentageLabel.setVisible(false); - this._percentageLabel.setDepth(100); - - this._noclipIndicator = this.add.bitmapText(10, 10, "bigFont", "Noclip", 20) - .setOrigin(0, 0) - .setAlpha(0.4) - .setDepth(100) - .setVisible(false); - - this._accuracyIndicator = this.add.bitmapText(10, 30, "bigFont", "100.00%", 20) - .setOrigin(0, 0) - .setAlpha(0.4) - .setDepth(100) - .setVisible(false); - - this._deathsIndicator = this.add.bitmapText(10, 50, "bigFont", "0 Deaths", 20) - .setOrigin(0, 0) - .setAlpha(0.4) - .setDepth(100) - .setVisible(false); - - this._cpsIndicator = this.add.bitmapText(10, 70, "bigFont", "0 CPS", 20) - .setOrigin(0, 0) - .setAlpha(0.4) - .setDepth(100) - .setVisible(false); - - this._bottedIndicator = this.add.bitmapText(10, 70, "bigFont", "Botted", 20) - .setOrigin(0, 0) - .setAlpha(0.4) - .setDepth(100) - .setTint(0xff0000) - .setVisible(false); - - this.noclipFlash = this.add.rectangle( - this.cameras.main.centerX, - this.cameras.main.centerY, - this.cameras.main.width, - this.cameras.main.height, - 0xff0000 - ); - this.noclipFlash.setScrollFactor(0); - this.noclipFlash.setDepth(99); - this.noclipFlash.setAlpha(0); - - this._updatePracticeHUDBar = () => {}; - - this._pauseBtn = this.add.image(screenWidth - 30, 30, "GJ_WebSheet", "GJ_pauseBtn_clean_001.png").setScrollFactor(0).setDepth(30).setAlpha(75 / 255).setVisible(false); - this._pauseBtn.setInteractive(); - this._expandHitArea(this._pauseBtn, 2); - this._pauseBtn.on("pointerdown", () => this._pauseGame()); - this._escKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ESC); - this._escKey.on("down", () => { - if (this._levelSelectOverlay) { - this._closeLevelSelect(); - return; - } - if (this._iconOverlay) { - this._closeIconSelector(); - return; - } - if (this._updateLogPopup) { - this._closeUpdateLogPopup(); - return; - } - if (this._levelViewOverlay) { - this._closeLevelView(); - return; - } - if (this._editorOverlay) { - this._closeEditorMenu(); - this._openCreatorMenu(); - return; - } - if (this._playOverlay) { - this._closePlayMenu(false, () => this._playMenuBackTarget()); - return; - } - if (this._searchResultOverlay) { - this._closeSearchResultScene(); - return; - } - if (this._searchOverlay) { - this._closeSearchMenu(true); - this._openCreatorMenu(); - return; - } - if (this._onlineLevelsOverlay) { - this._closeOnlineLevelsScene(); - return; - } - if (this._creatorOverlay) { - this._closeCreatorMenu(); - return; - } - if (this._settingsPopup) { - this._settingsPopup.destroy(); - this._settingsPopup = null; - return; - } - if (this._macroPopup) { - this.events.off("update", this._refreshMacroButtons); - this._macroPopup.destroy(); - this._macroPopup = null; - return; - } - if (this._settingsLayerOverlay) { - if (!this._settingsScreenClosing) { - this._hideSettingsScreen(); - } - return; - } - if (this._infoPopup) { - this._infoPopup.destroy(); - this._infoPopup = null; - return; - } - if (this._newgroundsPopup) { - this._closeNewgroundsPopup(); - return; - } - if (this._editorTriggerChannelPopup) { - if (typeof this._closeEditorTriggerChannelPopup === "function") { - this._closeEditorTriggerChannelPopup(); - } else { - this._editorTriggerChannelPopup.destroy(); - this._editorTriggerChannelPopup = null; - } - return; - } - if (this._editorColorPickerPopup) { - this._closeEditorColorPickerPopup(); - return; - } - if (this._editorHorizontalOptionPopup) { - this._closeEditorHorizontalOptionPopup(); - return; - } - if (this._editorStartOptionsPopup) { - this._closeEditorStartOptionsPopup(); - return; - } - if (this._editorLevelSettingsPopup) { - this._closeEditorLevelSettingsPopup(); - return; - } - if (this._statsLayerOverlay) { - this._hideStatsScreen(); - return; - } - if (this._paused) { - this._audio.playEffect("quitSound_01"); - this._audio.stopMusic(); - this._resumeGame(); - this.scene.restart(); - } else if (!this._menuActive && !this._slideIn && !this._levelWon) { - this._pauseGame(); - } - }); - this._restartKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.R); - this._restartKey.on("down", () => { - if (!this._menuActive && !this._slideIn && !this._levelWon && !this._menuActive) { - this._restartLevel(); - } - }); - this._practiceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.P); - this._practiceKey.on("down", () => { - if (!this._menuActive && !this._slideIn) { - const isPracticeMode = this._practicedMode.togglePracticeMode(); - if (this._checkpointBtnContainer) { - this._checkpointBtnContainer.setVisible(isPracticeMode); - } - if (this._practiceModeBarContainer) { - this._practiceModeBarContainer.setVisible(isPracticeMode); - } - this._audio.startMusic(this._getCurrentMusicSyncOffset()); - } - }); - this._saveCheckpointKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Z); - this._saveCheckpointKey.on("down", () => { - if (!this._menuActive && !this._slideIn && this._practicedMode.practiceMode) { - const saved = this._practicedMode.saveCheckpoint(this._state, this._playerWorldX, this._cameraX, this); - if (saved) { - } - } - }); - this._deleteCheckpointKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.X); - this._deleteCheckpointKey.on("down", () => { - if (!this._menuActive && !this._slideIn && this._practicedMode.practiceMode) { - const deleted = this._practicedMode.deleteLastCheckpoint(); - } - }); - this._paused = false; - this._pauseContainer = null; - this._sfxVolume = localStorage.getItem("userSfxVol") ?? 1; - this._initMacroBot(); - this.input.on("pointerdown", () => { - if (!this._menuActive && !this._paused && !this._levelSelectOverlay && !this._levelWon && !window.isEditor) { - this._pushButton(); - } - }); - this.input.on("pointerup", () => { - if (!this._menuActive && !this._paused && !this._levelSelectOverlay && !this._levelWon && !window.isEditor) { - this._releaseButton(); - } - }); - if (!window.gdpointerup) { - window.gdpointerup = true; - window.addEventListener("pointerup", () => this._releaseButton(true)); - } - if (!window.gdtouchend) { - window.gdtouchend = true; - window.addEventListener("touchend", () => this._releaseButton(true)); - } - this.scale.on("enterfullscreen", () => this._onFullscreenChange(true)); - this.scale.on("leavefullscreen", () => this._onFullscreenChange(false)); - - this._buildHUD(); - this._createStartPosGui(); - this._loadSettings(); - - document.addEventListener("visibilitychange", () => { - if (document.hidden) { - this._audio.pauseMusic(); - } else if (!this._menuActive && !this._paused && !this._state.isDead && !this._levelWon) { - this._audio.resumeMusic(); - } - }); - if (!window.gdorientationchange) { - window.gdorientationchange = true; - window.addEventListener("orientationchange", () => { - this.time.delayedCall(100, () => this.scale.refresh()); - }); - } - if (!window.gdresize) { - window.gdresize = true; - window.addEventListener("resize", () => { - this.scale.refresh(); - }); - } - if (this.game.registry.get("fadeInFromBlack")) { - this.game.registry.remove("fadeInFromBlack"); - this.cameras.main.fadeIn(400, 0, 0, 0); - } - this._levelLabel = this.add.bitmapText(screenWidth - 565, 30, "bigFont", window.currentlevel[1], 30).setOrigin(0.5, 0.5).setVisible(false); - this._levelLabel.setScale(Math.min(1, 220 / this._levelLabel.width)); - - this._leftBtn = this.add.image(screenWidth - 700, 30, "GJ_GameSheet03", "edit_leftBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setVisible(false); - this._rightBtn = this.add.image(screenWidth - 429, 30, "GJ_GameSheet03", "edit_leftBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setVisible(false); - this._rightBtn.setRotation(Math.PI); - window.scene = this.scene; - window.rightbuttoncallback = () => { - if (this._levelSelectOverlay && this._levelSelectSwitchLevel) { - this._levelSelectSwitchLevel(1); - } - }; - window.leftbuttoncallback = () => { - if (this._levelSelectOverlay && this._levelSelectSwitchLevel) { - this._levelSelectSwitchLevel(-1); - } - }; - this._makeBouncyButton(this._leftBtn, 1, () => {window.leftbuttoncallback()}, () => this._menuActive); - this._makeBouncyButton(this._rightBtn, 1, () => {window.rightbuttoncallback()}, () => this._menuActive); - const menuMusicEnabled = localStorage.getItem("menuMusicEnabled"); - const shouldPlayMenuMusic = menuMusicEnabled === null ? true : menuMusicEnabled === "true"; - - if (window.isEditor) { - this._audio.stopMusic(); - } else if (!this._audio.isplaying() && shouldPlayMenuMusic) { - this._audio.startMenuMusic(); - } else if (this._audio.isplaying() && !shouldPlayMenuMusic) { - this._audio.stopMusic(); - } - if (!window.updateLogShown) { - this._buildUpdateLogPopup(); - window.updateLogShown = true; - } - if (window.levelID) { - this._openSearchMenu(); - } - if (this.game.registry.get("autoStartGame")) { - if (!window.settingsMap) { - const cachedLevelText = this.cache.text.get(window.currentlevel[2]) || - ((window._onlineLevelString && window.currentlevel[2] === window._onlineLevelId) ? window._onlineLevelString : null); - if (cachedLevelText) { - this._level.loadLevel(cachedLevelText); - } - } - if (window.settingsMap) { - this.game.registry.remove("autoStartGame"); - this._levelLabel.setVisible(false); - this._leftBtn.setVisible(false); - this._rightBtn.setVisible(false); - if (this._practiceModeBarContainer) { - this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); - } - this._instantLevelStart = true; - this._startGame(); - } else { - console.warn("autoStartGame: missing settingsMap for", window.currentlevel && window.currentlevel[2]); - } - } else if (window._createdLevelReturnToView) { - const returnTarget = window._createdLevelReturnToView; - window._createdLevelReturnToView = null; - const levelId = returnTarget?.createdId; - let level = null; - try { - const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); - level = createdLevels.find(entry => - entry && levelId !== undefined && levelId !== null && - String(entry.createdId) === String(levelId) - ) || null; - } catch (err) { - console.warn("Failed to restore the created-level view", err); - } - if (!level && returnTarget?.snapshot) { - level = returnTarget.snapshot; - } - if (level) { - this._openLevelView(level); - } else { - this._openEditorMenu(); - } - } else if (window._editorReturnToLevelViewId) { - const levelId = window._editorReturnToLevelViewId; - window._editorReturnToLevelViewId = null; - let level = null; - try { - const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); - level = createdLevels.find(entry => entry && entry.createdId === levelId) || null; - } catch (err) { - console.warn("Failed to restore the editor level view", err); - } - if (level) { - this._openLevelView(level); - } else { - this._openEditorMenu(); - } - } else if (window._onlineReturnToPlayMenu) { - const { lvl, backTarget } = window._onlineReturnToPlayMenu; - window._onlineReturnToPlayMenu = null; - window._selectedLevelData = lvl; - this._openPlayMenu(backTarget); - } - } - _parseLevelColors(levelId) { - const LEVEL_COLORS = [ - 0x0100f5,0xf902f8,0xf90285,0xfa0102, - 0xfa8702,0xfcfc06,0x03fb03,0x02fbfb, - 0x007dff - ]; - let index = 0; - if (window.allLevels) { - index = window.allLevels.findIndex(l => l[2] === levelId); - if (index === -1) index = 0; - } - const bgHex = LEVEL_COLORS[index % LEVEL_COLORS.length]; - return { bgHex, groundHex: bgHex }; - } - _openLevelSelect() { - if (this._levelSelectOverlay) return; - const sw = screenWidth; - const sh = screenHeight; - const cx = sw / 2; - const cy = sh / 2; - let { bgHex, groundHex } = this._parseLevelColors(window.currentlevel[2]); - const drawOverlay = (gfx, colorHex, isEveryEnd = false) => { - gfx.clear(); - const rRaw = (colorHex >> 16) & 0xff; - const gRaw = (colorHex >> 8) & 0xff; - const bRaw = colorHex & 0xff; - const topMul = isEveryEnd ? 0.30 : 0.65; - const botMul = isEveryEnd ? 0.18 : 0.42; - const steps = 60; - for (let i = 0; i < steps; i++) { - const t = i / (steps - 1); - const mul = topMul + (botMul - topMul) * t; - const r2 = Math.min(255, Math.round(rRaw * mul)); - const g2 = Math.min(255, Math.round(gRaw * mul)); - const b2 = Math.min(255, Math.round(bRaw * mul)); - gfx.fillStyle((r2 << 16) | (g2 << 8) | b2, 1); - const y0 = Math.floor(i * sh / steps); - gfx.fillRect(0, y0, sw, Math.ceil(sh / steps) + 1); - } - }; - const isEveryEnd = (levelId) => levelId === "level_99"; - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); - const overlay = this.add.graphics().setScrollFactor(0).setDepth(150); - drawOverlay(overlay, bgHex, isEveryEnd(window.currentlevel[2])); - this._levelSelectOverlay = overlay; - const tableBottom = this.add.image(cx, 0, "GJ_GameSheet03", "GJ_topBar_001.png").setScrollFactor(0).setDepth(152).setOrigin(0.5, 0); - const groundY = sh + 175; - const groundId = (window._groundId || "00"); - const groundFrame = this.textures.getFrame("groundSquare_" + groundId + "_001.png"); - const referenceGroundFrame = this.textures.getFrame("groundSquare_00_001.png") || groundFrame; - const referenceGroundH = referenceGroundFrame ? referenceGroundFrame.height : 270; - const groundTopY = groundY - referenceGroundH; - const tileW = groundFrame ? groundFrame.width : 1012; - const numTiles = Math.ceil(sw / tileW) + 2; - const groundTintHex = (colorHex) => { - const r = Math.round(((colorHex >> 16) & 0xff) * 0.45); - const g = Math.round(((colorHex >> 8) & 0xff) * 0.45); - const b = Math.round(( colorHex & 0xff) * 0.45); - return (r << 16) | (g << 8) | b; - }; - const staticGroundTiles = []; - const staticGround2Tiles = []; - const ground2Key = "groundSquare_" + groundId + "_2_001.png"; - const hasGround2 = this.textures.exists(ground2Key); - for (let gi = 0; gi < numTiles; gi++) { - const tileX = gi * tileW; - const gt = this.add.image(tileX, groundTopY, "groundSquare_" + groundId + "_001.png") - .setScrollFactor(0).setDepth(151).setOrigin(0, 0).setTint(groundTintHex(groundHex)); - staticGroundTiles.push(gt); - if (hasGround2) { - const gt2 = this.add.image(tileX, groundTopY, ground2Key) - .setScrollFactor(0).setDepth(151.5).setOrigin(0, 0).setTint(groundTintHex(groundHex)); - staticGround2Tiles.push(gt2); - } - } - const floorLineFrame = this.textures.getFrame("GJ_WebSheet", "floorLine_01_001.png"); - const floorLineW = floorLineFrame ? floorLineFrame.width : 888; - const floorLineScale = sw / floorLineW; - const staticFloorLine = this.add.image(cx, groundTopY, "GJ_WebSheet", "floorLine_01_001.png") - .setScrollFactor(0).setDepth(152).setOrigin(0.5, 0.5).setScale(floorLineScale, 1).setBlendMode(S); - const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1).setFlipY(false); - const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); - const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png").setScrollFactor(0).setDepth(154).setFlipX(true).setScale(1, -1).setRotation(Math.PI).setInteractive(); - backBtn.on("pointerdown", () => { - backBtn._pressed = true; - this.tweens.killTweensOf(backBtn); - this.tweens.add({ targets: backBtn, scaleX: 1.26, scaleY: -1.26, duration: 300, ease: "Bounce.Out" }); - }); - backBtn.on("pointerout", () => { - if (backBtn._pressed) { - backBtn._pressed = false; - this.tweens.killTweensOf(backBtn); - this.tweens.add({ targets: backBtn, scaleX: 1, scaleY: -1, duration: 400, ease: "Bounce.Out" }); - } - }); - backBtn.on("pointerup", () => { - if (backBtn._pressed) { - backBtn._pressed = false; - this.tweens.killTweensOf(backBtn); - backBtn.setScale(1, -1); - this._closeLevelSelect(); - } - }); - const infoBtn = this.add.image(sw - 40, 40, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScrollFactor(0).setDepth(154).setInteractive(); - const arrowL = this.add.image(55, cy - 25, "GJ_GameSheet03", "navArrowBtn_001.png").setScrollFactor(0).setDepth(154).setScale(1.1).setFlipX(true).setInteractive(); - const arrowR = this.add.image(sw - 55, cy - 25, "GJ_GameSheet03", "navArrowBtn_001.png").setScrollFactor(0).setDepth(154).setScale(1.1).setFlipX(false).setInteractive(); - const allLevels = window.allLevels || []; - const visibleLevels = allLevels.filter(level => !(level && level[2] === "level_22")); - const pageCount = visibleLevels.length + 1; - let currentPageIndex = visibleLevels.findIndex(l => l[2] === window.currentlevel[2]); - if (currentPageIndex < 0) currentPageIndex = 0; - const isComingSoonPage = () => currentPageIndex >= visibleLevels.length; - const getPageLevel = () => { - if (isComingSoonPage()) return visibleLevels[visibleLevels.length - 1] || window.currentlevel || []; - return visibleLevels[currentPageIndex] || window.currentlevel || []; - }; - const applyCurrentPage = () => { - this._levelSelectIsComingSoonPage = isComingSoonPage(); - if (!isComingSoonPage() && visibleLevels[currentPageIndex]) { - window.currentlevel = [...visibleLevels[currentPageIndex]]; - } - }; - applyCurrentPage(); - const dotY = sh - 36; - const maxDots = Math.min(pageCount, 28); - const dotSpacing = 27; - const dotStartX = cx - (maxDots - 1) * dotSpacing / 2; - const dotObjs = []; - const refreshDots = () => { - for (const d of dotObjs) d.destroy(); - dotObjs.length = 0; - for (let di = 0; di < maxDots; di++) { - const active = di === currentPageIndex; - const d = this.add.graphics().setScrollFactor(0).setDepth(153); - d.fillStyle(0xffffff, active ? 1 : 0.3); - d.fillCircle(dotStartX + di * dotSpacing, dotY, 7); - dotObjs.push(d); - } - }; - refreshDots(); - const cardW = Math.min(700, sw - 180); - const cardH = 180; - const cardX = cx; - const cardY = cy - 100; - const cardSlideContainer = this.add.container(0, 0).setScrollFactor(0).setDepth(152); - const cardBounceContainer = this.add.container(cardX, cardY).setScrollFactor(0).setDepth(0); - cardSlideContainer.add(cardBounceContainer); - const cardContainer = cardSlideContainer; - const cardBg = this.add.graphics(); - const drawCardBg = (colorHex, dark = false, textOnly = false) => { - cardBg.clear(); - if (textOnly) return; - const mul = dark ? 0.10 : 0.22; - const r = Math.round(((colorHex >> 16) & 0xff) * mul); - const g = Math.round(((colorHex >> 8) & 0xff) * mul); - const b = Math.round(( colorHex & 0xff) * mul); - cardBg.fillStyle((r << 16) | (g << 8) | b, 0.92); - cardBg.fillRoundedRect(-cardW / 2, -cardH / 2, cardW, cardH, 14); - }; - drawCardBg(bgHex, isEveryEnd(window.currentlevel[2]), isComingSoonPage()); - cardBounceContainer.add(cardBg); - - const cardHit = this.add.zone(cardX, cardY, cardW, cardH) - .setScrollFactor(0).setDepth(156).setInteractive(); - const dragState = { - pressed: false, - dragging: false, - startX: 0, - lastX: 0, - velSamples: [], - get vel() { - if (!this.velSamples.length) return 0; - return this.velSamples.reduce((a, b) => a + b, 0) / this.velSamples.length; - }, - pushVel(v) { - this.velSamples.push(v); - if (this.velSamples.length > 5) this.velSamples.shift(); - }, - reset() { - this.pressed = false; - this.dragging = false; - this.velSamples = []; - } - }; - - const onDragStart = (ptr) => { - dragState.pressed = true; - dragState.startX = ptr.x; - dragState.lastX = ptr.x; - dragState.dragging = false; - dragState.velSamples = []; - }; - cardHit.on("pointerdown", (ptr) => { - onDragStart(ptr); - if (isComingSoonPage()) return; - this.tweens.killTweensOf(cardBounceContainer, "scale"); - this.tweens.add({ targets: cardBounceContainer, scale: 1.26, duration: 300, ease: "Bounce.Out" }); - }); - - const onDragMove = (ptr) => { - if (!dragState.pressed) return; - const dx = ptr.x - dragState.startX; - const frameDelta = ptr.x - dragState.lastX; - dragState.pushVel(frameDelta); - dragState.lastX = ptr.x; - if (!dragState.dragging && Math.abs(dx) > 12) { - dragState.dragging = true; - this.tweens.killTweensOf(cardBounceContainer, "scale"); - this.tweens.add({ targets: cardBounceContainer, scale: 1, duration: 200, ease: "Quad.Out" }); - } - if (dragState.dragging) { - cardContainer.x = dx; - } - }; - const onDragUp = (ptr) => { - if (!dragState.pressed) return; - const wasDragging = dragState.dragging; - const totalDx = ptr.x - dragState.startX; - const vel = dragState.vel; - dragState.reset(); - if (wasDragging) { - const dragThreshold = cardW * 0.18; - if (Math.abs(totalDx) > dragThreshold || Math.abs(vel) > 3) { - const dir = totalDx < 0 ? 1 : -1; - switchLevel(dir, cardContainer.x, vel); - } else { - if (_currentAnimUpdate) { - this.events.off("preupdate", _currentAnimUpdate); - _currentAnimUpdate = null; - } - let snapX = cardContainer.x; - let snapVel = vel * 40; - const snapUpdate = (time, delta) => { - const dt = Math.min(delta / 1000, 0.05); - const tension = 400; - const friction = 18; - const force = -tension * snapX - friction * snapVel; - snapVel += force * dt; - snapX += snapVel * dt; - if (Math.abs(snapX) < 0.5 && Math.abs(snapVel) < 5) { - snapX = 0; - this.events.off("preupdate", snapUpdate); - if (_currentAnimUpdate === snapUpdate) _currentAnimUpdate = null; - } - cardContainer.x = snapX; - }; - _currentAnimUpdate = snapUpdate; - this.events.on("preupdate", snapUpdate); - } - } else { - if (ptr.x >= cardX - cardW/2 && ptr.x <= cardX + cardW/2 && - ptr.y >= cardY - cardH/2 && ptr.y <= cardY + cardH/2) { - if (isComingSoonPage()) { - return; - } - - this.input.enabled = false; - this.tweens.killTweensOf(cardBounceContainer, "scale"); - cardBounceContainer.setScale(1); - - const lvl = window.currentlevel; - const songID = lvl[0]; - const levelFileName = lvl[2]; - const songFileName = lvl[4] ? lvl[4] : lvl[1].replaceAll(" ", ""); - - const loadingText = this.add.bitmapText(cx, cy, "goldFont", "Downloading Level Assets...", 20).setOrigin(0.5).setDepth(200); - - this.load.text(levelFileName, "assets/levels/" + levelFileName.split("_")[1] + ".txt"); - this.load.audio(songID, "assets/music/" + songFileName + ".mp3"); - - this.load.once("complete", () => { - loadingText.destroy(); - this._audio.playEffect("playSound_01", { volume: 1 }); - this._closeLevelSelect(true); - this._audio.stopMusic(); - this.input.enabled = true; - this.game.registry.set("autoStartGame", true); - this.scene.restart(); - }); - - this.load.start(); - } else { - this.tweens.killTweensOf(cardBounceContainer, "scale"); - this.tweens.add({ targets: cardBounceContainer, scale: 1, duration: 200, ease: "Quad.Out" }); - } - } - }; - this.input.on("pointermove", onDragMove); - this.input.on("pointerup", onDragUp); - const _origClose = this._closeLevelSelect.bind(this); - const _patchedClose = (doTransition) => { - this.input.off("pointermove", onDragMove); - this.input.off("pointerup", onDragUp); - this._closeLevelSelect = _origClose; - _origClose(doTransition); - }; - this._closeLevelSelect = _patchedClose; - const cardContentObjs = []; - const buildCardContent = () => { - for (const o of cardContentObjs) { this.tweens.killTweensOf(o); o.destroy(); } - cardContentObjs.length = 0; - if (isComingSoonPage()) { - this.tweens.killTweensOf(cardBounceContainer, "scale"); - cardBounceContainer.setScale(1); - const comingSoonLabel = this.add.bitmapText(0, 0, "bigFont", "Coming Soon!", 56) - .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); - comingSoonLabel.setScale(Math.min(1, (cardW - 40) / comingSoonLabel.width)); - cardContentObjs.push(comingSoonLabel); - cardBounceContainer.add(comingSoonLabel); - return; - } - const lvl = window.currentlevel; - const levelId = lvl[2] || "level_1"; - const levelDifficultyMap = { - "level_1": "diffIcon_01_btn_001", - "level_2": "diffIcon_01_btn_001", - "level_3": "diffIcon_02_btn_001", - "level_4": "diffIcon_02_btn_001", - "level_5": "diffIcon_03_btn_001", - "level_6": "diffIcon_03_btn_001", - "level_7": "diffIcon_04_btn_001", - "level_8": "diffIcon_04_btn_001", - "level_9": "diffIcon_04_btn_001", - "level_10": "diffIcon_05_btn_001", - "level_11": "diffIcon_05_btn_001", - "level_12": "diffIcon_05_btn_001", - "level_13": "diffIcon_05_btn_001", - "level_14": "diffIcon_06_btn_001", - "level_15": "diffIcon_05_btn_001", - "level_16": "diffIcon_05_btn_001", - "level_17": "diffIcon_04_btn_001", - "level_18": "diffIcon_06_btn_001", - "level_19": "diffIcon_04_btn_001", - "level_20": "diffIcon_06_btn_001", - "level_21": "diffIcon_05_btn_001", - "level_22": "diffIcon_05_btn_001", - "level_99": "diffIcon_10_btn_001", - "level_100": "diffIcon_10_btn_001", - "level_137409445": "diffIcon_00_btn_001", - "level_5703070": "diffIcon_07_btn_001", - "level_137677336": "diffIcon_00_btn_001", - "level_116489424": "diffIcon_00_btn_001", - "level_4284013": "diffIcon_06_btn_001", - "level_56199846": "diffIcon_04_btn_001", - "level_23": "diffIcon_10_btn_001" - }; - const diffIconKey = levelDifficultyMap[levelId] || "diffIcon_05_btn_001"; - const diffFrame = diffIconKey + ".png"; - const iconX = cardX - cardW / 2 + 52; - const isHardDemon = diffIconKey === "diffIcon_06_btn_001"; - const iconRotation = isHardDemon ? Math.PI / 2 : 0; - const demonIcon = this.add.image(iconX - cardX, 0, "GJ_GameSheet03", diffFrame) - .setScrollFactor(0).setDepth(155).setScale(1).setOrigin(0.5, 0.5); - cardContentObjs.push(demonIcon); - cardBounceContainer.add(demonIcon); - const maxIconH = cardH - 16; - const maxIconW = 80; - const iconFrame = this.textures.getFrame("GJ_GameSheet03", diffFrame); - let finalIconScale = 1; - if (iconFrame) { - const scaleForH = maxIconH / iconFrame.height; - let scaleForW = maxIconW / iconFrame.width; - finalIconScale = Math.min(1, scaleForH, scaleForW); - demonIcon.setScale(finalIconScale); - } - let iconDisplayW = (iconFrame ? iconFrame.width : 80) * finalIconScale; - const iconDisplayH = (iconFrame ? iconFrame.height : 80) * finalIconScale; - const nameLabel = this.add.bitmapText(0, 0, "bigFont", lvl[1], 50) - .setScrollFactor(0).setDepth(155).setOrigin(0, 0.5); - const gap = 25; - const naturalGroupW = iconDisplayW + gap + nameLabel.width; - const naturalGroupH = Math.max(iconDisplayH, nameLabel.height); - const cardPad = 16; - const maxGroupW = cardW - cardPad * 2; - const maxGroupH = cardH - cardPad * 2; - const groupScale = Math.min(1, maxGroupW / naturalGroupW, maxGroupH / naturalGroupH); - const scaledIconW = iconDisplayW * groupScale; - const scaledLabelW = nameLabel.width * groupScale; - const scaledGap = gap * groupScale; - const totalW = scaledIconW + scaledGap + scaledLabelW; - const groupStartX = cardX - totalW / 2; - demonIcon.setScale(finalIconScale * groupScale); - demonIcon.setPosition(groupStartX + scaledIconW / 2 - cardX, 0); - nameLabel.setScale(groupScale); - nameLabel.setPosition(groupStartX + scaledIconW + scaledGap - cardX, 0); - cardContentObjs.push(nameLabel); - cardBounceContainer.add(nameLabel); - }; - const barAreaY = cardY + cardH / 2 + 100; - const barW2 = Math.min(600, sw - 200); - const barH2 = 36; - const barX0 = cx - barW2 / 2; - let barObjs = []; - const buildBar = () => { - for (const o of barObjs) { this.tweens.killTweensOf(o); o.destroy(); } - barObjs.length = 0; - if (isComingSoonPage()) return; - const bestNormal = parseFloat(localStorage.getItem("bestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); - const modeLabel = this.add.bitmapText(cx, barAreaY - 40, "bigFont", "Normal Mode", 30) - .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); - barObjs.push(modeLabel); - cardContainer.add(modeLabel); - const barBg = this.add.graphics().setScrollFactor(0).setDepth(154); - barBg.fillStyle(0x000000, 0.6); - barBg.fillRoundedRect(barX0, barAreaY - barH2 / 2, barW2, barH2, barH2 / 2); - barObjs.push(barBg); - cardContainer.add(barBg); - const padding = 3; - const innerH2 = barH2 - padding * 2; - const innerW2 = barW2 - padding * 2; - const innerRadius = innerH2 / 2; - const fillW = Math.max(innerH2, innerW2 * bestNormal / 100); - if(bestNormal > 0) { - const barFg = this.add.graphics().setScrollFactor(0).setDepth(155); - barFg.fillStyle(0x00FF00, 1); - const rightR = (bestNormal >= 100) ? innerRadius : 0; - barFg.fillRoundedRect(barX0 + padding, barAreaY - barH2 / 2 + padding, fillW, innerH2, { - tl: innerRadius, - bl: innerRadius, - tr: rightR, - br: rightR - }); - - barObjs.push(barFg); - cardContainer.add(barFg); - } - const pctLabel = this.add.bitmapText(cx, barAreaY, "bigFont", Math.round(bestNormal) + "%", 22) - .setScrollFactor(0).setDepth(156).setOrigin(0.5, 0.5); - barObjs.push(pctLabel); - cardContainer.add(pctLabel); - const bestPractice = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); - const practBarAreaY = barAreaY + barH2 + 48; - const practModeLabel = this.add.bitmapText(cx, practBarAreaY - 40, "bigFont", "Practice Mode", 30) - .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); - barObjs.push(practModeLabel); - cardContainer.add(practModeLabel); - const practBarBg = this.add.graphics().setScrollFactor(0).setDepth(154); - practBarBg.fillStyle(0x000000, 0.6); - practBarBg.fillRoundedRect(barX0, practBarAreaY - barH2 / 2, barW2, barH2, barH2 / 2); - barObjs.push(practBarBg); - cardContainer.add(practBarBg); - if (bestPractice > 0) { - const practFillW = Math.max(innerH2, innerW2 * bestPractice / 100); - const practBarFg = this.add.graphics().setScrollFactor(0).setDepth(155); - practBarFg.fillStyle(0x00FFFF, 1); - const practRightR = (bestPractice >= 100) ? innerRadius : 0; - practBarFg.fillRoundedRect(barX0 + padding, practBarAreaY - barH2 / 2 + padding, practFillW, innerH2, { - tl: innerRadius, bl: innerRadius, tr: practRightR, br: practRightR - }); - barObjs.push(practBarFg); - cardContainer.add(practBarFg); - } - const practPctLabel = this.add.bitmapText(cx, practBarAreaY, "bigFont", Math.round(bestPractice) + "%", 22) - .setScrollFactor(0).setDepth(156).setOrigin(0.5, 0.5); - barObjs.push(practPctLabel); - cardContainer.add(practPctLabel); - }; - buildCardContent(); - buildBar(); - let _currentAnimUpdate = null; - const switchLevel = (dir, startX = null, dragVel = 0) => { - if (pageCount <= 0) return; - - if (_currentAnimUpdate) { - this.events.off("preupdate", _currentAnimUpdate); - _currentAnimUpdate = null; - } - currentPageIndex = (currentPageIndex + dir + pageCount) % pageCount; - applyCurrentPage(); - const pageLevel = getPageLevel(); - const newColors = this._parseLevelColors(pageLevel[2]); - const dark = isEveryEnd(pageLevel[2]); - const slideDist = cardW - 200; - const slideOutTarget = -dir * slideDist; - const slideInStart = dir * slideDist; - this.tweens.killTweensOf(cardContainer); - let state = "out"; - let currentX = startX !== null ? startX : cardContainer.x; - const dragSpeedBoost = Math.abs(dragVel) * 60; - const slideOutSpeed = slideDist * 14 + dragSpeedBoost; - const slideInVel = slideDist * 6 + dragSpeedBoost; - let vel = 0; - const scrollAnimUpdate = (time, delta) => { - const dt = Math.min(delta / 1000, 0.05); - if (state === "out") { - currentX += (-dir) * slideOutSpeed * dt; - if ((dir > 0 && currentX <= slideOutTarget) || (dir < 0 && currentX >= slideOutTarget)) { - for (const o of cardContentObjs) { - cardBounceContainer.remove(o, false); - o.destroy(); - } - for (const o of barObjs) { - cardSlideContainer.remove(o, false); - o.destroy(); - } - cardContentObjs.length = 0; - barObjs.length = 0; - drawCardBg(newColors.bgHex, dark, isComingSoonPage()); - buildCardContent(); - buildBar(); - drawOverlay(overlay, newColors.bgHex, dark); - for (const gt of staticGroundTiles) gt.setTint(groundTintHex(newColors.groundHex)); - for (const gt of staticGround2Tiles) gt.setTint(groundTintHex(newColors.groundHex)); - refreshDots(); - state = "in"; - currentX = slideInStart; - vel = (-dir) * slideInVel; - } - } else if (state === "in") { - const tension = 300; - const friction = 15; - const force = -tension * currentX - friction * vel; - vel += force * dt; - currentX += vel * dt; - - if (Math.abs(currentX) < 1 && Math.abs(vel) < 15) { - currentX = 0; - this.events.off("preupdate", scrollAnimUpdate); - if (_currentAnimUpdate === scrollAnimUpdate) _currentAnimUpdate = null; - } - } - cardContainer.x = currentX; - }; - _currentAnimUpdate = scrollAnimUpdate; - this.events.on("preupdate", scrollAnimUpdate); - }; - this._makeBouncyButton(arrowL, 1.1, () => { switchLevel(-1); }); - this._makeBouncyButton(arrowR, 1.1, () => { switchLevel(1); }); - const inputBlocker = this.add.zone(cx, cy, sw, sh) - .setScrollFactor(0).setDepth(151).setInteractive(); - inputBlocker.on("pointerdown", onDragStart); - this._levelSelectStaticObjs = [overlay, inputBlocker, tableBottom, ...staticGroundTiles, ...staticGround2Tiles, staticFloorLine, cornerBL, cornerBR, backBtn, infoBtn, arrowL, arrowR, cardSlideContainer, cardHit]; - this._levelSelectSwitchLevel = switchLevel; - this._levelSelectDotObjs = dotObjs; - this._levelSelectCardContent = cardContentObjs; - this._levelSelectBarObjs = barObjs; - } - _closeLevelSelect(silent = false) { - if (!this._levelSelectOverlay) return; - const destroy = () => { - const all = [ - ...(this._levelSelectStaticObjs || []), - ...(this._levelSelectDotObjs || []), - ...(this._levelSelectCardContent || []), - ...(this._levelSelectBarObjs || []), - ]; - for (const o of all) { if (o && o.destroy) { this.tweens.killTweensOf(o); o.destroy(); } } - this._levelSelectOverlay = null; - this._levelSelectStaticObjs = null; - this._levelSelectDotObjs = null; - this._levelSelectCardContent = null; - this._levelSelectBarObjs = null; - this._levelSelectSwitchLevel = null; - this._levelSelectIsComingSoonPage = false; - }; - if (silent) { destroy(); return; } - const sw = screenWidth; - const sh = screenHeight; - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ - targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", - onComplete: () => { - destroy(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); - } - }); - } - _buildHUD() { - this._attemptsLabel = this.add.bitmapText(0, 0, "bigFont", "Attempt 1", 65).setOrigin(0.5, 0.5).setVisible(false); - this._level.topContainer.add(this._attemptsLabel); - this._positionAttemptsLabel(); - this._checkpointBtnContainer = this.add.container(screenWidth / 2, screenHeight - 60) - .setScrollFactor(0) - .setDepth(30) - .setVisible(false); - this._checkpointBtn = this.add.image(-50, 0, "GJ_GameSheet03", "GJ_checkpointBtn_001.png") - .setOrigin(0.5, 0.5) - .setInteractive() - .setScale(0.8); - this._makeBouncyButton(this._checkpointBtn, 0.8, () => { - if (this._practicedMode.practiceMode && !this._menuActive && !this._slideIn) { - this._practicedMode.saveCheckpoint(this._state, this._playerWorldX, this._cameraX, this); - } - }); - this._expandHitArea(this._checkpointBtn, 2); - this._clearCheckpointBtn = this.add.image(50, 0, "GJ_GameSheet03", "GJ_removeCheckBtn_001.png") - .setOrigin(0.5, 0.5) - .setInteractive() - .setScale(0.8); - this._makeBouncyButton(this._clearCheckpointBtn, 0.8, () => { - if (this._practicedMode.practiceMode && !this._menuActive && !this._slideIn) { - this._practicedMode.deleteLastCheckpoint(); - } - }); - this._expandHitArea(this._clearCheckpointBtn, 1.5); - this._checkpointBtnContainer.add([this._checkpointBtn, this._clearCheckpointBtn]); - this._fpsText = this.add.text(screenWidth - 20, 10, "", { - fontSize: "28px", - fill: "#ffffff", - fontFamily: "Arial" - }).setOrigin(1, 0).setScrollFactor(0).setDepth(999).setVisible(false); - this._fpsAccum = 0; - this._fpsFrames = 0; - } - _createStartPosGui() { - const centerX = screenWidth / 2; - const bottomY = screenHeight - 60; - - this._startPosGui = this.add.container(centerX, bottomY).setScrollFactor(0).setDepth(100); - this._startPosGui.setVisible(false); - - const leftArrow = this.add.image(-90, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScale(0.6) - .setInteractive(); - - const rightArrow = this.add.image(90, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScale(0.6) - .setFlipX(true) - .setInteractive(); - - const positions = this._level.getStartPositions(); - const total = positions.length; - - this._startPosText = this.add.bitmapText(0, 0, "bigFont", `0/${total}`, 40).setOrigin(0.5); - - this._startPosGui.add([leftArrow, rightArrow, this._startPosText]); - - this._makeBouncyButton(leftArrow, 0.6, () => this.changeStartPos(-1)); - this._makeBouncyButton(rightArrow, 0.6, () => this.changeStartPos(1)); - } - changeStartPos(direction) { - if (this._paused || this._levelWon || this._menuActive || this._slideIn) return; - - const positions = this._level.getStartPositions(); - const totalPositions = positions.length; - - if (totalPositions === 0) return; - - this._startPosIndex += direction; - - if (this._startPosIndex < -1) { - this._startPosIndex = totalPositions - 1; - } else if (this._startPosIndex >= totalPositions) { - this._startPosIndex = -1; - } - - if (this._startPosText) { - const currentId = this._startPosIndex === -1 ? 0 : (this._startPosIndex + 1); - this._startPosText.setText(`${currentId}/${totalPositions}`); - } - - this._practicedMode.clearCheckpoints(); - this._restartLevel(); - } - toggleGlitter(_0x34c21a) { - if (this._editorPlaytestActive) { - this._glitterEmitter.stop(); - return; - } - - if (_0x34c21a) { - this._glitterEmitter.start(); - } else { - this._glitterEmitter.stop(); - } - } - _setParticleTimeScale(timeScale) { - const updateTimeScale = object => { - if (object && object.type === "ParticleEmitter") { - object.timeScale = timeScale; - } - if (object && object.list) { - object.list.forEach(updateTimeScale); - } - }; - updateTimeScale(this._level.container); - updateTimeScale(this._level.topContainer); - if (this._glitterEmitter) { - this._glitterEmitter.timeScale = timeScale; - } - } - _pauseGame() { - if (!this._paused && !this._menuActive && !this._slideIn && !this._levelWon) { - this._paused = true; - this._pauseBtn.setVisible(false); - this._audio.pauseMusic(); - this._setParticleTimeScale(0); - this._player?.setDeathAnimationPaused?.(true); - this._player2?.setDeathAnimationPaused?.(true); - this._buildPauseOverlay(); - } - } - _resumeGame() { - if (this._paused) { - this._setParticleTimeScale(1); - this._player?.setDeathAnimationPaused?.(false); - this._player2?.setDeathAnimationPaused?.(false); - this._paused = false; - this._pauseBtn.setVisible(true).setAlpha(75 / 255); - if (!this._state.isDead || this._practicedMode?.practiceMode) { - this._audio.resumeMusic(); - this._audio._ensureCorrectMusicMode(); - } - if (this._pauseContainer) { - this._pauseContainer.destroy(); - this._pauseContainer = null; - } - } - } - _queueGameplayLevelViewReturn() { - const currentLevelId = window.currentlevel?.[2] ?? window._onlineLevelId ?? null; - const pendingCreatedReturn = window._createdLevelReturnToView || null; - const candidateCreatedIds = [ - pendingCreatedReturn?.createdId, - currentLevelId, - window._onlineLevelId - ].filter(value => value !== undefined && value !== null); - - let createdLevel = null; - try { - const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); - createdLevel = createdLevels.find(level => { - if (!level) return false; - return candidateCreatedIds.some(id => - String(level.createdId) === String(id) || - (level.levelId !== undefined && level.levelId !== null && String(level.levelId) === String(id)) - ); - }) || null; - } catch (err) { - console.warn("Failed to determine the created-level return target", err); - } - - if (createdLevel || pendingCreatedReturn?.snapshot) { - const targetLevel = createdLevel || pendingCreatedReturn.snapshot; - window._createdLevelReturnToView = { - createdId: targetLevel.createdId ?? pendingCreatedReturn?.createdId ?? currentLevelId, - snapshot: { ...targetLevel } - }; - window._editorReturnToLevelViewId = null; - window._onlineReturnToPlayMenu = null; - return true; - } - - const levelSource = window.currentlevel?.[3]?.[0]; - const isOnlineLevel = levelSource === "Online" || String(currentLevelId || "").startsWith("online_"); - if (isOnlineLevel) { - const existingReturn = window._onlineReturnToPlayMenu; - const selectedLevel = existingReturn?.lvl || window._selectedLevelData || null; - if (selectedLevel) { - window._onlineReturnToPlayMenu = { - lvl: selectedLevel, - backTarget: existingReturn?.backTarget || null - }; - window._createdLevelReturnToView = null; - window._editorReturnToLevelViewId = null; - return true; - } - } - - window._createdLevelReturnToView = null; - return false; - } - - _createPauseToggleButton(_0x5376fd, _0x3b6200, _0x2b25c8, _0xe203c3, _0x268e2b, _0x2d04c4) { - const _0x4864cc = this.add.container(_0x3b6200, _0x2b25c8); - const pieceHeight = this.add.image(0, 0, "GJ_GameSheet03", _0x268e2b ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png").setScale(0.7).setInteractive(); - const _0x15c0df = this.add.bitmapText(25 + 10, 0, "bigFont", _0xe203c3, 32).setOrigin(0, 0.5); - _0x4864cc.add([pieceHeight, _0x15c0df]); - _0x5376fd.add(_0x4864cc); - const _0x232e51 = _0x1dce15 => { - pieceHeight.setTexture("GJ_GameSheet03", _0x1dce15 ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"); - this._expandHitArea(pieceHeight, 2); - _0x2d04c4(_0x1dce15); - }; - this._expandHitArea(pieceHeight, 2); - this._makeBouncyButton(pieceHeight, 0.7, () => { - _0x232e51(pieceHeight.frame.name === "GJ_checkOff_001.png"); - }, () => this._paused && !!this._pauseContainer); - _0x15c0df.setInteractive(); - _0x15c0df.on("pointerdown", () => { - if (this._paused && this._pauseContainer) { - _0x232e51(pieceHeight.frame.name === "GJ_checkOff_001.png"); - } - }); - return _0x4864cc; - } -_buildPauseOverlay() { - const textureY = screenWidth / 2; - const _0xf70e04 = 320; - const _0x4eb71b = screenWidth - 40; - this._pauseContainer = this.add.container(0, 0).setScrollFactor(0).setDepth(100); - - const _0x505665 = this.add.rectangle(textureY, _0xf70e04, screenWidth, screenHeight, 0, 75 / 255); - _0x505665.setInteractive(); - this._pauseContainer.add(_0x505665); - - const _0x103191 = this.textures.get("square04_001").source[0].width * 0.325; - const _0x954813 = this._drawScale9(textureY, _0xf70e04, _0x4eb71b, 600, "square04_001", _0x103191, 0, 150 / 255); - this._pauseContainer.add(_0x954813); - - const _0x3874ed = this.scale.isFullscreen; - const _0x426993 = this.add.image(textureY - _0x4eb71b / 2 + 40, 60, "GJ_WebSheet", _0x3874ed ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png").setScale(0.64).setInteractive(); - this._expandHitArea(_0x426993, 2.5); - this._pauseContainer.add(_0x426993); - this._makeBouncyButton(_0x426993, 0.64, () => { - const _0x23c9e5 = !this.scale.isFullscreen; - _0x426993.setTexture("GJ_WebSheet", _0x23c9e5 ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png"); - this._expandHitArea(_0x426993, 2.5); - this._toggleFullscreen(); - }); - - const settingsBtn = this.add.image(textureY + _0x4eb71b / 2 - 60, 80, 'GJ_GameSheet03', "GJ_optionsBtn_001.png").setScale(0.64).setInteractive(); - this._expandHitArea(settingsBtn, 2.5); - this._pauseContainer.add(settingsBtn); - this._makeBouncyButton(settingsBtn, 0.64, () => this._buildSettingsPopup()); - - this._macroBtn = this.add.image(textureY + _0x4eb71b / 2 - 60, 150, "macroBot").setScale(0.4).setInteractive(); - this._pauseContainer.add(this._macroBtn); - this._makeBouncyButton(this._macroBtn, 0.4, () => this._buildMacroPopup()); - - this._pauseContainer.add(this.add.bitmapText(textureY, 65, "bigFont", window.currentlevel[1], 40).setOrigin(0.5, 0.5)); - - const _0x21dacf = 170; - const _0x46bab2 = this._bestPercent || 0; - const _0x38b8d1 = this.add.image(textureY, _0x21dacf, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0).setAlpha(125 / 255); - this._pauseContainer.add(_0x38b8d1); - const _0x1d49a9 = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); - const _0xb5ab6f = _0x1d49a9 ? _0x1d49a9.width : 680; - const _0x1e6502 = _0x1d49a9 ? _0x1d49a9.height : 40; - const _0x3782ca = Math.max(1, Math.floor(_0xb5ab6f * (_0x46bab2 / 100))); - const _0x3d0987 = this.add.image(0, 0, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(65280).setScale(0.992, 0.86).setOrigin(0, 0.5).setCrop(0, 0, _0x3782ca, _0x1e6502); - _0x3d0987.setPosition(textureY - _0xb5ab6f * 0.992 / 2, _0x21dacf); - this._pauseContainer.add(_0x3d0987); - this._pauseContainer.add(this.add.bitmapText(textureY, _0x21dacf, "bigFont", _0x46bab2 + "%", 30).setOrigin(0.5, 0.5).setScale(0.7)); - this._pauseContainer.add(this.add.bitmapText(textureY, 130, "bigFont", "Normal Mode", 30).setOrigin(0.5, 0.5).setScale(0.78)); - - const _pausePractPct = this._practiceBestPercent || 0; - const _pausePractBarY = 255; - const _pausePractBarImg = this.add.image(textureY, _pausePractBarY, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0).setAlpha(125 / 255); - this._pauseContainer.add(_pausePractBarImg); - const _pausePractFrame = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); - const _pausePractBarW = _pausePractFrame ? _pausePractFrame.width : 680; - const _pausePractBarH = _pausePractFrame ? _pausePractFrame.height : 40; - const _pausePractFillW = Math.max(1, Math.floor(_pausePractBarW * (_pausePractPct / 100))); - const _pausePractFg = this.add.image(0, 0, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0x00FFFF).setScale(0.992, 0.86).setOrigin(0, 0.5).setCrop(0, 0, _pausePractFillW, _pausePractBarH); - _pausePractFg.setPosition(textureY - _pausePractBarW * 0.992 / 2, _pausePractBarY); - this._pauseContainer.add(_pausePractFg); - this._pauseContainer.add(this.add.bitmapText(textureY, _pausePractBarY, "bigFont", _pausePractPct + "%", 30).setOrigin(0.5, 0.5).setScale(0.7)); - this._pauseContainer.add(this.add.bitmapText(textureY, _pausePractBarY - 40, "bigFont", "Practice Mode", 30).setOrigin(0.5, 0.5).setScale(0.78)); - - const _0x4791ac = [ - { frame: this._practicedMode.practiceMode ? "GJ_normalBtn_001.png" : "GJ_practiceBtn_001.png", atlas: "GJ_GameSheet03", action: null }, - { frame: "GJ_playBtn2_001.png", atlas: "GJ_WebSheet", action: () => this._resumeGame() }, - { frame: "GJ_menuBtn_001.png", atlas: "GJ_WebSheet", action: () => { - this._audio.playEffect("quitSound_01"); - this._queueGameplayLevelViewReturn(); - this.game.registry.remove("autoStartGame"); - window.isEditor = false; - this._audio.stopMusic(); - this._resumeGame(); - this.scene.restart(); - }}, - { frame: "GJ_replayBtn_001.png", atlas: "GJ_WebSheet", action: () => { - this._resumeGame(); - this._restartLevel(); - }} - ]; - - const _0x25aa59 = _0x4791ac.map(btn => this.textures.getFrame(btn.atlas, btn.frame)?.width || 123); - let _0x599a9b = textureY - (_0x25aa59.reduce((a, b) => a + b, 0) + (_0x4791ac.length - 1) * 40) / 2; - - for (let i = 0; i < _0x4791ac.length; i++) { - const item = _0x4791ac[i]; - const width = _0x25aa59[i]; - const btn = this.add.image(_0x599a9b + width / 2, 390, item.atlas, item.frame).setInteractive(); - - if (item.action === null) { - this._pausePracticeBtn = btn; - this._makeBouncyButton(btn, 1, () => { - const isPracticeMode = this._practicedMode.togglePracticeMode(); - btn.setTexture("GJ_GameSheet03", isPracticeMode ? "GJ_normalBtn_001.png" : "GJ_practiceBtn_001.png"); - if (this._checkpointBtnContainer) this._checkpointBtnContainer.setVisible(isPracticeMode); - this._resumeGame(); - if (!isPracticeMode) { - this._practicedMode.clearCheckpoints(); - this._restartLevel(); - } - }); - } else { - this._makeBouncyButton(btn, 1, item.action); - } - this._pauseContainer.add(btn); - _0x599a9b += width + 40; - } - - const _0x1008ae = 530; - const _0x22b43a = 0.7; - const _0x41925a = this.textures.getFrame("GJ_WebSheet", "slidergroove.png"); - const _0x372782 = _0x41925a ? _0x41925a.width : 420; - - const createSlider = (posX, iconFrame, initialVal, setter) => { - this._pauseContainer.add(this.add.image(posX - 180 - 5, _0x1008ae, "GJ_WebSheet", iconFrame).setScale(1.2)); - const barMaxW = (_0x372782 - 8) * _0x22b43a; - const barStartX = posX - _0x372782 * _0x22b43a / 2 + 2.8; - const fillW = initialVal * barMaxW; - const fillBar = this.add.tileSprite(barStartX, _0x1008ae, fillW > 0 ? fillW : 1, 11.2, "sliderBar").setOrigin(0, 0.5); - this._pauseContainer.add(fillBar); - this._pauseContainer.add(this.add.image(posX, _0x1008ae, "GJ_WebSheet", "slidergroove.png").setScale(_0x22b43a)); - - const thumb = this.add.image(barStartX + fillW, _0x1008ae, "GJ_WebSheet", "sliderthumb.png").setScale(_0x22b43a).setInteractive({ draggable: true }); - this._pauseContainer.add(thumb); - thumb.on("drag", (p, dragX) => { - thumb.x = Math.max(barStartX, Math.min(barStartX + barMaxW, dragX)); - const pct = (thumb.x - barStartX) / barMaxW; - fillBar.width = Math.max(1, pct * barMaxW); - setter(pct < 0.03 ? 0 : pct); - }); - }; - - createSlider(textureY - 200, "gj_songIcon_001.png", this._audio.getUserMusicVolume(), v => this._audio.setUserMusicVolume(v)); - createSlider(textureY + 200, "GJ_sfxIcon_001.png", this._sfxVolume, v => { - this._sfxVolume = v; - localStorage.setItem("userSfxVol", v); - }); - } -_buildSettingsPopup() { - if (this._settingsPopup) return; - - const centerX = screenWidth / 2, - centerY = 320, - panelWidth = 800, - panelHeight = 550; - - this._settingsPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(250); - - const dim = this.add.rectangle(centerX, centerY, screenWidth, screenHeight, 0, 150 / 255).setInteractive(); - this._settingsPopup.add(dim); - - const innerContainer = this.add.container(centerX, centerY).setScale(0); - this._settingsPopup.add(innerContainer); - - const corner = 0.325 * this.textures.get("GJ_square01").source[0].width; - const panel = this._drawScale9(0, 0, panelWidth, panelHeight, 'GJ_square01', corner, 16777215, 1); - innerContainer.add(panel); - - const closeBtn = this.add.image(-(panelWidth / 2) + 10, -(panelHeight / 2) + 10, 'GJ_WebSheet', "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); - innerContainer.add(closeBtn); - this._makeBouncyButton(closeBtn, 0.8, () => { - this._settingsPopup.destroy(); - this._settingsPopup = null; - }); - - const pages = ["Gameplay", "Visual", "Advanced"]; - let currentPage = 0; - const pageTitle = this.add.bitmapText(0, -(panelHeight / 2) + 45, "bigFont", pages[currentPage], 40).setOrigin(0.5); - innerContainer.add(pageTitle); - const leftArrow = this.add.image(-(panelWidth / 2) - 130, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setFlipX(false).setInteractive(); - innerContainer.add(leftArrow); - const rightArrow = this.add.image((panelWidth / 2) + 130, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setInteractive().setFlipX(true); - innerContainer.add(rightArrow); - const column1X = -200; - const column2X = 200; - const checkOffset = -120; - const textOffset = -70; - const spacingY = 70; - const startY = -150; - let pageContainer = this.add.container(0, 0); - innerContainer.add(pageContainer); - - const createToggle = (container, x, y, label, getVal, setVal, callback, fontSize, hasInfoBox, infoText) => { - if (fontSize === undefined) fontSize = 25; - if (hasInfoBox === undefined) hasInfoBox = false; - if (infoText === undefined) infoText = null; - - var isOn = getVal(); - var checkTexture = isOn ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; - var check = this.add.image(x + checkOffset, y, "GJ_GameSheet03", checkTexture).setScale(0.8).setInteractive(); - var txt = this.add.bitmapText(x + textOffset, y, "bigFont", label, fontSize).setOrigin(0, 0.5); - container.add([check, txt]); - - if (hasInfoBox) { - if (infoText) { - createInfoButton(container, x + checkOffset - 34, y - 30, infoText, 0.45); - } - } - - this._makeBouncyButton(check, 0.8, () => { - var current = getVal(); - setVal(!current); - var newTexture = getVal() ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; - check.setTexture("GJ_GameSheet03", newTexture); - if (callback) { - callback(getVal()); - } - if (this._saveSettings) { - this._saveSettings(); - } - }); - }; - - function TextToSay(key) { - var normalized = String(key).replace(/[^a-z0-9]/gi, "").toLowerCase(); - return String(key); - } - - var infotextstuffsiwannabedonewiththis = { - "Enable Portal Guide": "Enables extra indicators on portals.", - "Enable Orb Guide": "Enables extra indicators on orbs.", - "Practice Music Bypass": "Plays normal mode music in practice mode.", - "Show Percentage": "Shows the percentage you are at in a level.", - "Percentage Decimals": "Shows decimals in level progress.", - "Hitboxes on Death": "Shows hitboxes upon death in both normal and practice mode.", - }; - - const createInfoButton = (container, x, y, infoTextOrKey, scale) => { - var key = String(infoTextOrKey || ""); - var words = TextToSay(key); - var Infotext = null; - if (window.settingInfoText && window.settingInfoText[words]) { - Infotext = window.settingInfoText[words]; - } else if (infotextstuffsiwannabedonewiththis[words]) { - Infotext = infotextstuffsiwannabedonewiththis[words]; - } - var infoText = Infotext ? Infotext : key; - if (!infoText) { - return; - } - - var infoButton = this.add.image(x, y, "GJ_GameSheet03", "GJ_infoIcon_001.png"); - infoButton.setScale(scale || 0.45); - infoButton.setInteractive(); - container.add(infoButton); - - this._makeBouncyButton(infoButton, scale, () => { - this.InfoBoxDoAThing(infoText); - }); - }; - const createNumberInput = (container, x, y, label, getVal, setVal) => { - const txt = this.add.bitmapText(x + textOffset, y, "bigFont", label, 25).setOrigin(0, 0.5); - container.add(txt); - - const boxX = x + checkOffset; - const boxY = y; - const boxW = 64; - const boxH = 48; - - const bgBoxGraphics = this.add.graphics(); - bgBoxGraphics.fillStyle(0x222222, 0.5); - bgBoxGraphics.fillRoundedRect(boxX - boxW / 2, boxY - boxH / 2, boxW, boxH, 8); - container.add(bgBoxGraphics); - - const hitArea = this.add.rectangle(boxX, boxY, boxW, boxH, 0x000000, 0) - .setOrigin(0.5) - .setInteractive({ useHandCursor: true }); - container.add(hitArea); - - let initialVal = getVal() || 1; - const valueTxt = this.add.bitmapText(boxX, boxY, "bigFont", initialVal.toString(), 28) - .setOrigin(0.5); - container.add(valueTxt); - - let isFocused = false; - let internalString = initialVal.toString(); - - const updateDisplay = () => { - if (isFocused) { - valueTxt.setText(internalString + "|"); - } else { - valueTxt.setText(internalString || " "); - } - }; - - const commitValue = () => { - isFocused = false; - - let val = parseFloat(internalString); - if (isNaN(val)) val = 1; - - if (val < 0.1) val = 0.1; - if (val > 10) val = 10; - - internalString = val.toString(); - valueTxt.setText(internalString); - - setVal(val); - if (this._saveSettings) this._saveSettings(); - }; - - hitArea.on('pointerdown', (pointer, localX, localY, event) => { - if (event) event.stopPropagation(); - - if (window._activeCustomInput && window._activeCustomInput !== commitValue) { - window._activeCustomInput(); - } - - isFocused = true; - window._activeCustomInput = commitValue; - - internalString = ""; - updateDisplay(); - }); - - const outsideClickListener = () => { - if (isFocused) commitValue(); - }; - dim.on('pointerdown', outsideClickListener); - - const keydownListener = (event) => { - if (!isFocused) return; - - const key = event.key; - - if (key === "Enter") { - event.preventDefault(); - commitValue(); - return; - } - - if (key === "Backspace") { - event.preventDefault(); - internalString = internalString.slice(0, -1); - updateDisplay(); - return; - } - - if (/^[0-9.]$/.test(key)) { - event.preventDefault(); - - if (key === "." && internalString.includes(".")) return; - - const parts = internalString.split('.'); - - if (key === ".") { - if (parts[0].length === 0) return; - } else { - if (parts.length === 1 && parts[0].length >= 2) return; - if (parts.length === 2 && parts[1].length >= 2) return; - } - - internalString += key; - updateDisplay(); - } - }; - - window.addEventListener('keydown', keydownListener); - - const originalDestroy = container.destroy; - container.destroy = (...args) => { - window.removeEventListener('keydown', keydownListener); - if (dim) dim.off('pointerdown', outsideClickListener); - if (window._activeCustomInput === commitValue) { - window._activeCustomInput = null; - } - originalDestroy.apply(container, args); - }; - }; - - const buildGameplayPage = (container) => { - createToggle(container, column1X, startY, "Show Percentage", - () => window.showPercentage, - (v) => window.showPercentage = v, - (v) => { if (this._percentageLabel) this._percentageLabel.setVisible(v); }, - undefined, - true, - "Show Percentage" - ); - - createToggle(container, column1X, startY + spacingY, "Percentage Decimals", - () => window.percentageDecimals, - (v) => window.percentageDecimals = v, - undefined, - undefined, - true, - "Percentage Decimals" - ); - - createToggle(container, column1X, startY + (spacingY * 2), "StartPos Switcher", - () => window.startPosSwitcher, - (v) => window.startPosSwitcher = v, - (v) => { - if (!v) this._startPosIndex = -1; - if (this._startPosGui) this._startPosGui.setVisible(v); - const total = this._level.getStartPositions().length; - if (this._startPosText) this._startPosText.setText(`0/${total}`); - } - ); - - createToggle(container, column1X, startY + (spacingY * 3), "Noclip", - () => window.noClip, - (v) => window.noClip = v, - (v) => { if (this._noclipIndicator) this._noclipIndicator.setVisible(v); } - ); - - createToggle(container, column1X, startY + (spacingY * 4), "Noclip Accuracy", - () => window.noClipAccuracy, - (v) => window.noClipAccuracy = v - ); - - createToggle(container, column1X, startY + (spacingY * 5), "Macro Bot", - () => window.macroBot, - (v) => window.macroBot = v - ); - - createNumberInput(container, column2X, startY, "Speedhack", - () => window.speedHack, - (v) => window.speedHack = v - ); - - createToggle(container, column2X, startY + spacingY, "Practice Music Bypass", - () => window.practiceMusicBypass, - (v) => { - const changed = !!window.practiceMusicBypass !== !!v; - window.practiceMusicBypass = v; - if (changed && !this._menuActive && this._practicedMode?.practiceMode) { - this._practiceBypassPending = true; - } - }, - null, - 20, - true, - "Practice Music Bypass" - ); - }; - - const buildVisualPage = (container) => { - createToggle(container, column1X, startY, "Show Hitboxes", - () => window.showHitboxes, - (v) => window.showHitboxes = v, - (v) => { - if (!v) { - this._player._hitboxGraphics.clear(); - } else { - this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); - } - } - ); - - createToggle(container, column1X, startY + (spacingY), "Hitbox Trail", - () => window.showHitboxTrail, - (v) => window.showHitboxTrail = v, - (v) => { if (window.showHitboxes) this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); } - ); - - createToggle(container, column1X, startY + (spacingY * 2), "Hitboxes on Death", - () => window.hitboxesOnDeath, - (v) => window.hitboxesOnDeath = v, - undefined, - undefined, - true, - "Hitboxes on Death" - ); - - createToggle(container, column1X, startY + (spacingY * 3), "Show FPS", - () => this._fpsText.visible, - (v) => this._fpsText.visible = v, - (v) => { if (this._fpsText) this._fpsText.setVisible(v); } - ); - - createToggle(container, column1X, startY + (spacingY * 4), "Solid Wave Trail", - () => window.solidWave, - (v) => window.solidWave = v - ); - - createToggle(container, column1X, startY + (spacingY * 5), "Show CPS", - () => window.showCPS, - (v) => window.showCPS = v - ); - - createToggle(container, column2X, startY, "Show Glow", - () => window.showGlow, - (v) => window.showGlow = v, - () => { if (this._level && this._level._updateGlowVisibility) this._level._updateGlowVisibility(); } - ); - - createToggle(container, column2X, startY + spacingY, "Create Object ID labels", - () => window.createObjectIds, - (v) => window.createObjectIds = v, - null, 17 - ); - - createToggle(container, column2X, startY + (spacingY * 2), "Show Object ID labels", - () => window.showObjectIds, - (v) => window.showObjectIds = v, - null, 17 - ); - createToggle(container, column2X, startY + (spacingY * 3), "Enable Portal Guide", - () => window.enablePortalGuide, - (v) => window.enablePortalGuide = v, - null, 22, - true, - "Enable Portal Guide" - ); - createToggle(container, column2X, startY + (spacingY * 4), "Enable Orb Guide", - () => window.enableOrbGuide, - (v) => window.enableOrbGuide = v, - null, - 25, - true, - "Enable Orb Guide" - ); - }; - - const buildAdvancedPage = (container) => { - createToggle(container, column1X, startY, "Use Proxy (for schools)", - () => !window.useDirectInternet, - (v) => { window.useDirectInternet = !v; }, - null, 22 - ); - }; - - const buildPage = (idx) => { - pageContainer.destroy(); - pageContainer = this.add.container(0, 0); - innerContainer.add(pageContainer); - pageTitle.setText(pages[idx]); - - if (idx === 0) buildGameplayPage(pageContainer); - else if (idx === 1) buildVisualPage(pageContainer); - else if (idx === 2) buildAdvancedPage(pageContainer); - }; - - buildPage(0); - - this._makeBouncyButton(leftArrow, 1, () => { - currentPage = (currentPage - 1 + pages.length) % pages.length; - buildPage(currentPage); - }); - - this._makeBouncyButton(rightArrow, 1, () => { - currentPage = (currentPage + 1) % pages.length; - buildPage(currentPage); - }); - this.tweens.add({ - targets: innerContainer, - scale: 1, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _saveSettings() { - const settings = { - noclip: window.noClip, - showPercentage: window.showPercentage, - percentDecimals: window.percentageDecimals, - showHitboxes: window.showHitboxes, - startPosSwitcher: window.startPosSwitcher, - hitboxTrail: window.showHitboxTrail, - showFPS: this._fpsText.visible, - solidWaveTrail: window.solidWave, - noclipAccuracy: window.noClipAccuracy, - hitboxesOnDeath: window.hitboxesOnDeath, - createObjectIds: window.createObjectIds, - showObjectIds: window.showObjectIds, - showCPS: window.showCPS, - speedHack: window.speedHack, - macroBot: window.macroBot, - practiceMusicBypass: window.practiceMusicBypass, - showGlow: window.showGlow, - showEditorGlow: window.showEditorGlow, - useDirectInternet: !!window.useDirectInternet, - enablePortalGuide: window.enablePortalGuide, - enableOrbGuide: window.enableOrbGuide, - settingInfoText: window.settingInfoText || {} - }; - localStorage.setItem("gd_settings", JSON.stringify(settings)); - localStorage.setItem("gd_useDirectInternet", String(!!window.useDirectInternet)); - } - _loadSettings() { - const saved = localStorage.getItem("gd_settings"); - const defaults = { - noclip: false, - showPercentage: true, - percentDecimals: false, - showHitboxes: false, - startPosSwitcher: false, - hitboxTrail: false, - showFPS: false, - solidWaveTrail: false, - noclipAccuracy: false, - hitboxesOnDeath: false, - createObjectIds: false, - showObjectIds: false, - showCPS: false, - speedHack: 1.0, - macroBot: false, - practiceMusicBypass: false, - showGlow: true, - showEditorGlow: false, - useDirectInternet: true, - enablePortalGuide: true, - enableOrbGuide: false - }; - - const data = { ...defaults, ...(saved ? JSON.parse(saved) : {}) }; - - window.noClip = data.noclip; - window.showPercentage = data.showPercentage; - window.percentageDecimals = data.percentDecimals; - window.showHitboxes = data.showHitboxes; - window.startPosSwitcher = data.startPosSwitcher; - window.showHitboxTrail = data.hitboxTrail; - this._fpsText.visible = data.showFPS; - window.solidWave = data.solidWaveTrail; - window.noClipAccuracy = data.noclipAccuracy; - window.hitboxesOnDeath = data.hitboxesOnDeath; - window.showCPS = data.showCPS; - window.speedHack = data.speedHack; - window.macroBot = data.macroBot; - window.practiceMusicBypass = !!data.practiceMusicBypass; - window.showGlow = data.showGlow; - window.showEditorGlow = data.showEditorGlow; - window.createObjectIds = data.createObjectIds; - window.showObjectIds = data.showObjectIds; - window.enablePortalGuide = data.enablePortalGuide; - window.enableOrbGuide = data.enableOrbGuide; - window.settingInfoText = data.settingInfoText || {}; - window.useDirectInternet = !!data.useDirectInternet; - localStorage.setItem("gd_useDirectInternet", String(!!window.useDirectInternet)); - } - _buildMacroPopup() { - if (this._macroPopup) return; - const centerX = screenWidth / 2; - const centerY = 320; - const panelWidth = 800; - const panelHeight = 400; - this._macroPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(250); - const dim = this.add.rectangle(centerX, centerY, screenWidth, screenHeight, 0x000000, 150 / 255).setInteractive(); - this._macroPopup.add(dim); - - const corner = 0.325 * this.textures.get("GJ_square02").source[0].width; - const panel = this._drawScale9(centerX, centerY, panelWidth, panelHeight, "GJ_square02", corner, 0xffffff, 1); - this._macroPopup.add(panel); - - this._macroPopup.add(this.add.bitmapText(centerX, centerY - (panelHeight / 2) + 45, "bigFont", "Web Bot v1.0", 40).setOrigin(0.5)); - - if (this._macroName === undefined) { - this._macroName = this._macroBot?.meta?.name || null; - } - if (this._macroLoaded === undefined) { - this._macroLoaded = !!this._macroName || (this._macroBot && this._macroBot.inputs && this._macroBot.inputs.length > 0); - } - - const loadedNameText = this.add.bitmapText(centerX, centerY - (panelHeight / 2) + 95, "goldFont", this._macroLoaded ? `Currently loaded "${this._macroName || 'macro'}"` : "No macro loaded", 24).setOrigin(0.5); - this._macroPopup.add(loadedNameText); - - const optionsBtn = this.add.image(centerX, centerY - (panelHeight / 2) + 95, "GJ_GameSheet03", "GJ_optionsBtn02_001.png").setInteractive().setScale(0.45); - this._macroPopup.add(optionsBtn); - - const closeBtn = this.add.image(centerX - (panelWidth / 2) + 20, centerY - (panelHeight / 2) + 20, "GJ_WebSheet", "GJ_closeBtn_001.png").setInteractive().setScale(0.8); - this._macroPopup.add(closeBtn); - - this._makeBouncyButton(closeBtn, 0.8, () => { - this.events.off("update", this._refreshMacroButtons); - this._macroPopup.destroy(); - this._macroPopup = null; - }); - - const importBtn = this.add.image(centerX - 300, centerY + 20,"importMacro").setInteractive(); - const exportBtn = this.add.image(centerX - 150, centerY + 20, "GJ_GameSheet03", "GJ_shareBtn_001.png").setInteractive().setScale(0.53); - const createBtn = this.add.image(centerX, centerY + 20, "GJ_GameSheet03", "GJ_plusBtn_001.png").setInteractive().setScale(1.2); - const playbackBtn = this.add.image(centerX + 150, centerY + 20, this._macroBot?.playing ? "stopPlayback" : "playbackMacro").setInteractive().setScale(0.25); - const recordBtn = this.add.image(centerX + 300, centerY + 20, this._macroBot?.recording ? "stopRecord" : "recordMacro").setInteractive().setScale(0.25); - - this._macroPopup.add([createBtn, importBtn, exportBtn, playbackBtn, recordBtn]); - - this._refreshMacroButtons = () => { - const playing = !!this._macroBot?.playing; - const recording = !!this._macroBot?.recording; - - let currentMetaName = this._macroBot?.meta?.name; - if (currentMetaName && currentMetaName !== this._macroName) { - this._macroName = currentMetaName; - this._macroLoaded = true; - } - - if (this._macroLoaded) { - loadedNameText.setText(`Currently loaded "${this._macroName || 'macro'}"`); - optionsBtn.setAlpha(1).setActive(true); - optionsBtn.x = centerX + (loadedNameText.width / 2) + 25; - } else { - loadedNameText.setText("No macro loaded"); - optionsBtn.setAlpha(0).setActive(false); - } - - playbackBtn.setTexture( - playing - ? "stopPlayback" - : "playbackMacro" - ); - - recordBtn.setTexture( - recording - ? "stopRecord" - : "recordMacro" - ); - - createBtn.setAlpha((playing || recording || this._macroLoaded) ? 0.5 : 1); - importBtn.setAlpha((playing || recording) ? 0.5 : 1); - exportBtn.setAlpha((playing || recording || !this._macroLoaded) ? 0.5 : 1); - playbackBtn.setAlpha((recording || !this._macroLoaded) ? 0.5 : 1); - recordBtn.setAlpha((playing || !this._macroLoaded) ? 0.5 : 1); - }; - - this._refreshMacroButtons(); - - this._makeBouncyButton(optionsBtn, 0.45, () => { - if (!this._macroLoaded) return; - const renamePrompt = prompt("New name", this._macroName); - if (renamePrompt && renamePrompt.trim() !== "") { - const cleanName = renamePrompt.trim(); - if (!this._macroBot) this._initMacroBot(); - - if (!this._macroBot.meta) { - this._macroBot.meta = {}; - } - this._macroBot.meta.name = cleanName; - this._macroName = cleanName; - this._refreshMacroButtons(); - } - }); - - this._makeBouncyButton(importBtn, 1, () => { - if (this._macroBot?.playing) return; - if (this._macroBot?.recording) return; - this._importMacroFile(); - }); - - this._makeBouncyButton(exportBtn, 0.53, () => { - if (this._macroBot?.playing) return; - if (this._macroBot?.recording) return; - if (!this._macroLoaded) return; - this._exportMacroFile(this._macroName ? `${this._macroName}.wbgdr` : null); - }); - - this._makeBouncyButton(createBtn, 1.2, () => { - if (this._macroBot?.playing || this._macroBot?.recording || this._macroLoaded) return; - const name = prompt("Enter macro name"); - if (name) { - if (!this._macroBot) this._initMacroBot(); - this._macroBot.resetAll(); - this._macroBot.meta.name = name; - this._macroName = name; - this._macroLoaded = true; - this._refreshMacroButtons(); - } - }); - - this._makeBouncyButton(playbackBtn, 0.25, () => { - if (this._macroBot?.recording) return; - if (!this._macroLoaded) return; - - if (this._macroBot?.playing) { - this._stopMacroPlayback(); - } else { - if (!this._macroBot) { - return; - } - const macro = this._macroBot.exportObject(); - this._startMacroPlayback(macro); - } - this._refreshMacroButtons(); - }); - - this._makeBouncyButton(recordBtn, 0.25, () => { - if (this._macroBot?.playing) return; - if (!this._macroLoaded) return; - - if (this._macroBot?.recording) { - this._stopMacroRecording(); - } else { - this._startMacroRecording({ - level: window.currentlevel?.[2] || "", - name: this._macroName - }); - } - - this._refreshMacroButtons(); - }); - - this.events.on("update", this._refreshMacroButtons); - } - _buildInfoPopup() { - if (this._infoPopup) { - return; - } - const xPos = screenWidth / 2; - const popupHeight = 320; - const popupWidth = 336; - this._infoPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - const background = this.add.rectangle(xPos, popupHeight, screenWidth, screenHeight, 0, 100 / 255); - background.setInteractive(); - this._infoPopup.add(background); - - const bounceContainer = this.add.container(xPos, popupHeight).setScale(0); - this._infoPopup.add(bounceContainer); - const cornerRadius = this.textures.get("GJ_square02").source[0].width * 0.325; - const popupBg = this._drawScale9(0, 0, 480, popupWidth, "GJ_square02", cornerRadius, 16777215, 1); - bounceContainer.add(popupBg); - const closeBtn = this.add.image(-240 + 20, -148, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); - bounceContainer.add(closeBtn); - this._expandHitArea(closeBtn, 2); - this._makeBouncyButton(closeBtn, 0.8, () => this._closeInfoPopup()); - const title = this.add.bitmapText(0, -124, "bigFont", "Credits", 30).setOrigin(0.5, 0.5); - bounceContainer.add(title); - const scrollAreaW = 420; - const scrollAreaH = 230; - const scrollAreaX = 0; - const scrollAreaY = 20; - const scrollFrameBg = this.add.graphics(); - scrollFrameBg.fillStyle(0x000000, 0.18); - scrollFrameBg.fillRoundedRect(scrollAreaX - scrollAreaW / 2, scrollAreaY - scrollAreaH / 2, scrollAreaW, scrollAreaH, 8); - bounceContainer.add(scrollFrameBg); - const contentContainer = this.add.container(0, scrollAreaY - scrollAreaH / 2 + 8); - bounceContainer.add(contentContainer); - - const creditsEntries = [ - { text: "Made by RobTop Games", scale: 0.8, font: "goldFont" }, - { text: "Modded by:", scale: 0.9, font: "bigFont" }, - { text: "breadbb, PinkDev, rohanis0000,", scale: 0.7, font: "goldFont" }, - { text: "bog, Lasokar, AntiMatter,", scale: 0.7, font: "goldFont" }, - { text: "arbstro, and aloaf", scale: 0.7, font: "goldFont" }, - { text: "Contributors:", scale: 0.9, font: "bigFont" }, - { text: "t0nchi7, Itzar and CoraBitz", scale: 0.7, font: "goldFont" }, - { text: "© 2026 RobTop Games. All rights reserved.", scale: 0.4, font: "Arial", color: 0x000000 }, - ]; - let yPos = 0; - const lineItems = []; - creditsEntries.forEach(entry => { - let txt; - if (entry.font === "Arial") { - txt = this.add.text(0, yPos, entry.text, { - fontSize: `${Math.round(32 * (entry.scale || 0.65))}px`, - fontFamily: "Arial", - color: entry.color ? `#${entry.color.toString(16).padStart(6, '0')}` : "#ffffff" - }).setOrigin(0.5, 0); - } else { - txt = this.add.bitmapText(0, yPos, entry.font || "bigFont", entry.text, 32) - .setOrigin(0.5, 0) - .setScale(entry.scale || 0.65); - if (entry.color != null) txt.setTint(entry.color); - } - contentContainer.add(txt); - lineItems.push(txt); - yPos += Math.round(32 * (entry.scale || 0.65)) + 10; - }); - const totalContentH = yPos; - const maxScrollDown = Math.max(0, totalContentH - scrollAreaH + 16); - const maskGraphics = this.add.graphics(); - const maskShape = this.add.graphics(); - maskShape.fillStyle(0xffffff, 1); - const updateMask = () => { - if (!bounceContainer || !bounceContainer.active) return; - const wx = xPos + bounceContainer.x - xPos; - const s = bounceContainer.scaleX; - const bwx = xPos; - const bwy = popupHeight; - maskShape.clear(); - maskShape.fillStyle(0xffffff, 1); - maskShape.fillRect( - bwx + (scrollAreaX - scrollAreaW / 2) * s, - bwy + (scrollAreaY - scrollAreaH / 2) * s, - scrollAreaW * s, - scrollAreaH * s - ); - }; - const geomMask = maskShape.createGeometryMask(); - contentContainer.setMask(geomMask); - const maskUpdateEvent = this.events.on('postupdate', updateMask); - let scrollY = 0; - const baseContentY = scrollAreaY - scrollAreaH / 2 + 8; - const applyScroll = () => { - contentContainer.y = baseContentY - scrollY; - }; - applyScroll(); - const scrollZone = this.add.zone(scrollAreaX, scrollAreaY, scrollAreaW, scrollAreaH).setInteractive(); - bounceContainer.add(scrollZone); - scrollZone.on('wheel', (_p, _dx, deltaY) => { - scrollY = Phaser.Math.Clamp(scrollY + deltaY * 0.6, 0, maxScrollDown); - applyScroll(); - }); - - let dragStartY = 0; - let dragStartScroll = 0; - scrollZone.on('pointerdown', (pointer) => { - dragStartY = pointer.y; - dragStartScroll = scrollY; - }); - scrollZone.on('pointermove', (pointer) => { - if (pointer.isDown) { - const dy = dragStartY - pointer.y; - scrollY = Phaser.Math.Clamp(dragStartScroll + dy, 0, maxScrollDown); - applyScroll(); - } - }); - this._infoPopupCleanup = () => { - this.events.off('postupdate', updateMask); - maskShape.destroy(); - geomMask.destroy(); - }; - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - this._infoPopupCleanup = () => { - this.events.off('postupdate', updateMask); - maskShape.destroy(); - geomMask.destroy(); - }; - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeInfoPopup() { - if (this._infoPopup) { - if (this._infoPopupCleanup) { - this._infoPopupCleanup(); - this._infoPopupCleanup = null; - } - this._infoPopup.destroy(); - this._infoPopup = null; - } - this._infogoaway = () => { - this.events.off('postupdate', updateMask); - maskShape.destroy(); - geomMask.destroy(); - }; - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeInfoPopup() { - if (this._infoPopup) { - if (this._infogoaway) { - this._infogoaway(); - this._infogoaway = null; - } - this._infoPopup.destroy(); - this._infoPopup = null; - } - } //im so tired of this - InfoBoxDoAThing(displayText) { - if (this.EditInfoText) { - this.InfoBoxStopAThing(); - } - - const xPos = screenWidth / 2; - const centerY = screenHeight / 2; - this.EditInfoText = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - - const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 0.5).setInteractive(); - this.EditInfoText.add(background); - - const box = this.add.container(xPos, centerY).setScale(0); - this.EditInfoText.add(box); - - const cornerRadius = this.textures.get("GJ_square01").source[0].width * 0.325; - const boxWidth = 720; - const boxHeight = 280; - box.add(this._drawScale9(0, 0, boxWidth, boxHeight, "square01_001", cornerRadius, 0xffffff, 1)); - box.add(this.add.bitmapText(0, -90, "goldFont", "Info", 45).setOrigin(0.5)); - - const textAreaW = boxWidth - 60; - const textAreaH = boxHeight - 140; - - const wrapText = (text, maxChars) => { - const words = String(text).split(" "); - const lines = []; - let line = ""; - for (let i = 0; i < words.length; i++) { - const word = words[i]; - if ((line + (line ? " " : "") + word).length <= maxChars) { - line = line ? `${line} ${word}` : word; - } else { - if (line) lines.push(line); - line = word; - } - } - if (line) lines.push(line); - return lines; - }; - - const infoText = String(displayText || ""); - const wrappedText = wrapText(infoText, 40); - let y = -30; - - wrappedText.forEach(line => { - box.add(this.add.text(0, y, line, { - fontFamily: "Arial", - fontSize: "30px", - color: "#ffffff", - align: "center" - }).setOrigin(0.5, 0)); - y += 32; - }); - - const okBtnBg = this._drawScale9(0, 0, 100, 60, "GJ_button01", this.textures.get("GJ_button01").source[0].width * 0.3, 0xffffff, 1); - const okBtn = this.add.rectangle(0, 0, 100, 60).setInteractive(); - const okLabel = this.add.bitmapText(0, 0, "goldFont", "OK", 48).setOrigin(0.55); - const okGroup = this.add.container(0, boxHeight / 2 - 50, [okBtnBg, okBtn, okLabel]); - okBtn._bouncyVisualTarget = okGroup; - box.add(okGroup); - - this._makeBouncyButton(okBtn, 1.0, () => { - this.InfoBoxStopAThing(); - }); - - this.tweens.add({ - targets: box, - scale: { from: 0, to: 1 }, - duration: 280, - ease: "Back.Out" - }); - } - - InfoBoxStopAThing() { - if (!this.EditInfoText) return; - - if (this._infoEscKey) { - this._infoEscKey.off('down', this._infoEscHandler); - this._infoEscKey.destroy(); - this._infoEscKey = null; - this._infoEscHandler = null; - } - - this.EditInfoText.destroy(); - this.EditInfoText = null; - } - _buildHowToPlayPopup() { - if (this._howToPlayPopup) { - return; - } - const TUTORIAL_PAGES = ["tutorial_01", "tutorial_02", "tutorial_03", "tutorial_04", "tutorial_05"]; - const GREEN = 0x00e719; - const YELLOW = 0xf8ff00; - const BLUE = 0x3cadf5; - const TUTORIAL_DESCRIPTIONS = [ - { fontSize: 40, lines: [ - [{ text: "TAP", color: GREEN }, { text: " the screen to jump." }], - [{ text: "HOLD", color: GREEN }, { text: " down to keep jumping." }] - ]}, - { fontSize: 40, lines: [ - [{ text: "Hold", color: GREEN }, { text: " to fly up." }], - [{ text: "Release", color: GREEN }, { text: " to fly down." }] - ]}, - { fontSize: 35, lines: [ - [{ text: "You can enter " }, { text: "practice mode", color: BLUE }, { text: " from" }], - [{ text: "the pause menu." }], - [{ text: "Practice mode lets you place" }], - [{ text: "checkpoints", color: GREEN }, { text: "." }] - ]}, - { fontSize: 35, lines: [ - [{ text: "You can place checkpoints manually, or" }], - [{ text: "use the auto-checkpoints feature." }], - [{ text: "Tap the delete button to remove your" }], - [{ text: "last checkpoint." }] - ]}, - { fontSize: 35, lines: [ - [{ text: "Jump Orbs", color: YELLOW }, { text: " activate when you are on" }], - [{ text: "top of them." }], - [{ text: "TAP", color: GREEN }, { text: " while touching an orb to" }], - [{ text: "interact with it and use its effect." }] - ]} - ]; - const TOTAL_PAGES = TUTORIAL_PAGES.length; - let currentPage = 0; - - const xPos = screenWidth / 2; - const _0x4c3182 = 320; - this._howToPlayPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(300); - const _0x249eb7 = this.add.rectangle(xPos, _0x4c3182, screenWidth, screenHeight, 0, 100 / 255); - _0x249eb7.setInteractive(); - this._howToPlayPopup.add(_0x249eb7); - const _0x14e46f = this.textures.get("GJ_square01").source[0].width * 0.325; - const panelContainer = this.add.container(xPos, _0x4c3182); - this._howToPlayPopup.add(panelContainer); - const _0x2c64c2 = this._drawScale9(0, 0, 830, 530, "GJ_square01", _0x14e46f, 16777215, 1); - panelContainer.add(_0x2c64c2); - const _0x5a0f88 = this.add.image(-240 - 160, 172 - _0x4c3182 - 110, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); - this._expandHitArea(_0x5a0f88, 2); - this._makeBouncyButton(_0x5a0f88, 0.8, () => this._closeHowToPlayPopup()); - panelContainer.add(_0x5a0f88); - const howToPlayTitle = this.add.bitmapText(0, -210, "bigFont", "How To Play", 62).setOrigin(0.5, 0.5); - panelContainer.add(howToPlayTitle); - const DESC_TOP_Y = -195; - const DESC_BOT_Y = 15; - const DESC_MAX_H = DESC_BOT_Y - DESC_TOP_Y; - - let descLineObjects = []; - - const _buildDescLines = (pageIndex) => { - for (const obj of descLineObjects) obj.destroy(); - descLineObjects = []; - - const page = TUTORIAL_DESCRIPTIONS[pageIndex]; - if (!page || !page.lines.length) return; - - const fontSize = page.fontSize; - const lineSpacing = 0.35; - const lineH = fontSize * (1 + lineSpacing); - const startY = DESC_TOP_Y + fontSize / 0.5; - - for (let i = 0; i < page.lines.length; i++) { - const segments = page.lines[i]; - const lineY = startY + i * lineH; - if (segments.length === 1 && !segments[0].color) { - const obj = this.add.bitmapText(0, lineY, "bigFont", segments[0].text, fontSize) - .setOrigin(0.5, 0.5); - panelContainer.add(obj); - descLineObjects.push(obj); - continue; - } - const measured = segments.map(seg => { - const tmp = this.add.bitmapText(0, -9999, "bigFont", seg.text, fontSize); - const w = tmp.width; - tmp.destroy(); - return w; - }); - const totalW = measured.reduce((a, b) => a + b, 0); - let curX = -totalW / 2; - - for (let s = 0; s < segments.length; s++) { - const seg = segments[s]; - const obj = this.add.bitmapText(curX, lineY, "bigFont", seg.text, fontSize) - .setOrigin(0, 0.5); - if (seg.color) obj.setTint(seg.color); - panelContainer.add(obj); - descLineObjects.push(obj); - curX += measured[s]; - } - } - }; - - _buildDescLines(0); - const tutorialImage = this.add.image(-240 + 150, 155, TUTORIAL_PAGES[0]); - panelContainer.add(tutorialImage); - const nextGroup = this.add.container(-240 + 550, 165); - const nextBtnW = 125, nextBtnH = 80; - const nextBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; - const nextBtn9 = this._drawScale9(0, 0, nextBtnW, nextBtnH, "GJ_button01", nextBtnBorder, 0xffffff, 1); - const nextBtn = this.add.rectangle(0, 0, nextBtnW, nextBtnH).setInteractive(); - const nextLabel = this.add.bitmapText(-5, -2.5, "bigFont", "Next", 35).setOrigin(0.5, 0.5); - nextGroup.add(nextBtn9); - nextGroup.add(nextBtn); - nextGroup.add(nextLabel); - panelContainer.add(nextGroup); - - nextBtn.on("pointerdown", () => { - nextGroup._pressed = true; - this.tweens.killTweensOf(nextGroup); - this.tweens.add({ targets: nextGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); - }); - nextBtn.on("pointerout", () => { - if (nextGroup._pressed) { - nextGroup._pressed = false; - this.tweens.killTweensOf(nextGroup); - this.tweens.add({ targets: nextGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); - } - }); - nextBtn.on("pointerup", () => { - if (!nextGroup._pressed) return; - nextGroup._pressed = false; - this.tweens.killTweensOf(nextGroup); - nextGroup.setScale(1); - - if (currentPage >= TOTAL_PAGES - 1) { - this._closeHowToPlayPopup(); - } else { - currentPage++; - tutorialImage.setTexture(TUTORIAL_PAGES[currentPage]); - _buildDescLines(currentPage); - nextLabel.setText(currentPage >= TOTAL_PAGES - 1 ? "Exit" : "Next"); - } - }); - panelContainer.setScale(0); - this.tweens.add({ - targets: panelContainer, - scale: 1, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); -} - _closeHowToPlayPopup() { - if (this._howToPlayPopup) { - this._howToPlayPopup.destroy(); - this._howToPlayPopup = null; - } - } - _buildUpdateLogPopup() { - if (this._updateLogPopup || window.levelID) { - return; - } - const xPos = screenWidth / 2; - const popupHeight = 320; - const popupWidth = 336; - this._updateLogPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - const background = this.add.rectangle(xPos, popupHeight, screenWidth, screenHeight, 0, 100 / 255); - background.setInteractive(); - this._updateLogPopup.add(background); - - const bounceContainer = this.add.container(xPos, popupHeight).setScale(0); - this._updateLogPopup.add(bounceContainer); - const cornerRadius = this.textures.get("GJ_square02").source[0].width * 0.325; - const popupBg = this._drawScale9(0, 0, 480, popupWidth, "GJ_square02", cornerRadius, 16777215, 1); - bounceContainer.add(popupBg); - const closeBtn = this.add.image(-240 + 20, -148, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); - bounceContainer.add(closeBtn); - this._expandHitArea(closeBtn, 2); - this._makeBouncyButton(closeBtn, 0.8, () => this._closeUpdateLogPopup()); - const title = this.add.bitmapText(0, -124, "bigFont", "BETA (EXPECT BUGS)", 30).setOrigin(0.5, 0.5).setTint(0xff6666); - bounceContainer.add(title); - const scrollAreaW = 420; - const scrollAreaH = 230; - const scrollAreaX = 0; - const scrollAreaY = 20; - const scrollFrameBg = this.add.graphics(); - scrollFrameBg.fillStyle(0x000000, 0.18); - scrollFrameBg.fillRoundedRect(scrollAreaX - scrollAreaW / 2, scrollAreaY - scrollAreaH / 2, scrollAreaW, scrollAreaH, 8); - bounceContainer.add(scrollFrameBg); - const contentContainer = this.add.container(0, scrollAreaY - scrollAreaH / 2 + 8); - bounceContainer.add(contentContainer); - /* colors for reference - 0xff6666 - 0xff9944 - 0xaaddff - fun messages from me :) - 0xFF008E - pink dev entries - */ - const updateEntries = [ - { text: "Update Log", scale: 0.85, font: "goldFont" }, - { text: "slopes (very buggy)", scale: 0.7, color: 0xff9944 }, - { text: "THEY WILL BE FIXED", scale: 0.7, }, - { text: "OVER TIME", scale: 0.7, }, - { text: "slopes work in imported", scale: 0.7, }, - { text: "levels now (thanks lasokadadyy)", scale: 0.7, }, - { text: "fixed SOME objects", scale: 0.7 }, - { text: "-pinkdih", scale: 0.7, color: 0xFF008E }, - ]; - let yPos = 0; - const lineItems = []; - updateEntries.forEach(entry => { - const txt = this.add.bitmapText(0, yPos, entry.font || "bigFont", entry.text, 32) - .setOrigin(0.5, 0) - .setScale(entry.scale || 0.65); - if (entry.color != null) txt.setTint(entry.color); - contentContainer.add(txt); - lineItems.push(txt); - yPos += Math.round(32 * (entry.scale || 0.65)) + 10; - }); - const totalContentH = yPos; - const maxScrollDown = Math.max(0, totalContentH - scrollAreaH + 16); - const maskGraphics = this.add.graphics(); - const maskShape = this.add.graphics(); - maskShape.fillStyle(0xffffff, 1); - const updateMask = () => { - if (!bounceContainer || !bounceContainer.active) return; - const wx = xPos + bounceContainer.x - xPos; - const s = bounceContainer.scaleX; - const bwx = xPos; - const bwy = popupHeight; - maskShape.clear(); - maskShape.fillStyle(0xffffff, 1); - maskShape.fillRect( - bwx + (scrollAreaX - scrollAreaW / 2) * s, - bwy + (scrollAreaY - scrollAreaH / 2) * s, - scrollAreaW * s, - scrollAreaH * s - ); - }; - const geomMask = maskShape.createGeometryMask(); - contentContainer.setMask(geomMask); - const maskUpdateEvent = this.events.on('postupdate', updateMask); - let scrollY = 0; - const baseContentY = scrollAreaY - scrollAreaH / 2 + 8; - const applyScroll = () => { - contentContainer.y = baseContentY - scrollY; - }; - applyScroll(); - const scrollZone = this.add.zone(scrollAreaX, scrollAreaY, scrollAreaW, scrollAreaH).setInteractive(); - bounceContainer.add(scrollZone); - scrollZone.on('wheel', (_p, _dx, deltaY) => { - scrollY = Phaser.Math.Clamp(scrollY + deltaY * 0.6, 0, maxScrollDown); - applyScroll(); - }); - - let dragStartY = 0; - let dragStartScroll = 0; - scrollZone.on('pointerdown', (pointer) => { - dragStartY = pointer.y; - dragStartScroll = scrollY; - }); - scrollZone.on('pointermove', (pointer) => { - if (pointer.isDown) { - const dy = dragStartY - pointer.y; - scrollY = Phaser.Math.Clamp(dragStartScroll + dy, 0, maxScrollDown); - applyScroll(); - } - }); - this._updateLogPopupCleanup = () => { - this.events.off('postupdate', updateMask); - maskShape.destroy(); - geomMask.destroy(); - }; - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeUpdateLogPopup() { - if (this._updateLogPopup) { - if (this._updateLogPopupCleanup) { - this._updateLogPopupCleanup(); - this._updateLogPopupCleanup = null; - } - this._updateLogPopup.destroy(); - this._updateLogPopup = null; - } - } - _buildNewgroundsPopup() { - if (this._newgroundsPopup || window.levelID) return; - const xPos = screenWidth / 2; - const centerY = screenHeight / 2; - this._newgroundsPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); - background.setInteractive(); - this._newgroundsPopup.add(background); - const bounceContainer = this.add.container(xPos, centerY).setScale(0); - this._newgroundsPopup.add(bounceContainer); - const cornerRadius = this.textures.get("square01_001").source[0].width * 0.325; - const panelBg = this._drawScale9(0, 0, 460, 240, "square01_001", cornerRadius, 16777215, 1); - bounceContainer.add(panelBg); - const title = this.add.bitmapText(0, -76, "goldFont", "Newgrounds", 40).setOrigin(0.5, 0.5); - bounceContainer.add(title); - const body = this.add.text(0, -10, "Visit Newgrounds to find awesome\nmusic?", { - fontSize: "25px", - fontFamily: "Arial, sans-serif", - color: "#ffffff", - align: "center" - }).setOrigin(0.5, 0.5); - bounceContainer.add(body); - const cancelGroup = this.add.container(-70, 65); - const cancelBtnW = 165, cancelBtnH = 55; - const cancelBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; - const cancelBtn9 = this._drawScale9(0, 0, cancelBtnW, cancelBtnH, "GJ_button01", cancelBtnBorder, 0xffffff, 1); - const cancelBtn = this.add.rectangle(0, 0, cancelBtnW, cancelBtnH).setInteractive(); - cancelGroup.add(cancelBtn9); - cancelGroup.add(cancelBtn); - const cancelLabel = this.add.bitmapText(-2, -3, "goldFont", "Cancel", 38).setOrigin(0.5, 0.5); - cancelGroup.add(cancelLabel); - bounceContainer.add(cancelGroup); - cancelBtn.on("pointerdown", () => { cancelGroup._pressed = true; this.tweens.killTweensOf(cancelGroup); this.tweens.add({ targets: cancelGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); - cancelBtn.on("pointerout", () => { if (cancelGroup._pressed) { cancelGroup._pressed = false; this.tweens.killTweensOf(cancelGroup); this.tweens.add({ targets: cancelGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); - cancelBtn.on("pointerup", () => { if (cancelGroup._pressed) { cancelGroup._pressed = false; this.tweens.killTweensOf(cancelGroup); cancelGroup.setScale(1); this._closeNewgroundsPopup(); } }); - const openGroup = this.add.container(90, 65); - const openBtnW = 125, openBtnH = 55; - const openBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; - const openBtn9 = this._drawScale9(0, 0, openBtnW, openBtnH, "GJ_button01", openBtnBorder, 0xffffff, 1); - const openBtn = this.add.rectangle(0, 0, openBtnW, openBtnH).setInteractive(); - openGroup.add(openBtn9); - openGroup.add(openBtn); - const openLabel = this.add.bitmapText(-2, -3, "goldFont", "Open", 39).setOrigin(0.5, 0.5); - openGroup.add(openLabel); - bounceContainer.add(openGroup); - openBtn.on("pointerdown", () => { openGroup._pressed = true; this.tweens.killTweensOf(openGroup); this.tweens.add({ targets: openGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); - openBtn.on("pointerout", () => { if (openGroup._pressed) { openGroup._pressed = false; this.tweens.killTweensOf(openGroup); this.tweens.add({ targets: openGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); - openBtn.on("pointerup", () => { if (openGroup._pressed) { openGroup._pressed = false; this.tweens.killTweensOf(openGroup); openGroup.setScale(1); this._closeNewgroundsPopup(); window.open("https://www.newgrounds.com/audio", "_blank"); } }); - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeNewgroundsPopup() { - if (this._newgroundsPopup) { - this._newgroundsPopup.destroy(); - this._newgroundsPopup = null; - } - } - _buildFeaturedInfoPopup() { - if (this._featuredInfoPopup) return; - const xPos = screenWidth / 2; - const centerY = screenHeight / 2; - this._featuredInfoPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); - background.setInteractive(); - this._featuredInfoPopup.add(background); - const bounceContainer = this.add.container(xPos, centerY).setScale(0); - this._featuredInfoPopup.add(bounceContainer); - const cornerRadius = this.textures.get("square01_001").source[0].width * 0.325; - const panelBg = this._drawScale9(0, 0, 560, 300, "square01_001", cornerRadius, 16777215, 1); - bounceContainer.add(panelBg); - const title = this.add.bitmapText(0, -98, "goldFont", "Featured", 42).setOrigin(0.5, 0.5); - bounceContainer.add(title); - const body = this.add.text(0, -5, "its finally finished after so long\nso this is awesome am i right\n it has aura. featured tab. roptop fgames.", { - fontSize: "21px", - fontFamily: "Arial, sans-serif", - color: "#ffffff", - align: "center", - lineSpacing: 4 - }).setOrigin(0.5, 0.5); - bounceContainer.add(body); - const okGroup = this.add.container(-5, 95); - const okBtnW = 90, okBtnH = 55; - const okBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; - const okBtn9 = this._drawScale9(0, 0, okBtnW, okBtnH, "GJ_button01", okBtnBorder, 0xffffff, 1); - const okBtn = this.add.rectangle(0, 0, okBtnW, okBtnH).setInteractive(); - okGroup.add(okBtn9); - okGroup.add(okBtn); - const okLabel = this.add.bitmapText(-3, -4, "goldFont", "OK", 44).setOrigin(0.5, 0.5); - okGroup.add(okLabel); - bounceContainer.add(okGroup); - okBtn.on("pointerdown", () => { okGroup._pressed = true; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); - okBtn.on("pointerout", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); - okBtn.on("pointerup", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); okGroup.setScale(1); this._closeFeaturedInfoPopup(); } }); - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeFeaturedInfoPopup() { - if (this._featuredInfoPopup) { - this._featuredInfoPopup.destroy(); - this._featuredInfoPopup = null; - } - } - _buildDemonFilterPopup() { - if (this._demonFilterPopup) return; - const xPos = screenWidth / 2; - const centerY = screenHeight / 2; - this._demonFilterPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); - const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); - background.setInteractive(); - this._demonFilterPopup.add(background); - const bounceContainer = this.add.container(xPos, centerY).setScale(0); - this._demonFilterPopup.add(bounceContainer); - - const panelW = 760, panelH = 360; - const cornerRadius = this.textures.get("GJ_square01").source[0].width * 0.325; - const panelBg = this.add.nineslice(0, 0, "GJ_square01", null, panelW, panelH, cornerRadius, cornerRadius, cornerRadius, cornerRadius) - .setOrigin(0.5); - bounceContainer.add(panelBg); - - const title = this.add.bitmapText(0, -panelH / 2 + 40, "bigFont", "Demon Filter", 64).setOrigin(0.5, 0.5); - bounceContainer.add(title); - - const _tierDefs = [ - { frame: "difficulty_06_btn_001.png", w: 72, h: 88, tier: null }, - { frame: "difficulty_07_btn2_001.png", w: 72, h: 85, tier: 1 }, - { frame: "difficulty_08_btn2_001.png", w: 72, h: 85, tier: 2 }, - { frame: "difficulty_06_btn2_001.png", w: 72, h: 88, tier: 3 }, - { frame: "difficulty_09_btn2_001.png", w: 74, h: 88, tier: 4 }, - { frame: "difficulty_10_btn2_001.png", w: 80, h: 91, tier: 5 }, - ]; - const slotW = (panelW - 60) / _tierDefs.length; - const iconY = 0; - const iconTargetH = 78; - const tierIcons = []; - let selectedTierIdx = _tierDefs.findIndex(t => t.tier === (this._selectedDemonTier || null)); - if (selectedTierIdx < 0) selectedTierIdx = 0; - const baseScale = 1.1; - - _tierDefs.forEach((def, i) => { - const cx = -panelW / 2 + 30 + slotW * i + slotW / 2; - const icon = this.add.image(cx, iconY, "GJ_GameSheet03", def.frame) - .setOrigin(0.5).setScale(baseScale).setInteractive(); - icon.setTint(i === selectedTierIdx ? 0xffffff : 0x8F8F8F); - bounceContainer.add(icon); - tierIcons.push(icon); - - icon.on("pointerdown", () => { - icon._pressed = true; - this.tweens.killTweensOf(icon, "scale"); - this.tweens.add({ targets: icon, scale: baseScale * 1.15, duration: 300, ease: "Bounce.Out" }); - }); - icon.on("pointerout", () => { - if (icon._pressed) { - icon._pressed = false; - this.tweens.killTweensOf(icon, "scale"); - this.tweens.add({ targets: icon, scale: baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - icon.on("pointerup", () => { - if (!icon._pressed) return; - icon._pressed = false; - this.tweens.killTweensOf(icon, "scale"); - icon.setScale(baseScale); - selectedTierIdx = i; - tierIcons.forEach((other, oi) => other.setTint(oi === i ? 0xffffff : 0x8f8f8f)); - }); - }); - - const okGroup = this.add.container(0, panelH / 2 - 45); - const okBtnW = 110, okBtnH = 55; - const okBtn9 = this.add.nineslice(0, 0, "GJ_button01", null, okBtnW, okBtnH, 18, 18, 18, 18) - .setOrigin(0.5).setInteractive(); - okGroup.add(okBtn9); - const okLabel = this.add.bitmapText(-3, -4, "goldFont", "OK", 44).setOrigin(0.5, 0.5); - okGroup.add(okLabel); - bounceContainer.add(okGroup); - okBtn9.on("pointerdown", () => { okGroup._pressed = true; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); - okBtn9.on("pointerout", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); - okBtn9.on("pointerup", () => { - if (!okGroup._pressed) return; - okGroup._pressed = false; - this.tweens.killTweensOf(okGroup); - okGroup.setScale(1); - const chosen = _tierDefs[selectedTierIdx]; - this._selectedDemonTier = chosen.tier; - const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; - if (demonIcon) { - demonIcon.setTexture("GJ_GameSheet03", chosen.frame); - demonIcon.setScale(0.85); - } - this._closeDemonFilterPopup(); - }); - - this.tweens.add({ - targets: bounceContainer, - scale: { from: 0, to: 1 }, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6] - }); - } - _closeDemonFilterPopup() { - if (this._demonFilterPopup) { - this._demonFilterPopup.destroy(); - this._demonFilterPopup = null; - } - } - _expandHitArea(_0x122213, _0x37180a) { - const _0x46ea45 = _0x122213.width; - const _0x43b461 = _0x122213.height; - const _0x960250 = _0x46ea45 * (_0x37180a - 1) / 2; - const _0x3f88a1 = _0x43b461 * (_0x37180a - 1) / 2; - _0x122213.input.hitArea.setTo(-_0x960250, -_0x3f88a1, _0x46ea45 + _0x960250 * 2, _0x43b461 + _0x3f88a1 * 2); - } - _makeBouncyButton(textureX, _0x57b645, _0x2f13d0, _0xda0c21) { - textureX._bouncyBaseScale = _0x57b645; - const getBouncyVisualTargets = () => { - const configured = Array.isArray(textureX._bouncyVisualTargets) && textureX._bouncyVisualTargets.length - ? textureX._bouncyVisualTargets - : [textureX._bouncyVisualTarget || textureX]; - return configured - .map(entry => { - const target = entry && entry.target ? entry.target : entry; - if (!target || typeof target.setScale !== "function") return null; - const baseScale = - (entry && typeof entry.getBaseScale === "function" ? entry.getBaseScale() : undefined) ?? - (entry && entry.baseScale !== undefined ? entry.baseScale : undefined) ?? - target._bouncyBaseScale ?? - textureX._bouncyBaseScale ?? - _0x57b645; - const baseScaleX = - (entry && typeof entry.getBaseScaleX === "function" ? entry.getBaseScaleX() : undefined) ?? - (entry && entry.baseScaleX !== undefined ? entry.baseScaleX : undefined) ?? - baseScale; - const baseScaleY = - (entry && typeof entry.getBaseScaleY === "function" ? entry.getBaseScaleY() : undefined) ?? - (entry && entry.baseScaleY !== undefined ? entry.baseScaleY : undefined) ?? - baseScale; - return { target, baseScaleX, baseScaleY }; - }) - .filter(Boolean); - }; - const tweenBouncyTargets = (scaleMultiplier, duration) => { - for (const entry of getBouncyVisualTargets()) { - this.tweens.killTweensOf(entry.target); - this.tweens.add({ - targets: entry.target, - scaleX: entry.baseScaleX * scaleMultiplier, - scaleY: entry.baseScaleY * scaleMultiplier, - duration, - ease: "Bounce.Out" - }); - } - }; - const resetBouncyTargets = (instant = false) => { - for (const entry of getBouncyVisualTargets()) { - this.tweens.killTweensOf(entry.target); - - if (instant) { - entry.target.setScale(entry.baseScaleX, entry.baseScaleY); - } else { - this.tweens.add({ - targets: entry.target, - scaleX: entry.baseScaleX, - scaleY: entry.baseScaleY, - duration: 400, - ease: "Bounce.Out" - }); - } - } - }; - textureX.on("pointerdown", () => { - if (!_0xda0c21 || !!_0xda0c21()) { - textureX._pressed = true; - tweenBouncyTargets(1.26, 300); - } - }); - textureX.on("pointerout", () => { - if (textureX._pressed) { - textureX._pressed = false; - resetBouncyTargets(false); - } - }); - textureX.on("pointerup", () => { - if (textureX._pressed) { - textureX._pressed = false; - resetBouncyTargets(true); - _0x2f13d0?.(); - } - }); - textureX.on("pointerupoutside", () => { - if (textureX._pressed) { - textureX._pressed = false; - resetBouncyTargets(false); - } - }); - return textureX; - } - _makeCompositeBouncyButton(trigger, visualTargets, baseScale, callback, condition) { - trigger._bouncyVisualTargets = (Array.isArray(visualTargets) ? visualTargets : [visualTargets]) - .filter(Boolean) - .map(entry => { - const target = entry && entry.target ? entry.target : entry; - const currentScaleX = target?.scaleX ?? baseScale; - const currentScaleY = target?.scaleY ?? baseScale; - const entryBase = entry && entry.baseScale !== undefined ? entry.baseScale : undefined; - - return { - target, - baseScaleX: entry && entry.baseScaleX !== undefined ? entry.baseScaleX : (entryBase ?? currentScaleX), - baseScaleY: entry && entry.baseScaleY !== undefined ? entry.baseScaleY : (entryBase ?? currentScaleY), - getBaseScale: entry && entry.getBaseScale, - getBaseScaleX: entry && entry.getBaseScaleX, - getBaseScaleY: entry && entry.getBaseScaleY - }; - }); - - return this._makeBouncyButton(trigger, baseScale, callback, condition); - } - _toggleFullscreen() { - if (this.scale.isFullscreen) { - this.scale.stopFullscreen(); - } else { - this.scale.startFullscreen(); - try { - screen.orientation.lock("landscape").catch(() => {}); - } catch (_0x22124f) {} - } - } - _drawScale9(x, y, scaleWidth, scaleHeight, textureKey, borderSize, tint, alpha) { - const container = this.add.container(x, y); - const texture = this.textures.get(textureKey); - const baseFrame = texture?.get?.(); - const source = texture?.source?.[0]; - const textureWidth = baseFrame?.width || source?.width || scaleWidth; - const textureHeight = baseFrame?.height || source?.height || scaleHeight; - const requestedBorder = Math.max(0, Number(borderSize) || 0); - const horizontalBorder = Math.min(requestedBorder, textureWidth / 2, scaleWidth / 2); - const verticalBorder = Math.min(requestedBorder, textureHeight / 2, scaleHeight / 2); - - const nineSlice = this.add.nineslice( - 0, - 0, - textureKey, - null, - scaleWidth, - scaleHeight, - horizontalBorder, - horizontalBorder, - verticalBorder, - verticalBorder - ).setOrigin(0.5); - - if (tint !== undefined) { - nineSlice.setTint(tint); - } - if (alpha !== undefined) { - nineSlice.setAlpha(alpha); - } - - container.add(nineSlice); - return container; - } - _startGame() { - if (!this._menuActive) { - return; - } - const _instant = !!this._instantLevelStart; - this._instantLevelStart = false; - const _dismiss = (target, tweenProps, cleanup) => { - if (!target) return; - if (_instant) { - cleanup(); - return; - } - this.tweens.killTweensOf(target); - this.tweens.add({ - targets: target, - ...tweenProps, - onComplete: cleanup - }); - }; - - // fixed loading saved new best from local storage - this._bestPercent = parseFloat(localStorage.getItem("bestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); - this._practiceBestPercent = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); - - this._menuActive = false; - this._practiceBypassPending = false; - this._slideIn = true; - if (this._menuGlitter) { - this._menuGlitter.destroy(); - this._menuGlitter = null; - } - if (this._menuUpdateLogBtn) { - this._menuUpdateLogBtn.setVisible(false); - } - if (this._menuNewgroundsBtn) { - this._menuNewgroundsBtn.setVisible(false); - } - if (this._menuSettingsBtn) { - this._menuSettingsBtn.setVisible(false); - } - if (this._menuAchievementsBtn) { - this._menuAchievementsBtn.setVisible(false); - } - if (this._menuStatsBtn) { - this._menuStatsBtn.setVisible(false); - } - _dismiss(this._playBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { - this._playBtn.destroy(); - this._playBtn = null; - }); - //icon stuff the threequel - if (this._iconBtn) { - this._closeIconSelector && this._closeIconSelector(true); - _dismiss(this._iconBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { - this._iconBtn.destroy(); - this._iconBtn = null; - }); - } - _dismiss(this._chrSelDecor, { y: screenHeight + 100, alpha: 0, duration: 200, ease: "Quad.In" }, () => { - if (this._chrSelDecor) { this._chrSelDecor.destroy(); this._chrSelDecor = null; } - }); - _dismiss(this._lvlEditDecor, { y: screenHeight + 100, alpha: 0, duration: 200, ease: "Quad.In" }, () => { - if (this._lvlEditDecor) { this._lvlEditDecor.destroy(); this._lvlEditDecor = null; } - }); - //creator stuff the threequel - if (this._creatorBtn) { - this._closeCreatorMenu && this._closeCreatorMenu(true); - this._closeSearchMenu && this._closeSearchMenu(true); - _dismiss(this._creatorBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { - this._creatorBtn.destroy(); - this._creatorBtn = null; - }); - } - _dismiss(this._robLogo, { y: screenHeight + (this._robLogo ? this._robLogo.height : 0), duration: 300, ease: "Quad.In" }, () => { - this._robLogo.destroy(); - this._robLogo = null; - }); - _dismiss(this._copyrightText, { y: 680, duration: 300, ease: "Quad.In" }, () => { - this._copyrightText.destroy(); - this._copyrightText = null; - }); - _dismiss(this._menuFsBtn, { y: this._menuFsBtn ? -this._menuFsBtn.height : 0, duration: 300, ease: "Quad.In" }, () => { - this._menuFsBtn.destroy(); - this._menuFsBtn = null; - }); - _dismiss(this._menuInfoBtn, { y: this._menuInfoBtn ? -this._menuInfoBtn.height : 0, duration: 300, ease: "Quad.In" }, () => { - this._menuInfoBtn.destroy(); - this._menuInfoBtn = null; - }); - this._closeInfoPopup(); - this._closeUpdateLogPopup(); - _dismiss(this._tryMeImg, { y: this._tryMeImg ? -this._tryMeImg.height : 0, duration: 300, ease: "Quad.In" }, () => { - this._tryMeImg.destroy(); - this._tryMeImg = null; - }); - if (this._downloadBtns) { - for (const _0xaa3a95 of this._downloadBtns) { - _dismiss(_0xaa3a95, { y: screenHeight + _0xaa3a95.height, duration: 300, ease: "Quad.In" }, () => _0xaa3a95.destroy()); - } - this._downloadBtns = null; - } - if (this._socialIcons && this._socialIcons.length > 0) { - for (const _icon of this._socialIcons) { - _dismiss(_icon, { y: screenHeight + 64, duration: 300, ease: "Quad.In" }, () => _icon.destroy()); - } - this._socialIcons = []; - } - _dismiss(this._logo, { y: this._logo ? -this._logo.height : 0, duration: 300, ease: "Quad.In" }, () => { - this._logo.destroy(); - this._logo = null; - }); - - if (window.isEditor) { - this._audio.stopMusic(); - this._cameraX = 0; - this._cameraY = 0; - this._playerWorldX = 0; - this._level.additiveContainer.setVisible(true); - this._level.container.setVisible(true); - this._level.topContainer.setVisible(true); - this._player.setCubeVisible(false); - this._player2.setCubeVisible(false); - this._attemptsLabel.setVisible(false); - window.selectedObjId = 1; - this._levelEditor._initEditorLogic(); - return; - } - this._cameraX = -centerX; - this._cameraY = 0; - this._cameraXRef._v = this._cameraX; - this._prevCameraX = this._cameraX; - const _0x22e36e = this._cameraX - (this._menuCameraX || 0); - this._level.shiftGroundTiles(_0x22e36e); - this._playerWorldX = this._cameraX; - let speedKey = parseInt(window.settingsMap["kA4"] || "0"); - if (speedKey == 0) { - playerSpeed = SpeedPortal.ONE_TIMES; - } else if (speedKey == 1) { - playerSpeed = SpeedPortal.HALF; - } else if (speedKey == 2) { - playerSpeed = SpeedPortal.TWO_TIMES; - } else if (speedKey == 3) { - playerSpeed = SpeedPortal.THREE_TIMES; - } else if (speedKey == 4) { - playerSpeed = SpeedPortal.FOUR_TIMES; - } - this._state.y = 30; - this._state.onGround = true; - this._level.additiveContainer.setVisible(true); - this._level.container.setVisible(true); - this._level.topContainer.setVisible(true); - this._player.setCubeVisible(true); - this._player.reset(); - this._isDual = false; - this._state2.reset(); - this._player2.reset(); - this._player2.setCubeVisible(false); - this._player2.setShipVisible(false); - this._player2.setBallVisible(false); - this._player2.setWaveVisible(false); - this._player2.setBirdVisible?.(false); - this._player2.setSpiderVisible(false); - this._player2.setRobotVisible(false); - this._levelAttempts = 1; - this._levelJumps = 0; - this._attempts++; - localStorage.setItem("gd_totalAttempts", this._attempts); - this._attemptsLabel.setText("Attempt " + this._levelAttempts); - this._attemptsLabel.setVisible(true); - this._positionAttemptsLabel(); - let gamemode = parseInt(window.settingsMap["kA2"] || "0"); - if (gamemode == 1) { - this._player.enterShipMode(); - } else if (gamemode == 2) { - this._state.y = 30; - this._player.enterBallMode({ y: 30 }); - } else if (gamemode == 3) { - this._player.enterUfoMode(); - } else if (gamemode == 4) { - this._player.enterWaveMode(); - } else if (gamemode == 5) { - this._player.enterRobotMode(); - } else if (gamemode == 6) { - this._player.enterSpiderMode(); - } - - this._applyLevelStartOptions(); - } - _pushButton(ignoreMacro = false) { - const objectsUnderPointer = this.input.manager.hitTest( - this.input.activePointer, - this._startPosGui.list, - this.cameras.main - ); - const isOverUI = objectsUnderPointer.length > 0; - const fromClick = this.input.activePointer.isDown; - const cancelInput = isOverUI && fromClick; - - if (this._menuActive) { - this._audio.playEffect("playSound_01", { - volume: 1 - }); - this._startGame(); - return; - } - - if (!cancelInput) { - if (!this._clickHistory) this._clickHistory = []; - this._clickHistory.push(this.time.now); - } - - if (!this._slideIn && !this._state.isDead && !cancelInput) { - this._state.upKeyDown = true; - this._state.upKeyPressed = true; - this._state.queuedHold = true; - this._state._orbActivationConsumedForPress = false; - if (this._isDual && !this._state2.isDead) { - this._state2.upKeyDown = true; - this._state2.upKeyPressed = true; - this._state2.queuedHold = true; - this._state2._orbActivationConsumedForPress = false; - } - const _dualImmediateBeforeGravity = !!this._state.gravityFlipped; - let _primaryImmediateJumped = false; - if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && this._state.canJump) { - this._player.updateJump(0); - _primaryImmediateJumped = true; - } else if (this._state.isUfo) { - if (!this._player._shouldPrioritizeUfoOrbInput?.()) { - this._player.updateJump(0); - _primaryImmediateJumped = true; - } - } - const _primaryImmediateGravityChanged = this._isDual && !!this._state.gravityFlipped !== _dualImmediateBeforeGravity; - let _primaryImmediateGravitySynced = false; - if (_primaryImmediateGravityChanged) { - _primaryImmediateGravitySynced = this._syncDualGlobalsFromPrimary({ - skipBallInputGravity: this._state.isBall && _primaryImmediateJumped, - skipSpiderInputGravity: this._state.isSpider && _primaryImmediateJumped - }); - } - if (this._isDual && !this._state2.isDead) { - if (this._shouldSuppressDualGravityAction(this._state2, _primaryImmediateGravitySynced)) { - this._state2.upKeyPressed = false; - this._state2.queuedHold = false; - } - const _secondaryImmediateBeforeGravity = !!this._state2.gravityFlipped; - const _secondaryImmediateBallInput = this._state2.isBall && this._state2.upKeyPressed; - const _secondaryImmediateSpiderInput = this._state2.isSpider && this._state2.upKeyPressed; - if (!this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && this._state2.canJump) { - this._player2.updateJump(0); - } else if (this._state2.isUfo) { - if (!this._player2._shouldPrioritizeUfoOrbInput?.()) { - this._player2.updateJump(0); - } - } - if (!!this._state2.gravityFlipped !== _secondaryImmediateBeforeGravity) { - this._syncDualGlobalsFromSecondary({ - skipBallInputGravity: _secondaryImmediateBallInput, - skipSpiderInputGravity: _secondaryImmediateSpiderInput - }); - } - } - if (_primaryImmediateJumped) { - this._totalJumps++; - this._levelJumps++; - localStorage.setItem("gd_totalJumps", this._totalJumps); - } - } - - if (!ignoreMacro && this._macroBot) { - this._macroBot.recordEdge(true, this._physicsFrame); - } - } - _releaseButton(ignoreMacro = false) { - this._state.upKeyDown = false; - this._state.upKeyPressed = false; - this._state.queuedHold = false; - this._state._orbActivationConsumedForPress = false; - this._state2.upKeyDown = false; - this._state2.upKeyPressed = false; - this._state2.queuedHold = false; - this._state2._orbActivationConsumedForPress = false; - if (!ignoreMacro && this._macroBot) { - this._macroBot.recordEdge(false, this._physicsFrame); - } - } - _initMacroBot() { - this._macroBot = new MacroBot(this); - window.macroBot = this._macroBot; - } - _startMacroRecording(meta = {}) { - if (!this._macroBot) this._initMacroBot(); - this._macroBot.startRecording({ - level: window.currentlevel?.[2] || "", - ...meta - }); - } - _stopMacroRecording() { - if (!this._macroBot) return null; - return this._macroBot.stopRecording(); - } - _startMacroPlayback(macroData) { - console.log(macroData); - if (!this._macroBot) this._initMacroBot(); - this._macroBot.startPlayback(macroData); - } - _stopMacroPlayback() { - if (this._macroBot) this._macroBot.stopPlayback(); - } - _exportMacroFile(filename = null) { - if (!this._macroBot) return; - const safeName = (filename || `${window.currentlevel?.[2] || "macro"}.gdr`) - .replace(/[^\w.\-]+/g, "_"); - this._macroBot.download(safeName); - } - _importMacroFile() { - const fileInput = document.createElement("input"); - fileInput.type = "file"; - fileInput.accept = ".wbgdr"; - - fileInput.onchange = async (e) => { - const file = e.target.files?.[0]; - if (!file) return; - - try { - if (!this._macroBot) this._initMacroBot(); - - const macroData = await this._macroBot.importFile(file); - this._macroBot.inputs = Array.isArray(macroData.inputs) ? macroData.inputs.slice() : []; - const fallback = file.name.replace(/\.[^/.]+$/, ""); - const macroName = macroData.meta?.name || fallback; - - this._macroBot.meta = macroData.meta || this._macroBot.meta; - this._macroBot.meta.name = macroName; - - this._macroName = macroName; - this._macroLoaded = true; - } catch (err) { - alert("Failed to import: " + err.message); - } - }; - - fileInput.click(); - } - _positionMenuItems() { - const _0x1e5db8 = screenWidth / 2; - if (this._logo) { - this._logo.x = _0x1e5db8; - } - if (this._menuInfoBtn) { - this._menuInfoBtn.x = screenWidth - 30 - 3; - } - if (this._copyrightText) { - this._copyrightText.x = screenWidth - 20; - } - if (this._tryMeImg) { - this._tryMeImg.x = _0x1e5db8 + 260; - } - if (this._menuGlitter) { - this._menuGlitter.x = _0x1e5db8; - this._menuGlitter.y = 320; - } - if (this._playBtn) { - this._playBtn.x = _0x1e5db8; - this.tweens.killTweensOf(this._playBtn, "y"); - this._playBtn.y = 320; - } - if (this._downloadBtns) { - const _0x285ef7 = screenWidth - 130; - const _0x4a8263 = 570; - const _0x23d03e = 60; - for (let _0x1bdfae = 0; _0x1bdfae < this._downloadBtns.length; _0x1bdfae++) { - const yOffset = _0x1bdfae === 1 ? -_0x23d03e : 0; - this._downloadBtns[_0x1bdfae].setPosition(_0x285ef7, _0x4a8263 + yOffset); - } - } - if (this._iconBtn) { - this._iconBtn.x = (screenWidth / 2) - this._playBtn.width / 2 - 100 - (this._iconBtn.width * this._iconBtn.scaleX) / 2; - this.tweens.killTweensOf(this._iconBtn, "y"); - this._iconBtn.y = 320; - this.tweens.add({ - targets: this._iconBtn, - y: 324, - duration: 750, - ease: "Quad.InOut", - yoyo: true, - repeat: -1 - }); - } - if (this._creatorBtn) { - this._creatorBtn.x = (screenWidth / 2) + this._playBtn.width / 2 + 100 + (this._creatorBtn.width * this._creatorBtn.scaleX) / 2; - this.tweens.killTweensOf(this._creatorBtn, "y"); - this._creatorBtn.y = 320; - } - if (this._robLogo) { - this._robLogo.x = 110; - this._robLogo.y = 585; - } - if (this._socialIcons && this._socialIcons.length > 0) { - const _iconSpacing = 52; - const _originX = 65; - const _originY = 478; - const _layout = [{row:0,col:0},{row:0,col:1},{row:0,col:2},{row:0,col:3}, - {row:1,col:0},{row:1,col:1},{row:1,col:2},{row:1,col:3}, - {row:2,col:0},{row:2,col:1},{row:2,col:2},{row:2,col:3},{row:2,col:4}]; - this._socialIcons.forEach((icon, i) => { - icon.x = _originX + _layout[i].col * _iconSpacing; - icon.y = _originY + _layout[i].row * _iconSpacing; - }); - } - } - _positionAttemptsLabel() { - let _0xdbdd91 = this._cameraX + screenWidth / 2; - if (this._levelAttempts > 1) { - _0xdbdd91 += 100; - } - this._attemptsLabel.setPosition(_0xdbdd91, 150); - } - _resetGameplayState() { - this._cameraX = -centerX; - this._cameraY = 0; - this._cameraXRef._v = -centerX; - this._prevCameraX = -centerX; - this._playerWorldX = 0; - this._deltaBuffer = 0; - this._deathTimer = 0; - this._deathSoundPlayed = false; - this._newBestShown = false; - this._hadNewBest = false; - this._levelWon = false; - this._endCameraOverride = false; - this._endCamTween = null; - this._spaceWasDown = false; - this._physicsFrame = 0; - } - _restartLevel() { - this._attempts++; - localStorage.setItem("gd_totalAttempts", this._attempts); - this._levelAttempts++; - this._levelJumps = 0; - const _0x2ba78a = this._cameraX; - if (this._levelWon && this._practicedMode.practiceMode) { - this._practicedMode.togglePracticeMode(); - this._practicedMode.clearCheckpoints(); - if (this._checkpointBtnContainer) { - this._checkpointBtnContainer.setVisible(false); - } - } - if (this._practicedMode.practiceMode) { - const checkpoint = this._practicedMode.loadLastCheckpoint(); - if (checkpoint) { - this._respawnFromCheckpoint(); - return; - } - } - this._practicedMode.clearCheckpoints(); - this._resetGameplayState(); - this._state.reset(); - this._player.reset(); - this._isDual = false; - this._state2.reset(); - this._player2.reset(); - this._player2.setCubeVisible(false); - this._player2.setShipVisible(false); - this._player2.setBallVisible(false); - this._player2.setWaveVisible(false); - this._player2.setBirdVisible?.(false); - this._player2.setSpiderVisible(false); - this._player2.setRobotVisible(false); - this._glitterEmitter.stop(); - let speedKey = parseInt(window.settingsMap["kA4"] || "0"); - if (speedKey == 0) { - playerSpeed = SpeedPortal.ONE_TIMES; - } else if (speedKey == 1) { - playerSpeed = SpeedPortal.HALF; - } else if (speedKey == 2) { - playerSpeed = SpeedPortal.TWO_TIMES; - } else if (speedKey == 3) { - playerSpeed = SpeedPortal.THREE_TIMES; - } else if (speedKey == 4) { - playerSpeed = SpeedPortal.FOUR_TIMES; - } - this._level.resetObjects(); - this._level.shiftGroundTiles(this._cameraX - _0x2ba78a); - this._level.resetGroundState(); - this._level.resetColorTriggers(); - this._level.resetAlphaTriggers(); - this._level.resetRotateTriggers(); - this._level.resetPulseTriggers(); - this._level.resetEnterEffectTriggers(); - this._level.resetSpawnTriggers(); - this._level.resetMoveTriggers(); - this._level.resetVisibility(); - if (this._orbGfx) { this._orbGfx.clear(); } - this._colorManager.reset(); - this._player.noclipStats.totalFrames = 0; - this._player.noclipStats.deathFrames = 0; - this._player.noclipStats.deaths = 0; - - const musicOffset = this._getStartPosMusicOffset(); - const startPositions = this._level.getStartPositions(); - const activeStartPos = this._startPosIndex !== -1 && !!startPositions[this._startPosIndex]; - - if (activeStartPos) { - const pos = startPositions[this._startPosIndex]; - const startPosY = Number.isFinite(Number(pos.y)) ? Number(pos.y) : 30; - - this._playerWorldX = pos.x; - this._state.y = startPosY; - this._state.lastY = startPosY; - this._state.lastGroundPosY = startPosY; - if (pos.gameMode == 1) { - this._player.enterShipMode(); - } else if (pos.gameMode == 2) { - this._state.y = startPosY; - this._player.enterBallMode({ y: startPosY }); - } else if (pos.gameMode == 3) { - this._player.enterUfoMode(); - } else if (pos.gameMode == 4) { - this._player.enterWaveMode(); - } else if (pos.gameMode == 5) { - this._player.enterRobotMode(); - } else if (pos.gameMode == 6) { - this._player.enterSpiderMode(); - } - this._state.gravityFlipped = pos.gravityFlipped; - this._state.isMini = pos.miniMode; - playerSpeed = [ - SpeedPortal.ONE_TIMES, - SpeedPortal.HALF, - SpeedPortal.TWO_TIMES, - SpeedPortal.THREE_TIMES, - SpeedPortal.FOUR_TIMES - ][pos.speed]; - this._state.mirrored = pos.mirrored; - if (pos.dualMode) { - this._enableDualMode(); - } - this._level.fastForwardTriggers(pos.x, this._colorManager); - if (this._player) { - this._player._lastCollisionWorldX = Number.isFinite(Number(this._playerWorldX)) ? Number(this._playerWorldX) : null; - this._player._lastCollisionWorldY = startPosY; - } - } - - this._practiceBypassPending = false; - this._audio.reset(); - this._audio.startMusic(musicOffset); - this._paused = false; - if (this._pauseContainer) { - this._pauseContainer.destroy(); - this._pauseContainer = null; - } - this._pauseBtn.setVisible(true).setAlpha(75 / 255); - if (this._practiceModeBarContainer) { - this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); - } - this._attemptsLabel.setText("Attempt " + this._levelAttempts); - this._attemptsLabel.setVisible(true); - this._positionAttemptsLabel(); - if (!activeStartPos) { - let gamemode = parseInt(window.settingsMap["kA2"] || "0"); - if (gamemode == 1) { - this._player.enterShipMode(); - } else if (gamemode == 2) { - this._state.y = 30; - this._player.enterBallMode({ y: 30 }); - } else if (gamemode == 3) { - this._player.enterUfoMode(); - } else if (gamemode == 4) { - this._player.enterWaveMode(); - } else if (gamemode == 5) { - this._player.enterRobotMode(); - } else if (gamemode == 6) { - this._player.enterSpiderMode(); - } - - this._applyLevelStartOptions(); - } - - if (this._player && this._player._hitboxTrail) { - this._player._hitboxTrail = []; - } - if (this._player?._hitboxGraphics) this._player._hitboxGraphics.clear(); - if (this._player2 && this._player2._hitboxTrail) { - this._player2._hitboxTrail = []; - } - if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); - - if (this._macroBot?.recording == true){ - this._macroBot?.clearRecording(); - } - if (this._macroBot?.playing == true){ - this._macroBot?.clearPlayback(); - } - this._level._updateGlowVisibility?.(); - this._updateCameraY(0, true); - } - _getSongOffsetForWorldX(worldX) { - const startX = Number.isFinite(Number(worldX)) ? Number(worldX) : 0; - return this._level?.getSongOffsetForX - ? this._level.getSongOffsetForX(startX, { sourceObjects: window.levelObjects }) - : Math.max(0, startX) / 623.16; - } - _getStartPosMusicOffset(){ - const startPositions = this._level.getStartPositions(); - if (this._startPosIndex !== -1 && startPositions[this._startPosIndex]) { - return this._getSongOffsetForWorldX(startPositions[this._startPosIndex].x); - } - return 0; - } - _getCurrentMusicSyncOffset() { - if (this._startPosIndex !== -1 && this._playerWorldX <= 0) { - return this._getStartPosMusicOffset(); - } - return this._getSongOffsetForWorldX(this._playerWorldX); - } - _respawnFromCheckpoint() { - const checkpoint = this._practicedMode.loadLastCheckpoint(); - if (!checkpoint) { - this._restartLevel(); - return; - } - this._deathTimer = 0; - this._deathSoundPlayed = false; - this._newBestShown = false; - this._state.isDead = false; - this._slideIn = false; - this._playerWorldX = checkpoint.x; - this._cameraX = checkpoint.cameraX; - this._cameraY = checkpoint.cameraY; - this._cameraXRef._v = this._cameraX; - this._state.y = checkpoint.y; - this._state.yVelocity = checkpoint.yVelocity; - this._state.gravityFlipped = checkpoint.gravityFlipped; - this._state.isMini = checkpoint.isMini; - this._state.isCube = checkpoint.isCube; - this._state.isShip = checkpoint.isShip; - this._state.isBall = checkpoint.isBall; - this._state.isUfo = checkpoint.isUfo; - this._state.isWave = checkpoint.isWave; - this._state.isSpider = checkpoint.isSpider; - this._state.isBird = checkpoint.isBird; - this._state.isDart = checkpoint.isDart; - this._state.isRobot = checkpoint.isRobot; - this._state.isSwing = checkpoint.isSwing; - this._state.isJetpack = checkpoint.isJetpack; - this._state.isFlying = checkpoint.isFlying; - this._state.isJumping = checkpoint.isJumping; - this._state.onGround = checkpoint.onGround; - this._state.canJump = checkpoint.canJump; - this._state.wasBoosted = checkpoint.wasBoosted; - this._state.rotation = checkpoint.rotation; - this._state.gravity = checkpoint.gravity; - this._state.jumpPower = checkpoint.jumpPower; - this._state.mirrored = checkpoint.mirrored; - this._state.isDashing = checkpoint.isDashing; - this._state.dashYVelocity = checkpoint.dashYVelocity; - this._state.ballShouldRotate = checkpoint.ballShouldRotate || false; - this._state.ballRotateOpposite = checkpoint.ballRotateOpposite || false; - this._state.ballNormalRotate = checkpoint.ballNormalRotate || 1; - this._state.ballHitPad = checkpoint.ballHitPad || false; - this._state._robotHold = !!checkpoint.robotHold; - this._state._robotHoldTimer = checkpoint.robotHoldTimer || 0; - this._player.reset(); - this._state.isFlying = false; - this._state.isBall = false; - this._state.isWave = false; - this._state.isUfo = false; - this._state.isSpider = false; - this._state.isRobot = false; - this._state.isBird = false; - if (checkpoint.isFlying) { - this._player.enterShipMode(null, true); // dont mess with y velocity if ur loading a checkpoint - } else if (checkpoint.isBall) { - this._player.enterBallMode(); - } else if (checkpoint.isUfo) { - this._player.enterUfoMode(null, true); // dont mess with y velocity if ur loading a checkpoint - } else if (checkpoint.isWave) { - this._player.enterWaveMode(); - } else if (checkpoint.isRobot) { - this._player.enterRobotMode(); - } else if (checkpoint.isSpider) { - this._player.enterSpiderMode(); - } else if (checkpoint.isBird) { - this._player.setBirdVisible(true); - this._player.setCubeVisible(true); - for (const layer of this._player._playerLayers) { - if (layer) { - layer.sprite.setScale(0.55); - } - } - } else { - this._player.setCubeVisible(true); - } - this._state.isFlying = checkpoint.isFlying; - this._state.isBall = checkpoint.isBall; - this._state.isWave = checkpoint.isWave; - this._state.isUfo = checkpoint.isUfo; - this._state.isSpider = checkpoint.isSpider; - this._state.isRobot = checkpoint.isRobot; - this._state.isBird = checkpoint.isBird; - this._state._robotHold = !!checkpoint.robotHold; - this._state._robotHoldTimer = checkpoint.robotHoldTimer || 0; - this._state.ignorePortals = true; - this._state2.ignorePortals = true; - this._level.resetGroundTiles(this._cameraX); - this._level.resetObjects(); - this._level._flyFloorY = checkpoint.flyFloorY !== undefined - ? checkpoint.flyFloorY - : (this._level._flyFloorY ?? 0); - this._level._flyCeilingY = checkpoint.flyCeilingY; - this._level._flyGroundActive = checkpoint.flyGroundActive; - this._level._flyVisualOnly = checkpoint.flyVisualOnly; - this._level._flyVisualFloorInset = checkpoint.flyVisualFloorInset !== undefined - ? checkpoint.flyVisualFloorInset - : (this._level._flyVisualFloorInset ?? 0); - this._level._flyVisualCeilingInset = checkpoint.flyVisualCeilingInset !== undefined - ? checkpoint.flyVisualCeilingInset - : (this._level._flyVisualCeilingInset ?? 0); - this._level._groundTargetValue = checkpoint.groundTargetValue; - this._level.flyCameraTarget = checkpoint.flyCameraTarget; - this._level._groundAnimating = checkpoint.groundAnimating; - this._level._groundAnimFrom = checkpoint.groundAnimFrom; - this._level._groundAnimTo = checkpoint.groundAnimTo; - this._level._groundAnimTime = checkpoint.groundAnimTime; - this._level._groundAnimDuration = checkpoint.groundAnimDuration; - this._level._groundStartScreenY = checkpoint.groundStartScreenY !== undefined - ? checkpoint.groundStartScreenY - (checkpoint.cameraY || 0) + this._cameraY - : b(0) + this._cameraY; - this._level._ceilingStartScreenY = checkpoint.ceilingStartScreenY - - (checkpoint.cameraY || 0) + this._cameraY; - this._level._groundY = checkpoint.groundY; - this._level._ceilingY = checkpoint.ceilingY; - if (typeof checkpoint.speed === "number") { - playerSpeed = checkpoint.speed; - } else { - let speedKey = parseInt(window.settingsMap["kA4"] || "0"); - if (speedKey == 0) { - playerSpeed = SpeedPortal.ONE_TIMES; - } else if (speedKey == 1) { - playerSpeed = SpeedPortal.HALF; - } else if (speedKey == 2) { - playerSpeed = SpeedPortal.TWO_TIMES; - } else if (speedKey == 3) { - playerSpeed = SpeedPortal.THREE_TIMES; - } else if (speedKey == 4) { - playerSpeed = SpeedPortal.FOUR_TIMES; - } - } - if (checkpoint.dualMode) { - this._isDual = false; - this._dualBallOverlapResolved = false; - this._dualBallSpawnGravityLock = false; - this._state2.reset(); - this._player2.reset(); - this._player2.setInvertedColors?.(true); - this._enableDualMode(); - this._state2.isDead = false; - if (Number.isFinite(Number(checkpoint.dualY))) this._state2.y = Number(checkpoint.dualY); - if (Number.isFinite(Number(checkpoint.dualYVelocity))) this._state2.yVelocity = Number(checkpoint.dualYVelocity); - if (checkpoint.dualIsMini !== undefined) this._state2.isMini = !!checkpoint.dualIsMini; - if (checkpoint.dualGameMode) this._setPlayerGamemode(this._player2, this._state2, checkpoint.dualGameMode, true); - if (checkpoint.dualGravityFlipped !== undefined) this._state2.gravityFlipped = !!checkpoint.dualGravityFlipped; - if (checkpoint.dualOnGround !== undefined) this._state2.onGround = !!checkpoint.dualOnGround; - if (checkpoint.dualOnCeiling !== undefined) this._state2.onCeiling = !!checkpoint.dualOnCeiling; - if (checkpoint.dualCanJump !== undefined) this._state2.canJump = !!checkpoint.dualCanJump; - if (checkpoint.dualIsJumping !== undefined) this._state2.isJumping = !!checkpoint.dualIsJumping; - this._copyDualInputFlags(this._state, this._state2); - this._ensureDualFlyBounds(this._state.y); - } else { - this._isDual = false; - this._state2.reset(); - this._player2.reset(); - this._player2.setCubeVisible(false); - this._player2.setShipVisible(false); - this._player2.setBallVisible(false); - this._player2.setWaveVisible(false); - this._player2.setBirdVisible?.(false); - this._player2.setSpiderVisible(false); - this._player2.setRobotVisible(false); - if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); - if (this._player2) this._player2._hitboxTrail = []; - } - this._level.resetColorTriggers(); - this._level.resetAlphaTriggers(); - this._level.resetRotateTriggers(); - this._level.resetPulseTriggers(); - this._level.resetEnterEffectTriggers(); - this._level.resetSpawnTriggers(); - this._level.resetMoveTriggers(); - this._level.resetVisibility(); - this._level.additiveContainer.x = -this._cameraX; - this._level.additiveContainer.y = this._cameraY; - this._level.container.x = -this._cameraX; - this._level.container.y = this._cameraY; - this._level.topContainer.x = -this._cameraX; - this._level.topContainer.y = this._cameraY; - this._level.updateVisibility(this._cameraX); - this._level.updateObjectDebugIds(); - this._updateBackground(); - this._applyMirrorEffect(); - this._practiceBypassPending = false; - if (window.practiceMusicBypass) { - this._audio.startMusic(this._getSongOffsetForWorldX(checkpoint.x)); - } else if (!this._audio.musicPlaying) { - this._audio.startMusic(); - } - - if (this._player && this._player._hitboxTrail) { - this._player._hitboxTrail = []; - } - if (this._player?._hitboxGraphics) this._player._hitboxGraphics.clear(); - if (this._player2 && this._player2._hitboxTrail) { - this._player2._hitboxTrail = []; - } - if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); - - this._deltaBuffer = 0; - this._physicsFrame = checkpoint.physicsFrame; - if (this._macroBot?.recording == true){ - this._macroBot?.rollbackRecording(this._physicsFrame); - if (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown){ - this._macroBot.recordEdge(true, this._physicsFrame); - } else { - this._macroBot.recordEdge(false, this._physicsFrame); - } - } - if (this._macroBot?.playing == true){ - this._macroBot?.rollbackPlayback(this._physicsFrame); - } - this._level._updateGlowVisibility?.(); - } - _onFullscreenChange(_0x310c5b) { - if (!_0x310c5b) { - l(1138); - } - this.time.delayedCall(200, () => this._applyScreenResize()); - } - _applyScreenResize() { - if (this.scale.isFullscreen) { - const _0x5bc34b = window.innerWidth / window.innerHeight; - l(Math.round(screenHeight * _0x5bc34b)); - } - this.scale.setGameSize(screenWidth, screenHeight); - this.scale.refresh(); - this._bg.setSize(screenWidth, screenHeight); - this._pauseBtn.x = screenWidth - 30; - if (this._menuActive) { - this._positionMenuItems(); - } - if (this._paused && this._pauseContainer) { - this._pauseContainer.destroy(); - this._pauseContainer = null; - this._buildPauseOverlay(); - } - this._level.resizeScreen(); - if (!this._menuActive) { - const _0x56287b = this._cameraX; - this._cameraX = this._playerWorldX - centerX; - this._cameraXRef._v = this._cameraX; - this._level.additiveContainer.x = -this._cameraX; - this._level.additiveContainer.y = this._cameraY; - this._level.container.x = -this._cameraX; - this._level.container.y = this._cameraY; - this._level.topContainer.x = -this._cameraX; - this._level.topContainer.y = this._cameraY; - this._level.shiftGroundTiles(this._cameraX - _0x56287b); - this._level.updateGroundTiles(this._cameraY); - this._level.updateVisibility(this._cameraX); - this._level.updateObjectDebugIds(); - this._level.applyEnterEffects(this._cameraX); - const _0xde8a1a = this._playerWorldX - this._cameraX; - this._player.syncSprites(this._cameraX, this._cameraY, 0, this._getMirrorXOffset(_0xde8a1a)); - this._applyMirrorEffect(); - } - } - _createMirroredBackgroundTexture(textureKey) { - const mirroredKey = textureKey + "__mirror_y_loop"; - if (this.textures.exists(mirroredKey)) return mirroredKey; - - const texture = this.textures.get(textureKey); - const source = texture?.source?.[0]; - const image = source?.image || source?.canvas; - const width = source?.width || image?.width || image?.naturalWidth || 0; - const height = source?.height || image?.height || image?.naturalHeight || 0; - - if (!image || width <= 0 || height <= 0 || !this.textures.createCanvas) { - return textureKey; - } - - try { - const mirroredTexture = this.textures.createCanvas(mirroredKey, width, height * 2); - const ctx = mirroredTexture.getContext(); - ctx.clearRect(0, 0, width, height * 2); - ctx.drawImage(image, 0, 0, width, height, 0, 0, width, height); - ctx.save(); - ctx.translate(0, height * 2); - ctx.scale(1, -1); - ctx.drawImage(image, 0, 0, width, height, 0, 0, width, height); - ctx.restore(); - mirroredTexture.refresh(); - return mirroredKey; - } catch (err) { - console.warn("Failed to create mirrored background texture", textureKey, err); - if (this.textures.exists(mirroredKey)) this.textures.remove(mirroredKey); - return textureKey; - } - } - - _applyMirroredBackgroundTexture(textureKey) { - const texture = this.textures.get(textureKey); - const source = texture?.source?.[0]; - const sourceHeight = source?.height || source?.image?.height || source?.image?.naturalHeight || 0; - const mirroredKey = this._createMirroredBackgroundTexture(textureKey); - this._bg.setTexture(mirroredKey); - this._bgInitY = sourceHeight > 0 ? sourceHeight - screenHeight - o : 0; - this._bgMirrorTileHeight = sourceHeight > 0 ? sourceHeight * 2 : 0; - } - - _updateBackground() { - this._bg.tilePositionX += (this._cameraX - this._prevCameraX) * this._bgSpeedX; - this._prevCameraX = this._cameraX; - let tileY = this._bgInitY - this._cameraY * this._bgSpeedY; - if (this._bgMirrorTileHeight > 0) { - tileY = ((tileY % this._bgMirrorTileHeight) + this._bgMirrorTileHeight) % this._bgMirrorTileHeight; - } - this._bg.tilePositionY = tileY; - } - _updateCameraY(_0xc7c517, snap = false) { - let explosionPiece = this._cameraY; - let _0x1a27be = explosionPiece; - if (this._level.flyCameraTarget !== null) { - _0x1a27be = this._level.flyCameraTarget; - } else { - let _0x2bc8fb = this._state.y; - let _0x259956 = 140; - let _0x5025ec = 80; - let _0x1f7976 = explosionPiece - (typeof o !== 'undefined' ? o : 0) + 320; - if (this._state.gravityFlipped) { - if (_0x2bc8fb > _0x1f7976 + _0x5025ec) { - _0x1a27be = _0x2bc8fb - 320 - _0x5025ec + (typeof o !== 'undefined' ? o : 0); - } else if (_0x2bc8fb < _0x1f7976 - _0x259956) { - _0x1a27be = _0x2bc8fb - 320 + _0x259956 + (typeof o !== 'undefined' ? o : 0); - } - } else { - if (_0x2bc8fb > _0x1f7976 + _0x259956) { - _0x1a27be = _0x2bc8fb - 320 - _0x259956 + (typeof o !== 'undefined' ? o : 0); - } else if (_0x2bc8fb < _0x1f7976 - _0x5025ec) { - _0x1a27be = _0x2bc8fb - 320 + _0x5025ec + (typeof o !== 'undefined' ? o : 0); - } - } - } - if (_0x1a27be < 0) { - _0x1a27be = 0; - } - if (snap) { - this._cameraY = _0x1a27be; - } else if (_0xc7c517 !== 0) { - explosionPiece += (_0x1a27be - explosionPiece) / (10 / _0xc7c517); - if (explosionPiece < 0) { - explosionPiece = 0; - } - this._cameraY = explosionPiece; - } - } - _quantizeDelta(_0x654f39) { - const speed = window.speedHack || 1; - let _0x578d1b = (_0x654f39 * speed) / 1000 + this._deltaBuffer; - let _0x53e02e = Math.round(_0x578d1b / u); - if (_0x53e02e < 0) { - _0x53e02e = 0; - } - if (_0x53e02e > 60) { - _0x53e02e = 60; - } - let _0xd8019e = _0x53e02e * u; - this._deltaBuffer = _0x578d1b - _0xd8019e; - return _0xd8019e * 60; - } - update(_0x54fa47, deltaTime) { - if (window.isEditor) { - if (this._editorPlaytestActive && !this._editorPlaytestPaused) { - this._levelEditor._updateEditorPlaytest(deltaTime); - this._levelEditor._updateEditorGrid(); - this._levelEditor._updateEditorTimeline(); - return; - } - - if (window.isEditorPause) return; - const pointer = this.input.activePointer; - this._hitObjects = this.input.hitTestPointer(pointer); - this._levelEditor._handleEditorCamera(deltaTime); - this._levelEditor._updateEditorGrid(); - if (pointer.isDown && !this._isDraggingSlider) { - if (this._isSwipeEnabled) { - if (this._editorTab !== "edit") { - if (this._hitObjects.length !== 0) return; - const currentGridX = Math.floor((pointer.x + this._cameraX) / 60) * 60; - const currentGridY = Math.floor((pointer.y + this._cameraY + 20) / 60) * 60; - - if (currentGridX !== this._lastSwipeGridX || currentGridY !== this._lastSwipeGridY) { - this._levelEditor._editorAction(); - this._lastSwipeGridX = currentGridX; - this._lastSwipeGridY = currentGridY; - } - } - } else { - if (!this._isDragging && this._hitObjects.length !== 0) return; - const dragX = pointer.x - this._clickStartPos.x; - const dragY = pointer.y - this._clickStartPos.y; - const dragDistance = Math.sqrt(dragX * dragX + dragY * dragY); - if (dragDistance > 10) { - this._isDragging = true; - this._cameraX = this._cameraStartX - dragX; - this._cameraY = this._cameraStartY - dragY; - } - } - } - this._levelEditor._updateEditorTimeline(); - if (this._editorPlaytestActive && this._editorPlaytestPaused) { - this._levelEditor._refreshEditorPlaytestGlowVisibility(); - this._levelEditor._syncEditorPlaytestPlayerVisual(deltaTime / 1000); - } - return; - } - - let rawPercent = (this._playerWorldX / this._level.endXPos) * 100; - rawPercent = Math.min(100, Math.max(0, rawPercent)); - let displayValue; - if (this._levelWon) { - const p = this._interpolatedPercent || 0; - if (window.percentageDecimals) { - displayValue = p.toFixed(2) + "%"; - } else { - displayValue = Math.floor(p) + "%"; - } - } else if (window.percentageDecimals) { - displayValue = rawPercent.toFixed(2) + "%"; - } else { - displayValue = Math.floor(rawPercent) + "%"; - } - this._percentageLabel.setText(displayValue); - this._percentageLabel.setVisible(window.showPercentage && !this._menuActive); - this._startPosGui.setVisible(window.startPosSwitcher && !this._menuActive); - this._noclipIndicator.setVisible(window.noClip && !this._menuActive); - this._accuracyIndicator.setVisible(window.noClip && window.noClipAccuracy && !this._menuActive); - this._deathsIndicator.setVisible(window.noClip && window.noClipAccuracy && !this._menuActive); - this._accuracyIndicator.setText(`${this._player.noclipStats.accuracy.toFixed(2)}%`); - this._deathsIndicator.setText(`${this._player.noclipStats.deaths} Deaths`); - - this._cpsIndicator.setVisible(window.showCPS && !this._menuActive); - if (this._clickHistory && this._clickHistory.length > 0) { - this._clickHistory = this._clickHistory.filter(timestamp => this.time.now - timestamp <= 1000); - this._cpsIndicator.setText(`${this._clickHistory.length} CPS`); - } else { - this._cpsIndicator.setText("0 CPS"); - } - if (this._state.upKeyDown){ - this._cpsIndicator.setTint(0x00ff00); - } else{ - this._cpsIndicator.setTint(0xffffff); - } - this._cpsIndicator.setPosition(10, 10 + (window.noClip * 20) + (window.noClip && window.noClipAccuracy * 40)); - - this._bottedIndicator.setVisible(this._macroBot?.playing); - this._bottedIndicator.setPosition(10, 10 + (window.noClip * 20) + (window.noClip && window.noClipAccuracy * 40) + (window.showCPS * 20)); - if (this._macroBtn){ - this._macroBtn.setVisible(window.macroBot); - } - - this._fpsAccum += deltaTime; - this._fpsFrames++; - if (this._fpsAccum >= 250) { - this._fpsText.setText(Math.round(this._fpsFrames * 1000 / this._fpsAccum)); - this._fpsAccum = 0; - this._fpsFrames = 0; - } - if (this._paused) { - if (!this._updateLogPopup && (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown) && !this._spaceWasDown && !this._settingsPopup) { - setTimeout(() => { - this._resumeGame(); - }, 75); - } - this._deltaBuffer = 0; - return; - } - if (this._menuActive) { - const _anyOverlayOpen = this._iconOverlay || this._creatorOverlay || this._searchOverlay || - this._onlineLevelsOverlay || this._settingsLayerOverlay || this._settingsPopup || - this._infoPopup || this._newgroundsPopup || this._statsLayerOverlay || this._updateLogPopup; - if (!_anyOverlayOpen && (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown) && !this._spaceWasDown) { - if (this._creatorMenuOpen) return; - this._spaceWasDown = true; - if (this._levelSelectOverlay) { - if (this._levelSelectIsComingSoonPage) { - return; - } - this._creatorMenuOpen; - this.input.enabled = false; - - const lvl = window.currentlevel; - const songID = lvl[0]; - const levelFileName = lvl[2]; - const songFileName = lvl[4] ? lvl[4] : lvl[1].replaceAll(" ", ""); - - const loadingText = this.add.bitmapText( - screenWidth / 2, screenHeight / 2, "goldFont", "Downloading Level Assets...", 20 - ).setOrigin(0.5).setDepth(200); - - this.load.text(levelFileName, "assets/levels/" + levelFileName.split("_")[1] + ".txt"); - this.load.audio(songID, "assets/music/" + songFileName + ".mp3"); - - this.load.once("complete", () => { - loadingText.destroy(); - this._audio.playEffect("playSound_01", { volume: 1 }); - this._closeLevelSelect(true); - this._audio.stopMusic(); - this.input.enabled = true; - this.game.registry.set("autoStartGame", true); - this.scene.restart(); - }); - - this.load.start(); - return; - } - this._openLevelSelect(); - return; - } - const _arrowLeft = this._leftKey.isDown || this._aKey.isDown; - const _arrowRight = this._rightKey.isDown || this._dKey.isDown; - if (!_anyOverlayOpen && (_arrowLeft || _arrowRight) && !this._arrowWasDown) { - if (this._levelSelectOverlay) { - if (_arrowLeft) window.leftbuttoncallback(); - else window.rightbuttoncallback(); - } - } - this._arrowWasDown = _arrowLeft || _arrowRight; - this._spaceWasDown = this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown; - const menuDelta = Math.min(deltaTime / 1000 * 60, 2); - const menuSpeed = 0.85; - this._menuCameraX = (this._menuCameraX || 0) + menuDelta * playerSpeed * d * menuSpeed; - const _0x38afac = this._cameraX; - this._cameraX = this._menuCameraX; - this._updateBackground(); - this._cameraX = _0x38afac; - this._prevCameraX = this._menuCameraX; - this._cameraXRef._v = this._menuCameraX; - this._level.stepGroundAnimation(deltaTime / 1000); - this._level.updateGroundTiles(this._cameraY); - if (this._menuRainbowTime === undefined) this._menuRainbowTime = 0; - this._menuRainbowTime += deltaTime / 1000; - const _rainbowHue = (this._menuRainbowTime * 15) % 360; - const _rainbowHex = Phaser.Display.Color.HSVToRGB(_rainbowHue / 360, 0.85, 1.0).color; - const _groundHex = Phaser.Display.Color.HSVToRGB(_rainbowHue / 360, 0.85, 1.0).color; - this._bg.setTint(_rainbowHex); - this._level.setGroundColor(_groundHex); - this._level.setGround2Color?.(_groundHex); - return; - } - if (this._slideIn) { - const slideDelta = this._quantizeDelta(deltaTime); - this._playerWorldX += slideDelta * playerSpeed * d; - const slideGroundSpeed = 0.25; - this._slideGroundX = (this._slideGroundX || this._cameraX) + slideDelta * playerSpeed * d * slideGroundSpeed; - this._cameraXRef._v = this._slideGroundX; - const slidePlayerScreenX = this._playerWorldX - this._cameraX; - this._player.updateGroundRotation(slideDelta * d); - this._player.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(slidePlayerScreenX)); - this._level.additiveContainer.x = -this._cameraX; - this._level.additiveContainer.y = this._cameraY; - this._level.container.x = -this._cameraX; - this._level.container.y = this._cameraY; - this._level.topContainer.x = -this._cameraX; - this._level.topContainer.y = this._cameraY; - this._level.updateVisibility(this._cameraX); - this._level.updateObjectDebugIds(); - this._updateBackground(); - this._level.stepGroundAnimation(deltaTime / 1000); - this._level.updateGroundTiles(this._cameraY); - this._applyMirrorEffect(); - if (this._playerWorldX >= 0) { - this._slideIn = false; - this._deltaBuffer = 0; - this._playerWorldX = 0; - this._cameraX = this._playerWorldX - centerX; - this._cameraXRef._v = this._cameraX; - const _0x490749 = this._cameraX - this._slideGroundX; - this._level.shiftGroundTiles(_0x490749); - if (this._firstPlay) { - this._firstPlay = false; - this._audio.startMusic(); - } - this._pauseBtn.setVisible(true).setAlpha(0); - this.tweens.add({ - targets: this._pauseBtn, - alpha: 75 / 255, - duration: 500 - }); - if (this._practiceModeBarContainer) { - this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); - } - } - return; - } - this._applyJumpInput = () => { - const jumpHeld = this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown; - if (!this._updateLogPopup && jumpHeld && !this._spaceWasDown) { - this._pushButton(); - } else if (!jumpHeld && this._spaceWasDown) { - this._releaseButton(); - } - this._spaceWasDown = jumpHeld; - }; - - const objectsUnderPointer = this.input.manager.hitTest( - this.input.activePointer, - this._startPosGui.list, - this.cameras.main - ); - const isOverUI = objectsUnderPointer.length > 0; - const fromClick = this.input.activePointer.isDown; - const cancelInput = isOverUI && fromClick; - - if (!!this.input.activePointer.isDown && !this._state.upKeyDown && !this._state.isDead) { - this._state.upKeyDown = true; - this._state.queuedHold = true; - this._state._orbActivationConsumedForPress = false; - } - if (cancelInput) { - this._state.upKeyDown = false; - this._state.upKeyPressed = false; - this._state.queuedHold = false; - this._state._orbActivationConsumedForPress = false; - } - this._level.updateEndPortalY(this._cameraY, this._state.isFlying || this._state.isWave || this._state.isUfo || this._state.isSpider); - if (!this._levelWon && !this._state.isDead && this._level.endXPos > 0) { - const _0x448396 = 600; - if (this._playerWorldX >= this._level.endXPos - _0x448396) { - this._levelWon = true; - this._endPortalGameY = this._level._endPortalGameY || 240; - this._triggerEndPortal(); - } - } - if (this._levelWon) { - this._deltaBuffer = 0; - if (this._endCamTween) { - const visMaxSection = this._endCamTween; - this._cameraX = visMaxSection.fromX + (visMaxSection.toX - visMaxSection.fromX) * visMaxSection.p; - this._cameraY = visMaxSection.fromY + (visMaxSection.toY - visMaxSection.fromY) * visMaxSection.p; - } - this._cameraXRef._v = this._cameraX; - this._level.additiveContainer.x = -this._cameraX; - this._level.additiveContainer.y = this._cameraY; - this._level.container.x = -this._cameraX; - this._level.container.y = this._cameraY; - this._level.topContainer.x = -this._cameraX; - this._level.topContainer.y = this._cameraY; - this._updateBackground(); - this._level.stepGroundAnimation(deltaTime / 1000); - this._level.updateGroundTiles(this._cameraY); - this._applyMirrorEffect(); - return; - } - if (this._state.isDead) { - if (!this._deathSoundPlayed) { - if (!this._audio._shouldUsePracticeSong()) { - this._audio.stopMusic(); - } - this._audio.playEffect("explode_11", { - volume: 0.65 * this._sfxVolume - }); - this._deathSoundPlayed = true; - this._totalDeaths++; - localStorage.setItem("gd_totalDeaths", this._totalDeaths); - } - if (!this._newBestShown) { - this._newBestShown = true; - let _0x435587 = this._level.endXPos || 6000; - let _0x169d53 = this._playerWorldX; - this._lastPercent = Math.min(99, Math.max(0, Math.floor(_0x169d53 / _0x435587 * 100))); - if (this._lastPercent > this._bestPercent && !this._practicedMode.practiceMode) { - this._bestPercent = this._lastPercent; - localStorage.setItem("bestPercent_" + (window.currentlevel[2] || "level_1"), this._bestPercent); - this._hadNewBest = true; - this._showNewBest(); - } - if (this._practicedMode.practiceMode) { - const pracKey = "practiceBestPercent_" + (window.currentlevel[2] || "level_1"); - const prevPracticeBest = parseFloat(localStorage.getItem(pracKey) || "0"); - if (this._lastPercent > prevPracticeBest) { - localStorage.setItem(pracKey, this._lastPercent); - this._practiceBestPercent = this._lastPercent; - if (this._updatePracticeHUDBar) this._updatePracticeHUDBar(); - } - } - } - this._player?.updateExplosionPieces?.(deltaTime); - if (this._isDual) { - this._player2?.updateExplosionPieces?.(deltaTime); - } - if (this._player?._hitboxGraphics) { - if (window.showHitboxes || window.hitboxesOnDeath) { - this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); - } else { - this._player._hitboxGraphics.clear(); - } - } - if (this._isDual && this._player2?._hitboxGraphics) { - if (window.showHitboxes || window.hitboxesOnDeath) { - this._player2.drawHitboxes(this._player2._hitboxGraphics, this._cameraX, this._cameraY); - } else { - this._player2._hitboxGraphics.clear(); - } - } - this._deathTimer += deltaTime; - let _0x237728 = this._hadNewBest ? 1400 : 1000; - if (this._deathTimer > _0x237728) { - if (this._practicedMode.practiceMode) { - this._respawnFromCheckpoint(); - } else { - this._restartLevel(); - } - } - return; - } - this._playTime += deltaTime / 1000; - this._audio.update(deltaTime / 1000); - - window._animTimer += deltaTime; - for (let _as of window._animatedSprites) { - if (window._animTimer - (_as._lastAnimSwap || 0) >= _as._animInterval) { - _as._lastAnimSwap = window._animTimer; - _as._animIdx = (_as._animIdx + 1) % _as._animFrames.length; - let _fr = getAtlasFrame(_as._animScene, _as._animFrames[_as._animIdx]); - if (_fr) { - try { - _as.setTexture(_fr.atlas, _fr.frame); - } catch(e){} - } - } - } - if (this._level && this._level._sawSprites) { - const sawRotation = deltaTime * 0.003; - for (let _saw of this._level._sawSprites) { - if (_saw && _saw.active) _saw.rotation += sawRotation; - } - } - this._level.updateAudioScale(this._audio.getMeteringValue()); - if (!this._orbGfx) { - this._orbGfx = this.add.graphics().setDepth(54).setBlendMode(S); - } - this._orbParticleAngle = ((this._orbParticleAngle || 0) + deltaTime * 0.004) % (Math.PI * 2); - this._orbGfxTimer = (this._orbGfxTimer || 0) + deltaTime; - if (this._orbGfxTimer > 33) { - this._orbGfxTimer = 0; - this._orbGfx.clear(); - if (this._level && this._level._orbSprites && this._level.container) { - try { - let _drawn = 0; - const _orbTypeColorMap = { - 36: 0xfffb57, - 84: 0x58ffff, - 141: 0xff52f0, - 444: 0xff00d2, - 1022: 0x63ff5f, - 1330: 0xffffff, - 1333: 0xff6326, - 1594: 0x6cff6b, - 1704: 0x04ff04, - 1751: 0xff00d2 - }; - for (let _oSpr of this._level._orbSprites) { - if (_drawn >= 4) break; - if (!_oSpr || !_oSpr.visible || !_oSpr.active || !_oSpr.scene) continue; - const _sx = _oSpr.x + this._level.container.x; - const _sy = _oSpr.y + this._level.container.y; - if (_sx < -40 || _sx > screenWidth + 40 || _sy < -40 || _sy > screenHeight + 40) continue; - _drawn++; - const _orbTypeTint = _orbTypeColorMap[_oSpr._orbId]; - for (let _pi = 0; _pi < 5; _pi++) { - const _orbitSpeed = 0.7 + (_pi % 3) * 0.35; - const _orbitR = 34 + (_pi * 5 % 17); - const _ang = this._orbParticleAngle * _orbitSpeed + (_pi * Math.PI * 2 / 5); - const _px = _sx + Math.cos(_ang) * _orbitR; - const _py = _sy + Math.sin(_ang) * (_orbitR * 0.85); - const _size = (window.orbParticleSize || 3.5) + (_pi % 3) * 1.0; - const _alpha = 0.5 + (_pi % 4) * 0.12; - this._orbGfx.fillStyle(_orbTypeTint, _alpha); - this._orbGfx.fillRect(_px - _size, _py - _size, _size * 2, _size * 2); - } - } - } catch(e) {} - } - } - let quantizedDelta = this._quantizeDelta(deltaTime); - let subSteps = quantizedDelta > 0 ? Math.max(1, Math.round(quantizedDelta * 4)) : 0; - if (subSteps > 60) { - subSteps = 60; - } - let subStepDelta = subSteps > 0 ? quantizedDelta / subSteps : 0; - let verticalDelta = subStepDelta * d; - let horizontalDelta = subStepDelta * playerSpeed * d; - const initialY = this._state.y; - const initialY2 = this._state2.y; - for (let i = 0; i < subSteps; i++) { - this._state.lastY = this._state.y; - this._physicsFrame++; - this._applyJumpInput(); - if (this._macroBot?.playing) { - this._macroBot.step(this._physicsFrame); - } - const _dualInputState = { - upKeyDown: this._state.upKeyDown, - upKeyPressed: this._state.upKeyPressed, - queuedHold: this._state.queuedHold, - orbActivationConsumedForPress: !!this._state._orbActivationConsumedForPress - }; - const _primaryGravityBefore = !!this._state.gravityFlipped; - const _primarySharedBefore = this._getDualSharedSignature(this._state); - this._player.updateJump(verticalDelta); - this._state.y += this._state.yVelocity * verticalDelta; - this._player.checkCollisions(this._playerWorldX - centerX); - const _primaryGravityChanged = this._isDual && !!this._state.gravityFlipped !== _primaryGravityBefore; - let _primaryGravitySynced = false; - if (this._isDual && this._getDualSharedSignature(this._state) !== _primarySharedBefore) { - _primaryGravitySynced = this._syncDualGlobalsFromPrimary({ - skipBallInputGravity: _primaryGravityChanged && this._state.isBall && _dualInputState.upKeyPressed, - skipSpiderInputGravity: _primaryGravityChanged && this._state.isSpider && _dualInputState.upKeyPressed - }); - } - if (this._isDual && this._state.isDead && !this._state2.isDead) { - this._player2.killPlayer(); - } - this._playerWorldX += horizontalDelta; - if (this._isDual && !this._state2.isDead) { - this._copyDualInputFlags(_dualInputState, this._state2); - if (this._shouldSuppressDualGravityAction(this._state2, _primaryGravitySynced)) { - this._state2.upKeyPressed = false; - this._state2.queuedHold = false; - } - this._state2.lastY = this._state2.y; - const _secondarySharedBefore = this._getDualSharedSignature(this._state2); - const _secondaryBallInputGravity = this._state2.isBall && this._state2.upKeyPressed; - const _secondarySpiderInputGravity = this._state2.isSpider && this._state2.upKeyPressed; - this._player2.updateJump(verticalDelta); - if (!this._state2.upKeyPressed) this._state.upKeyPressed = false; - if (!this._state2.queuedHold) this._state.queuedHold = false; - if (this._state2._orbActivationConsumedForPress) this._state._orbActivationConsumedForPress = true; - this._state2.y += this._state2.yVelocity * verticalDelta; - this._player2.checkCollisions(this._playerWorldX - centerX - horizontalDelta); - if (this._isDual && !this._state2.isDead && this._getDualSharedSignature(this._state2) !== _secondarySharedBefore) { - this._syncDualGlobalsFromSecondary({ - skipBallInputGravity: _secondaryBallInputGravity, - skipSpiderInputGravity: _secondarySpiderInputGravity - }); - } - this._resolveDualBallOverlap(); - if (this._isDual && this._state2.isDead && !this._state.isDead) { - this._player.killPlayer(); - } - if (this._isDual && this._state.isDead && !this._state2.isDead) { - this._player2.killPlayer(); - } - if (this._isDual) this._ensureDualFlyBounds(); - } - if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo) { - if (this._state.isBall) { - const ballOnSurface = this._state.onGround || this._state.onCeiling; - this._player.updateBallRoll(horizontalDelta, ballOnSurface); - } else if (this._state.onGround) { - this._player.updateGroundRotation(verticalDelta); - } else if (this._player.rotateActionActive) { - this._player.updateRotateAction(u); - } else if (this._state.isDashing) { - this._player.updateDashRotation(u); - } - } - if (this._isDual && !this._state2.isDead && !this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo) { - if (this._state2.isBall) { - const ball2OnSurface = this._state2.onGround || this._state2.onCeiling; - this._player2.updateBallRoll(horizontalDelta, ball2OnSurface); - } else if (this._state2.onGround) { - this._player2.updateGroundRotation(verticalDelta); - } else if (this._player2.rotateActionActive) { - this._player2.updateRotateAction(u); - } else if (this._state2.isDashing) { - this._player2.updateDashRotation(u); - } - } - - if (!this._player._scene._slideIn){ - if (!this._player._hitboxTrail) this._player._hitboxTrail = []; - if (!this._player.p.isDead) { - const _trailSize = this._player.p.isMini ? 18 : 30; - this._player._hitboxTrail.push({ x: this._playerWorldX, y: this._player.p.y, rotation: this._player._rotation, size: _trailSize, isWave: this._player.p.isWave }); - if (this._player._hitboxTrail.length > 180) this._player._hitboxTrail.shift(); - } - if (this._isDual && !this._player2.p.isDead) { - if (!this._player2._hitboxTrail) this._player2._hitboxTrail = []; - const _trailSize2 = this._player2.p.isMini ? 18 : 30; - this._player2._hitboxTrail.push({ x: this._playerWorldX, y: this._player2.p.y, rotation: this._player2._rotation, size: _trailSize2, isWave: this._player2.p.isWave }); - if (this._player2._hitboxTrail.length > 180) this._player2._hitboxTrail.shift(); - } - } - } - this._state.lastY = initialY; - if (this._isDual) this._state2.lastY = initialY2; - this._state.ignorePortals = false; - this._state2.ignorePortals = false; - if (!this._endCameraOverride) { - const cameraOffsetX = this._playerWorldX - centerX; - if (this._level.endXPos > 0) { - const maxCameraX = this._level.endXPos - screenWidth; - if (cameraOffsetX >= maxCameraX - 200) { - this._endCameraOverride = true; - this._cameraX = cameraOffsetX; - const endCameraY = -140 + (this._level._endPortalGameY || 240); - const easingPower = 1.8; - const easeInOutCubic = t => t < 0.5 ? Math.pow(t * 2, easingPower) / 2 : 1 - Math.pow((1 - t) * 2, easingPower) / 2; - this._endCamTween = { - p: 0, - fromX: this._cameraX, - toX: maxCameraX, - fromY: this._cameraY, - toY: endCameraY - }; - this.tweens.add({ - targets: this._endCamTween, - p: 1, - duration: 1200, - ease: easeInOutCubic - }); - } else { - this._cameraX = cameraOffsetX; - } - } else { - this._cameraX = cameraOffsetX; - } - } - if (this._endCameraOverride && this._endCamTween) { - const tween = this._endCamTween; - this._cameraX = tween.fromX + (tween.toX - tween.fromX) * tween.p; - this._cameraY = tween.fromY + (tween.toY - tween.fromY) * tween.p; - } - this._cameraXRef._v = this._cameraX; - if (!this._endCameraOverride) { - this._updateCameraY(quantizedDelta); - } - this._level.additiveContainer.x = -this._cameraX; - this._level.additiveContainer.y = this._cameraY; - this._level.container.x = -this._cameraX; - this._level.container.y = this._cameraY; - this._level.topContainer.x = -this._cameraX; - this._level.topContainer.y = this._cameraY; - let playerX = this._playerWorldX; - const applyColorTrigger = (colorTrigger) => { - this._colorManager.triggerColor(colorTrigger.index, colorTrigger.color, colorTrigger.duration); - if (colorTrigger.tintGround) { - this._colorManager.triggerColor(gs, colorTrigger.color, colorTrigger.duration); - } - }; - for (let colorTrigger of this._level.checkColorTriggers(playerX)) { - applyColorTrigger(colorTrigger); - } - if (this._level.checkTouchColorTriggers) { - for (let colorTrigger of this._level.checkTouchColorTriggers(playerX, this._state.y)) { - applyColorTrigger(colorTrigger); - } - if (this._isDual && !this._state2.isDead) { - for (let colorTrigger of this._level.checkTouchColorTriggers(playerX, this._state2.y)) { - applyColorTrigger(colorTrigger); - } - } - } - this._level.checkMoveTriggers(playerX); - this._level.checkSpawnTriggers(playerX); - if (this._level.checkTouchSpawnTriggers) { - this._level.checkTouchSpawnTriggers(playerX, this._state.y); - if (this._isDual && !this._state2.isDead) { - this._level.checkTouchSpawnTriggers(playerX, this._state2.y); - } - } - if (this._level.checkTouchMoveTriggers) { - this._level.checkTouchMoveTriggers(playerX, this._state.y); - if (this._isDual && !this._state2.isDead) { - this._level.checkTouchMoveTriggers(playerX, this._state2.y); - } - } - this._level.stepMoveTriggers(deltaTime / 1000); - this._level.stepSpawnTriggers(deltaTime / 1000, this._colorManager); - this._level.checkAlphaTriggers(playerX); - this._level.stepAlphaTriggers(deltaTime / 1000); - this._level.checkRotateTriggers(playerX); - this._level.stepRotateTriggers(deltaTime / 1000); - this._level.checkPulseTriggers(playerX); - this._level.stepPulseTriggers(deltaTime / 1000, this._colorManager); - this._colorManager.step(deltaTime / 1000); - this._level.applyColorChannels(this._colorManager); - this._bg.setTint(this._colorManager.getHex(fs)); - this._level.setGroundColor(this._colorManager.getHex(gs)); - this._level.setGround2Color?.(this._colorManager.getHex(1009)); - this._level.updateVisibility(this._cameraX); - this._level.updateObjectDebugIds(); - this._level.checkEnterEffectTriggers(playerX); - this._level.applyEnterEffects(this._cameraX); - this._glitterCenterX = this._cameraX + screenWidth / 2; - this._glitterCenterY = T - this._cameraY; - this._updateBackground(); - this._level.stepGroundAnimation(deltaTime / 1000); - this._level.updateGroundTiles(this._cameraY); - if (this._state.isFlying) { - this._player.updateShipRotation(quantizedDelta); - } - if (this._isDual && this._state2.isFlying && !this._state2.isDead) { - this._player2.updateShipRotation(quantizedDelta); - } - const playerScreenX = this._playerWorldX - this._cameraX; - this._player.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(playerScreenX)); - if (this._isDual && !this._state2.isDead) { - this._player2.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(playerScreenX)); - } - this._applyMirrorEffect(); - } - -_applyMirrorEffect() { - const isMirrored = this._state.mirrored; - const containers = [this._level.additiveContainer, this._level.container, this._level.topContainer]; - if (isMirrored) { - for (const c of containers) { - c.scaleX = -1; - c.x = this._cameraX + screenWidth; - } - for (const tile of this._level._groundTiles) { - tile.x = screenWidth - tile.x - this._level._tileW; - tile.setFlipX(true); - } - for (const tile of this._level._ceilingTiles) { - tile.x = screenWidth - tile.x - this._level._tileW; - tile.setFlipX(true); - } - } else { - for (const c of containers) { - if (c.scaleX !== 1) c.scaleX = 1; - } - for (const tile of this._level._groundTiles) { - tile.setFlipX(false); - } - for (const tile of this._level._ceilingTiles) { - tile.setFlipX(false); - } - } - this._bg.setFlipX(isMirrored); - } - _getDualSharedSignature(state) { - if (!state) return "0|0"; - return [ - state.gravityFlipped ? 1 : 0, - state.mirrored ? 1 : 0 - ].join("|"); - } - _getDualModeId(state) { - if (!state) return "cube"; - if (state.isFlying) return "ship"; - if (state.isBall) return "ball"; - if (state.isUfo) return "ufo"; - if (state.isWave) return "wave"; - if (state.isRobot) return "robot"; - if (state.isSpider) return "spider"; - return "cube"; - } - _getGamemodePortalMode(portalType) { - switch (portalType) { - case "portal_cube": - return "cube"; - case "portal_fly": - return "ship"; - case "portal_ball": - return "ball"; - case "portal_wave": - return "wave"; - case "portal_ufo": - return "ufo"; - case "portal_robot": - return "robot"; - case "portal_spider": - return "spider"; - default: - return null; - } - } - _setPlayerGamemode(player, state, mode, keepVelocity = true) { - if (!player || !state) return; - const currentMode = this._getDualModeId(state); - if (currentMode === mode) { - player.setCubeVisible(mode === "cube" || mode === "ufo"); - player.setShipVisible(mode === "ship"); - player.setBallVisible(mode === "ball"); - player.setWaveVisible(mode === "wave"); - player.setBirdVisible?.(mode === "ufo"); - player.setRobotVisible(mode === "robot"); - player.setSpiderVisible(mode === "spider"); - return; - } - const saved = { - y: state.y, - yVelocity: state.yVelocity, - gravityFlipped: state.gravityFlipped, - upKeyDown: state.upKeyDown, - upKeyPressed: state.upKeyPressed, - queuedHold: state.queuedHold, - orbActivationConsumedForPress: !!state._orbActivationConsumedForPress, - mirrored: state.mirrored, - isMini: state.isMini - }; - switch (mode) { - case "ship": - player.enterShipMode({ y: saved.y, portalY: saved.y }, true); - break; - case "ball": - player.enterBallMode({ y: saved.y, portalY: saved.y }); - break; - case "ufo": - player.enterUfoMode({ y: saved.y, portalY: saved.y }, true); - break; - case "wave": - player.enterWaveMode({ y: saved.y, portalY: saved.y }); - break; - case "robot": - player.enterRobotMode({ y: saved.y, portalY: saved.y }); - break; - case "spider": - player.enterSpiderMode({ y: saved.y, portalY: saved.y }); - break; - default: - player.exitShipMode(); - player.exitBallMode(); - player.exitUfoMode(); - player.exitWaveMode(); - player.exitRobotMode(); - player.exitSpiderMode(); - state.isFlying = false; - state.isBall = false; - state.isUfo = false; - state.isWave = false; - state.isRobot = false; - state.isSpider = false; - player.setShipVisible(false); - player.setBallVisible(false); - player.setWaveVisible(false); - player.setBirdVisible?.(false); - player.setRobotVisible(false); - player.setSpiderVisible(false); - player.setCubeVisible(true); - break; - } - state.y = saved.y; - if (keepVelocity && Number.isFinite(saved.yVelocity)) state.yVelocity = saved.yVelocity; - state.gravityFlipped = saved.gravityFlipped; - state.upKeyDown = saved.upKeyDown; - state.upKeyPressed = saved.upKeyPressed; - state.queuedHold = saved.queuedHold; - state._orbActivationConsumedForPress = !!saved.orbActivationConsumedForPress; - state.mirrored = saved.mirrored; - state.isMini = saved.isMini; - } - _getInitialDualPortalMode() { - if (!this._level || !this._player2 || !this._state2) return null; - - const worldX = Number(this._playerWorldX); - const worldY = Number(this._state2.y); - if (!Number.isFinite(worldX) || !Number.isFinite(worldY)) return null; - - const halfSize = this._state2.isWave - ? (this._state2.isMini ? 6 : 9) - : (this._state2.isMini ? 18 : 30); - - const previousWorldXRaw = Number(this._player?._lastCollisionWorldX); - const previousWorldYRaw = Number(this._player?._lastCollisionWorldY); - const previousWorldX = Number.isFinite(previousWorldXRaw) ? previousWorldXRaw : worldX; - const previousWorldY = Number.isFinite(previousWorldYRaw) - ? previousWorldYRaw - : (Number.isFinite(Number(this._state?.lastY)) ? Number(this._state.lastY) : worldY); - - const nearbyObjects = this._level.getNearbySectionObjects?.(worldX) || []; - const previousNearbyObjects = previousWorldX !== worldX - ? (this._level.getNearbySectionObjects?.(previousWorldX) || []) - : []; - const portalObjects = [...new Set([...nearbyObjects, ...previousNearbyObjects])]; - - let portalMode = null; - - for (const gameObj of portalObjects) { - const mode = this._getGamemodePortalMode(gameObj?.type); - if (!mode) continue; - - let touching = false; - - if (gameObj.hitbox_radius !== undefined && gameObj.hitbox_radius !== null) { - const radius = gameObj.hitbox_radius + halfSize; - const dx = worldX - gameObj.x; - const dy = worldY - gameObj.y; - touching = (dx * dx + dy * dy) <= radius * radius; - - if (!touching && (previousWorldX !== worldX || previousWorldY !== worldY)) { - const prevDx = previousWorldX - gameObj.x; - const prevDy = previousWorldY - gameObj.y; - touching = (prevDx * prevDx + prevDy * prevDy) <= radius * radius; - - if (!touching) { - const steps = Math.min( - 12, - Math.max(2, Math.ceil( - Math.max(Math.abs(worldX - previousWorldX), Math.abs(worldY - previousWorldY)) / Math.max(1, halfSize) - )) - ); - - for (let i = 1; i < steps; i++) { - const t = i / steps; - const sampleX = previousWorldX + (worldX - previousWorldX) * t; - const sampleY = previousWorldY + (worldY - previousWorldY) * t; - const sampleDx = sampleX - gameObj.x; - const sampleDy = sampleY - gameObj.y; - - if ((sampleDx * sampleDx + sampleDy * sampleDy) <= radius * radius) { - touching = true; - break; - } - } - } - } - } else if (typeof this._player2._isPlayerTouchingPortalHitbox === "function") { - touching = this._player2._isPlayerTouchingPortalHitbox( - gameObj, - worldX, - worldY, - halfSize, - previousWorldX, - previousWorldY - ); - } - - if (touching) portalMode = mode; - } - - return portalMode; - } - _copyDualInputFlags(fromState, toState) { - if (!fromState || !toState) return; - toState.upKeyDown = fromState.upKeyDown; - toState.upKeyPressed = fromState.upKeyPressed; - toState.queuedHold = fromState.queuedHold; - const fromConsumed = !!(fromState._orbActivationConsumedForPress ?? fromState.orbActivationConsumedForPress); - toState._orbActivationConsumedForPress = !!fromState.upKeyDown && (!!toState._orbActivationConsumedForPress || fromConsumed); - } - _shouldSuppressDualGravityAction(state, gravityAlreadySynced) { - return !!(gravityAlreadySynced && state && state.isBall && state.upKeyPressed); - } - _shouldSkipDualBallGravitySync(fromState, toState, options = {}) { - if (!fromState?.isBall || !toState) return false; - if (options.forceGravitySync) return false; - if (options.skipBallInputGravity) return true; - return !(toState.onGround || toState.onCeiling || toState.canJump); - } - _shouldSkipDualSpiderInputGravitySync(fromState, options = {}) { - if (!fromState?.isSpider) return false; - if (options.forceGravitySync) return false; - return !!options.skipSpiderInputGravity; - } - _isDualBallOnSurface(state) { - return !!(state && (state.onGround || state.onCeiling || state.canJump)); - } - _areDualBallsOverlapping() { - if (!this._isDual || !this._state || !this._state2) return false; - if (this._state.isDead || this._state2.isDead) return false; - if (!this._state.isBall || !this._state2.isBall) return false; - const size1 = this._state.isMini ? 18 : 30; - const size2 = this._state2.isMini ? 18 : 30; - return Math.abs(this._state.y - this._state2.y) < (size1 + size2); - } - _flipDualBallForOverlap(player, state) { - if (!player || !state || !state.isBall) return false; - const flipMod = state.gravityFlipped ? -1 : 1; - state.yVelocity = flipMod * 22.360064 * (state.isMini ? 0.8 : 1); - player.flipGravity(!state.gravityFlipped); - state.onGround = false; - state.onCeiling = false; - state.canJump = false; - state.isJumping = false; - state.yVelocity *= 0.6; - return true; - } - _resolveDualBallOverlap() { - if (!this._areDualBallsOverlapping()) { - this._dualBallOverlapResolved = false; - this._dualBallSpawnGravityLock = false; - return false; - } - if (this._dualBallSpawnGravityLock) { - this._state2.gravityFlipped = !this._state.gravityFlipped; - this._dualBallOverlapResolved = true; - return false; - } - if (this._dualBallOverlapResolved) return false; - const primaryOnSurface = this._isDualBallOnSurface(this._state); - const secondaryOnSurface = this._isDualBallOnSurface(this._state2); - if (!primaryOnSurface && !secondaryOnSurface) return false; - - let flipped = false; - if (primaryOnSurface && !secondaryOnSurface) { - flipped = this._flipDualBallForOverlap(this._player2, this._state2); - } else if (secondaryOnSurface && !primaryOnSurface) { - flipped = this._flipDualBallForOverlap(this._player, this._state); - } else if (primaryOnSurface && secondaryOnSurface) { - flipped = this._flipDualBallForOverlap(this._player2, this._state2); - } - if (flipped) this._dualBallOverlapResolved = true; - return flipped; - } - _copyInitialDualModeFlags(fromState, toState) { - if (!fromState || !toState) return; - toState.isMini = fromState.isMini; - toState.mirrored = fromState.mirrored; - toState.gravityFlipped = !fromState.gravityFlipped; - this._copyDualInputFlags(fromState, toState); - } - _syncDualGlobalsFromPrimary(options = {}) { - if (!this._isDual || !this._state || !this._state2 || this._state2.isDead) return false; - let gravitySynced = false; - if (!this._shouldSkipDualBallGravitySync(this._state, this._state2, options) && !this._shouldSkipDualSpiderInputGravitySync(this._state, options)) { - const nextGravity = !this._state.gravityFlipped; - this._state2.gravityFlipped = nextGravity; - gravitySynced = true; - } - this._state2.mirrored = this._state.mirrored; - this._ensureDualFlyBounds(); - return gravitySynced; - } - _syncDualGlobalsFromSecondary(options = {}) { - if (!this._isDual || !this._state || !this._state2 || this._state.isDead || this._state2.isDead) return false; - let gravitySynced = false; - if (!this._shouldSkipDualBallGravitySync(this._state2, this._state, options) && !this._shouldSkipDualSpiderInputGravitySync(this._state2, options)) { - const nextGravity = !this._state2.gravityFlipped; - this._state.gravityFlipped = nextGravity; - gravitySynced = true; - } - this._state.mirrored = this._state2.mirrored; - this._ensureDualFlyBounds(); - return gravitySynced; - } - _ensureDualFlyBounds(centerY = null) { - if (!this._isDual || !this._level) return; - const span = Number(typeof f !== "undefined" ? f : 480) || 480; - const floorY = this._level._flyFloorY; - const ceilingY = this._level._flyCeilingY; - const currentSpan = Number.isFinite(Number(floorY)) && Number.isFinite(Number(ceilingY)) ? Number(ceilingY) - Number(floorY) : null; - if (currentSpan === null || Math.abs(currentSpan - span) > 0.01 || !this._level._flyGroundActive) { - const y = Number.isFinite(Number(centerY)) ? Number(centerY) : (Number.isFinite(Number(this._state?.y)) ? Number(this._state.y) : 30); - this._level.setFlyMode(true, y, span, false); - } - } - _refreshFlyBoundsAfterDual() { - if (!this._level) return; - if (this._state.isFlying || this._state.isWave || this._state.isUfo) { - this._level.setFlyMode(true, this._state.y, f, false); - } else if (this._state.isBall) { - this._level.setFlyMode(true, this._state.y, f - a * 2, false); - } else if (this._state.isSpider) { - const spiderBlockSize = typeof a !== "undefined" ? a : 30; - const spiderBaseHeight = typeof f !== "undefined" ? f : 480; - const spiderFlyHeight = Math.max(spiderBlockSize, spiderBaseHeight - spiderBlockSize); - this._level.setFlyMode(true, this._state.y, spiderFlyHeight, false, spiderFlyHeight); - } else { - this._level.setFlyMode(false, 0); - } - } - _killDualPlayers() { - if (this._state && !this._state.isDead) this._player.killPlayer(); - if (this._isDual && this._state2 && !this._state2.isDead) this._player2.killPlayer(); - } - - _getMirrorXOffset(xOffset) { - return this._state.mirrored ? screenWidth - xOffset : xOffset; - } - _enableDualMode() { - if (this._isDual) return; - this._isDual = true; - this._dualBallSpawnGravityLock = false; - this._dualBallOverlapResolved = false; - this._state2.reset(); - this._state2.isDead = false; - this._state2.yVelocity = this._state.yVelocity; - this._copyInitialDualModeFlags(this._state, this._state2); - this._ensureDualFlyBounds(this._state.y); - const primaryY = Number.isFinite(Number(this._state.y)) ? Number(this._state.y) : 30; - this._state2.y = primaryY; - this._state2.lastY = primaryY; - this._state2.lastGroundPosY = primaryY; - this._state2.onGround = false; - this._state2.onCeiling = false; - this._state2.canJump = false; - this._state2.isJumping = false; - this._player2.reset(); - this._player2.setInvertedColors?.(true); - this._setPlayerGamemode(this._player2, this._state2, this._getDualModeId(this._state), true); - this._copyInitialDualModeFlags(this._state, this._state2); - const initialPortalMode = this._getInitialDualPortalMode(); - if (initialPortalMode) this._setPlayerGamemode(this._player2, this._state2, initialPortalMode, true); - if (this._state.isBall && this._state2.isBall) { - this._state2.gravityFlipped = !this._state.gravityFlipped; - this._dualBallOverlapResolved = true; - this._dualBallSpawnGravityLock = true; - } - this._ensureDualFlyBounds(this._state.y); - if (this._player2 && this._player2._hitboxTrail) this._player2._hitboxTrail = []; - if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); - } - _disableDualMode() { - if (!this._isDual) return; - this._isDual = false; - this._dualBallOverlapResolved = false; - this._dualBallSpawnGravityLock = false; - this._state2.isDead = true; - this._state2.upKeyDown = false; - this._state2.upKeyPressed = false; - this._state2.queuedHold = false; - this._player2.setCubeVisible(false); - this._player2.setShipVisible(false); - this._player2.setBallVisible(false); - this._player2.setWaveVisible(false); - this._player2.setBirdVisible?.(false); - this._player2.setRobotVisible(false); - this._player2.setSpiderVisible(false); - if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); - if (this._player2 && this._player2._hitboxTrail) this._player2._hitboxTrail = []; - this._refreshFlyBoundsAfterDual(); - } - _showNewBest() { - let _0x9f2437 = screenWidth / 2; - let _0x12bde3 = this.add.image(0, 0, "GJ_WebSheet", "GJ_newBest_001.png").setOrigin(0.5, 1); - let _0x544c9c = this.add.bitmapText(0, 2, "bigFont", this._lastPercent + "%", 65).setOrigin(0.5, 0).setScale(1.1); - let _0x326cb9 = this.add.container(_0x9f2437, 300, [_0x12bde3, _0x544c9c]).setScrollFactor(0).setDepth(60).setScale(0.01); - this.tweens.add({ - targets: _0x326cb9, - scale: 1, - duration: 400, - ease: "Elastic.Out", - easeParams: [1, 0.6], - onComplete: () => { - this.tweens.add({ - targets: _0x326cb9, - scale: 0.01, - duration: 200, - delay: 700, - ease: "Quad.In", - onComplete: () => { - _0x326cb9.setVisible(false); - _0x326cb9.destroy(); - } - }); - } - }); - } - - _triggerEndPortal() { - if (this._isDual && this._player2 && this._state2 && !this._state2.isDead) { - this._player2.playEndAnimation(this._level.endXPos, () => {}, this._endPortalGameY); - } - this._player.playEndAnimation(this._level.endXPos, () => this._levelComplete(), this._endPortalGameY); - } - _levelComplete() { - if (!this._practicedMode.practiceMode) { - this._bestPercent = 100; - localStorage.setItem("bestPercent_" + (window.currentlevel[2] || "level_1"), 100); - const completedKey = "gd_completedSet"; - let completedSet; - try { completedSet = JSON.parse(localStorage.getItem(completedKey) || "[]"); } catch(e) { completedSet = []; } - const levelId = window.currentlevel[2] || "level_1"; - if (!completedSet.includes(levelId)) { - completedSet.push(levelId); - localStorage.setItem(completedKey, JSON.stringify(completedSet)); - window._completedLevels = completedSet.length; - localStorage.setItem("gd_completedLevels", window._completedLevels); - } - } else { - this._practiceBestPercent = 100; - localStorage.setItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1"), 100); - if (this._updatePracticeHUDBar) this._updatePracticeHUDBar(); - } - - const _0x356782 = this._level.endXPos - this._cameraX; - const _0x2d967b = b(this._endPortalGameY) + this._cameraY; - for (let _0x481f7c = 0; _0x481f7c < 5; _0x481f7c++) { - this.time.delayedCall(_0x481f7c * 50, () => circleEffect(this, _0x356782, _0x2d967b, 10, screenWidth, 500, false, true, window.mainColor)); - } - circleEffect(this, _0x356782, _0x2d967b, 10, 1000, 500, true, false, window.mainColor); - this._showCompleteEffect(); - } - _showCompleteEffect() { - this._audio.fadeOutMusic(1500); - this.sound.play("endStart_02", { - volume: 0.8 * this._sfxVolume - }); - (function (_0x3f5321, _0x8f5267, _0x2f1e2d, _0x4b5e5b) { - const _0x29d856 = 2; - const _0x1b2543 = 8; - const _0x2cc21f = _0x29d856 * 1; - const _0x26b2b1 = _0x29d856 * 30; - const _0x6f49c1 = _0x29d856 * 20; - const _0x232789 = Math.round(Math.sqrt(screenWidth ** 2 + 102400)) + _0x29d856 * 32.5; - const _0x1c105b = 180; - const _0x586720 = 40; - const _0x57b9ff = 195; - const _0x2b6612 = 40; - const _0x5ce50e = 40; - const _0x4da54f = 155 / 255; - const _0x20decf = 100 / 255; - const _0x576e6f = 400; - const _0x487fb1 = -135; - const _0x323ded = 90 / _0x1b2543; - const _0x44369e = Array.from({ - length: _0x1b2543 - }, (_0x18e51d, _0x59ebd4) => _0x487fb1 + _0x59ebd4 * _0x323ded); - for (let _0x59890f = _0x44369e.length - 1; _0x59890f > 0; _0x59890f--) { - const _0x2bf73b = Math.floor(Math.random() * (_0x59890f + 1)); - [_0x44369e[_0x59890f], _0x44369e[_0x2bf73b]] = [_0x44369e[_0x2bf73b], _0x44369e[_0x59890f]]; - } - let _0x594d69 = 0; - const _0x116c8c = []; - for (let _0x104cbb = 0; _0x104cbb < _0x1b2543; _0x104cbb++) { - const _0x1a79fc = _0x104cbb * _0x57b9ff + _0x2b6612 + _0x5ce50e * (Math.random() * 2 - 1); - const _0x6eb03a = _0x26b2b1 + _0x6f49c1 * (Math.random() * 2 - 1); - const _0x2e9531 = _0x1c105b + _0x586720 * (Math.random() * 2 - 1); - const _0x28e7b3 = Math.min(1, Math.max(0, _0x4da54f + _0x20decf * (Math.random() * 2 - 1))); - const _0x34147c = _0x44369e[_0x104cbb] + _0x323ded * Math.random() + 180; - const containerY = _0x3f5321.add.graphics().setScrollFactor(0).setDepth(-1).setBlendMode(S).setPosition(_0x8f5267, _0x2f1e2d).setAngle(_0x34147c).setAlpha(_0x28e7b3).setVisible(false); - const _0x496d96 = { - h: 1, - w: _0x2cc21f - }; - _0x3f5321.time.delayedCall(Math.max(0, _0x1a79fc), () => { - containerY.setVisible(true); - _0x3f5321.tweens.add({ - targets: _0x496d96, - h: _0x232789, - w: _0x6eb03a, - duration: _0x2e9531, - ease: "Quad.Out", - onUpdate: () => { - const _0x2db3d7 = _0x2cc21f + (_0x496d96.w - _0x2cc21f) / 4; - containerY.clear(); - containerY.fillStyle(_0x4b5e5b, 1); - containerY.beginPath(); - containerY.moveTo(-_0x2db3d7 / 2, 0); - containerY.lineTo(_0x2db3d7 / 2, 0); - containerY.lineTo(_0x496d96.w / 2, _0x496d96.h); - containerY.lineTo(-_0x496d96.w / 2, _0x496d96.h); - containerY.closePath(); - containerY.fillPath(); - } - }); - }); - if (_0x1a79fc > _0x594d69) { - _0x594d69 = _0x1a79fc; - } - _0x116c8c.push(containerY); - } - _0x3f5321.time.delayedCall(_0x594d69 + _0x576e6f, () => { - for (const _0x15b95e of _0x116c8c) { - const _0x51b5fc = Math.random() * 200; - const _0x3ed1de = 400 + (Math.random() * 2 - 1) * 100; - _0x3f5321.tweens.add({ - targets: _0x15b95e, - alpha: 0, - delay: _0x51b5fc, - duration: _0x3ed1de, - onComplete: () => _0x15b95e.destroy() - }); - } - }); - })(this, this._level.endXPos - this._cameraX + 60, b(this._endPortalGameY) + this._cameraY, window.mainColor); - this.cameras.main.shake(1950, 0.004); - this.time.delayedCall(1950, () => this._showCompleteText()); - } - _showCompleteText() { - const _0x56628c = screenWidth / 2; - const _0x45ab26 = this._practicedMode.practiceMode - ? this.add.image(_0x56628c, 250, "GJ_GameSheet03", "GJ_practiceComplete_001.png").setScrollFactor(0).setDepth(60).setScale(0.01) - : this.add.image(_0x56628c, 250, "GJ_WebSheet", "GJ_levelComplete_001.png").setScrollFactor(0).setDepth(60).setScale(0.01); - this.tweens.add({ - targets: _0x45ab26, - scale: 1.1, - duration: 660, - ease: "Elastic.Out", - easeParams: [1, 0.6], - onComplete: () => { - this.tweens.add({ - targets: _0x45ab26, - scale: 0.01, - duration: 220, - delay: 880, - ease: "Quad.In", - onComplete: () => { - _0x45ab26.setVisible(false); - _0x45ab26.destroy(); - } - }); - } - }); - const _0x2884ff = [window.mainColor, 16777215]; - for (let _0x5f16c8 = 0; _0x5f16c8 < 2; _0x5f16c8++) { - this.add.particles(_0x56628c, 250, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 300, - max: 700 - }, - angle: { - min: 0, - max: 360 - }, - scale: { - start: 0.4, - end: 0.13 - }, - lifespan: { - min: 0, - max: 1000 - }, - quantity: 50, - stopAfter: 200, - blendMode: S, - tint: _0x2884ff[_0x5f16c8], - x: { - min: -800, - max: 800 - }, - y: { - min: -80, - max: 80 - } - }).setScrollFactor(0).setDepth(59); - } - const _0x2eadf2 = this._level.endXPos - this._cameraX; - const _0x380b24 = b(this._endPortalGameY) + this._cameraY; - circleEffect(this, _0x2eadf2, _0x380b24, 10, screenWidth, 800, true, false, window.mainColor); - circleEffect(this, _0x56628c, 250, 10, 1000, 800, true, false, window.mainColor); - for (let _0x579e05 = 0; _0x579e05 < 5; _0x579e05++) { - this.time.delayedCall(_0x579e05 * 50, () => circleEffect(this, _0x2eadf2, _0x380b24, 10, screenWidth, 500, false, true, window.mainColor)); - } - for (let _0x429722 = 0; _0x429722 < 10; _0x429722++) { - const _0xbf7dd0 = _0x429722 * 150 + (Math.random() * 160 - 80); - this.time.delayedCall(Math.max(0, _0xbf7dd0), () => particleEffect(this, window.mainColor, window.secondaryColor)); - } - this.time.delayedCall(1500, () => this._showEndLayer()); - } - _showEndLayer() { - if (this._pauseBtn) { - this.tweens.add({ - targets: this._pauseBtn, - alpha: 0, - duration: 300 - }); - } - const containerX = screenWidth / 2; - const _0x1aa656 = 320; - this._endLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); - this._endLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); - this.tweens.add({ - targets: this._endLayerOverlay, - alpha: 100 / 255, - duration: 1000 - }); - const _0x59b9ab = { - p: 0 - }; - this.tweens.add({ - targets: _0x59b9ab, - p: 1, - duration: 1000, - ease: "Bounce.Out", - onUpdate: () => { - this._endLayerInternal.y = _0x59b9ab.p * 650 - 640; - }, - onComplete: () => this._playStarAward() - }); - const _0x595215 = 712; - const _0x950c8d = 460; - const _0x2a115c = (screenWidth - _0x595215) / 2; - this._endLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0, 180 / 255)); - const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; - this._endLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); - this._endLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); - const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); - this._endLayerInternal.add(_0x33b564); - this._endLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); - const _0x3e9c79 = _0x33b564.y - 35; - this._endLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - this._endLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - const _completeBanner = this._practicedMode.practiceMode - ? this.add.image(containerX, 170, "GJ_GameSheet03", "GJ_practiceComplete_001.png").setScale(0.8) - : this.add.image(containerX, 170, "GJ_WebSheet", "GJ_levelComplete_001.png").setScale(0.8); - this._endLayerInternal.add(_completeBanner); - const _0x45b6e4 = 0.8; - let _0xe44f6d = 250; - const _0x2de55e = this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Attempts: " + this._levelAttempts, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4); - this._endLayerInternal.add(_0x2de55e); - _0xe44f6d += 48; - this._endLayerInternal.add(this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Jumps: " + this._levelJumps, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4)); - _0xe44f6d += 48; - const _0x596450 = Math.floor(this._playTime); - const _0x30687e = Math.floor(_0x596450 / 3600); - const _0x52f8ee = Math.floor(_0x596450 % 3600 / 60); - const _0x2591d0 = _0x596450 % 60; - let _0x2be782; - _0x2be782 = _0x30687e > 0 ? String(_0x30687e).padStart(2, "0") + ":" + String(_0x52f8ee).padStart(2, "0") + ":" + String(_0x2591d0).padStart(2, "0") : String(_0x52f8ee).padStart(2, "0") + ":" + String(_0x2591d0).padStart(2, "0"); - const _0x241209 = _0xe44f6d; - this._endLayerInternal.add(this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Time: " + _0x2be782, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4)); - const _0x452429 = ["Awesome!", "Good\nJob!", "Well\nDone!", "Impressive!", "Amazing!", "Incredible!", "Skillful!", "Brilliant!", "Not\nbad!", "Warp\nSpeed!", "Challenge\nBreaker!", "Reflex\nMaster!", "I am\nspeechless...", "You are...\nThe One!", "How is this\npossible!?", "You beat\nme..."]; - const _0x165c06 = _0x452429[Math.floor(Math.random() * _0x452429.length)]; - const _0x45540f = 225; - const _0x8e2b = ["\x5f\x6d\x61\x63\x72\x6f\x42\x6f\x74", "\x70\x6c\x61\x79\x69\x6e\x67"];let _0x3bc14 = 0xffffff; try {if (this[_0x8e2b[0]] && this[_0x8e2b[0]][_0x8e2b[1]]) {_0x3bc14 = (_0x3bc14 & 0xffff00) | 0xfa;}} catch (_0xe31) {}const _0x17fa2b = this.add.bitmapText(containerX + _0x45540f, _0x241209, "bigFont", _0x165c06, 40).setOrigin(0.5, 0.5).setScale(0.8).setCenterAlign();if (_0x3bc14 !== 0xffffff) _0x17fa2b.setTint(_0x3bc14); - this._endLayerInternal.add(_0x17fa2b); - this._endLayerInternal.add(this.add.image(containerX - _0x45540f, 352.5, "GJ_WebSheet", "getIt_001.png").setScale(1 / 1.5)); - const _0x34b1bd = [{ - key: "downloadApple_001", - url: "https://discord.gg/TfEzAVWPSJ" - }, { - key: "downloadSteam_001", - url: "https://github.com/web-dashers/web-dashers.github.io" - }]; - for (let _0x10f8cc = 0; _0x10f8cc < _0x34b1bd.length; _0x10f8cc++) { - const _0xd7310b = _0x34b1bd[_0x10f8cc]; - const _0x1e3f82 = (_0x10f8cc - 1) * _0x45540f; - const _0x55a82e = 1 / 1.5; - const _0x4c7fb8 = this.add.image(containerX + _0x1e3f82, 437.5, "GJ_WebSheet", _0xd7310b.key + ".png").setScale(_0x55a82e).setInteractive(); - this._endLayerInternal.add(_0x4c7fb8); - this._makeBouncyButton(_0x4c7fb8, _0x55a82e, () => window.open(_0xd7310b.url, "_blank")); - } - _0x2de55e.width; - this._endStarX = containerX + _0x45540f; - this._endStarY = _0x241209 - 77.5; - if (window.macroBot){ - const botMenuBtn = this.add.image(containerX - 225, 255, "macroBot").setScale(0.4).setInteractive(); - this._endLayerInternal.add(botMenuBtn); - this._makeBouncyButton(botMenuBtn, 0.4, () => { - this._buildMacroPopup(); - if (this._macroPopup) { - this._macroPopup.setDepth(300); - } - }); - } - const _0x45fc2b = [{ - frame: "GJ_replayBtn_001.png", - dx: -200, - action: () => this._hideEndLayer(() => this._restartLevel()) - }, { - frame: "GJ_menuBtn_001.png", - dx: 200, - action: () => { - this._audio.playEffect("quitSound_01"); - this._audio.stopMusic(); - this.game.registry.set("fadeInFromBlack", true); - this.cameras.main.fadeOut(400, 0, 0, 0, (_0x53bf86, _0x15310d) => { - if (_0x15310d >= 1) { - this.scene.restart(); - } - }); - } - }]; - for (const _0x2d4335 of _0x45fc2b) { - const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 555, "GJ_WebSheet", _0x2d4335.frame).setInteractive(); - this._endLayerInternal.add(_0xdde774); - this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); - } - } - _showSettingsScreen() { - this._settingsScreenClosing = false; - if (this._pauseBtn) { - this.tweens.add({ - targets: this._pauseBtn, - alpha: 0, - duration: 300 - }); - } - const containerX = screenWidth / 2; - const _0x1aa656 = 320; - this._settingsLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); - this._settingsLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); - this._settingsScreenClosing = false; - this.tweens.add({ - targets: this._settingsLayerOverlay, - alpha: 180 / 255, - duration: 400, - ease: "Linear" - }); - - const _0x59b9ab = { - p: 0 - }; - this.tweens.add({ - targets: _0x59b9ab, - p: 1, - duration: 500, - ease: "Quad.Out", - onUpdate: () => { - this._settingsLayerInternal.y = _0x59b9ab.p * 650 - 640; - }, - onComplete: () => {} - }); - const _0x595215 = 712; - const _0x950c8d = 460; - const _0x2a115c = (screenWidth - _0x595215) / 2; - this._settingsLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0, 180 / 255)); - const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; - this._settingsLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); - this._settingsLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); - const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); - this._settingsLayerInternal.add(_0x33b564); - this._settingsLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); - const _0x3e9c79 = _0x33b564.y - 35; - this._settingsLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - this._settingsLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - this._settingsLayerInternal.add(this.add.bitmapText(containerX, 65, "bigFont", "Settings", 55).setOrigin(0.5, 0.5)); - const _sBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; - const _sBtnH = 62; - const _sBtnW2 = 310; - const _sBtnW3 = 200; - const _sGap = 18; - const _sColL = containerX - _sBtnW2 / 2 - _sGap / 2; - const _sColR = containerX + _sBtnW2 / 2 + _sGap / 2; - const _sCol3L = containerX - _sBtnW3 - _sGap; - const _sCol3M = containerX; - const _sCol3R = containerX + _sBtnW3 + _sGap; - const _sRow1Y = 155; - const _sRow2Y = 235; - const _sRow3Y = 312; - const _makeSettingsBtn = (cx, cy, label, btnW, isActive, action) => { - const grp = this.add.container(cx, cy); - const tint = isActive ? 0xffffff : 0x666666; - const btn9 = this.add.nineslice(0, 0, "GJ_button01", null, btnW, _sBtnH, _sBtnBorder, _sBtnBorder, _sBtnBorder, _sBtnBorder).setOrigin(0.5).setTint(tint); - grp.add(btn9); - const fontSize = label === "How To Play" ? 41 : 50; - const lbl = this.add.bitmapText(0, -5, "goldFont", label, fontSize).setOrigin(0.5, 0.5); - if (!isActive) lbl.setTint(0x666666); - grp.add(lbl); - if (isActive && action) { - const hitZone = this.add.zone(0, 0, btnW, _sBtnH).setInteractive(); - grp.add(hitZone); - const baseScale = 1; - const pressedScale = baseScale * 1.26; - hitZone.on("pointerdown", () => { - hitZone._pressed = true; - this.tweens.killTweensOf(grp, "scale"); - this.tweens.add({ targets: grp, scale: pressedScale, duration: 300, ease: "Bounce.Out" }); - }); - hitZone.on("pointerout", () => { - if (hitZone._pressed) { - hitZone._pressed = false; - this.tweens.killTweensOf(grp, "scale"); - this.tweens.add({ targets: grp, scale: baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - hitZone.on("pointerup", () => { - if (hitZone._pressed) { - hitZone._pressed = false; - this.tweens.killTweensOf(grp, "scale"); - grp.setScale(baseScale); - action(); - } - }); - } - this._settingsLayerInternal.add(grp); - return grp; - }; - - _makeSettingsBtn(_sColL, _sRow1Y, "Account", _sBtnW2, false, null); - _makeSettingsBtn(_sColR, _sRow1Y, "How To Play", _sBtnW2, true, () => { this._buildHowToPlayPopup(); }); - _makeSettingsBtn(_sColL, _sRow2Y, "Options", _sBtnW2, true, () => { this._buildSettingsPopup(); }); - _makeSettingsBtn(_sColR, _sRow2Y, "Graphics", _sBtnW2, false, null); - _makeSettingsBtn(_sCol3L, _sRow3Y, "Rate", _sBtnW3, false, null); - _makeSettingsBtn(_sCol3M, _sRow3Y, "Songs", _sBtnW3, false, null); - _makeSettingsBtn(_sCol3R, _sRow3Y, "Help", _sBtnW3, false, null); - - const lockIcon = this.add.image(containerX + 535, 30, "GJ_GameSheet03", "GJ_lock_open_001.png").setFlipX(false).setFlipY(false); - lockIcon.setScale(0.9); - lockIcon.setInteractive(); - this._expandHitArea(lockIcon, 1.5); - this._makeBouncyButton(lockIcon, 0.9, () => { this._openVaultMenu(); }); - this._settingsLayerInternal.add(lockIcon); - - const _0x45b6e4 = 0.8; - let _0xe44f6d = 250; - const sliderStartY = 430; - const _0x22b43a = 0.7; - const _0x41925a = this.textures.getFrame("GJ_WebSheet", "slidergroove.png"); - const _0x372782 = _0x41925a ? _0x41925a.width : 420; - - const createSlider = (posY, labelText, initialVal, setter) => { - this._settingsLayerInternal.add(this.add.bitmapText(containerX, posY - 37, "bigFont", labelText, 33).setOrigin(0.5, 0.5)); - const barMaxW = (_0x372782 - 8) * _0x22b43a * 1.3; - const barStartX = containerX - barMaxW / 2 + 2.8; - const fillW = initialVal * barMaxW; - const fillBar = this.add.tileSprite(barStartX, posY, fillW > 0 ? fillW : 1, 18, "sliderBar").setOrigin(0, 0.5); - this._settingsLayerInternal.add(fillBar); - this._settingsLayerInternal.add(this.add.image(containerX, posY, "GJ_WebSheet", "slidergroove.png").setScale(_0x22b43a * 1.3)); - - const thumb = this.add.image(barStartX + fillW, posY, "GJ_WebSheet", "sliderthumb.png").setScale(_0x22b43a * 1.3).setInteractive({ draggable: true }); - this._settingsLayerInternal.add(thumb); - thumb.on("drag", (p, dragX) => { - thumb.x = Math.max(barStartX, Math.min(barStartX + barMaxW, dragX)); - const pct = (thumb.x - barStartX) / barMaxW; - fillBar.width = Math.max(1, pct * barMaxW); - setter(pct < 0.03 ? 0 : pct); - }); - }; - - createSlider(sliderStartY - 15, "Music", this._audio.getUserMusicVolume(), v => this._audio.setUserMusicVolume(v)); - createSlider(sliderStartY + 60, "SFX", this._sfxVolume, v => { - this._sfxVolume = v; - localStorage.setItem("userSfxVol", v); - }); - const checkboxY = sliderStartY - 10; - const checkboxX = containerX + 280; - this._settingsLayerInternal.add(this.add.bitmapText(checkboxX, checkboxY - 42, "bigFont", "Menu", 20).setOrigin(0.5, 0.5)); - this._settingsLayerInternal.add(this.add.bitmapText(checkboxX, checkboxY - 22, "bigFont", "Music", 20).setOrigin(0.5, 0.5)); - - const getMenuMusicEnabled = () => { - const saved = localStorage.getItem("menuMusicEnabled"); - return saved === null ? true : saved === "true"; - }; - const setMenuMusicEnabled = (value) => localStorage.setItem("menuMusicEnabled", value); - - const getTex = () => getMenuMusicEnabled() ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; - const check = this.add.image(checkboxX, checkboxY + 15, "GJ_GameSheet03", getTex()).setScale(0.7).setInteractive(); - this._settingsLayerInternal.add(check); - this._makeBouncyButton(check, 0.8, () => { - const newState = !getMenuMusicEnabled(); - setMenuMusicEnabled(newState); - check.setTexture("GJ_GameSheet03", getTex()); - if (newState) { - if (!this._audio.isplaying()) { - this._audio.startMenuMusic(); - } - } else { - if (this._audio.isplaying()) { - this._audio.stopMusic(); - } - } - }); - const _0x45fc2b = [{ - frame: "GJ_arrow_03_001.png", - dx: -535, - action: () => this._hideSettingsScreen() - }]; - for (const _0x2d4335 of _0x45fc2b) { - const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 30, "GJ_GameSheet03", _0x2d4335.frame).setInteractive(); - this._settingsLayerInternal.add(_0xdde774); - this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); - } - } - _playSettingsStarAward() { - if (!this._settingsLayerInternal) { - return; - } - const _0x4edc03 = containerX; - const _0x5a0e9 = 200; - const _0x453043 = this.add.image(_0x4edc03, _0x5a0e9, "GJ_WebSheet", "GJ_bigStar_001.png").setScale(3).setAlpha(0); - this._settingsLayerInternal.add(_0x453043); - this.tweens.add({ - targets: _0x453043, - scale: 0.8, - alpha: 1, - duration: 300, - delay: 0, - ease: "Bounce.Out" - }); - } - _hideSettingsScreen() { - if (!this._settingsLayerInternal || this._settingsScreenClosing) { - return; - } - this._settingsScreenClosing = true; - const _0x272eb1 = () => { - this._settingsScreenClosing = false; - if (this._settingsLayerOverlay) { - this._settingsLayerOverlay.destroy(); - this._settingsLayerOverlay = null; - } - if (this._settingsLayerInternal) { - this._settingsLayerInternal.destroy(); - this._settingsLayerInternal = null; - } - - if (this._pauseBtn) { - this.tweens.add({ - targets: this._pauseBtn, - alpha: 1, - duration: 300 - }); - } - }; - this.tweens.add({ - targets: this._settingsLayerOverlay, - alpha: 0, - duration: 500, - ease: "Linear" - }); - - const _0x59b9ab = { - p: 1 - }; - this.tweens.add({ - targets: _0x59b9ab, - p: 0, - duration: 500, - ease: "Quad.In", - onUpdate: () => { - this._settingsLayerInternal.y = _0x59b9ab.p * 650 - 640; - }, - onComplete: _0x272eb1 - }); - } - _showStatsScreen() { - if (this._pauseBtn) { - this.tweens.add({ - targets: this._pauseBtn, - alpha: 0, - duration: 300 - }); - } - const containerX = screenWidth / 2; - const _0x1aa656 = 320; - this._statsLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); - this._statsLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); - this.tweens.add({ - targets: this._statsLayerOverlay, - alpha: 100 / 255, - duration: 1000 - }); - const _0x59b9ab = { - p: 0 - }; - this.tweens.add({ - targets: _0x59b9ab, - p: 1, - duration: 500, - ease: "Quad.Out", - onUpdate: () => { - this._statsLayerInternal.y = _0x59b9ab.p * 650 - 640; - } - }); - const _0x595215 = 712; - const _0x950c8d = 460; - const _0x2a115c = (screenWidth - _0x595215) / 2; - this._statsLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0xac531e)); - const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; - this._statsLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); - this._statsLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); - const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); - this._statsLayerInternal.add(_0x33b564); - this._statsLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); - const _0x3e9c79 = _0x33b564.y - 35; - this._statsLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - this._statsLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); - this._statsLayerInternal.add(this.add.bitmapText(containerX, 65, "bigFont", "Stats", 55).setOrigin(0.5, 0.5)); - const _rowPanelTop = 102; - const _rowPanelBottom = 528; - const _rowLeft = _0x2a115c + 7.8; - const _rowRight = _0x2a115c + _0x595215 - 7.8; - const _rowWidth = _rowRight - _rowLeft; - const _rowCount = 6; - const _rowH = (_rowPanelBottom - _rowPanelTop) / _rowCount; - - const rows = [ - { label: "Total Jumps:", value: String(this._totalJumps || 0) }, - { label: "Total Attempts:", value: String(this._attempts || 1) }, - { label: "Completed Levels:", value: String(window._completedLevels || 0) }, - { label: "Total Deaths:", value: String(this._totalDeaths || 0) }, - { label: "???:", value: String(window._totalDiamonds || '?') }, - { label: "???:", value: String(window._totalOrbs || '?') }, - - ]; - rows.forEach((row, index) => { - const rowCenterY = _rowPanelTop + index * _rowH + _rowH / 2; - const bgColor = index % 2 === 0 ? 0xac531e : 0xcf6d30; - this._statsLayerInternal.add( - this.add.rectangle(containerX, rowCenterY, _rowWidth, _rowH, bgColor).setOrigin(0.5, 0.5) - ); - if (index > 0) { - this._statsLayerInternal.add( - this.add.rectangle(containerX, _rowPanelTop + index * _rowH, _rowWidth, 0.5, 0x000000).setOrigin(0.5, 0.5) - ); - } - this._statsLayerInternal.add( - this.add.bitmapText(_rowLeft + 20, rowCenterY, "goldFont", row.label, 34).setOrigin(0, 0.5) - ); - this._statsLayerInternal.add( - this.add.bitmapText(_rowRight - 20, rowCenterY, "goldFont", row.value, 34).setOrigin(1, 0.5) - ); - }); - const _0x45fc2b = [{ - frame: "GJ_arrow_03_001.png", - dx: -535, - action: () => this._hideStatsScreen() - }]; - for (const _0x2d4335 of _0x45fc2b) { - const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 30, "GJ_GameSheet03", _0x2d4335.frame).setInteractive(); - this._statsLayerInternal.add(_0xdde774); - this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); - } - } - _hideStatsScreen() { - if (!this._statsLayerInternal) { - return; - } - const _0x272eb1 = () => { - if (this._statsLayerOverlay) { - this._statsLayerOverlay.destroy(); - this._statsLayerOverlay = null; - } - if (this._statsLayerInternal) { - this._statsLayerInternal.destroy(); - this._statsLayerInternal = null; - } - if (this._pauseBtn) { - this.tweens.add({ - targets: this._pauseBtn, - alpha: 1, - duration: 300 - }); - } - }; - this.tweens.add({ - targets: this._statsLayerOverlay, - alpha: 0, - duration: 500, - ease: "Linear" - }); - const _0x59b9ab = { - p: 1 - }; - this.tweens.add({ - targets: _0x59b9ab, - p: 0, - duration: 500, - ease: "Quad.In", - onUpdate: () => { - this._statsLayerInternal.y = _0x59b9ab.p * 650 - 640; - }, - onComplete: _0x272eb1 - }); - } - _playStarAward() { - if (!this._endLayerInternal) { - return; - } - const _0x4edc03 = this._endStarX; - const _0x5a0e9 = this._endStarY; - const _0x453043 = this.add.image(_0x4edc03, _0x5a0e9, "GJ_WebSheet", "GJ_bigStar_001.png").setScale(3).setAlpha(0); - this._endLayerInternal.add(_0x453043); - this.tweens.add({ - targets: _0x453043, - scale: 0.8, - alpha: 1, - duration: 300, - delay: 0, - ease: "Bounce.Out" - }); - this.time.delayedCall(100, () => { - this._audio.playEffect("highscoreGet02"); - const _0x1204d3 = _0x4edc03; - const _0x96e3b2 = _0x5a0e9 + this._endLayerInternal.y; - this.add.particles(_0x1204d3, _0x96e3b2, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 200, - max: 600 - }, - angle: { - min: 0, - max: 360 - }, - scale: { - start: 0.5, - end: 0 - }, - alpha: { - start: 1, - end: 0 - }, - lifespan: { - min: 200, - max: 600 - }, - quantity: 30, - stopAfter: 30, - blendMode: S, - tint: 16776960 - }).setScrollFactor(0).setDepth(202); - const _0x43203f = this.add.graphics().setScrollFactor(0).setDepth(202).setBlendMode(S); - const _0x403316 = { - t: 0 - }; - this.tweens.add({ - targets: _0x403316, - t: 1, - duration: 400, - ease: "Quad.Out", - onUpdate: () => { - _0x43203f.clear(); - _0x43203f.fillStyle(16776960, 1 - _0x403316.t); - _0x43203f.fillCircle(_0x1204d3, _0x96e3b2, 20 + _0x403316.t * 200); - }, - onComplete: () => _0x43203f.destroy() - }); - }); - } - _openListScene(title, rowHeight, onBack) { - const sw = screenWidth; - const sh = screenHeight; - const objects = []; - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(300); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 280, ease: "Linear", - onComplete: () => fadeIn.destroy() }); - - const bgGfx = this.add.graphics().setScrollFactor(0).setDepth(200); - const steps = 80; - for (let i = 0; i < steps; i++) { - const t = i / (steps - 1); - const r = 0; - const g = Math.round(0x66 * (1 - t) + 0x33 * t); - const b = Math.round(0xff * (1 - t) + 0x99 * t); - bgGfx.fillStyle((r << 16) | (g << 8) | b, 1); - bgGfx.fillRect(0, Math.floor(i * sh / steps), sw, Math.ceil(sh / steps) + 1); - } - objects.push(bgGfx); - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) - .setScrollFactor(0).setDepth(200).setInteractive(); - objects.push(blocker); - const cBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(201).setOrigin(0, 1).setFlipY(false); - const cBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(201).setOrigin(1, 1).setFlipX(true); - objects.push(cBL, cBR); - const panelW = 712; - const panelH = 460; - const panelCX = sw / 2; - const panelCY = sh / 2; - const panelBg = this.add.rectangle(panelCX, panelCY + 10, panelW, panelH, 0xC2723E) - .setScrollFactor(0).setDepth(201).setOrigin(0.5); - objects.push(panelBg); - const listLeft = panelCX - panelW / 2; - const listTop = panelCY - panelH / 2 + 10; - const stripesGfx = this.add.graphics().setScrollFactor(0).setDepth(202); - objects.push(stripesGfx); - let _rowCount = 0; - const _redrawStripes = (offsetY = 0) => { - stripesGfx.clear(); - for (let ri = 0; ri < _rowCount; ri++) { - const ry = (listTop + 12) + ri * rowHeight - offsetY; - const ryBottom = ry + rowHeight; - if (ryBottom <= (listTop + 12) || ry >= listTop + panelH) continue; - const clampedY = Math.max(ry, listTop + 12); - const clampedH = Math.min(ryBottom, listTop + panelH) - clampedY; - stripesGfx.fillStyle(ri % 2 === 0 ? 0xB5652E : 0xC2723E, 1); - stripesGfx.fillRect(listLeft, clampedY, panelW, clampedH); - } - if (_rowCount > 0) { - const topDividerY = (listTop + 12) - offsetY; - if (topDividerY >= listTop + 12 && topDividerY < listTop + panelH) { - stripesGfx.fillStyle(0x000000, 0.6); - stripesGfx.fillRect(listLeft + 5, topDividerY, panelW - 10, 1.5); - } - const lastRowY = (listTop + 12) + (_rowCount - 1) * rowHeight - offsetY; - const bottomDividerY = lastRowY + rowHeight; - if (bottomDividerY > listTop + 12 && bottomDividerY <= listTop + panelH) { - stripesGfx.fillStyle(0x000000, 0.6); - stripesGfx.fillRect(listLeft + 5, bottomDividerY, panelW - 10, 1.5); - } - } - }; - - const addRow = () => { _rowCount++; _redrawStripes(); }; - const clearRows = () => { _rowCount = 0; _redrawStripes(); }; - const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const sideScaleY = sideFrame ? panelH / sideFrame.height : 1; - const leftBorder = this.add.image(listLeft - 40, 90, - "GJ_WebSheet", "GJ_table_side_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0, 0).setScale(1, sideScaleY); - objects.push(leftBorder); - const rightBorder = this.add.image(listLeft + panelW + 40, 90, - "GJ_WebSheet", "GJ_table_side_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY); - objects.push(rightBorder); - const topBorder = this.add.image(panelCX, 80, - "GJ_WebSheet", "GJ_table_top_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - objects.push(topBorder); - const bottomBorder = this.add.image(panelCX, 570, - "GJ_WebSheet", "GJ_table_bottom_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - objects.push(bottomBorder); - - if (title) { - const titleTxt = this.add.bitmapText(panelCX, panelCY - 245, "bigFont", title, 52) - .setScrollFactor(0).setDepth(204).setOrigin(0.5, 0.5); - objects.push(titleTxt); - } - const pageLbl = this.add.bitmapText(sw - 8, 3, "goldFont", "", 22) - .setScrollFactor(0).setDepth(204).setOrigin(1, 0).setVisible(false); - objects.push(pageLbl); - const backBtn = this.add.image(45, 45, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(backBtn); - const closeOverlay = (returnToParent = true, onComplete = null) => { - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(400).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeOut, alpha: 1, duration: 160, ease: "Linear", - onComplete: () => { - for (const o of objects) if (o && o.destroy) o.destroy(); - if (returnToParent && onBack) onBack(); - if (onComplete) onComplete(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 160, ease: "Linear", - onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._makeBouncyButton(backBtn, 1, () => closeOverlay()); - const prevBtn = this.add.image(40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setVisible(false); - objects.push(prevBtn); - this._makeBouncyButton(prevBtn, 1, () => {}); - const nextBtn = this.add.image(sw - 40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setFlipX(true).setVisible(false); - objects.push(nextBtn); - this._makeBouncyButton(nextBtn, 1, () => {}); - - return { overlay: bgGfx, objects, listLeft, listTop, panelW, panelH, - panelCX, panelCY, addRow, clearRows, prevBtn, nextBtn, - pageLbl, closeOverlay, redrawStripes: _redrawStripes }; - } - - _fitBitmapText(textObj, maxWidth, minScale = 0.3) { - textObj.setScale(1); - if (textObj.width > maxWidth) { - textObj.setScale(Math.max(minScale, maxWidth / textObj.width)); - } - return textObj; - } - - _formatStatCount(n) { - n = Number(n) || 0; - if (n < 1000) return String(n); - if (n < 1000000) { - const v = n / 1000; - return (v >= 100 ? Math.round(v) : parseFloat(v.toFixed(1))) + "K"; - } - const v = n / 1000000; - return (v >= 100 ? Math.round(v) : parseFloat(v.toFixed(1))) + "M"; - } - - _getLevelLengthLabel(lengthIdx) { - const _lengthValues = ["Tiny", "Short", "Medium", "Long", "XL"]; - if (lengthIdx === 5) { - return "Plat."; - } - return _lengthValues[lengthIdx] || "Tiny"; - } - - _openOnlineLevelsScene(params = {}) { - if (this._onlineLevelsOverlay) return; - - const sw = screenWidth; - const sh = screenHeight; - const isFeatured = (params.type === 6); - const shell = this._openListScene( - isFeatured ? "" : "Online Levels", - 180, - () => { - this._onlineLevelsOverlay = null; - if (isFeatured) { - this._openCreatorMenu(); - } else { - this._openSearchMenu(); - } - } - ); - const { objects, listLeft, listTop, panelW, panelH, - panelCX, panelCY, addRow, clearRows, - prevBtn, nextBtn, pageLbl, closeOverlay, redrawStripes } = shell; - - this._onlineLevelsOverlay = shell.overlay; - this._closeOnlineLevelsOverlay = closeOverlay; - if (isFeatured) { - const header = this.add.image(sw / 2, sh / 2 - 265, - "GJ_GameSheet03", "featuredLabel_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5); - objects.push(header); - } - { - const pageBtnGroup = this.add.container(sw - 35, sh / 2 - 240); - const pageBtn = this.add.image(0, 0, "GJ_button02").setScale(0.7); - const pageNum = this.add.bitmapText(-2, 0, "bigFont", "1", 35).setOrigin(0.5); - pageBtnGroup.add(pageBtn); - pageBtnGroup.add(pageNum); - const _pageBtnFrame = this.textures.getFrame("GJ_button02"); - const _pageBtnW = (_pageBtnFrame ? _pageBtnFrame.realWidth : 100) * 0.7; - const _pageBtnH = (_pageBtnFrame ? _pageBtnFrame.realHeight : 100) * 0.7; - pageBtnGroup.setScrollFactor(0).setDepth(205).setInteractive( - new Phaser.Geom.Rectangle(-_pageBtnW / 2, -_pageBtnH / 2, _pageBtnW, _pageBtnH), - Phaser.Geom.Rectangle.Contains - ); - objects.push(pageBtnGroup); - this._makeBouncyButton(pageBtnGroup, 1, () => { - if (!_loading) { - const pageCount = isFeatured ? 10 : _knownMaxPages; - const nextPage = (currentPage + 1) % Math.max(1, pageCount); - _setPage(nextPage); - } - }, () => true); - const updatePageNum = (page) => { - pageNum.setText(String(page + 1)); - }; - this._featuredPageUpdate = updatePageNum; - } - const spinSprite = this.add.image(sw / 2, sh / 2, "loadingCircle") - .setScrollFactor(0).setDepth(205).setOrigin(0.5).setBlendMode(Phaser.BlendModes.ADD).setAlpha(0.5); - objects.push(spinSprite); - const spinTimer = this.time.addEvent({ - delay: 16, - loop: true, - callback: () => { - if (!spinSprite.scene) { spinTimer.remove(); return; } - spinSprite.rotation += 0.1; - } - }); - objects.push({ destroy: () => spinTimer.remove() }); - const infoBtn = this.add.image(60, sh - 60, - "GJ_GameSheet03", "GJ_infoIcon_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(infoBtn); - this._makeBouncyButton(infoBtn, 1, () => { this._buildFeaturedInfoPopup(); }); - - const refreshBtn = this.add.image(sw - 55, sh - 55, - "GJ_GameSheet03", "GJ_updateBtn_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(refreshBtn); - let currentPage = 0; - let _knownMaxPages = 1; - const cache = {}; - const _processedCache = {}; - let activeCellObjs = []; - let _loading = false; - let scrollOffsetY = 0; - let _lastLevelStrs = null; - let _lastLevelData = []; - const _panelBoundaryTop = listTop + 12; - const _panelBoundaryBottom = listTop + panelH - 22; - const _panelMaskShape = this.add.graphics().setScrollFactor(0); - _panelMaskShape.fillStyle(0xffffff); - _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); - const _panelMask = _panelMaskShape.createGeometryMask(); - objects.push(_panelMaskShape); - - const _diffFrames = [ - "difficulty_00_btn_001.png", - "difficulty_01_btn_001.png", - "difficulty_02_btn_001.png", - "difficulty_03_btn_001.png", - "difficulty_04_btn_001.png", - "difficulty_05_btn_001.png", - "difficulty_06_btn_001.png", - "difficulty_07_btn_001.png", - "difficulty_08_btn_001.png", - "difficulty_09_btn_001.png", - "difficulty_10_btn_001.png", - "difficulty_auto_btn_001.png" - ]; - const _diffSizes = { - "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, - "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, - "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, - "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, - "difficulty_06_btn_001.png": { w: 72, h: 88, rotated: false }, - "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_09_btn_001.png": { w: 74, h: 88, rotated: false }, - "difficulty_10_btn_001.png": { w: 80, h: 91, rotated: false }, - "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, - }; - const _officialGDSongs = [ - "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", - "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", - "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", - "Hexagon Force","Blast Processing","Theory of Everything 2", - "Geometrical Dominator","Deadlocked","Fingerdash","Dash" - ]; - - const _buildLevelCell = (levelData, rowIdx) => { - const rowH = 180; - const rowY = _panelBoundaryTop + rowIdx * rowH - scrollOffsetY; - const rowCenterY = rowY + rowH / 2; - const cellObjs = []; - const rx = listLeft; - const boundaryTop = _panelBoundaryTop; - const boundaryBottom = _panelBoundaryBottom; - if (rowIdx > 0 && rowY >= boundaryTop && rowY <= boundaryBottom) { - const div = this.add.rectangle(rx + panelW / 2, rowY, panelW - 10, 1.5, 0x000000, 0.6) - .setScrollFactor(0).setDepth(203).setOrigin(0.5, 0.5); - div.setMask(_panelMask); - cellObjs.push(div); - } - const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); - const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; - const _targetH = 85; - const _maxW = 90; - const _scaleW = _diffMeta ? _diffMeta.w : 90; - const _scaleH = _diffMeta ? _diffMeta.h : 85; - const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); - const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; - const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", _diffFrames[diffIdx]) - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) - .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); - if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); - diffIcon.setMask(_panelMask); - cellObjs.push(diffIcon); - let coinIcon = null; - if (levelData.epic >= 3) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 2) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 1) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.featured) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } - if (coinIcon) { - coinIcon.setMask(_panelMask); - cellObjs.push(coinIcon); - } - const nameX = rx + 105; - const btnX = rx + panelW - 88; - const _progressKeyId = "online_" + (levelData.id || "0"); - const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); - const _hasBest = _bestPercent > 0; - const _isComplete = _bestPercent >= 100; - const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); - const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; - const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(nameText, _maxTextWidth); - nameText.setMask(_panelMask); - cellObjs.push(nameText); - if (_isComplete) { - const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); - completeIcon.setMask(_panelMask); - cellObjs.push(completeIcon); - } else if (_hasBest) { - const bestPctText = this.add.bitmapText(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5) - bestPctText.setMask(_panelMask); - cellObjs.push(bestPctText); - } - const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(authorText, _maxTextWidth); - authorText.setMask(_panelMask); - cellObjs.push(authorText); - const _isOfficialSong = _officialGDSongs.includes(levelData.songName); - const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); - this._fitBitmapText(songText, _maxTextWidth); - songText.setMask(_panelMask); - cellObjs.push(songText); - const _statY = rowCenterY + 63; - const _statGap = 25; - const _statDefs = [ - { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, - { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, - { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } - ]; - let _statX = nameX; - _statDefs.forEach((stat) => { - const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); - statIcon.setMask(_panelMask); - cellObjs.push(statIcon); - const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(statText, _maxTextWidth / 2); - statText.setMask(_panelMask); - cellObjs.push(statText); - _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; - }); - const _hasViewedLevel = !!localStorage.getItem("viewedLevel_" + (levelData.id || "0")); - const _rowBtnFrame = _hasViewedLevel ? "GJ_button01" : "GJ_button02"; - const _rowBtnLabel = _hasViewedLevel ? "View" : "Get It"; - const _rowBtnLabelSize = _hasViewedLevel ? 40 : 30; - const btn9 = this.add.nineslice(btnX, rowCenterY, _rowBtnFrame, null, 140, 60, 20, 20, 20, 20) - .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); - btn9.setMask(_panelMask); - const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", _rowBtnLabel, _rowBtnLabelSize) - .setScrollFactor(0).setDepth(207).setOrigin(0.5); - btnLbl.setMask(_panelMask); - cellObjs.push(btn9, btnLbl); - - const _btnTargets = [btn9, btnLbl]; - const _baseScale = 1, _pressScale = 1.26; - btn9.on("pointerdown", () => { - btn9._pressed = true; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); - }); - btn9.on("pointerout", () => { - if (btn9._pressed) { - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - btn9.on("pointerup", () => { - if (!btn9._pressed) return; - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets); - btn9.setScale(_baseScale); - btnLbl.setScale(_baseScale); - window._selectedLevelData = levelData; - closeOverlay(false, () => { - this._onlineLevelsOverlay = null; - this._closeOnlineLevelsOverlay = null; - this._openPlayMenu(() => this._openOnlineLevelsScene(params)); - }); - }); - - return cellObjs; - }; - const _parseKV = (str) => { - const m = {}, p = str.split(":"); - for (let i = 0; i + 1 < p.length; i += 2) m[p[i]] = p[i + 1]; - return m; - }; - const _setPage = async (page) => { - if (_loading) return; - _loading = true; - currentPage = page; - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - clearRows(); - if (this._featuredPageUpdate) { - this._featuredPageUpdate(page); - } - - spinSprite.setVisible(true); - refreshBtn.setVisible(false); - pageLbl.setVisible(false); - this.tweens.killTweensOf(prevBtn, "scale"); - prevBtn.setScale(1); - prevBtn._pressed = false; - prevBtn.setVisible(false); - this.tweens.killTweensOf(nextBtn, "scale"); - nextBtn.setScale(1); - nextBtn._pressed = false; - nextBtn.setVisible(false); - - try { - let response = cache[page]; - if (!response) { - const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); - if (!PROXY_BASE) throw new Error("no proxy configured"); - const body = Object.entries({ secret: "Wmfd2893gb7", page, ...params }) - .map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&"); - let retryCount = 0; - const maxRetries = 3; - let res; - while (retryCount < maxRetries) { - res = await fetch(`${PROXY_BASE}/getGJLevels21.php`, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body - }); - - if (res.status === 429) { - retryCount++; - if (retryCount >= maxRetries) { - throw new Error(`rate limited after ${maxRetries} retries`); - } - await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retryCount))); - continue; - } - break; - } - if (!res.ok) throw new Error(`HTTP ${res.status}`); - response = await res.text(); - if (!response || response === "-1") throw new Error("no results"); - cache[page] = response; - } - spinSprite.setVisible(false); - refreshBtn.setVisible(true); - pageLbl.setVisible(true); - prevBtn.setVisible(page > 0); - nextBtn.setVisible(true); - const sections = response.split("#"); - const levelStrs = (sections[0] || "").split("|").filter(Boolean); - const playerStrs = (sections[1] || "").split("|").filter(Boolean); - const songStrs = (sections[2] || "").split("~:~").filter(Boolean); - const pageInfo = (sections[3] || "0:0:10").split(":"); - - const playerMap = {}; - for (const ps of playerStrs) { - const p = ps.split(":"); - if (p.length >= 2) playerMap[p[0]] = p[1]; - } - const songMap = {}; - for (const ss of songStrs) { - const sp = ss.split("~|~"), sm = {}; - for (let i = 0; i + 1 < sp.length; i += 2) sm[sp[i]] = sp[i + 1]; - if (sm["1"]) songMap[sm["1"]] = sm["2"] || ""; - } - const total = parseInt(pageInfo[0]) || 0; - const offset = parseInt(pageInfo[1]) || 0; - const count = parseInt(pageInfo[2]) || 10; - const start = offset + 1; - const end = count * (page + 1); - pageLbl.setText(`${start} to ${end} of ${total}`); - const maxPages = Math.ceil(total / count); - _knownMaxPages = Math.max(1, maxPages); - const hasNextPage = (page + 1) < maxPages; - nextBtn.setVisible(hasNextPage); - scrollOffsetY = 0; - // wip - _lastLevelStrs = levelStrs; - if (_processedCache[page]) { - _lastLevelData = _processedCache[page]; - _lastLevelData.forEach((levelData, idx) => { - const cellObjs = _buildLevelCell(levelData, idx); - activeCellObjs.push(...cellObjs); - addRow(); - }); - spinSprite.setVisible(false); - refreshBtn.setVisible(true); - pageLbl.setVisible(true); - prevBtn.setVisible(page > 0); - nextBtn.setVisible(hasNextPage); - _loading = false; - return; - } - _lastLevelData = levelStrs.map((ls) => { - const m = _parseKV(ls); - const rawLikes = parseInt(m["14"]) || 0; - const isDemon = parseInt(m["17"]) === 1; - const isAuto = parseInt(m["25"]) === 1; - let diffIdx = 0; - if (isAuto) { - diffIdx = 11; - } else if (isDemon) { - const d9 = parseInt(m["9"]); - const d43 = parseInt(m["43"]); - if (!isNaN(d9) && d9 >= 1 && d9 <= 5) { - diffIdx = [7, 8, 6, 9, 10][d9 - 1] ?? 8; - } else if (!isNaN(d43)) { - const demonMap43 = { 3: 7, 4: 8, 0: 6, 5: 9, 6: 10 }; - diffIdx = demonMap43.hasOwnProperty(d43) ? demonMap43[d43] : 8; - } else { - diffIdx = 8; - } - } else { - diffIdx = Math.min(5, Math.max(0, Math.round((parseInt(m["9"]) || 0) / 10))); - } - return { - id: m["1"] || null, - name: m["2"] || "Unknown", - author: playerMap[m["6"]] || ("Player " + (m["6"] || "?")), - difficulty: diffIdx, - downloads: parseInt(m["10"]) || 0, - length: parseInt(m["15"]) || 0, - likes: rawLikes, - stars: parseInt(m["18"]) || 0, - coins: parseInt(m["37"]) || 0, - coinsVerified: m["38"] === "1", - customSongID: (m["35"] && m["35"] !== "0") ? m["35"] : null, - songName: m["35"] - ? (songMap[m["35"]] || ("Song #" + m["35"])) - : ("Song #" + (m["12"] || "0")), - featureScore: parseInt(m["19"]) || 0, - featured: (parseInt(m["19"]) || 0) > 0, - epic: parseInt(m["42"]) || 0 - }; - }); - const _officialEntries = _lastLevelData.filter(ld => !ld.customSongID && ld.id); - if (_officialEntries.length > 0) { - await Promise.all(_officialEntries.map(ld => { - return fetch(`https://gdbrowser.com/api/level/${ld.id}`) - .then(r => r.ok ? r.json() : null) - .then(data => { if (data && data.songName) ld.songName = data.songName; }) - .catch(() => {}); - })); - } - _processedCache[page] = _lastLevelData; - _lastLevelData.forEach((levelData, idx) => { - const cellObjs = _buildLevelCell(levelData, idx); - activeCellObjs.push(...cellObjs); - addRow(); - }); - - } catch (err) { - spinSprite.setVisible(false); - refreshBtn.setVisible(true); - } - _loading = false; - }; - prevBtn.removeAllListeners("pointerup"); - nextBtn.removeAllListeners("pointerup"); - prevBtn.on("pointerup", () => { if (!_loading && currentPage > 0) _setPage(currentPage - 1); }); - nextBtn.on("pointerup", () => { if (!_loading) _setPage(currentPage + 1); }); - this._makeBouncyButton(refreshBtn, 1, () => { delete cache[currentPage]; delete _processedCache[currentPage]; _setPage(currentPage); }); - const _onWheel = (pointer, gameObjects, deltaX, deltaY) => { - if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; - if (pointer.y < listTop || pointer.y > listTop + panelH) return; - const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); - const newScrollOffset = Math.max(0, Math.min(scrollOffsetY + deltaY * 0.5, maxScroll)); - if (newScrollOffset !== scrollOffsetY) { - scrollOffsetY = newScrollOffset; - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { - const cellObjs = _buildLevelCell(levelData, idx); - activeCellObjs.push(...cellObjs); - }); - - redrawStripes(scrollOffsetY); - } - }; this.input.on("wheel", _onWheel); - objects.push({ destroy: () => this.input.off("wheel", _onWheel) }); - let isDragging = false; - let dragStartY = 0; - let dragStartScrollOffset = 0; - let dragThreshold = 5; - let bounceBackTween = null; - const onDragStart = (pointer) => { - if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; - if (pointer.y < listTop || pointer.y > listTop + panelH) return; - if (bounceBackTween) { - bounceBackTween.destroy(); - bounceBackTween = null; - } - isDragging = true; - dragStartY = pointer.y; - dragStartScrollOffset = scrollOffsetY; - }; - const onDragMove = (pointer) => { - if (!isDragging || !pointer.isDown) return; - if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; - if (pointer.y < listTop || pointer.y > listTop + panelH) return; - const deltaY = dragStartY - pointer.y; - if (Math.abs(deltaY) < dragThreshold) return; - const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); - let newScrollOffset = dragStartScrollOffset + deltaY * 0.5; - const elasticLimit = 100; - if (newScrollOffset < -elasticLimit) { - newScrollOffset = -elasticLimit; - } else if (newScrollOffset > maxScroll + elasticLimit) { - newScrollOffset = maxScroll + elasticLimit; - } - if (newScrollOffset !== scrollOffsetY) { - scrollOffsetY = newScrollOffset; - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { - const cellObjs = _buildLevelCell(levelData, idx); - activeCellObjs.push(...cellObjs); - }); - redrawStripes(scrollOffsetY); - } - }; - - const onDragEnd = () => { - isDragging = false; - const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); - let targetScrollOffset = scrollOffsetY; - if (scrollOffsetY < 0) { - targetScrollOffset = 0; - } else if (scrollOffsetY > maxScroll) { - targetScrollOffset = maxScroll; - } - if (targetScrollOffset !== scrollOffsetY) { - const startOffset = scrollOffsetY; - bounceBackTween = this.tweens.add({ - targets: { scrollOffset: startOffset }, - scrollOffset: targetScrollOffset, - duration: 300, - ease: "Quad.Out", - onStart: () => { - isDragging = false; - }, - onUpdate: () => { - scrollOffsetY = bounceBackTween.targets[0].scrollOffset; - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { - const cellObjs = _buildLevelCell(levelData, idx); - activeCellObjs.push(...cellObjs); - }); - - redrawStripes(scrollOffsetY); - }, - onComplete: () => { - bounceBackTween = null; - } - }); - } - }; - - this.input.on('pointerdown', onDragStart); - this.input.on('pointermove', onDragMove); - this.input.on('pointerup', onDragEnd); - - objects.push({ destroy: () => this.input.off('pointerdown', onDragStart) }); - objects.push({ destroy: () => this.input.off('pointermove', onDragMove) }); - objects.push({ destroy: () => this.input.off('pointerup', onDragEnd) }); - objects.push({ destroy: () => { - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - }}); - - _setPage(0); - } - - _openSavedLevelsScene() { - const sw = screenWidth; - const sh = screenHeight; - - const objects = []; - const rowHeight = 180; - - const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(300); - fadeIn.fillStyle(0x000000, 1); - fadeIn.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeIn, alpha: 0, duration: 280, ease: "Linear", - onComplete: () => fadeIn.destroy() }); - - const bgGfx = this.add.graphics().setScrollFactor(0).setDepth(200); - const steps = 80; - for (let i = 0; i < steps; i++) { - const t = i / (steps - 1); - const r = 0; - const g = Math.round(0x66 * (1 - t) + 0x33 * t); - const b = Math.round(0xff * (1 - t) + 0x99 * t); - bgGfx.fillStyle((r << 16) | (g << 8) | b, 1); - bgGfx.fillRect(0, Math.floor(i * sh / steps), sw, Math.ceil(sh / steps) + 1); - } - objects.push(bgGfx); - - const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) - .setScrollFactor(0).setDepth(200).setInteractive(); - objects.push(blocker); - - const cBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(201).setOrigin(0, 1).setFlipY(false); - const cBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") - .setScrollFactor(0).setDepth(201).setOrigin(1, 1).setFlipX(true); - objects.push(cBL, cBR); - - const panelW = 712; - const panelH = 460; - const panelCX = sw / 2; - const panelCY = sh / 2; - const panelBg = this.add.rectangle(panelCX, panelCY + 10, panelW, panelH, 0xC2723E) - .setScrollFactor(0).setDepth(201).setOrigin(0.5); - objects.push(panelBg); - - const listLeft = panelCX - panelW / 2; - const listTop = panelCY - panelH / 2 + 10; - - const stripesGfx = this.add.graphics().setScrollFactor(0).setDepth(202); - objects.push(stripesGfx); - let _rowCount = 0; - const redrawStripes = (offsetY = 0) => { - stripesGfx.clear(); - for (let ri = 0; ri < _rowCount; ri++) { - const ry = (listTop + 12) + ri * rowHeight - offsetY; - const ryBottom = ry + rowHeight; - if (ryBottom <= (listTop + 12) || ry >= listTop + panelH) continue; - const clampedY = Math.max(ry, listTop + 12); - const clampedH = Math.min(ryBottom, listTop + panelH) - clampedY; - stripesGfx.fillStyle(ri % 2 === 0 ? 0xB5652E : 0xC2723E, 1); - stripesGfx.fillRect(listLeft, clampedY, panelW, clampedH); - } - if (_rowCount > 0) { - const topDividerY = (listTop + 12) - offsetY; - if (topDividerY >= listTop + 12 && topDividerY < listTop + panelH) { - stripesGfx.fillStyle(0x000000, 0.6); - stripesGfx.fillRect(listLeft + 5, topDividerY, panelW - 10, 1.5); - } - const lastRowY = (listTop + 12) + (_rowCount - 1) * rowHeight - offsetY; - const bottomDividerY = lastRowY + rowHeight; - if (bottomDividerY > listTop + 12 && bottomDividerY <= listTop + panelH) { - stripesGfx.fillStyle(0x000000, 0.6); - stripesGfx.fillRect(listLeft + 5, bottomDividerY, panelW - 10, 1.5); - } - } - }; - const addRow = () => { _rowCount++; redrawStripes(); }; - const clearRows = () => { _rowCount = 0; redrawStripes(); }; - - const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); - const sideScaleY = sideFrame ? panelH / sideFrame.height : 1; - const leftBorder = this.add.image(listLeft - 40, 90, - "GJ_WebSheet", "GJ_table_side_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0, 0).setScale(1, sideScaleY); - objects.push(leftBorder); - const rightBorder = this.add.image(listLeft + panelW + 40, 90, - "GJ_WebSheet", "GJ_table_side_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY); - objects.push(rightBorder); - const topBorder = this.add.image(panelCX, 80, - "GJ_WebSheet", "GJ_table_top_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - objects.push(topBorder); - const bottomBorder = this.add.image(panelCX, 570, - "GJ_WebSheet", "GJ_table_bottom_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - objects.push(bottomBorder); - - const pageLbl = this.add.bitmapText(sw - 8, 3, "goldFont", "", 22) - .setScrollFactor(0).setDepth(204).setOrigin(1, 0).setVisible(false); - objects.push(pageLbl); - - const backBtn = this.add.image(45, 45, "GJ_GameSheet03", "GJ_arrow_01_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(backBtn); - const closeOverlay = (returnToCreator = true, onComplete = null) => { - const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(400).setAlpha(0); - fadeOut.fillStyle(0x000000, 1); - fadeOut.fillRect(0, 0, sw, sh); - this.tweens.add({ targets: fadeOut, alpha: 1, duration: 160, ease: "Linear", - onComplete: () => { - for (const o of objects) if (o && o.destroy) o.destroy(); - if (returnToCreator) this._openCreatorMenu(); - if (onComplete) onComplete(); - this.tweens.add({ targets: fadeOut, alpha: 0, duration: 160, ease: "Linear", - onComplete: () => fadeOut.destroy() }); - } - }); - }; - this._makeBouncyButton(backBtn, 1, () => closeOverlay()); - const prevBtn = this.add.image(40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setVisible(false); - objects.push(prevBtn); - this._makeBouncyButton(prevBtn, 1, () => {}); - const nextBtn = this.add.image(sw - 40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setFlipX(true).setVisible(false); - objects.push(nextBtn); - this._makeBouncyButton(nextBtn, 1, () => {}); - const header = this.add.bitmapText(sw / 2, sh / 2 - 245, "bigFont", "Saved Levels", 52) - .setScrollFactor(0).setDepth(204).setOrigin(0.5); - objects.push(header); - const savedPerPage = 10; - let currentPage = 0; - const pageBtnGroup = this.add.container(sw - 35, sh / 2 - 240); - const pageBtn = this.add.image(0, 0, "GJ_button02").setScale(0.7); - const pageNum = this.add.bitmapText(-2, 0, "bigFont", "1", 35).setOrigin(0.5); - pageBtnGroup.add(pageBtn); - pageBtnGroup.add(pageNum); - const _pageBtnFrame = this.textures.getFrame("GJ_button02"); - const _pageBtnW = (_pageBtnFrame ? _pageBtnFrame.realWidth : 100) * 0.7; - const _pageBtnH = (_pageBtnFrame ? _pageBtnFrame.realHeight : 100) * 0.7; - pageBtnGroup.setScrollFactor(0).setDepth(205).setInteractive( - new Phaser.Geom.Rectangle(-_pageBtnW / 2, -_pageBtnH / 2, _pageBtnW, _pageBtnH), - Phaser.Geom.Rectangle.Contains - ); - objects.push(pageBtnGroup); - const _updateSavedPageNum = (page) => { pageNum.setText(String(page + 1)); }; - const _getSavedTotalPages = () => Math.max(1, Math.ceil(savedLevelData.length / savedPerPage)); - const infoBtn = this.add.image(60, sh - 60, - "GJ_GameSheet03", "GJ_infoIcon_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(infoBtn); - this._makeBouncyButton(infoBtn, 1, () => {}, () => true); - - const refreshBtn = this.add.image(sw - 55, sh - 55, - "GJ_GameSheet03", "GJ_deleteBtn_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); - objects.push(refreshBtn); - this._makeBouncyButton(refreshBtn, 1, () => { - try { localStorage.removeItem("gd_saved_online_levels"); } catch(_e) {} - savedLevelData = []; - currentPage = 0; - scrollOffsetY = 0; - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - clearRows(); - redrawStripes(scrollOffsetY); - _updateSavedNav(); - if (_emptyTxt) { - _emptyTxt.setVisible(true); - } else { - _emptyTxt = this.add.bitmapText(panelCX, panelCY + 10, "bigFont", "You have not downloaded any\n levels yet!", 32) - .setScrollFactor(0).setDepth(204).setOrigin(0.5); - objects.push(_emptyTxt); - } - }, () => true); - - const _panelBoundaryTop = listTop + 12; - const _panelBoundaryBottom = listTop + panelH - 22; - const _panelMaskShape = this.add.graphics().setScrollFactor(0); - _panelMaskShape.fillStyle(0xffffff); - _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); - const _panelMask = _panelMaskShape.createGeometryMask(); - objects.push(_panelMaskShape); - let scrollOffsetY = 0; - let activeCellObjs = []; - let savedLevelData = []; - let _emptyTxt = null; - const diffFrames = [ - "difficulty_00_btn_001.png", - "difficulty_01_btn_001.png", - "difficulty_02_btn_001.png", - "difficulty_03_btn_001.png", - "difficulty_04_btn_001.png", - "difficulty_05_btn_001.png", - "difficulty_06_btn_001.png", - "difficulty_07_btn_001.png", - "difficulty_08_btn_001.png", - "difficulty_09_btn_001.png", - "difficulty_10_btn_001.png", - "difficulty_auto_btn_001.png" - ]; - const _buildSavedCell = (levelData, rowIdx) => { - const rowH = 180; - const rowCenterY = _panelBoundaryTop + rowIdx * rowH + rowH / 2 - scrollOffsetY; - const cellObjs = []; - const rx = listLeft; - if (rowCenterY + rowH / 2 < _panelBoundaryTop || rowCenterY - rowH / 2 > _panelBoundaryBottom) { - return cellObjs; - } - if (rowIdx > 0) { - const divY = _panelBoundaryTop + rowIdx * rowH - scrollOffsetY; - if (divY >= _panelBoundaryTop && divY <= _panelBoundaryBottom) { - const div = this.add.rectangle(rx + panelW / 2, divY, panelW - 10, 1.5, 0x000000, 0.6) - .setScrollFactor(0).setDepth(203).setOrigin(0.5, 0.5); - div.setMask(_panelMask); - cellObjs.push(div); - } - } - const diffIdx = Math.min(diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); - const _diffSizes = { - "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, - "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, - "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, - "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, - "difficulty_06_btn_001.png": { w: 72, h: 90, rotated: false }, - "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_09_btn_001.png": { w: 74, h: 90, rotated: false }, - "difficulty_10_btn_001.png": { w: 80, h: 95, rotated: false }, - "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, - }; - const _diffMeta = _diffSizes[diffFrames[diffIdx]]; - const _targetH = 85; - const _maxW = 90; - const _scaleW = _diffMeta ? _diffMeta.w : 90; - const _scaleH = _diffMeta ? _diffMeta.h : 85; - const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); - const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; - const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", diffFrames[diffIdx]) - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) - .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); - if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); - diffIcon.setMask(_panelMask); - cellObjs.push(diffIcon); - let coinIcon = null; - if (levelData.epic >= 3) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 2) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 1) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.featured) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } - if (coinIcon) { - coinIcon.setMask(_panelMask); - cellObjs.push(coinIcon); - } - const nameX = rx + 105; - const btnX = rx + panelW - 88; - const _progressKeyId = "online_" + (levelData.id || "0"); - const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); - const _hasBest = _bestPercent > 0; - const _isComplete = _bestPercent >= 100; - const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); - const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; - const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(nameText, _maxTextWidth); - nameText.setMask(_panelMask); - cellObjs.push(nameText); - if (_isComplete) { - const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); - completeIcon.setMask(_panelMask); - cellObjs.push(completeIcon); - } else if (_hasBest) { - const bestPctText = this.add.bitmapText(nameX + 5+ nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - bestPctText.setMask(_panelMask); - cellObjs.push(bestPctText); - } - const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(authorText, _maxTextWidth); - authorText.setMask(_panelMask); - cellObjs.push(authorText); - const _officialGDSongs = [ - "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", - "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", - "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", - "Hexagon Force","Blast Processing","Theory of Everything 2", - "Geometrical Dominator","Deadlocked","Fingerdash","Dash" - ]; - const _isOfficialSong = _officialGDSongs.includes(levelData.songName); - const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); - this._fitBitmapText(songText, _maxTextWidth); - songText.setMask(_panelMask); - cellObjs.push(songText); - const _statY = rowCenterY + 63; - const _statGap = 25; - const _statDefs = [ - { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, - { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, - { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } - ]; - let _statX = nameX; - _statDefs.forEach((stat) => { - const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); - statIcon.setMask(_panelMask); - cellObjs.push(statIcon); - const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(statText, _maxTextWidth / 2); - statText.setMask(_panelMask); - cellObjs.push(statText); - _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; - }); - const btn9 = this.add.nineslice(btnX, rowCenterY, "GJ_button01", null, 140, 60, 20, 20, 20, 20) - .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); - btn9.setMask(_panelMask); - const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", "View", 40) - .setScrollFactor(0).setDepth(207).setOrigin(0.5); - btnLbl.setMask(_panelMask); - cellObjs.push(btn9, btnLbl); - - const _btnTargets = [btn9, btnLbl]; - const _baseScale = 1, _pressScale = 1.26; - btn9.on("pointerdown", () => { - btn9._pressed = true; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); - }); - btn9.on("pointerout", () => { - if (btn9._pressed) { - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - btn9.on("pointerup", () => { - if (!btn9._pressed) return; - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets); - btn9.setScale(_baseScale); - btnLbl.setScale(_baseScale); - window._selectedLevelData = levelData; - closeOverlay(false, () => { - this._openPlayMenu(() => this._openSavedLevelsScene()); - }); - }); - - return cellObjs; - }; - - const _rebuildCells = () => { - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - clearRows(); - const totalPages = _getSavedTotalPages(); - if (currentPage >= totalPages) currentPage = 0; - _updateSavedNav(); - const pageData = savedLevelData.slice(currentPage * savedPerPage, currentPage * savedPerPage + savedPerPage); - pageData.forEach((levelData, idx) => { - const cellObjs = _buildSavedCell(levelData, idx); - activeCellObjs.push(...cellObjs); - addRow(); - }); - }; - const _updateSavedNav = () => { - const totalPages = _getSavedTotalPages(); - const hasData = savedLevelData.length > 0; - pageBtnGroup.setVisible(hasData); - _updateSavedPageNum(currentPage); - const start = hasData ? currentPage * savedPerPage + 1 : 0; - const end = hasData ? Math.min(savedLevelData.length, (currentPage + 1) * savedPerPage) : 0; - pageLbl.setText(`${start} to ${end} of ${savedLevelData.length}`); - pageLbl.setVisible(hasData); - prevBtn.setVisible(hasData && currentPage > 0); - nextBtn.setVisible(hasData && currentPage < totalPages - 1); - }; - - const _goToSavedPage = (page) => { - const totalPages = _getSavedTotalPages(); - currentPage = Math.max(0, Math.min(page, totalPages - 1)); - scrollOffsetY = 0; - _rebuildCells(); - redrawStripes(scrollOffsetY); - }; - - this._makeBouncyButton(pageBtnGroup, 1, () => { - const totalPages = _getSavedTotalPages(); - _goToSavedPage((currentPage + 1) % totalPages); - }, () => true); - - prevBtn.removeAllListeners("pointerup"); - nextBtn.removeAllListeners("pointerup"); - prevBtn.on("pointerup", () => { if (currentPage > 0) _goToSavedPage(currentPage - 1); }); - nextBtn.on("pointerup", () => { - const totalPages = _getSavedTotalPages(); - if (currentPage < totalPages - 1) _goToSavedPage(currentPage + 1); - }); - try { - savedLevelData = JSON.parse(localStorage.getItem("gd_saved_online_levels") || "[]"); - let _neededNormalize = false; - savedLevelData.forEach(ld => { - if (typeof ld.id === "string" && ld.id.startsWith("online_")) { - ld.id = ld.id.replace(/^online_/, ""); - _neededNormalize = true; - } - }); - if (_neededNormalize) { - try { localStorage.setItem("gd_saved_online_levels", JSON.stringify(savedLevelData)); } catch(_e) {} - } - } catch(_e) { savedLevelData = []; } - - if (savedLevelData.length === 0) { - const emptyTxt = this.add.bitmapText(panelCX, panelCY + 10, "bigFont", "You have not downloaded any\n levels yet!", 38) - .setScrollFactor(0).setDepth(204).setOrigin(0.5); - objects.push(emptyTxt); - _emptyTxt = emptyTxt; - _updateSavedNav(); - } else { - const _needsFetch = savedLevelData.filter(ld => { - const numericId = String(ld.id || "").replace(/^online_/, ""); - return /^\d+$/.test(numericId) && (!ld.author || ld.author === "Unknown" || !ld.songName || ld.songName === "Unknown" || ld.difficulty === 0 || ld.difficulty == null); - }); - - const _doRender = () => { - _rebuildCells(); - }; - - if (_needsFetch.length === 0) { - _doRender(); - } else { - Promise.all(_needsFetch.map(levelData => { - const numericId = String(levelData.id || "").replace(/^online_/, ""); - return fetch(`https://gdbrowser.com/api/level/${numericId}`) - .then(r => r.ok ? r.json() : null) - .then(data => { - if (data) { - if (data.author) levelData.author = data.author; - if (data.songName) levelData.songName = data.songName; - if (!levelData.customSongID && data.songID) levelData.customSongID = String(data.songID); - const _diffMap = { - "N/A": 0, "Auto": 11, "Easy": 1, "Normal": 2, - "Hard": 3, "Harder": 4, "Insane": 5, - "Easy Demon": 7, "Medium Demon": 8, "Hard Demon": 6, - "Insane Demon": 9, "Extreme Demon": 10 - }; - if (data.difficulty && _diffMap.hasOwnProperty(data.difficulty)) { - levelData.difficulty = _diffMap[data.difficulty]; - } - } - }) - .catch(() => {}); - })).then(() => { - try { - const _savedKey = "gd_saved_online_levels"; - const all = JSON.parse(localStorage.getItem(_savedKey) || "[]"); - for (const ld of savedLevelData) { - const idx = all.findIndex(sl => sl.id === ld.id); - if (idx !== -1) { - all[idx].author = ld.author; - all[idx].songName = ld.songName; - all[idx].difficulty = ld.difficulty; - all[idx].customSongID = ld.customSongID; - } - } - localStorage.setItem(_savedKey, JSON.stringify(all)); - } catch(_e) {} - _doRender(); - }); - } - - objects.push({ destroy: () => { - for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); - activeCellObjs = []; - }}); - const _getSavedPageCount = () => Math.min(savedPerPage, savedLevelData.length - currentPage * savedPerPage); - const _onWheel = (pointer, gameObjects, deltaX, deltaY) => { - if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; - if (pointer.y < listTop || pointer.y > listTop + panelH) return; - const maxScroll = Math.max(0, _getSavedPageCount() * 180 - (panelH - 33)); - const newOffset = Math.max(0, Math.min(scrollOffsetY + deltaY * 0.5, maxScroll)); - if (newOffset !== scrollOffsetY) { - scrollOffsetY = newOffset; - _rebuildCells(); - redrawStripes(scrollOffsetY); - } - }; - this.input.on("wheel", _onWheel); - objects.push({ destroy: () => this.input.off("wheel", _onWheel) }); - let isDragging = false, dragStartY = 0, dragStartOffset = 0; - const onDragStart = (pointer) => { - if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; - if (pointer.y < listTop || pointer.y > listTop + panelH) return; - isDragging = true; dragStartY = pointer.y; dragStartOffset = scrollOffsetY; - }; - const onDragMove = (pointer) => { - if (!isDragging || !pointer.isDown) return; - const maxScroll = Math.max(0, _getSavedPageCount() * 180 - (panelH - 33)); - const newOffset = Math.max(0, Math.min(dragStartOffset + (dragStartY - pointer.y) * 0.5, maxScroll)); - if (newOffset !== scrollOffsetY) { - scrollOffsetY = newOffset; - _rebuildCells(); - redrawStripes(scrollOffsetY); - } - }; - const onDragEnd = () => { isDragging = false; }; - this.input.on("pointerdown", onDragStart); - this.input.on("pointermove", onDragMove); - this.input.on("pointerup", onDragEnd); - objects.push({ destroy: () => this.input.off("pointerdown", onDragStart) }); - objects.push({ destroy: () => this.input.off("pointermove", onDragMove) }); - objects.push({ destroy: () => this.input.off("pointerup", onDragEnd) }); - } - } - - _closeOnlineLevelsScene() { - if (this._onlineLevelsOverlay) { - if (this._closeOnlineLevelsOverlay) { - this._closeOnlineLevelsOverlay(); - } - this._onlineLevelsOverlay = null; - } - } - - _openSearchResultScene(levelData) { - if (this._searchResultOverlay) return; - - const sw = screenWidth; - const sh = screenHeight; - const shell = this._openListScene( - "Online Levels", - 180, - () => { this._searchResultOverlay = null; this._openSearchMenu(); } - ); - const { objects, listLeft, listTop, panelW, panelH, addRow, closeOverlay } = shell; - - this._searchResultOverlay = shell.overlay; - this._closeSearchResultOverlay = closeOverlay; - - const _panelBoundaryTop = listTop + 12; - const _panelBoundaryBottom = listTop + panelH - 22; - const _panelMaskShape = this.add.graphics().setScrollFactor(0); - _panelMaskShape.fillStyle(0xffffff); - _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); - const _panelMask = _panelMaskShape.createGeometryMask(); - objects.push(_panelMaskShape); - - const _diffFrames = [ - "difficulty_00_btn_001.png", - "difficulty_01_btn_001.png", - "difficulty_02_btn_001.png", - "difficulty_03_btn_001.png", - "difficulty_04_btn_001.png", - "difficulty_05_btn_001.png", - "difficulty_06_btn_001.png", - "difficulty_07_btn_001.png", - "difficulty_08_btn_001.png", - "difficulty_09_btn_001.png", - "difficulty_10_btn_001.png", - "difficulty_auto_btn_001.png" - ]; - const _diffSizes = { - "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, - "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, - "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, - "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, - "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, - "difficulty_06_btn_001.png": { w: 72, h: 88, rotated: false }, - "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, - "difficulty_09_btn_001.png": { w: 74, h: 88, rotated: false }, - "difficulty_10_btn_001.png": { w: 80, h: 91, rotated: false }, - "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, - }; - const _officialGDSongs = [ - "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", - "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", - "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", - "Hexagon Force","Blast Processing","Theory of Everything 2", - "Geometrical Dominator","Deadlocked","Fingerdash","Dash" - ]; - - const rowH = 180; - const rowY = _panelBoundaryTop; - const rowCenterY = rowY + rowH / 2; - const rx = listLeft; - - const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); - const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; - const _targetH = 85; - const _maxW = 90; - const _scaleW = _diffMeta ? _diffMeta.w : 90; - const _scaleH = _diffMeta ? _diffMeta.h : 85; - const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); - const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; - const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", _diffFrames[diffIdx]) - .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) - .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); - if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); - diffIcon.setMask(_panelMask); - objects.push(diffIcon); - - let coinIcon = null; - if (levelData.epic >= 3) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 2) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.epic === 1) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } else if (levelData.featured) { - coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") - .setScrollFactor(0).setDepth(203).setOrigin(0.5); - } - if (coinIcon) { - coinIcon.setMask(_panelMask); - objects.push(coinIcon); - } - - const nameX = rx + 105; - const btnX = rx + panelW - 88; - const _progressKeyId = "online_" + (levelData.id || "0"); - const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); - const _hasBest = _bestPercent > 0; - const _isComplete = _bestPercent >= 100; - const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); - const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; - const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(nameText, _maxTextWidth); - nameText.setMask(_panelMask); - objects.push(nameText); - if (_isComplete) { - const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); - completeIcon.setMask(_panelMask); - objects.push(completeIcon); - } else if (_hasBest) { - const bestPctText = this.add.bitmapText(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5) - bestPctText.setMask(_panelMask); - objects.push(bestPctText); - } - const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(authorText, _maxTextWidth); - authorText.setMask(_panelMask); - objects.push(authorText); - const _isOfficialSong = _officialGDSongs.includes(levelData.songName); - const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); - this._fitBitmapText(songText, _maxTextWidth); - songText.setMask(_panelMask); - objects.push(songText); - const _statY = rowCenterY + 63; - const _statGap = 25; - const _statDefs = [ - { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, - { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, - { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } - ]; - let _statX = nameX; - _statDefs.forEach((stat) => { - const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); - statIcon.setMask(_panelMask); - objects.push(statIcon); - const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) - .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); - this._fitBitmapText(statText, _maxTextWidth / 2); - statText.setMask(_panelMask); - objects.push(statText); - _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; - }); - - const _hasViewedLevel = !!localStorage.getItem("viewedLevel_" + (levelData.id || "0")); - const _rowBtnFrame = _hasViewedLevel ? "GJ_button01" : "GJ_button02"; - const _rowBtnLabel = _hasViewedLevel ? "View" : "Get It"; - const _rowBtnLabelSize = _hasViewedLevel ? 40 : 30; - const btn9 = this.add.nineslice(btnX, rowCenterY, _rowBtnFrame, null, 140, 60, 20, 20, 20, 20) - .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); - btn9.setMask(_panelMask); - const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", _rowBtnLabel, _rowBtnLabelSize) - .setScrollFactor(0).setDepth(207).setOrigin(0.5); - btnLbl.setMask(_panelMask); - objects.push(btn9, btnLbl); - - const _btnTargets = [btn9, btnLbl]; - const _baseScale = 1, _pressScale = 1.26; - btn9.on("pointerdown", () => { - btn9._pressed = true; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); - }); - btn9.on("pointerout", () => { - if (btn9._pressed) { - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets, "scale"); - this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); - } - }); - btn9.on("pointerup", () => { - if (!btn9._pressed) return; - btn9._pressed = false; - this.tweens.killTweensOf(_btnTargets); - btn9.setScale(_baseScale); - btnLbl.setScale(_baseScale); - window._selectedLevelData = levelData; - closeOverlay(false, () => { - this._searchResultOverlay = null; - this._closeSearchResultOverlay = null; - this._openPlayMenu(() => this._openSearchResultScene(levelData)); - }); - }); - - addRow(); - } - - _closeSearchResultScene() { - if (this._searchResultOverlay) { - if (this._closeSearchResultOverlay) { - this._closeSearchResultOverlay(); - } - this._searchResultOverlay = null; - } - } - - _hideEndLayer(_0x272eb1) { - if (!this._endLayerInternal) { - if (_0x272eb1) { - _0x272eb1(); - } - return; - } - const _0x1215e0 = { - p: 0 - }; - this.tweens.add({ - targets: _0x1215e0, - p: 1, - duration: 500, - ease: _0xc1c75 => _0xc1c75 < 0.5 ? Math.pow(_0xc1c75 * 2, 2) / 2 : 1 - Math.pow((1 - _0xc1c75) * 2, 2) / 2, - onUpdate: () => { - this._endLayerInternal.y = _0x1215e0.p * -640; - }, - onComplete: () => { - this._endLayerInternal.destroy(); - this._endLayerInternal = null; - if (this._endLayerOverlay) { - this._endLayerOverlay.destroy(); - this._endLayerOverlay = null; - } - if (_0x272eb1) { - _0x272eb1(); - } - } - }); - this.tweens.add({ - targets: this._endLayerOverlay, - alpha: 0, - duration: 500 - }); - } -} +class PracticeMode { + constructor() { + this.checkpoints = []; + this.practiceMode = false; + this.checkpointSprites = []; + } + togglePracticeMode() { + this.practiceMode = !this.practiceMode; + if (!this.practiceMode) { + this.clearCheckpoints(); + } + return this.practiceMode; + } + saveCheckpoint(playerState, playerWorldX, cameraX, scene) { + if (!this.practiceMode) return false; + const checkpoint = { + x: playerWorldX, + y: playerState.y, + yVelocity: playerState.yVelocity, + gravityFlipped: playerState.gravityFlipped, + isMini: playerState.isMini, + isCube: playerState.isCube, + isShip: playerState.isShip, + isBall: playerState.isBall, + isUfo: playerState.isUfo, + isWave: playerState.isWave, + isSpider: playerState.isSpider, + isBird: playerState.isBird, + isDart: playerState.isDart, + isRobot: playerState.isRobot, + isSwing: playerState.isSwing, + isJetpack: playerState.isJetpack, + isFlying: playerState.isFlying, + isJumping: playerState.isJumping, + onGround: playerState.onGround, + canJump: playerState.canJump, + wasBoosted: playerState.wasBoosted, + rotation: playerState.rotation, + gravity: playerState.gravity, + jumpPower: playerState.jumpPower, + mirrored: playerState.mirrored, + isDashing: playerState.isDashing, + dashYVelocity: playerState.dashYVelocity, + ballShouldRotate: playerState.ballShouldRotate, + ballRotateOpposite: playerState.ballRotateOpposite, + ballNormalRotate: playerState.ballNormalRotate, + ballHitPad: playerState.ballHitPad, + robotHold: !!playerState._robotHold, + robotHoldTimer: playerState._robotHoldTimer || 0, + cameraX: cameraX, + flyFloorY: scene._level._flyFloorY, + flyCeilingY: scene._level._flyCeilingY, + flyGroundActive: scene._level._flyGroundActive, + flyVisualOnly: scene._level._flyVisualOnly, + flyVisualFloorInset: scene._level._flyVisualFloorInset, + flyVisualCeilingInset: scene._level._flyVisualCeilingInset, + groundTargetValue: scene._level._groundTargetValue, + flyCameraTarget: scene._level.flyCameraTarget, + groundAnimating: scene._level._groundAnimating, + groundAnimFrom: scene._level._groundAnimFrom, + groundAnimTo: scene._level._groundAnimTo, + groundAnimTime: scene._level._groundAnimTime, + groundAnimDuration: scene._level._groundAnimDuration, + cameraY: scene._cameraY, + groundStartScreenY: scene._level._groundStartScreenY, + ceilingStartScreenY: scene._level._ceilingStartScreenY, + groundY: scene._level._groundY, + ceilingY: scene._level._ceilingY, + speed: playerSpeed, + physicsFrame: scene._physicsFrame, + dualMode: !!scene._isDual, + dualGameMode: scene?._getDualModeId ? scene._getDualModeId(scene._state2) : null, + dualIsMini: !!scene._state2?.isMini, + dualY: scene._state2?.y, + dualYVelocity: scene._state2?.yVelocity, + dualGravityFlipped: scene._state2?.gravityFlipped, + dualOnGround: scene._state2?.onGround, + dualOnCeiling: scene._state2?.onCeiling, + dualCanJump: scene._state2?.canJump, + dualIsJumping: scene._state2?.isJumping, + timestamp: Date.now() + }; + this.checkpoints.push(checkpoint); + const checkpointSprite = scene.add.image(playerWorldX, b(playerState.y), "GJ_GameSheet02", "checkpoint_01_001.png") + .setOrigin(0.5, 0.5) + .setScrollFactor(1) + .setDepth(15) + .setScale(1.0); + scene._level.topContainer.add(checkpointSprite); + this.checkpointSprites.push(checkpointSprite); + return true; + } + deleteLastCheckpoint() { + if (this.checkpoints.length > 0) { + this.checkpoints.pop(); + if (this.checkpointSprites.length > 0) { + const lastSprite = this.checkpointSprites.pop(); + if (lastSprite && lastSprite.destroy) { + lastSprite.destroy(); + } + } + return true; + } + return false; + } + clearCheckpoints() { + this.checkpoints = []; + for (const sprite of this.checkpointSprites) { + if (sprite && sprite.destroy) { + sprite.destroy(); + } + } + this.checkpointSprites = []; + } + loadLastCheckpoint() { + if (this.checkpoints.length > 0) { + return this.checkpoints[this.checkpoints.length - 1]; + } + return null; + } +} + +class MacroBot { + constructor(scene) { + this.scene = scene; + this.resetAll(); + } + + resetAll() { + this.recording = false; + this.playing = false; + + this.cursor = 0; + this.isDown = false; + + this.inputs = []; + + this.meta = { + author: "Web Dashers", + level: "", // ill fix ts later + version: 1 + }; + } + + startRecording(meta = {}) { + this.resetAll(); + this.recording = true; + this.meta = { ...meta }; + } + + stopRecording() { + this.recording = false; + return this.exportObject(); + } + + clearRecording() { + this.inputs = []; + this.cursor = 0; + this.isDown = false; + } + + rollbackRecording(currentFrame) { + this.inputs = this.inputs.filter(ev => (ev.frame ?? 0) <= currentFrame); + this.cursor = 0; + this.isDown = false; + } + + clearPlayback() { + this.cursor = 0; + this.isDown = false; + } + + rollbackPlayback(currentFrame) { + if (!this.inputs.length) return; + + this.cursor = 0; + this.isDown = false; + + this.scene._releaseButton(true); + + while ( + this.cursor < this.inputs.length && + (this.inputs[this.cursor].frame ?? 0) <= currentFrame + ) { + const ev = this.inputs[this.cursor++]; + + if (ev.down) { + this.scene._pushButton(true); + this.isDown = true; + } else { + this.scene._releaseButton(true); + this.isDown = false; + } + } + } + + startPlayback(macroData) { + const macro = typeof macroData === "string" ? JSON.parse(macroData) : macroData; + + this.resetAll(); + this.playing = true; + + this.meta = { + ...this.meta, + ...(macro || {}) + }; + + this.inputs = Array.isArray(macro?.inputs) ? macro.inputs.slice() : []; + this.inputs.sort((a, b) => (a.frame ?? 0) - (b.frame ?? 0)); + + this.cursor = 0; + this.isDown = false; + } + + stopPlayback() { + this.playing = false; + this.cursor = 0; + this.isDown = false; + } + + recordEdge(down, currentFrame) { + if (!this.recording) return; + + const last = this.inputs[this.inputs.length - 1]; + if (last && last.down === !!down && last.frame === currentFrame) { + return; + } + + this.inputs.push({ + frame: currentFrame, + down: !!down + }); + + this.isDown = !!down; + } + + step(currentFrame) { + if (!this.playing) return; + + while ( + this.cursor < this.inputs.length && + (this.inputs[this.cursor].frame ?? 0) <= currentFrame + ) { + const ev = this.inputs[this.cursor++]; + + if (ev.down) { + if (!this.isDown) { + this.scene._pushButton(true); + this.isDown = true; + } + } else { + if (this.isDown) { + this.scene._releaseButton(true); + this.isDown = false; + } + } + } + } + + exportObject() { + return { + meta: this.meta, + inputs: this.inputs.slice() + }; + } + + exportString(pretty = false) { + return JSON.stringify(this.exportObject(), null, pretty ? 2 : 0); + } + + download(filename = "macro.wbgdr") { + const blob = new Blob([this.exportString(true)], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + a.remove(); + URL.revokeObjectURL(url); + } + + importFile(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const text = String(event.target.result || ""); + const macro = JSON.parse(text); + resolve(macro); + } catch (err) { + reject(err); + } + }; + reader.onerror = () => reject(reader.error || new Error("Failed to read macro file")); + reader.readAsText(file); + }); + } +} + +class GameScene extends Phaser.Scene { + constructor() { + super({ + key: "GameScene" + }); + } + create() { + this._bgSpeedX = 0.1; + this._bgSpeedY = 0.1; + this._menuCameraX = -centerX; + this._prevCameraX = -centerX; + this._bg = this.add.tileSprite(0, 0, screenWidth, screenHeight, "game_bg_01").setOrigin(0, 0).setScrollFactor(0).setDepth(-10); + this._applyMirroredBackgroundTexture("game_bg_01"); + this._cameraX = -centerX; + this._cameraY = 0; + this._cameraXRef = { + get value() { + return this._v; + }, + _v: -centerX + }; + this._state = new PlayerState(); + this._level = new window.LevelObject(this, this._cameraXRef); + this._levelEditor = new window.LevelEditor(this); + this._orbGfx = null; + this._orbGfxTimer = 0; + this._player = new PlayerObject(this, this._state, this._level); + this._player._activationKey = "main"; + this._state2 = new PlayerState(); + this._player2 = new PlayerObject(this, this._state2, this._level); + this._player2._activationKey = "dual"; + this._player2.setInvertedColors?.(true); + this._isDual = false; + this._player2.setCubeVisible(false); + this._player2.setShipVisible(false); + this._player2.setBallVisible(false); + this._player2.setWaveVisible(false); + this._player2.setBirdVisible?.(false); + this._player2.setSpiderVisible(false); + this._player2.setRobotVisible(false); + this._player2.setSwingVisible(false); + this._colorManager = new ColorManager(); + this._practicedMode = new PracticeMode(); + if (this._audio == null) { + this._audio = new AudioManager(this); + } + if (window._onlineLevelString && window._onlineLevelId && + window.currentlevel[2] === window._onlineLevelId) { + try { + this.cache.text.entries.set(window._onlineLevelId, window._onlineLevelString); + } catch(e) {} + } + let _0x591888 = this.cache.text.get(window.currentlevel[2]); + if (!_0x591888 && window._onlineLevelString && window.currentlevel[2] === window._onlineLevelId) { + _0x591888 = window._onlineLevelString; + } + if (_0x591888) { + this._level.loadLevel(_0x591888); + } + const _resolveGdArtId = (key, fallback = 1) => { + const raw = window.settingsMap?.[key]; + const parsed = parseInt(raw ?? fallback, 10); + return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; + }; + + const _bgGdId = _resolveGdArtId("kA6", parseInt(window._backgroundId || "01", 10) || 1); + window._backgroundId = String(_bgGdId).padStart(2, "0"); + + const _groundRaw = window.settingsMap?.["kA7"] ?? ((parseInt(window._groundId || "00", 10) || 0) + 1); + window._groundId = getGroundTextureId(_groundRaw); + + const _bgKey = "game_bg_" + getBackgroundTextureIndex(_bgGdId); + if (this.textures.exists(_bgKey)) { + this._applyMirroredBackgroundTexture(_bgKey); + } + this._level.applyGroundTexture(); + if (this._level._initialColors) { + for (let chId in this._level._initialColors) { + let col = this._level._initialColors[chId]; + this._colorManager.setInitialColor(parseInt(chId, 10), col); + } + } + this._level.createEndPortal(this); + this._glitterCenterX = 0; + this._glitterCenterY = T; + this._glitterEmitter = this.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + speed: 0, + scale: { + start: 0.375, + end: 0 + }, + alpha: { + start: 1, + end: 0 + }, + lifespan: { + min: 200, + max: 1800 + }, + frequency: 60, + blendMode: S, + tint: window.mainColor, + emitting: false, + emitCallback: _0x3c2a3e => { + _0x3c2a3e.x = this._glitterCenterX + (Math.random() * 2 - 1) * (screenWidth / 1.8); + _0x3c2a3e.y = this._glitterCenterY + (Math.random() * 2 - 1) * 320; + } + }); + this._level.additiveContainer.add(this._glitterEmitter); + this._bg.setTint(this._colorManager.getHex(fs)); + this._level.setGroundColor(this._colorManager.getHex(gs)); + this._level.setGround2Color?.(this._colorManager.getHex(1009)); + this._level.additiveContainer.setVisible(false); + this._level.container.setVisible(false); + this._level.topContainer.setVisible(false); + this._attempts = parseInt(localStorage.getItem("gd_totalAttempts") || "1", 10); + this._bestPercent = 0; + this._lastPercent = 0; + this._practiceBestPercent = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); + this._endPortalGameY = 240; + this._resetGameplayState(); + this._totalJumps = parseInt(localStorage.getItem("gd_totalJumps") || "0", 10); + this._totalDeaths = parseInt(localStorage.getItem("gd_totalDeaths") || "0", 10); + window._completedLevels = parseInt(localStorage.getItem("gd_completedLevels") || "0", 10); + this._playTime = 0; + this._menuActive = true; + this._slideIn = false; + this._slideGroundX = null; + this._firstPlay = true; + this._player.setCubeVisible(false); + this._player.setShipVisible(false); + this._player.setBallVisible(false); + this._logo = this.add.image(0, 100, "GJ_WebSheet", "GJ_logo_001.png").setScrollFactor(0).setDepth(30).setScale(1.2); + this._robLogo = this.add.image(110, 595, "GJ_WebSheet", "RobTopLogoBig_001.png").setScrollFactor(0).setDepth(30).setScale(0.525).setInteractive(); + this._makeBouncyButton(this._robLogo, 0.525, () => { + window.open("https://geometrydash.com", "_blank"); + }, () => this._menuActive); + const _socialIconDefs = [ + {frame: "", url: "", angle: 0, row: 0, col: 0 }, + {frame: "", url: "", angle: 0, row: 0, col: 1 }, + {frame: "", url: "", angle: 0, row: 0, col: 2 }, + {frame: "", url: "", angle: 0, row: 0, col: 3 }, + + { frame: "gj_twIcon_001.png", url: "https://x.com/rohanis0000gd", angle: 0, flipX: false, row: 1, col: 0 }, + { frame: "gj_ytIcon_001.png", url: "https://www.youtube.com/@rohanis0000gd", angle: 0, row: 1, col: 1 }, + { frame: "gj_tiktokIcon_001.png", url: "https://www.tiktok.com/@rohanis00000", angle: 0, flipX: false, row: 1, col: 2 }, + { frame: "gj_githubIcon_001.png", url: "https://github.com/web-dashers/web-dashers.github.io", angle: 0, row: 1, col: 3 }, + + {frame: "", url: "", angle: 0, row: 2, col: 0 }, + {frame: "", url: "", angle: 0, row: 2, col: 1 }, + {frame: "", url: "", angle: 0, row: 2, col: 2 }, + { frame: "gj_discordIcon_001.png", url: "https://discord.gg/TfEzAVWPSJ", angle: 0, row: 2, col: 3 }, + + + //{ frame: "gj_instaIcon_001.png", url: "https://www.instagram.com/", angle: -90, flipX: true, row: 1, col: 3 }, + //{ frame: "gj_twitchIcon_001.png", url: "https://www.twitch.tv/", angle: -90, flipX: true, row: 0, col: 0 }, + //{ frame: "gj_fbIcon_001.png", url: "https://www.facebook.com/", angle: 0, row: 0, col: 0 }, + //{ frame: "gj_rdIcon_001.png", url: "https://www.reddit.com/r/geometrydash/", angle: -90, flipX: true, row: 0, col: 0 }, + + ]; + const _socialScale = 0.75; + this._socialIcons = _socialIconDefs.map((def, index) => { + const icon = this.add.image(0, 0, "GJ_GameSheet03", def.frame) + .setScrollFactor(0) + .setDepth(30) + .setScale(_socialScale) + .setAngle(def.angle) + .setFlipX(!!def.flipX); + + if (!def.frame || def.frame.trim() === "") { + icon.setVisible(false); + icon.setActive(false); + return icon; + } + icon.setInteractive(); + this._makeBouncyButton(icon, _socialScale, () => { + window.open(def.url, "_blank"); + }, () => this._menuActive); + + return icon; + }); + + this._copyrightText = this.add.text(0, 625, "© 2026 RobTop Games · geometrydash.com", { + fontSize: "14px", + color: "#ffffff", + fontFamily: "Arial" + }).setOrigin(1, 1).setScrollFactor(0).setDepth(30).setAlpha(0.3); + this._tryMeImg = this.add.image(0, 150, "GJ_MenuBeta").setScrollFactor(0).setDepth(30).setScale(0.75); + this._downloadBtns = []; + const _0x4fc67f = [{ + key: "downloadSteam_001", + url: "https://github.com/web-dashers/web-dashers.github.io" + }, + { + key: "downloadApple_001", + url: "https://discord.gg/TfEzAVWPSJ" + }]; + for (let _0xfeaf5c = 0; _0xfeaf5c < _0x4fc67f.length; _0xfeaf5c++) { + const _0x1ce2a6 = _0x4fc67f[_0xfeaf5c]; + const _0x6bf69f = 1 / 1.5; + const _0x1d293f = this.add.image(0, 0, "GJ_WebSheet", _0x1ce2a6.key + ".png").setScrollFactor(0).setDepth(30).setScale(_0x6bf69f).setInteractive(); + this._makeBouncyButton(_0x1d293f, _0x6bf69f, () => window.open(_0x1ce2a6.url, "_blank"), () => this._menuActive); + this._downloadBtns.push(_0x1d293f); + } + const _0x28fa5b = this.scale.isFullscreen; +this._menuFsBtn = this.add.image(33, 33, "GJ_WebSheet", _0x28fa5b ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setAlpha(0.8).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); + this._expandHitArea(this._menuFsBtn, 1.5); + this._makeBouncyButton(this._menuFsBtn, 0.64, () => { + const _0x26b7c = !this.scale.isFullscreen; + this._menuFsBtn.setTexture("GJ_WebSheet", _0x26b7c ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png"); + this._expandHitArea(this._menuFsBtn, 1.5); + this._toggleFullscreen(); + }, () => this._menuActive); + this._menuInfoBtn = this.add.image(screenWidth + 20, 33, "GJ_GameSheet03", "communityCreditsBtn_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); + this._expandHitArea(this._menuInfoBtn, 1.5); + this._makeBouncyButton(this._menuInfoBtn, 0.64, () => { + this._buildInfoPopup(); + }, () => this._menuActive && !this._infoPopup); +this._menuUpdateLogBtn = this.add.image(screenWidth - 30 - 50, 33, "GJ_WebSheet", "GJ_infoIcon_001.png").setScrollFactor(0).setDepth(30).setScale(0.64).setTint(Phaser.Display.Color.GetColor(255, 255, 255)).setInteractive(); + this._expandHitArea(this._menuUpdateLogBtn, 1.5); + this._makeBouncyButton(this._menuUpdateLogBtn, 0.64, () => { + this._buildUpdateLogPopup(); + }, () => this._menuActive && !this._updateLogPopup); + this._menuSettingsBtn = this.add.image(centerX + 92, screenHeight - 90, "GJ_GameSheet03", "GJ_optionsBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); + this._expandHitArea(this._menuSettingsBtn, 1); + this._makeBouncyButton(this._menuSettingsBtn, 1, () => { + this._showSettingsScreen(); + }, () => this._menuActive && !this._settingsPopup); + this._menuStatsBtn = this.add.image(centerX + 202, screenHeight - 90, "GJ_GameSheet03", "GJ_statsBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); + this._expandHitArea(this._menuStatsBtn, 1); + this._makeBouncyButton(this._menuStatsBtn, 1, () => { + this._showStatsScreen(); + }, () => this._menuActive); + this._menuAchievementsBtn = this.add.image(centerX - 12, screenHeight - 90, "GJ_GameSheet03", "GJ_achBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setTint(0x666666); + this._expandHitArea(this._menuAchievementsBtn, 1); + this._makeBouncyButton(this._menuAchievementsBtn, 1, () => { + }, () => this._menuActive); + this._menuNewgroundsBtn = this.add.image(centerX + 312, screenHeight - 90, "GJ_GameSheet03", "GJ_ngBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); + this._expandHitArea(this._menuNewgroundsBtn, 1); + this._makeBouncyButton(this._menuNewgroundsBtn, 1, () => { + this._buildNewgroundsPopup(); + }, () => this._menuActive && !this._newgroundsPopup); + this._menuGlitter = this.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + speed: 0, + scale: { + start: 0.5, + end: 0 + }, + alpha: { + start: 0.6, + end: 0.2 + }, + lifespan: { + min: 1000, + max: 2000 + }, + frequency: 35, + blendMode: S, + tint: 20670, + x: { + min: -130, + max: 130 + }, + y: { + min: -100, + max: 100 + } + }).setScrollFactor(0).setDepth(29); + this._playBtn = this.add.image(0, 0, "GJ_GameSheet04", "GJ_playBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); + this._playBtnPressed = false; + this._makeBouncyButton(this._playBtn, 1, () => { + this._openLevelSelect(); + }, () => this._menuActive && !this._playBtnPressed && !this._levelSelectOverlay); + // creator stuff + this._creatorBtn = this.add.image(0, 0, "GJ_GameSheet04", "GJ_creatorBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setScale(1); + this._creatorOverlay = null; + this._creatorOverlayObjects = null; + + this._openCreatorMenu = () => { + if (this._creatorOverlay) return; + this._creatorMenuOpen = true; + + const sw = screenWidth; + const sh = screenHeight; + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + + const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x00 + (0x01 - 0x00) * t); + const g1 = Math.round(0x65 + (0x2c - 0x65) * t); + const b1 = Math.round(0xff + (0x71 - 0xff) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + const bandY = Math.floor(gi * sh / gradientSteps); + const bandH = Math.ceil(sh / gradientSteps) + 1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, bandY, sw, bandH); + } + this._creatorOverlay = overlay; + + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) + .setScrollFactor(0).setDepth(101).setInteractive(); + + const cornerTL = this.add.image(0, 0, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(100).setOrigin(0, 0).setFlipY(true) + const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(152).setOrigin(0, 1).setFlipX(false) + + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true) + .setRotation(Math.PI).setInteractive(); + this._makeBouncyButton(backBtn, 1, () => this._closeCreatorMenu()); + + this._creatorOverlayObjects = [overlay, blocker, cornerTL, cornerBL, backBtn]; + + const menuButtons = [ + "GJ_createBtn_001.png", + "GJ_savedBtn_001.png", + "GJ_highscoreBtn_001.png", + "GJ_challengeBtn_001.png", + "GJ_versusBtn_001.png", + "GJ_mapBtn_001.png", + "GJ_dailyBtn_001.png", + "GJ_weeklyBtn_001.png", + "GJ_eventBtn_001.png", + "GJ_gauntletsBtn_001.png", + "GJ_featuredBtn_001.png", + "GJ_listsBtn_001.png", + "GJ_pathsBtn_001.png", + "GJ_mapPacksBtn_001.png", + "GJ_searchBtn_001.png", + ]; + + const cols = 5; + const btnScale = 0.77; + const btnSize = 209 * btnScale; + const gapX = 18; + const gapY = 18; + const gridW = cols * btnSize + (cols - 1) * gapX; + const gridStartX = sw / 2 - gridW / 2 + btnSize / 2; + const rows = Math.ceil(menuButtons.length / cols); + const gridH = rows * btnSize + (rows - 1) * gapY; + const gridStartY = sh / 2 - gridH / 2 + btnSize / 2; + menuButtons.forEach((frame, idx) => { + const col = idx % cols; + const row = Math.floor(idx / cols); + const bx = gridStartX + col * (btnSize + gapX); + const by = gridStartY + row * (btnSize + gapY); + const btn = this.add.image(bx, by, "GJ_GameSheet04", frame) + .setScrollFactor(0).setDepth(104).setScale(btnScale); + const isSearchButton = frame === "GJ_searchBtn_001.png"; + const isFeaturedButton = frame === "GJ_featuredBtn_001.png"; + const isEditorButton = frame === "GJ_createBtn_001.png"; + const isSavedButton = frame === "GJ_savedBtn_001.png"; + if (isSearchButton) { + btn.setInteractive(); + this._makeBouncyButton(btn, btnScale, () => { + this._closeCreatorMenu(true); + this._openSearchMenu(); + }, () => true); + } else if (isFeaturedButton) { + btn.setInteractive(); + this._makeBouncyButton(btn, btnScale, () => { + this._closeCreatorMenu(true); + this._openOnlineLevelsScene({ type: 6 }); + }, () => true); + } else if (isEditorButton) { + btn.setInteractive(); + this._makeBouncyButton(btn, btnScale, () => { + this._closeCreatorMenu(true); + this._openEditorMenu(); + }, () => true); + } else if (isSavedButton) { + btn.setInteractive(); + this._makeBouncyButton(btn, btnScale, () => { + this._closeCreatorMenu(true); + this._openSavedLevelsScene(); + }, () => true); + } else { + btn.setTint(0x666666); + } + this._creatorOverlayObjects.push(btn); + }); + }; + this._searchOverlay = null; + this._searchOverlayObjects = []; + this._playOverlay = null; + this._playOverlayObjects = []; + this._saveOnlineLevelToSavedList = (lvl) => { + if (!lvl || !lvl.id) return; + try { + const _savedKey = "gd_saved_online_levels"; + let _savedLevels = JSON.parse(localStorage.getItem(_savedKey) || "[]"); + const numericId = String(lvl.id); + const _alreadySaved = _savedLevels.some(sl => String(sl.id) === numericId); + if (!_alreadySaved) { + _savedLevels.unshift({ + id: numericId, + name: lvl.name || "Online Level", + author: lvl.author || "Unknown", + customSongID: lvl.customSongID || null, + songName: lvl.songName || "Unknown", + difficulty: lvl.difficulty || 0, + downloads: lvl.downloads || 0, + likes: lvl.likes || 0, + stars: lvl.stars || 0, + coins: lvl.coins || 0, + coinsVerified: lvl.coinsVerified || false, + length: lvl.length || 0, + featured: !!lvl.featured, + epic: lvl.epic || 0, + savedAt: Date.now() + }); + localStorage.setItem(_savedKey, JSON.stringify(_savedLevels)); + } + } catch (_e) {} + }; + this._openPlayMenu = (onBack = null) => { + if (this._playOverlay) return; + const sw = screenWidth; + const sh = screenHeight; + this._playMenuBackTarget = onBack || (() => this._openCreatorMenu()); + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(600); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + + const overlay = this.add.graphics().setScrollFactor(0).setDepth(500); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x00 + (0x01 - 0x00) * t); + const g1 = Math.round(0x65 + (0x2c - 0x65) * t); + const b1 = Math.round(0xff + (0x71 - 0xff) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + const bandY = Math.floor(gi * sh / gradientSteps); + const bandH = Math.ceil(sh / gradientSteps) + 1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, bandY, sw, bandH); + } + this._playOverlay = overlay; + + const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(502).setOrigin(0, 1).setFlipY(false); + const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(502).setOrigin(1, 1).setFlipX(true); + + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh).setScrollFactor(0).setDepth(501).setInteractive(); + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(504).setFlipX(true).setFlipY(true) + .setRotation(Math.PI).setInteractive(); + this._makeBouncyButton(backBtn, 1, () => { this._closePlayMenu(false, () => this._playMenuBackTarget()); }); + + this._playOverlayObjects.push(overlay, blocker, backBtn, cornerBL, cornerBR); + const lvl = window._selectedLevelData || {}; + if (lvl.id) localStorage.setItem("viewedLevel_" + lvl.id, "1"); + this._saveOnlineLevelToSavedList(lvl); + const centerX = sw / 2; + + const _diffFrames = [ + "difficulty_00_btn_001.png", "difficulty_01_btn_001.png", "difficulty_02_btn_001.png", + "difficulty_03_btn_001.png", "difficulty_04_btn_001.png", "difficulty_05_btn_001.png", + "difficulty_06_btn2_001.png", "difficulty_07_btn2_001.png", "difficulty_08_btn2_001.png", + "difficulty_09_btn2_001.png", "difficulty_10_btn2_001.png", "difficulty_auto_btn_001.png" + ]; + const _diffSizes = { + "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, + "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, + "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, + "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, + "difficulty_06_btn2_001.png": { w: 72, h: 88, rotated: false }, + "difficulty_07_btn2_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_08_btn2_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_09_btn2_001.png": { w: 74, h: 88, rotated: false }, + "difficulty_10_btn2_001.png": { w: 80, h: 91, rotated: false }, + "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, + }; + const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, lvl.difficulty || 0)); + const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; + const _targetH = 100, _maxW = 105; + const _scaleW = _diffMeta ? _diffMeta.w : 90; + const _scaleH = _diffMeta ? _diffMeta.h : 85; + const _iconScale = Math.min(_targetH / _scaleH, _maxW / _scaleW); + + const nameText = this.add.bitmapText(centerX, sh * 0.11 - 30, "bigFont", lvl.name || "Unknown", 50) + .setScrollFactor(0).setDepth(503).setOrigin(0.5); + this._fitBitmapText(nameText, sw * 0.7); + this._playOverlayObjects.push(nameText); + + const authorText = this.add.bitmapText(centerX, nameText.y + 42, "goldFont", "By " + (lvl.author || "Unknown"), 36) + .setScrollFactor(0).setDepth(503).setOrigin(0.5); + this._fitBitmapText(authorText, sw * 0.6); + this._playOverlayObjects.push(authorText); + + const playBtnY = sh * 0.36 - 15; + const playBtn2 = this.add.image(centerX, playBtnY, "GJ_GameSheet03", "GJ_playBtn2_001.png") + .setScrollFactor(0).setDepth(504).setInteractive(); + let playBtnLoading = false; + this._makeBouncyButton(playBtn2, 1, async () => { + if (playBtnLoading) return; + playBtnLoading = true; + this._audio.playEffect("playSound_01", { volume: 1 }); + playBtn2.setTint(0x666666); + playBtn2.disableInteractive(); + + let started = false; + try { + started = await this._playSelectedOnlineLevel(lvl); + } catch (err) { + console.warn("Failed to start selected online level", err); + } + + if (!started && playBtn2.scene) { + playBtnLoading = false; + playBtn2.clearTint(); + playBtn2.setInteractive(); + } + }, () => !playBtnLoading); + this._playOverlayObjects.push(playBtn2); + + const _playStatDefs = [ + { icon: "GJ_downloadsIcon_001.png", value: (Number(lvl.downloads) || 0).toLocaleString("en-US"), scale: 0.9 }, + { icon: "GJ_sLikeIcon_001.png", value: (Number(lvl.likes) || 0).toLocaleString("en-US"), scale: 1.3 }, + { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(lvl.length), scale: 0.9 } + ]; + const _playStatX = centerX + (playBtn2.displayWidth / 2) + 100; + const _playStatGap = 57; + const _playStatY0 = playBtnY - _playStatGap; + const _playStatMaxTextW = (sw - 30) - (_playStatX + 60); + _playStatDefs.forEach((stat, i) => { + const _statY = _playStatY0 + i * _playStatGap; + const statIcon = this.add.image(_playStatX, _statY, "GJ_GameSheet03", stat.icon) + .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(stat.scale); + this._playOverlayObjects.push(statIcon); + const statText = this.add.bitmapText(_playStatX + statIcon.displayWidth / 2 + 12, _statY, "bigFont", stat.value, 30) + .setScrollFactor(0).setDepth(503).setOrigin(0, 0.5); + this._fitBitmapText(statText, _playStatMaxTextW); + this._playOverlayObjects.push(statText); + }); + + const diffIconX = centerX - (playBtn2.displayWidth / 2) - 100; + const diffIconY = playBtnY; + const diffIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", _diffFrames[diffIdx]) + .setScrollFactor(0).setDepth(503).setOrigin(0.5) + if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); + this._playOverlayObjects.push(diffIcon); + + let coinIcon = null; + if (lvl.epic >= 3) { + coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin3_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); + } else if (lvl.epic === 2) { + coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin2_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); + } else if (lvl.epic === 1) { + coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_epicCoin_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); + } else if (lvl.featured) { + coinIcon = this.add.image(diffIconX, diffIconY, "GJ_GameSheet03", "GJ_featuredCoin_001.png").setScrollFactor(0).setDepth(502).setOrigin(0.5); + } + if (coinIcon) this._playOverlayObjects.push(coinIcon); + + const _progressKeyId = "online_" + (lvl.id || "0"); + const _bestNormal = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); + const _bestPractice = parseFloat(localStorage.getItem("practiceBestPercent_" + _progressKeyId) || "0"); + + const _barFrame = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); + const _barW = _barFrame ? _barFrame.width : 680; + const _barH = _barFrame ? _barFrame.height : 40; + + const normalBarY = sh * 0.58 - 15; + const normalLabel = this.add.bitmapText(centerX, normalBarY - 30, "bigFont", "Normal Mode", 32) + .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(0.78); + const normalBarBg = this.add.image(centerX, normalBarY, "GJ_WebSheet", "GJ_progressBar_001.png") + .setScrollFactor(0).setDepth(503).setTint(0).setAlpha(125 / 255).setScale(0.7, 0.69); + const normalFillW = Math.max(1, Math.floor(_barW * (_bestNormal / 100))); + const normalBarFg = this.add.image(centerX - _barW * 0.695 / 2, normalBarY, "GJ_WebSheet", "GJ_progressBar_001.png") + .setScrollFactor(0).setDepth(503).setTint(0x00ff00).setScale(0.695, 0.57).setOrigin(0, 0.5) + .setCrop(0, 0, normalFillW, _barH); + const normalPctText = this.add.bitmapText(centerX, normalBarY, "bigFont", _bestNormal + "%", 30) + .setScrollFactor(0).setDepth(504).setOrigin(0.5).setScale(0.7); + this._playOverlayObjects.push(normalLabel, normalBarBg, normalBarFg, normalPctText); + + const practiceBarY = sh * 0.70 - 25; + const practiceLabel = this.add.bitmapText(centerX, practiceBarY - 30, "bigFont", "Practice Mode", 32) + .setScrollFactor(0).setDepth(503).setOrigin(0.5).setScale(0.78); + const practiceBarBg = this.add.image(centerX, practiceBarY, "GJ_WebSheet", "GJ_progressBar_001.png") + .setScrollFactor(0).setDepth(503).setTint(0).setAlpha(125 / 255).setScale(0.7, 0.7); + const practiceFillW = Math.max(1, Math.floor(_barW * (_bestPractice / 100))); + const practiceBarFg = this.add.image(centerX - _barW * 0.695 / 2, practiceBarY, "GJ_WebSheet", "GJ_progressBar_001.png") + .setScrollFactor(0).setDepth(503).setTint(0x00ffff).setScale(0.695, 0.57).setOrigin(0, 0.5) + .setCrop(0, 0, practiceFillW, _barH); + const practicePctText = this.add.bitmapText(centerX, practiceBarY, "bigFont", _bestPractice + "%", 30) + .setScrollFactor(0).setDepth(504).setOrigin(0.5).setScale(0.7); + this._playOverlayObjects.push(practiceLabel, practiceBarBg, practiceBarFg, practicePctText); + const sideBtnX = sw - 55; + const sideBtnGap = sh * 0.16; + const sideBtnY0 = sh * 0.08 - 100; + const sideBtnScale = 1; + + const rateLockBtn = this.add.image(55, sideBtnY0 + 350, "GJ_GameSheet03", "GJ_duplicateBtn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); + this._makeBouncyButton(rateLockBtn, sideBtnScale, () => { + this._duplicateOnlineLevelToEditor(lvl); + }); + + const closeBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap, "GJ_GameSheet03", "GJ_deleteBtn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); + this._makeBouncyButton(closeBtn, sideBtnScale, () => { + this._closePlayMenu(false, () => this._playMenuBackTarget()); + }); + + const refreshBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 2, "GJ_GameSheet03", "GJ_updateBtn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive(); + this._makeBouncyButton(refreshBtn, sideBtnScale, () => { + const backTarget = this._playMenuBackTarget; + this._closePlayMenu(true, () => this._openPlayMenu(backTarget)); + }); + + const infoBtn2 = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 3, "GJ_GameSheet03", "GJ_infoBtn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); + this._makeBouncyButton(infoBtn2, sideBtnScale, () => { + }); + + const leaderboardBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 4, "GJ_GameSheet03", "GJ_levelLeaderboardBtn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); + this._makeBouncyButton(leaderboardBtn, sideBtnScale, () => { + }); + + const likeBtn = this.add.image(sideBtnX, sideBtnY0 + sideBtnGap * 5, "GJ_GameSheet03", "GJ_like2Btn_001.png") + .setScrollFactor(0).setDepth(504).setScale(sideBtnScale).setInteractive().setTint(0x666666); + this._makeBouncyButton(likeBtn, sideBtnScale, () => { + }); + + this._playOverlayObjects.push(rateLockBtn, closeBtn, refreshBtn, infoBtn2, leaderboardBtn, likeBtn); + const songBoxW = sw * 0.55; + const songBoxH = 190; + const songBoxY = sh - 95; + const _squareCorner = 0.325 * this.textures.get("GJ_square01").source[0].width; + const songBox = this.add.nineslice(centerX, songBoxY, "GJ_square01", null, songBoxW, songBoxH, _squareCorner, _squareCorner, _squareCorner, _squareCorner) + .setScrollFactor(0).setDepth(503).setOrigin(0.5); + this._playOverlayObjects.push(songBox); + + const songNameText = this.add.bitmapText(centerX - songBoxW / 2 + 20, songBoxY - 60, "bigFont", lvl.songName || "Unknown", 50) + .setScrollFactor(0).setDepth(504).setOrigin(0, 0.5) + this._fitBitmapText(songNameText, songBoxW - 100); + this._playOverlayObjects.push(songNameText); + let songAuthor = "Unknown"; + + const songAuthorText = this.add.bitmapText(centerX - songBoxW / 2 + 20, songBoxY - 15, "goldFont", "By: " + songAuthor, 36) + .setScrollFactor(0).setDepth(504).setOrigin(0, 0.5) + this._fitBitmapText(songAuthorText, songBoxW - 100); + this._playOverlayObjects.push(songAuthorText); + + if (lvl.customSongID) { + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + if (!PROXY_BASE) { + console.warn("Play menu song author: window._gdProxyUrl is not configured"); + } else { + fetch(`${PROXY_BASE}/getGJSongInfo.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `songID=${lvl.customSongID}&secret=Wmfd2893gb7` + }) + .then(res => (res.ok ? res.text() : "-1")) + .then(ngText => { + if (!ngText || ngText === "-1") return; + const ngParts = ngText.split("~|~"); + const ngMap = {}; + for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; + + const artistName = (ngMap["4"] || "Unknown").trim(); + if (artistName) { + songAuthor = artistName; + songAuthorText.setText("By: " + songAuthor); + this._fitBitmapText(songAuthorText, songBoxW - 100); + } + }) + .catch(err => { + console.warn("Failed to fetch song author:", err); + }); + } + } + }; + this._closePlayMenu = (silent = false, onComplete = null) => { + if (!this._playOverlay) return; + const destroy = () => { + for (const obj of this._playOverlayObjects) { + if (obj && obj.destroy) obj.destroy(); + } + this._playOverlayObjects = []; + this._playOverlay = null; + }; + if (silent) { destroy(); if (onComplete) onComplete(); return; } + const sw = screenWidth, sh = screenHeight; + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(600).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ + targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", + onComplete: () => { + destroy(); + if (onComplete) onComplete(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._playSelectedOnlineLevel = async (lvl) => { + if (!lvl || !lvl.id) return false; + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + if (!PROXY_BASE) { console.warn("Play online level: window._gdProxyUrl is not configured"); return false; } + try { + const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `levelID=${lvl.id}&secret=Wmfd2893gb7` + }); + if (!res.ok) throw new Error(`Proxy returned ${res.status}`); + const rawResponse = await res.text(); + if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) return false; + + const lvlParts = rawResponse.split("#")[0].split(":"); + const m = {}; + for (let i = 0; i + 1 < lvlParts.length; i += 2) m[lvlParts[i]] = lvlParts[i + 1]; + + const levelString = m["4"] || null; + const officialSong = parseInt(m["12"]) || 0; + const customSongID = (m["35"] || "").trim(); + const isCustomSong = !!customSongID && customSongID !== "0"; + const offset = parseFloat(m["45"] || "0") || 0; + + window._onlineLevelId = "online_" + lvl.id; + window._onlineLevelString = levelString; + window._onlineLevelName = lvl.name || "Online Level"; + window._onlineSongOffset = offset; + window._onlineSongBuffer = null; + window._onlineSongKey = null; + + let songKey = (window.allLevels && window.allLevels[officialSong]) ? window.allLevels[officialSong][0] : `ng_song_${customSongID}`; + let songArtist = "Unknown"; + let songTitle = null; + + if (isCustomSong) { + songKey = `ng_song_${customSongID}`; + try { + const ngRes = await fetch(`${PROXY_BASE}/getGJSongInfo.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `songID=${customSongID}&secret=Wmfd2893gb7` + }); + const ngText = ngRes.ok ? await ngRes.text() : "-1"; + if (ngText && ngText !== "-1") { + const ngParts = ngText.split("~|~"); + const ngMap = {}; + for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; + const songUrl = decodeURIComponent((ngMap["10"] || "").trim()); + songArtist = (ngMap["4"] || "Unknown").replace(/:$/, "").trim(); + songTitle = (ngMap["2"] || "").trim() || null; + if (songUrl) { + const audioCtx = this.game.sound.context; + if (audioCtx.state === "suspended") await audioCtx.resume(); + const proxiedUrl = songUrl.includes("geometrydashfiles.b-cdn.net") + ? songUrl + : `${PROXY_BASE}/audio-proxy?url=${encodeURIComponent(songUrl)}`; + const audioRes = await fetch(proxiedUrl); + const arrayBuf = await audioRes.arrayBuffer(); + const decoded = await audioCtx.decodeAudioData(arrayBuf); + window._onlineSongBuffer = decoded; + window._onlineSongKey = songKey; + } + } + } catch (err) { + console.warn("Failed to load custom song for online level", err); + } + } else if (window.allLevels && window.allLevels[officialSong]) { + songArtist = window.allLevels[officialSong][3] || "Unknown"; + } + window.currentlevel = [songKey, window._onlineLevelName, window._onlineLevelId, ["Online", songArtist]]; + this.game.registry.set("autoStartGame", true); + window._onlineReturnToPlayMenu = { lvl, backTarget: this._playMenuBackTarget }; + this._closePlayMenu(false, () => this.scene.restart()); + return true; + } catch (err) { + console.warn("Failed to start online level", err); + return false; + } + }; + this._duplicateOnlineLevelToEditor = async (lvl) => { + if (!lvl || !lvl.id) return; + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + if (!PROXY_BASE) { console.warn("Duplicate level: window._gdProxyUrl is not configured"); return; } + try { + const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `levelID=${lvl.id}&secret=Wmfd2893gb7` + }); + if (!res.ok) throw new Error(`Proxy returned ${res.status}`); + const rawResponse = await res.text(); + if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) return; + + const lvlParts = rawResponse.split("#")[0].split(":"); + const m = {}; + for (let i = 0; i + 1 < lvlParts.length; i += 2) m[lvlParts[i]] = lvlParts[i + 1]; + + const levelString = m["4"] || ""; + if (!levelString) { console.warn("Duplicate level: no level data in response"); return; } + + const officialSong = parseInt(m["12"]) || 0; + const customSongID = (m["35"] || "").trim(); + const isCustomSong = !!customSongID && customSongID !== "0"; + const levelVersion = parseInt(m["16"]) || 1; + + let songName, songId; + if (isCustomSong) { + songId = parseInt(customSongID) || 0; + songName = lvl.songName || `NG#${customSongID}`; + } else { + songId = -officialSong - 1; + try { songName = window.allLevels[officialSong][1]; } catch (e) { songName = lvl.songName || "Unknown"; } + } + + const rawLevels = localStorage.getItem("created_levels"); + const createdLevels = rawLevels ? JSON.parse(rawLevels) : []; + + const newLevel = { + levelName: lvl.name || "Unknown", + song: songName, + songId: songId, + levelId: lvl.id, + levelString: levelString, + levelLength: lvl.length || 0, + normalBest: 0, + practiceBest: 0, + description: lvl.description || "", + version: levelVersion, + status: "Unverified", + createdId: this._getNextLocalId() + }; + + createdLevels.push(newLevel); + localStorage.setItem("created_levels", JSON.stringify(createdLevels)); + + this._audio.playEffect("build_01"); + this._closePlayMenu(false, () => this._openLevelView(newLevel)); + } catch (err) { + console.warn("Failed to duplicate level to editor:", err); + } + }; + this._openEditorMenu = () => { + if (this._editorOverlay) return; + const sw = screenWidth; + const sh = screenHeight; + const centerX = sw / 2; + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + + const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x00 + (0x01 - 0x00) * t); + const g1 = Math.round(0x65 + (0x2c - 0x65) * t); + const b1 = Math.round(0xff + (0x71 - 0xff) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, Math.floor(gi * sh / gradientSteps), sw, Math.ceil(sh / gradientSteps) + 1); + } + this._editorOverlay = overlay; + + const blocker = this.add.zone(centerX, sh / 2, sw, sh).setScrollFactor(0).setDepth(101).setInteractive(); + const container = this.add.container(0, 0).setScrollFactor(0).setDepth(102); + + const tableW = 712; + const tableH = 460; + const tableX = (sw - tableW) / 2; + const tableY = 85; + + const rawData = localStorage.getItem("created_levels"); + const createdLevels = rawData ? JSON.parse(rawData) : []; + + createdLevels.sort((a, b) => { + const idA = parseInt(a.createdId.replace("local_", "")) || 0; + const idB = parseInt(b.createdId.replace("local_", "")) || 0; + return idB - idA; + }); + + const nameCounts = {}; + const levelRevisions = {}; + + createdLevels.forEach(lvl => { + const name = lvl.levelName; + if (!nameCounts[name]) { + nameCounts[name] = 1; + levelRevisions[lvl.createdId] = ""; + } else { + levelRevisions[lvl.createdId] = `Rev. ${nameCounts[name]}`; + nameCounts[name]++; + } + }); + + const lengthValues = ["Tiny", "Short", "Medium", "Long", "XL", "Plat."] + + const listContainer = this.add.container(0, 0); + const maskShape = this.add.graphics().fillStyle(0xffffff).fillRect(tableX, tableY, tableW, tableH).setVisible(false); + const mask = maskShape.createGeometryMask(); + listContainer.setMask(mask); + container.add(this.add.graphics().setScrollFactor(0).setDepth(90).fillStyle(0xc2723e, 1).fillRect(tableX, tableY, tableW, tableH)); + container.add(listContainer); + + createdLevels.forEach((level, index) => { + const spacing = 100; + const slotY = (index * spacing) + (spacing / 2); + + const isOdd = index % 2 !== 0; + const stripeColor = isOdd ? 0xc2723e : 0xa1582c; + + const bgStripe = this.add.rectangle(centerX, slotY, tableW - 10, spacing, stripeColor, 1); + const separator = this.add.rectangle(centerX, slotY + (spacing / 2), tableW - 10, 1, 0x502c16, 1); + const nameTxt = this.add.bitmapText(tableX + 20, slotY - 22, "bigFont", level.levelName, 32).setOrigin(0, 0.5); + const revLabel = levelRevisions[level.createdId]; + const revText = this.add.bitmapText( + nameTxt.x + nameTxt.width + 10, + nameTxt.y + 5, + "goldFont", + revLabel, + 20 + ).setOrigin(0, 0.5); + const infoY = slotY + 18; + const lenIcon = this.add.image(tableX + 35, infoY, "GJ_GameSheet03", "GJ_timeIcon_001.png").setScale(0.65); + const lenTxt = this.add.bitmapText(lenIcon.x + 22, infoY, "bigFont", lengthValues[parseInt(level.levelLength, 10)] || "Tiny", 18).setOrigin(0, 0.5); + const songIcon = this.add.image(tableX + 150, infoY, "GJ_GameSheet03", "GJ_musicIcon_001.png").setScale(0.65); + const songTxt = this.add.bitmapText(songIcon.x + 22, infoY, "bigFont", level.song, 18).setOrigin(0, 0.5); + const statusIcon = this.add.image(tableX + 380, infoY, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScale(0.65); + const songTxtMaxW = Math.max(20, (statusIcon.x - 25) - songTxt.x); + songTxt.setScale(1); + if (songTxt.width > songTxtMaxW) { + songTxt.setScale(songTxtMaxW / songTxt.width); + } + const statusTxt = this.add.bitmapText(statusIcon.x + 22, infoY, "bigFont", level.status, 18).setOrigin(0, 0.5); + + const viewBtn = this.add.nineslice(tableX + tableW - 80, slotY, "GJ_button01", null, 120, 60, 24, 24, 24, 24 ).setScale(0.75).setInteractive(); + const viewTxt = this.add.bitmapText(viewBtn.x - 2, viewBtn.y - 1, "bigFont", "View", 32).setOrigin(0.5).setScale(0.8); + + this._makeCompositeBouncyButton(viewBtn, [viewBtn, viewTxt], 0.75, () => { + this._closeEditorMenu(false); + this._openLevelView(level); + }); + + listContainer.add([bgStripe, separator, nameTxt, revText, lenIcon, lenTxt, songIcon, songTxt, statusIcon, statusTxt, viewBtn, viewTxt]); + }); + if (createdLevels.length === 0) { + container.add(this.add.bitmapText(centerX, tableY + (tableH/2), "bigFont", "No Levels", 30).setOrigin(0.5).setAlpha(0.5)); + } + const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const sideScaleY = tableH / sideFrame.height; + container.add(this.add.image(tableX - 40, tableY, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, sideScaleY)); + container.add(this.add.image(tableX + tableW + 40, tableY, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY)); + container.add(this.add.image(centerX, tableY - 10, "GJ_WebSheet", "GJ_table_top_001.png")); + container.add(this.add.image(centerX, tableY + tableH + 20, "GJ_WebSheet", "GJ_table_bottom_001.png")); + container.add(this.add.bitmapText(centerX, tableY - 15, "bigFont", "My Levels", 42).setOrigin(0.5).setScale(1.1)); + + let startY = tableY; + const listHeight = createdLevels.length * 100; + const minY = tableY - Math.max(0, listHeight - tableH) - 10; + const maxY = tableY + 22; + + listContainer.y = maxY; + this._scrollTargetY = maxY; + this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => { + if (!this._editorOverlay) return; + this._scrollTargetY -= deltaY; + this._scrollTargetY = Phaser.Math.Clamp(this._scrollTargetY, minY, maxY); + + this.tweens.add({ + targets: listContainer, + y: this._scrollTargetY, + duration: 250, + ease: 'Power2', + overwrite: true + }); + }); + blocker.on('pointerdown', (pointer) => { + startY = pointer.y - listContainer.y; + }); + + blocker.on('pointermove', (pointer) => { + if (pointer.isDown) { + listContainer.y = pointer.y - startY; + listContainer.y = Phaser.Math.Clamp(listContainer.y, minY, maxY); + } + }); + + const newBtnX = sw - 60; + const newBtnY = sh - 55; + const newBtn = this.add.image(newBtnX, newBtnY, "GJ_GameSheet03", "GJ_newBtn_001.png") + .setScale(0.9) + .setInteractive(); + + this._makeBouncyButton(newBtn, 0.9, () => { + const rawData = localStorage.getItem("created_levels"); + let createdLevels = rawData ? JSON.parse(rawData) : []; + + let counter = 0; + while (createdLevels.some(lvl => lvl.levelName === "Unnamed " + counter)) { + counter++; + } + const newName = "Unnamed " + counter; + + const newLevel = { + levelName: newName, + song: "Stereo Madness", + songId: -1, + levelId: null, + levelString: "H4sIAAAAAAAACq1QwRHDMAhbyO0hwIlzfWWGDsAAXaHD10Z-9Ff3Ln4gG4GMeD2tFYRLaEBrWGitARCUwKTHDbEFRCT2wF3yBOrXvYVEC7wRKSi6JoirBY8FwdHB9iVJjZ5ckP1rlf19taIv7pLGh-wP43XROPq9z9mOtX1uS7LldcKKzPx41ZKwEbz0yPueUSfPF9qApx3kMlrGJE7PSBbCIlYpy5QVuheMciE0AgiaoFRUihk5I2ec0Knp1PTK9slxYDM2OIFmjL8bv-1mBmB6YrvO4UErHR4fJXMaP9sDAAA=", + levelLength: 0, + normalBest: 0, + practiceBest: 0, + description: "", + version: 1, + status: "Unverified", + createdId: this._getNextLocalId() + }; + + createdLevels.push(newLevel); + localStorage.setItem("created_levels", JSON.stringify(createdLevels)); + + this._closeEditorMenu(); + this._openLevelView(newLevel); + + this._audio.playEffect("build_01"); + }); + container.add(newBtn); + + const importBtn = this.add.image(newBtnX, newBtnY - 90, "import").setScale(0.3).setInteractive(); + this._makeBouncyButton(importBtn, 0.3, () => { + this._importGMD(); + }); + container.add(importBtn); + + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true).setRotation(Math.PI).setInteractive(); + + this._makeBouncyButton(backBtn, 1, () => { + this._closeEditorMenu(); + this._openCreatorMenu(); + }); + + this._editorObjects = [overlay, blocker, container, backBtn, maskShape]; + }; + this._importGMD = () => { + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.gmd'; + + fileInput.onchange = (e) => { + const file = e.target.files[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = (event) => { + const content = event.target.result; + try { + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(content, "text/xml"); + const keys = xmlDoc.querySelectorAll("key, k"); + + let extracted = { + name: "Imported Level", + data: "", + version: 1, + length: 0, + id: "NA", + desc: "", + officialSongId: 0, + customSongId: 0 + }; + + keys.forEach(keyNode => { + const k = keyNode.textContent; + const v = keyNode.nextElementSibling; + if (!v) return; + const val = v.textContent; + + if (k === "k2") extracted.name = val; + if (k === "k4") extracted.data = val; + if (k === "k1") extracted.id = val; + if (k === "k23") extracted.length = parseInt(val) || 0; + if (k === "k16") extracted.version = parseInt(val) || 1; + if (k === "k8") extracted.officialSongId = parseInt(val) || 0; + if (k === "k45") extracted.customSongId = parseInt(val) || 0; + if (k === "k3") { + try { extracted.desc = atob(val); } catch(e) { extracted.desc = val; } + } + }); + + if (!extracted.data) throw new Error("No level string found."); + + let finalSongName = "Stereo Madness"; + let finalSongId = -1; + + if (extracted.customSongId > 0) { + finalSongId = extracted.customSongId; + finalSongName = `NG#${extracted.customSongId}`; + } else { + finalSongId = -extracted.officialSongId -1; + try { + finalSongName = window.allLevels[extracted.officialSongId][1]; + } catch(e) { + finalSongName = "Unknown"; + } + } + + const rawLevels = localStorage.getItem("created_levels"); + let createdLevels = rawLevels ? JSON.parse(rawLevels) : []; + + const newLevel = { + levelName: extracted.name, + song: finalSongName, + songId: finalSongId, + levelId: (extracted.id === "0" || !extracted.id) ? "NA" : extracted.id, + levelString: extracted.data, + levelLength: extracted.length, + normalBest: 0, + practiceBest: 0, + description: extracted.desc || "", + version: extracted.version, + status: "Unverified", + createdId: this._getNextLocalId() + }; + + createdLevels.push(newLevel); + localStorage.setItem("created_levels", JSON.stringify(createdLevels)); + + this._closeEditorMenu(false); + this._openLevelView(newLevel); + + } catch (err) { + console.error("GMD Import Error:", err); + alert("Failed to parse .gmd: " + err.message); + } + }; + reader.readAsText(file); + }; + + fileInput.click(); + }; + this._escapeXml = (value) => { + return String(value ?? "") + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + }; + this._decodeWebLevelStringForGMD = (levelString) => { + if (!levelString) return ""; + try { + let base64 = String(levelString) + .trim() + .replace(/-/g, "+") + .replace(/_/g, "/"); + + while (base64.length % 4 !== 0) { + base64 += "="; + } + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return pako.inflate(bytes, { to: "string" }); + } catch (err) { + console.warn("Why the fuck didnt it work", err); + return String(levelString); + } + }; + this._exportGMD = (level) => { + const encodedDesc = btoa(unescape(encodeURIComponent(level.description || ""))); + const authorName = "Web Dashers"; + const officialSong = level.songId < 0 ? Math.abs(level.songId) : 0; + const customSong = level.songId > 0 ? level.songId : 0; + const rawLevelData = this._decodeWebLevelStringForGMD(level.levelString); + const safeName = this._escapeXml(level.levelName || "Unnamed"); + const safeDesc = this._escapeXml(encodedDesc); + const safeAuthor = this._escapeXml(authorName); + const safeLevelData = this._escapeXml(rawLevelData); + + let xml = ""; + xml += ''; + xml += ''; + xml += ''; + xml += 'kCEK4'; + xml += `k1${ + level.levelId && level.levelId !== "NA" + ? String(level.levelId).replace(/\D/g, "") + : 0 + }`; + xml += `k2${safeName}`; + xml += `k3${safeDesc}`; + xml += `k4${safeLevelData}`; + xml += `k5${safeAuthor}`; + xml += `k8${officialSong - 1}`; + xml += `k45${customSong}`; + xml += `k16${level.version || 1}`; + xml += `k18${level.levelLength || 0}`; + xml += `k23${level.levelLength || 0}`; + xml += 'k13'; + xml += 'k212'; + xml += 'k5047'; + xml += 'k1010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0'; + xml += 'kI10'; + xml += 'kI20'; + xml += 'kI30.1'; + xml += 'kI6'; + xml += '00102030'; + xml += '40506070'; + xml += '8090100110'; + xml += '120130'; + xml += ''; + xml += ''; + xml += ''; + + const blob = new Blob([xml], { type: "text/xml" }); + const url = window.URL.createObjectURL(blob); + const link = document.createElement("a"); + const fileName = `${String(level.levelName || "Unnamed").replace(/[^a-z0-9]/gi, "_")}.gmd`; + + link.href = url; + link.download = fileName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + }; + this._getNextLocalId = () => { + const rawData = localStorage.getItem("created_levels"); + const levels = rawData ? JSON.parse(rawData) : []; + let maxId = 0; + levels.forEach(l => { + if (l.createdId && typeof l.createdId === "string") { + const idNum = parseInt(l.createdId.split('_')[1]); + if (!isNaN(idNum) && idNum > maxId) { + maxId = idNum; + } + } + }); + return "local_" + (maxId + 1); + }; + this._openLevelView = (level) => { + const sw = screenWidth; + const sh = screenHeight; + const centerX = sw / 2; + const saveToLS = (key, val) => { + const rawData = localStorage.getItem("created_levels"); + let levels = rawData ? JSON.parse(rawData) : []; + const idx = levels.findIndex(l => l.createdId === level.createdId); + if (idx !== -1) { + levels[idx][key] = val; + localStorage.setItem("created_levels", JSON.stringify(levels)); + } + }; + const deleteLevel = () => { + if (!confirm(`Are you sure you want to delete ${level.levelName}?`)) return; + const rawData = localStorage.getItem("created_levels"); + let levels = rawData ? JSON.parse(rawData) : []; + levels = levels.filter(l => l.createdId !== level.createdId); + localStorage.setItem("created_levels", JSON.stringify(levels)); + cleanup(); + this._openEditorMenu(); + }; + this._activeInput = null; + let cursorVisible = true; + + const blocker = this.add.zone(centerX, sh / 2, sw, sh) + .setOrigin(0.5).setDepth(101).setInteractive(); + blocker.on('pointerdown', () => { this._activeInput = null; }); + const overlay = this.add.graphics().setScrollFactor(0).setDepth(102); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x00 + (0x01 - 0x00) * t); + const g1 = Math.round(0x65 + (0x2c - 0x65) * t); + const b1 = Math.round(0xff + (0x71 - 0xff) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, Math.floor(gi * sh / gradientSteps), sw, Math.ceil(sh / gradientSteps) + 1); + } + + const container = this.add.container(0, 0).setDepth(150); + const boxWidth = sw * 0.6; + const cornerRad = 18; + + const nameY = 50; + const nameBox = this.add.graphics().setDepth(151).setInteractive(new Phaser.Geom.Rectangle(centerX - (boxWidth / 2), nameY - 28, boxWidth, 70), Phaser.Geom.Rectangle.Contains); + nameBox.fillStyle(0x000000, 0.3).fillRoundedRect(centerX - (boxWidth / 2), nameY - 28, boxWidth, 70, cornerRad); + const titleText = this.add.bitmapText(centerX, nameY + 5, "bigFont", level.levelName, 45).setOrigin(0.5).setDepth(152); + const titleCursor = this.add.bitmapText(0, nameY + 5, "bigFont", "|", 45).setOrigin(0, 0.5).setDepth(153).setVisible(false); + + const descY = 180; + const descH = 120; + const descBox = this.add.graphics().setDepth(151).setInteractive(new Phaser.Geom.Rectangle(centerX - (boxWidth / 2), descY - (descH / 2), boxWidth, descH), Phaser.Geom.Rectangle.Contains); + descBox.fillStyle(0x000000, 0.3).fillRoundedRect(centerX - (boxWidth / 2), descY - (descH / 2), boxWidth, descH, cornerRad); + const descText = this.add.text(centerX, descY, level.description || "Description [Optional]", { + fontFamily: "Helvetica, Arial, sans-serif", + fontSize: "22px", + color: "#ffffff", + align: "center", + lineSpacing: 4, + wordWrap: { width: boxWidth - 40, useAdvancedWrap: true } + }).setOrigin(0.5).setDepth(152); + const descCursor = this.add.text(0, 0, "|", { fontFamily: "Helvetica", fontSize: "18px", color: "#ffffff" }) + .setOrigin(0.5).setDepth(153).setVisible(false); + + const updateDisplay = () => { + titleText.setText(level.levelName); + if (this._activeInput === 'title') { + titleCursor.setPosition(titleText.x + (titleText.width / 2) + 2, nameY + 5).setVisible(cursorVisible); + descCursor.setVisible(false); + } + else if (this._activeInput === 'desc') { + descText.setText(level.description || ""); + titleCursor.setVisible(false); + + const lines = descText.getWrappedText(level.description || ""); + const lineCount = lines.length; + const lastLine = lines[lineCount - 1] || ""; + const metrics = descText.canvas.getContext('2d').measureText(lastLine); + const lastLineWidth = metrics.width; + + const size = 22; + const spacing = 4; + const fullLineHeight = size + spacing; + const totalHeight = (lineCount * fullLineHeight) - spacing; + + const topOfText = descY - (totalHeight / 2); + const cursorY = topOfText + ((lineCount - 1) * fullLineHeight) + (size / 2); + + descCursor.setPosition(centerX + (lastLineWidth / 2) + 2, cursorY).setVisible(cursorVisible); + } else { + descText.setText(level.description || "Description [Optional]"); + titleCursor.setVisible(false); + descCursor.setVisible(false); + } + }; + + const cursorInterval = setInterval(() => { + cursorVisible = !cursorVisible; + updateDisplay(); + }, 500); + + const keyHandler = (event) => { + if (!this._activeInput) return; + if (event.key === "Backspace") { + if (this._activeInput === 'title') level.levelName = level.levelName.slice(0, -1); + else level.description = (level.description || "").slice(0, -1); + } else if (event.key === "Enter") { + this._activeInput = null; + } else if (event.key.length === 1) { + if (this._activeInput === 'title' && level.levelName.length < 20) { + level.levelName += event.key; + } else if (this._activeInput === 'desc' && (level.description || "").length < 150) { + level.description = (level.description || "") + event.key; + } + } + saveToLS(this._activeInput === 'title' ? "levelName" : "description", + this._activeInput === 'title' ? level.levelName : level.description); + cursorVisible = true; + updateDisplay(); + }; + + window.addEventListener('keydown', keyHandler); + nameBox.on('pointerdown', () => { this._activeInput = 'title'; updateDisplay(); }); + descBox.on('pointerdown', () => { this._activeInput = 'desc'; updateDisplay(); }); + + const cleanup = () => { + clearInterval(cursorInterval); + window.removeEventListener('keydown', keyHandler); + container.destroy(); + overlay.destroy(); + blocker.destroy(); + this._levelViewOverlay = null; + this._closeLevelView = null; + }; + this._levelViewOverlay = overlay; + this._closeLevelView = () => { cleanup(); this._openEditorMenu(); }; + + const btnY = sh * 0.58; + const editBtn = this.add.image(centerX - 220, btnY, "GJ_GameSheet03", "GJ_editBtn_001.png").setInteractive().setScale(1.1); + this._makeBouncyButton(editBtn, 1.1, () => { cleanup(); this._startCreatedLevel(level, true); }); + const playBtn = this.add.image(centerX, btnY, "GJ_GameSheet03", "GJ_playBtn2_001.png").setInteractive().setScale(1.1); + let playBtnLoading = false; + this._makeBouncyButton(playBtn, 1.1, async () => { + if (playBtnLoading) return; + playBtnLoading = true; + this._audio.playEffect("playSound_01", { volume: 1 }); + playBtn.setTint(0x666666); + playBtn.disableInteractive(); + + let started = false; + try { + started = await this._startCreatedLevel(level, false, cleanup); + } catch (err) { + console.warn("Failed to start saved level", err); + } + + if (!started && playBtn.scene) { + playBtnLoading = false; + playBtn.clearTint(); + playBtn.setInteractive(); + } + }, () => !playBtnLoading); + const shareBtn = this.add.image(centerX + 220, btnY, "GJ_GameSheet03", "GJ_shareBtn_001.png").setInteractive().setScale(1.1); + this._makeBouncyButton(shareBtn, 1.1, () => { this._exportGMD(level); }); + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png").setFlipX(true).setFlipY(true).setRotation(Math.PI).setInteractive(); + this._makeBouncyButton(backBtn, 1, () => { this._closeLevelView(); }); + const deleteBtn = this.add.image(sw - 50, 48, "GJ_GameSheet03", "GJ_deleteBtn_001.png").setInteractive().setScale(0.8); + this._makeBouncyButton(deleteBtn, 0.8, () => { deleteLevel(); }); + + const footerY = sh - 100; + const subFooterY = sh - 30; + const lengthValues = ["Tiny", "Short", "Medium", "Long", "XL", "Plat."] + + const lengthIcon = this.add.image(centerX - 350, footerY, "GJ_GameSheet03", "GJ_timeIcon_001.png").setScale(1).setDepth(152); + const lengthLabel = this.add.bitmapText(centerX - 310, footerY, "bigFont", lengthValues[parseInt(level.levelLength, 10)] || "Tiny", 33).setOrigin(0, 0.5).setDepth(152); + const songIcon = this.add.image(centerX - 160, footerY, "GJ_GameSheet03", "GJ_musicIcon_001.png").setScale(1).setDepth(152); + const songLabel = this.add.bitmapText(centerX - 115, footerY, "bigFont", level.song, 29).setOrigin(0, 0.5).setDepth(152); + const statusIcon = this.add.image(centerX + 200, footerY, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScale(1).setDepth(152); + const songLabelMaxW = Math.max(40, (statusIcon.x - 30) - songLabel.x); + songLabel.setScale(1); + if (songLabel.width > songLabelMaxW) { + songLabel.setScale(songLabelMaxW / songLabel.width); + } + const statusLabel = this.add.bitmapText(centerX + 245, footerY, "bigFont", level.status, 33).setOrigin(0, 0.5).setDepth(152); + const versionText = this.add.bitmapText(centerX - 180, subFooterY, "goldFont", `Version: ${level.version || 1}`, 30).setOrigin(0.5).setDepth(152); + const idText = this.add.bitmapText(centerX + 180, subFooterY, "goldFont", `ID: ${level.levelId || "na"}`, 30).setOrigin(0.5).setDepth(152); + + container.add([nameBox, titleText, titleCursor, descBox, descText, descCursor, playBtn, editBtn, shareBtn, backBtn, deleteBtn, lengthIcon, lengthLabel, songIcon, songLabel, statusIcon, statusLabel, versionText, idText]); + }; + this._startCreatedLevel = async (level, isEditor, onBeforeRestart = null) => { + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + window._onlineLevelString = level.levelString; + window._onlineLevelName = level.levelName; + window._onlineLevelId = level.createdId; + if (!isEditor) { + window._createdLevelReturnToView = { + createdId: level.createdId, + snapshot: { ...level } + }; + } + window._onlineSongBuffer = null; + window._onlineSongKey = null; + window._onlineSongOffset = 0; + window.isEditor = !!isEditor; + this.game.registry.set("autoStartGame", true); + window.currentlevel = [ + "Placeholder", + level.levelName, + level.createdId, + ["Local", "SongAuthor"] + ]; + if (level.songId < 0){ + window.currentlevel[0] = window.allLevels[Math.abs(level.songId) - 1][0]; + window.currentlevel[3] = ["Local", window.allLevels[Math.abs(level.songId) - 1][3]] + } else { + const songId = level.songId; + const songKey = `ng_song_${songId}`; + window.currentlevel[0] = songKey; + + if (PROXY_BASE && songId > 0) { + try { + const ngRes = await fetch(`${PROXY_BASE}/getGJSongInfo.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: `songID=${songId}&secret=Wmfd2893gb7` + }); + + const ngText = ngRes.ok ? await ngRes.text() : "-1"; + if (ngText && ngText !== "-1") { + const ngParts = ngText.split("~|~"); + const ngMap = {}; + for (let i = 0; i + 1 < ngParts.length; i += 2) ngMap[ngParts[i]] = ngParts[i + 1]; + + const songUrl = decodeURIComponent((ngMap["10"] || "").trim()); + const songArtist = (ngMap["4"] || "Unknown").replace(/:$/, "").trim(); + const songTitle = (ngMap["2"] || `Song #${songId}`).replace(/:$/, "").trim(); + + if (songUrl) { + const audioCtx = this.game.sound.context; + if (audioCtx.state === "suspended") await audioCtx.resume(); + const proxiedUrl = songUrl.includes("geometrydashfiles.b-cdn.net") + ? songUrl + : `${PROXY_BASE}/audio-proxy?url=${encodeURIComponent(songUrl)}`; + const audioRes = await fetch(proxiedUrl); + const arrayBuf = await audioRes.arrayBuffer(); + const decoded = await audioCtx.decodeAudioData(arrayBuf); + window._onlineSongBuffer = decoded; + window._onlineSongKey = songKey; + window._onlineSongTitle = songTitle; + window._onlineSongArtist = songArtist; + + window.currentlevel[3] = ["Local", window._onlineSongArtist] + } + } + } catch (err) { + console.warn("Failed to load custom song", err); + } + } + } + if (onBeforeRestart) onBeforeRestart(); + this.scene.restart(); + return true; + }; + this._closeEditorMenu = () => { + if (this._editorObjects) { + this._editorObjects.forEach(obj => obj.destroy()); + } + this._editorOverlay = null; + this._editorObjects = null; + }; + this._openSearchMenu = () => { + if (this._searchOverlay) return; + const sw = screenWidth; + const sh = screenHeight; + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x00 + (0x01 - 0x00) * t); + const g1 = Math.round(0x65 + (0x2c - 0x65) * t); + const b1 = Math.round(0xff + (0x71 - 0xff) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + const bandY = Math.floor(gi * sh / gradientSteps); + const bandH = Math.ceil(sh / gradientSteps) + 1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, bandY, sw, bandH); + } + this._searchOverlay = overlay; + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh).setScrollFactor(0).setDepth(101).setInteractive(); + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(104).setFlipX(true).setFlipY(true) + .setRotation(Math.PI).setInteractive(); + this._makeBouncyButton(backBtn, 1, () => { this._closeSearchMenu(false, () => this._openCreatorMenu()); }); + + const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); + const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1); + const panelMarginX = sw * 0.18; + const panelLeft = panelMarginX; + const panelRight = sw - panelMarginX; + const panelW = panelRight - panelLeft; + const panelRadius = 10; + const panelColor = 0x002e75; + const topPanelColor = 0x00388d; + const innerPanelColor = 0x002762; + const filtersPanelColor = 0x00245b; + const extraPanelColor = 0x001f4f; + const panelAlpha = 0.7; + const labelSize = 32; + const labelColor = 0xffffff; + const gfx = this.add.graphics().setScrollFactor(0).setDepth(104); + const topPanelY = sh * 0.10 - 40; + const topPanelH = sh * 0.12; + gfx.fillStyle(topPanelColor, panelAlpha); + gfx.fillRoundedRect(panelLeft, topPanelY, panelW, topPanelH, panelRadius); + const innerPanelY = topPanelY + 10; + const innerPanelX = panelLeft + 10; + const innerPanelW = panelW * 0.57; + const innerPanelH = topPanelH - 20; + gfx.fillStyle(innerPanelColor, panelAlpha); + gfx.fillRoundedRect(innerPanelX, innerPanelY, innerPanelW, innerPanelH, panelRadius); + + const innerBtnX = innerPanelX + innerPanelW + 20; + const innerBtnY = innerPanelY + (innerPanelH / 2); + + const innerBtn2 = this.add.image(innerBtnX + 137, innerBtnY, "GJ_GameSheet03", "GJ_longBtn05_001.png") + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); + this._makeBouncyButton(innerBtn2, 1, () => {}); + const innerBtn1 = this.add.image(innerBtnX + 47, innerBtnY, "GJ_GameSheet03", "GJ_longBtn06_001.png") + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); + this._makeBouncyButton(innerBtn1, 1, () => { _doSearch(); }); + + const innerBtn3 = this.add.image(innerBtnX + 231, innerBtnY, "GJ_GameSheet03", "GJ_longBtn07_001.png") + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setInteractive(); + this._makeBouncyButton(innerBtn3, 1, () => { inputText = ""; _updateInputDisplay(); }); + + const allowedChars = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + const inputMaxLen = 64; + const inputCX = innerPanelX + innerPanelW / 2; + const inputCY = innerPanelY + innerPanelH / 2; + + let inputText = ""; + let inputFocused = false; + let cursorVisible = false; + let cursorTimer = null; + const placeholderLabel = this.add.bitmapText(inputCX - 5, inputCY, "bigFont", "Enter a level, user or id", 28) + .setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5) + .setTint(0x6c99d8).setAlpha(0.85); + const typedLabel = this.add.bitmapText(innerPanelX + 10, inputCY, "bigFont", "", 46) + .setScrollFactor(0).setDepth(106).setOrigin(0, 0.5) + .setTint(0xffffff).setVisible(false); + const inputCursor = this.add.text(0, inputCY, "|", { + fontSize: "33px", fontFamily: "Arial", color: "#92a7c0" + }).setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false); + + const _updateInputDisplay = () => { + if (inputText === "") { + typedLabel.setVisible(false); + placeholderLabel.setVisible(true); + } else { + placeholderLabel.setVisible(false); + typedLabel.setText(inputText).setVisible(true); + } + if (inputFocused) { + const textW = inputText === "" ? 0 : typedLabel.width; + const textLeft = innerPanelX + 10; + inputCursor.x = textLeft + textW + 2; + inputCursor.setVisible(cursorVisible); + } else { + inputCursor.setVisible(false); + } + }; + + const _startCursorBlink = () => { + cursorVisible = true; + _updateInputDisplay(); + if (cursorTimer) cursorTimer.remove(); + cursorTimer = null; + }; + + const _stopCursorBlink = () => { + if (cursorTimer) { cursorTimer.remove(); cursorTimer = null; } + cursorVisible = false; + inputCursor.setVisible(false); + }; + + const _focusInput = () => { + inputFocused = true; + _startCursorBlink(); + }; + + const _blurInput = () => { + inputFocused = false; + _stopCursorBlink(); + _updateInputDisplay(); + }; + const inputHitZone = this.add.zone( + innerPanelX + innerPanelW / 2, innerPanelY + innerPanelH / 2, + innerPanelW, innerPanelH + ).setScrollFactor(0).setDepth(107).setInteractive(); + inputHitZone.on("pointerdown", () => _focusInput()); + + blocker.on("pointerdown", () => { if (inputFocused) _blurInput(); }); + const _onKeyDown = (event) => { + if (!inputFocused) return; + event.stopPropagation(); + if (event.key === "Backspace") { + if (inputText.length > 0) { + inputText = inputText.slice(0, -1); + _updateInputDisplay(); + } + } else if (event.key === "Enter") { + _doSearch(); + } else if (event.ctrlKey || event.metaKey) { + if (event.key === "c" || event.key === "C") { + event.preventDefault(); + navigator.clipboard.writeText(inputText); + } else if (event.key === "v" || event.key === "V") { + event.preventDefault(); + navigator.clipboard.readText().then(pastedText => { + const filtered = pastedText.split('').filter(c => allowedChars.includes(c)).join(''); + if (filtered.length > 0) { + const availableSpace = inputMaxLen - inputText.length; + inputText += filtered.slice(0, availableSpace); + _updateInputDisplay(); + } + }).catch(() => {}); + } else if (event.key === "a" || event.key === "A") { + event.preventDefault(); + } + } else if (event.key.length === 1 && allowedChars.includes(event.key) && !event.ctrlKey) { + if (inputText.length < inputMaxLen) { + inputText += event.key; + _updateInputDisplay(); + } + } + }; + window.addEventListener("keydown", _onKeyDown); + + const htmlInput = { + remove: () => { + window.removeEventListener("keydown", _onKeyDown); + window.removeEventListener("keydown", _onEnterKeydown); + window.removeEventListener("keyup", _onKeyUpStop); + window.removeEventListener("keypress", _onKeyPressStop); + _blurInput(); + }, + get value() { return inputText; }, + }; + const _onEnterKeydown = (e) => { + if (e.key === "Enter") _doSearch(); + e.stopPropagation(); + }; + const _onKeyUpStop = (e) => e.stopPropagation(); + const _onKeyPressStop = (e) => e.stopPropagation(); + window.addEventListener("keydown", _onEnterKeydown); + window.addEventListener("keyup", _onKeyUpStop); + window.addEventListener("keypress", _onKeyPressStop); + const _repositionInput = () => {}; + const qsLabelY = sh * 0.195; + const qsPanelY = qsLabelY + 25; + const qsPanelH = sh * 0.36; + const qsLabel = this.add.bitmapText(sw / 2, qsLabelY, "bigFont", "Quick Search", labelSize) + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(labelColor); + + gfx.fillStyle(panelColor, panelAlpha); + gfx.fillRoundedRect(panelLeft, qsPanelY, panelW, qsPanelH, panelRadius); + const gridRows = 3; + const gridCols = 3; + const qsPadX = 14; + const qsPadY = 14.5; + const qsGapX = 10; + const qsGapY = 12; + const totalBtnW = panelW - qsPadX * 2; + const totalBtnH = qsPanelH - qsPadY * 2; + const btnW = (totalBtnW - qsGapX * (gridCols - 1)) / gridCols; + const btnH = (totalBtnH - qsGapY * (gridRows - 1)) / gridRows; + + const lbFrame = this.textures.getFrame("GJ_GameSheet03", "GJ_longBtn01_001.png"); + const lbBorder = Math.round(lbFrame.height * 0.28); + + for (let row = 0; row < gridRows; row++) { + for (let col = 0; col < gridCols; col++) { + const btnCX = panelLeft + qsPadX + col * (btnW + qsGapX) + btnW / 2; + const btnCY = qsPanelY + qsPadY + row * (btnH + qsGapY) + btnH / 2; + + const atlas = this.textures.get("GJ_GameSheet03"); + const frameX = lbFrame.cutX; + const frameY = lbFrame.cutY; + const frameW = lbFrame.cutWidth; + const frameH = lbFrame.cutHeight; + const midW = btnW - lbBorder * 2; + const midH = btnH - lbBorder * 2; + const tag = `_lbqs_${row}_${col}`; + + const pieces = [ + { sx: frameX, sy: frameY, sw: lbBorder, sh: lbBorder, dx: -btnW/2, dy: -btnH/2, dw: lbBorder, dh: lbBorder }, + { sx: frameX + lbBorder, sy: frameY, sw: frameW-lbBorder*2, sh: lbBorder, dx: -btnW/2 + lbBorder, dy: -btnH/2, dw: midW, dh: lbBorder }, + { sx: frameX + frameW - lbBorder, sy: frameY, sw: lbBorder, sh: lbBorder, dx: btnW/2 - lbBorder, dy: -btnH/2, dw: lbBorder, dh: lbBorder }, + { sx: frameX, sy: frameY + lbBorder, sw: lbBorder, sh: frameH-lbBorder*2, dx: -btnW/2, dy: -btnH/2 + lbBorder, dw: lbBorder, dh: midH }, + { sx: frameX + lbBorder, sy: frameY + lbBorder, sw: frameW-lbBorder*2, sh: frameH-lbBorder*2, dx: -btnW/2 + lbBorder, dy: -btnH/2 + lbBorder, dw: midW, dh: midH }, + { sx: frameX + frameW - lbBorder, sy: frameY + lbBorder, sw: lbBorder, sh: frameH-lbBorder*2, dx: btnW/2 - lbBorder, dy: -btnH/2 + lbBorder, dw: lbBorder, dh: midH }, + { sx: frameX, sy: frameY + frameH - lbBorder, sw: lbBorder, sh: lbBorder, dx: -btnW/2, dy: btnH/2 - lbBorder, dw: lbBorder, dh: lbBorder }, + { sx: frameX + lbBorder, sy: frameY + frameH - lbBorder, sw: frameW-lbBorder*2, sh: lbBorder, dx: -btnW/2 + lbBorder, dy: btnH/2 - lbBorder, dw: midW, dh: lbBorder }, + { sx: frameX + frameW - lbBorder, sy: frameY + frameH - lbBorder, sw: lbBorder, sh: lbBorder, dx: btnW/2 - lbBorder, dy: btnH/2 - lbBorder, dw: lbBorder, dh: lbBorder }, + ]; + + const btnContainer = this.add.container(btnCX, btnCY).setScrollFactor(0).setDepth(105); + const bgPieces = []; + pieces.forEach((p, i) => { + const frameKey = `${tag}_p${i}`; + if (!atlas.has(frameKey)) { + atlas.add(frameKey, 0, p.sx, p.sy, p.sw, p.sh); + } + const bgPiece = this.add.image(p.dx, p.dy, "GJ_GameSheet03", frameKey) + .setOrigin(0, 0).setDisplaySize(p.dw, p.dh); + bgPieces.push(bgPiece); + btnContainer.add(bgPiece); + }); + + const hitZone = this.add.zone(0, 0, btnW, btnH).setInteractive(); + btnContainer.add(hitZone); + + const qsLabels = [ + ["Downloads", "Likes", "Sent" ], + ["Trending", "Recent", "Magic" ], + ["Awarded", "Followed", "Friends"], + ]; + const qsIcons = [ + ["GJ_sDownloadIcon_001.png", "GJ_sLikeIcon_001.png", "GJ_sModIcon_001.png" ], + ["GJ_sTrendingIcon_001.png", "GJ_sRecentIcon_001.png", "GJ_sMagicIcon_001.png" ], + ["GJ_sStarsIcon_001.png", "GJ_sFollowedIcon_001.png", "GJ_sFriendsIcon_001.png"], + ]; + const labelStr = qsLabels[row][col]; + const iconFrame = qsIcons[row][col]; + const fontSize = labelStr === "Downloads" ? 26 : 32; + + const iconSize = btnH * 0.54; + const gap = 10; + const tmpLbl = this.add.bitmapText(0, -9999, "bigFont", labelStr, fontSize).setOrigin(0, 0.5); + const measuredW = tmpLbl.width; + tmpLbl.destroy(); + + const groupW = measuredW + gap + iconSize; + const groupLeft = -groupW / 2; + + const lbl = this.add.bitmapText(groupLeft, -1, "bigFont", labelStr, fontSize) + .setOrigin(0, 0.5).setScrollFactor(0).setDepth(106); + btnContainer.add(lbl); + + const qsIconSizes = { + "GJ_sDownloadIcon_001.png": { w: 30, h: 30, scale: 1 }, + "GJ_sLikeIcon_001.png": { w: 31, h: 37, scale: 1 }, + "GJ_sModIcon_001.png": { w: 31, h: 31, scale: 1 }, + "GJ_sTrendingIcon_001.png": { w: 33, h: 25, scale: 1 }, + "GJ_sRecentIcon_001.png": { w: 31, h: 29, scale: 1 }, + "GJ_sMagicIcon_001.png": { w: 33, h: 30, scale: 1 }, + "GJ_sStarsIcon_001.png": { w: 30, h: 29, scale: 1 }, + "GJ_sFollowedIcon_001.png": { w: 31, h: 29, scale: 1 }, + "GJ_sFriendsIcon_001.png": { w: 35, h: 29, scale: 1 }, + }; + const iconConfig = qsIconSizes[iconFrame]; + const iconScale = iconConfig.scale; + const iconW = iconConfig.w * iconScale; + const iconH = iconConfig.h * iconScale; + const iconCX = groupLeft + measuredW + gap + iconW / 2 + 5; + const iconY = iconFrame === "GJ_sLikeIcon_001.png" ? 2 : (labelStr === "Downloads" ? -2 : -1); + const icon = this.add.image(iconCX, iconY, "GJ_GameSheet03", iconFrame) + .setOrigin(0.5, 0.5).setScrollFactor(0).setDepth(106) + .setScale(iconScale); + btnContainer.add(icon); + const buttonTypes = { + "Downloads": 1, + "Likes": 2, + "Trending": 3, + "Recent": 4, + "Magic": 7, + "Awarded": 11, + }; + const type = buttonTypes[labelStr]; + if (!type) { + const disabledTint = 0x666666; + lbl.setTint(disabledTint); + icon.setTint(disabledTint); + bgPieces.forEach(p => p.setTint(disabledTint)); + } + if (type) { + const baseScale = 1; + const pressedScale = baseScale * 1.26; + hitZone.on("pointerdown", () => { + hitZone._pressed = true; + this.tweens.killTweensOf(btnContainer, "scale"); + this.tweens.add({ targets: btnContainer, scale: pressedScale, duration: 300, ease: "Bounce.Out" }); + }); + hitZone.on("pointerout", () => { + if (hitZone._pressed) { + hitZone._pressed = false; + this.tweens.killTweensOf(btnContainer, "scale"); + this.tweens.add({ targets: btnContainer, scale: baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + hitZone.on("pointerup", () => { + if (hitZone._pressed) { + hitZone._pressed = false; + this.tweens.killTweensOf(btnContainer, "scale"); + btnContainer.setScale(baseScale); + this._closeSearchMenu(true); + const searchParams = { type }; + const diffParam = _getActiveDiffParam(); + if (diffParam) { + searchParams.diff = diffParam; + const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; + if (demonIcon && demonIcon._diffFilterActive && this._selectedDemonTier) { + searchParams.demonFilter = this._selectedDemonTier; + } + } + this._openOnlineLevelsScene(searchParams); + } + }); + } else { + this._makeBouncyButton(hitZone, 1, () => {}); + } + this._searchOverlayObjects.push(btnContainer); + } + } + const filtersLabelY = qsPanelY + qsPanelH + 24; + const filtersPanelY = filtersLabelY + 20; + const filtersPanelH = sh * 0.16; + const filtersLabel = this.add.bitmapText(sw / 2, filtersLabelY, "bigFont", "Filters", labelSize) + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(labelColor); + + gfx.fillStyle(filtersPanelColor, panelAlpha); + gfx.fillRoundedRect(panelLeft, filtersPanelY, panelW, filtersPanelH, panelRadius); + const _diffFilterFrames = [ + "difficulty_00_btn_001.png", "difficulty_01_btn_001.png", "difficulty_02_btn_001.png", + "difficulty_03_btn_001.png", "difficulty_04_btn_001.png", "difficulty_05_btn_001.png", + "difficulty_06_btn_001.png", "difficulty_auto_btn_001.png" + ]; + const _diffFilterCount = _diffFilterFrames.length; + const _diffFilterSlotW = panelW / _diffFilterCount; + const _diffFilterIconY = filtersPanelY + filtersPanelH / 2; + this._diffFilterIcons = []; + const _diffFilterInactiveTint = 0x666666; + const _diffFilterBaseScale = 0.85; + const _diffFilterPressScale = 1; + const _diffFilterExclusiveIdx = [0, 6, 7]; + _diffFilterFrames.forEach((frame, i) => { + const cx = panelLeft + _diffFilterSlotW * i + _diffFilterSlotW / 2; + const icon = this.add.image(cx, _diffFilterIconY, "GJ_GameSheet03", frame) + .setScrollFactor(0).setDepth(105).setOrigin(0.5) + .setScale(_diffFilterBaseScale) + .setInteractive() + .setTint(_diffFilterInactiveTint); + icon._diffFilterActive = false; + icon._diffFilterExclusive = _diffFilterExclusiveIdx.includes(i); + this._diffFilterIcons.push(icon); + + icon.on("pointerdown", () => { + icon._pressed = true; + this.tweens.killTweensOf(icon, "scale"); + this.tweens.add({ targets: icon, scale: _diffFilterPressScale, duration: 300, ease: "Bounce.Out" }); + }); + icon.on("pointerout", () => { + if (icon._pressed) { + icon._pressed = false; + this.tweens.killTweensOf(icon, "scale"); + this.tweens.add({ targets: icon, scale: _diffFilterBaseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + icon.on("pointerup", () => { + if (!icon._pressed) return; + icon._pressed = false; + this.tweens.killTweensOf(icon, "scale"); + icon.setScale(_diffFilterBaseScale); + const wasActive = icon._diffFilterActive; + if (icon._diffFilterExclusive) { + this._diffFilterIcons.forEach(other => { + other.setTint(_diffFilterInactiveTint); + other._diffFilterActive = false; + }); + if (!wasActive) { + icon.clearTint(); + icon._diffFilterActive = true; + } + } else { + this._diffFilterIcons.forEach(other => { + if (other._diffFilterExclusive && other._diffFilterActive) { + other.setTint(_diffFilterInactiveTint); + other._diffFilterActive = false; + } + }); + if (wasActive) { + icon.setTint(_diffFilterInactiveTint); + icon._diffFilterActive = false; + } else { + icon.clearTint(); + icon._diffFilterActive = true; + } + } + this._refreshDemonFilterPlus(); + }); + this._searchOverlayObjects.push(icon); + }); + const _demonPlusX = panelRight + 42; + const _demonPlusY = filtersPanelY + filtersPanelH / 2; + const demonPlusBtn = this.add.image(_demonPlusX, _demonPlusY, "GJ_GameSheet03", "GJ_plus2Btn_001.png") + .setScrollFactor(0).setDepth(105).setOrigin(0.5) + .setInteractive().setVisible(false); + this._demonFilterPlusBtn = demonPlusBtn; + this._makeBouncyButton(demonPlusBtn, 1, () => { this._buildDemonFilterPopup(); }, () => demonPlusBtn.visible); + this._searchOverlayObjects.push(demonPlusBtn); + + this._refreshDemonFilterPlus = () => { + const demonIcon = this._diffFilterIcons[6]; + if (demonPlusBtn && demonPlusBtn.scene) { + demonPlusBtn.setVisible(!!(demonIcon && demonIcon._diffFilterActive)); + } + }; + this._refreshDemonFilterPlus(); + + const extraPanelY = filtersPanelY + filtersPanelH + 18; + const extraPanelH = sh * 0.11; + gfx.fillStyle(extraPanelColor, panelAlpha); + gfx.fillRoundedRect(panelLeft, extraPanelY, panelW, extraPanelH, panelRadius); + + const extraComingSoon = this.add.bitmapText(sw / 2, extraPanelY + extraPanelH / 2, "bigFont", "Coming Soon!", 42) + .setScrollFactor(0).setDepth(105).setOrigin(0.5, 0.5).setTint(0xadd8e6).setAlpha(0.75); + + this._searchOverlayObjects.push(gfx, qsLabel, filtersLabel, cornerBR, cornerBL, + placeholderLabel, typedLabel, inputCursor, inputHitZone, innerBtn1, innerBtn2, innerBtn3, + extraComingSoon); + + let _loading = false; + const _diffFilterCodeMap = [-1, 1, 2, 3, 4, 5, -2, -3]; + const _getActiveDiffParam = () => { + const icons = this._diffFilterIcons || []; + const activeCodes = []; + icons.forEach((icon, idx) => { + if (icon._diffFilterActive) activeCodes.push(_diffFilterCodeMap[idx]); + }); + return activeCodes.length ? activeCodes.join(",") : null; + }; + const _doSearch = async () => { + if (_loading) return; + const rawInput = htmlInput.value.trim(); + if (rawInput && /^\d+$/.test(rawInput)) { + const levelId = rawInput; + _loading = true; + try { + await _doSearchInner(levelId); + } catch (err) { + } finally { + _loading = false; + } + return; + } + htmlInput.remove(); + window.removeEventListener("resize", _repositionInput); + this._closeSearchMenu(true); + const diffParam = _getActiveDiffParam(); + const searchParams = rawInput ? { type: 0, str: rawInput } : { type: 2 }; + if (diffParam) { + searchParams.diff = diffParam; + const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; + if (demonIcon && demonIcon._diffFilterActive && this._selectedDemonTier) { + searchParams.demonFilter = this._selectedDemonTier; + } + } + this._openOnlineLevelsScene(searchParams); + }; + const _doSearchInner = async (levelId) => { + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + if (!PROXY_BASE) { console.warn("Level search: window._gdProxyUrl is not configured"); return; } + const formBody = `levelID=${levelId}&secret=Wmfd2893gb7`; + const res = await fetch(`${PROXY_BASE}/downloadGJLevel22.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: formBody + }); + if (!res.ok) throw new Error(`Proxy returned ${res.status}`); + const rawResponse = await res.text(); + if (!rawResponse || rawResponse === "-1" || !rawResponse.includes(":")) { + return; + } + + const responseSegments = rawResponse.split("#"); + const lvlParts = responseSegments[0].split(":"); + const lvlMap = {}; + for (let i = 0; i + 1 < lvlParts.length; i += 2) { + lvlMap[lvlParts[i]] = lvlParts[i + 1]; + } + + const levelData = { + // Core Level Info + id: lvlMap["1"] || levelId, + title: (lvlMap["2"] || "Online Level").trim(), + description: lvlMap["3"] ? atob(lvlMap["3"].replace(/-/g, '+').replace(/_/g, '/')) : "", // Base64 decoded + string: lvlMap["4"] || null, // The raw level data string + version: parseInt(lvlMap["5"]) || 1, + + // User / Author Info + playerID: lvlMap["6"] || null, + accountID: lvlMap["57"] || null, // The author's accountID returned by the server + + // Song Info + officialSong: lvlMap["12"] || "0", + customSongID: (lvlMap["35"] || "").trim(), + isCustomSong: !!(lvlMap["35"] || "").trim() && (lvlMap["35"] || "").trim() !== "0", + isLibrarySong: !!(lvlMap["35"] || "").trim() && (lvlMap["35"] || "").trim() !== "0" && parseInt((lvlMap["35"] || "").trim()) >= 1000000, + offset: parseFloat(lvlMap["45"] || "0") || 0, + + // Gameplay Details + difficulty: (() => { + const isDemon = parseInt(lvlMap["17"]) === 1; + const isAuto = parseInt(lvlMap["25"]) === 1; + if (isAuto) return 11; + if (isDemon) { + const d9 = parseInt(lvlMap["9"]); + const d43 = parseInt(lvlMap["43"]); + if (!isNaN(d9) && d9 >= 1 && d9 <= 5) { + return [7, 8, 6, 9, 10][d9 - 1] ?? 8; + } else if (!isNaN(d43)) { + const demonMap43 = { 3: 7, 4: 8, 0: 6, 5: 9, 6: 10 }; + return demonMap43.hasOwnProperty(d43) ? demonMap43[d43] : 8; + } + return 8; + } + return Math.min(5, Math.max(0, Math.round((parseInt(lvlMap["9"]) || 0) / 10))); + })(), // Auto, Easy, Normal, Hard, Harder, Insane, Demons + stars: parseInt(lvlMap["18"]) || 0, + diamonds: parseInt(lvlMap["46"]) || 0, + orbs: parseInt(lvlMap["48"]) || 0, + length: parseInt(lvlMap["15"]) || 0, // 0=Tiny, 1=Small, 2=Medium, 3=Long, 4=XL, 5=Platformer + featured: (parseInt(lvlMap["19"]) || 0) > 0, // Featured score > 0 means the level is Featured + epic: parseInt(lvlMap["42"]) || 0, // 0=Original/Featured (see 'featured' flag), 1=Epic, 2=Mythic, 3+=Legendary + gameVersion: parseInt(lvlMap["13"]) || 22, // The game version the level was created in (e.g. 22 = 2.2) + binaryVersion: parseInt(lvlMap["52"]) || 0, // The build version used to upload + + // Meta / Social Counters + downloads: parseInt(lvlMap["10"]) || 0, + likes: parseInt(lvlMap["14"]) || 0, + objects: parseInt(lvlMap["45"]) || 0, // Object count (Note: 45 can double as audio offset or object count depending on context) + ts: lvlMap["28"] || null, // Upload/Update timestamp hint + + // Technical / Security Verification keys sent back by server + chk: lvlMap["chk"] || null, + rs: lvlMap["rs"] || null + }; + console.groupCollapsed("level data"); + const { string, ...tableFriendlyData } = levelData; + console.table(tableFriendlyData); + console.groupEnd(); + + let authorName = "Unknown"; + let songNameForCell = levelData.isCustomSong + ? ("Song #" + levelData.customSongID) + : (window.allLevels && window.allLevels[levelData.officialSong] ? window.allLevels[levelData.officialSong][1] : "Unknown"); + try { + const infoRes = await fetch(`https://gdbrowser.com/api/level/${levelData.id}`); + if (infoRes.ok) { + const infoData = await infoRes.json(); + if (infoData) { + if (infoData.author) authorName = infoData.author; + if (infoData.songName) songNameForCell = infoData.songName; + } + } + } catch (_e) {} + + const cellData = { + ...levelData, + name: levelData.title, + author: authorName, + songName: songNameForCell + }; + + htmlInput.remove(); + window.removeEventListener("resize", _repositionInput); + this._closeSearchMenu(true); + this._openSearchResultScene(cellData); + }; + this._searchOverlayObjects.push(overlay, blocker, backBtn); + if (window.levelID && !window.alreadydownloaded) { // if there's an ID parameter, load it directly + window.alreadydownloaded = true; + htmlInput.remove(); + const loadingBg = this.add.graphics().setScrollFactor(0).setDepth(1000); + loadingBg.fillStyle(0x000000, 1); + loadingBg.fillRect(0, 0, sw, sh); + const loadingText = this.add.bitmapText(sw / 2, sh / 2, "bigFont", "Loading level...", 30) + .setScrollFactor(0).setDepth(1001).setOrigin(0.5); + this._searchOverlayObjects.push(loadingBg, loadingText); + _doSearchInner(window.levelID); + } + this._searchHtmlInput = htmlInput; + this._searchInputResizeFn = _repositionInput; + }; + this._closeSearchMenu = (silent = false, onComplete = null) => { + if (!this._searchOverlay) return; + if (this._searchHtmlInput) { + this._searchHtmlInput.remove(); + this._searchHtmlInput = null; + } + if (this._searchInputResizeFn) { + window.removeEventListener("resize", this._searchInputResizeFn); + this._searchInputResizeFn = null; + } + const destroy = () => { + for (const obj of this._searchOverlayObjects) { + if (obj && obj.destroy) obj.destroy(); + } + this._searchOverlayObjects = []; + this._searchOverlay = null; + }; + if (silent) { destroy(); if (onComplete) onComplete(); return; } + const sw = screenWidth, sh = screenHeight; + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ + targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", + onComplete: () => { + destroy(); + if (onComplete) onComplete(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._makeBouncyButton(this._creatorBtn, 1, () => { + this._openCreatorMenu(); + }, () => this._menuActive && !this._levelSelectOverlay); + //icon stufff + this._iconBtn = this.add.image(0, 0, "GJ_GameSheet03", "GJ_garageBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setScale(1); + this._iconBtnSelected = false; + this._makeBouncyButton(this._iconBtn, 1, () => { + this._openIconSelector(); + }, () => this._menuActive && !this._levelSelectOverlay); + + this._iconOverlay = null; + + const _iconFrameSets = { + icon: [ +"player_01_001.png", "player_02_001.png", "player_03_001.png", "player_04_001.png", "player_05_001.png", "player_06_001.png", "player_07_001.png", "player_08_001.png", "player_09_001.png", "player_10_001.png", +"player_11_001.png", "player_12_001.png", "player_13_001.png", "player_14_001.png", "player_15_001.png", "player_16_001.png", "player_17_001.png", "player_18_001.png", "player_19_001.png", "player_20_001.png", +"player_21_001.png", "player_22_001.png", "player_23_001.png", "player_24_001.png", "player_25_001.png", "player_26_001.png", "player_27_001.png", "player_28_001.png", "player_29_001.png", "player_30_001.png", +"player_31_001.png", "player_32_001.png", "player_33_001.png", "player_34_001.png", "player_35_001.png", "player_36_001.png", "player_37_001.png", "player_38_001.png", "player_39_001.png", "player_40_001.png", +"player_41_001.png", "player_42_001.png", "player_43_001.png", "player_44_001.png", "player_45_001.png", "player_46_001.png", "player_47_001.png", "player_48_001.png", "player_49_001.png", "player_50_001.png", +"player_51_001.png", "player_52_001.png", "player_53_001.png", "player_54_001.png", "player_55_001.png", "player_56_001.png", "player_57_001.png", "player_58_001.png", "player_59_001.png", "player_60_001.png", +"player_61_001.png", "player_62_001.png", "player_63_001.png", "player_64_001.png", "player_65_001.png", "player_66_001.png", "player_67_001.png", "player_68_001.png", "player_69_001.png", "player_70_001.png", +"player_71_001.png", "player_72_001.png", "player_73_001.png", "player_74_001.png", "player_75_001.png", "player_76_001.png", "player_77_001.png", "player_78_001.png", "player_79_001.png", "player_80_001.png", +"player_81_001.png", "player_82_001.png", "player_83_001.png", "player_84_001.png", "player_85_001.png", "player_86_001.png", "player_87_001.png", "player_88_001.png", "player_89_001.png", "player_90_001.png", +"player_91_001.png", "player_92_001.png", "player_93_001.png", "player_94_001.png", "player_95_001.png", "player_96_001.png", "player_97_001.png", "player_98_001.png", "player_99_001.png", "player_100_001.png", +"player_101_001.png", "player_102_001.png", "player_103_001.png", "player_104_001.png", "player_105_001.png", "player_106_001.png", "player_107_001.png", "player_108_001.png", "player_109_001.png", "player_110_001.png", +"player_111_001.png", "player_112_001.png", "player_113_001.png", "player_114_001.png", "player_115_001.png", "player_116_001.png", "player_117_001.png", "player_118_001.png", "player_119_001.png", "player_120_001.png", +"player_121_001.png", "player_122_001.png", "player_123_001.png", "player_124_001.png", "player_125_001.png", "player_126_001.png", "player_127_001.png", "player_128_001.png", "player_129_001.png", "player_130_001.png", +"player_131_001.png", "player_132_001.png", "player_133_001.png", "player_134_001.png", "player_135_001.png", "player_136_001.png", "player_137_001.png", "player_138_001.png", "player_139_001.png", "player_140_001.png", +"player_141_001.png", "player_142_001.png", "player_143_001.png", "player_144_001.png", "player_145_001.png", "player_146_001.png", "player_147_001.png", "player_148_001.png", "player_149_001.png", "player_150_001.png", +"player_151_001.png", "player_152_001.png", "player_153_001.png", "player_154_001.png", "player_155_001.png", "player_156_001.png", "player_157_001.png", "player_158_001.png", "player_159_001.png", "player_160_001.png", +"player_161_001.png", "player_162_001.png", "player_163_001.png", "player_164_001.png", "player_165_001.png", "player_166_001.png", "player_167_001.png", "player_168_001.png", "player_169_001.png", "player_170_001.png", +"player_171_001.png", "player_172_001.png", "player_173_001.png", "player_174_001.png", "player_175_001.png", "player_176_001.png", "player_177_001.png", "player_178_001.png", "player_179_001.png", "player_180_001.png", +"player_181_001.png", "player_182_001.png", "player_183_001.png", "player_184_001.png", "player_185_001.png", "player_186_001.png", "player_187_001.png", "player_188_001.png", "player_189_001.png", "player_190_001.png", +"player_191_001.png", "player_192_001.png", +"player_193_001.png", "player_194_001.png", "player_195_001.png", "player_196_001.png", "player_197_001.png", "player_198_001.png", "player_199_001.png", "player_200_001.png", "player_201_001.png", "player_202_001.png", +"player_203_001.png", "player_204_001.png", "player_205_001.png", "player_206_001.png", "player_207_001.png", "player_208_001.png", "player_209_001.png", "player_210_001.png", "player_211_001.png", "player_212_001.png", +"player_213_001.png", "player_214_001.png", "player_215_001.png", "player_216_001.png", "player_217_001.png", "player_218_001.png", "player_219_001.png", "player_220_001.png", "player_221_001.png", "player_222_001.png", +"player_223_001.png", "player_224_001.png", "player_225_001.png", "player_226_001.png", "player_227_001.png", "player_228_001.png", "player_229_001.png", "player_230_001.png", "player_231_001.png", "player_232_001.png", +"player_233_001.png", "player_234_001.png", "player_235_001.png", "player_236_001.png", "player_237_001.png", "player_238_001.png", "player_239_001.png", "player_240_001.png", "player_241_001.png", "player_242_001.png", +"player_243_001.png", "player_244_001.png", "player_245_001.png", "player_246_001.png", "player_247_001.png", "player_248_001.png" + ], + ship: [ + "ship_01_001.png", "ship_02_001.png", "ship_03_001.png", "ship_04_001.png", "ship_05_001.png", "ship_06_001.png", "ship_07_001.png", "ship_08_001.png", "ship_09_001.png", "ship_10_001.png", +"ship_11_001.png", "ship_12_001.png", "ship_13_001.png", "ship_14_001.png", "ship_15_001.png", "ship_16_001.png", "ship_17_001.png", "ship_18_001.png", "ship_19_001.png", "ship_20_001.png", +"ship_21_001.png", "ship_22_001.png", "ship_23_001.png", "ship_24_001.png", "ship_25_001.png", "ship_26_001.png", "ship_27_001.png", "ship_28_001.png", "ship_29_001.png", "ship_30_001.png", +"ship_31_001.png", "ship_32_001.png", "ship_33_001.png", "ship_34_001.png", "ship_35_001.png", "ship_36_001.png", "ship_37_001.png", "ship_38_001.png", "ship_39_001.png", "ship_40_001.png", +"ship_41_001.png", "ship_42_001.png", "ship_43_001.png", "ship_44_001.png", "ship_45_001.png", "ship_46_001.png", "ship_47_001.png", "ship_48_001.png", "ship_49_001.png", "ship_50_001.png", +"ship_51_001.png", "ship_52_001.png", "ship_53_001.png", "ship_54_001.png", "ship_55_001.png", "ship_56_001.png", "ship_57_001.png", "ship_58_001.png", "ship_59_001.png", "ship_60_001.png", +"ship_61_001.png", "ship_62_001.png", "ship_63_001.png", "ship_64_001.png", "ship_65_001.png", "ship_66_001.png", "ship_67_001.png", "ship_68_001.png", "ship_69_001.png", "ship_70_001.png", +"ship_71_001.png", "ship_72_001.png", "ship_73_001.png", "ship_74_001.png", "ship_75_001.png", "ship_76_001.png", "ship_77_001.png", "ship_78_001.png", "ship_79_001.png" + ], + ball: [ + "player_ball_01_001.png", "player_ball_02_001.png", "player_ball_03_001.png", "player_ball_04_001.png", "player_ball_05_001.png", "player_ball_06_001.png", "player_ball_07_001.png", "player_ball_08_001.png", "player_ball_09_001.png", "player_ball_10_001.png", + "player_ball_11_001.png", "player_ball_12_001.png", "player_ball_13_001.png", "player_ball_14_001.png", "player_ball_15_001.png", "player_ball_16_001.png", "player_ball_17_001.png", "player_ball_18_001.png", "player_ball_19_001.png", "player_ball_20_001.png", + "player_ball_21_001.png", "player_ball_22_001.png", "player_ball_23_001.png", "player_ball_24_001.png", "player_ball_25_001.png", "player_ball_26_001.png", "player_ball_27_001.png", "player_ball_28_001.png", "player_ball_29_001.png", "player_ball_30_001.png", + + "player_ball_31_001.png", "player_ball_32_001.png", "player_ball_33_001.png", "player_ball_34_001.png", "player_ball_35_001.png", "player_ball_36_001.png", "player_ball_37_001.png", "player_ball_38_001.png", "player_ball_39_001.png", "player_ball_40_001.png", + "player_ball_41_001.png", "player_ball_42_001.png", "player_ball_43_001.png", "player_ball_44_001.png", "player_ball_45_001.png", "player_ball_46_001.png", "player_ball_47_001.png", "player_ball_48_001.png", "player_ball_49_001.png", "player_ball_50_001.png", + "player_ball_51_001.png", "player_ball_52_001.png", + ], + wave: [ + "dart_01_001.png", "dart_02_001.png", "dart_03_001.png", "dart_04_001.png", "dart_05_001.png", + "dart_06_001.png", "dart_07_001.png", "dart_08_001.png", "dart_09_001.png", "dart_10_001.png", + "dart_11_001.png", "dart_12_001.png", "dart_13_001.png", "dart_14_001.png", "dart_15_001.png", + "dart_16_001.png", "dart_17_001.png", "dart_18_001.png", "dart_19_001.png", "dart_20_001.png", + "dart_21_001.png", "dart_22_001.png", "dart_23_001.png", "dart_24_001.png", "dart_25_001.png", + "dart_26_001.png", "dart_27_001.png", "dart_28_001.png", "dart_29_001.png", "dart_30_001.png", + "dart_31_001.png", "dart_32_001.png", "dart_33_001.png", "dart_34_001.png", "dart_35_001.png", + ], + ufo: [ + "bird_01_001.png", "bird_02_001.png", "bird_03_001.png", "bird_04_001.png", "bird_05_001.png", + "bird_06_001.png", "bird_07_001.png", "bird_08_001.png", "bird_09_001.png", "bird_10_001.png", + "bird_11_001.png", "bird_12_001.png", "bird_13_001.png", "bird_14_001.png", "bird_15_001.png", + "bird_16_001.png", "bird_17_001.png", "bird_18_001.png", "bird_19_001.png", "bird_20_001.png", + "bird_21_001.png", "bird_22_001.png", "bird_23_001.png", "bird_24_001.png", "bird_25_001.png", + "bird_26_001.png", "bird_27_001.png", "bird_28_001.png", "bird_29_001.png", "bird_30_001.png", + "bird_31_001.png", "bird_32_001.png", "bird_33_001.png", "bird_34_001.png", "bird_35_001.png", + "bird_36_001.png", "bird_37_001.png", "bird_38_001.png", "bird_39_001.png", "bird_40_001.png", + "bird_41_001.png", "bird_42_001.png", "bird_43_001.png", "bird_44_001.png", "bird_45_001.png", + "bird_46_001.png", "bird_47_001.png", "bird_48_001.png", "bird_49_001.png", "bird_50_001.png", + "bird_51_001.png", + ], + }; + + + const _selectorParseAnimPair = (value, fallbackX = 0, fallbackY = 0) => { + const match = String(value ?? "").match(/\{\s*([-+]?\d*\.?\d+)\s*,\s*([-+]?\d*\.?\d+)\s*\}/); + if (!match) return { x: fallbackX, y: fallbackY }; + const x = parseFloat(match[1]); + const y = parseFloat(match[2]); + return { + x: Number.isFinite(x) ? x : fallbackX, + y: Number.isFinite(y) ? y : fallbackY + }; + }; + + const _selectorVariantFrameName = (frameName, variant) => { + if (!frameName) return frameName; + if (variant === "glow") return frameName.replace(/_001\.png$/, "_glow_001.png"); + if (variant === "overlay") return frameName.replace(/_001\.png$/, "_2_001.png"); + if (variant === "extra") return frameName.replace(/_001\.png$/, "_extra_001.png"); + return frameName; + }; + + const _segmentedIconConfig = { + spider: { + prop: "currentSpider", + prefix: "spider", + descKey: "Spider_AnimDesc", + fallbackBase: "spider_01", + idlePatterns: [/^Spider_idle01_001\.png$/, /^Spider_idle01_\d+\.png$/, /^Spider_idle02_\d+\.png$/, /^Spider_idle_\d+\.png$/, /^Spider_walk_\d+\.png$/], + defaultEntries: [ + { tag: "0", texture: "spider_01_02_001.png" }, + { tag: "1", texture: "spider_01_02_001.png" }, + { tag: "2", texture: "spider_01_04_001.png" }, + { tag: "3", texture: "spider_01_01_001.png" }, + { tag: "4", texture: "spider_01_03_001.png" }, + { tag: "5", texture: "spider_01_02_001.png" } + ] + }, + robot: { + prop: "currentRobot", + prefix: "robot", + descKey: "Robot_AnimDesc", + fallbackBase: "robot_01", + idlePatterns: [/^Robot_idle_001\.png$/, /^Robot_idle_\d+\.png$/, /^Robot_idle01_\d+\.png$/, /^Robot_idle02_\d+\.png$/, /^Robot_run_001\.png$/, /^Robot_run_\d+\.png$/], + defaultEntries: [ + { tag: "0", texture: "robot_01_03_001.png" }, + { tag: "1", texture: "robot_01_02_001.png" }, + { tag: "2", texture: "robot_01_04_001.png" }, + { tag: "3", texture: "robot_01_01_001.png" }, + { tag: "4", texture: "robot_01_03_001.png" }, + { tag: "5", texture: "robot_01_02_001.png" }, + { tag: "6", texture: "robot_01_04_001.png" } + ] + } + }; + + const _isSegmentedIconTab = (tab) => !!_segmentedIconConfig[tab]; + + const _getSegmentedAnimDesc = (tab) => { + const cfg = _segmentedIconConfig[tab]; + if (!cfg) return null; + let data = null; + try { data = this.cache?.json?.get?.(cfg.descKey) || null; } catch (e) { data = null; } + if (!data && typeof window !== "undefined") data = window[cfg.descKey] || null; + return data && data.animationContainer ? data : null; + }; + + const _getSegmentedIdleFrame = (tab) => { + const cfg = _segmentedIconConfig[tab]; + const desc = _getSegmentedAnimDesc(tab); + if (!cfg || !desc?.animationContainer) return null; + const keys = Object.keys(desc.animationContainer).sort((a, b) => { + const aa = parseInt((String(a).match(/_(\d+)\.png$/) || [0, 0])[1], 10) || 0; + const bb = parseInt((String(b).match(/_(\d+)\.png$/) || [0, 0])[1], 10) || 0; + return aa - bb; + }); + for (const pattern of cfg.idlePatterns) { + const match = keys.find(key => pattern.test(key)); + if (match) return desc.animationContainer[match]; + } + return desc.animationContainer[keys[0]] || null; + }; + + const _replaceSegmentedBase = (tab, textureName, baseName) => { + const cfg = _segmentedIconConfig[tab]; + if (!cfg) return textureName; + return String(textureName || "").replace(new RegExp("^" + cfg.prefix + "_\\d+"), baseName); + }; + + const _makeSegmentedIconFrames = (tab, max = 120) => { + const cfg = _segmentedIconConfig[tab]; + if (!cfg) return []; + const desc = _getSegmentedAnimDesc(tab); + const entries = desc?.usedTextures + ? Object.values(desc.usedTextures).slice().sort((a, b) => (parseInt(a.tag || "0", 10) || 0) - (parseInt(b.tag || "0", 10) || 0)) + : cfg.defaultEntries; + const frames = []; + for (let i = 1; i <= max; i++) { + const baseName = `${cfg.prefix}_${String(i).padStart(2, "0")}`; + const hasAnyPart = entries.some(entry => { + const frameName = _replaceSegmentedBase(tab, entry.texture, baseName); + return typeof getAtlasFrame === "function" && !!getAtlasFrame(this, frameName); + }); + if (hasAnyPart) frames.push(`${baseName}_001.png`); + } + return frames.length ? frames : [`${cfg.fallbackBase}_001.png`]; + }; + + window.currentSpider = window.currentSpider || localStorage.getItem("iconCurrentSpider") || "spider_01"; + window.currentRobot = window.currentRobot || localStorage.getItem("iconCurrentRobot") || "robot_01"; + window.currentSwing = window.currentSwing || localStorage.getItem("iconCurrentSwing") || "swing_01"; + _iconFrameSets.spider = _makeSegmentedIconFrames("spider"); + _iconFrameSets.robot = _makeSegmentedIconFrames("robot"); + _iconFrameSets.swing = ["swing_01_001.png", "swing_02_001.png", "swing_03_001.png", "swing_04_001.png", "swing_05_001.png", "swing_06_001.png", "swing_07_001.png", "swing_08_001.png", "swing_09_001.png", "swing_10_001.png", "swing_11_001.png", "swing_12_001.png", "swing_13_001.png", "swing_14_001.png", "swing_15_001.png", "swing_16_001.png", "swing_17_001.png", "swing_18_001.png", "swing_19_001.png", "swing_20_001.png", "swing_21_001.png", "swing_22_001.png", "swing_23_001.png", "swing_24_001.png", "swing_25_001.png", "swing_26_001.png", "swing_27_001.png", "swing_28_001.png", "swing_29_001.png", "swing_30_001.png", "swing_31_001.png", "swing_32_001.png", "swing_33_001.png", "swing_34_001.png", "swing_35_001.png", "swing_36_001.png", "swing_37_001.png", "swing_38_001.png", "swing_39_001.png", "swing_40_001.png", "swing_41_001.png", "swing_42_001.png", "swing_43_001.png"]; + + + const _iconWindowProps = { + icon: "currentPlayer", + ship: "currentShip", + ball: "currentBall", + wave: "currentWave", + ufo: "currentBird", + robot: "currentRobot", + spider: "currentSpider", + swing: "currentSwing", + }; + + const _iconAtlas = { + icon: "GJ_GameSheetIcons", + ship: "GJ_GameSheetIcons", + ball: "GJ_GameSheetIcons", + wave: "GJ_GameSheetIcons", + ufo: "GJ_GameSheetIcons", + robot: "GJ_GameSheetIcons", + spider: "GJ_GameSheetIcons", + swing: "GJ_GameSheetIcons", + }; + + const _tabBtnFrames = { + icon: { on: "gj_iconBtn_on_001.png", off: "gj_iconBtn_off_001.png" }, + ship: { on: "gj_shipBtn_on_001.png", off: "gj_shipBtn_off_001.png" }, + ball: { on: "gj_ballBtn_on_001.png", off: "gj_ballBtn_off_001.png" }, + wave: { on: "gj_dartBtn_on_001.png", off: "gj_dartBtn_off_001.png" }, + ufo: { on: "gj_birdBtn_on_001.png", off: "gj_birdBtn_off_001.png" }, + robot:{ on: "gj_robotBtn_on_001.png", off: "gj_robotBtn_off_001.png" }, + spider:{ on: "gj_spiderBtn_on_001.png", off: "gj_spiderBtn_off_001.png" }, + swing:{ on: "gj_swingBtn_on_001.png", off: "gj_swingBtn_off_001.png" }, + }; + + const _safeTabBtnFrame = (tab, state) => { + const frame = _tabBtnFrames[tab]?.[state] || _tabBtnFrames.icon[state]; + return (typeof getAtlasFrame === "function" && getAtlasFrame(this, frame)) ? frame : _tabBtnFrames.icon[state]; + }; + + this._openIconSelector = (startTab = "icon") => { + if (this._iconOverlay) return; + + const sw = screenWidth; + const sh = screenHeight; + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + + const overlay = this.add.graphics().setScrollFactor(0).setDepth(100); + const gradientSteps = 80; + for (let gi = 0; gi < gradientSteps; gi++) { + const t = gi / (gradientSteps - 1); + const r1 = Math.round(0x92 + (0x3a - 0x92) * t); + const g1 = Math.round(0x92 + (0x3a - 0x92) * t); + const b1 = Math.round(0x92 + (0x3a - 0x92) * t); + const bandColor = (r1 << 16) | (g1 << 8) | b1; + const bandY = Math.floor(gi * sh / gradientSteps); + const bandH = Math.ceil(sh / gradientSteps) + 1; + overlay.fillStyle(bandColor, 1); + overlay.fillRect(0, bandY, sw, bandH); + } + this._iconOverlay = overlay; + + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) + .setScrollFactor(0).setDepth(101).setInteractive(); + + const titleTxt = this.add.bitmapText(sw / 2, 60, "goldFont", "Icon Selector", 32) + .setOrigin(0.5, 0.5).setScrollFactor(0).setDepth(105); + + this._iconOverlayObjects = [overlay, blocker, titleTxt]; + + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(104).setFlipY(true) + .setFlipX(true) + .setRotation(Math.PI).setInteractive(); + this._iconOverlayObjects.push(backBtn); + this._makeBouncyButton(backBtn, 1, () => this._closeIconSelector()); + + const topBarHeight = 100; + const lineY = topBarHeight + 100; + const linePadding = 230; + const topBar = this.add.graphics().setScrollFactor(0).setDepth(102); + const lineSegments = 40; + const lineStart = linePadding; + const lineEnd = sw - linePadding; + const lineWidth = lineEnd - lineStart; + const fadeZone = lineWidth * 0.25; + for (let li = 0; li < lineSegments; li++) { + const t0 = li / lineSegments; + const t1 = (li + 1) / lineSegments; + const x0 = lineStart + t0 * lineWidth; + const x1 = lineStart + t1 * lineWidth; + const mid = (t0 + t1) / 2 * lineWidth; + let alpha; + if (mid < fadeZone) { + alpha = mid / fadeZone; + } else if (mid > lineWidth - fadeZone) { + alpha = (lineWidth - mid) / fadeZone; + } else { + alpha = 1; + } + topBar.lineStyle(3, 0xFFFFFF, alpha); + topBar.beginPath(); + topBar.moveTo(x0, lineY); + topBar.lineTo(x1, lineY); + topBar.strokePath(); + } + this._iconOverlayObjects.push(topBar); + + const cols = 12; + const iconSize = 60; + const padding = 2; + const containerPadding = 10; + const rows = 3; + const containerWidth = cols * iconSize + (cols - 1) * padding + 12; + const containerHeight = rows * iconSize + (rows - 1) * padding + 12; + const containerX = sw / 2 - containerWidth / 2; + const containerY = sh - containerHeight - containerPadding - 150; + const startX = containerX + 6 + iconSize / 2; + const startY = containerY + 6 + iconSize / 2; + + const gridBg = this.add.graphics().setScrollFactor(0).setDepth(102); + gridBg.fillStyle(0x454444, 1); + gridBg.fillRoundedRect(containerX, containerY, containerWidth, containerHeight, 10); + this._iconOverlayObjects.push(gridBg); + + const cornerTL = this.add.image(0, 0, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(100).setOrigin(0, 0).setFlipY(true) + const cornerTR = this.add.image(sw, 0, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(103).setOrigin(1, 0).setFlipY(true).setFlipX(true); + const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); + const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1); + this._iconOverlayObjects.push(cornerTL, cornerTR, cornerBR, cornerBL); + + const navDotSpacing = 35; + const navDotY = containerY + containerHeight + 30; + const navDot1 = this.add.image(sw / 2 - navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_on_001.png").setScrollFactor(0).setDepth(104).setScale(0.75); + const navDot2 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75); + const navDot3 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot4 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot5 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot6 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot7 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot8 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + const navDot9 = this.add.image(sw / 2 + navDotSpacing / 2, navDotY, "GJ_GameSheet03", "gj_navDotBtn_off_001.png").setScrollFactor(0).setDepth(104).setScale(0.75).setVisible(false); + this._iconOverlayObjects.push(navDot1, navDot2, navDot3, navDot4, navDot5, navDot6, navDot7, navDot8, navDot9); + const _updateNavDots = (page, tab) => { + const maxPages = Math.max(1, _getMaxPages(tab)); + const dots = [navDot1, navDot2, navDot3, navDot4, navDot5, navDot6, navDot7, navDot8, navDot9]; + dots.forEach(dot => dot.setVisible(false)); + const totalDotsToShow = Math.min(maxPages, dots.length); + const totalWidth = (totalDotsToShow - 1) * navDotSpacing; + const dotStartX = sw / 2 - totalWidth / 2; + for (let i = 0; i < totalDotsToShow; i++) { + dots[i].setPosition(dotStartX + i * navDotSpacing, navDotY).setVisible(true); + dots[i].setTexture("GJ_GameSheet03", page === i ? "gj_navDotBtn_on_001.png" : "gj_navDotBtn_off_001.png"); + } + }; + + const rainbowColors = [ + 0xFF0000, 0xFF4500, 0xFF7F00, 0xFFAA00, 0xFFD700, + 0xFFFF00, 0xAAFF00, 0x00FF00, 0x00FF7F, 0x00FFFF, + 0x007FFF, 0x0000FF, 0x7F00FF, 0xFF00FF, 0xFF007F, + 0xFFFFFF, 0xC0C0C0, 0x808080, 0x404040, 0x000000, + ]; + + const colorBtnSize = 35; + const colorPadding = 6; + const colorRowWidth = rainbowColors.length * (colorBtnSize + colorPadding) - colorPadding; + const colorRow1Y = containerY + containerHeight + 88; + const colorRow2Y = colorRow1Y + colorBtnSize + 10; + const colorRowStartX = sw / 2 - colorRowWidth / 2 + colorBtnSize / 2; + + const colorLabel1 = this.add.text(sw / 2 - colorRowWidth / 2, colorRow1Y - 14, "", { + fontSize: "11px", color: "#ffffff", fontFamily: "Arial"}).setScrollFactor(0).setDepth(104).setOrigin(0, 0.5).setAlpha(1); + this._iconOverlayObjects.push(colorLabel1); + + const colorLabel2 = this.add.text(sw / 2 - colorRowWidth / 2, colorRow2Y - 14, "", { + fontSize: "11px", color: "#ffffff", fontFamily: "Arial"}).setScrollFactor(0).setDepth(104).setOrigin(0, 0.5).setAlpha(1); + this._iconOverlayObjects.push(colorLabel2); + + const colorBoxWidth = sw; + const colorBoxHeight = colorBtnSize * 2 + 10 + 20; + const colorBoxX = 0; + const colorBoxY = colorRow1Y - colorBtnSize / 2 - 10; + const colorBox = this.add.graphics().setScrollFactor(0).setDepth(101); + colorBox.fillStyle(0x000000, 0.5); + colorBox.fillRect(colorBoxX, colorBoxY, colorBoxWidth, colorBoxHeight); + this._iconOverlayObjects.push(colorBox); + + const color1SelLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false).setScale(0.6); + const color2SelLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false).setScale(0.6); + this._iconOverlayObjects.push(color1SelLabel, color2SelLabel); + + const _moveColorSelect = (label, color, rowY) => { + const idx = rainbowColors.indexOf(color); + if (idx === -1) { + label.setVisible(false); + return; + } + + label.setPosition(colorRowStartX + idx * (colorBtnSize + colorPadding), rowY).setVisible(true); + }; + + _moveColorSelect(color1SelLabel, window.mainColor, colorRow1Y); + _moveColorSelect(color2SelLabel, window.secondaryColor, colorRow2Y); + + for (let ci = 0; ci < rainbowColors.length; ci++) { + const cx = colorRowStartX + ci * (colorBtnSize + colorPadding); + + const btn1AtlasInfo = getAtlasFrame(this, "GJ_colorBtn_001.png"); + let btn1; + btn1 = this.add.rectangle(cx, colorRow1Y, colorBtnSize, colorBtnSize, rainbowColors[ci]).setScrollFactor(0).setDepth(104).setInteractive(); + this._iconOverlayObjects.push(btn1); + + const btn2AtlasInfo = getAtlasFrame(this, "GJ_colorBtn_001.png"); + let btn2; + btn2 = this.add.rectangle(cx, colorRow2Y, colorBtnSize, colorBtnSize, rainbowColors[ci]).setScrollFactor(0).setDepth(104).setInteractive(); + this._iconOverlayObjects.push(btn2); + + ((color, b1, b2) => { + this._makeBouncyButton(b1, 1.0, () => { + window.mainColor = color; + localStorage.setItem("iconMainColor", hexadecimalToHex(color)); + _moveColorSelect(color1SelLabel, color, colorRow1Y); + if (this._player) { + const safeSetTint = (sprite, color) => { + if (sprite && sprite.setTint) { + try { + sprite.setTint(color); + if (this.renderer.type === Phaser.CANVAS && sprite.tintTopLeft !== undefined) { + if (sprite.tintTopLeft === 0xffffff && color !== 0xffffff) { + } + } + } catch (e) { + } + } + }; + + safeSetTint(this._player._playerSpriteLayer?.sprite, color); + safeSetTint(this._player._shipSpriteLayer?.sprite, color); + safeSetTint(this._player._ballSpriteLayer?.sprite, color); + safeSetTint(this._player._waveSpriteLayer?.sprite, color); + for (const layer of this._player._robotLayers || []) safeSetTint(layer?.sprite, color); + for (const layer of this._player._spiderLayers || []) safeSetTint(layer?.sprite, color); + if (this._player._particleEmitter) { + try { + this._player._particleEmitter.tint = color; + } catch (e) { + } + } + } + selectedIcon.setTint(color); + _refreshPreview(_currentTab, _getPreviewFrame(_currentTab)); + }); + this._makeBouncyButton(b2, 1.0, () => { + window.secondaryColor = color; + localStorage.setItem("iconSecondaryColor", hexadecimalToHex(color)); + _moveColorSelect(color2SelLabel, color, colorRow2Y); + if (this._player) { + const safeSetTint = (sprite, color) => { + if (sprite && sprite.setTint) { + try { + sprite.setTint(color); + } catch (e) { + } + } + }; + + safeSetTint(this._player._playerGlowLayer?.sprite, color); + safeSetTint(this._player._playerOverlayLayer?.sprite, color); + safeSetTint(this._player._shipGlowLayer?.sprite, color); + safeSetTint(this._player._shipOverlayLayer?.sprite, color); + safeSetTint(this._player._ballGlowLayer?.sprite, color); + safeSetTint(this._player._ballOverlayLayer?.sprite, color); + safeSetTint(this._player._waveGlowLayer?.sprite, color); + safeSetTint(this._player._waveOverlayLayer?.sprite, color); + for (const layer of this._player._robotLayers || []) safeSetTint(layer?.sprite, color); + for (const layer of this._player._spiderLayers || []) safeSetTint(layer?.sprite, color); + if (this._player._streak) { + try { + this._player._streak._color = color; + } catch (e) { + } + } + } + selectedIconExtra.setTint(window.secondaryColor); + _refreshPreview(_currentTab, _getPreviewFrame(_currentTab)); + }); + })(rainbowColors[ci], btn1, btn2); + } + + const previewY = lineY - 35; + const selectedIconExtra = this.add.image(sw / 2, previewY, _iconAtlas[startTab], null).setScrollFactor(0).setDepth(102).setVisible(false); + const selectedIconOutline = this.add.image(sw / 2, previewY, _iconAtlas[startTab], null).setScrollFactor(0).setDepth(103.5).setVisible(false); + const selectedIcon = this.add.image(sw / 2, previewY, _iconAtlas[startTab], null).setScrollFactor(0).setDepth(103); + let selectedSegmentedPreview = null; + + const _destroySegmentedPreview = () => { + if (selectedSegmentedPreview?.destroy) selectedSegmentedPreview.destroy(true); + selectedSegmentedPreview = null; + }; + + const _createSegmentedIconComposite = (tab, pseudoFrame, x, y, maxSize, depth, muted = false) => { + const cfg = _segmentedIconConfig[tab]; + const idleFrame = _getSegmentedIdleFrame(tab); + if (!cfg || !idleFrame) return null; + const baseName = String(pseudoFrame || `${cfg.fallbackBase}_001.png`).replace(/_001\.png$/, ""); + const container = this.add.container(x, y).setScrollFactor(0).setDepth(depth); + const parts = []; + for (const spriteKey of Object.keys(idleFrame)) { + if (!spriteKey.startsWith("sprite_")) continue; + const spriteData = idleFrame[spriteKey]; + const tag = parseInt(spriteData.tag || "0", 10) || 0; + const pos = _selectorParseAnimPair(spriteData.position, 0, 0); + const sc = _selectorParseAnimPair(spriteData.scale, 1, 1); + const fl = _selectorParseAnimPair(spriteData.flipped, 0, 0); + const zValue = parseFloat(spriteData.zValue || tag || "0") || 0; + const rotDeg = parseFloat(spriteData.rotation || "0") || 0; + const sourceTexture = _replaceSegmentedBase(tab, spriteData.texture || `${cfg.fallbackBase}_01_001.png`, baseName); + const isSpiderLegTag = tab === "spider" && [0, 1, 4, 5].includes(tag); + const isRobotLegTag = tab === "robot" && [0, 2, 4, 6].includes(tag); + const isRobotArmTag = tab === "robot" && [1, 5].includes(tag); + const localYOffset = tab === "spider" + ? (tag === 3 ? 5 : (isSpiderLegTag ? -9 : 0)) + : (tag === 3 ? 5 : (isRobotArmTag ? -1 : (isRobotLegTag ? -9 : 0))); + const localXScale = tab === "spider" + ? (isSpiderLegTag ? 1.8 : 1) + : ((isRobotLegTag || isRobotArmTag) ? 1.8 : 1); + const variants = [ + { kind: "base", frame: sourceTexture, tint: muted ? 0xAFAFAF : window.mainColor, z: zValue * 0.1 }, + { kind: "overlay", frame: _selectorVariantFrameName(sourceTexture, "overlay"), tint: muted ? 0xffffff : window.secondaryColor, z: zValue * 0.1 + 0.04 }, + { kind: "extra", frame: _selectorVariantFrameName(sourceTexture, "extra"), tint: null, z: zValue * 0.1 + 0.08 } + ]; + for (const variant of variants) { + if (typeof getAtlasFrame !== "function" || !getAtlasFrame(this, variant.frame)) continue; + const img = this.add.image(pos.x * localXScale, -(pos.y + localYOffset), "GJ_GameSheetIcons", variant.frame); + img.rotation = rotDeg * Math.PI / 180; + img.scaleX = sc.x * (fl.x ? -1 : 1); + img.scaleY = sc.y * (fl.y ? -1 : 1); + if (variant.tint !== null && variant.tint !== undefined) img.setTint(variant.tint); + img._selectorZ = variant.z; + parts.push(img); + } + } + parts.sort((a, b) => (a._selectorZ || 0) - (b._selectorZ || 0)); + parts.forEach(part => container.add(part)); + if (!parts.length) { + container.destroy(true); + return null; + } + let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; + for (const img of parts) { + const w = Math.abs((img.width || 1) * (img.scaleX || 1)); + const h = Math.abs((img.height || 1) * (img.scaleY || 1)); + minX = Math.min(minX, img.x - w / 2); + maxX = Math.max(maxX, img.x + w / 2); + minY = Math.min(minY, img.y - h / 2); + maxY = Math.max(maxY, img.y + h / 2); + } + const width = Math.max(1, maxX - minX); + const height = Math.max(1, maxY - minY); + const fitScale = muted ? (maxSize / height) : Math.min(maxSize / width, maxSize / height); + container.setScale(fitScale); + container._selectorBaseScale = fitScale; + return container; + }; + + const _getPreviewFrame = (tab) => { + const prop = _iconWindowProps[tab]; + const frames = _iconFrameSets[tab] || []; + const currentValue = String(window[prop] || ""); + const match = frames.find(f => f.replace("_001.png", "") === currentValue); + return match || frames[0]; + }; + + const _refreshPreview = (tab, frame) => { + if (_isSegmentedIconTab(tab)) { + _destroySegmentedPreview(); + selectedIcon.setVisible(false); + selectedIconExtra.setVisible(false); + selectedIconOutline.setVisible(false); + selectedSegmentedPreview = _createSegmentedIconComposite(tab, frame, sw / 2, previewY, 82, 103, false); + if (selectedSegmentedPreview) this._iconOverlayObjects.push(selectedSegmentedPreview); + return; + } + _destroySegmentedPreview(); + selectedIcon.setVisible(true); + selectedIcon.setTexture(_iconAtlas[tab], frame); + const s = Math.min(80 / (selectedIcon.width || 80), 80 / (selectedIcon.height || 80)) * 0.85; + selectedIcon.setScale(s); + selectedIcon.setTint(window.mainColor); + const extraFrame = frame.replace("_001.png", "_2_001.png"); + const extraInfo = getAtlasFrame(this, extraFrame); + if (extraInfo) { + selectedIconExtra.setTexture(extraInfo.atlas, extraInfo.frame).setVisible(true).setScale(s).setTint(window.secondaryColor); + } else { + selectedIconExtra.setVisible(false); + } + const outlineFrame = frame.replace("_001.png", "_extra_001.png"); + const outlineInfo = getAtlasFrame(this, outlineFrame); + if (outlineInfo) { + selectedIconOutline.setTexture(outlineInfo.atlas, outlineInfo.frame).setVisible(true).setScale(s); + } else { + selectedIconOutline.setVisible(false); + } + }; + + _refreshPreview(startTab, _getPreviewFrame(startTab)); + this._iconOverlayObjects.push(selectedIconExtra, selectedIconOutline, selectedIcon); + + const tabBtnY = containerY - 40; + const tabKeys = ["icon", "ship", "ball", "ufo", "wave", "robot", "spider", "swing"]; + const tabSpacing = 58; + const tabOffsets = { + icon: -tabSpacing * 3.5, + ship: -tabSpacing * 2.5, + ball: -tabSpacing * 1.5, + ufo: -tabSpacing * 0.5, + wave: tabSpacing * 0.5, + robot: tabSpacing * 1.5, + spider: tabSpacing * 2.5, + swing: tabSpacing * 3.5, + }; + const tabRotations = { icon: -Math.PI/2, ship: 0, ball: -Math.PI/2, ufo: Math.PI/2, wave: Math.PI/2, robot: 0, spider: 0, swing: 0 }; + const tabFlipXStates = { icon: true, ship: false, ball: true, ufo: false, wave: false, robot: false, spider: false, swing: false }; + const tabFlipYStates = { icon: false, ship: false, ball: false, ufo: true, wave: true, robot: false, spider: false, swing: false }; + const tabBtnSprites = {}; + + const _switchTab = (tab) => { + for (const k of tabKeys) { + if (tabBtnSprites[k]) { + tabBtnSprites[k].setTexture("GJ_GameSheet03", + _safeTabBtnFrame(k, k === tab ? "on" : "off")); + } + } + _refreshPreview(tab, _getPreviewFrame(tab)); + _buildGrid(tab); + }; + + tabKeys.forEach((tab, i) => { + const isActive = tab === startTab; + const btn = this.add.image(sw / 2 + tabOffsets[tab], tabBtnY, "GJ_GameSheet03", + _safeTabBtnFrame(tab, isActive ? "on" : "off")) + .setScrollFactor(0).setDepth(104).setScale(0.75) + + .setInteractive(); + tabBtnSprites[tab] = btn; + this._iconOverlayObjects.push(btn); + this._makeBouncyButton(btn, 0.75, () => _switchTab(tab)); + }); + + this._iconGridObjects = []; + + const selLabel = this.add.image(0, 0, "GJ_GameSheet03", "GJ_select_001.png").setScrollFactor(0).setDepth(106).setOrigin(0.5, 0.5).setVisible(false); + this._iconOverlayObjects.push(selLabel); + + const iconsPerPage = cols * rows; + let currentPage = 0; + + const arrowY = containerY + containerHeight / 2; + const arrowMargin = 54; + + const prevArrow = this.add.image(containerX - arrowMargin, arrowY, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(106).setScale(0.8).setFlipX(false).setInteractive(); + const nextArrow = this.add.image(containerX + containerWidth + arrowMargin, arrowY, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(106).setScale(0.8).setInteractive().setFlipX(true); + + //bouncy buttons for arrows + const _getMaxPages = (tab) => { + return Math.ceil(_iconFrameSets[tab].length / iconsPerPage); + }; + const _prevPage = () => { + const maxPages = _getMaxPages(_currentTab); + currentPage = (currentPage - 1 + maxPages) % maxPages; + _updateNavDots(currentPage, _currentTab); + _buildGrid(_currentTab, currentPage); + }; + const _nextPage = () => { + const maxPages = _getMaxPages(_currentTab); + currentPage = (currentPage + 1) % maxPages; + _updateNavDots(currentPage, _currentTab); + _buildGrid(_currentTab, currentPage); + }; + this._makeBouncyButton(prevArrow, 0.8, _prevPage); + this._makeBouncyButton(nextArrow, 0.8, _nextPage); + this._iconOverlayObjects.push(prevArrow, nextArrow); + const _buildGrid = (tab, page = 0) => { + for (const o of this._iconGridObjects) { + if (o && o.destroy) o.destroy(); + } + this._iconGridObjects = []; + selLabel.setVisible(false); + const allFrames = _iconFrameSets[tab]; + const frames = allFrames.slice(page * iconsPerPage, (page + 1) * iconsPerPage); + const atlas = _iconAtlas[tab]; + const prop = _iconWindowProps[tab]; + frames.forEach((frame, idx) => { + const col = idx % cols; + const row = Math.floor(idx / cols); + const ix = startX + col * (iconSize + padding); + const iy = startY + row * (iconSize + padding); + const hitRect = this.add.rectangle(ix, iy, iconSize, iconSize, 0x000000, 0).setScrollFactor(0).setDepth(104).setInteractive(); + let iconImg; + let extraImg = null; + let outlineImg = null; + let origScale; + if (_isSegmentedIconTab(tab)) { + iconImg = _createSegmentedIconComposite(tab, frame, ix, iy, iconSize * 0.76, 103, true); + if (!iconImg) { + iconImg = this.add.image(ix, iy, "GJ_GameSheetIcons", frame).setScrollFactor(0).setDepth(103).setTint(0xAFAFAF); + origScale = Math.min(iconSize / (iconImg.width || iconSize), iconSize / (iconImg.height || iconSize)) * 0.7; + iconImg.setScale(origScale); + } else { + origScale = iconImg._selectorBaseScale || iconImg.scaleX || 1; + } + } else { + iconImg = this.add.image(ix, iy, atlas, frame).setScrollFactor(0).setDepth(103).setTint(0xAFAFAF); + origScale = Math.min( + iconSize / (iconImg.width || iconSize), + iconSize / (iconImg.height || iconSize) + ) * 0.7; + iconImg.setScale(origScale); + const extraFrame = frame.replace("_001.png", "_2_001.png"); + const extraInfo = getAtlasFrame(this, extraFrame); + extraImg = extraInfo + ? this.add.image(ix, iy, extraInfo.atlas, extraInfo.frame).setScrollFactor(0).setDepth(102).setScale(origScale) + : null; + const outlineFrame = frame.replace("_001.png", "_extra_001.png"); + const outlineInfo = getAtlasFrame(this, outlineFrame); + outlineImg = outlineInfo + ? this.add.image(ix, iy, outlineInfo.atlas, outlineInfo.frame).setScrollFactor(0).setDepth(103.5).setScale(origScale) + : null; + } + if (outlineImg) this._iconGridObjects.push(outlineImg); + if (extraImg) this._iconGridObjects.push(extraImg); + this._iconGridObjects.push(iconImg, hitRect); + if (frame.replace("_001.png", "") === window[prop]) { + selLabel.setPosition(ix, iy).setScale(0.75).setVisible(true); + } + + ((capturedFrame, capturedImg, capturedExtra, capturedOutline, capturedOrigScale) => { + const bouncedScale = capturedOrigScale * 1.26; + const iconTargets = [capturedImg, capturedExtra, capturedOutline].filter(Boolean); + hitRect.on("pointerdown", () => { + hitRect._pressed = true; + iconTargets.forEach(t => this.tweens.killTweensOf(t, "scale")); + iconTargets.forEach(t => this.tweens.add({ targets: t, scale: bouncedScale, duration: 300, ease: "Bounce.Out" })); + }); + hitRect.on("pointerout", () => { + if (hitRect._pressed) { + hitRect._pressed = false; + iconTargets.forEach(t => this.tweens.killTweensOf(t, "scale")); + iconTargets.forEach(t => this.tweens.add({ targets: t, scale: capturedOrigScale, duration: 400, ease: "Bounce.Out" })); + } + }); + hitRect.on("pointerup", () => { + hitRect._pressed = false; + iconTargets.forEach(t => { this.tweens.killTweensOf(t); t.setScale(capturedOrigScale); }); + if (!this._iconOverlay) return; + + selLabel.setPosition(capturedImg.x, capturedImg.y).setScale(0.75).setVisible(true); + + window[prop] = capturedFrame.replace("_001.png", ""); + localStorage.setItem("icon" + prop.charAt(0).toUpperCase() + prop.slice(1), window[prop]); + + if (tab === "icon" && this._player) { + const layerMap = [ + { lp: "_playerSpriteLayer", suffix: "_001.png", tint: window.mainColor }, + { lp: "_playerGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, + { lp: "_playerOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + { lp: "_playerExtraLayer", suffix: "_extra_001.png", tint: window.mainColor }, + ]; + for (const { lp, suffix, tint } of layerMap) { + const layer = this._player[lp]; + if (!layer || !layer.sprite) continue; + const found = getAtlasFrame(this, `${window.currentPlayer}${suffix}`); + if (found) { + layer.sprite.setTexture(found.atlas, found.frame); + if (tint !== null) layer.sprite.setTint(tint); + } + } + } + if (tab === "ship" && this._player) { + const layerMap = [ + { lp: "_shipSpriteLayer", suffix: "_001.png", tint: window.mainColor }, + { lp: "_shipGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, + { lp: "_shipOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + { lp: "_shipExtraLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + ]; + for (const { lp, suffix, tint } of layerMap) { + const layer = this._player[lp]; + if (!layer || !layer.sprite) continue; + const found = getAtlasFrame(this, `${window.currentShip}${suffix}`); + if (found) { + layer.sprite.setTexture(found.atlas, found.frame); + if (tint !== null) layer.sprite.setTint(tint); + } + } + } + if (tab === "ball" && this._player) { + const layerMap = [ + { lp: "_ballSpriteLayer", suffix: "_001.png", tint: window.mainColor }, + { lp: "_ballGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, + { lp: "_ballOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + ]; + for (const { lp, suffix, tint } of layerMap) { + const layer = this._player[lp]; + if (!layer || !layer.sprite) continue; + const found = getAtlasFrame(this, `${window.currentBall}${suffix}`); + if (found) { + layer.sprite.setTexture(found.atlas, found.frame); + layer.sprite.setTint(tint); + } + } + } + if (tab === "wave" && this._player) { + const layerMap = [ + { lp: "_waveSpriteLayer", suffix: "_001.png", tint: window.mainColor }, + { lp: "_waveGlowLayer", suffix: "_glow_001.png", tint: window.secondaryColor }, + { lp: "_waveOverlayLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + ]; + for (const { lp, suffix, tint } of layerMap) { + const layer = this._player[lp]; + if (!layer || !layer.sprite) continue; + const found = getAtlasFrame(this, `${window.currentWave}${suffix}`); + if (found) { + layer.sprite.setTexture(found.atlas, found.frame); + if (tint !== null) layer.sprite.setTint(tint); + } + } + } + if (tab === "ufo" && this._player) { + const layerMap = [ + { lp: "_birdSpriteLayer", suffix: "_001.png", tint: window.mainColor }, + { lp: "_birdGlowLayer", suffix: "_2_001.png", tint: window.secondaryColor }, + { lp: "_birdOverlayLayer", suffix: "_3_001.png", tint: window.secondaryColor }, + { lp: "_birdExtraLayer", suffix: "_extra_001.png",tint: window.mainColor }, + ]; + for (const { lp, suffix, tint } of layerMap) { + const layer = this._player[lp]; + if (!layer || !layer.sprite) continue; + const found = getAtlasFrame(this, `${window.currentBird}${suffix}`); + if (found) { + layer.sprite.setTexture(found.atlas, found.frame); + if (tint !== null) layer.sprite.setTint(tint); + } + } + } + + _refreshPreview(tab, capturedFrame); + }); + })(frame, iconImg, extraImg, outlineImg, origScale); + }); + }; + + let _currentTab = startTab; + + const _switchTabOrig = _switchTab; + const _switchTabPaged = (tab) => { + _currentTab = tab; + currentPage = 0; + _updateNavDots(0, tab); + for (const k of tabKeys) { + if (tabBtnSprites[k]) { + tabBtnSprites[k].setTexture("GJ_GameSheet03", + _safeTabBtnFrame(k, k === tab ? "on" : "off")); + } + } + _refreshPreview(tab, _getPreviewFrame(tab)); + _buildGrid(tab, 0); + }; + tabKeys.forEach(tab => { + const btn = tabBtnSprites[tab]; + if (btn) { + btn.removeAllListeners("pointerup"); + btn.removeAllListeners("pointerdown"); + btn.removeAllListeners("pointerout"); + this._makeBouncyButton(btn, 0.75, () => _switchTabPaged(tab)); + } + }); + + _updateNavDots(0, startTab); + _buildGrid(startTab, 0); + }; + + this._closeIconSelector = (silent = false) => { + if (!this._iconOverlay) return; + const destroy = () => { + if (this._iconGridObjects) { + for (const obj of this._iconGridObjects) { + if (obj && obj.destroy) obj.destroy(); + } + this._iconGridObjects = null; + } + if (this._iconOverlayObjects) { + for (const obj of this._iconOverlayObjects) { + if (obj && obj.destroy) obj.destroy(); + } + this._iconOverlayObjects = null; + } + this._iconOverlay = null; + }; + if (silent) { destroy(); return; } + const sw = screenWidth; + const sh = screenHeight; + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ + targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", + onComplete: () => { + destroy(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._closeCreatorMenu = (silent = false) => { + if (!this._creatorOverlay) return; + if (silent == false) this._creatorMenuOpen = false; + const destroy = () => { + if (this._creatorOverlayObjects) { + for (const obj of this._creatorOverlayObjects) { + if (obj && obj.destroy) obj.destroy(); + } + this._creatorOverlayObjects = null; + } + this._creatorOverlay = null; + }; + if (silent) { destroy(); return; } + const sw = screenWidth; + const sh = screenHeight; + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ + targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", + onComplete: () => { + destroy(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._positionMenuItems(); + //icon stuff sequel + if (this._iconBtn) { + this._iconBtn.x = (screenWidth / 2) - this._playBtn.width / 2 - 50 - (this._iconBtn.width * this._iconBtn.scaleX) / 2; + this.tweens.killTweensOf(this._iconBtn, "y"); + this._iconBtn.y = 320; + if (this._chrSelDecor) this._chrSelDecor.destroy(); + this._chrSelDecor = this.add.image(this._iconBtn.x - 110, this._iconBtn.y - (this._iconBtn.height * this._iconBtn.scaleY) / 2 + 160, "GJ_GameSheet03", "GJ_chrSel_001.png").setScrollFactor(0).setDepth(31); +} + if (this._creatorBtn) { + this._creatorBtn.x = (screenWidth / 2) + this._playBtn.width / 2 + 50 + (this._creatorBtn.width * this._creatorBtn.scaleX) / 2; + this.tweens.killTweensOf(this._creatorBtn, "y"); + this._creatorBtn.y = 320; + if (this._lvlEditDecor) this._lvlEditDecor.destroy(); + this._lvlEditDecor = this.add.image(this._creatorBtn.x + 110, this._creatorBtn.y - (this._creatorBtn.height * this._creatorBtn.scaleY) / 2 + 160, "GJ_GameSheet03", "GJ_lvlEdit_001.png").setScrollFactor(0).setDepth(31); +} + this._spaceWasDown = false; + this._spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); + this._upKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP); + this._wKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W); + this._lKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.L); + this._leftKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT); + this._rightKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT); + this._aKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A); + this._dKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D); + + this._startPosIndex = -1; + + this.input.keyboard.on('keydown-Q', () => { + if (!window.startPosSwitcher) return; + this.changeStartPos(-1); + }); + + this.input.keyboard.on('keydown-E', () => { + if (!window.startPosSwitcher) return; + this.changeStartPos(1); + }); + + this._percentageLabel = this.add.bitmapText(screenWidth / 2, 20, "bigFont", "0%", 30).setOrigin(0.5, 0.5); + this._percentageLabel.setVisible(false); + this._percentageLabel.setDepth(100); + + this._noclipIndicator = this.add.bitmapText(10, 10, "bigFont", "Noclip", 20) + .setOrigin(0, 0) + .setAlpha(0.4) + .setDepth(100) + .setVisible(false); + + this._accuracyIndicator = this.add.bitmapText(10, 30, "bigFont", "100.00%", 20) + .setOrigin(0, 0) + .setAlpha(0.4) + .setDepth(100) + .setVisible(false); + + this._deathsIndicator = this.add.bitmapText(10, 50, "bigFont", "0 Deaths", 20) + .setOrigin(0, 0) + .setAlpha(0.4) + .setDepth(100) + .setVisible(false); + + this._cpsIndicator = this.add.bitmapText(10, 70, "bigFont", "0 CPS", 20) + .setOrigin(0, 0) + .setAlpha(0.4) + .setDepth(100) + .setVisible(false); + + this._bottedIndicator = this.add.bitmapText(10, 70, "bigFont", "Botted", 20) + .setOrigin(0, 0) + .setAlpha(0.4) + .setDepth(100) + .setTint(0xff0000) + .setVisible(false); + + this.noclipFlash = this.add.rectangle( + this.cameras.main.centerX, + this.cameras.main.centerY, + this.cameras.main.width, + this.cameras.main.height, + 0xff0000 + ); + this.noclipFlash.setScrollFactor(0); + this.noclipFlash.setDepth(99); + this.noclipFlash.setAlpha(0); + + this._updatePracticeHUDBar = () => {}; + + this._pauseBtn = this.add.image(screenWidth - 30, 30, "GJ_WebSheet", "GJ_pauseBtn_clean_001.png").setScrollFactor(0).setDepth(30).setAlpha(75 / 255).setVisible(false); + this._pauseBtn.setInteractive(); + this._expandHitArea(this._pauseBtn, 2); + this._pauseBtn.on("pointerdown", () => this._pauseGame()); + this._escKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ESC); + this._escKey.on("down", () => { + if (this._levelSelectOverlay) { + this._closeLevelSelect(); + return; + } + if (this._iconOverlay) { + this._closeIconSelector(); + return; + } + if (this._updateLogPopup) { + this._closeUpdateLogPopup(); + return; + } + if (this._levelViewOverlay) { + this._closeLevelView(); + return; + } + if (this._editorOverlay) { + this._closeEditorMenu(); + this._openCreatorMenu(); + return; + } + if (this._playOverlay) { + this._closePlayMenu(false, () => this._playMenuBackTarget()); + return; + } + if (this._searchResultOverlay) { + this._closeSearchResultScene(); + return; + } + if (this._searchOverlay) { + this._closeSearchMenu(true); + this._openCreatorMenu(); + return; + } + if (this._onlineLevelsOverlay) { + this._closeOnlineLevelsScene(); + return; + } + if (this._creatorOverlay) { + this._closeCreatorMenu(); + return; + } + if (this._settingsPopup) { + this._settingsPopup.destroy(); + this._settingsPopup = null; + return; + } + if (this._macroPopup) { + this.events.off("update", this._refreshMacroButtons); + this._macroPopup.destroy(); + this._macroPopup = null; + return; + } + if (this._settingsLayerOverlay) { + if (!this._settingsScreenClosing) { + this._hideSettingsScreen(); + } + return; + } + if (this._infoPopup) { + this._infoPopup.destroy(); + this._infoPopup = null; + return; + } + if (this._newgroundsPopup) { + this._closeNewgroundsPopup(); + return; + } + if (this._editorTriggerChannelPopup) { + if (typeof this._closeEditorTriggerChannelPopup === "function") { + this._closeEditorTriggerChannelPopup(); + } else { + this._editorTriggerChannelPopup.destroy(); + this._editorTriggerChannelPopup = null; + } + return; + } + if (this._editorColorPickerPopup) { + this._closeEditorColorPickerPopup(); + return; + } + if (this._editorHorizontalOptionPopup) { + this._closeEditorHorizontalOptionPopup(); + return; + } + if (this._editorStartOptionsPopup) { + this._closeEditorStartOptionsPopup(); + return; + } + if (this._editorLevelSettingsPopup) { + this._closeEditorLevelSettingsPopup(); + return; + } + if (this._statsLayerOverlay) { + this._hideStatsScreen(); + return; + } + if (this._paused) { + this._audio.playEffect("quitSound_01"); + this._audio.stopMusic(); + this._resumeGame(); + this.scene.restart(); + } else if (!this._menuActive && !this._slideIn && !this._levelWon) { + this._pauseGame(); + } + }); + this._restartKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.R); + this._restartKey.on("down", () => { + if (!this._menuActive && !this._slideIn && !this._levelWon && !this._menuActive) { + this._restartLevel(); + } + }); + this._practiceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.P); + this._practiceKey.on("down", () => { + if (!this._menuActive && !this._slideIn) { + const isPracticeMode = this._practicedMode.togglePracticeMode(); + if (this._checkpointBtnContainer) { + this._checkpointBtnContainer.setVisible(isPracticeMode); + } + if (this._practiceModeBarContainer) { + this._practiceModeBarContainer.setVisible(isPracticeMode); + } + this._audio.startMusic(this._getCurrentMusicSyncOffset()); + } + }); + this._saveCheckpointKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Z); + this._saveCheckpointKey.on("down", () => { + if (!this._menuActive && !this._slideIn && this._practicedMode.practiceMode) { + const saved = this._practicedMode.saveCheckpoint(this._state, this._playerWorldX, this._cameraX, this); + if (saved) { + } + } + }); + this._deleteCheckpointKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.X); + this._deleteCheckpointKey.on("down", () => { + if (!this._menuActive && !this._slideIn && this._practicedMode.practiceMode) { + const deleted = this._practicedMode.deleteLastCheckpoint(); + } + }); + this._paused = false; + this._pauseContainer = null; + this._sfxVolume = localStorage.getItem("userSfxVol") ?? 1; + this._initMacroBot(); + this.input.on("pointerdown", () => { + if (!this._menuActive && !this._paused && !this._levelSelectOverlay && !this._levelWon && !window.isEditor) { + this._pushButton(); + } + }); + this.input.on("pointerup", () => { + if (!this._menuActive && !this._paused && !this._levelSelectOverlay && !this._levelWon && !window.isEditor) { + this._releaseButton(); + } + }); + if (!window.gdpointerup) { + window.gdpointerup = true; + window.addEventListener("pointerup", () => this._releaseButton(true)); + } + if (!window.gdtouchend) { + window.gdtouchend = true; + window.addEventListener("touchend", () => this._releaseButton(true)); + } + this.scale.on("enterfullscreen", () => this._onFullscreenChange(true)); + this.scale.on("leavefullscreen", () => this._onFullscreenChange(false)); + + this._buildHUD(); + this._createStartPosGui(); + this._loadSettings(); + + document.addEventListener("visibilitychange", () => { + if (document.hidden) { + this._audio.pauseMusic(); + } else if (!this._menuActive && !this._paused && !this._state.isDead && !this._levelWon) { + this._audio.resumeMusic(); + } + }); + if (!window.gdorientationchange) { + window.gdorientationchange = true; + window.addEventListener("orientationchange", () => { + this.time.delayedCall(100, () => this.scale.refresh()); + }); + } + if (!window.gdresize) { + window.gdresize = true; + window.addEventListener("resize", () => { + this.scale.refresh(); + }); + } + if (this.game.registry.get("fadeInFromBlack")) { + this.game.registry.remove("fadeInFromBlack"); + this.cameras.main.fadeIn(400, 0, 0, 0); + } + this._levelLabel = this.add.bitmapText(screenWidth - 565, 30, "bigFont", window.currentlevel[1], 30).setOrigin(0.5, 0.5).setVisible(false); + this._levelLabel.setScale(Math.min(1, 220 / this._levelLabel.width)); + + this._leftBtn = this.add.image(screenWidth - 700, 30, "GJ_GameSheet03", "edit_leftBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setVisible(false); + this._rightBtn = this.add.image(screenWidth - 429, 30, "GJ_GameSheet03", "edit_leftBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive().setVisible(false); + this._rightBtn.setRotation(Math.PI); + window.scene = this.scene; + window.rightbuttoncallback = () => { + if (this._levelSelectOverlay && this._levelSelectSwitchLevel) { + this._levelSelectSwitchLevel(1); + } + }; + window.leftbuttoncallback = () => { + if (this._levelSelectOverlay && this._levelSelectSwitchLevel) { + this._levelSelectSwitchLevel(-1); + } + }; + this._makeBouncyButton(this._leftBtn, 1, () => {window.leftbuttoncallback()}, () => this._menuActive); + this._makeBouncyButton(this._rightBtn, 1, () => {window.rightbuttoncallback()}, () => this._menuActive); + const menuMusicEnabled = localStorage.getItem("menuMusicEnabled"); + const shouldPlayMenuMusic = menuMusicEnabled === null ? true : menuMusicEnabled === "true"; + + if (window.isEditor) { + this._audio.stopMusic(); + } else if (!this._audio.isplaying() && shouldPlayMenuMusic) { + this._audio.startMenuMusic(); + } else if (this._audio.isplaying() && !shouldPlayMenuMusic) { + this._audio.stopMusic(); + } + if (!window.updateLogShown) { + this._buildUpdateLogPopup(); + window.updateLogShown = true; + } + if (window.levelID) { + this._openSearchMenu(); + } + if (this.game.registry.get("autoStartGame")) { + if (!window.settingsMap) { + const cachedLevelText = this.cache.text.get(window.currentlevel[2]) || + ((window._onlineLevelString && window.currentlevel[2] === window._onlineLevelId) ? window._onlineLevelString : null); + if (cachedLevelText) { + this._level.loadLevel(cachedLevelText); + } + } + if (window.settingsMap) { + this.game.registry.remove("autoStartGame"); + this._levelLabel.setVisible(false); + this._leftBtn.setVisible(false); + this._rightBtn.setVisible(false); + if (this._practiceModeBarContainer) { + this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); + } + this._instantLevelStart = true; + this._startGame(); + } else { + console.warn("autoStartGame: missing settingsMap for", window.currentlevel && window.currentlevel[2]); + } + } else if (window._createdLevelReturnToView) { + const returnTarget = window._createdLevelReturnToView; + window._createdLevelReturnToView = null; + const levelId = returnTarget?.createdId; + let level = null; + try { + const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); + level = createdLevels.find(entry => + entry && levelId !== undefined && levelId !== null && + String(entry.createdId) === String(levelId) + ) || null; + } catch (err) { + console.warn("Failed to restore the created-level view", err); + } + if (!level && returnTarget?.snapshot) { + level = returnTarget.snapshot; + } + if (level) { + this._openLevelView(level); + } else { + this._openEditorMenu(); + } + } else if (window._editorReturnToLevelViewId) { + const levelId = window._editorReturnToLevelViewId; + window._editorReturnToLevelViewId = null; + let level = null; + try { + const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); + level = createdLevels.find(entry => entry && entry.createdId === levelId) || null; + } catch (err) { + console.warn("Failed to restore the editor level view", err); + } + if (level) { + this._openLevelView(level); + } else { + this._openEditorMenu(); + } + } else if (window._onlineReturnToPlayMenu) { + const { lvl, backTarget } = window._onlineReturnToPlayMenu; + window._onlineReturnToPlayMenu = null; + window._selectedLevelData = lvl; + this._openPlayMenu(backTarget); + } + } + _parseLevelColors(levelId) { + const LEVEL_COLORS = [ + 0x0100f5,0xf902f8,0xf90285,0xfa0102, + 0xfa8702,0xfcfc06,0x03fb03,0x02fbfb, + 0x007dff + ]; + let index = 0; + if (window.allLevels) { + index = window.allLevels.findIndex(l => l[2] === levelId); + if (index === -1) index = 0; + } + const bgHex = LEVEL_COLORS[index % LEVEL_COLORS.length]; + return { bgHex, groundHex: bgHex }; + } + _openLevelSelect() { + if (this._levelSelectOverlay) return; + const sw = screenWidth; + const sh = screenHeight; + const cx = sw / 2; + const cy = sh / 2; + let { bgHex, groundHex } = this._parseLevelColors(window.currentlevel[2]); + const drawOverlay = (gfx, colorHex, isEveryEnd = false) => { + gfx.clear(); + const rRaw = (colorHex >> 16) & 0xff; + const gRaw = (colorHex >> 8) & 0xff; + const bRaw = colorHex & 0xff; + const topMul = isEveryEnd ? 0.30 : 0.65; + const botMul = isEveryEnd ? 0.18 : 0.42; + const steps = 60; + for (let i = 0; i < steps; i++) { + const t = i / (steps - 1); + const mul = topMul + (botMul - topMul) * t; + const r2 = Math.min(255, Math.round(rRaw * mul)); + const g2 = Math.min(255, Math.round(gRaw * mul)); + const b2 = Math.min(255, Math.round(bRaw * mul)); + gfx.fillStyle((r2 << 16) | (g2 << 8) | b2, 1); + const y0 = Math.floor(i * sh / steps); + gfx.fillRect(0, y0, sw, Math.ceil(sh / steps) + 1); + } + }; + const isEveryEnd = (levelId) => levelId === "level_99"; + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(200); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 300, ease: "Linear", onComplete: () => fadeIn.destroy() }); + const overlay = this.add.graphics().setScrollFactor(0).setDepth(150); + drawOverlay(overlay, bgHex, isEveryEnd(window.currentlevel[2])); + this._levelSelectOverlay = overlay; + const tableBottom = this.add.image(cx, 0, "GJ_GameSheet03", "GJ_topBar_001.png").setScrollFactor(0).setDepth(152).setOrigin(0.5, 0); + const groundY = sh + 175; + const groundId = (window._groundId || "00"); + const groundFrame = this.textures.getFrame("groundSquare_" + groundId + "_001.png"); + const referenceGroundFrame = this.textures.getFrame("groundSquare_00_001.png") || groundFrame; + const referenceGroundH = referenceGroundFrame ? referenceGroundFrame.height : 270; + const groundTopY = groundY - referenceGroundH; + const tileW = groundFrame ? groundFrame.width : 1012; + const numTiles = Math.ceil(sw / tileW) + 2; + const groundTintHex = (colorHex) => { + const r = Math.round(((colorHex >> 16) & 0xff) * 0.45); + const g = Math.round(((colorHex >> 8) & 0xff) * 0.45); + const b = Math.round(( colorHex & 0xff) * 0.45); + return (r << 16) | (g << 8) | b; + }; + const staticGroundTiles = []; + const staticGround2Tiles = []; + const ground2Key = "groundSquare_" + groundId + "_2_001.png"; + const hasGround2 = this.textures.exists(ground2Key); + for (let gi = 0; gi < numTiles; gi++) { + const tileX = gi * tileW; + const gt = this.add.image(tileX, groundTopY, "groundSquare_" + groundId + "_001.png") + .setScrollFactor(0).setDepth(151).setOrigin(0, 0).setTint(groundTintHex(groundHex)); + staticGroundTiles.push(gt); + if (hasGround2) { + const gt2 = this.add.image(tileX, groundTopY, ground2Key) + .setScrollFactor(0).setDepth(151.5).setOrigin(0, 0).setTint(groundTintHex(groundHex)); + staticGround2Tiles.push(gt2); + } + } + const floorLineFrame = this.textures.getFrame("GJ_WebSheet", "floorLine_01_001.png"); + const floorLineW = floorLineFrame ? floorLineFrame.width : 888; + const floorLineScale = sw / floorLineW; + const staticFloorLine = this.add.image(cx, groundTopY, "GJ_WebSheet", "floorLine_01_001.png") + .setScrollFactor(0).setDepth(152).setOrigin(0.5, 0.5).setScale(floorLineScale, 1).setBlendMode(S); + const cornerBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(0, 1).setFlipY(false); + const cornerBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png").setScrollFactor(0).setDepth(152).setOrigin(1, 1).setFlipX(true); + const backBtn = this.add.image(50, 48, "GJ_GameSheet03", "GJ_arrow_01_001.png").setScrollFactor(0).setDepth(154).setFlipX(true).setScale(1, -1).setRotation(Math.PI).setInteractive(); + backBtn.on("pointerdown", () => { + backBtn._pressed = true; + this.tweens.killTweensOf(backBtn); + this.tweens.add({ targets: backBtn, scaleX: 1.26, scaleY: -1.26, duration: 300, ease: "Bounce.Out" }); + }); + backBtn.on("pointerout", () => { + if (backBtn._pressed) { + backBtn._pressed = false; + this.tweens.killTweensOf(backBtn); + this.tweens.add({ targets: backBtn, scaleX: 1, scaleY: -1, duration: 400, ease: "Bounce.Out" }); + } + }); + backBtn.on("pointerup", () => { + if (backBtn._pressed) { + backBtn._pressed = false; + this.tweens.killTweensOf(backBtn); + backBtn.setScale(1, -1); + this._closeLevelSelect(); + } + }); + const infoBtn = this.add.image(sw - 40, 40, "GJ_GameSheet03", "GJ_infoIcon_001.png").setScrollFactor(0).setDepth(154).setInteractive(); + const arrowL = this.add.image(55, cy - 25, "GJ_GameSheet03", "navArrowBtn_001.png").setScrollFactor(0).setDepth(154).setScale(1.1).setFlipX(true).setInteractive(); + const arrowR = this.add.image(sw - 55, cy - 25, "GJ_GameSheet03", "navArrowBtn_001.png").setScrollFactor(0).setDepth(154).setScale(1.1).setFlipX(false).setInteractive(); + const allLevels = window.allLevels || []; + const visibleLevels = allLevels.filter(level => !(level && level[2] === "level_22")); + const pageCount = visibleLevels.length + 1; + let currentPageIndex = visibleLevels.findIndex(l => l[2] === window.currentlevel[2]); + if (currentPageIndex < 0) currentPageIndex = 0; + const isComingSoonPage = () => currentPageIndex >= visibleLevels.length; + const getPageLevel = () => { + if (isComingSoonPage()) return visibleLevels[visibleLevels.length - 1] || window.currentlevel || []; + return visibleLevels[currentPageIndex] || window.currentlevel || []; + }; + const applyCurrentPage = () => { + this._levelSelectIsComingSoonPage = isComingSoonPage(); + if (!isComingSoonPage() && visibleLevels[currentPageIndex]) { + window.currentlevel = [...visibleLevels[currentPageIndex]]; + } + }; + applyCurrentPage(); + const dotY = sh - 36; + const maxDots = Math.min(pageCount, 28); + const dotSpacing = 27; + const dotStartX = cx - (maxDots - 1) * dotSpacing / 2; + const dotObjs = []; + const refreshDots = () => { + for (const d of dotObjs) d.destroy(); + dotObjs.length = 0; + for (let di = 0; di < maxDots; di++) { + const active = di === currentPageIndex; + const d = this.add.graphics().setScrollFactor(0).setDepth(153); + d.fillStyle(0xffffff, active ? 1 : 0.3); + d.fillCircle(dotStartX + di * dotSpacing, dotY, 7); + dotObjs.push(d); + } + }; + refreshDots(); + const cardW = Math.min(700, sw - 180); + const cardH = 180; + const cardX = cx; + const cardY = cy - 100; + const cardSlideContainer = this.add.container(0, 0).setScrollFactor(0).setDepth(152); + const cardBounceContainer = this.add.container(cardX, cardY).setScrollFactor(0).setDepth(0); + cardSlideContainer.add(cardBounceContainer); + const cardContainer = cardSlideContainer; + const cardBg = this.add.graphics(); + const drawCardBg = (colorHex, dark = false, textOnly = false) => { + cardBg.clear(); + if (textOnly) return; + const mul = dark ? 0.10 : 0.22; + const r = Math.round(((colorHex >> 16) & 0xff) * mul); + const g = Math.round(((colorHex >> 8) & 0xff) * mul); + const b = Math.round(( colorHex & 0xff) * mul); + cardBg.fillStyle((r << 16) | (g << 8) | b, 0.92); + cardBg.fillRoundedRect(-cardW / 2, -cardH / 2, cardW, cardH, 14); + }; + drawCardBg(bgHex, isEveryEnd(window.currentlevel[2]), isComingSoonPage()); + cardBounceContainer.add(cardBg); + + const cardHit = this.add.zone(cardX, cardY, cardW, cardH) + .setScrollFactor(0).setDepth(156).setInteractive(); + const dragState = { + pressed: false, + dragging: false, + startX: 0, + lastX: 0, + velSamples: [], + get vel() { + if (!this.velSamples.length) return 0; + return this.velSamples.reduce((a, b) => a + b, 0) / this.velSamples.length; + }, + pushVel(v) { + this.velSamples.push(v); + if (this.velSamples.length > 5) this.velSamples.shift(); + }, + reset() { + this.pressed = false; + this.dragging = false; + this.velSamples = []; + } + }; + + const onDragStart = (ptr) => { + dragState.pressed = true; + dragState.startX = ptr.x; + dragState.lastX = ptr.x; + dragState.dragging = false; + dragState.velSamples = []; + }; + cardHit.on("pointerdown", (ptr) => { + onDragStart(ptr); + if (isComingSoonPage()) return; + this.tweens.killTweensOf(cardBounceContainer, "scale"); + this.tweens.add({ targets: cardBounceContainer, scale: 1.26, duration: 300, ease: "Bounce.Out" }); + }); + + const onDragMove = (ptr) => { + if (!dragState.pressed) return; + const dx = ptr.x - dragState.startX; + const frameDelta = ptr.x - dragState.lastX; + dragState.pushVel(frameDelta); + dragState.lastX = ptr.x; + if (!dragState.dragging && Math.abs(dx) > 12) { + dragState.dragging = true; + this.tweens.killTweensOf(cardBounceContainer, "scale"); + this.tweens.add({ targets: cardBounceContainer, scale: 1, duration: 200, ease: "Quad.Out" }); + } + if (dragState.dragging) { + cardContainer.x = dx; + } + }; + const onDragUp = (ptr) => { + if (!dragState.pressed) return; + const wasDragging = dragState.dragging; + const totalDx = ptr.x - dragState.startX; + const vel = dragState.vel; + dragState.reset(); + if (wasDragging) { + const dragThreshold = cardW * 0.18; + if (Math.abs(totalDx) > dragThreshold || Math.abs(vel) > 3) { + const dir = totalDx < 0 ? 1 : -1; + switchLevel(dir, cardContainer.x, vel); + } else { + if (_currentAnimUpdate) { + this.events.off("preupdate", _currentAnimUpdate); + _currentAnimUpdate = null; + } + let snapX = cardContainer.x; + let snapVel = vel * 40; + const snapUpdate = (time, delta) => { + const dt = Math.min(delta / 1000, 0.05); + const tension = 400; + const friction = 18; + const force = -tension * snapX - friction * snapVel; + snapVel += force * dt; + snapX += snapVel * dt; + if (Math.abs(snapX) < 0.5 && Math.abs(snapVel) < 5) { + snapX = 0; + this.events.off("preupdate", snapUpdate); + if (_currentAnimUpdate === snapUpdate) _currentAnimUpdate = null; + } + cardContainer.x = snapX; + }; + _currentAnimUpdate = snapUpdate; + this.events.on("preupdate", snapUpdate); + } + } else { + if (ptr.x >= cardX - cardW/2 && ptr.x <= cardX + cardW/2 && + ptr.y >= cardY - cardH/2 && ptr.y <= cardY + cardH/2) { + if (isComingSoonPage()) { + return; + } + + this.input.enabled = false; + this.tweens.killTweensOf(cardBounceContainer, "scale"); + cardBounceContainer.setScale(1); + + const lvl = window.currentlevel; + const songID = lvl[0]; + const levelFileName = lvl[2]; + const songFileName = lvl[4] ? lvl[4] : lvl[1].replaceAll(" ", ""); + + const loadingText = this.add.bitmapText(cx, cy, "goldFont", "Downloading Level Assets...", 20).setOrigin(0.5).setDepth(200); + + this.load.text(levelFileName, "assets/levels/" + levelFileName.split("_")[1] + ".txt"); + this.load.audio(songID, "assets/music/" + songFileName + ".mp3"); + + this.load.once("complete", () => { + loadingText.destroy(); + this._audio.playEffect("playSound_01", { volume: 1 }); + this._closeLevelSelect(true); + this._audio.stopMusic(); + this.input.enabled = true; + this.game.registry.set("autoStartGame", true); + this.scene.restart(); + }); + + this.load.start(); + } else { + this.tweens.killTweensOf(cardBounceContainer, "scale"); + this.tweens.add({ targets: cardBounceContainer, scale: 1, duration: 200, ease: "Quad.Out" }); + } + } + }; + this.input.on("pointermove", onDragMove); + this.input.on("pointerup", onDragUp); + const _origClose = this._closeLevelSelect.bind(this); + const _patchedClose = (doTransition) => { + this.input.off("pointermove", onDragMove); + this.input.off("pointerup", onDragUp); + this._closeLevelSelect = _origClose; + _origClose(doTransition); + }; + this._closeLevelSelect = _patchedClose; + const cardContentObjs = []; + const buildCardContent = () => { + for (const o of cardContentObjs) { this.tweens.killTweensOf(o); o.destroy(); } + cardContentObjs.length = 0; + if (isComingSoonPage()) { + this.tweens.killTweensOf(cardBounceContainer, "scale"); + cardBounceContainer.setScale(1); + const comingSoonLabel = this.add.bitmapText(0, 0, "bigFont", "Coming Soon!", 56) + .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); + comingSoonLabel.setScale(Math.min(1, (cardW - 40) / comingSoonLabel.width)); + cardContentObjs.push(comingSoonLabel); + cardBounceContainer.add(comingSoonLabel); + return; + } + const lvl = window.currentlevel; + const levelId = lvl[2] || "level_1"; + const levelDifficultyMap = { + "level_1": "diffIcon_01_btn_001", + "level_2": "diffIcon_01_btn_001", + "level_3": "diffIcon_02_btn_001", + "level_4": "diffIcon_02_btn_001", + "level_5": "diffIcon_03_btn_001", + "level_6": "diffIcon_03_btn_001", + "level_7": "diffIcon_04_btn_001", + "level_8": "diffIcon_04_btn_001", + "level_9": "diffIcon_04_btn_001", + "level_10": "diffIcon_05_btn_001", + "level_11": "diffIcon_05_btn_001", + "level_12": "diffIcon_05_btn_001", + "level_13": "diffIcon_05_btn_001", + "level_14": "diffIcon_06_btn_001", + "level_15": "diffIcon_05_btn_001", + "level_16": "diffIcon_05_btn_001", + "level_17": "diffIcon_04_btn_001", + "level_18": "diffIcon_06_btn_001", + "level_19": "diffIcon_04_btn_001", + "level_20": "diffIcon_06_btn_001", + "level_21": "diffIcon_05_btn_001", + "level_22": "diffIcon_05_btn_001", + "level_99": "diffIcon_10_btn_001", + "level_100": "diffIcon_10_btn_001", + "level_137409445": "diffIcon_00_btn_001", + "level_5703070": "diffIcon_07_btn_001", + "level_137677336": "diffIcon_00_btn_001", + "level_116489424": "diffIcon_00_btn_001", + "level_4284013": "diffIcon_06_btn_001", + "level_56199846": "diffIcon_04_btn_001", + "level_23": "diffIcon_10_btn_001" + }; + const diffIconKey = levelDifficultyMap[levelId] || "diffIcon_05_btn_001"; + const diffFrame = diffIconKey + ".png"; + const iconX = cardX - cardW / 2 + 52; + const isHardDemon = diffIconKey === "diffIcon_06_btn_001"; + const iconRotation = isHardDemon ? Math.PI / 2 : 0; + const demonIcon = this.add.image(iconX - cardX, 0, "GJ_GameSheet03", diffFrame) + .setScrollFactor(0).setDepth(155).setScale(1).setOrigin(0.5, 0.5); + cardContentObjs.push(demonIcon); + cardBounceContainer.add(demonIcon); + const maxIconH = cardH - 16; + const maxIconW = 80; + const iconFrame = this.textures.getFrame("GJ_GameSheet03", diffFrame); + let finalIconScale = 1; + if (iconFrame) { + const scaleForH = maxIconH / iconFrame.height; + let scaleForW = maxIconW / iconFrame.width; + finalIconScale = Math.min(1, scaleForH, scaleForW); + demonIcon.setScale(finalIconScale); + } + let iconDisplayW = (iconFrame ? iconFrame.width : 80) * finalIconScale; + const iconDisplayH = (iconFrame ? iconFrame.height : 80) * finalIconScale; + const nameLabel = this.add.bitmapText(0, 0, "bigFont", lvl[1], 50) + .setScrollFactor(0).setDepth(155).setOrigin(0, 0.5); + const gap = 25; + const naturalGroupW = iconDisplayW + gap + nameLabel.width; + const naturalGroupH = Math.max(iconDisplayH, nameLabel.height); + const cardPad = 16; + const maxGroupW = cardW - cardPad * 2; + const maxGroupH = cardH - cardPad * 2; + const groupScale = Math.min(1, maxGroupW / naturalGroupW, maxGroupH / naturalGroupH); + const scaledIconW = iconDisplayW * groupScale; + const scaledLabelW = nameLabel.width * groupScale; + const scaledGap = gap * groupScale; + const totalW = scaledIconW + scaledGap + scaledLabelW; + const groupStartX = cardX - totalW / 2; + demonIcon.setScale(finalIconScale * groupScale); + demonIcon.setPosition(groupStartX + scaledIconW / 2 - cardX, 0); + nameLabel.setScale(groupScale); + nameLabel.setPosition(groupStartX + scaledIconW + scaledGap - cardX, 0); + cardContentObjs.push(nameLabel); + cardBounceContainer.add(nameLabel); + }; + const barAreaY = cardY + cardH / 2 + 100; + const barW2 = Math.min(600, sw - 200); + const barH2 = 36; + const barX0 = cx - barW2 / 2; + let barObjs = []; + const buildBar = () => { + for (const o of barObjs) { this.tweens.killTweensOf(o); o.destroy(); } + barObjs.length = 0; + if (isComingSoonPage()) return; + const bestNormal = parseFloat(localStorage.getItem("bestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); + const modeLabel = this.add.bitmapText(cx, barAreaY - 40, "bigFont", "Normal Mode", 30) + .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); + barObjs.push(modeLabel); + cardContainer.add(modeLabel); + const barBg = this.add.graphics().setScrollFactor(0).setDepth(154); + barBg.fillStyle(0x000000, 0.6); + barBg.fillRoundedRect(barX0, barAreaY - barH2 / 2, barW2, barH2, barH2 / 2); + barObjs.push(barBg); + cardContainer.add(barBg); + const padding = 3; + const innerH2 = barH2 - padding * 2; + const innerW2 = barW2 - padding * 2; + const innerRadius = innerH2 / 2; + const fillW = Math.max(innerH2, innerW2 * bestNormal / 100); + if(bestNormal > 0) { + const barFg = this.add.graphics().setScrollFactor(0).setDepth(155); + barFg.fillStyle(0x00FF00, 1); + const rightR = (bestNormal >= 100) ? innerRadius : 0; + barFg.fillRoundedRect(barX0 + padding, barAreaY - barH2 / 2 + padding, fillW, innerH2, { + tl: innerRadius, + bl: innerRadius, + tr: rightR, + br: rightR + }); + + barObjs.push(barFg); + cardContainer.add(barFg); + } + const pctLabel = this.add.bitmapText(cx, barAreaY, "bigFont", Math.round(bestNormal) + "%", 22) + .setScrollFactor(0).setDepth(156).setOrigin(0.5, 0.5); + barObjs.push(pctLabel); + cardContainer.add(pctLabel); + const bestPractice = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); + const practBarAreaY = barAreaY + barH2 + 48; + const practModeLabel = this.add.bitmapText(cx, practBarAreaY - 40, "bigFont", "Practice Mode", 30) + .setScrollFactor(0).setDepth(155).setOrigin(0.5, 0.5); + barObjs.push(practModeLabel); + cardContainer.add(practModeLabel); + const practBarBg = this.add.graphics().setScrollFactor(0).setDepth(154); + practBarBg.fillStyle(0x000000, 0.6); + practBarBg.fillRoundedRect(barX0, practBarAreaY - barH2 / 2, barW2, barH2, barH2 / 2); + barObjs.push(practBarBg); + cardContainer.add(practBarBg); + if (bestPractice > 0) { + const practFillW = Math.max(innerH2, innerW2 * bestPractice / 100); + const practBarFg = this.add.graphics().setScrollFactor(0).setDepth(155); + practBarFg.fillStyle(0x00FFFF, 1); + const practRightR = (bestPractice >= 100) ? innerRadius : 0; + practBarFg.fillRoundedRect(barX0 + padding, practBarAreaY - barH2 / 2 + padding, practFillW, innerH2, { + tl: innerRadius, bl: innerRadius, tr: practRightR, br: practRightR + }); + barObjs.push(practBarFg); + cardContainer.add(practBarFg); + } + const practPctLabel = this.add.bitmapText(cx, practBarAreaY, "bigFont", Math.round(bestPractice) + "%", 22) + .setScrollFactor(0).setDepth(156).setOrigin(0.5, 0.5); + barObjs.push(practPctLabel); + cardContainer.add(practPctLabel); + }; + buildCardContent(); + buildBar(); + let _currentAnimUpdate = null; + const switchLevel = (dir, startX = null, dragVel = 0) => { + if (pageCount <= 0) return; + + if (_currentAnimUpdate) { + this.events.off("preupdate", _currentAnimUpdate); + _currentAnimUpdate = null; + } + currentPageIndex = (currentPageIndex + dir + pageCount) % pageCount; + applyCurrentPage(); + const pageLevel = getPageLevel(); + const newColors = this._parseLevelColors(pageLevel[2]); + const dark = isEveryEnd(pageLevel[2]); + const slideDist = cardW - 200; + const slideOutTarget = -dir * slideDist; + const slideInStart = dir * slideDist; + this.tweens.killTweensOf(cardContainer); + let state = "out"; + let currentX = startX !== null ? startX : cardContainer.x; + const dragSpeedBoost = Math.abs(dragVel) * 60; + const slideOutSpeed = slideDist * 14 + dragSpeedBoost; + const slideInVel = slideDist * 6 + dragSpeedBoost; + let vel = 0; + const scrollAnimUpdate = (time, delta) => { + const dt = Math.min(delta / 1000, 0.05); + if (state === "out") { + currentX += (-dir) * slideOutSpeed * dt; + if ((dir > 0 && currentX <= slideOutTarget) || (dir < 0 && currentX >= slideOutTarget)) { + for (const o of cardContentObjs) { + cardBounceContainer.remove(o, false); + o.destroy(); + } + for (const o of barObjs) { + cardSlideContainer.remove(o, false); + o.destroy(); + } + cardContentObjs.length = 0; + barObjs.length = 0; + drawCardBg(newColors.bgHex, dark, isComingSoonPage()); + buildCardContent(); + buildBar(); + drawOverlay(overlay, newColors.bgHex, dark); + for (const gt of staticGroundTiles) gt.setTint(groundTintHex(newColors.groundHex)); + for (const gt of staticGround2Tiles) gt.setTint(groundTintHex(newColors.groundHex)); + refreshDots(); + state = "in"; + currentX = slideInStart; + vel = (-dir) * slideInVel; + } + } else if (state === "in") { + const tension = 300; + const friction = 15; + const force = -tension * currentX - friction * vel; + vel += force * dt; + currentX += vel * dt; + + if (Math.abs(currentX) < 1 && Math.abs(vel) < 15) { + currentX = 0; + this.events.off("preupdate", scrollAnimUpdate); + if (_currentAnimUpdate === scrollAnimUpdate) _currentAnimUpdate = null; + } + } + cardContainer.x = currentX; + }; + _currentAnimUpdate = scrollAnimUpdate; + this.events.on("preupdate", scrollAnimUpdate); + }; + this._makeBouncyButton(arrowL, 1.1, () => { switchLevel(-1); }); + this._makeBouncyButton(arrowR, 1.1, () => { switchLevel(1); }); + const inputBlocker = this.add.zone(cx, cy, sw, sh) + .setScrollFactor(0).setDepth(151).setInteractive(); + inputBlocker.on("pointerdown", onDragStart); + this._levelSelectStaticObjs = [overlay, inputBlocker, tableBottom, ...staticGroundTiles, ...staticGround2Tiles, staticFloorLine, cornerBL, cornerBR, backBtn, infoBtn, arrowL, arrowR, cardSlideContainer, cardHit]; + this._levelSelectSwitchLevel = switchLevel; + this._levelSelectDotObjs = dotObjs; + this._levelSelectCardContent = cardContentObjs; + this._levelSelectBarObjs = barObjs; + } + _closeLevelSelect(silent = false) { + if (!this._levelSelectOverlay) return; + const destroy = () => { + const all = [ + ...(this._levelSelectStaticObjs || []), + ...(this._levelSelectDotObjs || []), + ...(this._levelSelectCardContent || []), + ...(this._levelSelectBarObjs || []), + ]; + for (const o of all) { if (o && o.destroy) { this.tweens.killTweensOf(o); o.destroy(); } } + this._levelSelectOverlay = null; + this._levelSelectStaticObjs = null; + this._levelSelectDotObjs = null; + this._levelSelectCardContent = null; + this._levelSelectBarObjs = null; + this._levelSelectSwitchLevel = null; + this._levelSelectIsComingSoonPage = false; + }; + if (silent) { destroy(); return; } + const sw = screenWidth; + const sh = screenHeight; + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(200).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ + targets: fadeOut, alpha: 1, duration: 150, ease: "Linear", + onComplete: () => { + destroy(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 150, ease: "Linear", onComplete: () => fadeOut.destroy() }); + } + }); + } + _buildHUD() { + this._attemptsLabel = this.add.bitmapText(0, 0, "bigFont", "Attempt 1", 65).setOrigin(0.5, 0.5).setVisible(false); + this._level.topContainer.add(this._attemptsLabel); + this._positionAttemptsLabel(); + this._checkpointBtnContainer = this.add.container(screenWidth / 2, screenHeight - 60) + .setScrollFactor(0) + .setDepth(30) + .setVisible(false); + this._checkpointBtn = this.add.image(-50, 0, "GJ_GameSheet03", "GJ_checkpointBtn_001.png") + .setOrigin(0.5, 0.5) + .setInteractive() + .setScale(0.8); + this._makeBouncyButton(this._checkpointBtn, 0.8, () => { + if (this._practicedMode.practiceMode && !this._menuActive && !this._slideIn) { + this._practicedMode.saveCheckpoint(this._state, this._playerWorldX, this._cameraX, this); + } + }); + this._expandHitArea(this._checkpointBtn, 2); + this._clearCheckpointBtn = this.add.image(50, 0, "GJ_GameSheet03", "GJ_removeCheckBtn_001.png") + .setOrigin(0.5, 0.5) + .setInteractive() + .setScale(0.8); + this._makeBouncyButton(this._clearCheckpointBtn, 0.8, () => { + if (this._practicedMode.practiceMode && !this._menuActive && !this._slideIn) { + this._practicedMode.deleteLastCheckpoint(); + } + }); + this._expandHitArea(this._clearCheckpointBtn, 1.5); + this._checkpointBtnContainer.add([this._checkpointBtn, this._clearCheckpointBtn]); + this._fpsText = this.add.text(screenWidth - 20, 10, "", { + fontSize: "28px", + fill: "#ffffff", + fontFamily: "Arial" + }).setOrigin(1, 0).setScrollFactor(0).setDepth(999).setVisible(false); + this._fpsAccum = 0; + this._fpsFrames = 0; + } + _createStartPosGui() { + const centerX = screenWidth / 2; + const bottomY = screenHeight - 60; + + this._startPosGui = this.add.container(centerX, bottomY).setScrollFactor(0).setDepth(100); + this._startPosGui.setVisible(false); + + const leftArrow = this.add.image(-90, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScale(0.6) + .setInteractive(); + + const rightArrow = this.add.image(90, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScale(0.6) + .setFlipX(true) + .setInteractive(); + + const positions = this._level.getStartPositions(); + const total = positions.length; + + this._startPosText = this.add.bitmapText(0, 0, "bigFont", `0/${total}`, 40).setOrigin(0.5); + + this._startPosGui.add([leftArrow, rightArrow, this._startPosText]); + + this._makeBouncyButton(leftArrow, 0.6, () => this.changeStartPos(-1)); + this._makeBouncyButton(rightArrow, 0.6, () => this.changeStartPos(1)); + } + changeStartPos(direction) { + if (this._paused || this._levelWon || this._menuActive || this._slideIn) return; + + const positions = this._level.getStartPositions(); + const totalPositions = positions.length; + + if (totalPositions === 0) return; + + this._startPosIndex += direction; + + if (this._startPosIndex < -1) { + this._startPosIndex = totalPositions - 1; + } else if (this._startPosIndex >= totalPositions) { + this._startPosIndex = -1; + } + + if (this._startPosText) { + const currentId = this._startPosIndex === -1 ? 0 : (this._startPosIndex + 1); + this._startPosText.setText(`${currentId}/${totalPositions}`); + } + + this._practicedMode.clearCheckpoints(); + this._restartLevel(); + } + toggleGlitter(_0x34c21a) { + if (this._editorPlaytestActive) { + this._glitterEmitter.stop(); + return; + } + + if (_0x34c21a) { + this._glitterEmitter.start(); + } else { + this._glitterEmitter.stop(); + } + } + _setParticleTimeScale(timeScale) { + const updateTimeScale = object => { + if (object && object.type === "ParticleEmitter") { + object.timeScale = timeScale; + } + if (object && object.list) { + object.list.forEach(updateTimeScale); + } + }; + updateTimeScale(this._level.container); + updateTimeScale(this._level.topContainer); + if (this._glitterEmitter) { + this._glitterEmitter.timeScale = timeScale; + } + } + _pauseGame() { + if (!this._paused && !this._menuActive && !this._slideIn && !this._levelWon) { + this._paused = true; + this._pauseBtn.setVisible(false); + this._audio.pauseMusic(); + this._setParticleTimeScale(0); + this._player?.setDeathAnimationPaused?.(true); + this._player2?.setDeathAnimationPaused?.(true); + this._buildPauseOverlay(); + } + } + _resumeGame() { + if (this._paused) { + this._setParticleTimeScale(1); + this._player?.setDeathAnimationPaused?.(false); + this._player2?.setDeathAnimationPaused?.(false); + this._paused = false; + this._pauseBtn.setVisible(true).setAlpha(75 / 255); + if (!this._state.isDead || this._practicedMode?.practiceMode) { + this._audio.resumeMusic(); + this._audio._ensureCorrectMusicMode(); + } + if (this._pauseContainer) { + this._pauseContainer.destroy(); + this._pauseContainer = null; + } + } + } + _queueGameplayLevelViewReturn() { + const currentLevelId = window.currentlevel?.[2] ?? window._onlineLevelId ?? null; + const pendingCreatedReturn = window._createdLevelReturnToView || null; + const candidateCreatedIds = [ + pendingCreatedReturn?.createdId, + currentLevelId, + window._onlineLevelId + ].filter(value => value !== undefined && value !== null); + + let createdLevel = null; + try { + const createdLevels = JSON.parse(localStorage.getItem("created_levels") || "[]"); + createdLevel = createdLevels.find(level => { + if (!level) return false; + return candidateCreatedIds.some(id => + String(level.createdId) === String(id) || + (level.levelId !== undefined && level.levelId !== null && String(level.levelId) === String(id)) + ); + }) || null; + } catch (err) { + console.warn("Failed to determine the created-level return target", err); + } + + if (createdLevel || pendingCreatedReturn?.snapshot) { + const targetLevel = createdLevel || pendingCreatedReturn.snapshot; + window._createdLevelReturnToView = { + createdId: targetLevel.createdId ?? pendingCreatedReturn?.createdId ?? currentLevelId, + snapshot: { ...targetLevel } + }; + window._editorReturnToLevelViewId = null; + window._onlineReturnToPlayMenu = null; + return true; + } + + const levelSource = window.currentlevel?.[3]?.[0]; + const isOnlineLevel = levelSource === "Online" || String(currentLevelId || "").startsWith("online_"); + if (isOnlineLevel) { + const existingReturn = window._onlineReturnToPlayMenu; + const selectedLevel = existingReturn?.lvl || window._selectedLevelData || null; + if (selectedLevel) { + window._onlineReturnToPlayMenu = { + lvl: selectedLevel, + backTarget: existingReturn?.backTarget || null + }; + window._createdLevelReturnToView = null; + window._editorReturnToLevelViewId = null; + return true; + } + } + + window._createdLevelReturnToView = null; + return false; + } + + _createPauseToggleButton(_0x5376fd, _0x3b6200, _0x2b25c8, _0xe203c3, _0x268e2b, _0x2d04c4) { + const _0x4864cc = this.add.container(_0x3b6200, _0x2b25c8); + const pieceHeight = this.add.image(0, 0, "GJ_GameSheet03", _0x268e2b ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png").setScale(0.7).setInteractive(); + const _0x15c0df = this.add.bitmapText(25 + 10, 0, "bigFont", _0xe203c3, 32).setOrigin(0, 0.5); + _0x4864cc.add([pieceHeight, _0x15c0df]); + _0x5376fd.add(_0x4864cc); + const _0x232e51 = _0x1dce15 => { + pieceHeight.setTexture("GJ_GameSheet03", _0x1dce15 ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"); + this._expandHitArea(pieceHeight, 2); + _0x2d04c4(_0x1dce15); + }; + this._expandHitArea(pieceHeight, 2); + this._makeBouncyButton(pieceHeight, 0.7, () => { + _0x232e51(pieceHeight.frame.name === "GJ_checkOff_001.png"); + }, () => this._paused && !!this._pauseContainer); + _0x15c0df.setInteractive(); + _0x15c0df.on("pointerdown", () => { + if (this._paused && this._pauseContainer) { + _0x232e51(pieceHeight.frame.name === "GJ_checkOff_001.png"); + } + }); + return _0x4864cc; + } +_buildPauseOverlay() { + const textureY = screenWidth / 2; + const _0xf70e04 = 320; + const _0x4eb71b = screenWidth - 40; + this._pauseContainer = this.add.container(0, 0).setScrollFactor(0).setDepth(100); + + const _0x505665 = this.add.rectangle(textureY, _0xf70e04, screenWidth, screenHeight, 0, 75 / 255); + _0x505665.setInteractive(); + this._pauseContainer.add(_0x505665); + + const _0x103191 = this.textures.get("square04_001").source[0].width * 0.325; + const _0x954813 = this._drawScale9(textureY, _0xf70e04, _0x4eb71b, 600, "square04_001", _0x103191, 0, 150 / 255); + this._pauseContainer.add(_0x954813); + + const _0x3874ed = this.scale.isFullscreen; + const _0x426993 = this.add.image(textureY - _0x4eb71b / 2 + 40, 60, "GJ_WebSheet", _0x3874ed ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png").setScale(0.64).setInteractive(); + this._expandHitArea(_0x426993, 2.5); + this._pauseContainer.add(_0x426993); + this._makeBouncyButton(_0x426993, 0.64, () => { + const _0x23c9e5 = !this.scale.isFullscreen; + _0x426993.setTexture("GJ_WebSheet", _0x23c9e5 ? "toggleFullscreenOff_001.png" : "toggleFullscreenOn_001.png"); + this._expandHitArea(_0x426993, 2.5); + this._toggleFullscreen(); + }); + + const settingsBtn = this.add.image(textureY + _0x4eb71b / 2 - 60, 80, 'GJ_GameSheet03', "GJ_optionsBtn_001.png").setScale(0.64).setInteractive(); + this._expandHitArea(settingsBtn, 2.5); + this._pauseContainer.add(settingsBtn); + this._makeBouncyButton(settingsBtn, 0.64, () => this._buildSettingsPopup()); + + this._macroBtn = this.add.image(textureY + _0x4eb71b / 2 - 60, 150, "macroBot").setScale(0.4).setInteractive(); + this._pauseContainer.add(this._macroBtn); + this._makeBouncyButton(this._macroBtn, 0.4, () => this._buildMacroPopup()); + + this._pauseContainer.add(this.add.bitmapText(textureY, 65, "bigFont", window.currentlevel[1], 40).setOrigin(0.5, 0.5)); + + const _0x21dacf = 170; + const _0x46bab2 = this._bestPercent || 0; + const _0x38b8d1 = this.add.image(textureY, _0x21dacf, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0).setAlpha(125 / 255); + this._pauseContainer.add(_0x38b8d1); + const _0x1d49a9 = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); + const _0xb5ab6f = _0x1d49a9 ? _0x1d49a9.width : 680; + const _0x1e6502 = _0x1d49a9 ? _0x1d49a9.height : 40; + const _0x3782ca = Math.max(1, Math.floor(_0xb5ab6f * (_0x46bab2 / 100))); + const _0x3d0987 = this.add.image(0, 0, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(65280).setScale(0.992, 0.86).setOrigin(0, 0.5).setCrop(0, 0, _0x3782ca, _0x1e6502); + _0x3d0987.setPosition(textureY - _0xb5ab6f * 0.992 / 2, _0x21dacf); + this._pauseContainer.add(_0x3d0987); + this._pauseContainer.add(this.add.bitmapText(textureY, _0x21dacf, "bigFont", _0x46bab2 + "%", 30).setOrigin(0.5, 0.5).setScale(0.7)); + this._pauseContainer.add(this.add.bitmapText(textureY, 130, "bigFont", "Normal Mode", 30).setOrigin(0.5, 0.5).setScale(0.78)); + + const _pausePractPct = this._practiceBestPercent || 0; + const _pausePractBarY = 255; + const _pausePractBarImg = this.add.image(textureY, _pausePractBarY, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0).setAlpha(125 / 255); + this._pauseContainer.add(_pausePractBarImg); + const _pausePractFrame = this.textures.getFrame("GJ_WebSheet", "GJ_progressBar_001.png"); + const _pausePractBarW = _pausePractFrame ? _pausePractFrame.width : 680; + const _pausePractBarH = _pausePractFrame ? _pausePractFrame.height : 40; + const _pausePractFillW = Math.max(1, Math.floor(_pausePractBarW * (_pausePractPct / 100))); + const _pausePractFg = this.add.image(0, 0, "GJ_WebSheet", "GJ_progressBar_001.png").setTint(0x00FFFF).setScale(0.992, 0.86).setOrigin(0, 0.5).setCrop(0, 0, _pausePractFillW, _pausePractBarH); + _pausePractFg.setPosition(textureY - _pausePractBarW * 0.992 / 2, _pausePractBarY); + this._pauseContainer.add(_pausePractFg); + this._pauseContainer.add(this.add.bitmapText(textureY, _pausePractBarY, "bigFont", _pausePractPct + "%", 30).setOrigin(0.5, 0.5).setScale(0.7)); + this._pauseContainer.add(this.add.bitmapText(textureY, _pausePractBarY - 40, "bigFont", "Practice Mode", 30).setOrigin(0.5, 0.5).setScale(0.78)); + + const _0x4791ac = [ + { frame: this._practicedMode.practiceMode ? "GJ_normalBtn_001.png" : "GJ_practiceBtn_001.png", atlas: "GJ_GameSheet03", action: null }, + { frame: "GJ_playBtn2_001.png", atlas: "GJ_WebSheet", action: () => this._resumeGame() }, + { frame: "GJ_menuBtn_001.png", atlas: "GJ_WebSheet", action: () => { + this._audio.playEffect("quitSound_01"); + this._queueGameplayLevelViewReturn(); + this.game.registry.remove("autoStartGame"); + window.isEditor = false; + this._audio.stopMusic(); + this._resumeGame(); + this.scene.restart(); + }}, + { frame: "GJ_replayBtn_001.png", atlas: "GJ_WebSheet", action: () => { + this._resumeGame(); + this._restartLevel(); + }} + ]; + + const _0x25aa59 = _0x4791ac.map(btn => this.textures.getFrame(btn.atlas, btn.frame)?.width || 123); + let _0x599a9b = textureY - (_0x25aa59.reduce((a, b) => a + b, 0) + (_0x4791ac.length - 1) * 40) / 2; + + for (let i = 0; i < _0x4791ac.length; i++) { + const item = _0x4791ac[i]; + const width = _0x25aa59[i]; + const btn = this.add.image(_0x599a9b + width / 2, 390, item.atlas, item.frame).setInteractive(); + + if (item.action === null) { + this._pausePracticeBtn = btn; + this._makeBouncyButton(btn, 1, () => { + const isPracticeMode = this._practicedMode.togglePracticeMode(); + btn.setTexture("GJ_GameSheet03", isPracticeMode ? "GJ_normalBtn_001.png" : "GJ_practiceBtn_001.png"); + if (this._checkpointBtnContainer) this._checkpointBtnContainer.setVisible(isPracticeMode); + this._resumeGame(); + if (!isPracticeMode) { + this._practicedMode.clearCheckpoints(); + this._restartLevel(); + } + }); + } else { + this._makeBouncyButton(btn, 1, item.action); + } + this._pauseContainer.add(btn); + _0x599a9b += width + 40; + } + + const _0x1008ae = 530; + const _0x22b43a = 0.7; + const _0x41925a = this.textures.getFrame("GJ_WebSheet", "slidergroove.png"); + const _0x372782 = _0x41925a ? _0x41925a.width : 420; + + const createSlider = (posX, iconFrame, initialVal, setter) => { + this._pauseContainer.add(this.add.image(posX - 180 - 5, _0x1008ae, "GJ_WebSheet", iconFrame).setScale(1.2)); + const barMaxW = (_0x372782 - 8) * _0x22b43a; + const barStartX = posX - _0x372782 * _0x22b43a / 2 + 2.8; + const fillW = initialVal * barMaxW; + const fillBar = this.add.tileSprite(barStartX, _0x1008ae, fillW > 0 ? fillW : 1, 11.2, "sliderBar").setOrigin(0, 0.5); + this._pauseContainer.add(fillBar); + this._pauseContainer.add(this.add.image(posX, _0x1008ae, "GJ_WebSheet", "slidergroove.png").setScale(_0x22b43a)); + + const thumb = this.add.image(barStartX + fillW, _0x1008ae, "GJ_WebSheet", "sliderthumb.png").setScale(_0x22b43a).setInteractive({ draggable: true }); + this._pauseContainer.add(thumb); + thumb.on("drag", (p, dragX) => { + thumb.x = Math.max(barStartX, Math.min(barStartX + barMaxW, dragX)); + const pct = (thumb.x - barStartX) / barMaxW; + fillBar.width = Math.max(1, pct * barMaxW); + setter(pct < 0.03 ? 0 : pct); + }); + }; + + createSlider(textureY - 200, "gj_songIcon_001.png", this._audio.getUserMusicVolume(), v => this._audio.setUserMusicVolume(v)); + createSlider(textureY + 200, "GJ_sfxIcon_001.png", this._sfxVolume, v => { + this._sfxVolume = v; + localStorage.setItem("userSfxVol", v); + }); + } +_buildSettingsPopup() { + if (this._settingsPopup) return; + + const centerX = screenWidth / 2, + centerY = 320, + panelWidth = 800, + panelHeight = 550; + + this._settingsPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(250); + + const dim = this.add.rectangle(centerX, centerY, screenWidth, screenHeight, 0, 150 / 255).setInteractive(); + this._settingsPopup.add(dim); + + const innerContainer = this.add.container(centerX, centerY).setScale(0); + this._settingsPopup.add(innerContainer); + + const corner = 0.325 * this.textures.get("GJ_square01").source[0].width; + const panel = this._drawScale9(0, 0, panelWidth, panelHeight, 'GJ_square01', corner, 16777215, 1); + innerContainer.add(panel); + + const closeBtn = this.add.image(-(panelWidth / 2) + 10, -(panelHeight / 2) + 10, 'GJ_WebSheet', "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); + innerContainer.add(closeBtn); + this._makeBouncyButton(closeBtn, 0.8, () => { + this._settingsPopup.destroy(); + this._settingsPopup = null; + }); + + const pages = ["Gameplay", "Visual", "Advanced"]; + let currentPage = 0; + const pageTitle = this.add.bitmapText(0, -(panelHeight / 2) + 45, "bigFont", pages[currentPage], 40).setOrigin(0.5); + innerContainer.add(pageTitle); + const leftArrow = this.add.image(-(panelWidth / 2) - 130, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setFlipX(false).setInteractive(); + innerContainer.add(leftArrow); + const rightArrow = this.add.image((panelWidth / 2) + 130, 0, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setInteractive().setFlipX(true); + innerContainer.add(rightArrow); + const column1X = -200; + const column2X = 200; + const checkOffset = -120; + const textOffset = -70; + const spacingY = 70; + const startY = -150; + let pageContainer = this.add.container(0, 0); + innerContainer.add(pageContainer); + + const createToggle = (container, x, y, label, getVal, setVal, callback, fontSize, hasInfoBox, infoText) => { + if (fontSize === undefined) fontSize = 25; + if (hasInfoBox === undefined) hasInfoBox = false; + if (infoText === undefined) infoText = null; + + var isOn = getVal(); + var checkTexture = isOn ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; + var check = this.add.image(x + checkOffset, y, "GJ_GameSheet03", checkTexture).setScale(0.8).setInteractive(); + var txt = this.add.bitmapText(x + textOffset, y, "bigFont", label, fontSize).setOrigin(0, 0.5); + container.add([check, txt]); + + if (hasInfoBox) { + if (infoText) { + createInfoButton(container, x + checkOffset - 34, y - 30, infoText, 0.45); + } + } + + this._makeBouncyButton(check, 0.8, () => { + var current = getVal(); + setVal(!current); + var newTexture = getVal() ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; + check.setTexture("GJ_GameSheet03", newTexture); + if (callback) { + callback(getVal()); + } + if (this._saveSettings) { + this._saveSettings(); + } + }); + }; + + function TextToSay(key) { + var normalized = String(key).replace(/[^a-z0-9]/gi, "").toLowerCase(); + return String(key); + } + + var infotextstuffsiwannabedonewiththis = { + "Enable Portal Guide": "Enables extra indicators on portals.", + "Enable Orb Guide": "Enables extra indicators on orbs.", + "Practice Music Bypass": "Plays normal mode music in practice mode.", + "Show Percentage": "Shows the percentage you are at in a level.", + "Percentage Decimals": "Shows decimals in level progress.", + "Hitboxes on Death": "Shows hitboxes upon death in both normal and practice mode.", + }; + + const createInfoButton = (container, x, y, infoTextOrKey, scale) => { + var key = String(infoTextOrKey || ""); + var words = TextToSay(key); + var Infotext = null; + if (window.settingInfoText && window.settingInfoText[words]) { + Infotext = window.settingInfoText[words]; + } else if (infotextstuffsiwannabedonewiththis[words]) { + Infotext = infotextstuffsiwannabedonewiththis[words]; + } + var infoText = Infotext ? Infotext : key; + if (!infoText) { + return; + } + + var infoButton = this.add.image(x, y, "GJ_GameSheet03", "GJ_infoIcon_001.png"); + infoButton.setScale(scale || 0.45); + infoButton.setInteractive(); + container.add(infoButton); + + this._makeBouncyButton(infoButton, scale, () => { + this.InfoBoxDoAThing(infoText); + }); + }; + const createNumberInput = (container, x, y, label, getVal, setVal) => { + const txt = this.add.bitmapText(x + textOffset, y, "bigFont", label, 25).setOrigin(0, 0.5); + container.add(txt); + + const boxX = x + checkOffset; + const boxY = y; + const boxW = 64; + const boxH = 48; + + const bgBoxGraphics = this.add.graphics(); + bgBoxGraphics.fillStyle(0x222222, 0.5); + bgBoxGraphics.fillRoundedRect(boxX - boxW / 2, boxY - boxH / 2, boxW, boxH, 8); + container.add(bgBoxGraphics); + + const hitArea = this.add.rectangle(boxX, boxY, boxW, boxH, 0x000000, 0) + .setOrigin(0.5) + .setInteractive({ useHandCursor: true }); + container.add(hitArea); + + let initialVal = getVal() || 1; + const valueTxt = this.add.bitmapText(boxX, boxY, "bigFont", initialVal.toString(), 28) + .setOrigin(0.5); + container.add(valueTxt); + + let isFocused = false; + let internalString = initialVal.toString(); + + const updateDisplay = () => { + if (isFocused) { + valueTxt.setText(internalString + "|"); + } else { + valueTxt.setText(internalString || " "); + } + }; + + const commitValue = () => { + isFocused = false; + + let val = parseFloat(internalString); + if (isNaN(val)) val = 1; + + if (val < 0.1) val = 0.1; + if (val > 10) val = 10; + + internalString = val.toString(); + valueTxt.setText(internalString); + + setVal(val); + if (this._saveSettings) this._saveSettings(); + }; + + hitArea.on('pointerdown', (pointer, localX, localY, event) => { + if (event) event.stopPropagation(); + + if (window._activeCustomInput && window._activeCustomInput !== commitValue) { + window._activeCustomInput(); + } + + isFocused = true; + window._activeCustomInput = commitValue; + + internalString = ""; + updateDisplay(); + }); + + const outsideClickListener = () => { + if (isFocused) commitValue(); + }; + dim.on('pointerdown', outsideClickListener); + + const keydownListener = (event) => { + if (!isFocused) return; + + const key = event.key; + + if (key === "Enter") { + event.preventDefault(); + commitValue(); + return; + } + + if (key === "Backspace") { + event.preventDefault(); + internalString = internalString.slice(0, -1); + updateDisplay(); + return; + } + + if (/^[0-9.]$/.test(key)) { + event.preventDefault(); + + if (key === "." && internalString.includes(".")) return; + + const parts = internalString.split('.'); + + if (key === ".") { + if (parts[0].length === 0) return; + } else { + if (parts.length === 1 && parts[0].length >= 2) return; + if (parts.length === 2 && parts[1].length >= 2) return; + } + + internalString += key; + updateDisplay(); + } + }; + + window.addEventListener('keydown', keydownListener); + + const originalDestroy = container.destroy; + container.destroy = (...args) => { + window.removeEventListener('keydown', keydownListener); + if (dim) dim.off('pointerdown', outsideClickListener); + if (window._activeCustomInput === commitValue) { + window._activeCustomInput = null; + } + originalDestroy.apply(container, args); + }; + }; + + const buildGameplayPage = (container) => { + createToggle(container, column1X, startY, "Show Percentage", + () => window.showPercentage, + (v) => window.showPercentage = v, + (v) => { if (this._percentageLabel) this._percentageLabel.setVisible(v); }, + undefined, + true, + "Show Percentage" + ); + + createToggle(container, column1X, startY + spacingY, "Percentage Decimals", + () => window.percentageDecimals, + (v) => window.percentageDecimals = v, + undefined, + undefined, + true, + "Percentage Decimals" + ); + + createToggle(container, column1X, startY + (spacingY * 2), "StartPos Switcher", + () => window.startPosSwitcher, + (v) => window.startPosSwitcher = v, + (v) => { + if (!v) this._startPosIndex = -1; + if (this._startPosGui) this._startPosGui.setVisible(v); + const total = this._level.getStartPositions().length; + if (this._startPosText) this._startPosText.setText(`0/${total}`); + } + ); + + createToggle(container, column1X, startY + (spacingY * 3), "Noclip", + () => window.noClip, + (v) => window.noClip = v, + (v) => { if (this._noclipIndicator) this._noclipIndicator.setVisible(v); } + ); + + createToggle(container, column1X, startY + (spacingY * 4), "Noclip Accuracy", + () => window.noClipAccuracy, + (v) => window.noClipAccuracy = v + ); + + createToggle(container, column1X, startY + (spacingY * 5), "Macro Bot", + () => window.macroBot, + (v) => window.macroBot = v + ); + + createNumberInput(container, column2X, startY, "Speedhack", + () => window.speedHack, + (v) => window.speedHack = v + ); + + createToggle(container, column2X, startY + spacingY, "Practice Music Bypass", + () => window.practiceMusicBypass, + (v) => { + const changed = !!window.practiceMusicBypass !== !!v; + window.practiceMusicBypass = v; + if (changed && !this._menuActive && this._practicedMode?.practiceMode) { + this._practiceBypassPending = true; + } + }, + null, + 20, + true, + "Practice Music Bypass" + ); + }; + + const buildVisualPage = (container) => { + createToggle(container, column1X, startY, "Show Hitboxes", + () => window.showHitboxes, + (v) => window.showHitboxes = v, + (v) => { + if (!v) { + this._player._hitboxGraphics.clear(); + } else { + this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); + } + } + ); + + createToggle(container, column1X, startY + (spacingY), "Hitbox Trail", + () => window.showHitboxTrail, + (v) => window.showHitboxTrail = v, + (v) => { if (window.showHitboxes) this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); } + ); + + createToggle(container, column1X, startY + (spacingY * 2), "Hitboxes on Death", + () => window.hitboxesOnDeath, + (v) => window.hitboxesOnDeath = v, + undefined, + undefined, + true, + "Hitboxes on Death" + ); + + createToggle(container, column1X, startY + (spacingY * 3), "Show FPS", + () => this._fpsText.visible, + (v) => this._fpsText.visible = v, + (v) => { if (this._fpsText) this._fpsText.setVisible(v); } + ); + + createToggle(container, column1X, startY + (spacingY * 4), "Solid Wave Trail", + () => window.solidWave, + (v) => window.solidWave = v + ); + + createToggle(container, column1X, startY + (spacingY * 5), "Show CPS", + () => window.showCPS, + (v) => window.showCPS = v + ); + + createToggle(container, column2X, startY, "Show Glow", + () => window.showGlow, + (v) => window.showGlow = v, + () => { if (this._level && this._level._updateGlowVisibility) this._level._updateGlowVisibility(); } + ); + + createToggle(container, column2X, startY + spacingY, "Create Object ID labels", + () => window.createObjectIds, + (v) => window.createObjectIds = v, + null, 17 + ); + + createToggle(container, column2X, startY + (spacingY * 2), "Show Object ID labels", + () => window.showObjectIds, + (v) => window.showObjectIds = v, + null, 17 + ); + createToggle(container, column2X, startY + (spacingY * 3), "Enable Portal Guide", + () => window.enablePortalGuide, + (v) => window.enablePortalGuide = v, + null, 22, + true, + "Enable Portal Guide" + ); + createToggle(container, column2X, startY + (spacingY * 4), "Enable Orb Guide", + () => window.enableOrbGuide, + (v) => window.enableOrbGuide = v, + null, + 25, + true, + "Enable Orb Guide" + ); + }; + + const buildAdvancedPage = (container) => { + createToggle(container, column1X, startY, "Use Proxy (for schools)", + () => !window.useDirectInternet, + (v) => { window.useDirectInternet = !v; }, + null, 22 + ); + }; + + const buildPage = (idx) => { + pageContainer.destroy(); + pageContainer = this.add.container(0, 0); + innerContainer.add(pageContainer); + pageTitle.setText(pages[idx]); + + if (idx === 0) buildGameplayPage(pageContainer); + else if (idx === 1) buildVisualPage(pageContainer); + else if (idx === 2) buildAdvancedPage(pageContainer); + }; + + buildPage(0); + + this._makeBouncyButton(leftArrow, 1, () => { + currentPage = (currentPage - 1 + pages.length) % pages.length; + buildPage(currentPage); + }); + + this._makeBouncyButton(rightArrow, 1, () => { + currentPage = (currentPage + 1) % pages.length; + buildPage(currentPage); + }); + this.tweens.add({ + targets: innerContainer, + scale: 1, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _saveSettings() { + const settings = { + noclip: window.noClip, + showPercentage: window.showPercentage, + percentDecimals: window.percentageDecimals, + showHitboxes: window.showHitboxes, + startPosSwitcher: window.startPosSwitcher, + hitboxTrail: window.showHitboxTrail, + showFPS: this._fpsText.visible, + solidWaveTrail: window.solidWave, + noclipAccuracy: window.noClipAccuracy, + hitboxesOnDeath: window.hitboxesOnDeath, + createObjectIds: window.createObjectIds, + showObjectIds: window.showObjectIds, + showCPS: window.showCPS, + speedHack: window.speedHack, + macroBot: window.macroBot, + practiceMusicBypass: window.practiceMusicBypass, + showGlow: window.showGlow, + showEditorGlow: window.showEditorGlow, + useDirectInternet: !!window.useDirectInternet, + enablePortalGuide: window.enablePortalGuide, + enableOrbGuide: window.enableOrbGuide, + settingInfoText: window.settingInfoText || {} + }; + localStorage.setItem("gd_settings", JSON.stringify(settings)); + localStorage.setItem("gd_useDirectInternet", String(!!window.useDirectInternet)); + } + _loadSettings() { + const saved = localStorage.getItem("gd_settings"); + const defaults = { + noclip: false, + showPercentage: true, + percentDecimals: false, + showHitboxes: false, + startPosSwitcher: false, + hitboxTrail: false, + showFPS: false, + solidWaveTrail: false, + noclipAccuracy: false, + hitboxesOnDeath: false, + createObjectIds: false, + showObjectIds: false, + showCPS: false, + speedHack: 1.0, + macroBot: false, + practiceMusicBypass: false, + showGlow: true, + showEditorGlow: false, + useDirectInternet: true, + enablePortalGuide: true, + enableOrbGuide: false + }; + + const data = { ...defaults, ...(saved ? JSON.parse(saved) : {}) }; + + window.noClip = data.noclip; + window.showPercentage = data.showPercentage; + window.percentageDecimals = data.percentDecimals; + window.showHitboxes = data.showHitboxes; + window.startPosSwitcher = data.startPosSwitcher; + window.showHitboxTrail = data.hitboxTrail; + this._fpsText.visible = data.showFPS; + window.solidWave = data.solidWaveTrail; + window.noClipAccuracy = data.noclipAccuracy; + window.hitboxesOnDeath = data.hitboxesOnDeath; + window.showCPS = data.showCPS; + window.speedHack = data.speedHack; + window.macroBot = data.macroBot; + window.practiceMusicBypass = !!data.practiceMusicBypass; + window.showGlow = data.showGlow; + window.showEditorGlow = data.showEditorGlow; + window.createObjectIds = data.createObjectIds; + window.showObjectIds = data.showObjectIds; + window.enablePortalGuide = data.enablePortalGuide; + window.enableOrbGuide = data.enableOrbGuide; + window.settingInfoText = data.settingInfoText || {}; + window.useDirectInternet = !!data.useDirectInternet; + localStorage.setItem("gd_useDirectInternet", String(!!window.useDirectInternet)); + } + _buildMacroPopup() { + if (this._macroPopup) return; + const centerX = screenWidth / 2; + const centerY = 320; + const panelWidth = 800; + const panelHeight = 400; + this._macroPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(250); + const dim = this.add.rectangle(centerX, centerY, screenWidth, screenHeight, 0x000000, 150 / 255).setInteractive(); + this._macroPopup.add(dim); + + const corner = 0.325 * this.textures.get("GJ_square02").source[0].width; + const panel = this._drawScale9(centerX, centerY, panelWidth, panelHeight, "GJ_square02", corner, 0xffffff, 1); + this._macroPopup.add(panel); + + this._macroPopup.add(this.add.bitmapText(centerX, centerY - (panelHeight / 2) + 45, "bigFont", "Web Bot v1.0", 40).setOrigin(0.5)); + + if (this._macroName === undefined) { + this._macroName = this._macroBot?.meta?.name || null; + } + if (this._macroLoaded === undefined) { + this._macroLoaded = !!this._macroName || (this._macroBot && this._macroBot.inputs && this._macroBot.inputs.length > 0); + } + + const loadedNameText = this.add.bitmapText(centerX, centerY - (panelHeight / 2) + 95, "goldFont", this._macroLoaded ? `Currently loaded "${this._macroName || 'macro'}"` : "No macro loaded", 24).setOrigin(0.5); + this._macroPopup.add(loadedNameText); + + const optionsBtn = this.add.image(centerX, centerY - (panelHeight / 2) + 95, "GJ_GameSheet03", "GJ_optionsBtn02_001.png").setInteractive().setScale(0.45); + this._macroPopup.add(optionsBtn); + + const closeBtn = this.add.image(centerX - (panelWidth / 2) + 20, centerY - (panelHeight / 2) + 20, "GJ_WebSheet", "GJ_closeBtn_001.png").setInteractive().setScale(0.8); + this._macroPopup.add(closeBtn); + + this._makeBouncyButton(closeBtn, 0.8, () => { + this.events.off("update", this._refreshMacroButtons); + this._macroPopup.destroy(); + this._macroPopup = null; + }); + + const importBtn = this.add.image(centerX - 300, centerY + 20,"importMacro").setInteractive(); + const exportBtn = this.add.image(centerX - 150, centerY + 20, "GJ_GameSheet03", "GJ_shareBtn_001.png").setInteractive().setFlipY(true).setAngle(90).setScale(0.53); + const createBtn = this.add.image(centerX, centerY + 20, "GJ_GameSheet03", "GJ_plusBtn_001.png").setInteractive().setFlipY(true).setAngle(90).setScale(1.2); + const playbackBtn = this.add.image(centerX + 150, centerY + 20, this._macroBot?.playing ? "stopPlayback" : "playbackMacro").setInteractive().setScale(0.25); + const recordBtn = this.add.image(centerX + 300, centerY + 20, this._macroBot?.recording ? "stopRecord" : "recordMacro").setInteractive().setScale(0.25); + + this._macroPopup.add([createBtn, importBtn, exportBtn, playbackBtn, recordBtn]); + + this._refreshMacroButtons = () => { + const playing = !!this._macroBot?.playing; + const recording = !!this._macroBot?.recording; + + let currentMetaName = this._macroBot?.meta?.name; + if (currentMetaName && currentMetaName !== this._macroName) { + this._macroName = currentMetaName; + this._macroLoaded = true; + } + + if (this._macroLoaded) { + loadedNameText.setText(`Currently loaded "${this._macroName || 'macro'}"`); + optionsBtn.setAlpha(1).setActive(true); + optionsBtn.x = centerX + (loadedNameText.width / 2) + 25; + } else { + loadedNameText.setText("No macro loaded"); + optionsBtn.setAlpha(0).setActive(false); + } + + playbackBtn.setTexture( + playing + ? "stopPlayback" + : "playbackMacro" + ); + + recordBtn.setTexture( + recording + ? "stopRecord" + : "recordMacro" + ); + + createBtn.setAlpha((playing || recording || this._macroLoaded) ? 0.5 : 1); + importBtn.setAlpha((playing || recording) ? 0.5 : 1); + exportBtn.setAlpha((playing || recording || !this._macroLoaded) ? 0.5 : 1); + playbackBtn.setAlpha((recording || !this._macroLoaded) ? 0.5 : 1); + recordBtn.setAlpha((playing || !this._macroLoaded) ? 0.5 : 1); + }; + + this._refreshMacroButtons(); + + this._makeBouncyButton(optionsBtn, 0.45, () => { + if (!this._macroLoaded) return; + const renamePrompt = prompt("New name", this._macroName); + if (renamePrompt && renamePrompt.trim() !== "") { + const cleanName = renamePrompt.trim(); + if (!this._macroBot) this._initMacroBot(); + + if (!this._macroBot.meta) { + this._macroBot.meta = {}; + } + this._macroBot.meta.name = cleanName; + this._macroName = cleanName; + this._refreshMacroButtons(); + } + }); + + this._makeBouncyButton(importBtn, 1, () => { + if (this._macroBot?.playing) return; + if (this._macroBot?.recording) return; + this._importMacroFile(); + }); + + this._makeBouncyButton(exportBtn, 0.53, () => { + if (this._macroBot?.playing) return; + if (this._macroBot?.recording) return; + if (!this._macroLoaded) return; + this._exportMacroFile(this._macroName ? `${this._macroName}.wbgdr` : null); + }); + + this._makeBouncyButton(createBtn, 1.2, () => { + if (this._macroBot?.playing || this._macroBot?.recording || this._macroLoaded) return; + const name = prompt("Enter macro name"); + if (name) { + if (!this._macroBot) this._initMacroBot(); + this._macroBot.resetAll(); + this._macroBot.meta.name = name; + this._macroName = name; + this._macroLoaded = true; + this._refreshMacroButtons(); + } + }); + + this._makeBouncyButton(playbackBtn, 0.25, () => { + if (this._macroBot?.recording) return; + if (!this._macroLoaded) return; + + if (this._macroBot?.playing) { + this._stopMacroPlayback(); + } else { + if (!this._macroBot) { + return; + } + const macro = this._macroBot.exportObject(); + this._startMacroPlayback(macro); + } + this._refreshMacroButtons(); + }); + + this._makeBouncyButton(recordBtn, 0.25, () => { + if (this._macroBot?.playing) return; + if (!this._macroLoaded) return; + + if (this._macroBot?.recording) { + this._stopMacroRecording(); + } else { + this._startMacroRecording({ + level: window.currentlevel?.[2] || "", + name: this._macroName + }); + } + + this._refreshMacroButtons(); + }); + + this.events.on("update", this._refreshMacroButtons); + } + _buildInfoPopup() { + if (this._infoPopup) { + return; + } + const xPos = screenWidth / 2; + const popupHeight = 320; + const popupWidth = 336; + this._infoPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + const background = this.add.rectangle(xPos, popupHeight, screenWidth, screenHeight, 0, 100 / 255); + background.setInteractive(); + this._infoPopup.add(background); + + const bounceContainer = this.add.container(xPos, popupHeight).setScale(0); + this._infoPopup.add(bounceContainer); + const cornerRadius = this.textures.get("GJ_square02").source[0].width * 0.325; + const popupBg = this._drawScale9(0, 0, 480, popupWidth, "GJ_square02", cornerRadius, 16777215, 1); + bounceContainer.add(popupBg); + const closeBtn = this.add.image(-240 + 20, -148, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); + bounceContainer.add(closeBtn); + this._expandHitArea(closeBtn, 2); + this._makeBouncyButton(closeBtn, 0.8, () => this._closeInfoPopup()); + const title = this.add.bitmapText(0, -124, "bigFont", "Credits", 30).setOrigin(0.5, 0.5); + bounceContainer.add(title); + const scrollAreaW = 420; + const scrollAreaH = 230; + const scrollAreaX = 0; + const scrollAreaY = 20; + const scrollFrameBg = this.add.graphics(); + scrollFrameBg.fillStyle(0x000000, 0.18); + scrollFrameBg.fillRoundedRect(scrollAreaX - scrollAreaW / 2, scrollAreaY - scrollAreaH / 2, scrollAreaW, scrollAreaH, 8); + bounceContainer.add(scrollFrameBg); + const contentContainer = this.add.container(0, scrollAreaY - scrollAreaH / 2 + 8); + bounceContainer.add(contentContainer); + + const creditsEntries = [ + { text: "Made by RobTop Games", scale: 0.8, font: "goldFont" }, + { text: "Modded by:", scale: 0.9, font: "bigFont" }, + { text: "breadbb, PinkDev, rohanis0000,", scale: 0.7, font: "goldFont" }, + { text: "bog, Lasokar, AntiMatter,", scale: 0.7, font: "goldFont" }, + { text: "arbstro, and aloaf", scale: 0.7, font: "goldFont" }, + { text: "Contributors:", scale: 0.9, font: "bigFont" }, + { text: "t0nchi7, Itzar and CoraBitz", scale: 0.7, font: "goldFont" }, + { text: "© 2026 RobTop Games. All rights reserved.", scale: 0.4, font: "Arial", color: 0x000000 }, + ]; + let yPos = 0; + const lineItems = []; + creditsEntries.forEach(entry => { + let txt; + if (entry.font === "Arial") { + txt = this.add.text(0, yPos, entry.text, { + fontSize: `${Math.round(32 * (entry.scale || 0.65))}px`, + fontFamily: "Arial", + color: entry.color ? `#${entry.color.toString(16).padStart(6, '0')}` : "#ffffff" + }).setOrigin(0.5, 0); + } else { + txt = this.add.bitmapText(0, yPos, entry.font || "bigFont", entry.text, 32) + .setOrigin(0.5, 0) + .setScale(entry.scale || 0.65); + if (entry.color != null) txt.setTint(entry.color); + } + contentContainer.add(txt); + lineItems.push(txt); + yPos += Math.round(32 * (entry.scale || 0.65)) + 10; + }); + const totalContentH = yPos; + const maxScrollDown = Math.max(0, totalContentH - scrollAreaH + 16); + const maskGraphics = this.add.graphics(); + const maskShape = this.add.graphics(); + maskShape.fillStyle(0xffffff, 1); + const updateMask = () => { + if (!bounceContainer || !bounceContainer.active) return; + const wx = xPos + bounceContainer.x - xPos; + const s = bounceContainer.scaleX; + const bwx = xPos; + const bwy = popupHeight; + maskShape.clear(); + maskShape.fillStyle(0xffffff, 1); + maskShape.fillRect( + bwx + (scrollAreaX - scrollAreaW / 2) * s, + bwy + (scrollAreaY - scrollAreaH / 2) * s, + scrollAreaW * s, + scrollAreaH * s + ); + }; + const geomMask = maskShape.createGeometryMask(); + contentContainer.setMask(geomMask); + const maskUpdateEvent = this.events.on('postupdate', updateMask); + let scrollY = 0; + const baseContentY = scrollAreaY - scrollAreaH / 2 + 8; + const applyScroll = () => { + contentContainer.y = baseContentY - scrollY; + }; + applyScroll(); + const scrollZone = this.add.zone(scrollAreaX, scrollAreaY, scrollAreaW, scrollAreaH).setInteractive(); + bounceContainer.add(scrollZone); + scrollZone.on('wheel', (_p, _dx, deltaY) => { + scrollY = Phaser.Math.Clamp(scrollY + deltaY * 0.6, 0, maxScrollDown); + applyScroll(); + }); + + let dragStartY = 0; + let dragStartScroll = 0; + scrollZone.on('pointerdown', (pointer) => { + dragStartY = pointer.y; + dragStartScroll = scrollY; + }); + scrollZone.on('pointermove', (pointer) => { + if (pointer.isDown) { + const dy = dragStartY - pointer.y; + scrollY = Phaser.Math.Clamp(dragStartScroll + dy, 0, maxScrollDown); + applyScroll(); + } + }); + this._infoPopupCleanup = () => { + this.events.off('postupdate', updateMask); + maskShape.destroy(); + geomMask.destroy(); + }; + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + this._infoPopupCleanup = () => { + this.events.off('postupdate', updateMask); + maskShape.destroy(); + geomMask.destroy(); + }; + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeInfoPopup() { + if (this._infoPopup) { + if (this._infoPopupCleanup) { + this._infoPopupCleanup(); + this._infoPopupCleanup = null; + } + this._infoPopup.destroy(); + this._infoPopup = null; + } + this._infogoaway = () => { + this.events.off('postupdate', updateMask); + maskShape.destroy(); + geomMask.destroy(); + }; + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeInfoPopup() { + if (this._infoPopup) { + if (this._infogoaway) { + this._infogoaway(); + this._infogoaway = null; + } + this._infoPopup.destroy(); + this._infoPopup = null; + } + } //im so tired of this + InfoBoxDoAThing(displayText) { + if (this.EditInfoText) { + this.InfoBoxStopAThing(); + } + + const xPos = screenWidth / 2; + const centerY = screenHeight / 2; + this.EditInfoText = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + + const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 0.5).setInteractive(); + this.EditInfoText.add(background); + + const box = this.add.container(xPos, centerY).setScale(0); + this.EditInfoText.add(box); + + const cornerRadius = this.textures.get("GJ_square01").source[0].width * 0.325; + const boxWidth = 720; + const boxHeight = 280; + box.add(this._drawScale9(0, 0, boxWidth, boxHeight, "square01_001", cornerRadius, 0xffffff, 1)); + box.add(this.add.bitmapText(0, -90, "goldFont", "Info", 45).setOrigin(0.5)); + + const textAreaW = boxWidth - 60; + const textAreaH = boxHeight - 140; + + const wrapText = (text, maxChars) => { + const words = String(text).split(" "); + const lines = []; + let line = ""; + for (let i = 0; i < words.length; i++) { + const word = words[i]; + if ((line + (line ? " " : "") + word).length <= maxChars) { + line = line ? `${line} ${word}` : word; + } else { + if (line) lines.push(line); + line = word; + } + } + if (line) lines.push(line); + return lines; + }; + + const infoText = String(displayText || ""); + const wrappedText = wrapText(infoText, 40); + let y = -30; + + wrappedText.forEach(line => { + box.add(this.add.text(0, y, line, { + fontFamily: "Arial", + fontSize: "30px", + color: "#ffffff", + align: "center" + }).setOrigin(0.5, 0)); + y += 32; + }); + + const okBtnBg = this._drawScale9(0, 0, 100, 60, "GJ_button01", this.textures.get("GJ_button01").source[0].width * 0.3, 0xffffff, 1); + const okBtn = this.add.rectangle(0, 0, 100, 60).setInteractive(); + const okLabel = this.add.bitmapText(0, 0, "goldFont", "OK", 48).setOrigin(0.55); + const okGroup = this.add.container(0, boxHeight / 2 - 50, [okBtnBg, okBtn, okLabel]); + okBtn._bouncyVisualTarget = okGroup; + box.add(okGroup); + + this._makeBouncyButton(okBtn, 1.0, () => { + this.InfoBoxStopAThing(); + }); + + this.tweens.add({ + targets: box, + scale: { from: 0, to: 1 }, + duration: 280, + ease: "Back.Out" + }); + } + + InfoBoxStopAThing() { + if (!this.EditInfoText) return; + + if (this._infoEscKey) { + this._infoEscKey.off('down', this._infoEscHandler); + this._infoEscKey.destroy(); + this._infoEscKey = null; + this._infoEscHandler = null; + } + + this.EditInfoText.destroy(); + this.EditInfoText = null; + } + _buildHowToPlayPopup() { + if (this._howToPlayPopup) { + return; + } + const TUTORIAL_PAGES = ["tutorial_01", "tutorial_02", "tutorial_03", "tutorial_04", "tutorial_05"]; + const GREEN = 0x00e719; + const YELLOW = 0xf8ff00; + const BLUE = 0x3cadf5; + const TUTORIAL_DESCRIPTIONS = [ + { fontSize: 40, lines: [ + [{ text: "TAP", color: GREEN }, { text: " the screen to jump." }], + [{ text: "HOLD", color: GREEN }, { text: " down to keep jumping." }] + ]}, + { fontSize: 40, lines: [ + [{ text: "Hold", color: GREEN }, { text: " to fly up." }], + [{ text: "Release", color: GREEN }, { text: " to fly down." }] + ]}, + { fontSize: 35, lines: [ + [{ text: "You can enter " }, { text: "practice mode", color: BLUE }, { text: " from" }], + [{ text: "the pause menu." }], + [{ text: "Practice mode lets you place" }], + [{ text: "checkpoints", color: GREEN }, { text: "." }] + ]}, + { fontSize: 35, lines: [ + [{ text: "You can place checkpoints manually, or" }], + [{ text: "use the auto-checkpoints feature." }], + [{ text: "Tap the delete button to remove your" }], + [{ text: "last checkpoint." }] + ]}, + { fontSize: 35, lines: [ + [{ text: "Jump Orbs", color: YELLOW }, { text: " activate when you are on" }], + [{ text: "top of them." }], + [{ text: "TAP", color: GREEN }, { text: " while touching an orb to" }], + [{ text: "interact with it and use its effect." }] + ]} + ]; + const TOTAL_PAGES = TUTORIAL_PAGES.length; + let currentPage = 0; + + const xPos = screenWidth / 2; + const _0x4c3182 = 320; + this._howToPlayPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(300); + const _0x249eb7 = this.add.rectangle(xPos, _0x4c3182, screenWidth, screenHeight, 0, 100 / 255); + _0x249eb7.setInteractive(); + this._howToPlayPopup.add(_0x249eb7); + const _0x14e46f = this.textures.get("GJ_square01").source[0].width * 0.325; + const panelContainer = this.add.container(xPos, _0x4c3182); + this._howToPlayPopup.add(panelContainer); + const _0x2c64c2 = this._drawScale9(0, 0, 830, 530, "GJ_square01", _0x14e46f, 16777215, 1); + panelContainer.add(_0x2c64c2); + const _0x5a0f88 = this.add.image(-240 - 160, 172 - _0x4c3182 - 110, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); + this._expandHitArea(_0x5a0f88, 2); + this._makeBouncyButton(_0x5a0f88, 0.8, () => this._closeHowToPlayPopup()); + panelContainer.add(_0x5a0f88); + const howToPlayTitle = this.add.bitmapText(0, -210, "bigFont", "How To Play", 62).setOrigin(0.5, 0.5); + panelContainer.add(howToPlayTitle); + const DESC_TOP_Y = -195; + const DESC_BOT_Y = 15; + const DESC_MAX_H = DESC_BOT_Y - DESC_TOP_Y; + + let descLineObjects = []; + + const _buildDescLines = (pageIndex) => { + for (const obj of descLineObjects) obj.destroy(); + descLineObjects = []; + + const page = TUTORIAL_DESCRIPTIONS[pageIndex]; + if (!page || !page.lines.length) return; + + const fontSize = page.fontSize; + const lineSpacing = 0.35; + const lineH = fontSize * (1 + lineSpacing); + const startY = DESC_TOP_Y + fontSize / 0.5; + + for (let i = 0; i < page.lines.length; i++) { + const segments = page.lines[i]; + const lineY = startY + i * lineH; + if (segments.length === 1 && !segments[0].color) { + const obj = this.add.bitmapText(0, lineY, "bigFont", segments[0].text, fontSize) + .setOrigin(0.5, 0.5); + panelContainer.add(obj); + descLineObjects.push(obj); + continue; + } + const measured = segments.map(seg => { + const tmp = this.add.bitmapText(0, -9999, "bigFont", seg.text, fontSize); + const w = tmp.width; + tmp.destroy(); + return w; + }); + const totalW = measured.reduce((a, b) => a + b, 0); + let curX = -totalW / 2; + + for (let s = 0; s < segments.length; s++) { + const seg = segments[s]; + const obj = this.add.bitmapText(curX, lineY, "bigFont", seg.text, fontSize) + .setOrigin(0, 0.5); + if (seg.color) obj.setTint(seg.color); + panelContainer.add(obj); + descLineObjects.push(obj); + curX += measured[s]; + } + } + }; + + _buildDescLines(0); + const tutorialImage = this.add.image(-240 + 150, 155, TUTORIAL_PAGES[0]); + panelContainer.add(tutorialImage); + const nextGroup = this.add.container(-240 + 550, 165); + const nextBtnW = 125, nextBtnH = 80; + const nextBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; + const nextBtn9 = this._drawScale9(0, 0, nextBtnW, nextBtnH, "GJ_button01", nextBtnBorder, 0xffffff, 1); + const nextBtn = this.add.rectangle(0, 0, nextBtnW, nextBtnH).setInteractive(); + const nextLabel = this.add.bitmapText(-5, -2.5, "bigFont", "Next", 35).setOrigin(0.5, 0.5); + nextGroup.add(nextBtn9); + nextGroup.add(nextBtn); + nextGroup.add(nextLabel); + panelContainer.add(nextGroup); + + nextBtn.on("pointerdown", () => { + nextGroup._pressed = true; + this.tweens.killTweensOf(nextGroup); + this.tweens.add({ targets: nextGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); + }); + nextBtn.on("pointerout", () => { + if (nextGroup._pressed) { + nextGroup._pressed = false; + this.tweens.killTweensOf(nextGroup); + this.tweens.add({ targets: nextGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); + } + }); + nextBtn.on("pointerup", () => { + if (!nextGroup._pressed) return; + nextGroup._pressed = false; + this.tweens.killTweensOf(nextGroup); + nextGroup.setScale(1); + + if (currentPage >= TOTAL_PAGES - 1) { + this._closeHowToPlayPopup(); + } else { + currentPage++; + tutorialImage.setTexture(TUTORIAL_PAGES[currentPage]); + _buildDescLines(currentPage); + nextLabel.setText(currentPage >= TOTAL_PAGES - 1 ? "Exit" : "Next"); + } + }); + panelContainer.setScale(0); + this.tweens.add({ + targets: panelContainer, + scale: 1, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); +} + _closeHowToPlayPopup() { + if (this._howToPlayPopup) { + this._howToPlayPopup.destroy(); + this._howToPlayPopup = null; + } + } + _buildUpdateLogPopup() { + if (this._updateLogPopup || window.levelID) { + return; + } + const xPos = screenWidth / 2; + const popupHeight = 320; + const popupWidth = 336; + this._updateLogPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + const background = this.add.rectangle(xPos, popupHeight, screenWidth, screenHeight, 0, 100 / 255); + background.setInteractive(); + this._updateLogPopup.add(background); + + const bounceContainer = this.add.container(xPos, popupHeight).setScale(0); + this._updateLogPopup.add(bounceContainer); + const cornerRadius = this.textures.get("GJ_square02").source[0].width * 0.325; + const popupBg = this._drawScale9(0, 0, 480, popupWidth, "GJ_square02", cornerRadius, 16777215, 1); + bounceContainer.add(popupBg); + const closeBtn = this.add.image(-240 + 20, -148, "GJ_WebSheet", "GJ_closeBtn_001.png").setScale(0.8).setInteractive(); + bounceContainer.add(closeBtn); + this._expandHitArea(closeBtn, 2); + this._makeBouncyButton(closeBtn, 0.8, () => this._closeUpdateLogPopup()); + const title = this.add.bitmapText(0, -124, "bigFont", "BETA (EXPECT BUGS)", 30).setOrigin(0.5, 0.5).setTint(0xff6666); + bounceContainer.add(title); + const scrollAreaW = 420; + const scrollAreaH = 230; + const scrollAreaX = 0; + const scrollAreaY = 20; + const scrollFrameBg = this.add.graphics(); + scrollFrameBg.fillStyle(0x000000, 0.18); + scrollFrameBg.fillRoundedRect(scrollAreaX - scrollAreaW / 2, scrollAreaY - scrollAreaH / 2, scrollAreaW, scrollAreaH, 8); + bounceContainer.add(scrollFrameBg); + const contentContainer = this.add.container(0, scrollAreaY - scrollAreaH / 2 + 8); + bounceContainer.add(contentContainer); + /* colors for reference + 0xff6666 + 0xff9944 + 0xaaddff - fun messages from me :) + 0xFF008E - pink dev entries + */ + const updateEntries = [ + { text: "Update Log", scale: 0.85, font: "goldFont" }, + { text: "slopes (very buggy)", scale: 0.7, color: 0xff9944 }, + { text: "THEY WILL BE FIXED", scale: 0.7, }, + { text: "OVER TIME", scale: 0.7, }, + { text: "slopes work in imported", scale: 0.7, }, + { text: "levels now (thanks lasokadadyy)", scale: 0.7, }, + { text: "fixed SOME objects", scale: 0.7 }, + { text: "-pinkdih", scale: 0.7, color: 0xFF008E }, + ]; + let yPos = 0; + const lineItems = []; + updateEntries.forEach(entry => { + const txt = this.add.bitmapText(0, yPos, entry.font || "bigFont", entry.text, 32) + .setOrigin(0.5, 0) + .setScale(entry.scale || 0.65); + if (entry.color != null) txt.setTint(entry.color); + contentContainer.add(txt); + lineItems.push(txt); + yPos += Math.round(32 * (entry.scale || 0.65)) + 10; + }); + const totalContentH = yPos; + const maxScrollDown = Math.max(0, totalContentH - scrollAreaH + 16); + const maskGraphics = this.add.graphics(); + const maskShape = this.add.graphics(); + maskShape.fillStyle(0xffffff, 1); + const updateMask = () => { + if (!bounceContainer || !bounceContainer.active) return; + const wx = xPos + bounceContainer.x - xPos; + const s = bounceContainer.scaleX; + const bwx = xPos; + const bwy = popupHeight; + maskShape.clear(); + maskShape.fillStyle(0xffffff, 1); + maskShape.fillRect( + bwx + (scrollAreaX - scrollAreaW / 2) * s, + bwy + (scrollAreaY - scrollAreaH / 2) * s, + scrollAreaW * s, + scrollAreaH * s + ); + }; + const geomMask = maskShape.createGeometryMask(); + contentContainer.setMask(geomMask); + const maskUpdateEvent = this.events.on('postupdate', updateMask); + let scrollY = 0; + const baseContentY = scrollAreaY - scrollAreaH / 2 + 8; + const applyScroll = () => { + contentContainer.y = baseContentY - scrollY; + }; + applyScroll(); + const scrollZone = this.add.zone(scrollAreaX, scrollAreaY, scrollAreaW, scrollAreaH).setInteractive(); + bounceContainer.add(scrollZone); + scrollZone.on('wheel', (_p, _dx, deltaY) => { + scrollY = Phaser.Math.Clamp(scrollY + deltaY * 0.6, 0, maxScrollDown); + applyScroll(); + }); + + let dragStartY = 0; + let dragStartScroll = 0; + scrollZone.on('pointerdown', (pointer) => { + dragStartY = pointer.y; + dragStartScroll = scrollY; + }); + scrollZone.on('pointermove', (pointer) => { + if (pointer.isDown) { + const dy = dragStartY - pointer.y; + scrollY = Phaser.Math.Clamp(dragStartScroll + dy, 0, maxScrollDown); + applyScroll(); + } + }); + this._updateLogPopupCleanup = () => { + this.events.off('postupdate', updateMask); + maskShape.destroy(); + geomMask.destroy(); + }; + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeUpdateLogPopup() { + if (this._updateLogPopup) { + if (this._updateLogPopupCleanup) { + this._updateLogPopupCleanup(); + this._updateLogPopupCleanup = null; + } + this._updateLogPopup.destroy(); + this._updateLogPopup = null; + } + } + _buildNewgroundsPopup() { + if (this._newgroundsPopup || window.levelID) return; + const xPos = screenWidth / 2; + const centerY = screenHeight / 2; + this._newgroundsPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); + background.setInteractive(); + this._newgroundsPopup.add(background); + const bounceContainer = this.add.container(xPos, centerY).setScale(0); + this._newgroundsPopup.add(bounceContainer); + const cornerRadius = this.textures.get("square01_001").source[0].width * 0.325; + const panelBg = this._drawScale9(0, 0, 460, 240, "square01_001", cornerRadius, 16777215, 1); + bounceContainer.add(panelBg); + const title = this.add.bitmapText(0, -76, "goldFont", "Newgrounds", 40).setOrigin(0.5, 0.5); + bounceContainer.add(title); + const body = this.add.text(0, -10, "Visit Newgrounds to find awesome\nmusic?", { + fontSize: "25px", + fontFamily: "Arial, sans-serif", + color: "#ffffff", + align: "center" + }).setOrigin(0.5, 0.5); + bounceContainer.add(body); + const cancelGroup = this.add.container(-70, 65); + const cancelBtnW = 165, cancelBtnH = 55; + const cancelBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; + const cancelBtn9 = this._drawScale9(0, 0, cancelBtnW, cancelBtnH, "GJ_button01", cancelBtnBorder, 0xffffff, 1); + const cancelBtn = this.add.rectangle(0, 0, cancelBtnW, cancelBtnH).setInteractive(); + cancelGroup.add(cancelBtn9); + cancelGroup.add(cancelBtn); + const cancelLabel = this.add.bitmapText(-2, -3, "goldFont", "Cancel", 38).setOrigin(0.5, 0.5); + cancelGroup.add(cancelLabel); + bounceContainer.add(cancelGroup); + cancelBtn.on("pointerdown", () => { cancelGroup._pressed = true; this.tweens.killTweensOf(cancelGroup); this.tweens.add({ targets: cancelGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); + cancelBtn.on("pointerout", () => { if (cancelGroup._pressed) { cancelGroup._pressed = false; this.tweens.killTweensOf(cancelGroup); this.tweens.add({ targets: cancelGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); + cancelBtn.on("pointerup", () => { if (cancelGroup._pressed) { cancelGroup._pressed = false; this.tweens.killTweensOf(cancelGroup); cancelGroup.setScale(1); this._closeNewgroundsPopup(); } }); + const openGroup = this.add.container(90, 65); + const openBtnW = 125, openBtnH = 55; + const openBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; + const openBtn9 = this._drawScale9(0, 0, openBtnW, openBtnH, "GJ_button01", openBtnBorder, 0xffffff, 1); + const openBtn = this.add.rectangle(0, 0, openBtnW, openBtnH).setInteractive(); + openGroup.add(openBtn9); + openGroup.add(openBtn); + const openLabel = this.add.bitmapText(-2, -3, "goldFont", "Open", 39).setOrigin(0.5, 0.5); + openGroup.add(openLabel); + bounceContainer.add(openGroup); + openBtn.on("pointerdown", () => { openGroup._pressed = true; this.tweens.killTweensOf(openGroup); this.tweens.add({ targets: openGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); + openBtn.on("pointerout", () => { if (openGroup._pressed) { openGroup._pressed = false; this.tweens.killTweensOf(openGroup); this.tweens.add({ targets: openGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); + openBtn.on("pointerup", () => { if (openGroup._pressed) { openGroup._pressed = false; this.tweens.killTweensOf(openGroup); openGroup.setScale(1); this._closeNewgroundsPopup(); window.open("https://www.newgrounds.com/audio", "_blank"); } }); + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeNewgroundsPopup() { + if (this._newgroundsPopup) { + this._newgroundsPopup.destroy(); + this._newgroundsPopup = null; + } + } + _buildFeaturedInfoPopup() { + if (this._featuredInfoPopup) return; + const xPos = screenWidth / 2; + const centerY = screenHeight / 2; + this._featuredInfoPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); + background.setInteractive(); + this._featuredInfoPopup.add(background); + const bounceContainer = this.add.container(xPos, centerY).setScale(0); + this._featuredInfoPopup.add(bounceContainer); + const cornerRadius = this.textures.get("square01_001").source[0].width * 0.325; + const panelBg = this._drawScale9(0, 0, 560, 300, "square01_001", cornerRadius, 16777215, 1); + bounceContainer.add(panelBg); + const title = this.add.bitmapText(0, -98, "goldFont", "Featured", 42).setOrigin(0.5, 0.5); + bounceContainer.add(title); + const body = this.add.text(0, -5, "its finally finished after so long\nso this is awesome am i right\n it has aura. featured tab. roptop fgames.", { + fontSize: "21px", + fontFamily: "Arial, sans-serif", + color: "#ffffff", + align: "center", + lineSpacing: 4 + }).setOrigin(0.5, 0.5); + bounceContainer.add(body); + const okGroup = this.add.container(-5, 95); + const okBtnW = 90, okBtnH = 55; + const okBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; + const okBtn9 = this._drawScale9(0, 0, okBtnW, okBtnH, "GJ_button01", okBtnBorder, 0xffffff, 1); + const okBtn = this.add.rectangle(0, 0, okBtnW, okBtnH).setInteractive(); + okGroup.add(okBtn9); + okGroup.add(okBtn); + const okLabel = this.add.bitmapText(-3, -4, "goldFont", "OK", 44).setOrigin(0.5, 0.5); + okGroup.add(okLabel); + bounceContainer.add(okGroup); + okBtn.on("pointerdown", () => { okGroup._pressed = true; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); + okBtn.on("pointerout", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); + okBtn.on("pointerup", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); okGroup.setScale(1); this._closeFeaturedInfoPopup(); } }); + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeFeaturedInfoPopup() { + if (this._featuredInfoPopup) { + this._featuredInfoPopup.destroy(); + this._featuredInfoPopup = null; + } + } + _buildDemonFilterPopup() { + if (this._demonFilterPopup) return; + const xPos = screenWidth / 2; + const centerY = screenHeight / 2; + this._demonFilterPopup = this.add.container(0, 0).setScrollFactor(0).setDepth(1000); + const background = this.add.rectangle(xPos, centerY, screenWidth, screenHeight, 0, 100 / 255); + background.setInteractive(); + this._demonFilterPopup.add(background); + const bounceContainer = this.add.container(xPos, centerY).setScale(0); + this._demonFilterPopup.add(bounceContainer); + + const panelW = 760, panelH = 360; + const cornerRadius = this.textures.get("GJ_square01").source[0].width * 0.325; + const panelBg = this.add.nineslice(0, 0, "GJ_square01", null, panelW, panelH, cornerRadius, cornerRadius, cornerRadius, cornerRadius) + .setOrigin(0.5); + bounceContainer.add(panelBg); + + const title = this.add.bitmapText(0, -panelH / 2 + 40, "bigFont", "Demon Filter", 64).setOrigin(0.5, 0.5); + bounceContainer.add(title); + + const _tierDefs = [ + { frame: "difficulty_06_btn_001.png", w: 72, h: 88, tier: null }, + { frame: "difficulty_07_btn2_001.png", w: 72, h: 85, tier: 1 }, + { frame: "difficulty_08_btn2_001.png", w: 72, h: 85, tier: 2 }, + { frame: "difficulty_06_btn2_001.png", w: 72, h: 88, tier: 3 }, + { frame: "difficulty_09_btn2_001.png", w: 74, h: 88, tier: 4 }, + { frame: "difficulty_10_btn2_001.png", w: 80, h: 91, tier: 5 }, + ]; + const slotW = (panelW - 60) / _tierDefs.length; + const iconY = 0; + const iconTargetH = 78; + const tierIcons = []; + let selectedTierIdx = _tierDefs.findIndex(t => t.tier === (this._selectedDemonTier || null)); + if (selectedTierIdx < 0) selectedTierIdx = 0; + const baseScale = 1.1; + + _tierDefs.forEach((def, i) => { + const cx = -panelW / 2 + 30 + slotW * i + slotW / 2; + const icon = this.add.image(cx, iconY, "GJ_GameSheet03", def.frame) + .setOrigin(0.5).setScale(baseScale).setInteractive(); + icon.setTint(i === selectedTierIdx ? 0xffffff : 0x8F8F8F); + bounceContainer.add(icon); + tierIcons.push(icon); + + icon.on("pointerdown", () => { + icon._pressed = true; + this.tweens.killTweensOf(icon, "scale"); + this.tweens.add({ targets: icon, scale: baseScale * 1.15, duration: 300, ease: "Bounce.Out" }); + }); + icon.on("pointerout", () => { + if (icon._pressed) { + icon._pressed = false; + this.tweens.killTweensOf(icon, "scale"); + this.tweens.add({ targets: icon, scale: baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + icon.on("pointerup", () => { + if (!icon._pressed) return; + icon._pressed = false; + this.tweens.killTweensOf(icon, "scale"); + icon.setScale(baseScale); + selectedTierIdx = i; + tierIcons.forEach((other, oi) => other.setTint(oi === i ? 0xffffff : 0x8f8f8f)); + }); + }); + + const okGroup = this.add.container(0, panelH / 2 - 45); + const okBtnW = 110, okBtnH = 55; + const okBtn9 = this.add.nineslice(0, 0, "GJ_button01", null, okBtnW, okBtnH, 18, 18, 18, 18) + .setOrigin(0.5).setInteractive(); + okGroup.add(okBtn9); + const okLabel = this.add.bitmapText(-3, -4, "goldFont", "OK", 44).setOrigin(0.5, 0.5); + okGroup.add(okLabel); + bounceContainer.add(okGroup); + okBtn9.on("pointerdown", () => { okGroup._pressed = true; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1.26, scaleY: 1.26, duration: 300, ease: "Bounce.Out" }); }); + okBtn9.on("pointerout", () => { if (okGroup._pressed) { okGroup._pressed = false; this.tweens.killTweensOf(okGroup); this.tweens.add({ targets: okGroup, scaleX: 1, scaleY: 1, duration: 400, ease: "Bounce.Out" }); } }); + okBtn9.on("pointerup", () => { + if (!okGroup._pressed) return; + okGroup._pressed = false; + this.tweens.killTweensOf(okGroup); + okGroup.setScale(1); + const chosen = _tierDefs[selectedTierIdx]; + this._selectedDemonTier = chosen.tier; + const demonIcon = this._diffFilterIcons && this._diffFilterIcons[6]; + if (demonIcon) { + demonIcon.setTexture("GJ_GameSheet03", chosen.frame); + demonIcon.setScale(0.85); + } + this._closeDemonFilterPopup(); + }); + + this.tweens.add({ + targets: bounceContainer, + scale: { from: 0, to: 1 }, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6] + }); + } + _closeDemonFilterPopup() { + if (this._demonFilterPopup) { + this._demonFilterPopup.destroy(); + this._demonFilterPopup = null; + } + } + _expandHitArea(_0x122213, _0x37180a) { + const _0x46ea45 = _0x122213.width; + const _0x43b461 = _0x122213.height; + const _0x960250 = _0x46ea45 * (_0x37180a - 1) / 2; + const _0x3f88a1 = _0x43b461 * (_0x37180a - 1) / 2; + _0x122213.input.hitArea.setTo(-_0x960250, -_0x3f88a1, _0x46ea45 + _0x960250 * 2, _0x43b461 + _0x3f88a1 * 2); + } + _makeBouncyButton(textureX, _0x57b645, _0x2f13d0, _0xda0c21) { + textureX._bouncyBaseScale = _0x57b645; + const getBouncyVisualTargets = () => { + const configured = Array.isArray(textureX._bouncyVisualTargets) && textureX._bouncyVisualTargets.length + ? textureX._bouncyVisualTargets + : [textureX._bouncyVisualTarget || textureX]; + return configured + .map(entry => { + const target = entry && entry.target ? entry.target : entry; + if (!target || typeof target.setScale !== "function") return null; + const baseScale = + (entry && typeof entry.getBaseScale === "function" ? entry.getBaseScale() : undefined) ?? + (entry && entry.baseScale !== undefined ? entry.baseScale : undefined) ?? + target._bouncyBaseScale ?? + textureX._bouncyBaseScale ?? + _0x57b645; + const baseScaleX = + (entry && typeof entry.getBaseScaleX === "function" ? entry.getBaseScaleX() : undefined) ?? + (entry && entry.baseScaleX !== undefined ? entry.baseScaleX : undefined) ?? + baseScale; + const baseScaleY = + (entry && typeof entry.getBaseScaleY === "function" ? entry.getBaseScaleY() : undefined) ?? + (entry && entry.baseScaleY !== undefined ? entry.baseScaleY : undefined) ?? + baseScale; + return { target, baseScaleX, baseScaleY }; + }) + .filter(Boolean); + }; + const tweenBouncyTargets = (scaleMultiplier, duration) => { + for (const entry of getBouncyVisualTargets()) { + this.tweens.killTweensOf(entry.target); + this.tweens.add({ + targets: entry.target, + scaleX: entry.baseScaleX * scaleMultiplier, + scaleY: entry.baseScaleY * scaleMultiplier, + duration, + ease: "Bounce.Out" + }); + } + }; + const resetBouncyTargets = (instant = false) => { + for (const entry of getBouncyVisualTargets()) { + this.tweens.killTweensOf(entry.target); + + if (instant) { + entry.target.setScale(entry.baseScaleX, entry.baseScaleY); + } else { + this.tweens.add({ + targets: entry.target, + scaleX: entry.baseScaleX, + scaleY: entry.baseScaleY, + duration: 400, + ease: "Bounce.Out" + }); + } + } + }; + textureX.on("pointerdown", () => { + if (!_0xda0c21 || !!_0xda0c21()) { + textureX._pressed = true; + tweenBouncyTargets(1.26, 300); + } + }); + textureX.on("pointerout", () => { + if (textureX._pressed) { + textureX._pressed = false; + resetBouncyTargets(false); + } + }); + textureX.on("pointerup", () => { + if (textureX._pressed) { + textureX._pressed = false; + resetBouncyTargets(true); + _0x2f13d0?.(); + } + }); + textureX.on("pointerupoutside", () => { + if (textureX._pressed) { + textureX._pressed = false; + resetBouncyTargets(false); + } + }); + return textureX; + } + _makeCompositeBouncyButton(trigger, visualTargets, baseScale, callback, condition) { + trigger._bouncyVisualTargets = (Array.isArray(visualTargets) ? visualTargets : [visualTargets]) + .filter(Boolean) + .map(entry => { + const target = entry && entry.target ? entry.target : entry; + const currentScaleX = target?.scaleX ?? baseScale; + const currentScaleY = target?.scaleY ?? baseScale; + const entryBase = entry && entry.baseScale !== undefined ? entry.baseScale : undefined; + + return { + target, + baseScaleX: entry && entry.baseScaleX !== undefined ? entry.baseScaleX : (entryBase ?? currentScaleX), + baseScaleY: entry && entry.baseScaleY !== undefined ? entry.baseScaleY : (entryBase ?? currentScaleY), + getBaseScale: entry && entry.getBaseScale, + getBaseScaleX: entry && entry.getBaseScaleX, + getBaseScaleY: entry && entry.getBaseScaleY + }; + }); + + return this._makeBouncyButton(trigger, baseScale, callback, condition); + } + _toggleFullscreen() { + if (this.scale.isFullscreen) { + this.scale.stopFullscreen(); + } else { + this.scale.startFullscreen(); + try { + screen.orientation.lock("landscape").catch(() => {}); + } catch (_0x22124f) {} + } + } + _drawScale9(x, y, scaleWidth, scaleHeight, textureKey, borderSize, tint, alpha) { + const container = this.add.container(x, y); + const texture = this.textures.get(textureKey); + const baseFrame = texture?.get?.(); + const source = texture?.source?.[0]; + const textureWidth = baseFrame?.width || source?.width || scaleWidth; + const textureHeight = baseFrame?.height || source?.height || scaleHeight; + const requestedBorder = Math.max(0, Number(borderSize) || 0); + const horizontalBorder = Math.min(requestedBorder, textureWidth / 2, scaleWidth / 2); + const verticalBorder = Math.min(requestedBorder, textureHeight / 2, scaleHeight / 2); + + const nineSlice = this.add.nineslice( + 0, + 0, + textureKey, + null, + scaleWidth, + scaleHeight, + horizontalBorder, + horizontalBorder, + verticalBorder, + verticalBorder + ).setOrigin(0.5); + + if (tint !== undefined) { + nineSlice.setTint(tint); + } + if (alpha !== undefined) { + nineSlice.setAlpha(alpha); + } + + container.add(nineSlice); + return container; + } + _startGame() { + if (!this._menuActive) { + return; + } + const _instant = !!this._instantLevelStart; + this._instantLevelStart = false; + const _dismiss = (target, tweenProps, cleanup) => { + if (!target) return; + if (_instant) { + cleanup(); + return; + } + this.tweens.killTweensOf(target); + this.tweens.add({ + targets: target, + ...tweenProps, + onComplete: cleanup + }); + }; + + // fixed loading saved new best from local storage + this._bestPercent = parseFloat(localStorage.getItem("bestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); + this._practiceBestPercent = parseFloat(localStorage.getItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1")) || "0"); + + this._menuActive = false; + this._practiceBypassPending = false; + this._slideIn = true; + if (this._menuGlitter) { + this._menuGlitter.destroy(); + this._menuGlitter = null; + } + if (this._menuUpdateLogBtn) { + this._menuUpdateLogBtn.setVisible(false); + } + if (this._menuNewgroundsBtn) { + this._menuNewgroundsBtn.setVisible(false); + } + if (this._menuSettingsBtn) { + this._menuSettingsBtn.setVisible(false); + } + if (this._menuAchievementsBtn) { + this._menuAchievementsBtn.setVisible(false); + } + if (this._menuStatsBtn) { + this._menuStatsBtn.setVisible(false); + } + _dismiss(this._playBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { + this._playBtn.destroy(); + this._playBtn = null; + }); + //icon stuff the threequel + if (this._iconBtn) { + this._closeIconSelector && this._closeIconSelector(true); + _dismiss(this._iconBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { + this._iconBtn.destroy(); + this._iconBtn = null; + }); + } + _dismiss(this._chrSelDecor, { y: screenHeight + 100, alpha: 0, duration: 200, ease: "Quad.In" }, () => { + if (this._chrSelDecor) { this._chrSelDecor.destroy(); this._chrSelDecor = null; } + }); + _dismiss(this._lvlEditDecor, { y: screenHeight + 100, alpha: 0, duration: 200, ease: "Quad.In" }, () => { + if (this._lvlEditDecor) { this._lvlEditDecor.destroy(); this._lvlEditDecor = null; } + }); + //creator stuff the threequel + if (this._creatorBtn) { + this._closeCreatorMenu && this._closeCreatorMenu(true); + this._closeSearchMenu && this._closeSearchMenu(true); + _dismiss(this._creatorBtn, { scale: 0.01, duration: 200, ease: "Quad.In" }, () => { + this._creatorBtn.destroy(); + this._creatorBtn = null; + }); + } + _dismiss(this._robLogo, { y: screenHeight + (this._robLogo ? this._robLogo.height : 0), duration: 300, ease: "Quad.In" }, () => { + this._robLogo.destroy(); + this._robLogo = null; + }); + _dismiss(this._copyrightText, { y: 680, duration: 300, ease: "Quad.In" }, () => { + this._copyrightText.destroy(); + this._copyrightText = null; + }); + _dismiss(this._menuFsBtn, { y: this._menuFsBtn ? -this._menuFsBtn.height : 0, duration: 300, ease: "Quad.In" }, () => { + this._menuFsBtn.destroy(); + this._menuFsBtn = null; + }); + _dismiss(this._menuInfoBtn, { y: this._menuInfoBtn ? -this._menuInfoBtn.height : 0, duration: 300, ease: "Quad.In" }, () => { + this._menuInfoBtn.destroy(); + this._menuInfoBtn = null; + }); + this._closeInfoPopup(); + this._closeUpdateLogPopup(); + _dismiss(this._tryMeImg, { y: this._tryMeImg ? -this._tryMeImg.height : 0, duration: 300, ease: "Quad.In" }, () => { + this._tryMeImg.destroy(); + this._tryMeImg = null; + }); + if (this._downloadBtns) { + for (const _0xaa3a95 of this._downloadBtns) { + _dismiss(_0xaa3a95, { y: screenHeight + _0xaa3a95.height, duration: 300, ease: "Quad.In" }, () => _0xaa3a95.destroy()); + } + this._downloadBtns = null; + } + if (this._socialIcons && this._socialIcons.length > 0) { + for (const _icon of this._socialIcons) { + _dismiss(_icon, { y: screenHeight + 64, duration: 300, ease: "Quad.In" }, () => _icon.destroy()); + } + this._socialIcons = []; + } + _dismiss(this._logo, { y: this._logo ? -this._logo.height : 0, duration: 300, ease: "Quad.In" }, () => { + this._logo.destroy(); + this._logo = null; + }); + + if (window.isEditor) { + this._audio.stopMusic(); + this._cameraX = 0; + this._cameraY = 0; + this._playerWorldX = 0; + this._level.additiveContainer.setVisible(true); + this._level.container.setVisible(true); + this._level.topContainer.setVisible(true); + this._player.setCubeVisible(false); + this._player2.setCubeVisible(false); + this._attemptsLabel.setVisible(false); + window.selectedObjId = 1; + this._levelEditor._initEditorLogic(); + return; + } + this._cameraX = -centerX; + this._cameraY = 0; + this._cameraXRef._v = this._cameraX; + this._prevCameraX = this._cameraX; + const _0x22e36e = this._cameraX - (this._menuCameraX || 0); + this._level.shiftGroundTiles(_0x22e36e); + this._playerWorldX = this._cameraX; + let speedKey = parseInt(window.settingsMap["kA4"] || "0"); + if (speedKey == 0) { + playerSpeed = SpeedPortal.ONE_TIMES; + } else if (speedKey == 1) { + playerSpeed = SpeedPortal.HALF; + } else if (speedKey == 2) { + playerSpeed = SpeedPortal.TWO_TIMES; + } else if (speedKey == 3) { + playerSpeed = SpeedPortal.THREE_TIMES; + } else if (speedKey == 4) { + playerSpeed = SpeedPortal.FOUR_TIMES; + } + this._state.y = 30; + this._state.onGround = true; + this._level.additiveContainer.setVisible(true); + this._level.container.setVisible(true); + this._level.topContainer.setVisible(true); + this._player.setCubeVisible(true); + this._player.reset(); + this._isDual = false; + this._state2.reset(); + this._player2.reset(); + this._player2.setCubeVisible(false); + this._player2.setShipVisible(false); + this._player2.setBallVisible(false); + this._player2.setWaveVisible(false); + this._player2.setBirdVisible?.(false); + this._player2.setSpiderVisible(false); + this._player2.setRobotVisible(false); + this._player2.setSwingVisible(false); + this._levelAttempts = 1; + this._levelJumps = 0; + this._attempts++; + localStorage.setItem("gd_totalAttempts", this._attempts); + this._attemptsLabel.setText("Attempt " + this._levelAttempts); + this._attemptsLabel.setVisible(true); + this._positionAttemptsLabel(); + let gamemode = parseInt(window.settingsMap["kA2"] || "0"); + if (gamemode == 1) { + this._player.enterShipMode(); + } else if (gamemode == 2) { + this._state.y = 30; + this._player.enterBallMode({ y: 30 }); + } else if (gamemode == 3) { + this._player.enterUfoMode(); + } else if (gamemode == 4) { + this._player.enterWaveMode(); + } else if (gamemode == 5) { + this._player.enterRobotMode(); + } else if (gamemode == 6) { + this._player.enterSpiderMode(); + } else if (gamemode == 7) { + this._player.enterSwingMode(); + } + + this._applyLevelStartOptions(); + } + _pushButton(ignoreMacro = false) { + const objectsUnderPointer = this.input.manager.hitTest( + this.input.activePointer, + this._startPosGui.list, + this.cameras.main + ); + const isOverUI = objectsUnderPointer.length > 0; + const fromClick = this.input.activePointer.isDown; + const cancelInput = isOverUI && fromClick; + + if (this._menuActive) { + this._audio.playEffect("playSound_01", { + volume: 1 + }); + this._startGame(); + return; + } + + if (!cancelInput) { + if (!this._clickHistory) this._clickHistory = []; + this._clickHistory.push(this.time.now); + } + + if (!this._slideIn && !this._state.isDead && !cancelInput) { + this._state.upKeyDown = true; + this._state.upKeyPressed = true; + this._state.queuedHold = true; + this._state._orbActivationConsumedForPress = false; + if (this._isDual && !this._state2.isDead) { + this._state2.upKeyDown = true; + this._state2.upKeyPressed = true; + this._state2.queuedHold = true; + this._state2._orbActivationConsumedForPress = false; + } + const _dualImmediateBeforeGravity = !!this._state.gravityFlipped; + let _primaryImmediateJumped = false; + if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && !this._state.isSwing && this._state.canJump) { + this._player.updateJump(0); + _primaryImmediateJumped = true; + } else if (this._state.isUfo || this._state.isSwing) { + if (!this._player._shouldPrioritizeUfoOrbInput?.()) { + this._player.updateJump(0); + _primaryImmediateJumped = true; + } + } + const _primaryImmediateGravityChanged = this._isDual && !!this._state.gravityFlipped !== _dualImmediateBeforeGravity; + let _primaryImmediateGravitySynced = false; + if (_primaryImmediateGravityChanged) { + _primaryImmediateGravitySynced = this._syncDualGlobalsFromPrimary({ + skipBallInputGravity: this._state.isBall && _primaryImmediateJumped, + skipSpiderInputGravity: this._state.isSpider && _primaryImmediateJumped, + skipSwingInputGravity: this._state.isSwing && _primaryImmediateJumped + }); + } + if (this._isDual && !this._state2.isDead) { + if (this._shouldSuppressDualGravityAction(this._state2, _primaryImmediateGravitySynced)) { + this._state2.upKeyPressed = false; + this._state2.queuedHold = false; + } + const _secondaryImmediateBeforeGravity = !!this._state2.gravityFlipped; + const _secondaryImmediateBallInput = this._state2.isBall && this._state2.upKeyPressed; + const _secondaryImmediateSpiderInput = this._state2.isSpider && this._state2.upKeyPressed; + const _secondaryImmediateSwingInput = this._state2.isSwing && this._state2.upKeyPressed; + if (!this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && !this._state2.isSwing && this._state2.canJump) { + this._player2.updateJump(0); + } else if (this._state2.isUfo || this._state2.isSwing) { + if (!this._player2._shouldPrioritizeUfoOrbInput?.()) { + this._player2.updateJump(0); + } + } + if (!!this._state2.gravityFlipped !== _secondaryImmediateBeforeGravity) { + this._syncDualGlobalsFromSecondary({ + skipBallInputGravity: _secondaryImmediateBallInput, + skipSpiderInputGravity: _secondaryImmediateSpiderInput, + skipSwingInputGravity: _secondaryImmediateSwingInput + }); + } + } + if (_primaryImmediateJumped) { + this._totalJumps++; + this._levelJumps++; + localStorage.setItem("gd_totalJumps", this._totalJumps); + } + } + + if (!ignoreMacro && this._macroBot) { + this._macroBot.recordEdge(true, this._physicsFrame); + } + } + _releaseButton(ignoreMacro = false) { + this._state.upKeyDown = false; + this._state.upKeyPressed = false; + this._state.queuedHold = false; + this._state._orbActivationConsumedForPress = false; + this._state2.upKeyDown = false; + this._state2.upKeyPressed = false; + this._state2.queuedHold = false; + this._state2._orbActivationConsumedForPress = false; + if (!ignoreMacro && this._macroBot) { + this._macroBot.recordEdge(false, this._physicsFrame); + } + } + _initMacroBot() { + this._macroBot = new MacroBot(this); + window.macroBot = this._macroBot; + } + _startMacroRecording(meta = {}) { + if (!this._macroBot) this._initMacroBot(); + this._macroBot.startRecording({ + level: window.currentlevel?.[2] || "", + ...meta + }); + } + _stopMacroRecording() { + if (!this._macroBot) return null; + return this._macroBot.stopRecording(); + } + _startMacroPlayback(macroData) { + console.log(macroData); + if (!this._macroBot) this._initMacroBot(); + this._macroBot.startPlayback(macroData); + } + _stopMacroPlayback() { + if (this._macroBot) this._macroBot.stopPlayback(); + } + _exportMacroFile(filename = null) { + if (!this._macroBot) return; + const safeName = (filename || `${window.currentlevel?.[2] || "macro"}.gdr`) + .replace(/[^\w.\-]+/g, "_"); + this._macroBot.download(safeName); + } + _importMacroFile() { + const fileInput = document.createElement("input"); + fileInput.type = "file"; + fileInput.accept = ".wbgdr"; + + fileInput.onchange = async (e) => { + const file = e.target.files?.[0]; + if (!file) return; + + try { + if (!this._macroBot) this._initMacroBot(); + + const macroData = await this._macroBot.importFile(file); + this._macroBot.inputs = Array.isArray(macroData.inputs) ? macroData.inputs.slice() : []; + const fallback = file.name.replace(/\.[^/.]+$/, ""); + const macroName = macroData.meta?.name || fallback; + + this._macroBot.meta = macroData.meta || this._macroBot.meta; + this._macroBot.meta.name = macroName; + + this._macroName = macroName; + this._macroLoaded = true; + } catch (err) { + alert("Failed to import: " + err.message); + } + }; + + fileInput.click(); + } + _positionMenuItems() { + const _0x1e5db8 = screenWidth / 2; + if (this._logo) { + this._logo.x = _0x1e5db8; + } + if (this._menuInfoBtn) { + this._menuInfoBtn.x = screenWidth - 30 - 3; + } + if (this._copyrightText) { + this._copyrightText.x = screenWidth - 20; + } + if (this._tryMeImg) { + this._tryMeImg.x = _0x1e5db8 + 260; + } + if (this._menuGlitter) { + this._menuGlitter.x = _0x1e5db8; + this._menuGlitter.y = 320; + } + if (this._playBtn) { + this._playBtn.x = _0x1e5db8; + this.tweens.killTweensOf(this._playBtn, "y"); + this._playBtn.y = 320; + } + if (this._downloadBtns) { + const _0x285ef7 = screenWidth - 130; + const _0x4a8263 = 570; + const _0x23d03e = 60; + for (let _0x1bdfae = 0; _0x1bdfae < this._downloadBtns.length; _0x1bdfae++) { + const yOffset = _0x1bdfae === 1 ? -_0x23d03e : 0; + this._downloadBtns[_0x1bdfae].setPosition(_0x285ef7, _0x4a8263 + yOffset); + } + } + if (this._iconBtn) { + this._iconBtn.x = (screenWidth / 2) - this._playBtn.width / 2 - 100 - (this._iconBtn.width * this._iconBtn.scaleX) / 2; + this.tweens.killTweensOf(this._iconBtn, "y"); + this._iconBtn.y = 320; + this.tweens.add({ + targets: this._iconBtn, + y: 324, + duration: 750, + ease: "Quad.InOut", + yoyo: true, + repeat: -1 + }); + } + if (this._creatorBtn) { + this._creatorBtn.x = (screenWidth / 2) + this._playBtn.width / 2 + 100 + (this._creatorBtn.width * this._creatorBtn.scaleX) / 2; + this.tweens.killTweensOf(this._creatorBtn, "y"); + this._creatorBtn.y = 320; + } + if (this._robLogo) { + this._robLogo.x = 110; + this._robLogo.y = 585; + } + if (this._socialIcons && this._socialIcons.length > 0) { + const _iconSpacing = 52; + const _originX = 65; + const _originY = 478; + const _layout = [{row:0,col:0},{row:0,col:1},{row:0,col:2},{row:0,col:3}, + {row:1,col:0},{row:1,col:1},{row:1,col:2},{row:1,col:3}, + {row:2,col:0},{row:2,col:1},{row:2,col:2},{row:2,col:3},{row:2,col:4}]; + this._socialIcons.forEach((icon, i) => { + icon.x = _originX + _layout[i].col * _iconSpacing; + icon.y = _originY + _layout[i].row * _iconSpacing; + }); + } + } + _positionAttemptsLabel() { + let _0xdbdd91 = this._cameraX + screenWidth / 2; + if (this._levelAttempts > 1) { + _0xdbdd91 += 100; + } + this._attemptsLabel.setPosition(_0xdbdd91, 150); + } + _resetGameplayState() { + this._cameraX = -centerX; + this._cameraY = 0; + this._cameraXRef._v = -centerX; + this._prevCameraX = -centerX; + this._playerWorldX = 0; + this._deltaBuffer = 0; + this._deathTimer = 0; + this._deathSoundPlayed = false; + this._newBestShown = false; + this._hadNewBest = false; + this._levelWon = false; + this._endCameraOverride = false; + this._endCamTween = null; + this._spaceWasDown = false; + this._physicsFrame = 0; + } + _restartLevel() { + this._attempts++; + localStorage.setItem("gd_totalAttempts", this._attempts); + this._levelAttempts++; + this._levelJumps = 0; + const _0x2ba78a = this._cameraX; + if (this._levelWon && this._practicedMode.practiceMode) { + this._practicedMode.togglePracticeMode(); + this._practicedMode.clearCheckpoints(); + if (this._checkpointBtnContainer) { + this._checkpointBtnContainer.setVisible(false); + } + } + if (this._practicedMode.practiceMode) { + const checkpoint = this._practicedMode.loadLastCheckpoint(); + if (checkpoint) { + this._respawnFromCheckpoint(); + return; + } + } + this._practicedMode.clearCheckpoints(); + this._resetGameplayState(); + this._state.reset(); + this._player.reset(); + this._isDual = false; + this._state2.reset(); + this._player2.reset(); + this._player2.setCubeVisible(false); + this._player2.setShipVisible(false); + this._player2.setBallVisible(false); + this._player2.setWaveVisible(false); + this._player2.setBirdVisible?.(false); + this._player2.setSpiderVisible(false); + this._player2.setRobotVisible(false); + this._player2.setSwingVisible(false); + this._glitterEmitter.stop(); + let speedKey = parseInt(window.settingsMap["kA4"] || "0"); + if (speedKey == 0) { + playerSpeed = SpeedPortal.ONE_TIMES; + } else if (speedKey == 1) { + playerSpeed = SpeedPortal.HALF; + } else if (speedKey == 2) { + playerSpeed = SpeedPortal.TWO_TIMES; + } else if (speedKey == 3) { + playerSpeed = SpeedPortal.THREE_TIMES; + } else if (speedKey == 4) { + playerSpeed = SpeedPortal.FOUR_TIMES; + } + this._level.resetObjects(); + this._level.shiftGroundTiles(this._cameraX - _0x2ba78a); + this._level.resetGroundState(); + this._level.resetColorTriggers(); + this._level.resetAlphaTriggers(); + this._level.resetRotateTriggers(); + this._level.resetPulseTriggers(); + this._level.resetEnterEffectTriggers(); + this._level.resetSpawnTriggers(); + this._level.resetMoveTriggers(); + this._level.resetVisibility(); + if (this._orbGfx) { this._orbGfx.clear(); } + this._colorManager.reset(); + this._player.noclipStats.totalFrames = 0; + this._player.noclipStats.deathFrames = 0; + this._player.noclipStats.deaths = 0; + + const musicOffset = this._getStartPosMusicOffset(); + const startPositions = this._level.getStartPositions(); + const activeStartPos = this._startPosIndex !== -1 && !!startPositions[this._startPosIndex]; + + if (activeStartPos) { + const pos = startPositions[this._startPosIndex]; + const startPosY = Number.isFinite(Number(pos.y)) ? Number(pos.y) : 30; + + this._playerWorldX = pos.x; + this._state.y = startPosY; + this._state.lastY = startPosY; + this._state.lastGroundPosY = startPosY; + if (pos.gameMode == 1) { + this._player.enterShipMode(); + } else if (pos.gameMode == 2) { + this._state.y = startPosY; + this._player.enterBallMode({ y: startPosY }); + } else if (pos.gameMode == 3) { + this._player.enterUfoMode(); + } else if (pos.gameMode == 4) { + this._player.enterWaveMode(); + } else if (pos.gameMode == 5) { + this._player.enterRobotMode(); + } else if (pos.gameMode == 6) { + this._player.enterSpiderMode(); + } + this._state.gravityFlipped = pos.gravityFlipped; + this._state.isMini = pos.miniMode; + playerSpeed = [ + SpeedPortal.ONE_TIMES, + SpeedPortal.HALF, + SpeedPortal.TWO_TIMES, + SpeedPortal.THREE_TIMES, + SpeedPortal.FOUR_TIMES + ][pos.speed]; + this._state.mirrored = pos.mirrored; + if (pos.dualMode) { + this._enableDualMode(); + } + this._level.fastForwardTriggers(pos.x, this._colorManager); + if (this._player) { + this._player._lastCollisionWorldX = Number.isFinite(Number(this._playerWorldX)) ? Number(this._playerWorldX) : null; + this._player._lastCollisionWorldY = startPosY; + } + } + + this._practiceBypassPending = false; + this._audio.reset(); + this._audio.startMusic(musicOffset); + this._paused = false; + if (this._pauseContainer) { + this._pauseContainer.destroy(); + this._pauseContainer = null; + } + this._pauseBtn.setVisible(true).setAlpha(75 / 255); + if (this._practiceModeBarContainer) { + this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); + } + this._attemptsLabel.setText("Attempt " + this._levelAttempts); + this._attemptsLabel.setVisible(true); + this._positionAttemptsLabel(); + if (!activeStartPos) { + let gamemode = parseInt(window.settingsMap["kA2"] || "0"); + if (gamemode == 1) { + this._player.enterShipMode(); + } else if (gamemode == 2) { + this._state.y = 30; + this._player.enterBallMode({ y: 30 }); + } else if (gamemode == 3) { + this._player.enterUfoMode(); + } else if (gamemode == 4) { + this._player.enterWaveMode(); + } else if (gamemode == 5) { + this._player.enterRobotMode(); + } else if (gamemode == 6) { + this._player.enterSpiderMode(); + } else if (gamemode == 7) { + this._player.enterSwingMode(); + } + + this._applyLevelStartOptions(); + } + + if (this._player && this._player._hitboxTrail) { + this._player._hitboxTrail = []; + } + if (this._player?._hitboxGraphics) this._player._hitboxGraphics.clear(); + if (this._player2 && this._player2._hitboxTrail) { + this._player2._hitboxTrail = []; + } + if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); + + if (this._macroBot?.recording == true){ + this._macroBot?.clearRecording(); + } + if (this._macroBot?.playing == true){ + this._macroBot?.clearPlayback(); + } + this._level._updateGlowVisibility?.(); + this._updateCameraY(0, true); + } + _getSongOffsetForWorldX(worldX) { + const startX = Number.isFinite(Number(worldX)) ? Number(worldX) : 0; + return this._level?.getSongOffsetForX + ? this._level.getSongOffsetForX(startX, { sourceObjects: window.levelObjects }) + : Math.max(0, startX) / 623.16; + } + _getStartPosMusicOffset(){ + const startPositions = this._level.getStartPositions(); + if (this._startPosIndex !== -1 && startPositions[this._startPosIndex]) { + return this._getSongOffsetForWorldX(startPositions[this._startPosIndex].x); + } + return 0; + } + _getCurrentMusicSyncOffset() { + if (this._startPosIndex !== -1 && this._playerWorldX <= 0) { + return this._getStartPosMusicOffset(); + } + return this._getSongOffsetForWorldX(this._playerWorldX); + } + _respawnFromCheckpoint() { + const checkpoint = this._practicedMode.loadLastCheckpoint(); + if (!checkpoint) { + this._restartLevel(); + return; + } + this._deathTimer = 0; + this._deathSoundPlayed = false; + this._newBestShown = false; + this._state.isDead = false; + this._slideIn = false; + this._playerWorldX = checkpoint.x; + this._cameraX = checkpoint.cameraX; + this._cameraY = checkpoint.cameraY; + this._cameraXRef._v = this._cameraX; + this._state.y = checkpoint.y; + this._state.yVelocity = checkpoint.yVelocity; + this._state.gravityFlipped = checkpoint.gravityFlipped; + this._state.isMini = checkpoint.isMini; + this._state.isCube = checkpoint.isCube; + this._state.isShip = checkpoint.isShip; + this._state.isBall = checkpoint.isBall; + this._state.isUfo = checkpoint.isUfo; + this._state.isWave = checkpoint.isWave; + this._state.isSpider = checkpoint.isSpider; + this._state.isBird = checkpoint.isBird; + this._state.isDart = checkpoint.isDart; + this._state.isRobot = checkpoint.isRobot; + this._state.isSwing = checkpoint.isSwing; + this._state.isJetpack = checkpoint.isJetpack; + this._state.isFlying = checkpoint.isFlying; + this._state.isJumping = checkpoint.isJumping; + this._state.onGround = checkpoint.onGround; + this._state.canJump = checkpoint.canJump; + this._state.wasBoosted = checkpoint.wasBoosted; + this._state.rotation = checkpoint.rotation; + this._state.gravity = checkpoint.gravity; + this._state.jumpPower = checkpoint.jumpPower; + this._state.mirrored = checkpoint.mirrored; + this._state.isDashing = checkpoint.isDashing; + this._state.dashYVelocity = checkpoint.dashYVelocity; + this._state.ballShouldRotate = checkpoint.ballShouldRotate || false; + this._state.ballRotateOpposite = checkpoint.ballRotateOpposite || false; + this._state.ballNormalRotate = checkpoint.ballNormalRotate || 1; + this._state.ballHitPad = checkpoint.ballHitPad || false; + this._state._robotHold = !!checkpoint.robotHold; + this._state._robotHoldTimer = checkpoint.robotHoldTimer || 0; + this._player.reset(); + this._state.isFlying = false; + this._state.isBall = false; + this._state.isWave = false; + this._state.isUfo = false; + this._state.isSpider = false; + this._state.isRobot = false; + this._state.isSwing = false; + this._state.isBird = false; + if (checkpoint.isFlying) { + this._player.enterShipMode(null, true); // dont mess with y velocity if ur loading a checkpoint + } else if (checkpoint.isBall) { + this._player.enterBallMode(); + } else if (checkpoint.isUfo) { + this._player.enterUfoMode(null, true); // dont mess with y velocity if ur loading a checkpoint + } else if (checkpoint.isWave) { + this._player.enterWaveMode(); + } else if (checkpoint.isRobot) { + this._player.enterRobotMode(); + } else if (checkpoint.isSpider) { + this._player.enterSpiderMode(); + } else if (checkpoint.isSwing) { + this._player.enterSwingMode(null, true); // dont mess with y velocity if ur loading a checkpoint + } else if (checkpoint.isBird) { + this._player.setBirdVisible(true); + this._player.setCubeVisible(true); + for (const layer of this._player._playerLayers) { + if (layer) { + layer.sprite.setScale(0.55); + } + } + } else { + this._player.setCubeVisible(true); + } + this._state.isFlying = checkpoint.isFlying; + this._state.isBall = checkpoint.isBall; + this._state.isWave = checkpoint.isWave; + this._state.isUfo = checkpoint.isUfo; + this._state.isSpider = checkpoint.isSpider; + this._state.isRobot = checkpoint.isRobot; + this._state.isSwing = checkpoint.isSwing; + this._state.isBird = checkpoint.isBird; + this._state._robotHold = !!checkpoint.robotHold; + this._state._robotHoldTimer = checkpoint.robotHoldTimer || 0; + this._state.ignorePortals = true; + this._state2.ignorePortals = true; + this._level.resetGroundTiles(this._cameraX); + this._level.resetObjects(); + this._level._flyFloorY = checkpoint.flyFloorY !== undefined + ? checkpoint.flyFloorY + : (this._level._flyFloorY ?? 0); + this._level._flyCeilingY = checkpoint.flyCeilingY; + this._level._flyGroundActive = checkpoint.flyGroundActive; + this._level._flyVisualOnly = checkpoint.flyVisualOnly; + this._level._flyVisualFloorInset = checkpoint.flyVisualFloorInset !== undefined + ? checkpoint.flyVisualFloorInset + : (this._level._flyVisualFloorInset ?? 0); + this._level._flyVisualCeilingInset = checkpoint.flyVisualCeilingInset !== undefined + ? checkpoint.flyVisualCeilingInset + : (this._level._flyVisualCeilingInset ?? 0); + this._level._groundTargetValue = checkpoint.groundTargetValue; + this._level.flyCameraTarget = checkpoint.flyCameraTarget; + this._level._groundAnimating = checkpoint.groundAnimating; + this._level._groundAnimFrom = checkpoint.groundAnimFrom; + this._level._groundAnimTo = checkpoint.groundAnimTo; + this._level._groundAnimTime = checkpoint.groundAnimTime; + this._level._groundAnimDuration = checkpoint.groundAnimDuration; + this._level._groundStartScreenY = checkpoint.groundStartScreenY !== undefined + ? checkpoint.groundStartScreenY - (checkpoint.cameraY || 0) + this._cameraY + : b(0) + this._cameraY; + this._level._ceilingStartScreenY = checkpoint.ceilingStartScreenY + - (checkpoint.cameraY || 0) + this._cameraY; + this._level._groundY = checkpoint.groundY; + this._level._ceilingY = checkpoint.ceilingY; + if (typeof checkpoint.speed === "number") { + playerSpeed = checkpoint.speed; + } else { + let speedKey = parseInt(window.settingsMap["kA4"] || "0"); + if (speedKey == 0) { + playerSpeed = SpeedPortal.ONE_TIMES; + } else if (speedKey == 1) { + playerSpeed = SpeedPortal.HALF; + } else if (speedKey == 2) { + playerSpeed = SpeedPortal.TWO_TIMES; + } else if (speedKey == 3) { + playerSpeed = SpeedPortal.THREE_TIMES; + } else if (speedKey == 4) { + playerSpeed = SpeedPortal.FOUR_TIMES; + } + } + if (checkpoint.dualMode) { + this._isDual = false; + this._dualBallOverlapResolved = false; + this._dualBallSpawnGravityLock = false; + this._state2.reset(); + this._player2.reset(); + this._player2.setInvertedColors?.(true); + this._enableDualMode(); + this._state2.isDead = false; + if (Number.isFinite(Number(checkpoint.dualY))) this._state2.y = Number(checkpoint.dualY); + if (Number.isFinite(Number(checkpoint.dualYVelocity))) this._state2.yVelocity = Number(checkpoint.dualYVelocity); + if (checkpoint.dualIsMini !== undefined) this._state2.isMini = !!checkpoint.dualIsMini; + if (checkpoint.dualGameMode) this._setPlayerGamemode(this._player2, this._state2, checkpoint.dualGameMode, true); + if (checkpoint.dualGravityFlipped !== undefined) this._state2.gravityFlipped = !!checkpoint.dualGravityFlipped; + if (checkpoint.dualOnGround !== undefined) this._state2.onGround = !!checkpoint.dualOnGround; + if (checkpoint.dualOnCeiling !== undefined) this._state2.onCeiling = !!checkpoint.dualOnCeiling; + if (checkpoint.dualCanJump !== undefined) this._state2.canJump = !!checkpoint.dualCanJump; + if (checkpoint.dualIsJumping !== undefined) this._state2.isJumping = !!checkpoint.dualIsJumping; + this._copyDualInputFlags(this._state, this._state2); + this._ensureDualFlyBounds(this._state.y); + } else { + this._isDual = false; + this._state2.reset(); + this._player2.reset(); + this._player2.setCubeVisible(false); + this._player2.setShipVisible(false); + this._player2.setBallVisible(false); + this._player2.setWaveVisible(false); + this._player2.setBirdVisible?.(false); + this._player2.setSpiderVisible(false); + this._player2.setRobotVisible(false); + if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); + if (this._player2) this._player2._hitboxTrail = []; + } + this._level.resetColorTriggers(); + this._level.resetAlphaTriggers(); + this._level.resetRotateTriggers(); + this._level.resetPulseTriggers(); + this._level.resetEnterEffectTriggers(); + this._level.resetSpawnTriggers(); + this._level.resetMoveTriggers(); + this._level.resetVisibility(); + this._level.additiveContainer.x = -this._cameraX; + this._level.additiveContainer.y = this._cameraY; + this._level.container.x = -this._cameraX; + this._level.container.y = this._cameraY; + this._level.topContainer.x = -this._cameraX; + this._level.topContainer.y = this._cameraY; + this._level.updateVisibility(this._cameraX); + this._level.updateObjectDebugIds(); + this._updateBackground(); + this._applyMirrorEffect(); + this._practiceBypassPending = false; + if (window.practiceMusicBypass) { + this._audio.startMusic(this._getSongOffsetForWorldX(checkpoint.x)); + } else if (!this._audio.musicPlaying) { + this._audio.startMusic(); + } + + if (this._player && this._player._hitboxTrail) { + this._player._hitboxTrail = []; + } + if (this._player?._hitboxGraphics) this._player._hitboxGraphics.clear(); + if (this._player2 && this._player2._hitboxTrail) { + this._player2._hitboxTrail = []; + } + if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); + + this._physicsFrame = checkpoint.physicsFrame; + if (this._macroBot?.recording == true){ + this._macroBot?.rollbackRecording(this._physicsFrame); + if (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown){ + this._macroBot.recordEdge(true, this._physicsFrame); + } else { + this._macroBot.recordEdge(false, this._physicsFrame); + } + } + if (this._macroBot?.playing == true){ + this._macroBot?.rollbackPlayback(this._physicsFrame); + } + this._level._updateGlowVisibility?.(); + } + _onFullscreenChange(_0x310c5b) { + if (!_0x310c5b) { + l(1138); + } + this.time.delayedCall(200, () => this._applyScreenResize()); + } + _applyScreenResize() { + if (this.scale.isFullscreen) { + const _0x5bc34b = window.innerWidth / window.innerHeight; + l(Math.round(screenHeight * _0x5bc34b)); + } + this.scale.setGameSize(screenWidth, screenHeight); + this.scale.refresh(); + this._bg.setSize(screenWidth, screenHeight); + this._pauseBtn.x = screenWidth - 30; + if (this._menuActive) { + this._positionMenuItems(); + } + if (this._paused && this._pauseContainer) { + this._pauseContainer.destroy(); + this._pauseContainer = null; + this._buildPauseOverlay(); + } + this._level.resizeScreen(); + if (!this._menuActive) { + const _0x56287b = this._cameraX; + this._cameraX = this._playerWorldX - centerX; + this._cameraXRef._v = this._cameraX; + this._level.additiveContainer.x = -this._cameraX; + this._level.additiveContainer.y = this._cameraY; + this._level.container.x = -this._cameraX; + this._level.container.y = this._cameraY; + this._level.topContainer.x = -this._cameraX; + this._level.topContainer.y = this._cameraY; + this._level.shiftGroundTiles(this._cameraX - _0x56287b); + this._level.updateGroundTiles(this._cameraY); + this._level.updateVisibility(this._cameraX); + this._level.updateObjectDebugIds(); + this._level.applyEnterEffects(this._cameraX); + const _0xde8a1a = this._playerWorldX - this._cameraX; + this._player.syncSprites(this._cameraX, this._cameraY, 0, this._getMirrorXOffset(_0xde8a1a)); + this._applyMirrorEffect(); + } + } + _createMirroredBackgroundTexture(textureKey) { + const mirroredKey = textureKey + "__mirror_y_loop"; + if (this.textures.exists(mirroredKey)) return mirroredKey; + + const texture = this.textures.get(textureKey); + const source = texture?.source?.[0]; + const image = source?.image || source?.canvas; + const width = source?.width || image?.width || image?.naturalWidth || 0; + const height = source?.height || image?.height || image?.naturalHeight || 0; + + if (!image || width <= 0 || height <= 0 || !this.textures.createCanvas) { + return textureKey; + } + + try { + const mirroredTexture = this.textures.createCanvas(mirroredKey, width, height * 2); + const ctx = mirroredTexture.getContext(); + ctx.clearRect(0, 0, width, height * 2); + ctx.drawImage(image, 0, 0, width, height, 0, 0, width, height); + ctx.save(); + ctx.translate(0, height * 2); + ctx.scale(1, -1); + ctx.drawImage(image, 0, 0, width, height, 0, 0, width, height); + ctx.restore(); + mirroredTexture.refresh(); + return mirroredKey; + } catch (err) { + console.warn("Failed to create mirrored background texture", textureKey, err); + if (this.textures.exists(mirroredKey)) this.textures.remove(mirroredKey); + return textureKey; + } + } + + _applyMirroredBackgroundTexture(textureKey) { + const texture = this.textures.get(textureKey); + const source = texture?.source?.[0]; + const sourceHeight = source?.height || source?.image?.height || source?.image?.naturalHeight || 0; + const mirroredKey = this._createMirroredBackgroundTexture(textureKey); + this._bg.setTexture(mirroredKey); + this._bgInitY = sourceHeight > 0 ? sourceHeight - screenHeight - o : 0; + this._bgMirrorTileHeight = sourceHeight > 0 ? sourceHeight * 2 : 0; + } + + _updateBackground() { + this._bg.tilePositionX += (this._cameraX - this._prevCameraX) * this._bgSpeedX; + this._prevCameraX = this._cameraX; + let tileY = this._bgInitY - this._cameraY * this._bgSpeedY; + if (this._bgMirrorTileHeight > 0) { + tileY = ((tileY % this._bgMirrorTileHeight) + this._bgMirrorTileHeight) % this._bgMirrorTileHeight; + } + this._bg.tilePositionY = tileY; + } + _updateCameraY(_0xc7c517, snap = false) { + let explosionPiece = this._cameraY; + let _0x1a27be = explosionPiece; + if (this._level.flyCameraTarget !== null) { + _0x1a27be = this._level.flyCameraTarget; + } else { + let _0x2bc8fb = this._state.y; + let _0x259956 = 140; + let _0x5025ec = 80; + let _0x1f7976 = explosionPiece - (typeof o !== 'undefined' ? o : 0) + 320; + if (this._state.gravityFlipped) { + if (_0x2bc8fb > _0x1f7976 + _0x5025ec) { + _0x1a27be = _0x2bc8fb - 320 - _0x5025ec + (typeof o !== 'undefined' ? o : 0); + } else if (_0x2bc8fb < _0x1f7976 - _0x259956) { + _0x1a27be = _0x2bc8fb - 320 + _0x259956 + (typeof o !== 'undefined' ? o : 0); + } + } else { + if (_0x2bc8fb > _0x1f7976 + _0x259956) { + _0x1a27be = _0x2bc8fb - 320 - _0x259956 + (typeof o !== 'undefined' ? o : 0); + } else if (_0x2bc8fb < _0x1f7976 - _0x5025ec) { + _0x1a27be = _0x2bc8fb - 320 + _0x5025ec + (typeof o !== 'undefined' ? o : 0); + } + } + } + if (_0x1a27be < 0) { + _0x1a27be = 0; + } + if (snap) { + this._cameraY = _0x1a27be; + } else if (_0xc7c517 !== 0) { + explosionPiece += (_0x1a27be - explosionPiece) / (10 / _0xc7c517); + if (explosionPiece < 0) { + explosionPiece = 0; + } + this._cameraY = explosionPiece; + } + } + _quantizeDelta(_0x654f39) { + const speed = window.speedHack || 1; + let _0x578d1b = (_0x654f39 * speed) / 1000 + this._deltaBuffer; + let _0x53e02e = Math.round(_0x578d1b / u); + if (_0x53e02e < 0) { + _0x53e02e = 0; + } + if (_0x53e02e > 60) { + _0x53e02e = 60; + } + let _0xd8019e = _0x53e02e * u; + this._deltaBuffer = _0x578d1b - _0xd8019e; + return _0xd8019e * 60; + } + update(_0x54fa47, deltaTime) { + if (window.isEditor) { + if (this._editorPlaytestActive && !this._editorPlaytestPaused) { + this._levelEditor._updateEditorPlaytest(deltaTime); + this._levelEditor._updateEditorGrid(); + this._levelEditor._updateEditorTimeline(); + return; + } + + if (window.isEditorPause) return; + const pointer = this.input.activePointer; + this._hitObjects = this.input.hitTestPointer(pointer); + this._levelEditor._handleEditorCamera(deltaTime); + this._levelEditor._updateEditorGrid(); + if (pointer.isDown && !this._isDraggingSlider) { + if (this._isSwipeEnabled) { + if (this._editorTab !== "edit") { + if (this._hitObjects.length !== 0) return; + const currentGridX = Math.floor((pointer.x + this._cameraX) / 60) * 60; + const currentGridY = Math.floor((pointer.y + this._cameraY + 20) / 60) * 60; + + if (currentGridX !== this._lastSwipeGridX || currentGridY !== this._lastSwipeGridY) { + this._levelEditor._editorAction(); + this._lastSwipeGridX = currentGridX; + this._lastSwipeGridY = currentGridY; + } + } + } else { + if (!this._isDragging && this._hitObjects.length !== 0) return; + const dragX = pointer.x - this._clickStartPos.x; + const dragY = pointer.y - this._clickStartPos.y; + const dragDistance = Math.sqrt(dragX * dragX + dragY * dragY); + if (dragDistance > 10) { + this._isDragging = true; + this._cameraX = this._cameraStartX - dragX; + this._cameraY = this._cameraStartY - dragY; + } + } + } + this._levelEditor._updateEditorTimeline(); + if (this._editorPlaytestActive && this._editorPlaytestPaused) { + this._levelEditor._refreshEditorPlaytestGlowVisibility(); + this._levelEditor._syncEditorPlaytestPlayerVisual(deltaTime / 1000); + } + return; + } + + let rawPercent = (this._playerWorldX / this._level.endXPos) * 100; + rawPercent = Math.min(100, Math.max(0, rawPercent)); + let displayValue; + if (this._levelWon) { + const p = this._interpolatedPercent || 0; + if (window.percentageDecimals) { + displayValue = p.toFixed(2) + "%"; + } else { + displayValue = Math.floor(p) + "%"; + } + } else if (window.percentageDecimals) { + displayValue = rawPercent.toFixed(2) + "%"; + } else { + displayValue = Math.floor(rawPercent) + "%"; + } + this._percentageLabel.setText(displayValue); + this._percentageLabel.setVisible(window.showPercentage && !this._menuActive); + this._startPosGui.setVisible(window.startPosSwitcher && !this._menuActive); + this._noclipIndicator.setVisible(window.noClip && !this._menuActive); + this._accuracyIndicator.setVisible(window.noClip && window.noClipAccuracy && !this._menuActive); + this._deathsIndicator.setVisible(window.noClip && window.noClipAccuracy && !this._menuActive); + this._accuracyIndicator.setText(`${this._player.noclipStats.accuracy.toFixed(2)}%`); + this._deathsIndicator.setText(`${this._player.noclipStats.deaths} Deaths`); + + this._cpsIndicator.setVisible(window.showCPS && !this._menuActive); + if (this._clickHistory && this._clickHistory.length > 0) { + this._clickHistory = this._clickHistory.filter(timestamp => this.time.now - timestamp <= 1000); + this._cpsIndicator.setText(`${this._clickHistory.length} CPS`); + } else { + this._cpsIndicator.setText("0 CPS"); + } + if (this._state.upKeyDown){ + this._cpsIndicator.setTint(0x00ff00); + } else{ + this._cpsIndicator.setTint(0xffffff); + } + this._cpsIndicator.setPosition(10, 10 + (window.noClip * 20) + (window.noClip && window.noClipAccuracy * 40)); + + this._bottedIndicator.setVisible(this._macroBot?.playing); + this._bottedIndicator.setPosition(10, 10 + (window.noClip * 20) + (window.noClip && window.noClipAccuracy * 40) + (window.showCPS * 20)); + if (this._macroBtn){ + this._macroBtn.setVisible(window.macroBot); + } + + this._fpsAccum += deltaTime; + this._fpsFrames++; + if (this._fpsAccum >= 250) { + this._fpsText.setText(Math.round(this._fpsFrames * 1000 / this._fpsAccum)); + this._fpsAccum = 0; + this._fpsFrames = 0; + } + if (this._paused) { + if (!this._updateLogPopup && (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown) && !this._spaceWasDown && !this._settingsPopup) { + setTimeout(() => { + this._resumeGame(); + }, 75); + } + this._deltaBuffer = 0; + return; + } + if (this._menuActive) { + const _anyOverlayOpen = this._iconOverlay || this._creatorOverlay || this._searchOverlay || + this._onlineLevelsOverlay || this._settingsLayerOverlay || this._settingsPopup || + this._infoPopup || this._newgroundsPopup || this._statsLayerOverlay || this._updateLogPopup; + if (!_anyOverlayOpen && (this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown) && !this._spaceWasDown) { + if (this._creatorMenuOpen) return; + this._spaceWasDown = true; + if (this._levelSelectOverlay) { + if (this._levelSelectIsComingSoonPage) { + return; + } + this._creatorMenuOpen; + this.input.enabled = false; + + const lvl = window.currentlevel; + const songID = lvl[0]; + const levelFileName = lvl[2]; + const songFileName = lvl[4] ? lvl[4] : lvl[1].replaceAll(" ", ""); + + const loadingText = this.add.bitmapText( + screenWidth / 2, screenHeight / 2, "goldFont", "Downloading Level Assets...", 20 + ).setOrigin(0.5).setDepth(200); + + this.load.text(levelFileName, "assets/levels/" + levelFileName.split("_")[1] + ".txt"); + this.load.audio(songID, "assets/music/" + songFileName + ".mp3"); + + this.load.once("complete", () => { + loadingText.destroy(); + this._audio.playEffect("playSound_01", { volume: 1 }); + this._closeLevelSelect(true); + this._audio.stopMusic(); + this.input.enabled = true; + this.game.registry.set("autoStartGame", true); + this.scene.restart(); + }); + + this.load.start(); + return; + } + this._openLevelSelect(); + return; + } + const _arrowLeft = this._leftKey.isDown || this._aKey.isDown; + const _arrowRight = this._rightKey.isDown || this._dKey.isDown; + if (!_anyOverlayOpen && (_arrowLeft || _arrowRight) && !this._arrowWasDown) { + if (this._levelSelectOverlay) { + if (_arrowLeft) window.leftbuttoncallback(); + else window.rightbuttoncallback(); + } + } + this._arrowWasDown = _arrowLeft || _arrowRight; + this._spaceWasDown = this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown; + const menuDelta = Math.min(deltaTime / 1000 * 60, 2); + const menuSpeed = 0.85; + this._menuCameraX = (this._menuCameraX || 0) + menuDelta * playerSpeed * d * menuSpeed; + const _0x38afac = this._cameraX; + this._cameraX = this._menuCameraX; + this._updateBackground(); + this._cameraX = _0x38afac; + this._prevCameraX = this._menuCameraX; + this._cameraXRef._v = this._menuCameraX; + this._level.stepGroundAnimation(deltaTime / 1000); + this._level.updateGroundTiles(this._cameraY); + if (this._menuRainbowTime === undefined) this._menuRainbowTime = 0; + this._menuRainbowTime += deltaTime / 1000; + const _rainbowHue = (this._menuRainbowTime * 15) % 360; + const _rainbowHex = Phaser.Display.Color.HSVToRGB(_rainbowHue / 360, 0.85, 1.0).color; + const _groundHex = Phaser.Display.Color.HSVToRGB(_rainbowHue / 360, 0.85, 1.0).color; + this._bg.setTint(_rainbowHex); + this._level.setGroundColor(_groundHex); + this._level.setGround2Color?.(_groundHex); + return; + } + if (this._slideIn) { + const slideDelta = this._quantizeDelta(deltaTime); + this._playerWorldX += slideDelta * playerSpeed * d; + const slideGroundSpeed = 0.25; + this._slideGroundX = (this._slideGroundX || this._cameraX) + slideDelta * playerSpeed * d * slideGroundSpeed; + this._cameraXRef._v = this._slideGroundX; + const slidePlayerScreenX = this._playerWorldX - this._cameraX; + this._player.updateGroundRotation(slideDelta * d); + this._player.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(slidePlayerScreenX)); + this._level.additiveContainer.x = -this._cameraX; + this._level.additiveContainer.y = this._cameraY; + this._level.container.x = -this._cameraX; + this._level.container.y = this._cameraY; + this._level.topContainer.x = -this._cameraX; + this._level.topContainer.y = this._cameraY; + this._level.updateVisibility(this._cameraX); + this._level.updateObjectDebugIds(); + this._updateBackground(); + this._level.stepGroundAnimation(deltaTime / 1000); + this._level.updateGroundTiles(this._cameraY); + this._applyMirrorEffect(); + if (this._playerWorldX >= 0) { + this._slideIn = false; + this._deltaBuffer = 0; + this._playerWorldX = 0; + this._cameraX = this._playerWorldX - centerX; + this._cameraXRef._v = this._cameraX; + const _0x490749 = this._cameraX - this._slideGroundX; + this._level.shiftGroundTiles(_0x490749); + if (this._firstPlay) { + this._firstPlay = false; + this._audio.startMusic(); + } + this._pauseBtn.setVisible(true).setAlpha(0); + this.tweens.add({ + targets: this._pauseBtn, + alpha: 75 / 255, + duration: 500 + }); + if (this._practiceModeBarContainer) { + this._practiceModeBarContainer.setVisible(this._practicedMode && this._practicedMode.practiceMode); + } + } + return; + } + this._applyJumpInput = () => { + const jumpHeld = this._spaceKey.isDown || this._upKey.isDown || this._wKey.isDown || this._lKey.isDown; + if (!this._updateLogPopup && jumpHeld && !this._spaceWasDown) { + this._pushButton(); + } else if (!jumpHeld && this._spaceWasDown) { + this._releaseButton(); + } + this._spaceWasDown = jumpHeld; + }; + + const objectsUnderPointer = this.input.manager.hitTest( + this.input.activePointer, + this._startPosGui.list, + this.cameras.main + ); + const isOverUI = objectsUnderPointer.length > 0; + const fromClick = this.input.activePointer.isDown; + const cancelInput = isOverUI && fromClick; + + if (!!this.input.activePointer.isDown && !this._state.upKeyDown && !this._state.isDead) { + this._state.upKeyDown = true; + this._state.queuedHold = true; + this._state._orbActivationConsumedForPress = false; + } + if (cancelInput) { + this._state.upKeyDown = false; + this._state.upKeyPressed = false; + this._state.queuedHold = false; + this._state._orbActivationConsumedForPress = false; + } + this._level.updateEndPortalY(this._cameraY, this._state.isFlying || this._state.isWave || this._state.isUfo || this._state.isSpider); + if (!this._levelWon && !this._state.isDead && this._level.endXPos > 0) { + const _0x448396 = 600; + if (this._playerWorldX >= this._level.endXPos - _0x448396) { + this._levelWon = true; + this._endPortalGameY = this._level._endPortalGameY || 240; + this._triggerEndPortal(); + } + } + if (this._levelWon) { + this._deltaBuffer = 0; + if (this._endCamTween) { + const visMaxSection = this._endCamTween; + this._cameraX = visMaxSection.fromX + (visMaxSection.toX - visMaxSection.fromX) * visMaxSection.p; + this._cameraY = visMaxSection.fromY + (visMaxSection.toY - visMaxSection.fromY) * visMaxSection.p; + } + this._cameraXRef._v = this._cameraX; + this._level.additiveContainer.x = -this._cameraX; + this._level.additiveContainer.y = this._cameraY; + this._level.container.x = -this._cameraX; + this._level.container.y = this._cameraY; + this._level.topContainer.x = -this._cameraX; + this._level.topContainer.y = this._cameraY; + this._updateBackground(); + this._level.stepGroundAnimation(deltaTime / 1000); + this._level.updateGroundTiles(this._cameraY); + this._applyMirrorEffect(); + return; + } + if (this._state.isDead) { + if (!this._deathSoundPlayed) { + if (!this._practicedMode.practiceMode) { + this._audio.stopMusic(); + } + this._audio.playEffect("explode_11", { + volume: 0.65 * this._sfxVolume + }); + this._deathSoundPlayed = true; + this._totalDeaths++; + localStorage.setItem("gd_totalDeaths", this._totalDeaths); + } + if (!this._newBestShown) { + this._newBestShown = true; + let _0x435587 = this._level.endXPos || 6000; + let _0x169d53 = this._playerWorldX; + this._lastPercent = Math.min(99, Math.max(0, Math.floor(_0x169d53 / _0x435587 * 100))); + if (this._lastPercent > this._bestPercent && !this._practicedMode.practiceMode) { + this._bestPercent = this._lastPercent; + localStorage.setItem("bestPercent_" + (window.currentlevel[2] || "level_1"), this._bestPercent); + this._hadNewBest = true; + this._showNewBest(); + } + if (this._practicedMode.practiceMode) { + const pracKey = "practiceBestPercent_" + (window.currentlevel[2] || "level_1"); + const prevPracticeBest = parseFloat(localStorage.getItem(pracKey) || "0"); + if (this._lastPercent > prevPracticeBest) { + localStorage.setItem(pracKey, this._lastPercent); + this._practiceBestPercent = this._lastPercent; + if (this._updatePracticeHUDBar) this._updatePracticeHUDBar(); + } + } + } + this._player?.updateExplosionPieces?.(deltaTime); + if (this._isDual) { + this._player2?.updateExplosionPieces?.(deltaTime); + } + if (this._player?._hitboxGraphics) { + if (window.showHitboxes || window.hitboxesOnDeath) { + this._player.drawHitboxes(this._player._hitboxGraphics, this._cameraX, this._cameraY); + } else { + this._player._hitboxGraphics.clear(); + } + } + if (this._isDual && this._player2?._hitboxGraphics) { + if (window.showHitboxes || window.hitboxesOnDeath) { + this._player2.drawHitboxes(this._player2._hitboxGraphics, this._cameraX, this._cameraY); + } else { + this._player2._hitboxGraphics.clear(); + } + } + this._deathTimer += deltaTime; + let _0x237728 = this._hadNewBest ? 1400 : 1000; + if (this._deathTimer > _0x237728) { + if (this._practicedMode.practiceMode) { + this._respawnFromCheckpoint(); + } else { + this._restartLevel(); + } + } + return; + } + this._playTime += deltaTime / 1000; + this._audio.update(deltaTime / 1000); + + window._animTimer += deltaTime; + for (let _as of window._animatedSprites) { + if (window._animTimer - (_as._lastAnimSwap || 0) >= _as._animInterval) { + _as._lastAnimSwap = window._animTimer; + _as._animIdx = (_as._animIdx + 1) % _as._animFrames.length; + let _fr = getAtlasFrame(_as._animScene, _as._animFrames[_as._animIdx]); + if (_fr) { + try { + _as.setTexture(_fr.atlas, _fr.frame); + } catch(e){} + } + } + } + if (this._level && this._level._sawSprites) { + const sawRotation = deltaTime * 0.003; + for (let _saw of this._level._sawSprites) { + if (_saw && _saw.active) _saw.rotation += sawRotation; + } + } + this._level.updateAudioScale(this._audio.getMeteringValue()); + if (!this._orbGfx) { + this._orbGfx = this.add.graphics().setDepth(54).setBlendMode(S); + } + this._orbParticleAngle = ((this._orbParticleAngle || 0) + deltaTime * 0.004) % (Math.PI * 2); + this._orbGfxTimer = (this._orbGfxTimer || 0) + deltaTime; + if (this._orbGfxTimer > 33) { + this._orbGfxTimer = 0; + this._orbGfx.clear(); + if (this._level && this._level._orbSprites && this._level.container) { + try { + let _drawn = 0; + const _orbTypeColorMap = { + 36: 0xfffb57, + 84: 0x58ffff, + 141: 0xff52f0, + 444: 0xff00d2, + 1022: 0x63ff5f, + 1330: 0xffffff, + 1333: 0xff6326, + 1594: 0x6cff6b, + 1704: 0x04ff04, + 1751: 0xff00d2 + }; + for (let _oSpr of this._level._orbSprites) { + if (_drawn >= 4) break; + if (!_oSpr || !_oSpr.visible || !_oSpr.active || !_oSpr.scene) continue; + const _sx = _oSpr.x + this._level.container.x; + const _sy = _oSpr.y + this._level.container.y; + if (_sx < -40 || _sx > screenWidth + 40 || _sy < -40 || _sy > screenHeight + 40) continue; + _drawn++; + const _orbTypeTint = _orbTypeColorMap[_oSpr._orbId]; + for (let _pi = 0; _pi < 5; _pi++) { + const _orbitSpeed = 0.7 + (_pi % 3) * 0.35; + const _orbitR = 34 + (_pi * 5 % 17); + const _ang = this._orbParticleAngle * _orbitSpeed + (_pi * Math.PI * 2 / 5); + const _px = _sx + Math.cos(_ang) * _orbitR; + const _py = _sy + Math.sin(_ang) * (_orbitR * 0.85); + const _size = (window.orbParticleSize || 3.5) + (_pi % 3) * 1.0; + const _alpha = 0.5 + (_pi % 4) * 0.12; + this._orbGfx.fillStyle(_orbTypeTint, _alpha); + this._orbGfx.fillRect(_px - _size, _py - _size, _size * 2, _size * 2); + } + } + } catch(e) {} + } + } + let quantizedDelta = this._quantizeDelta(deltaTime); + let subSteps = quantizedDelta > 0 ? Math.max(1, Math.round(quantizedDelta * 4)) : 0; + if (subSteps > 60) { + subSteps = 60; + } + let subStepDelta = subSteps > 0 ? quantizedDelta / subSteps : 0; + let verticalDelta = subStepDelta * d; + let horizontalDelta = subStepDelta * playerSpeed * d; + const initialY = this._state.y; + const initialY2 = this._state2.y; + for (let i = 0; i < subSteps; i++) { + this._state.lastY = this._state.y; + this._physicsFrame++; + this._applyJumpInput(); + if (this._macroBot?.playing) { + this._macroBot.step(this._physicsFrame); + } + const _dualInputState = { + upKeyDown: this._state.upKeyDown, + upKeyPressed: this._state.upKeyPressed, + queuedHold: this._state.queuedHold, + orbActivationConsumedForPress: !!this._state._orbActivationConsumedForPress + }; + const _primaryGravityBefore = !!this._state.gravityFlipped; + const _primarySharedBefore = this._getDualSharedSignature(this._state); + this._player.updateJump(verticalDelta); + this._state.y += this._state.yVelocity * verticalDelta; + this._player.checkCollisions(this._playerWorldX - centerX); + const _primaryGravityChanged = this._isDual && !!this._state.gravityFlipped !== _primaryGravityBefore; + let _primaryGravitySynced = false; + if (this._isDual && this._getDualSharedSignature(this._state) !== _primarySharedBefore) { + _primaryGravitySynced = this._syncDualGlobalsFromPrimary({ + skipBallInputGravity: _primaryGravityChanged && this._state.isBall && _dualInputState.upKeyPressed, + skipSpiderInputGravity: _primaryGravityChanged && this._state.isSpider && _dualInputState.upKeyPressed, + skipSwingInputGravity: _primaryGravityChanged && this._state.isSwing && _dualInputState.upKeyPressed + }); + } + if (this._isDual && this._state.isDead && !this._state2.isDead) { + this._player2.killPlayer(); + } + this._playerWorldX += horizontalDelta; + if (this._isDual && !this._state2.isDead) { + this._copyDualInputFlags(_dualInputState, this._state2); + if (this._shouldSuppressDualGravityAction(this._state2, _primaryGravitySynced)) { + this._state2.upKeyPressed = false; + this._state2.queuedHold = false; + } + this._state2.lastY = this._state2.y; + const _secondarySharedBefore = this._getDualSharedSignature(this._state2); + const _secondaryBallInputGravity = this._state2.isBall && this._state2.upKeyPressed; + const _secondarySpiderInputGravity = this._state2.isSpider && this._state2.upKeyPressed; + const _secondarySwingInputGravity = this._state2.isSwing && this._state2.upKeyPressed; + this._player2.updateJump(verticalDelta); + this._state2.y += this._state2.yVelocity * verticalDelta; + this._player2.checkCollisions(this._playerWorldX - centerX - horizontalDelta); + if (this._isDual && !this._state2.isDead && this._getDualSharedSignature(this._state2) !== _secondarySharedBefore) { + this._syncDualGlobalsFromSecondary({ + skipBallInputGravity: _secondaryBallInputGravity, + skipSpiderInputGravity: _secondarySpiderInputGravity, + skipSwingInputGravity: _secondarySwingInputGravity + }); + } + this._resolveDualBallOverlap(); + if (this._isDual && this._state2.isDead && !this._state.isDead) { + this._player.killPlayer(); + } + if (this._isDual && this._state.isDead && !this._state2.isDead) { + this._player2.killPlayer(); + } + if (this._isDual) this._ensureDualFlyBounds(); + } + if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && !this._state.isSwing) { + if (this._state.isBall) { + const ballOnSurface = this._state.onGround || this._state.onCeiling; + this._player.updateBallRoll(horizontalDelta, ballOnSurface); + } else if (this._state.onGround) { + this._player.updateGroundRotation(verticalDelta); + } else if (this._player.rotateActionActive) { + this._player.updateRotateAction(u); + } else if (this._state.isDashing) { + this._player.updateDashRotation(u); + } + } + if (this._isDual && !this._state2.isDead && !this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && !this._state2.isSwing) { + if (this._state2.isBall) { + const ball2OnSurface = this._state2.onGround || this._state2.onCeiling; + this._player2.updateBallRoll(horizontalDelta, ball2OnSurface); + } else if (this._state2.onGround) { + this._player2.updateGroundRotation(verticalDelta); + } else if (this._player2.rotateActionActive) { + this._player2.updateRotateAction(u); + } else if (this._state2.isDashing) { + this._player2.updateDashRotation(u); + } + } + + if (!this._player._scene._slideIn){ + if (!this._player._hitboxTrail) this._player._hitboxTrail = []; + if (!this._player.p.isDead) { + const _trailSize = this._player.p.isMini ? 18 : 30; + this._player._hitboxTrail.push({ x: this._playerWorldX, y: this._player.p.y, rotation: this._player._rotation, size: _trailSize, isWave: this._player.p.isWave }); + if (this._player._hitboxTrail.length > 180) this._player._hitboxTrail.shift(); + } + if (this._isDual && !this._player2.p.isDead) { + if (!this._player2._hitboxTrail) this._player2._hitboxTrail = []; + const _trailSize2 = this._player2.p.isMini ? 18 : 30; + this._player2._hitboxTrail.push({ x: this._playerWorldX, y: this._player2.p.y, rotation: this._player2._rotation, size: _trailSize2, isWave: this._player2.p.isWave }); + if (this._player2._hitboxTrail.length > 180) this._player2._hitboxTrail.shift(); + } + } + } + this._state.lastY = initialY; + if (this._isDual) this._state2.lastY = initialY2; + this._state.ignorePortals = false; + this._state2.ignorePortals = false; + if (!this._endCameraOverride) { + const cameraOffsetX = this._playerWorldX - centerX; + if (this._level.endXPos > 0) { + const maxCameraX = this._level.endXPos - screenWidth; + if (cameraOffsetX >= maxCameraX - 200) { + this._endCameraOverride = true; + this._cameraX = cameraOffsetX; + const endCameraY = -140 + (this._level._endPortalGameY || 240); + const easingPower = 1.8; + const easeInOutCubic = t => t < 0.5 ? Math.pow(t * 2, easingPower) / 2 : 1 - Math.pow((1 - t) * 2, easingPower) / 2; + this._endCamTween = { + p: 0, + fromX: this._cameraX, + toX: maxCameraX, + fromY: this._cameraY, + toY: endCameraY + }; + this.tweens.add({ + targets: this._endCamTween, + p: 1, + duration: 1200, + ease: easeInOutCubic + }); + } else { + this._cameraX = cameraOffsetX; + } + } else { + this._cameraX = cameraOffsetX; + } + } + if (this._endCameraOverride && this._endCamTween) { + const tween = this._endCamTween; + this._cameraX = tween.fromX + (tween.toX - tween.fromX) * tween.p; + this._cameraY = tween.fromY + (tween.toY - tween.fromY) * tween.p; + } + this._cameraXRef._v = this._cameraX; + if (!this._endCameraOverride) { + this._updateCameraY(quantizedDelta); + } + this._level.additiveContainer.x = -this._cameraX; + this._level.additiveContainer.y = this._cameraY; + this._level.container.x = -this._cameraX; + this._level.container.y = this._cameraY; + this._level.topContainer.x = -this._cameraX; + this._level.topContainer.y = this._cameraY; + let playerX = this._playerWorldX; + const applyColorTrigger = (colorTrigger) => { + this._colorManager.triggerColor(colorTrigger.index, colorTrigger.color, colorTrigger.duration); + if (colorTrigger.tintGround) { + this._colorManager.triggerColor(gs, colorTrigger.color, colorTrigger.duration); + } + }; + for (let colorTrigger of this._level.checkColorTriggers(playerX)) { + applyColorTrigger(colorTrigger); + } + if (this._level.checkTouchColorTriggers) { + for (let colorTrigger of this._level.checkTouchColorTriggers(playerX, this._state.y)) { + applyColorTrigger(colorTrigger); + } + if (this._isDual && !this._state2.isDead) { + for (let colorTrigger of this._level.checkTouchColorTriggers(playerX, this._state2.y)) { + applyColorTrigger(colorTrigger); + } + } + } + this._level.checkMoveTriggers(playerX); + this._level.checkSpawnTriggers(playerX); + if (this._level.checkTouchSpawnTriggers) { + this._level.checkTouchSpawnTriggers(playerX, this._state.y); + if (this._isDual && !this._state2.isDead) { + this._level.checkTouchSpawnTriggers(playerX, this._state2.y); + } + } + if (this._level.checkTouchMoveTriggers) { + this._level.checkTouchMoveTriggers(playerX, this._state.y); + if (this._isDual && !this._state2.isDead) { + this._level.checkTouchMoveTriggers(playerX, this._state2.y); + } + } + this._level.stepMoveTriggers(deltaTime / 1000); + this._level.stepSpawnTriggers(deltaTime / 1000, this._colorManager); + this._level.checkAlphaTriggers(playerX); + this._level.stepAlphaTriggers(deltaTime / 1000); + this._level.checkRotateTriggers(playerX); + this._level.stepRotateTriggers(deltaTime / 1000); + this._level.checkPulseTriggers(playerX); + this._level.stepPulseTriggers(deltaTime / 1000, this._colorManager); + this._colorManager.step(deltaTime / 1000); + this._level.applyColorChannels(this._colorManager); + this._bg.setTint(this._colorManager.getHex(fs)); + this._level.setGroundColor(this._colorManager.getHex(gs)); + this._level.setGround2Color?.(this._colorManager.getHex(1009)); + this._level.updateVisibility(this._cameraX); + this._level.updateObjectDebugIds(); + this._level.checkEnterEffectTriggers(playerX); + this._level.applyEnterEffects(this._cameraX); + this._glitterCenterX = this._cameraX + screenWidth / 2; + this._glitterCenterY = T - this._cameraY; + this._updateBackground(); + this._level.stepGroundAnimation(deltaTime / 1000); + this._level.updateGroundTiles(this._cameraY); + if (this._state.isFlying) { + this._player.updateShipRotation(quantizedDelta); + } + if (this._isDual && this._state2.isFlying && !this._state2.isDead) { + this._player2.updateShipRotation(quantizedDelta); + } + const playerScreenX = this._playerWorldX - this._cameraX; + this._player.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(playerScreenX)); + if (this._isDual && !this._state2.isDead) { + this._player2.syncSprites(this._cameraX, this._cameraY, deltaTime / 1000, this._getMirrorXOffset(playerScreenX)); + } + this._applyMirrorEffect(); + } + +_applyMirrorEffect() { + const isMirrored = this._state.mirrored; + const containers = [this._level.additiveContainer, this._level.container, this._level.topContainer]; + if (isMirrored) { + for (const c of containers) { + c.scaleX = -1; + c.x = this._cameraX + screenWidth; + } + for (const tile of this._level._groundTiles) { + tile.x = screenWidth - tile.x - this._level._tileW; + tile.setFlipX(true); + } + for (const tile of this._level._ceilingTiles) { + tile.x = screenWidth - tile.x - this._level._tileW; + tile.setFlipX(true); + } + } else { + for (const c of containers) { + if (c.scaleX !== 1) c.scaleX = 1; + } + for (const tile of this._level._groundTiles) { + tile.setFlipX(false); + } + for (const tile of this._level._ceilingTiles) { + tile.setFlipX(false); + } + } + this._bg.setFlipX(isMirrored); + } + _getDualSharedSignature(state) { + if (!state) return "0|0"; + return [ + state.gravityFlipped ? 1 : 0, + state.mirrored ? 1 : 0 + ].join("|"); + } + _getDualModeId(state) { + if (!state) return "cube"; + if (state.isFlying) return "ship"; + if (state.isBall) return "ball"; + if (state.isUfo) return "ufo"; + if (state.isWave) return "wave"; + if (state.isRobot) return "robot"; + if (state.isSpider) return "spider"; + if (state.isSwing) return "swing"; + return "cube"; + } + _getGamemodePortalMode(portalType) { + switch (portalType) { + case "portal_cube": + return "cube"; + case "portal_fly": + return "ship"; + case "portal_ball": + return "ball"; + case "portal_wave": + return "wave"; + case "portal_ufo": + return "ufo"; + case "portal_robot": + return "robot"; + case "portal_spider": + return "spider"; + case "portal_swing": + return "swing"; + default: + return null; + } + } + _setPlayerGamemode(player, state, mode, keepVelocity = true) { + if (!player || !state) return; + const currentMode = this._getDualModeId(state); + if (currentMode === mode) { + player.setCubeVisible(mode === "cube" || mode === "ufo"); + player.setShipVisible(mode === "ship"); + player.setBallVisible(mode === "ball"); + player.setWaveVisible(mode === "wave"); + player.setBirdVisible?.(mode === "ufo"); + player.setRobotVisible(mode === "robot"); + player.setSpiderVisible(mode === "spider"); + player.setSwingVisible(mode === "swing"); + return; + } + const saved = { + y: state.y, + yVelocity: state.yVelocity, + gravityFlipped: state.gravityFlipped, + upKeyDown: state.upKeyDown, + upKeyPressed: state.upKeyPressed, + queuedHold: state.queuedHold, + orbActivationConsumedForPress: !!state._orbActivationConsumedForPress, + mirrored: state.mirrored, + isMini: state.isMini + }; + switch (mode) { + case "ship": + player.enterShipMode({ y: saved.y, portalY: saved.y }, true); + break; + case "ball": + player.enterBallMode({ y: saved.y, portalY: saved.y }); + break; + case "ufo": + player.enterUfoMode({ y: saved.y, portalY: saved.y }, true); + break; + case "wave": + player.enterWaveMode({ y: saved.y, portalY: saved.y }); + break; + case "robot": + player.enterRobotMode({ y: saved.y, portalY: saved.y }); + break; + case "spider": + player.enterSpiderMode({ y: saved.y, portalY: saved.y }); + break; + case "swing": + player.enterSwingMode({ y: saved.y, portalY: saved.y }, true); + break; + default: + player.exitShipMode(); + player.exitBallMode(); + player.exitUfoMode(); + player.exitWaveMode(); + player.exitRobotMode(); + player.exitSpiderMode(); + player.exitSwingMode(); + state.isFlying = false; + state.isBall = false; + state.isUfo = false; + state.isWave = false; + state.isRobot = false; + state.isSpider = false; + state.isSwing = false; + player.setShipVisible(false); + player.setBallVisible(false); + player.setWaveVisible(false); + player.setBirdVisible?.(false); + player.setRobotVisible(false); + player.setSpiderVisible(false); + player.setSwingVisible(false); + player.setCubeVisible(true); + break; + } + state.y = saved.y; + if (keepVelocity && Number.isFinite(saved.yVelocity)) state.yVelocity = saved.yVelocity; + state.gravityFlipped = saved.gravityFlipped; + state.upKeyDown = saved.upKeyDown; + state.upKeyPressed = saved.upKeyPressed; + state.queuedHold = saved.queuedHold; + state._orbActivationConsumedForPress = !!saved.orbActivationConsumedForPress; + state.mirrored = saved.mirrored; + state.isMini = saved.isMini; + } + _getInitialDualPortalMode() { + if (!this._level || !this._player2 || !this._state2) return null; + + const worldX = Number(this._playerWorldX); + const worldY = Number(this._state2.y); + if (!Number.isFinite(worldX) || !Number.isFinite(worldY)) return null; + + const halfSize = this._state2.isWave + ? (this._state2.isMini ? 6 : 9) + : (this._state2.isMini ? 18 : 30); + + const previousWorldXRaw = Number(this._player?._lastCollisionWorldX); + const previousWorldYRaw = Number(this._player?._lastCollisionWorldY); + const previousWorldX = Number.isFinite(previousWorldXRaw) ? previousWorldXRaw : worldX; + const previousWorldY = Number.isFinite(previousWorldYRaw) + ? previousWorldYRaw + : (Number.isFinite(Number(this._state?.lastY)) ? Number(this._state.lastY) : worldY); + + const nearbyObjects = this._level.getNearbySectionObjects?.(worldX) || []; + const previousNearbyObjects = previousWorldX !== worldX + ? (this._level.getNearbySectionObjects?.(previousWorldX) || []) + : []; + const portalObjects = [...new Set([...nearbyObjects, ...previousNearbyObjects])]; + + let portalMode = null; + + for (const gameObj of portalObjects) { + const mode = this._getGamemodePortalMode(gameObj?.type); + if (!mode) continue; + + let touching = false; + + if (gameObj.hitbox_radius !== undefined && gameObj.hitbox_radius !== null) { + const radius = gameObj.hitbox_radius + halfSize; + const dx = worldX - gameObj.x; + const dy = worldY - gameObj.y; + touching = (dx * dx + dy * dy) <= radius * radius; + + if (!touching && (previousWorldX !== worldX || previousWorldY !== worldY)) { + const prevDx = previousWorldX - gameObj.x; + const prevDy = previousWorldY - gameObj.y; + touching = (prevDx * prevDx + prevDy * prevDy) <= radius * radius; + + if (!touching) { + const steps = Math.min( + 12, + Math.max(2, Math.ceil( + Math.max(Math.abs(worldX - previousWorldX), Math.abs(worldY - previousWorldY)) / Math.max(1, halfSize) + )) + ); + + for (let i = 1; i < steps; i++) { + const t = i / steps; + const sampleX = previousWorldX + (worldX - previousWorldX) * t; + const sampleY = previousWorldY + (worldY - previousWorldY) * t; + const sampleDx = sampleX - gameObj.x; + const sampleDy = sampleY - gameObj.y; + + if ((sampleDx * sampleDx + sampleDy * sampleDy) <= radius * radius) { + touching = true; + break; + } + } + } + } + } else if (typeof this._player2._isPlayerTouchingPortalHitbox === "function") { + touching = this._player2._isPlayerTouchingPortalHitbox( + gameObj, + worldX, + worldY, + halfSize, + previousWorldX, + previousWorldY + ); + } + + if (touching) portalMode = mode; + } + + return portalMode; + } + _copyDualInputFlags(fromState, toState) { + if (!fromState || !toState) return; + toState.upKeyDown = fromState.upKeyDown; + toState.upKeyPressed = fromState.upKeyPressed; + toState.queuedHold = fromState.queuedHold; + const fromConsumed = !!(fromState._orbActivationConsumedForPress ?? fromState.orbActivationConsumedForPress); + toState._orbActivationConsumedForPress = !!fromState.upKeyDown && (!!toState._orbActivationConsumedForPress || fromConsumed); + } + _shouldSuppressDualGravityAction(state, gravityAlreadySynced) { + return !!(gravityAlreadySynced && state && state.isBall && state.upKeyPressed); + } + _shouldSkipDualBallGravitySync(fromState, toState, options = {}) { + if (!fromState?.isBall || !toState) return false; + if (options.forceGravitySync) return false; + if (options.skipBallInputGravity) return true; + return !(toState.onGround || toState.onCeiling || toState.canJump); + } + _shouldSkipDualSpiderInputGravitySync(fromState, options = {}) { + if (!fromState?.isSpider) return false; + if (options.forceGravitySync) return false; + return !!options.skipSpiderInputGravity; + } + _shouldSkipDualSwingInputGravitySync(fromState, options = {}) { + if (!fromState?.isSwing) return false; + if (options.forceGravitySync) return false; + return !!options.skipSwingInputGravity; + } + _isDualBallOnSurface(state) { + return !!(state && (state.onGround || state.onCeiling || state.canJump)); + } + _areDualBallsOverlapping() { + if (!this._isDual || !this._state || !this._state2) return false; + if (this._state.isDead || this._state2.isDead) return false; + if (!this._state.isBall || !this._state2.isBall) return false; + const size1 = this._state.isMini ? 18 : 30; + const size2 = this._state2.isMini ? 18 : 30; + return Math.abs(this._state.y - this._state2.y) < (size1 + size2); + } + _flipDualBallForOverlap(player, state) { + if (!player || !state || !state.isBall) return false; + const flipMod = state.gravityFlipped ? -1 : 1; + state.yVelocity = flipMod * 22.360064 * (state.isMini ? 0.8 : 1); + player.flipGravity(!state.gravityFlipped); + state.onGround = false; + state.onCeiling = false; + state.canJump = false; + state.isJumping = false; + state.yVelocity *= 0.6; + return true; + } + _resolveDualBallOverlap() { + if (!this._areDualBallsOverlapping()) { + this._dualBallOverlapResolved = false; + this._dualBallSpawnGravityLock = false; + return false; + } + if (this._dualBallSpawnGravityLock) { + this._state2.gravityFlipped = !this._state.gravityFlipped; + this._dualBallOverlapResolved = true; + return false; + } + if (this._dualBallOverlapResolved) return false; + const primaryOnSurface = this._isDualBallOnSurface(this._state); + const secondaryOnSurface = this._isDualBallOnSurface(this._state2); + if (!primaryOnSurface && !secondaryOnSurface) return false; + + let flipped = false; + if (primaryOnSurface && !secondaryOnSurface) { + flipped = this._flipDualBallForOverlap(this._player2, this._state2); + } else if (secondaryOnSurface && !primaryOnSurface) { + flipped = this._flipDualBallForOverlap(this._player, this._state); + } else if (primaryOnSurface && secondaryOnSurface) { + flipped = this._flipDualBallForOverlap(this._player2, this._state2); + } + if (flipped) this._dualBallOverlapResolved = true; + return flipped; + } + _copyInitialDualModeFlags(fromState, toState) { + if (!fromState || !toState) return; + toState.isMini = fromState.isMini; + toState.mirrored = fromState.mirrored; + toState.gravityFlipped = !fromState.gravityFlipped; + this._copyDualInputFlags(fromState, toState); + } + _syncDualGlobalsFromPrimary(options = {}) { + if (!this._isDual || !this._state || !this._state2 || this._state2.isDead) return false; + let gravitySynced = false; + if (!this._shouldSkipDualBallGravitySync(this._state, this._state2, options) && !this._shouldSkipDualSpiderInputGravitySync(this._state, options) && !this._shouldSkipDualSwingInputGravitySync(this._state, options)) { + const nextGravity = !this._state.gravityFlipped; + this._state2.gravityFlipped = nextGravity; + gravitySynced = true; + } + this._state2.mirrored = this._state.mirrored; + this._ensureDualFlyBounds(); + return gravitySynced; + } + _syncDualGlobalsFromSecondary(options = {}) { + if (!this._isDual || !this._state || !this._state2 || this._state.isDead || this._state2.isDead) return false; + let gravitySynced = false; + if (!this._shouldSkipDualBallGravitySync(this._state2, this._state, options) && !this._shouldSkipDualSpiderInputGravitySync(this._state2, options) && !this._shouldSkipDualSwingInputGravitySync(this._state2, options)) { + const nextGravity = !this._state2.gravityFlipped; + this._state.gravityFlipped = nextGravity; + gravitySynced = true; + } + this._state.mirrored = this._state2.mirrored; + this._ensureDualFlyBounds(); + return gravitySynced; + } + _ensureDualFlyBounds(centerY = null) { + if (!this._isDual || !this._level) return; + const span = Number(typeof f !== "undefined" ? f : 480) || 480; + const floorY = this._level._flyFloorY; + const ceilingY = this._level._flyCeilingY; + const currentSpan = Number.isFinite(Number(floorY)) && Number.isFinite(Number(ceilingY)) ? Number(ceilingY) - Number(floorY) : null; + if (currentSpan === null || Math.abs(currentSpan - span) > 0.01 || !this._level._flyGroundActive) { + const y = Number.isFinite(Number(centerY)) ? Number(centerY) : (Number.isFinite(Number(this._state?.y)) ? Number(this._state.y) : 30); + this._level.setFlyMode(true, y, span, false); + } + } + _refreshFlyBoundsAfterDual() { + if (!this._level) return; + if (this._state.isFlying || this._state.isWave || this._state.isUfo || this._state.isSwing) { + this._level.setFlyMode(true, this._state.y, f, false); + } else if (this._state.isBall) { + this._level.setFlyMode(true, this._state.y, f - a * 2, false); + } else if (this._state.isSpider) { + const spiderBlockSize = typeof a !== "undefined" ? a : 30; + const spiderBaseHeight = typeof f !== "undefined" ? f : 480; + const spiderFlyHeight = Math.max(spiderBlockSize, spiderBaseHeight - spiderBlockSize); + this._level.setFlyMode(true, this._state.y, spiderFlyHeight, false, spiderFlyHeight); + } else { + this._level.setFlyMode(false, 0); + } + } + _killDualPlayers() { + if (this._state && !this._state.isDead) this._player.killPlayer(); + if (this._isDual && this._state2 && !this._state2.isDead) this._player2.killPlayer(); + } + + _getMirrorXOffset(xOffset) { + return this._state.mirrored ? screenWidth - xOffset : xOffset; + } + _enableDualMode() { + if (this._isDual) return; + this._isDual = true; + this._dualBallSpawnGravityLock = false; + this._dualBallOverlapResolved = false; + this._state2.reset(); + this._state2.isDead = false; + this._state2.yVelocity = this._state.yVelocity; + this._copyInitialDualModeFlags(this._state, this._state2); + this._ensureDualFlyBounds(this._state.y); + const primaryY = Number.isFinite(Number(this._state.y)) ? Number(this._state.y) : 30; + this._state2.y = primaryY; + this._state2.lastY = primaryY; + this._state2.lastGroundPosY = primaryY; + this._state2.onGround = false; + this._state2.onCeiling = false; + this._state2.canJump = false; + this._state2.isJumping = false; + this._player2.reset(); + this._player2.setInvertedColors?.(true); + this._setPlayerGamemode(this._player2, this._state2, this._getDualModeId(this._state), true); + this._copyInitialDualModeFlags(this._state, this._state2); + const initialPortalMode = this._getInitialDualPortalMode(); + if (initialPortalMode) this._setPlayerGamemode(this._player2, this._state2, initialPortalMode, true); + if (this._state.isBall && this._state2.isBall) { + this._state2.gravityFlipped = !this._state.gravityFlipped; + this._dualBallOverlapResolved = true; + this._dualBallSpawnGravityLock = true; + } + this._ensureDualFlyBounds(this._state.y); + if (this._player2 && this._player2._hitboxTrail) this._player2._hitboxTrail = []; + if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); + } + _disableDualMode() { + if (!this._isDual) return; + this._isDual = false; + this._dualBallOverlapResolved = false; + this._dualBallSpawnGravityLock = false; + this._state2.isDead = true; + this._state2.upKeyDown = false; + this._state2.upKeyPressed = false; + this._state2.queuedHold = false; + this._player2.setCubeVisible(false); + this._player2.setShipVisible(false); + this._player2.setBallVisible(false); + this._player2.setWaveVisible(false); + this._player2.setBirdVisible?.(false); + this._player2.setRobotVisible(false); + this._player2.setSpiderVisible(false); + this._player2.setSwingVisible(false); + if (this._player2?._hitboxGraphics) this._player2._hitboxGraphics.clear(); + if (this._player2 && this._player2._hitboxTrail) this._player2._hitboxTrail = []; + this._refreshFlyBoundsAfterDual(); + } + _showNewBest() { + let _0x9f2437 = screenWidth / 2; + let _0x12bde3 = this.add.image(0, 0, "GJ_WebSheet", "GJ_newBest_001.png").setOrigin(0.5, 1); + let _0x544c9c = this.add.bitmapText(0, 2, "bigFont", this._lastPercent + "%", 65).setOrigin(0.5, 0).setScale(1.1); + let _0x326cb9 = this.add.container(_0x9f2437, 300, [_0x12bde3, _0x544c9c]).setScrollFactor(0).setDepth(60).setScale(0.01); + this.tweens.add({ + targets: _0x326cb9, + scale: 1, + duration: 400, + ease: "Elastic.Out", + easeParams: [1, 0.6], + onComplete: () => { + this.tweens.add({ + targets: _0x326cb9, + scale: 0.01, + duration: 200, + delay: 700, + ease: "Quad.In", + onComplete: () => { + _0x326cb9.setVisible(false); + _0x326cb9.destroy(); + } + }); + } + }); + } + + _triggerEndPortal() { + if (this._isDual && this._player2 && this._state2 && !this._state2.isDead) { + this._player2.playEndAnimation(this._level.endXPos, () => {}, this._endPortalGameY); + } + this._player.playEndAnimation(this._level.endXPos, () => this._levelComplete(), this._endPortalGameY); + } + _levelComplete() { + if (!this._practicedMode.practiceMode) { + this._bestPercent = 100; + localStorage.setItem("bestPercent_" + (window.currentlevel[2] || "level_1"), 100); + const completedKey = "gd_completedSet"; + let completedSet; + try { completedSet = JSON.parse(localStorage.getItem(completedKey) || "[]"); } catch(e) { completedSet = []; } + const levelId = window.currentlevel[2] || "level_1"; + if (!completedSet.includes(levelId)) { + completedSet.push(levelId); + localStorage.setItem(completedKey, JSON.stringify(completedSet)); + window._completedLevels = completedSet.length; + localStorage.setItem("gd_completedLevels", window._completedLevels); + } + } else { + this._practiceBestPercent = 100; + localStorage.setItem("practiceBestPercent_" + (window.currentlevel[2] || "level_1"), 100); + if (this._updatePracticeHUDBar) this._updatePracticeHUDBar(); + } + + const _0x356782 = this._level.endXPos - this._cameraX; + const _0x2d967b = b(this._endPortalGameY) + this._cameraY; + for (let _0x481f7c = 0; _0x481f7c < 5; _0x481f7c++) { + this.time.delayedCall(_0x481f7c * 50, () => circleEffect(this, _0x356782, _0x2d967b, 10, screenWidth, 500, false, true, window.mainColor)); + } + circleEffect(this, _0x356782, _0x2d967b, 10, 1000, 500, true, false, window.mainColor); + this._showCompleteEffect(); + } + _showCompleteEffect() { + this._audio.fadeOutMusic(1500); + this.sound.play("endStart_02", { + volume: 0.8 * this._sfxVolume + }); + (function (_0x3f5321, _0x8f5267, _0x2f1e2d, _0x4b5e5b) { + const _0x29d856 = 2; + const _0x1b2543 = 8; + const _0x2cc21f = _0x29d856 * 1; + const _0x26b2b1 = _0x29d856 * 30; + const _0x6f49c1 = _0x29d856 * 20; + const _0x232789 = Math.round(Math.sqrt(screenWidth ** 2 + 102400)) + _0x29d856 * 32.5; + const _0x1c105b = 180; + const _0x586720 = 40; + const _0x57b9ff = 195; + const _0x2b6612 = 40; + const _0x5ce50e = 40; + const _0x4da54f = 155 / 255; + const _0x20decf = 100 / 255; + const _0x576e6f = 400; + const _0x487fb1 = -135; + const _0x323ded = 90 / _0x1b2543; + const _0x44369e = Array.from({ + length: _0x1b2543 + }, (_0x18e51d, _0x59ebd4) => _0x487fb1 + _0x59ebd4 * _0x323ded); + for (let _0x59890f = _0x44369e.length - 1; _0x59890f > 0; _0x59890f--) { + const _0x2bf73b = Math.floor(Math.random() * (_0x59890f + 1)); + [_0x44369e[_0x59890f], _0x44369e[_0x2bf73b]] = [_0x44369e[_0x2bf73b], _0x44369e[_0x59890f]]; + } + let _0x594d69 = 0; + const _0x116c8c = []; + for (let _0x104cbb = 0; _0x104cbb < _0x1b2543; _0x104cbb++) { + const _0x1a79fc = _0x104cbb * _0x57b9ff + _0x2b6612 + _0x5ce50e * (Math.random() * 2 - 1); + const _0x6eb03a = _0x26b2b1 + _0x6f49c1 * (Math.random() * 2 - 1); + const _0x2e9531 = _0x1c105b + _0x586720 * (Math.random() * 2 - 1); + const _0x28e7b3 = Math.min(1, Math.max(0, _0x4da54f + _0x20decf * (Math.random() * 2 - 1))); + const _0x34147c = _0x44369e[_0x104cbb] + _0x323ded * Math.random() + 180; + const containerY = _0x3f5321.add.graphics().setScrollFactor(0).setDepth(-1).setBlendMode(S).setPosition(_0x8f5267, _0x2f1e2d).setAngle(_0x34147c).setAlpha(_0x28e7b3).setVisible(false); + const _0x496d96 = { + h: 1, + w: _0x2cc21f + }; + _0x3f5321.time.delayedCall(Math.max(0, _0x1a79fc), () => { + containerY.setVisible(true); + _0x3f5321.tweens.add({ + targets: _0x496d96, + h: _0x232789, + w: _0x6eb03a, + duration: _0x2e9531, + ease: "Quad.Out", + onUpdate: () => { + const _0x2db3d7 = _0x2cc21f + (_0x496d96.w - _0x2cc21f) / 4; + containerY.clear(); + containerY.fillStyle(_0x4b5e5b, 1); + containerY.beginPath(); + containerY.moveTo(-_0x2db3d7 / 2, 0); + containerY.lineTo(_0x2db3d7 / 2, 0); + containerY.lineTo(_0x496d96.w / 2, _0x496d96.h); + containerY.lineTo(-_0x496d96.w / 2, _0x496d96.h); + containerY.closePath(); + containerY.fillPath(); + } + }); + }); + if (_0x1a79fc > _0x594d69) { + _0x594d69 = _0x1a79fc; + } + _0x116c8c.push(containerY); + } + _0x3f5321.time.delayedCall(_0x594d69 + _0x576e6f, () => { + for (const _0x15b95e of _0x116c8c) { + const _0x51b5fc = Math.random() * 200; + const _0x3ed1de = 400 + (Math.random() * 2 - 1) * 100; + _0x3f5321.tweens.add({ + targets: _0x15b95e, + alpha: 0, + delay: _0x51b5fc, + duration: _0x3ed1de, + onComplete: () => _0x15b95e.destroy() + }); + } + }); + })(this, this._level.endXPos - this._cameraX + 60, b(this._endPortalGameY) + this._cameraY, window.mainColor); + this.cameras.main.shake(1950, 0.004); + this.time.delayedCall(1950, () => this._showCompleteText()); + } + _showCompleteText() { + const _0x56628c = screenWidth / 2; + const _0x45ab26 = this._practicedMode.practiceMode + ? this.add.image(_0x56628c, 250, "GJ_GameSheet03", "GJ_practiceComplete_001.png").setScrollFactor(0).setDepth(60).setScale(0.01) + : this.add.image(_0x56628c, 250, "GJ_WebSheet", "GJ_levelComplete_001.png").setScrollFactor(0).setDepth(60).setScale(0.01); + this.tweens.add({ + targets: _0x45ab26, + scale: 1.1, + duration: 660, + ease: "Elastic.Out", + easeParams: [1, 0.6], + onComplete: () => { + this.tweens.add({ + targets: _0x45ab26, + scale: 0.01, + duration: 220, + delay: 880, + ease: "Quad.In", + onComplete: () => { + _0x45ab26.setVisible(false); + _0x45ab26.destroy(); + } + }); + } + }); + const _0x2884ff = [window.mainColor, 16777215]; + for (let _0x5f16c8 = 0; _0x5f16c8 < 2; _0x5f16c8++) { + this.add.particles(_0x56628c, 250, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 300, + max: 700 + }, + angle: { + min: 0, + max: 360 + }, + scale: { + start: 0.4, + end: 0.13 + }, + lifespan: { + min: 0, + max: 1000 + }, + quantity: 50, + stopAfter: 200, + blendMode: S, + tint: _0x2884ff[_0x5f16c8], + x: { + min: -800, + max: 800 + }, + y: { + min: -80, + max: 80 + } + }).setScrollFactor(0).setDepth(59); + } + const _0x2eadf2 = this._level.endXPos - this._cameraX; + const _0x380b24 = b(this._endPortalGameY) + this._cameraY; + circleEffect(this, _0x2eadf2, _0x380b24, 10, screenWidth, 800, true, false, window.mainColor); + circleEffect(this, _0x56628c, 250, 10, 1000, 800, true, false, window.mainColor); + for (let _0x579e05 = 0; _0x579e05 < 5; _0x579e05++) { + this.time.delayedCall(_0x579e05 * 50, () => circleEffect(this, _0x2eadf2, _0x380b24, 10, screenWidth, 500, false, true, window.mainColor)); + } + for (let _0x429722 = 0; _0x429722 < 10; _0x429722++) { + const _0xbf7dd0 = _0x429722 * 150 + (Math.random() * 160 - 80); + this.time.delayedCall(Math.max(0, _0xbf7dd0), () => particleEffect(this, window.mainColor, window.secondaryColor)); + } + this.time.delayedCall(1500, () => this._showEndLayer()); + } + _showEndLayer() { + if (this._pauseBtn) { + this.tweens.add({ + targets: this._pauseBtn, + alpha: 0, + duration: 300 + }); + } + const containerX = screenWidth / 2; + const _0x1aa656 = 320; + this._endLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); + this._endLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); + this.tweens.add({ + targets: this._endLayerOverlay, + alpha: 100 / 255, + duration: 1000 + }); + const _0x59b9ab = { + p: 0 + }; + this.tweens.add({ + targets: _0x59b9ab, + p: 1, + duration: 1000, + ease: "Bounce.Out", + onUpdate: () => { + this._endLayerInternal.y = _0x59b9ab.p * 650 - 640; + }, + onComplete: () => this._playStarAward() + }); + const _0x595215 = 712; + const _0x950c8d = 460; + const _0x2a115c = (screenWidth - _0x595215) / 2; + this._endLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0, 180 / 255)); + const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; + this._endLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); + this._endLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); + const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); + this._endLayerInternal.add(_0x33b564); + this._endLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); + const _0x3e9c79 = _0x33b564.y - 35; + this._endLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + this._endLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + const _completeBanner = this._practicedMode.practiceMode + ? this.add.image(containerX, 170, "GJ_GameSheet03", "GJ_practiceComplete_001.png").setScale(0.8) + : this.add.image(containerX, 170, "GJ_WebSheet", "GJ_levelComplete_001.png").setScale(0.8); + this._endLayerInternal.add(_completeBanner); + const _0x45b6e4 = 0.8; + let _0xe44f6d = 250; + const _0x2de55e = this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Attempts: " + this._levelAttempts, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4); + this._endLayerInternal.add(_0x2de55e); + _0xe44f6d += 48; + this._endLayerInternal.add(this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Jumps: " + this._levelJumps, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4)); + _0xe44f6d += 48; + const _0x596450 = Math.floor(this._playTime); + const _0x30687e = Math.floor(_0x596450 / 3600); + const _0x52f8ee = Math.floor(_0x596450 % 3600 / 60); + const _0x2591d0 = _0x596450 % 60; + let _0x2be782; + _0x2be782 = _0x30687e > 0 ? String(_0x30687e).padStart(2, "0") + ":" + String(_0x52f8ee).padStart(2, "0") + ":" + String(_0x2591d0).padStart(2, "0") : String(_0x52f8ee).padStart(2, "0") + ":" + String(_0x2591d0).padStart(2, "0"); + const _0x241209 = _0xe44f6d; + this._endLayerInternal.add(this.add.bitmapText(containerX, _0xe44f6d, "goldFont", "Time: " + _0x2be782, 40).setOrigin(0.5, 0.5).setScale(_0x45b6e4)); + const _0x452429 = ["Awesome!", "Good\nJob!", "Well\nDone!", "Impressive!", "Amazing!", "Incredible!", "Skillful!", "Brilliant!", "Not\nbad!", "Warp\nSpeed!", "Challenge\nBreaker!", "Reflex\nMaster!", "I am\nspeechless...", "You are...\nThe One!", "How is this\npossible!?", "You beat\nme..."]; + const _0x165c06 = _0x452429[Math.floor(Math.random() * _0x452429.length)]; + const _0x45540f = 225; + const _0x8e2b = ["\x5f\x6d\x61\x63\x72\x6f\x42\x6f\x74", "\x70\x6c\x61\x79\x69\x6e\x67"];let _0x3bc14 = 0xffffff; try {if (this[_0x8e2b[0]] && this[_0x8e2b[0]][_0x8e2b[1]]) {_0x3bc14 = (_0x3bc14 & 0xffff00) | 0xfa;}} catch (_0xe31) {}const _0x17fa2b = this.add.bitmapText(containerX + _0x45540f, _0x241209, "bigFont", _0x165c06, 40).setOrigin(0.5, 0.5).setScale(0.8).setCenterAlign();if (_0x3bc14 !== 0xffffff) _0x17fa2b.setTint(_0x3bc14); + this._endLayerInternal.add(_0x17fa2b); + this._endLayerInternal.add(this.add.image(containerX - _0x45540f, 352.5, "GJ_WebSheet", "getIt_001.png").setScale(1 / 1.5)); + const _0x34b1bd = [{ + key: "downloadApple_001", + url: "https://discord.gg/TfEzAVWPSJ" + }, { + key: "downloadSteam_001", + url: "https://github.com/web-dashers/web-dashers.github.io" + }]; + for (let _0x10f8cc = 0; _0x10f8cc < _0x34b1bd.length; _0x10f8cc++) { + const _0xd7310b = _0x34b1bd[_0x10f8cc]; + const _0x1e3f82 = (_0x10f8cc - 1) * _0x45540f; + const _0x55a82e = 1 / 1.5; + const _0x4c7fb8 = this.add.image(containerX + _0x1e3f82, 437.5, "GJ_WebSheet", _0xd7310b.key + ".png").setScale(_0x55a82e).setInteractive(); + this._endLayerInternal.add(_0x4c7fb8); + this._makeBouncyButton(_0x4c7fb8, _0x55a82e, () => window.open(_0xd7310b.url, "_blank")); + } + _0x2de55e.width; + this._endStarX = containerX + _0x45540f; + this._endStarY = _0x241209 - 77.5; + if (window.macroBot){ + const botMenuBtn = this.add.image(containerX - 225, 255, "macroBot").setScale(0.4).setInteractive(); + this._endLayerInternal.add(botMenuBtn); + this._makeBouncyButton(botMenuBtn, 0.4, () => { + this._buildMacroPopup(); + if (this._macroPopup) { + this._macroPopup.setDepth(300); + } + }); + } + const _0x45fc2b = [{ + frame: "GJ_replayBtn_001.png", + dx: -200, + action: () => this._hideEndLayer(() => this._restartLevel()) + }, { + frame: "GJ_menuBtn_001.png", + dx: 200, + action: () => { + this._audio.playEffect("quitSound_01"); + this._audio.stopMusic(); + this.game.registry.set("fadeInFromBlack", true); + this.cameras.main.fadeOut(400, 0, 0, 0, (_0x53bf86, _0x15310d) => { + if (_0x15310d >= 1) { + this.scene.restart(); + } + }); + } + }]; + for (const _0x2d4335 of _0x45fc2b) { + const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 555, "GJ_WebSheet", _0x2d4335.frame).setInteractive(); + this._endLayerInternal.add(_0xdde774); + this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); + } + } + _showSettingsScreen() { + this._settingsScreenClosing = false; + if (this._pauseBtn) { + this.tweens.add({ + targets: this._pauseBtn, + alpha: 0, + duration: 300 + }); + } + const containerX = screenWidth / 2; + const _0x1aa656 = 320; + this._settingsLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); + this._settingsLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); + this._settingsScreenClosing = false; + this.tweens.add({ + targets: this._settingsLayerOverlay, + alpha: 180 / 255, + duration: 400, + ease: "Linear" + }); + + const _0x59b9ab = { + p: 0 + }; + this.tweens.add({ + targets: _0x59b9ab, + p: 1, + duration: 500, + ease: "Quad.Out", + onUpdate: () => { + this._settingsLayerInternal.y = _0x59b9ab.p * 650 - 640; + }, + onComplete: () => {} + }); + const _0x595215 = 712; + const _0x950c8d = 460; + const _0x2a115c = (screenWidth - _0x595215) / 2; + this._settingsLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0, 180 / 255)); + const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; + this._settingsLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); + this._settingsLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); + const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); + this._settingsLayerInternal.add(_0x33b564); + this._settingsLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); + const _0x3e9c79 = _0x33b564.y - 35; + this._settingsLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + this._settingsLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + this._settingsLayerInternal.add(this.add.bitmapText(containerX, 65, "bigFont", "Settings", 55).setOrigin(0.5, 0.5)); + const _sBtnBorder = this.textures.get("GJ_button01").source[0].width * 0.3; + const _sBtnH = 62; + const _sBtnW2 = 310; + const _sBtnW3 = 200; + const _sGap = 18; + const _sColL = containerX - _sBtnW2 / 2 - _sGap / 2; + const _sColR = containerX + _sBtnW2 / 2 + _sGap / 2; + const _sCol3L = containerX - _sBtnW3 - _sGap; + const _sCol3M = containerX; + const _sCol3R = containerX + _sBtnW3 + _sGap; + const _sRow1Y = 155; + const _sRow2Y = 235; + const _sRow3Y = 312; + const _makeSettingsBtn = (cx, cy, label, btnW, isActive, action) => { + const grp = this.add.container(cx, cy); + const tint = isActive ? 0xffffff : 0x666666; + const btn9 = this.add.nineslice(0, 0, "GJ_button01", null, btnW, _sBtnH, _sBtnBorder, _sBtnBorder, _sBtnBorder, _sBtnBorder).setOrigin(0.5).setTint(tint); + grp.add(btn9); + const fontSize = label === "How To Play" ? 41 : 50; + const lbl = this.add.bitmapText(0, -5, "goldFont", label, fontSize).setOrigin(0.5, 0.5); + if (!isActive) lbl.setTint(0x666666); + grp.add(lbl); + if (isActive && action) { + const hitZone = this.add.zone(0, 0, btnW, _sBtnH).setInteractive(); + grp.add(hitZone); + const baseScale = 1; + const pressedScale = baseScale * 1.26; + hitZone.on("pointerdown", () => { + hitZone._pressed = true; + this.tweens.killTweensOf(grp, "scale"); + this.tweens.add({ targets: grp, scale: pressedScale, duration: 300, ease: "Bounce.Out" }); + }); + hitZone.on("pointerout", () => { + if (hitZone._pressed) { + hitZone._pressed = false; + this.tweens.killTweensOf(grp, "scale"); + this.tweens.add({ targets: grp, scale: baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + hitZone.on("pointerup", () => { + if (hitZone._pressed) { + hitZone._pressed = false; + this.tweens.killTweensOf(grp, "scale"); + grp.setScale(baseScale); + action(); + } + }); + } + this._settingsLayerInternal.add(grp); + return grp; + }; + + _makeSettingsBtn(_sColL, _sRow1Y, "Account", _sBtnW2, false, null); + _makeSettingsBtn(_sColR, _sRow1Y, "How To Play", _sBtnW2, true, () => { this._buildHowToPlayPopup(); }); + _makeSettingsBtn(_sColL, _sRow2Y, "Options", _sBtnW2, true, () => { this._buildSettingsPopup(); }); + _makeSettingsBtn(_sColR, _sRow2Y, "Graphics", _sBtnW2, false, null); + _makeSettingsBtn(_sCol3L, _sRow3Y, "Rate", _sBtnW3, false, null); + _makeSettingsBtn(_sCol3M, _sRow3Y, "Songs", _sBtnW3, false, null); + _makeSettingsBtn(_sCol3R, _sRow3Y, "Help", _sBtnW3, false, null); + + const lockIcon = this.add.image(containerX + 535, 30, "GJ_GameSheet03", "GJ_lock_open_001.png").setFlipX(false).setFlipY(false); + lockIcon.setScale(0.9); + lockIcon.setInteractive(); + this._expandHitArea(lockIcon, 1.5); + this._makeBouncyButton(lockIcon, 0.9, () => { this._openVaultMenu(); }); + this._settingsLayerInternal.add(lockIcon); + + const _0x45b6e4 = 0.8; + let _0xe44f6d = 250; + const sliderStartY = 430; + const _0x22b43a = 0.7; + const _0x41925a = this.textures.getFrame("GJ_WebSheet", "slidergroove.png"); + const _0x372782 = _0x41925a ? _0x41925a.width : 420; + + const createSlider = (posY, labelText, initialVal, setter) => { + this._settingsLayerInternal.add(this.add.bitmapText(containerX, posY - 37, "bigFont", labelText, 33).setOrigin(0.5, 0.5)); + const barMaxW = (_0x372782 - 8) * _0x22b43a * 1.3; + const barStartX = containerX - barMaxW / 2 + 2.8; + const fillW = initialVal * barMaxW; + const fillBar = this.add.tileSprite(barStartX, posY, fillW > 0 ? fillW : 1, 18, "sliderBar").setOrigin(0, 0.5); + this._settingsLayerInternal.add(fillBar); + this._settingsLayerInternal.add(this.add.image(containerX, posY, "GJ_WebSheet", "slidergroove.png").setScale(_0x22b43a * 1.3)); + + const thumb = this.add.image(barStartX + fillW, posY, "GJ_WebSheet", "sliderthumb.png").setScale(_0x22b43a * 1.3).setInteractive({ draggable: true }); + this._settingsLayerInternal.add(thumb); + thumb.on("drag", (p, dragX) => { + thumb.x = Math.max(barStartX, Math.min(barStartX + barMaxW, dragX)); + const pct = (thumb.x - barStartX) / barMaxW; + fillBar.width = Math.max(1, pct * barMaxW); + setter(pct < 0.03 ? 0 : pct); + }); + }; + + createSlider(sliderStartY - 15, "Music", this._audio.getUserMusicVolume(), v => this._audio.setUserMusicVolume(v)); + createSlider(sliderStartY + 60, "SFX", this._sfxVolume, v => { + this._sfxVolume = v; + localStorage.setItem("userSfxVol", v); + }); + const checkboxY = sliderStartY - 10; + const checkboxX = containerX + 280; + this._settingsLayerInternal.add(this.add.bitmapText(checkboxX, checkboxY - 42, "bigFont", "Menu", 20).setOrigin(0.5, 0.5)); + this._settingsLayerInternal.add(this.add.bitmapText(checkboxX, checkboxY - 22, "bigFont", "Music", 20).setOrigin(0.5, 0.5)); + + const getMenuMusicEnabled = () => { + const saved = localStorage.getItem("menuMusicEnabled"); + return saved === null ? true : saved === "true"; + }; + const setMenuMusicEnabled = (value) => localStorage.setItem("menuMusicEnabled", value); + + const getTex = () => getMenuMusicEnabled() ? "GJ_checkOn_001.png" : "GJ_checkOff_001.png"; + const check = this.add.image(checkboxX, checkboxY + 15, "GJ_GameSheet03", getTex()).setScale(0.7).setInteractive(); + this._settingsLayerInternal.add(check); + this._makeBouncyButton(check, 0.8, () => { + const newState = !getMenuMusicEnabled(); + setMenuMusicEnabled(newState); + check.setTexture("GJ_GameSheet03", getTex()); + if (newState) { + if (!this._audio.isplaying()) { + this._audio.startMenuMusic(); + } + } else { + if (this._audio.isplaying()) { + this._audio.stopMusic(); + } + } + }); + const _0x45fc2b = [{ + frame: "GJ_arrow_03_001.png", + dx: -535, + action: () => this._hideSettingsScreen() + }]; + for (const _0x2d4335 of _0x45fc2b) { + const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 30, "GJ_GameSheet03", _0x2d4335.frame).setInteractive(); + this._settingsLayerInternal.add(_0xdde774); + this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); + } + } + _playSettingsStarAward() { + if (!this._settingsLayerInternal) { + return; + } + const _0x4edc03 = containerX; + const _0x5a0e9 = 200; + const _0x453043 = this.add.image(_0x4edc03, _0x5a0e9, "GJ_WebSheet", "GJ_bigStar_001.png").setScale(3).setAlpha(0); + this._settingsLayerInternal.add(_0x453043); + this.tweens.add({ + targets: _0x453043, + scale: 0.8, + alpha: 1, + duration: 300, + delay: 0, + ease: "Bounce.Out" + }); + } + _hideSettingsScreen() { + if (!this._settingsLayerInternal || this._settingsScreenClosing) { + return; + } + this._settingsScreenClosing = true; + const _0x272eb1 = () => { + this._settingsScreenClosing = false; + if (this._settingsLayerOverlay) { + this._settingsLayerOverlay.destroy(); + this._settingsLayerOverlay = null; + } + if (this._settingsLayerInternal) { + this._settingsLayerInternal.destroy(); + this._settingsLayerInternal = null; + } + + if (this._pauseBtn) { + this.tweens.add({ + targets: this._pauseBtn, + alpha: 1, + duration: 300 + }); + } + }; + this.tweens.add({ + targets: this._settingsLayerOverlay, + alpha: 0, + duration: 500, + ease: "Linear" + }); + + const _0x59b9ab = { + p: 1 + }; + this.tweens.add({ + targets: _0x59b9ab, + p: 0, + duration: 500, + ease: "Quad.In", + onUpdate: () => { + this._settingsLayerInternal.y = _0x59b9ab.p * 650 - 640; + }, + onComplete: _0x272eb1 + }); + } + _showStatsScreen() { + if (this._pauseBtn) { + this.tweens.add({ + targets: this._pauseBtn, + alpha: 0, + duration: 300 + }); + } + const containerX = screenWidth / 2; + const _0x1aa656 = 320; + this._statsLayerOverlay = this.add.rectangle(containerX, _0x1aa656, screenWidth, screenHeight, 0, 0).setScrollFactor(0).setDepth(200).setInteractive(); + this._statsLayerInternal = this.add.container(0, -640).setScrollFactor(0).setDepth(201); + this.tweens.add({ + targets: this._statsLayerOverlay, + alpha: 100 / 255, + duration: 1000 + }); + const _0x59b9ab = { + p: 0 + }; + this.tweens.add({ + targets: _0x59b9ab, + p: 1, + duration: 500, + ease: "Quad.Out", + onUpdate: () => { + this._statsLayerInternal.y = _0x59b9ab.p * 650 - 640; + } + }); + const _0x595215 = 712; + const _0x950c8d = 460; + const _0x2a115c = (screenWidth - _0x595215) / 2; + this._statsLayerInternal.add(this.add.rectangle(_0x2a115c + 356, 310, _0x595215, _0x950c8d, 0xac531e)); + const _0x43f2e3 = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const _0x3feccc = _0x43f2e3 ? _0x950c8d / _0x43f2e3.height : 1; + this._statsLayerInternal.add(this.add.image(_0x2a115c - 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(0, 0).setScale(1, _0x3feccc)); + this._statsLayerInternal.add(this.add.image(_0x2a115c + _0x595215 + 40, 80, "GJ_WebSheet", "GJ_table_side_001.png").setOrigin(1, 0).setFlipX(true).setScale(1, _0x3feccc)); + const _0x33b564 = this.add.image(_0x2a115c + 356, 70, "GJ_WebSheet", "GJ_table_top_001.png"); + this._statsLayerInternal.add(_0x33b564); + this._statsLayerInternal.add(this.add.image(_0x2a115c + 356, 560, "GJ_WebSheet", "GJ_table_bottom_001.png")); + const _0x3e9c79 = _0x33b564.y - 35; + this._statsLayerInternal.add(this.add.image(containerX - 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + this._statsLayerInternal.add(this.add.image(containerX + 312, _0x3e9c79, "GJ_WebSheet", "chain_01_001.png").setOrigin(0.5, 1)); + this._statsLayerInternal.add(this.add.bitmapText(containerX, 65, "bigFont", "Stats", 55).setOrigin(0.5, 0.5)); + const _rowPanelTop = 102; + const _rowPanelBottom = 528; + const _rowLeft = _0x2a115c + 7.8; + const _rowRight = _0x2a115c + _0x595215 - 7.8; + const _rowWidth = _rowRight - _rowLeft; + const _rowCount = 6; + const _rowH = (_rowPanelBottom - _rowPanelTop) / _rowCount; + + const rows = [ + { label: "Total Jumps:", value: String(this._totalJumps || 0) }, + { label: "Total Attempts:", value: String(this._attempts || 1) }, + { label: "Completed Levels:", value: String(window._completedLevels || 0) }, + { label: "Total Deaths:", value: String(this._totalDeaths || 0) }, + { label: "???:", value: String(window._totalDiamonds || '?') }, + { label: "???:", value: String(window._totalOrbs || '?') }, + + ]; + rows.forEach((row, index) => { + const rowCenterY = _rowPanelTop + index * _rowH + _rowH / 2; + const bgColor = index % 2 === 0 ? 0xac531e : 0xcf6d30; + this._statsLayerInternal.add( + this.add.rectangle(containerX, rowCenterY, _rowWidth, _rowH, bgColor).setOrigin(0.5, 0.5) + ); + if (index > 0) { + this._statsLayerInternal.add( + this.add.rectangle(containerX, _rowPanelTop + index * _rowH, _rowWidth, 0.5, 0x000000).setOrigin(0.5, 0.5) + ); + } + this._statsLayerInternal.add( + this.add.bitmapText(_rowLeft + 20, rowCenterY, "goldFont", row.label, 34).setOrigin(0, 0.5) + ); + this._statsLayerInternal.add( + this.add.bitmapText(_rowRight - 20, rowCenterY, "goldFont", row.value, 34).setOrigin(1, 0.5) + ); + }); + const _0x45fc2b = [{ + frame: "GJ_arrow_03_001.png", + dx: -535, + action: () => this._hideStatsScreen() + }]; + for (const _0x2d4335 of _0x45fc2b) { + const _0xdde774 = this.add.image(containerX + _0x2d4335.dx, 30, "GJ_GameSheet03", _0x2d4335.frame).setInteractive(); + this._statsLayerInternal.add(_0xdde774); + this._makeBouncyButton(_0xdde774, 1, _0x2d4335.action); + } + } + _hideStatsScreen() { + if (!this._statsLayerInternal) { + return; + } + const _0x272eb1 = () => { + if (this._statsLayerOverlay) { + this._statsLayerOverlay.destroy(); + this._statsLayerOverlay = null; + } + if (this._statsLayerInternal) { + this._statsLayerInternal.destroy(); + this._statsLayerInternal = null; + } + if (this._pauseBtn) { + this.tweens.add({ + targets: this._pauseBtn, + alpha: 1, + duration: 300 + }); + } + }; + this.tweens.add({ + targets: this._statsLayerOverlay, + alpha: 0, + duration: 500, + ease: "Linear" + }); + const _0x59b9ab = { + p: 1 + }; + this.tweens.add({ + targets: _0x59b9ab, + p: 0, + duration: 500, + ease: "Quad.In", + onUpdate: () => { + this._statsLayerInternal.y = _0x59b9ab.p * 650 - 640; + }, + onComplete: _0x272eb1 + }); + } + _playStarAward() { + if (!this._endLayerInternal) { + return; + } + const _0x4edc03 = this._endStarX; + const _0x5a0e9 = this._endStarY; + const _0x453043 = this.add.image(_0x4edc03, _0x5a0e9, "GJ_WebSheet", "GJ_bigStar_001.png").setScale(3).setAlpha(0); + this._endLayerInternal.add(_0x453043); + this.tweens.add({ + targets: _0x453043, + scale: 0.8, + alpha: 1, + duration: 300, + delay: 0, + ease: "Bounce.Out" + }); + this.time.delayedCall(100, () => { + this._audio.playEffect("highscoreGet02"); + const _0x1204d3 = _0x4edc03; + const _0x96e3b2 = _0x5a0e9 + this._endLayerInternal.y; + this.add.particles(_0x1204d3, _0x96e3b2, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 200, + max: 600 + }, + angle: { + min: 0, + max: 360 + }, + scale: { + start: 0.5, + end: 0 + }, + alpha: { + start: 1, + end: 0 + }, + lifespan: { + min: 200, + max: 600 + }, + quantity: 30, + stopAfter: 30, + blendMode: S, + tint: 16776960 + }).setScrollFactor(0).setDepth(202); + const _0x43203f = this.add.graphics().setScrollFactor(0).setDepth(202).setBlendMode(S); + const _0x403316 = { + t: 0 + }; + this.tweens.add({ + targets: _0x403316, + t: 1, + duration: 400, + ease: "Quad.Out", + onUpdate: () => { + _0x43203f.clear(); + _0x43203f.fillStyle(16776960, 1 - _0x403316.t); + _0x43203f.fillCircle(_0x1204d3, _0x96e3b2, 20 + _0x403316.t * 200); + }, + onComplete: () => _0x43203f.destroy() + }); + }); + } + _openListScene(title, rowHeight, onBack) { + const sw = screenWidth; + const sh = screenHeight; + const objects = []; + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(300); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 280, ease: "Linear", + onComplete: () => fadeIn.destroy() }); + + const bgGfx = this.add.graphics().setScrollFactor(0).setDepth(200); + const steps = 80; + for (let i = 0; i < steps; i++) { + const t = i / (steps - 1); + const r = 0; + const g = Math.round(0x66 * (1 - t) + 0x33 * t); + const b = Math.round(0xff * (1 - t) + 0x99 * t); + bgGfx.fillStyle((r << 16) | (g << 8) | b, 1); + bgGfx.fillRect(0, Math.floor(i * sh / steps), sw, Math.ceil(sh / steps) + 1); + } + objects.push(bgGfx); + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) + .setScrollFactor(0).setDepth(200).setInteractive(); + objects.push(blocker); + const cBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(201).setOrigin(0, 1).setFlipY(false); + const cBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(201).setOrigin(1, 1).setFlipX(true); + objects.push(cBL, cBR); + const panelW = 712; + const panelH = 460; + const panelCX = sw / 2; + const panelCY = sh / 2; + const panelBg = this.add.rectangle(panelCX, panelCY + 10, panelW, panelH, 0xC2723E) + .setScrollFactor(0).setDepth(201).setOrigin(0.5); + objects.push(panelBg); + const listLeft = panelCX - panelW / 2; + const listTop = panelCY - panelH / 2 + 10; + const stripesGfx = this.add.graphics().setScrollFactor(0).setDepth(202); + objects.push(stripesGfx); + let _rowCount = 0; + const _redrawStripes = (offsetY = 0) => { + stripesGfx.clear(); + for (let ri = 0; ri < _rowCount; ri++) { + const ry = (listTop + 12) + ri * rowHeight - offsetY; + const ryBottom = ry + rowHeight; + if (ryBottom <= (listTop + 12) || ry >= listTop + panelH) continue; + const clampedY = Math.max(ry, listTop + 12); + const clampedH = Math.min(ryBottom, listTop + panelH) - clampedY; + stripesGfx.fillStyle(ri % 2 === 0 ? 0xB5652E : 0xC2723E, 1); + stripesGfx.fillRect(listLeft, clampedY, panelW, clampedH); + } + if (_rowCount > 0) { + const topDividerY = (listTop + 12) - offsetY; + if (topDividerY >= listTop + 12 && topDividerY < listTop + panelH) { + stripesGfx.fillStyle(0x000000, 0.6); + stripesGfx.fillRect(listLeft + 5, topDividerY, panelW - 10, 1.5); + } + const lastRowY = (listTop + 12) + (_rowCount - 1) * rowHeight - offsetY; + const bottomDividerY = lastRowY + rowHeight; + if (bottomDividerY > listTop + 12 && bottomDividerY <= listTop + panelH) { + stripesGfx.fillStyle(0x000000, 0.6); + stripesGfx.fillRect(listLeft + 5, bottomDividerY, panelW - 10, 1.5); + } + } + }; + + const addRow = () => { _rowCount++; _redrawStripes(); }; + const clearRows = () => { _rowCount = 0; _redrawStripes(); }; + const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const sideScaleY = sideFrame ? panelH / sideFrame.height : 1; + const leftBorder = this.add.image(listLeft - 40, 90, + "GJ_WebSheet", "GJ_table_side_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0, 0).setScale(1, sideScaleY); + objects.push(leftBorder); + const rightBorder = this.add.image(listLeft + panelW + 40, 90, + "GJ_WebSheet", "GJ_table_side_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY); + objects.push(rightBorder); + const topBorder = this.add.image(panelCX, 80, + "GJ_WebSheet", "GJ_table_top_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + objects.push(topBorder); + const bottomBorder = this.add.image(panelCX, 570, + "GJ_WebSheet", "GJ_table_bottom_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + objects.push(bottomBorder); + + if (title) { + const titleTxt = this.add.bitmapText(panelCX, panelCY - 245, "bigFont", title, 52) + .setScrollFactor(0).setDepth(204).setOrigin(0.5, 0.5); + objects.push(titleTxt); + } + const pageLbl = this.add.bitmapText(sw - 8, 3, "goldFont", "", 22) + .setScrollFactor(0).setDepth(204).setOrigin(1, 0).setVisible(false); + objects.push(pageLbl); + const backBtn = this.add.image(45, 45, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(backBtn); + const closeOverlay = (returnToParent = true, onComplete = null) => { + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(400).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeOut, alpha: 1, duration: 160, ease: "Linear", + onComplete: () => { + for (const o of objects) if (o && o.destroy) o.destroy(); + if (returnToParent && onBack) onBack(); + if (onComplete) onComplete(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 160, ease: "Linear", + onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._makeBouncyButton(backBtn, 1, () => closeOverlay()); + const prevBtn = this.add.image(40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setVisible(false); + objects.push(prevBtn); + this._makeBouncyButton(prevBtn, 1, () => {}); + const nextBtn = this.add.image(sw - 40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setFlipX(true).setVisible(false); + objects.push(nextBtn); + this._makeBouncyButton(nextBtn, 1, () => {}); + + return { overlay: bgGfx, objects, listLeft, listTop, panelW, panelH, + panelCX, panelCY, addRow, clearRows, prevBtn, nextBtn, + pageLbl, closeOverlay, redrawStripes: _redrawStripes }; + } + + _fitBitmapText(textObj, maxWidth, minScale = 0.3) { + textObj.setScale(1); + if (textObj.width > maxWidth) { + textObj.setScale(Math.max(minScale, maxWidth / textObj.width)); + } + return textObj; + } + + _formatStatCount(n) { + n = Number(n) || 0; + if (n < 1000) return String(n); + if (n < 1000000) { + const v = n / 1000; + return (v >= 100 ? Math.round(v) : parseFloat(v.toFixed(1))) + "K"; + } + const v = n / 1000000; + return (v >= 100 ? Math.round(v) : parseFloat(v.toFixed(1))) + "M"; + } + + _getLevelLengthLabel(lengthIdx) { + const _lengthValues = ["Tiny", "Short", "Medium", "Long", "XL"]; + if (lengthIdx === 5) { + return "Plat."; + } + return _lengthValues[lengthIdx] || "Tiny"; + } + + _openOnlineLevelsScene(params = {}) { + if (this._onlineLevelsOverlay) return; + + const sw = screenWidth; + const sh = screenHeight; + const isFeatured = (params.type === 6); + const shell = this._openListScene( + isFeatured ? "" : "Online Levels", + 180, + () => { + this._onlineLevelsOverlay = null; + if (isFeatured) { + this._openCreatorMenu(); + } else { + this._openSearchMenu(); + } + } + ); + const { objects, listLeft, listTop, panelW, panelH, + panelCX, panelCY, addRow, clearRows, + prevBtn, nextBtn, pageLbl, closeOverlay, redrawStripes } = shell; + + this._onlineLevelsOverlay = shell.overlay; + this._closeOnlineLevelsOverlay = closeOverlay; + if (isFeatured) { + const header = this.add.image(sw / 2, sh / 2 - 265, + "GJ_GameSheet03", "featuredLabel_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5); + objects.push(header); + } + { + const pageBtnGroup = this.add.container(sw - 35, sh / 2 - 240); + const pageBtn = this.add.image(0, 0, "GJ_button02").setScale(0.7); + const pageNum = this.add.bitmapText(-2, 0, "bigFont", "1", 35).setOrigin(0.5); + pageBtnGroup.add(pageBtn); + pageBtnGroup.add(pageNum); + const _pageBtnFrame = this.textures.getFrame("GJ_button02"); + const _pageBtnW = (_pageBtnFrame ? _pageBtnFrame.realWidth : 100) * 0.7; + const _pageBtnH = (_pageBtnFrame ? _pageBtnFrame.realHeight : 100) * 0.7; + pageBtnGroup.setScrollFactor(0).setDepth(205).setInteractive( + new Phaser.Geom.Rectangle(-_pageBtnW / 2, -_pageBtnH / 2, _pageBtnW, _pageBtnH), + Phaser.Geom.Rectangle.Contains + ); + objects.push(pageBtnGroup); + this._makeBouncyButton(pageBtnGroup, 1, () => { + if (!_loading) { + const pageCount = isFeatured ? 10 : _knownMaxPages; + const nextPage = (currentPage + 1) % Math.max(1, pageCount); + _setPage(nextPage); + } + }, () => true); + const updatePageNum = (page) => { + pageNum.setText(String(page + 1)); + }; + this._featuredPageUpdate = updatePageNum; + } + const spinSprite = this.add.image(sw / 2, sh / 2, "loadingCircle") + .setScrollFactor(0).setDepth(205).setOrigin(0.5).setBlendMode(Phaser.BlendModes.ADD).setAlpha(0.5); + objects.push(spinSprite); + const spinTimer = this.time.addEvent({ + delay: 16, + loop: true, + callback: () => { + if (!spinSprite.scene) { spinTimer.remove(); return; } + spinSprite.rotation += 0.1; + } + }); + objects.push({ destroy: () => spinTimer.remove() }); + const infoBtn = this.add.image(60, sh - 60, + "GJ_GameSheet03", "GJ_infoIcon_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(infoBtn); + this._makeBouncyButton(infoBtn, 1, () => { this._buildFeaturedInfoPopup(); }); + + const refreshBtn = this.add.image(sw - 55, sh - 55, + "GJ_GameSheet03", "GJ_updateBtn_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(refreshBtn); + let currentPage = 0; + let _knownMaxPages = 1; + const cache = {}; + const _processedCache = {}; + let activeCellObjs = []; + let _loading = false; + let scrollOffsetY = 0; + let _lastLevelStrs = null; + let _lastLevelData = []; + const _panelBoundaryTop = listTop + 12; + const _panelBoundaryBottom = listTop + panelH - 22; + const _panelMaskShape = this.add.graphics().setScrollFactor(0); + _panelMaskShape.fillStyle(0xffffff); + _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); + const _panelMask = _panelMaskShape.createGeometryMask(); + objects.push(_panelMaskShape); + + const _diffFrames = [ + "difficulty_00_btn_001.png", + "difficulty_01_btn_001.png", + "difficulty_02_btn_001.png", + "difficulty_03_btn_001.png", + "difficulty_04_btn_001.png", + "difficulty_05_btn_001.png", + "difficulty_06_btn_001.png", + "difficulty_07_btn_001.png", + "difficulty_08_btn_001.png", + "difficulty_09_btn_001.png", + "difficulty_10_btn_001.png", + "difficulty_auto_btn_001.png" + ]; + const _diffSizes = { + "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, + "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, + "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, + "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, + "difficulty_06_btn_001.png": { w: 72, h: 88, rotated: false }, + "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_09_btn_001.png": { w: 74, h: 88, rotated: false }, + "difficulty_10_btn_001.png": { w: 80, h: 91, rotated: false }, + "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, + }; + const _officialGDSongs = [ + "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", + "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", + "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", + "Hexagon Force","Blast Processing","Theory of Everything 2", + "Geometrical Dominator","Deadlocked","Fingerdash","Dash" + ]; + + const _buildLevelCell = (levelData, rowIdx) => { + const rowH = 180; + const rowY = _panelBoundaryTop + rowIdx * rowH - scrollOffsetY; + const rowCenterY = rowY + rowH / 2; + const cellObjs = []; + const rx = listLeft; + const boundaryTop = _panelBoundaryTop; + const boundaryBottom = _panelBoundaryBottom; + if (rowIdx > 0 && rowY >= boundaryTop && rowY <= boundaryBottom) { + const div = this.add.rectangle(rx + panelW / 2, rowY, panelW - 10, 1.5, 0x000000, 0.6) + .setScrollFactor(0).setDepth(203).setOrigin(0.5, 0.5); + div.setMask(_panelMask); + cellObjs.push(div); + } + const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); + const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; + const _targetH = 85; + const _maxW = 90; + const _scaleW = _diffMeta ? _diffMeta.w : 90; + const _scaleH = _diffMeta ? _diffMeta.h : 85; + const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); + const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; + const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", _diffFrames[diffIdx]) + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) + .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); + if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); + diffIcon.setMask(_panelMask); + cellObjs.push(diffIcon); + let coinIcon = null; + if (levelData.epic >= 3) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 2) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 1) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.featured) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } + if (coinIcon) { + coinIcon.setMask(_panelMask); + cellObjs.push(coinIcon); + } + const nameX = rx + 105; + const btnX = rx + panelW - 88; + const _progressKeyId = "online_" + (levelData.id || "0"); + const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); + const _hasBest = _bestPercent > 0; + const _isComplete = _bestPercent >= 100; + const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); + const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; + const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(nameText, _maxTextWidth); + nameText.setMask(_panelMask); + cellObjs.push(nameText); + if (_isComplete) { + const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); + completeIcon.setMask(_panelMask); + cellObjs.push(completeIcon); + } else if (_hasBest) { + const bestPctText = this.add.bitmapText(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5) + bestPctText.setMask(_panelMask); + cellObjs.push(bestPctText); + } + const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(authorText, _maxTextWidth); + authorText.setMask(_panelMask); + cellObjs.push(authorText); + const _isOfficialSong = _officialGDSongs.includes(levelData.songName); + const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); + this._fitBitmapText(songText, _maxTextWidth); + songText.setMask(_panelMask); + cellObjs.push(songText); + const _statY = rowCenterY + 63; + const _statGap = 25; + const _statDefs = [ + { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, + { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, + { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } + ]; + let _statX = nameX; + _statDefs.forEach((stat) => { + const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); + statIcon.setMask(_panelMask); + cellObjs.push(statIcon); + const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(statText, _maxTextWidth / 2); + statText.setMask(_panelMask); + cellObjs.push(statText); + _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; + }); + const _hasViewedLevel = !!localStorage.getItem("viewedLevel_" + (levelData.id || "0")); + const _rowBtnFrame = _hasViewedLevel ? "GJ_button01" : "GJ_button02"; + const _rowBtnLabel = _hasViewedLevel ? "View" : "Get It"; + const _rowBtnLabelSize = _hasViewedLevel ? 40 : 30; + const btn9 = this.add.nineslice(btnX, rowCenterY, _rowBtnFrame, null, 140, 60, 20, 20, 20, 20) + .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); + btn9.setMask(_panelMask); + const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", _rowBtnLabel, _rowBtnLabelSize) + .setScrollFactor(0).setDepth(207).setOrigin(0.5); + btnLbl.setMask(_panelMask); + cellObjs.push(btn9, btnLbl); + + const _btnTargets = [btn9, btnLbl]; + const _baseScale = 1, _pressScale = 1.26; + btn9.on("pointerdown", () => { + btn9._pressed = true; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); + }); + btn9.on("pointerout", () => { + if (btn9._pressed) { + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + btn9.on("pointerup", () => { + if (!btn9._pressed) return; + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets); + btn9.setScale(_baseScale); + btnLbl.setScale(_baseScale); + window._selectedLevelData = levelData; + closeOverlay(false, () => { + this._onlineLevelsOverlay = null; + this._closeOnlineLevelsOverlay = null; + this._openPlayMenu(() => this._openOnlineLevelsScene(params)); + }); + }); + + return cellObjs; + }; + const _parseKV = (str) => { + const m = {}, p = str.split(":"); + for (let i = 0; i + 1 < p.length; i += 2) m[p[i]] = p[i + 1]; + return m; + }; + const _setPage = async (page) => { + if (_loading) return; + _loading = true; + currentPage = page; + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + clearRows(); + if (this._featuredPageUpdate) { + this._featuredPageUpdate(page); + } + + spinSprite.setVisible(true); + refreshBtn.setVisible(false); + pageLbl.setVisible(false); + this.tweens.killTweensOf(prevBtn, "scale"); + prevBtn.setScale(1); + prevBtn._pressed = false; + prevBtn.setVisible(false); + this.tweens.killTweensOf(nextBtn, "scale"); + nextBtn.setScale(1); + nextBtn._pressed = false; + nextBtn.setVisible(false); + + try { + let response = cache[page]; + if (!response) { + const PROXY_BASE = (window._gdProxyUrl || "").replace(/\/$/, ""); + if (!PROXY_BASE) throw new Error("no proxy configured"); + const body = Object.entries({ secret: "Wmfd2893gb7", page, ...params }) + .map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&"); + let retryCount = 0; + const maxRetries = 3; + let res; + while (retryCount < maxRetries) { + res = await fetch(`${PROXY_BASE}/getGJLevels21.php`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body + }); + + if (res.status === 429) { + retryCount++; + if (retryCount >= maxRetries) { + throw new Error(`rate limited after ${maxRetries} retries`); + } + await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retryCount))); + continue; + } + break; + } + if (!res.ok) throw new Error(`HTTP ${res.status}`); + response = await res.text(); + if (!response || response === "-1") throw new Error("no results"); + cache[page] = response; + } + spinSprite.setVisible(false); + refreshBtn.setVisible(true); + pageLbl.setVisible(true); + prevBtn.setVisible(page > 0); + nextBtn.setVisible(true); + const sections = response.split("#"); + const levelStrs = (sections[0] || "").split("|").filter(Boolean); + const playerStrs = (sections[1] || "").split("|").filter(Boolean); + const songStrs = (sections[2] || "").split("~:~").filter(Boolean); + const pageInfo = (sections[3] || "0:0:10").split(":"); + + const playerMap = {}; + for (const ps of playerStrs) { + const p = ps.split(":"); + if (p.length >= 2) playerMap[p[0]] = p[1]; + } + const songMap = {}; + for (const ss of songStrs) { + const sp = ss.split("~|~"), sm = {}; + for (let i = 0; i + 1 < sp.length; i += 2) sm[sp[i]] = sp[i + 1]; + if (sm["1"]) songMap[sm["1"]] = sm["2"] || ""; + } + const total = parseInt(pageInfo[0]) || 0; + const offset = parseInt(pageInfo[1]) || 0; + const count = parseInt(pageInfo[2]) || 10; + const start = offset + 1; + const end = count * (page + 1); + pageLbl.setText(`${start} to ${end} of ${total}`); + const maxPages = Math.ceil(total / count); + _knownMaxPages = Math.max(1, maxPages); + const hasNextPage = (page + 1) < maxPages; + nextBtn.setVisible(hasNextPage); + scrollOffsetY = 0; + // wip + _lastLevelStrs = levelStrs; + if (_processedCache[page]) { + _lastLevelData = _processedCache[page]; + _lastLevelData.forEach((levelData, idx) => { + const cellObjs = _buildLevelCell(levelData, idx); + activeCellObjs.push(...cellObjs); + addRow(); + }); + spinSprite.setVisible(false); + refreshBtn.setVisible(true); + pageLbl.setVisible(true); + prevBtn.setVisible(page > 0); + nextBtn.setVisible(hasNextPage); + _loading = false; + return; + } + _lastLevelData = levelStrs.map((ls) => { + const m = _parseKV(ls); + const rawLikes = parseInt(m["14"]) || 0; + const isDemon = parseInt(m["17"]) === 1; + const isAuto = parseInt(m["25"]) === 1; + let diffIdx = 0; + if (isAuto) { + diffIdx = 11; + } else if (isDemon) { + const d9 = parseInt(m["9"]); + const d43 = parseInt(m["43"]); + if (!isNaN(d9) && d9 >= 1 && d9 <= 5) { + diffIdx = [7, 8, 6, 9, 10][d9 - 1] ?? 8; + } else if (!isNaN(d43)) { + const demonMap43 = { 3: 7, 4: 8, 0: 6, 5: 9, 6: 10 }; + diffIdx = demonMap43.hasOwnProperty(d43) ? demonMap43[d43] : 8; + } else { + diffIdx = 8; + } + } else { + diffIdx = Math.min(5, Math.max(0, Math.round((parseInt(m["9"]) || 0) / 10))); + } + return { + id: m["1"] || null, + name: m["2"] || "Unknown", + author: playerMap[m["6"]] || ("Player " + (m["6"] || "?")), + difficulty: diffIdx, + downloads: parseInt(m["10"]) || 0, + length: parseInt(m["15"]) || 0, + likes: rawLikes, + stars: parseInt(m["18"]) || 0, + coins: parseInt(m["37"]) || 0, + coinsVerified: m["38"] === "1", + customSongID: (m["35"] && m["35"] !== "0") ? m["35"] : null, + songName: m["35"] + ? (songMap[m["35"]] || ("Song #" + m["35"])) + : ("Song #" + (m["12"] || "0")), + featureScore: parseInt(m["19"]) || 0, + featured: (parseInt(m["19"]) || 0) > 0, + epic: parseInt(m["42"]) || 0 + }; + }); + const _officialEntries = _lastLevelData.filter(ld => !ld.customSongID && ld.id); + if (_officialEntries.length > 0) { + await Promise.all(_officialEntries.map(ld => { + return fetch(`https://gdbrowser.com/api/level/${ld.id}`) + .then(r => r.ok ? r.json() : null) + .then(data => { if (data && data.songName) ld.songName = data.songName; }) + .catch(() => {}); + })); + } + _processedCache[page] = _lastLevelData; + _lastLevelData.forEach((levelData, idx) => { + const cellObjs = _buildLevelCell(levelData, idx); + activeCellObjs.push(...cellObjs); + addRow(); + }); + + } catch (err) { + spinSprite.setVisible(false); + refreshBtn.setVisible(true); + } + _loading = false; + }; + prevBtn.removeAllListeners("pointerup"); + nextBtn.removeAllListeners("pointerup"); + prevBtn.on("pointerup", () => { if (!_loading && currentPage > 0) _setPage(currentPage - 1); }); + nextBtn.on("pointerup", () => { if (!_loading) _setPage(currentPage + 1); }); + this._makeBouncyButton(refreshBtn, 1, () => { delete cache[currentPage]; delete _processedCache[currentPage]; _setPage(currentPage); }); + const _onWheel = (pointer, gameObjects, deltaX, deltaY) => { + if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; + if (pointer.y < listTop || pointer.y > listTop + panelH) return; + const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); + const newScrollOffset = Math.max(0, Math.min(scrollOffsetY + deltaY * 0.5, maxScroll)); + if (newScrollOffset !== scrollOffsetY) { + scrollOffsetY = newScrollOffset; + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { + const cellObjs = _buildLevelCell(levelData, idx); + activeCellObjs.push(...cellObjs); + }); + + redrawStripes(scrollOffsetY); + } + }; this.input.on("wheel", _onWheel); + objects.push({ destroy: () => this.input.off("wheel", _onWheel) }); + let isDragging = false; + let dragStartY = 0; + let dragStartScrollOffset = 0; + let dragThreshold = 5; + let bounceBackTween = null; + const onDragStart = (pointer) => { + if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; + if (pointer.y < listTop || pointer.y > listTop + panelH) return; + if (bounceBackTween) { + bounceBackTween.destroy(); + bounceBackTween = null; + } + isDragging = true; + dragStartY = pointer.y; + dragStartScrollOffset = scrollOffsetY; + }; + const onDragMove = (pointer) => { + if (!isDragging || !pointer.isDown) return; + if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; + if (pointer.y < listTop || pointer.y > listTop + panelH) return; + const deltaY = dragStartY - pointer.y; + if (Math.abs(deltaY) < dragThreshold) return; + const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); + let newScrollOffset = dragStartScrollOffset + deltaY * 0.5; + const elasticLimit = 100; + if (newScrollOffset < -elasticLimit) { + newScrollOffset = -elasticLimit; + } else if (newScrollOffset > maxScroll + elasticLimit) { + newScrollOffset = maxScroll + elasticLimit; + } + if (newScrollOffset !== scrollOffsetY) { + scrollOffsetY = newScrollOffset; + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { + const cellObjs = _buildLevelCell(levelData, idx); + activeCellObjs.push(...cellObjs); + }); + redrawStripes(scrollOffsetY); + } + }; + + const onDragEnd = () => { + isDragging = false; + const maxScroll = Math.max(0, (_lastLevelStrs ? _lastLevelStrs.length : 0) * 180 - (panelH - 33)); + let targetScrollOffset = scrollOffsetY; + if (scrollOffsetY < 0) { + targetScrollOffset = 0; + } else if (scrollOffsetY > maxScroll) { + targetScrollOffset = maxScroll; + } + if (targetScrollOffset !== scrollOffsetY) { + const startOffset = scrollOffsetY; + bounceBackTween = this.tweens.add({ + targets: { scrollOffset: startOffset }, + scrollOffset: targetScrollOffset, + duration: 300, + ease: "Quad.Out", + onStart: () => { + isDragging = false; + }, + onUpdate: () => { + scrollOffsetY = bounceBackTween.targets[0].scrollOffset; + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + if (_lastLevelData) _lastLevelData.forEach((levelData, idx) => { + const cellObjs = _buildLevelCell(levelData, idx); + activeCellObjs.push(...cellObjs); + }); + + redrawStripes(scrollOffsetY); + }, + onComplete: () => { + bounceBackTween = null; + } + }); + } + }; + + this.input.on('pointerdown', onDragStart); + this.input.on('pointermove', onDragMove); + this.input.on('pointerup', onDragEnd); + + objects.push({ destroy: () => this.input.off('pointerdown', onDragStart) }); + objects.push({ destroy: () => this.input.off('pointermove', onDragMove) }); + objects.push({ destroy: () => this.input.off('pointerup', onDragEnd) }); + objects.push({ destroy: () => { + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + }}); + + _setPage(0); + } + + _openSavedLevelsScene() { + const sw = screenWidth; + const sh = screenHeight; + + const objects = []; + const rowHeight = 180; + + const fadeIn = this.add.graphics().setScrollFactor(0).setDepth(300); + fadeIn.fillStyle(0x000000, 1); + fadeIn.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeIn, alpha: 0, duration: 280, ease: "Linear", + onComplete: () => fadeIn.destroy() }); + + const bgGfx = this.add.graphics().setScrollFactor(0).setDepth(200); + const steps = 80; + for (let i = 0; i < steps; i++) { + const t = i / (steps - 1); + const r = 0; + const g = Math.round(0x66 * (1 - t) + 0x33 * t); + const b = Math.round(0xff * (1 - t) + 0x99 * t); + bgGfx.fillStyle((r << 16) | (g << 8) | b, 1); + bgGfx.fillRect(0, Math.floor(i * sh / steps), sw, Math.ceil(sh / steps) + 1); + } + objects.push(bgGfx); + + const blocker = this.add.zone(sw / 2, sh / 2, sw, sh) + .setScrollFactor(0).setDepth(200).setInteractive(); + objects.push(blocker); + + const cBL = this.add.image(0, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(201).setOrigin(0, 1).setFlipY(false); + const cBR = this.add.image(sw, sh, "GJ_GameSheet03", "GJ_sideArt_001.png") + .setScrollFactor(0).setDepth(201).setOrigin(1, 1).setFlipX(true); + objects.push(cBL, cBR); + + const panelW = 712; + const panelH = 460; + const panelCX = sw / 2; + const panelCY = sh / 2; + const panelBg = this.add.rectangle(panelCX, panelCY + 10, panelW, panelH, 0xC2723E) + .setScrollFactor(0).setDepth(201).setOrigin(0.5); + objects.push(panelBg); + + const listLeft = panelCX - panelW / 2; + const listTop = panelCY - panelH / 2 + 10; + + const stripesGfx = this.add.graphics().setScrollFactor(0).setDepth(202); + objects.push(stripesGfx); + let _rowCount = 0; + const redrawStripes = (offsetY = 0) => { + stripesGfx.clear(); + for (let ri = 0; ri < _rowCount; ri++) { + const ry = (listTop + 12) + ri * rowHeight - offsetY; + const ryBottom = ry + rowHeight; + if (ryBottom <= (listTop + 12) || ry >= listTop + panelH) continue; + const clampedY = Math.max(ry, listTop + 12); + const clampedH = Math.min(ryBottom, listTop + panelH) - clampedY; + stripesGfx.fillStyle(ri % 2 === 0 ? 0xB5652E : 0xC2723E, 1); + stripesGfx.fillRect(listLeft, clampedY, panelW, clampedH); + } + if (_rowCount > 0) { + const topDividerY = (listTop + 12) - offsetY; + if (topDividerY >= listTop + 12 && topDividerY < listTop + panelH) { + stripesGfx.fillStyle(0x000000, 0.6); + stripesGfx.fillRect(listLeft + 5, topDividerY, panelW - 10, 1.5); + } + const lastRowY = (listTop + 12) + (_rowCount - 1) * rowHeight - offsetY; + const bottomDividerY = lastRowY + rowHeight; + if (bottomDividerY > listTop + 12 && bottomDividerY <= listTop + panelH) { + stripesGfx.fillStyle(0x000000, 0.6); + stripesGfx.fillRect(listLeft + 5, bottomDividerY, panelW - 10, 1.5); + } + } + }; + const addRow = () => { _rowCount++; redrawStripes(); }; + const clearRows = () => { _rowCount = 0; redrawStripes(); }; + + const sideFrame = this.textures.getFrame("GJ_WebSheet", "GJ_table_side_001.png"); + const sideScaleY = sideFrame ? panelH / sideFrame.height : 1; + const leftBorder = this.add.image(listLeft - 40, 90, + "GJ_WebSheet", "GJ_table_side_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0, 0).setScale(1, sideScaleY); + objects.push(leftBorder); + const rightBorder = this.add.image(listLeft + panelW + 40, 90, + "GJ_WebSheet", "GJ_table_side_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(1, 0).setFlipX(true).setScale(1, sideScaleY); + objects.push(rightBorder); + const topBorder = this.add.image(panelCX, 80, + "GJ_WebSheet", "GJ_table_top_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + objects.push(topBorder); + const bottomBorder = this.add.image(panelCX, 570, + "GJ_WebSheet", "GJ_table_bottom_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + objects.push(bottomBorder); + + const pageLbl = this.add.bitmapText(sw - 8, 3, "goldFont", "", 22) + .setScrollFactor(0).setDepth(204).setOrigin(1, 0).setVisible(false); + objects.push(pageLbl); + + const backBtn = this.add.image(45, 45, "GJ_GameSheet03", "GJ_arrow_01_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(backBtn); + const closeOverlay = (returnToCreator = true, onComplete = null) => { + const fadeOut = this.add.graphics().setScrollFactor(0).setDepth(400).setAlpha(0); + fadeOut.fillStyle(0x000000, 1); + fadeOut.fillRect(0, 0, sw, sh); + this.tweens.add({ targets: fadeOut, alpha: 1, duration: 160, ease: "Linear", + onComplete: () => { + for (const o of objects) if (o && o.destroy) o.destroy(); + if (returnToCreator) this._openCreatorMenu(); + if (onComplete) onComplete(); + this.tweens.add({ targets: fadeOut, alpha: 0, duration: 160, ease: "Linear", + onComplete: () => fadeOut.destroy() }); + } + }); + }; + this._makeBouncyButton(backBtn, 1, () => closeOverlay()); + const prevBtn = this.add.image(40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setVisible(false); + objects.push(prevBtn); + this._makeBouncyButton(prevBtn, 1, () => {}); + const nextBtn = this.add.image(sw - 40, sh / 2, "GJ_GameSheet03", "GJ_arrow_03_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive().setFlipX(true).setVisible(false); + objects.push(nextBtn); + this._makeBouncyButton(nextBtn, 1, () => {}); + const header = this.add.bitmapText(sw / 2, sh / 2 - 245, "bigFont", "Saved Levels", 52) + .setScrollFactor(0).setDepth(204).setOrigin(0.5); + objects.push(header); + const savedPerPage = 10; + let currentPage = 0; + const pageBtnGroup = this.add.container(sw - 35, sh / 2 - 240); + const pageBtn = this.add.image(0, 0, "GJ_button02").setScale(0.7); + const pageNum = this.add.bitmapText(-2, 0, "bigFont", "1", 35).setOrigin(0.5); + pageBtnGroup.add(pageBtn); + pageBtnGroup.add(pageNum); + const _pageBtnFrame = this.textures.getFrame("GJ_button02"); + const _pageBtnW = (_pageBtnFrame ? _pageBtnFrame.realWidth : 100) * 0.7; + const _pageBtnH = (_pageBtnFrame ? _pageBtnFrame.realHeight : 100) * 0.7; + pageBtnGroup.setScrollFactor(0).setDepth(205).setInteractive( + new Phaser.Geom.Rectangle(-_pageBtnW / 2, -_pageBtnH / 2, _pageBtnW, _pageBtnH), + Phaser.Geom.Rectangle.Contains + ); + objects.push(pageBtnGroup); + const _updateSavedPageNum = (page) => { pageNum.setText(String(page + 1)); }; + const _getSavedTotalPages = () => Math.max(1, Math.ceil(savedLevelData.length / savedPerPage)); + const infoBtn = this.add.image(60, sh - 60, + "GJ_GameSheet03", "GJ_infoIcon_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(infoBtn); + this._makeBouncyButton(infoBtn, 1, () => {}, () => true); + + const refreshBtn = this.add.image(sw - 55, sh - 55, + "GJ_GameSheet03", "GJ_deleteBtn_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setInteractive(); + objects.push(refreshBtn); + this._makeBouncyButton(refreshBtn, 1, () => { + try { localStorage.removeItem("gd_saved_online_levels"); } catch(_e) {} + savedLevelData = []; + currentPage = 0; + scrollOffsetY = 0; + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + clearRows(); + redrawStripes(scrollOffsetY); + _updateSavedNav(); + if (_emptyTxt) { + _emptyTxt.setVisible(true); + } else { + _emptyTxt = this.add.bitmapText(panelCX, panelCY + 10, "bigFont", "You have not downloaded any\n levels yet!", 32) + .setScrollFactor(0).setDepth(204).setOrigin(0.5); + objects.push(_emptyTxt); + } + }, () => true); + + const _panelBoundaryTop = listTop + 12; + const _panelBoundaryBottom = listTop + panelH - 22; + const _panelMaskShape = this.add.graphics().setScrollFactor(0); + _panelMaskShape.fillStyle(0xffffff); + _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); + const _panelMask = _panelMaskShape.createGeometryMask(); + objects.push(_panelMaskShape); + let scrollOffsetY = 0; + let activeCellObjs = []; + let savedLevelData = []; + let _emptyTxt = null; + const diffFrames = [ + "difficulty_00_btn_001.png", + "difficulty_01_btn_001.png", + "difficulty_02_btn_001.png", + "difficulty_03_btn_001.png", + "difficulty_04_btn_001.png", + "difficulty_05_btn_001.png", + "difficulty_06_btn_001.png", + "difficulty_07_btn_001.png", + "difficulty_08_btn_001.png", + "difficulty_09_btn_001.png", + "difficulty_10_btn_001.png", + "difficulty_auto_btn_001.png" + ]; + const _buildSavedCell = (levelData, rowIdx) => { + const rowH = 180; + const rowCenterY = _panelBoundaryTop + rowIdx * rowH + rowH / 2 - scrollOffsetY; + const cellObjs = []; + const rx = listLeft; + if (rowCenterY + rowH / 2 < _panelBoundaryTop || rowCenterY - rowH / 2 > _panelBoundaryBottom) { + return cellObjs; + } + if (rowIdx > 0) { + const divY = _panelBoundaryTop + rowIdx * rowH - scrollOffsetY; + if (divY >= _panelBoundaryTop && divY <= _panelBoundaryBottom) { + const div = this.add.rectangle(rx + panelW / 2, divY, panelW - 10, 1.5, 0x000000, 0.6) + .setScrollFactor(0).setDepth(203).setOrigin(0.5, 0.5); + div.setMask(_panelMask); + cellObjs.push(div); + } + } + const diffIdx = Math.min(diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); + const _diffSizes = { + "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, + "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, + "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, + "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, + "difficulty_06_btn_001.png": { w: 72, h: 90, rotated: false }, + "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_09_btn_001.png": { w: 74, h: 90, rotated: false }, + "difficulty_10_btn_001.png": { w: 80, h: 95, rotated: false }, + "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, + }; + const _diffMeta = _diffSizes[diffFrames[diffIdx]]; + const _targetH = 85; + const _maxW = 90; + const _scaleW = _diffMeta ? _diffMeta.w : 90; + const _scaleH = _diffMeta ? _diffMeta.h : 85; + const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); + const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; + const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", diffFrames[diffIdx]) + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) + .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); + if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); + diffIcon.setMask(_panelMask); + cellObjs.push(diffIcon); + let coinIcon = null; + if (levelData.epic >= 3) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 2) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 1) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.featured) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } + if (coinIcon) { + coinIcon.setMask(_panelMask); + cellObjs.push(coinIcon); + } + const nameX = rx + 105; + const btnX = rx + panelW - 88; + const _progressKeyId = "online_" + (levelData.id || "0"); + const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); + const _hasBest = _bestPercent > 0; + const _isComplete = _bestPercent >= 100; + const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); + const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; + const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(nameText, _maxTextWidth); + nameText.setMask(_panelMask); + cellObjs.push(nameText); + if (_isComplete) { + const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); + completeIcon.setMask(_panelMask); + cellObjs.push(completeIcon); + } else if (_hasBest) { + const bestPctText = this.add.bitmapText(nameX + 5+ nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + bestPctText.setMask(_panelMask); + cellObjs.push(bestPctText); + } + const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(authorText, _maxTextWidth); + authorText.setMask(_panelMask); + cellObjs.push(authorText); + const _officialGDSongs = [ + "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", + "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", + "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", + "Hexagon Force","Blast Processing","Theory of Everything 2", + "Geometrical Dominator","Deadlocked","Fingerdash","Dash" + ]; + const _isOfficialSong = _officialGDSongs.includes(levelData.songName); + const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); + this._fitBitmapText(songText, _maxTextWidth); + songText.setMask(_panelMask); + cellObjs.push(songText); + const _statY = rowCenterY + 63; + const _statGap = 25; + const _statDefs = [ + { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, + { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, + { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } + ]; + let _statX = nameX; + _statDefs.forEach((stat) => { + const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); + statIcon.setMask(_panelMask); + cellObjs.push(statIcon); + const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(statText, _maxTextWidth / 2); + statText.setMask(_panelMask); + cellObjs.push(statText); + _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; + }); + const btn9 = this.add.nineslice(btnX, rowCenterY, "GJ_button01", null, 140, 60, 20, 20, 20, 20) + .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); + btn9.setMask(_panelMask); + const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", "View", 40) + .setScrollFactor(0).setDepth(207).setOrigin(0.5); + btnLbl.setMask(_panelMask); + cellObjs.push(btn9, btnLbl); + + const _btnTargets = [btn9, btnLbl]; + const _baseScale = 1, _pressScale = 1.26; + btn9.on("pointerdown", () => { + btn9._pressed = true; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); + }); + btn9.on("pointerout", () => { + if (btn9._pressed) { + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + btn9.on("pointerup", () => { + if (!btn9._pressed) return; + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets); + btn9.setScale(_baseScale); + btnLbl.setScale(_baseScale); + window._selectedLevelData = levelData; + closeOverlay(false, () => { + this._openPlayMenu(() => this._openSavedLevelsScene()); + }); + }); + + return cellObjs; + }; + + const _rebuildCells = () => { + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + clearRows(); + const totalPages = _getSavedTotalPages(); + if (currentPage >= totalPages) currentPage = 0; + _updateSavedNav(); + const pageData = savedLevelData.slice(currentPage * savedPerPage, currentPage * savedPerPage + savedPerPage); + pageData.forEach((levelData, idx) => { + const cellObjs = _buildSavedCell(levelData, idx); + activeCellObjs.push(...cellObjs); + addRow(); + }); + }; + const _updateSavedNav = () => { + const totalPages = _getSavedTotalPages(); + const hasData = savedLevelData.length > 0; + pageBtnGroup.setVisible(hasData); + _updateSavedPageNum(currentPage); + const start = hasData ? currentPage * savedPerPage + 1 : 0; + const end = hasData ? Math.min(savedLevelData.length, (currentPage + 1) * savedPerPage) : 0; + pageLbl.setText(`${start} to ${end} of ${savedLevelData.length}`); + pageLbl.setVisible(hasData); + prevBtn.setVisible(hasData && currentPage > 0); + nextBtn.setVisible(hasData && currentPage < totalPages - 1); + }; + + const _goToSavedPage = (page) => { + const totalPages = _getSavedTotalPages(); + currentPage = Math.max(0, Math.min(page, totalPages - 1)); + scrollOffsetY = 0; + _rebuildCells(); + redrawStripes(scrollOffsetY); + }; + + this._makeBouncyButton(pageBtnGroup, 1, () => { + const totalPages = _getSavedTotalPages(); + _goToSavedPage((currentPage + 1) % totalPages); + }, () => true); + + prevBtn.removeAllListeners("pointerup"); + nextBtn.removeAllListeners("pointerup"); + prevBtn.on("pointerup", () => { if (currentPage > 0) _goToSavedPage(currentPage - 1); }); + nextBtn.on("pointerup", () => { + const totalPages = _getSavedTotalPages(); + if (currentPage < totalPages - 1) _goToSavedPage(currentPage + 1); + }); + try { + savedLevelData = JSON.parse(localStorage.getItem("gd_saved_online_levels") || "[]"); + let _neededNormalize = false; + savedLevelData.forEach(ld => { + if (typeof ld.id === "string" && ld.id.startsWith("online_")) { + ld.id = ld.id.replace(/^online_/, ""); + _neededNormalize = true; + } + }); + if (_neededNormalize) { + try { localStorage.setItem("gd_saved_online_levels", JSON.stringify(savedLevelData)); } catch(_e) {} + } + } catch(_e) { savedLevelData = []; } + + if (savedLevelData.length === 0) { + const emptyTxt = this.add.bitmapText(panelCX, panelCY + 10, "bigFont", "You have not downloaded any\n levels yet!", 38) + .setScrollFactor(0).setDepth(204).setOrigin(0.5); + objects.push(emptyTxt); + _emptyTxt = emptyTxt; + _updateSavedNav(); + } else { + const _needsFetch = savedLevelData.filter(ld => { + const numericId = String(ld.id || "").replace(/^online_/, ""); + return /^\d+$/.test(numericId) && (!ld.author || ld.author === "Unknown" || !ld.songName || ld.songName === "Unknown" || ld.difficulty === 0 || ld.difficulty == null); + }); + + const _doRender = () => { + _rebuildCells(); + }; + + if (_needsFetch.length === 0) { + _doRender(); + } else { + Promise.all(_needsFetch.map(levelData => { + const numericId = String(levelData.id || "").replace(/^online_/, ""); + return fetch(`https://gdbrowser.com/api/level/${numericId}`) + .then(r => r.ok ? r.json() : null) + .then(data => { + if (data) { + if (data.author) levelData.author = data.author; + if (data.songName) levelData.songName = data.songName; + if (!levelData.customSongID && data.songID) levelData.customSongID = String(data.songID); + const _diffMap = { + "N/A": 0, "Auto": 11, "Easy": 1, "Normal": 2, + "Hard": 3, "Harder": 4, "Insane": 5, + "Easy Demon": 7, "Medium Demon": 8, "Hard Demon": 6, + "Insane Demon": 9, "Extreme Demon": 10 + }; + if (data.difficulty && _diffMap.hasOwnProperty(data.difficulty)) { + levelData.difficulty = _diffMap[data.difficulty]; + } + } + }) + .catch(() => {}); + })).then(() => { + try { + const _savedKey = "gd_saved_online_levels"; + const all = JSON.parse(localStorage.getItem(_savedKey) || "[]"); + for (const ld of savedLevelData) { + const idx = all.findIndex(sl => sl.id === ld.id); + if (idx !== -1) { + all[idx].author = ld.author; + all[idx].songName = ld.songName; + all[idx].difficulty = ld.difficulty; + all[idx].customSongID = ld.customSongID; + } + } + localStorage.setItem(_savedKey, JSON.stringify(all)); + } catch(_e) {} + _doRender(); + }); + } + + objects.push({ destroy: () => { + for (const o of activeCellObjs) if (o && o.destroy) o.destroy(); + activeCellObjs = []; + }}); + const _getSavedPageCount = () => Math.min(savedPerPage, savedLevelData.length - currentPage * savedPerPage); + const _onWheel = (pointer, gameObjects, deltaX, deltaY) => { + if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; + if (pointer.y < listTop || pointer.y > listTop + panelH) return; + const maxScroll = Math.max(0, _getSavedPageCount() * 180 - (panelH - 33)); + const newOffset = Math.max(0, Math.min(scrollOffsetY + deltaY * 0.5, maxScroll)); + if (newOffset !== scrollOffsetY) { + scrollOffsetY = newOffset; + _rebuildCells(); + redrawStripes(scrollOffsetY); + } + }; + this.input.on("wheel", _onWheel); + objects.push({ destroy: () => this.input.off("wheel", _onWheel) }); + let isDragging = false, dragStartY = 0, dragStartOffset = 0; + const onDragStart = (pointer) => { + if (pointer.x < listLeft || pointer.x > listLeft + panelW) return; + if (pointer.y < listTop || pointer.y > listTop + panelH) return; + isDragging = true; dragStartY = pointer.y; dragStartOffset = scrollOffsetY; + }; + const onDragMove = (pointer) => { + if (!isDragging || !pointer.isDown) return; + const maxScroll = Math.max(0, _getSavedPageCount() * 180 - (panelH - 33)); + const newOffset = Math.max(0, Math.min(dragStartOffset + (dragStartY - pointer.y) * 0.5, maxScroll)); + if (newOffset !== scrollOffsetY) { + scrollOffsetY = newOffset; + _rebuildCells(); + redrawStripes(scrollOffsetY); + } + }; + const onDragEnd = () => { isDragging = false; }; + this.input.on("pointerdown", onDragStart); + this.input.on("pointermove", onDragMove); + this.input.on("pointerup", onDragEnd); + objects.push({ destroy: () => this.input.off("pointerdown", onDragStart) }); + objects.push({ destroy: () => this.input.off("pointermove", onDragMove) }); + objects.push({ destroy: () => this.input.off("pointerup", onDragEnd) }); + } + } + + _closeOnlineLevelsScene() { + if (this._onlineLevelsOverlay) { + if (this._closeOnlineLevelsOverlay) { + this._closeOnlineLevelsOverlay(); + } + this._onlineLevelsOverlay = null; + } + } + + _openSearchResultScene(levelData) { + if (this._searchResultOverlay) return; + + const sw = screenWidth; + const sh = screenHeight; + const shell = this._openListScene( + "Online Levels", + 180, + () => { this._searchResultOverlay = null; this._openSearchMenu(); } + ); + const { objects, listLeft, listTop, panelW, panelH, addRow, closeOverlay } = shell; + + this._searchResultOverlay = shell.overlay; + this._closeSearchResultOverlay = closeOverlay; + + const _panelBoundaryTop = listTop + 12; + const _panelBoundaryBottom = listTop + panelH - 22; + const _panelMaskShape = this.add.graphics().setScrollFactor(0); + _panelMaskShape.fillStyle(0xffffff); + _panelMaskShape.fillRect(listLeft, _panelBoundaryTop, panelW, _panelBoundaryBottom - _panelBoundaryTop); + const _panelMask = _panelMaskShape.createGeometryMask(); + objects.push(_panelMaskShape); + + const _diffFrames = [ + "difficulty_00_btn_001.png", + "difficulty_01_btn_001.png", + "difficulty_02_btn_001.png", + "difficulty_03_btn_001.png", + "difficulty_04_btn_001.png", + "difficulty_05_btn_001.png", + "difficulty_06_btn_001.png", + "difficulty_07_btn_001.png", + "difficulty_08_btn_001.png", + "difficulty_09_btn_001.png", + "difficulty_10_btn_001.png", + "difficulty_auto_btn_001.png" + ]; + const _diffSizes = { + "difficulty_00_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_01_btn_001.png": { w: 60, h: 85, rotated: false }, + "difficulty_02_btn_001.png": { w: 86, h: 85, rotated: false }, + "difficulty_03_btn_001.png": { w: 60, h: 84, rotated: false }, + "difficulty_04_btn_001.png": { w: 85, h: 84, rotated: false }, + "difficulty_05_btn_001.png": { w: 76, h: 85, rotated: false }, + "difficulty_06_btn_001.png": { w: 72, h: 88, rotated: false }, + "difficulty_07_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_08_btn_001.png": { w: 72, h: 85, rotated: false }, + "difficulty_09_btn_001.png": { w: 74, h: 88, rotated: false }, + "difficulty_10_btn_001.png": { w: 80, h: 91, rotated: false }, + "difficulty_auto_btn_001.png": { w: 60, h: 85, rotated: false }, + }; + const _officialGDSongs = [ + "Stereo Madness","Back On Track","Polargeist","Dry Out","Base After Base", + "Can't Let Go","Jumper","Time Machine","Cycles","xStep","Clutterfunk", + "Theory of Everything","Electroman Adventures","Clubstep","Electrodynamix", + "Hexagon Force","Blast Processing","Theory of Everything 2", + "Geometrical Dominator","Deadlocked","Fingerdash","Dash" + ]; + + const rowH = 180; + const rowY = _panelBoundaryTop; + const rowCenterY = rowY + rowH / 2; + const rx = listLeft; + + const diffIdx = Math.min(_diffFrames.length - 1, Math.max(0, levelData.difficulty || 0)); + const _diffMeta = _diffSizes[_diffFrames[diffIdx]]; + const _targetH = 85; + const _maxW = 90; + const _scaleW = _diffMeta ? _diffMeta.w : 90; + const _scaleH = _diffMeta ? _diffMeta.h : 85; + const _scale = Math.min(_targetH / _scaleH, _maxW / _scaleW); + const _diffIconExtraScale = { 6: 1.04, 9: 1.04, 10: 1.1 }[diffIdx] || 1; + const diffIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", _diffFrames[diffIdx]) + .setScrollFactor(0).setDepth(204).setOrigin(0.5).setAlpha(1) + .setDisplaySize(_scaleW * _scale * _diffIconExtraScale, _scaleH * _scale * _diffIconExtraScale); + if (_diffMeta && _diffMeta.rotated) diffIcon.setAngle(90).setFlipY(true); + diffIcon.setMask(_panelMask); + objects.push(diffIcon); + + let coinIcon = null; + if (levelData.epic >= 3) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin3_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 2) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin2_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.epic === 1) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_epicCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } else if (levelData.featured) { + coinIcon = this.add.image(rx + 52, rowCenterY, "GJ_GameSheet03", "GJ_featuredCoin_001.png") + .setScrollFactor(0).setDepth(203).setOrigin(0.5); + } + if (coinIcon) { + coinIcon.setMask(_panelMask); + objects.push(coinIcon); + } + + const nameX = rx + 105; + const btnX = rx + panelW - 88; + const _progressKeyId = "online_" + (levelData.id || "0"); + const _bestPercent = parseFloat(localStorage.getItem("bestPercent_" + _progressKeyId) || "0"); + const _hasBest = _bestPercent > 0; + const _isComplete = _bestPercent >= 100; + const _bestReserve = _isComplete ? 44 : (_hasBest ? 70 : 0); + const _maxTextWidth = (btnX - 70 - 15) - nameX - _bestReserve; + const nameText = this.add.bitmapText(nameX, rowCenterY - 60, "bigFont", levelData.name || "Unknown", 45) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(nameText, _maxTextWidth); + nameText.setMask(_panelMask); + objects.push(nameText); + if (_isComplete) { + const completeIcon = this.add.image(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "GJ_GameSheet03", "GJ_completesIcon_001.png") + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(0.75); + completeIcon.setMask(_panelMask); + objects.push(completeIcon); + } else if (_hasBest) { + const bestPctText = this.add.bitmapText(nameX + 5 + nameText.displayWidth + 14, rowCenterY - 60, "goldFont", Math.floor(_bestPercent) + "%", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5) + bestPctText.setMask(_panelMask); + objects.push(bestPctText); + } + const authorText = this.add.bitmapText(nameX, rowCenterY - 15, "goldFont", "By " + (levelData.author || "Unknown"), 32) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(authorText, _maxTextWidth); + authorText.setMask(_panelMask); + objects.push(authorText); + const _isOfficialSong = _officialGDSongs.includes(levelData.songName); + const songText = this.add.bitmapText(nameX, rowCenterY + 28, "bigFont", levelData.songName || "", 28) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setTint(_isOfficialSong ? 0x00d6ff : 0xff79ff); + this._fitBitmapText(songText, _maxTextWidth); + songText.setMask(_panelMask); + objects.push(songText); + const _statY = rowCenterY + 63; + const _statGap = 25; + const _statDefs = [ + { icon: "GJ_timeIcon_001.png", value: this._getLevelLengthLabel(levelData.length), scale: 0.6 }, + { icon: "GJ_downloadsIcon_001.png", value: this._formatStatCount(levelData.downloads), scale: 0.6 }, + { icon: "GJ_sLikeIcon_001.png", value: this._formatStatCount(levelData.likes), scale: 0.9 } + ]; + let _statX = nameX; + _statDefs.forEach((stat) => { + const statIcon = this.add.image(_statX, _statY, "GJ_GameSheet03", stat.icon) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5).setScale(stat.scale); + statIcon.setMask(_panelMask); + objects.push(statIcon); + const statText = this.add.bitmapText(_statX + statIcon.displayWidth + 8, _statY, "bigFont", stat.value, 26) + .setScrollFactor(0).setDepth(204).setOrigin(0, 0.5); + this._fitBitmapText(statText, _maxTextWidth / 2); + statText.setMask(_panelMask); + objects.push(statText); + _statX += statIcon.displayWidth + 8 + statText.displayWidth + _statGap; + }); + + const _hasViewedLevel = !!localStorage.getItem("viewedLevel_" + (levelData.id || "0")); + const _rowBtnFrame = _hasViewedLevel ? "GJ_button01" : "GJ_button02"; + const _rowBtnLabel = _hasViewedLevel ? "View" : "Get It"; + const _rowBtnLabelSize = _hasViewedLevel ? 40 : 30; + const btn9 = this.add.nineslice(btnX, rowCenterY, _rowBtnFrame, null, 140, 60, 20, 20, 20, 20) + .setScrollFactor(0).setDepth(206).setOrigin(0.5).setInteractive(); + btn9.setMask(_panelMask); + const btnLbl = this.add.bitmapText(btnX - 2, rowCenterY - 4, "bigFont", _rowBtnLabel, _rowBtnLabelSize) + .setScrollFactor(0).setDepth(207).setOrigin(0.5); + btnLbl.setMask(_panelMask); + objects.push(btn9, btnLbl); + + const _btnTargets = [btn9, btnLbl]; + const _baseScale = 1, _pressScale = 1.26; + btn9.on("pointerdown", () => { + btn9._pressed = true; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _pressScale, duration: 300, ease: "Bounce.Out" }); + }); + btn9.on("pointerout", () => { + if (btn9._pressed) { + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets, "scale"); + this.tweens.add({ targets: _btnTargets, scale: _baseScale, duration: 400, ease: "Bounce.Out" }); + } + }); + btn9.on("pointerup", () => { + if (!btn9._pressed) return; + btn9._pressed = false; + this.tweens.killTweensOf(_btnTargets); + btn9.setScale(_baseScale); + btnLbl.setScale(_baseScale); + window._selectedLevelData = levelData; + closeOverlay(false, () => { + this._searchResultOverlay = null; + this._closeSearchResultOverlay = null; + this._openPlayMenu(() => this._openSearchResultScene(levelData)); + }); + }); + + addRow(); + } + + _closeSearchResultScene() { + if (this._searchResultOverlay) { + if (this._closeSearchResultOverlay) { + this._closeSearchResultOverlay(); + } + this._searchResultOverlay = null; + } + } + + _hideEndLayer(_0x272eb1) { + if (!this._endLayerInternal) { + if (_0x272eb1) { + _0x272eb1(); + } + return; + } + const _0x1215e0 = { + p: 0 + }; + this.tweens.add({ + targets: _0x1215e0, + p: 1, + duration: 500, + ease: _0xc1c75 => _0xc1c75 < 0.5 ? Math.pow(_0xc1c75 * 2, 2) / 2 : 1 - Math.pow((1 - _0xc1c75) * 2, 2) / 2, + onUpdate: () => { + this._endLayerInternal.y = _0x1215e0.p * -640; + }, + onComplete: () => { + this._endLayerInternal.destroy(); + this._endLayerInternal = null; + if (this._endLayerOverlay) { + this._endLayerOverlay.destroy(); + this._endLayerOverlay = null; + } + if (_0x272eb1) { + _0x272eb1(); + } + } + }); + this.tweens.add({ + targets: this._endLayerOverlay, + alpha: 0, + duration: 500 + }); + } +} diff --git a/assets/scripts/core/level-editor.js b/assets/scripts/core/level-editor.js index 4b432305..6991b05c 100644 --- a/assets/scripts/core/level-editor.js +++ b/assets/scripts/core/level-editor.js @@ -839,7 +839,7 @@ class LevelEditor { player.setBirdVisible(false); player.setSpiderVisible(false); player.setRobotVisible(false); - player._hitboxTrail = []; + player.setSwingVisible(false); if (player._hitboxGraphics?.clear) player._hitboxGraphics.clear(); }; @@ -1035,6 +1035,8 @@ class LevelEditor { this._player.enterRobotMode(); } else if (gamemode == 6) { this._player.enterSpiderMode(); + } else if (gamemode == 7) { + this._player.enterSwingMode(); } const getBool = (key) => parseInt(window.settingsMap?.[key] || "0", 10) === 1; @@ -1213,9 +1215,9 @@ class LevelEditor { } const primaryGravityBefore = !!this._state.gravityFlipped; - if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && this._state.canJump) { + if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && !this._state.isSwing && this._state.canJump) { this._player.updateJump(0); - } else if (this._state.isUfo) { + } else if (this._state.isUfo || this._state.isSwing) { this._player.updateJump(0); } const primaryGravityChanged = this._isDual && !!this._state.gravityFlipped !== primaryGravityBefore; @@ -1223,7 +1225,8 @@ class LevelEditor { if (primaryGravityChanged) { primaryGravitySynced = this._syncDualGlobalsFromPrimary?.({ skipBallInputGravity: this._state.isBall, - skipSpiderInputGravity: this._state.isSpider + skipSpiderInputGravity: this._state.isSpider, + skipSwingInputGravity: this._state.isSwing }) || false; } @@ -1235,15 +1238,17 @@ class LevelEditor { const secondaryGravityBefore = !!this._state2.gravityFlipped; const secondaryBallInputGravity = this._state2.isBall && this._state2.upKeyPressed; const secondarySpiderInputGravity = this._state2.isSpider && this._state2.upKeyPressed; - if (!this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && this._state2.canJump) { + const secondarySwingInputGravity = this._state2.isSwing && this._state2.upKeyPressed; + if (!this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && !this._state2.isSwing && this._state2.canJump) { this._player2.updateJump(0); - } else if (this._state2.isUfo) { + } else if (this._state2.isUfo || this._state2.isSwing) { this._player2.updateJump(0); } if (!!this._state2.gravityFlipped !== secondaryGravityBefore) { this._syncDualGlobalsFromSecondary?.({ skipBallInputGravity: secondaryBallInputGravity, - skipSpiderInputGravity: secondarySpiderInputGravity + skipSpiderInputGravity: secondarySpiderInputGravity, + skipSwingInputGravity: secondarySwingInputGravity }); } } @@ -1322,7 +1327,8 @@ class LevelEditor { if (this._isDual && primarySharedBefore !== undefined && this._getDualSharedSignature?.(this._state) !== primarySharedBefore) { primaryGravitySynced = this._syncDualGlobalsFromPrimary?.({ skipBallInputGravity: primaryGravityChanged && this._state.isBall && dualInputState.upKeyPressed, - skipSpiderInputGravity: primaryGravityChanged && this._state.isSpider && dualInputState.upKeyPressed + skipSpiderInputGravity: primaryGravityChanged && this._state.isSpider && dualInputState.upKeyPressed, + skipSwingInputGravity: primaryGravityChanged && this._state.isSwing && dualInputState.upKeyPressed }) || false; } @@ -1342,16 +1348,15 @@ class LevelEditor { const secondarySharedBefore = this._getDualSharedSignature?.(this._state2); const secondaryBallInputGravity = this._state2.isBall && this._state2.upKeyPressed; const secondarySpiderInputGravity = this._state2.isSpider && this._state2.upKeyPressed; + const secondarySwingInputGravity = this._state2.isSwing && this._state2.upKeyPressed; this._player2.updateJump(verticalDelta); - if (!this._state2.upKeyPressed) this._state.upKeyPressed = false; - if (!this._state2.queuedHold) this._state.queuedHold = false; - if (this._state2._orbActivationConsumedForPress) this._state._orbActivationConsumedForPress = true; this._state2.y += this._state2.yVelocity * verticalDelta; this._player2.checkCollisions(this._playerWorldX - centerX - horizontalDelta); if (this._isDual && !this._state2.isDead && secondarySharedBefore !== undefined && this._getDualSharedSignature?.(this._state2) !== secondarySharedBefore) { this._syncDualGlobalsFromSecondary?.({ skipBallInputGravity: secondaryBallInputGravity, - skipSpiderInputGravity: secondarySpiderInputGravity + skipSpiderInputGravity: secondarySpiderInputGravity, + skipSwingInputGravity: secondarySwingInputGravity }); } this._resolveDualBallOverlap?.(); @@ -1366,7 +1371,7 @@ class LevelEditor { if (this._state.isDead) break; - if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo) { + if (!this._state.isFlying && !this._state.isWave && !this._state.isUfo && !this._state.isSwing) { if (this._state.isBall) { const ballOnSurface = this._state.onGround || this._state.onCeiling; this._player.updateBallRoll(horizontalDelta, ballOnSurface); @@ -1379,7 +1384,7 @@ class LevelEditor { } } - if (this._isDual && !this._state2.isDead && !this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo) { + if (this._isDual && !this._state2.isDead && !this._state2.isFlying && !this._state2.isWave && !this._state2.isUfo && !this._state2.isSwing) { if (this._state2.isBall) { const ball2OnSurface = this._state2.onGround || this._state2.onCeiling; this._player2.updateBallRoll(horizontalDelta, ball2OnSurface); diff --git a/assets/scripts/core/level.js b/assets/scripts/core/level.js index f4d27f7e..c80ff54b 100644 --- a/assets/scripts/core/level.js +++ b/assets/scripts/core/level.js @@ -318,11 +318,9 @@ function _resolveSlopeDir(objectDef, flipX, objId) { const text = frames.join(" "); let dir = 1; - /* if (/slope_02[^0-9]|slope_04|slope_06|slope_02[bcd]_|pit_0[14]_slope_02|plank_01_slope_02|slope_square_02|slope_square_04|slope_square_05/.test(text)) { dir = -1; } - */ if (flipX) dir = -dir; return dir; @@ -2304,6 +2302,7 @@ window.LevelObject = class LevelObject { 111: "ufo", 745: "robot", 1331: "spider", + 1933: "swing", 747: "teleport", 286: "dual_on", 287: "dual_off" @@ -2322,6 +2321,7 @@ window.LevelObject = class LevelObject { ufo: portalUfoType, robot: "portal_robot", spider: "portal_spider", + swing: "portal_swing", teleport: "portal_teleport", mirrora: "portal_mirror_on", mirrorb: "portal_mirror_off", diff --git a/assets/scripts/core/player.js b/assets/scripts/core/player.js index 9d6c7138..c9c46fb5 100644 --- a/assets/scripts/core/player.js +++ b/assets/scripts/core/player.js @@ -486,6 +486,8 @@ class PlayerObject { if (this._waveSpriteLayer?.sprite) this._waveSpriteLayer.sprite.setTint(this._primaryColor()); if (this._waveGlowLayer?.sprite) this._waveGlowLayer.sprite.setTint(this._secondaryColor()); if (this._waveOverlayLayer?.sprite) this._waveOverlayLayer.sprite.setTint(this._secondaryColor()); + if (this._swingSpriteLayer?.sprite) this._swingSpriteLayer.sprite.setTint(this._primaryColor()); + if (this._swingOverlayLayer?.sprite) this._swingOverlayLayer.sprite.setTint(this._secondaryColor()); if (this._birdSpriteLayer?.sprite) this._birdSpriteLayer.sprite.setTint(this._primaryColor()); if (this._birdGlowLayer?.sprite) this._birdGlowLayer.sprite.setTint(this._secondaryColor()); if (this._birdOverlayLayer?.sprite) this._birdOverlayLayer.sprite.setTint(this._secondaryColor()); @@ -1269,6 +1271,20 @@ class PlayerObject { if (this._shipOverlayLayer) { this._shipOverlayLayer.sprite.setTint(this._secondaryColor()); } + this._swingSpriteLayer = ds(spriteY, particleY, spriteX, `${window.currentSwing}_001.png`, 10, false); + this._swingOverlayLayer = ds(spriteY, particleY, spriteX, `${window.currentSwing}_2_001.png`, 8, false); + this._swingExtraLayer = ds(spriteY, particleY, spriteX, `${window.currentSwing}_extra_001.png`, 12, false); + if (this._swingSpriteLayer) { + this._swingSpriteLayer.sprite.setTint(this._primaryColor()); + } + if (this._swingOverlayLayer) { + this._swingOverlayLayer.sprite.setTint(this._secondaryColor()); + } + if (this._swingExtraLayer) { + this._swingExtraLayer.kind = "extra"; + if (this._swingExtraLayer.sprite.clearTint) this._swingExtraLayer.sprite.clearTint(); + } + this._swingLayers = [this._swingSpriteLayer, this._swingOverlayLayer, this._swingExtraLayer].filter(x => !!x); this._ballGlowLayer = ds(spriteY, particleY, spriteX, `${window.currentBall}_glow_001.png`, 9, false); this._ballSpriteLayer = ds(spriteY, particleY, spriteX, `${window.currentBall}_001.png`, 10, false); this._ballOverlayLayer = ds(spriteY, particleY, spriteX, `${window.currentBall}_2_001.png`, 8, false); @@ -1328,7 +1344,7 @@ class PlayerObject { } this._birdLayers = [this._birdSpriteLayer, this._birdGlowLayer, this._birdOverlayLayer, this._birdExtraLayer].filter(x => !!x); - this._allLayers = [...this._playerLayers, ...this._ballLayers, ...this._waveLayers, ...this._shipLayers, ...this._spiderLayers, ...this._robotLayers, ...this._birdLayers]; + this._allLayers = [...this._playerLayers, ...this._ballLayers, ...this._waveLayers, ...this._shipLayers, ...this._spiderLayers, ...this._robotLayers, ...this._birdLayers, ...this._swingLayers]; this._applyPlayerTints(); this._dashAnimationSprite = spriteY.add.image(particleY, spriteX, "GJ_GameSheetGlow", "playerDash2_001.png"); @@ -1578,7 +1594,7 @@ class PlayerObject { const _0x519d38 = b(this.p.y); this._particleEmitter.particleX = _0x119eb7 - 20; this._particleEmitter.particleY = _0x519d38 + (this.p.gravityFlipped ? (-26 + (this.p.isUfo ? -5 : 0)) : (26 + (this.p.isUfo ? 5 : 0))); - const _0x4436ac = this.p.onGround && !this.p.isFlying && !this.p.isWave; + const _0x4436ac = this.p.onGround && !this.p.isFlying && !this.p.isWave && !this.p.isSwing; if (_0x4436ac && !this._particleActive) { this._particleEmitter.start(); this._particleActive = true; @@ -1589,8 +1605,8 @@ class PlayerObject { { const _0xe76a85 = Math.cos(this._rotation); const _0x26ec65 = Math.sin(this._rotation); - const _0x216018 = this.p.isWave ? 0 : (this.p.isUfo ? 0 : -24); - const _0x2baeac = (this.p.isWave ? 4 : (this.p.isUfo ? 5 : 18)) * (this.p.gravityFlipped ? -1 : 1); + const _0x216018 = this.p.isWave ? 0 : (this.p.isUfo ? 0 : (this.p.isSwing ? 0 : -24)); + const _0x2baeac = (this.p.isWave ? 4 : (this.p.isUfo ? 5 : (this.p.isSwing ? 0 : 18))) * (this.p.gravityFlipped ? -1 : 1); const _0x75c380 = _0x119eb7 + _0x216018 * _0xe76a85 - _0x2baeac * _0x26ec65; const _0x2b31d7 = _0x519d38 + _0x216018 * _0x26ec65 + _0x2baeac * _0xe76a85; const _0x5d66f4 = (Math.random() * 2 - 1) * 2 * 2; @@ -1598,7 +1614,7 @@ class PlayerObject { this._flyParticleEmitter.particleY = _0x2b31d7 + _0x5d66f4; this._flyParticle2Emitter.particleX = _0x75c380; this._flyParticle2Emitter.particleY = _0x2b31d7 + _0x5d66f4; - this._streak.setPosition(this.p.isWave ? _0x75c380 : (this.p.isUfo ? _0x75c380 : _0x75c380 + 8), _0x2b31d7); + this._streak.setPosition(this.p.isWave || this.p.isUfo || this.p.isSwing ? _0x75c380 : _0x75c380 + 8, _0x2b31d7); this._waveTrail.setPosition(_0x119eb7, _0x519d38); } this._streak.update(_0x5af874); @@ -1665,6 +1681,12 @@ class PlayerObject { this._shipExtraLayer.sprite.setVisible(_0x1c5620); } } + setSwingVisible(v) { + for (const layer of (this._swingLayers || [])) { + if (!layer?.sprite) continue; + layer.sprite.setVisible(v); + } + } setBirdVisible(v) { for (const layer of (this._birdLayers || [])) { if (layer === this._birdGlowLayer) { @@ -1847,12 +1869,13 @@ if (this.p.isFlying || this.p.isUfo) { playerLayer.sprite.x = _0x7f0705; playerLayer.sprite.y = _0x1a433c; const isBallLayer = this._ballLayers.includes(playerLayer); - playerLayer.sprite.rotation = isBallLayer ? playerRotation : (this.p.mirrored ? -playerRotation : playerRotation); + const isSwingLayer = this._swingLayers.includes(playerLayer); + playerLayer.sprite.rotation = (isBallLayer || isSwingLayer) ? playerRotation : (this.p.mirrored ? -playerRotation : playerRotation); let _miniS = this.p.isMini ? 0.6 : 1; if (this.p.isWave && this._waveLayers.includes(playerLayer)) { _miniS *= 0.94; //fix wave size } - playerLayer.sprite.scaleY = isBallLayer ? _miniS : (this.p.gravityFlipped ? -_miniS : _miniS); + playerLayer.sprite.scaleY = (isBallLayer || this.p.isSwing) ? _miniS : (this.p.gravityFlipped ? -_miniS : _miniS); playerLayer.sprite.scaleX = (this.p.mirrored ? -_miniS : _miniS); } } @@ -1867,12 +1890,13 @@ if (this.p.isFlying || this.p.isUfo) { playerLayer.sprite.x = _0x7f0705; playerLayer.sprite.y = _0x1a433c; const isBallLayer = this._ballLayers.includes(playerLayer); - playerLayer.sprite.rotation = isBallLayer ? playerRotation : (this.p.mirrored ? -playerRotation : playerRotation); + const isSwingLayer = this._swingLayers.includes(playerLayer); + playerLayer.sprite.rotation = (isBallLayer || isSwingLayer) ? playerRotation : (this.p.mirrored ? -playerRotation : playerRotation); let _miniS = this.p.isMini ? 0.6 : 1; if (this.p.isWave && this._waveLayers.includes(playerLayer)) { _miniS *= 0.94; //fix wave size } - playerLayer.sprite.scaleY = isBallLayer ? _miniS : (this.p.gravityFlipped ? -_miniS : _miniS); + playerLayer.sprite.scaleY = (isBallLayer || this.p.isSwing) ? _miniS : (this.p.gravityFlipped ? -_miniS : _miniS); playerLayer.sprite.scaleX = (this.p.mirrored ? -_miniS : _miniS); } } @@ -1938,6 +1962,7 @@ if (this.p.isFlying || this.p.isUfo) { this.exitRobotMode(); this.exitBallMode(); this.exitWaveMode(); + this.exitSwingMode(); this.p.isFlying = true; this._scene.toggleGlitter(true); if (!fromCheckpoint){ // dont mess with y velocity if ur loading a checkpoint @@ -2004,6 +2029,9 @@ if (this.p.isFlying || this.p.isUfo) { this.exitSpiderMode(); this.exitRobotMode(); this.exitWaveMode(); + this.exitSwingMode(); + this.exitShipMode(); + this.exitUfoMode(); this.p.isBall = true; this.p.ballShouldRotate = false; this.p.ballRotateOpposite = false; @@ -2050,6 +2078,8 @@ if (this.p.isFlying || this.p.isUfo) { this.exitRobotMode(); this.exitShipMode(); this.exitBallMode(); + this.exitSwingMode(); + this.exitUfoMode(); this.p.isWave = true; this.p.yVelocity = 0; this.p.onGround = false; @@ -2102,6 +2132,8 @@ if (this.p.isFlying || this.p.isUfo) { this.exitRobotMode(); this.exitBallMode(); this.exitWaveMode(); + this.exitSwingMode(); + this.exitUfoMode(); const savedPortalYVelocity = Number.isFinite(portalYVelocity) ? portalYVelocity : null; this.p.isSpider = true; if (!enteredFromPortal) this.p.yVelocity = 0; @@ -2162,6 +2194,7 @@ if (this.p.isFlying || this.p.isUfo) { this.exitWaveMode(); this.exitSpiderMode(); this.exitUfoMode(); + this.exitSwingMode(); const savedPortalYVelocity = Number.isFinite(portalYVelocity) ? portalYVelocity : null; this.p.isRobot = true; this.p._robotHold = false; @@ -2198,7 +2231,7 @@ if (this.p.isFlying || this.p.isUfo) { this.stopRotation(); this._rotation = 0; this.setRobotVisible(false); - this.setCubeVisible(!this.p.isBall && !this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSpider); + this.setCubeVisible(!this.p.isBall && !this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSpider && !this.p.isSwing); this._setGamemodeFlyBounds(false, 0); } enterUfoMode(_portal = null, fromCheckpoint = false) { @@ -2208,6 +2241,7 @@ if (this.p.isFlying || this.p.isUfo) { this.exitBallMode(); this.exitWaveMode(); this.exitShipMode(); + this.exitSwingMode(); this.p.isUfo = true; this._scene.toggleGlitter(true); if (!fromCheckpoint){ // dont mess with y velocity if ur loading a checkpoint @@ -2264,9 +2298,62 @@ if (this.p.isFlying || this.p.isUfo) { } this._setGamemodeFlyBounds(false, 0); } + enterSwingMode(_portal = null, fromCheckpoint = false) { + if (this.p.isSwing) return; + this.exitSpiderMode(); + this.exitRobotMode(); + this.exitBallMode(); + this.exitWaveMode(); + this.exitShipMode(); + this.exitUfoMode(); + this.p.isSwing = true; + if (!fromCheckpoint) { + this.p.yVelocity *= 0.5; + } + this.p.onGround = false; + this.p.canJump = false; + this.p.isJumping = false; + this.stopRotation(); + this._rotation = 0; + this._particleEmitter.stop(); + this._streak.reset(); + this._streak.start(); + this.setBallVisible(false); + this.setShipVisible(false); + this.setWaveVisible(false); + this.setSpiderVisible(false); + this.setBirdVisible(false); + this.setCubeVisible(false); + this.setSwingVisible(true); + let _spawnY = this.p.y; + if (_portal) { + _spawnY = _portal.portalY !== undefined ? _portal.portalY : _portal.y; + } + this._setGamemodeFlyBounds(true, _spawnY, f, false); + } + exitSwingMode() { + if (!this.p.isSwing) return; + this.p.isSwing = false; + this.p.yVelocity *= 0.5; + this.p.onGround = false; + this.p.canJump = false; + this.p.isJumping = false; + this._streak.stop(); + this._streak.reset(); + this.stopRotation(); + this._rotation = 0; + this._particleEmitter.stop(); + this.setSwingVisible(false); + this.setCubeVisible(!this.p.isBall && !this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSpider && !this.p.isSwing); + this.setBallVisible(this.p.isBall); + this.setShipVisible(this.p.isFlying); + this.setWaveVisible(this.p.isWave); + this._setGamemodeFlyBounds(false, 0); + } hitGround() { + if (this.p.isSwing) console.log("SWING_HITGROUND", this.p === this._scene?._state2 ? "player2" : "player1", "upKeyDown=" + this.p.upKeyDown, "onCeiling_before=" + this.p.onCeiling); const _0x4a38a5 = !this.p.onGround; - if (!this.p.isFlying && !this.p.isWave && !this.p.isUfo) { + if (!this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSwing) { this.p.lastGroundY = this.p.y; } this.p.yVelocity = 0; @@ -2291,7 +2378,7 @@ if (this.p.isFlying || this.p.isUfo) { this._rotation = 0; } this.stopRotation(); - if (_0x4a38a5 && !this.p.isFlying && !this.p.isWave && !this.p.isSpider && !this._scene?._editorPlaytestActive) { + if (_0x4a38a5 && !this.p.isFlying && !this.p.isWave && !this.p.isSpider && !this.p.isSwing && !this._scene?._editorPlaytestActive) { this._landIdx = !this._landIdx; const _0x31584b = this._landIdx ? this._landEmitter1 : this._landEmitter2; const _0x2248d5 = this._scene._playerWorldX; @@ -3074,7 +3161,7 @@ if (this.p.isFlying || this.p.isUfo) { if (this.p.isFlying) { this.p._slopeBounceActive = true; } - if (!this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSpider && !this.p.isRobot) { + if (!this.p.isFlying && !this.p.isWave && !this.p.isUfo && !this.p.isSpider && !this.p.isRobot && !this.p.isSwing) { this.p.isJumping = true; this._rotation = slopeAngle; this.stopRotation(); @@ -3273,6 +3360,10 @@ if (this.p.isFlying || this.p.isUfo) { this._updateSpiderJump(_0x3d1c6f); } else if (this.p.isRobot) { this._updateRobotJump(_0x3d1c6f); + } else if (this.p.isSwing) { + if (this.p.upKeyPressed) console.log("SWING_CLICK_FIRE", this.p === this._scene?._state2 ? "player2" : "player1", "gravityFlipped=" + this.p.gravityFlipped); + this._updateSwingJump(_0x3d1c6f); + this.updateSwingRotation(_0x3d1c6f); } else if (this.p.upKeyDown && this.p.canJump) { this.p.isJumping = true; this.p.onGround = false; @@ -3389,6 +3480,73 @@ if (this.p.isFlying || this.p.isUfo) { this.p._slopeBounceActive = false; } } + _updateSwingJump(_0x2fe319) { + const _swingGrav = p * 0.4; + const _swingCap = 13; + if (this.p.upKeyPressed) { + this.p.upKeyPressed = false; + this.p.queuedHold = false; + if (this._activeSlopeObj && this._activeSlopeAngle !== null) { + const hitSize = this.p.isMini ? 18 : 30; + this.p.y += this.p.gravityFlipped ? -hitSize : hitSize; + } + this.flipGravity(!this.p.gravityFlipped, 1.0); + this.p.onGround = false; + this.p.onCeiling = false; + this.p.canJump = false; + this.p.isJumping = false; + return; + } + if (this.playerIsFalling() && !this.p._slopeBounceActive) { + this.p.canJump = false; + } + if (!(this.p.onGround || this.p.onCeiling)) { + this.p.yVelocity -= _swingGrav * _0x2fe319 * this.flipMod(); + } else { + this.p.yVelocity = 0; + } + if (this.p.isJumping) { + if (this.playerIsFalling()) { + this.p.isJumping = false; + this.p.onGround = false; + } + } else if (!this.p._slopeBounceActive) { + if (this.p.gravityFlipped) { + this.p.yVelocity = Math.min(this.p.yVelocity, _swingCap); + } else { + this.p.yVelocity = Math.max(this.p.yVelocity, -_swingCap); + } + } + if (this.playerIsFalling()) { + const _fallingHard = this.p.gravityFlipped ? this.p.yVelocity > p * 2 : this.p.yVelocity < -(p * 2); + if (_fallingHard) { + this.p.onGround = false; + } + } + if (this.p._slopeBounceActive && (this.playerIsFalling() || this.p.onGround)) { + this.p._slopeBounceActive = false; + } + } + updateSwingRotation(_0x217ad3) { + if (this._activeSlopeObj && this._onSlopeAngle !== null) { + const targetAngle = this.p.gravityFlipped ? this._onSlopeAngle + Math.PI : this._onSlopeAngle; + const _0x2371ed = 0.47250000000000003; + const _0x1857d4 = Math.min(_0x217ad3 * 1, _0x2371ed * _0x217ad3); + this._rotation = this.slerp2D(this._rotation, targetAngle, _0x1857d4); + return; + } + if ((this.p.onGround || this.p.onCeiling) && !this.p.isJumping) { + const _0x2371ed = 0.25; + const _0x1857d4 = Math.min(_0x217ad3 * 1, _0x2371ed * _0x217ad3); + this._rotation = this.slerp2D(this._rotation, 0, _0x1857d4); + return; + } + const _0x58cb3a = 10.3860036; + const _0x5e6a2b = Math.atan2(-this.p.yVelocity, _0x58cb3a); + const _0x2371ed = 0.15; + const _0x1857d4 = Math.min(_0x217ad3 * 1, _0x2371ed * _0x217ad3); + this._rotation = this.slerp2D(this._rotation, _0x5e6a2b, _0x1857d4); + } _updateBallJump(_0x2fe319) { const _0x144266 = p * 0.6; let prioritizeOrb = this._shouldPrioritizeGroundOrbInput(); @@ -3908,7 +4066,7 @@ _updateWaveJump(dt) { const playersY = this.p.y; const playersLastY = this.p.lastY; const previousCollisionWorldY = Number.isFinite(this._lastCollisionWorldY) ? this._lastCollisionWorldY : playersLastY; - const gamemodeAddition = this.p.isWave ? 0 : (this.p.isFlying || this.p.isUfo ? 12 : 20); + const gamemodeAddition = this.p.isFlying || this.p.isWave || this.p.isUfo || this.p.isSwing ? 12 : 20; this.p.collideTop = 0; this.p.collideBottom = 0; this.p.onCeiling = false; @@ -4048,6 +4206,20 @@ _updateWaveJump(dt) { this.exitBallMode(); this.exitWaveMode(); this.exitUfoMode(); + this.exitSwingMode(); + } + } else if (_colType === "portal_swing") { + if (!this._isObjectActivated(gameObj)) { + this._setObjectActivated(gameObj, true); + this._playPortalShine(gameObj); + this.exitRobotMode(); + this.exitBallMode(); + this.exitWaveMode(); + this.exitShipMode(); + this.exitUfoMode(); + this.exitSpiderMode(); + this.exitSwingMode(); + this.enterSwingMode(gameObj); } } else if (_colType === "portal_ball") { if (!this._isObjectActivated(gameObj)) { @@ -4610,7 +4782,7 @@ _updateWaveJump(dt) { this._activeSlopeObj = bestSlopeGameObj; this._activeSlopeAngle = bestSlopeCandidate.slopeAngle; _0x30410f = true; - if (!this.p.isFlying && !this.p.isWave) { + if (!this.p.isFlying && !this.p.isWave && !this.p.isSwing) { this._checkSnapJump(bestSlopeGameObj); } } @@ -4624,7 +4796,7 @@ _updateWaveJump(dt) { } } let _0x3020c8 = this._gameLayer.getFloorY(); - const iscube = !this.p.isFlying && !this.p.isBall && !this.p.isWave && !this.p.isUfo && !this.p.isSpider; + const iscube = !this.p.isFlying && !this.p.isBall && !this.p.isWave && !this.p.isUfo && !this.p.isSpider && !this.p.isSwing; const _effectiveSize = this.p.isWave ? waveHitSize : playerSize; if (!_0x30410f && !_boostedThisStep) { let gravCeilY = this._gameLayer.getCeilingY(); @@ -4703,14 +4875,14 @@ _updateWaveJump(dt) { this._activeSlopeObj = bestSlopeGameObj; this._activeSlopeAngle = bestSlopeCandidate.slopeAngle; _0x30410f = true; - if (!this.p.isFlying && !this.p.isWave) { + if (!this.p.isFlying && !this.p.isWave && !this.p.isSwing) { this._checkSnapJump(bestSlopeGameObj); } } if (this._prevSlopeObj && !this._activeSlopeObj) { this._applySlopeExitBounce(this._prevSlopeObj, this._prevSlopeAngle, pieceWidth); } - if (this.p.isFlying || this.p.isWave || this.p.isUfo || this.p.isSpider) { + if (this.p.isFlying || this.p.isWave || this.p.isUfo || this.p.isSpider || this.p.isSwing) { const _0x354b7c = this.p.y <= _0x3020c8 + _effectiveSize; const _0xdc296 = _0x496456 !== null && this.p.y >= _0x496456 - _effectiveSize; if (!_0x30410f && !_0x354b7c && this.p.collideTop === 0 && !_0xdc296) { @@ -4755,7 +4927,7 @@ _updateWaveJump(dt) { let hitboxColor = 65280; if (nearObject.type === hazardType) { hitboxColor = 16729156; - } else if (nearObject.type === "portal_fly" || nearObject.type === "portal_cube" || nearObject.type === "portal_ball" || nearObject.type === "portal_robot" || nearObject.type === portalWaveType || nearObject.type === portalUfoType) { + } else if (nearObject.type === "portal_fly" || nearObject.type === "portal_cube" || nearObject.type === "portal_ball" || nearObject.type === "portal_robot" || nearObject.type === "portal_swing" || nearObject.type === portalWaveType || nearObject.type === portalUfoType) { hitboxColor = 4491519; } else if (nearObject.type === "portal_gravity_down" || nearObject.type === "portal_gravity_up" || nearObject.type === "portal_gravity_toggle") { hitboxColor = 16776960; @@ -4939,7 +5111,8 @@ _updateWaveJump(dt) { this._shipSpriteLayer, this._shipGlowLayer, this._shipOverlayLayer, this._shipExtraLayer, ...(this._birdLayers || []), ...(this._spiderLayers || []), - ...(this._robotLayers || []) + ...(this._robotLayers || []), + ...(this._swingLayers || []) ].filter(_0x3e9c62 => _0x3e9c62 && _0x3e9c62.sprite && _0x3e9c62.sprite.visible).map(_0x5cedeb => _0x5cedeb.sprite); this._startPercent = (this._scene._playerWorldX / this._scene._level.endXPos) * 100; this._particleEmitter.stop(); @@ -5086,6 +5259,7 @@ _updateWaveJump(dt) { this.setBirdVisible(false); this.setSpiderVisible(false); this.setRobotVisible(false); + this.setSwingVisible(false); for (const _0x5a0fa9 of this._allLayers) { if (_0x5a0fa9) { _0x5a0fa9.sprite.setAlpha(1); diff --git a/assets/scripts/game/allObjects.js b/assets/scripts/game/allObjects.js index 69523aa6..9f00f3df 100644 --- a/assets/scripts/game/allObjects.js +++ b/assets/scripts/game/allObjects.js @@ -2313,15 +2313,7 @@ window.allobjects = function() { "spritesheet": "GJ_GameSheet-uhd", "default_detail_color_channel": -1, "default_z_layer": 5, - "default_z_order": 2, - "children": [ - { - "frame": "square_g_13_001.png", - "localDy": 0, - "tint": 65280, - "z": -1 - }, - ], + "default_z_order": 2 }, "163": { "can_color": true, @@ -5556,7 +5548,15 @@ window.allobjects = function() { "z": 9, "default_detail_color_channel": -1, "default_z_layer": 3, - "default_z_order": 9 + "default_z_order": 9, + "children": [ + { + "frame": "square_g_13_001.png", + "localDy": 0, + "tint": 65280, + "z": -1 + }, + ], }, "377": { "can_color": true, diff --git a/assets/scripts/utils/config.js b/assets/scripts/utils/config.js index 122b42c1..1aacd73d 100644 --- a/assets/scripts/utils/config.js +++ b/assets/scripts/utils/config.js @@ -12,6 +12,7 @@ window.currentBall = localStorage.getItem("iconCurrentBall") || "player_ball window.currentWave = localStorage.getItem("iconCurrentWave") || "dart_01"; window.currentSpider = localStorage.getItem("iconCurrentSpider") || "spider_01"; window.currentBird = localStorage.getItem("iconCurrentBird") || "bird_01"; +window.currentSwing = localStorage.getItem("iconCurrentSwing") || "swing_01"; const storedUseDirectInternet = localStorage.getItem("gd_useDirectInternet"); window.useDirectInternet = storedUseDirectInternet === null ? true : storedUseDirectInternet === "true"; window.getGdApiBase = function () { diff --git a/assets/sheets/GJ_GameSheetIcons.json b/assets/sheets/GJ_GameSheetIcons.json index 9f55304a..83d4e26f 100644 --- a/assets/sheets/GJ_GameSheetIcons.json +++ b/assets/sheets/GJ_GameSheetIcons.json @@ -2,10 +2,10 @@ "frames": { "bird_01_001.png": { "frame": { - "x": 308, - "y": 792, + "x": 689, + "y": 880, "w": 74, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, @@ -13,7 +13,7 @@ "x": 0, "y": 0, "w": 74, - "h": 31 + "h": 32 }, "sourceSize": { "w": 74, @@ -22,8 +22,8 @@ }, "bird_01_2_001.png": { "frame": { - "x": 948, - "y": 191, + "x": 887, + "y": 629, "w": 70, "h": 28 }, @@ -42,10 +42,10 @@ }, "bird_01_3_001.png": { "frame": { - "x": 1363, - "y": 260, + "x": 0, + "y": 277, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -53,7 +53,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -62,10 +62,10 @@ }, "bird_02_001.png": { "frame": { - "x": 629, - "y": 316, + "x": 252, + "y": 1054, "w": 78, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, @@ -73,7 +73,7 @@ "x": 0, "y": 0, "w": 78, - "h": 36 + "h": 40 }, "sourceSize": { "w": 78, @@ -82,18 +82,18 @@ }, "bird_02_2_001.png": { "frame": { - "x": 948, - "y": 220, + "x": 291, + "y": 1416, "w": 70, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 70, - "h": 29 + "h": 30 }, "sourceSize": { "w": 70, @@ -102,10 +102,10 @@ }, "bird_02_3_001.png": { "frame": { - "x": 1362, - "y": 511, + "x": 63, + "y": 277, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -113,7 +113,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -122,10 +122,10 @@ }, "bird_03_001.png": { "frame": { - "x": 722, - "y": 161, + "x": 988, + "y": 1100, "w": 76, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, @@ -133,7 +133,7 @@ "x": 0, "y": 0, "w": 76, - "h": 33 + "h": 34 }, "sourceSize": { "w": 76, @@ -142,10 +142,10 @@ }, "bird_03_2_001.png": { "frame": { - "x": 600, - "y": 877, + "x": 634, + "y": 557, "w": 72, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, @@ -153,7 +153,7 @@ "x": 0, "y": 0, "w": 72, - "h": 29 + "h": 30 }, "sourceSize": { "w": 72, @@ -162,10 +162,10 @@ }, "bird_03_3_001.png": { "frame": { - "x": 1362, - "y": 300, + "x": 126, + "y": 265, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -173,7 +173,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -182,18 +182,18 @@ }, "bird_04_001.png": { "frame": { - "x": 0, - "y": 591, + "x": 1041, + "y": 144, "w": 80, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 80, - "h": 33 + "h": 34 }, "sourceSize": { "w": 80, @@ -202,18 +202,18 @@ }, "bird_04_2_001.png": { "frame": { - "x": 1090, - "y": 432, + "x": 71, + "y": 1580, "w": 68, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 68, - "h": 29 + "h": 30 }, "sourceSize": { "w": 68, @@ -222,10 +222,10 @@ }, "bird_04_3_001.png": { "frame": { - "x": 1362, - "y": 551, + "x": 189, + "y": 265, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -233,7 +233,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -242,10 +242,10 @@ }, "bird_05_001.png": { "frame": { - "x": 656, - "y": 618, + "x": 1122, + "y": 744, "w": 76, - "h": 38 + "h": 44 }, "rotated": false, "trimmed": true, @@ -253,7 +253,7 @@ "x": 0, "y": 0, "w": 76, - "h": 38 + "h": 44 }, "sourceSize": { "w": 76, @@ -262,10 +262,10 @@ }, "bird_05_2_001.png": { "frame": { - "x": 1295, - "y": 1435, + "x": 640, + "y": 0, "w": 60, - "h": 27 + "h": 30 }, "rotated": false, "trimmed": true, @@ -273,7 +273,7 @@ "x": 0, "y": 0, "w": 60, - "h": 27 + "h": 30 }, "sourceSize": { "w": 60, @@ -282,10 +282,10 @@ }, "bird_05_3_001.png": { "frame": { - "x": 1362, - "y": 340, + "x": 252, + "y": 202, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -293,7 +293,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -302,10 +302,10 @@ }, "bird_06_001.png": { "frame": { - "x": 701, - "y": 788, + "x": 921, + "y": 1218, "w": 74, - "h": 37 + "h": 44 }, "rotated": false, "trimmed": true, @@ -313,7 +313,7 @@ "x": 0, "y": 0, "w": 74, - "h": 37 + "h": 44 }, "sourceSize": { "w": 74, @@ -322,10 +322,10 @@ }, "bird_06_2_001.png": { "frame": { - "x": 673, - "y": 877, + "x": 687, + "y": 1300, "w": 72, - "h": 36 + "h": 42 }, "rotated": false, "trimmed": true, @@ -333,7 +333,7 @@ "x": 0, "y": 0, "w": 72, - "h": 36 + "h": 42 }, "sourceSize": { "w": 72, @@ -342,10 +342,10 @@ }, "bird_06_3_001.png": { "frame": { - "x": 1362, - "y": 591, + "x": 333, + "y": 0, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -353,7 +353,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -362,10 +362,10 @@ }, "bird_07_001.png": { "frame": { - "x": 600, - "y": 843, + "x": 1276, + "y": 370, "w": 72, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, @@ -373,7 +373,7 @@ "x": 0, "y": 0, "w": 72, - "h": 33 + "h": 34 }, "sourceSize": { "w": 72, @@ -382,10 +382,10 @@ }, "bird_07_2_001.png": { "frame": { - "x": 1090, - "y": 462, + "x": 291, + "y": 1447, "w": 68, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, @@ -393,7 +393,7 @@ "x": 0, "y": 0, "w": 68, - "h": 26 + "h": 28 }, "sourceSize": { "w": 68, @@ -402,10 +402,10 @@ }, "bird_07_3_001.png": { "frame": { - "x": 1362, - "y": 380, + "x": 329, + "y": 99, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -413,7 +413,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -422,10 +422,10 @@ }, "bird_08_001.png": { "frame": { - "x": 383, - "y": 792, + "x": 1074, + "y": 1210, "w": 74, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, @@ -433,7 +433,7 @@ "x": 0, "y": 0, "w": 74, - "h": 33 + "h": 34 }, "sourceSize": { "w": 74, @@ -442,18 +442,18 @@ }, "bird_08_2_001.png": { "frame": { - "x": 316, - "y": 645, - "w": 71, - "h": 25 + "x": 1276, + "y": 405, + "w": 72, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 71, - "h": 25 + "w": 72, + "h": 32 }, "sourceSize": { "w": 72, @@ -462,10 +462,10 @@ }, "bird_08_3_001.png": { "frame": { - "x": 1362, - "y": 631, + "x": 317, + "y": 198, "w": 62, - "h": 41 + "h": 98 }, "rotated": false, "trimmed": true, @@ -473,7 +473,7 @@ "x": 0, "y": 0, "w": 62, - "h": 41 + "h": 98 }, "sourceSize": { "w": 62, @@ -482,18 +482,18 @@ }, "bird_09_001.png": { "frame": { - "x": 721, - "y": 195, + "x": 1121, + "y": 789, "w": 76, - "h": 34 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 76, - "h": 34 + "h": 36 }, "sourceSize": { "w": 76, @@ -502,10 +502,10 @@ }, "bird_09_2_001.png": { "frame": { - "x": 746, - "y": 877, + "x": 799, + "y": 1124, "w": 72, - "h": 28 + "h": 30 }, "rotated": false, "trimmed": true, @@ -513,7 +513,7 @@ "x": 0, "y": 0, "w": 72, - "h": 28 + "h": 30 }, "sourceSize": { "w": 72, @@ -522,10 +522,10 @@ }, "bird_09_3_001.png": { "frame": { - "x": 1040, - "y": 1818, + "x": 0, + "y": 376, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -533,7 +533,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -542,18 +542,18 @@ }, "bird_10_001.png": { "frame": { - "x": 1295, - "y": 1463, + "x": 1820, + "y": 849, "w": 60, - "h": 36 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 60, - "h": 36 + "h": 38 }, "sourceSize": { "w": 60, @@ -562,8 +562,8 @@ }, "bird_10_2_001.png": { "frame": { - "x": 1844, - "y": 828, + "x": 1981, + "y": 2167, "w": 52, "h": 30 }, @@ -582,10 +582,10 @@ }, "bird_10_3_001.png": { "frame": { - "x": 1095, - "y": 1818, + "x": 55, + "y": 376, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -593,7 +593,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -602,10 +602,10 @@ }, "bird_11_001.png": { "frame": { - "x": 1133, - "y": 1022, + "x": 692, + "y": 1609, "w": 66, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, @@ -613,7 +613,7 @@ "x": 0, "y": 0, "w": 66, - "h": 36 + "h": 40 }, "sourceSize": { "w": 66, @@ -622,10 +622,10 @@ }, "bird_11_2_001.png": { "frame": { - "x": 392, - "y": 784, + "x": 1886, + "y": 1860, "w": 42, - "h": 7 + "h": 22 }, "rotated": false, "trimmed": true, @@ -633,7 +633,7 @@ "x": 0, "y": 0, "w": 42, - "h": 7 + "h": 22 }, "sourceSize": { "w": 42, @@ -642,10 +642,10 @@ }, "bird_11_3_001.png": { "frame": { - "x": 1150, - "y": 1818, + "x": 110, + "y": 376, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -653,7 +653,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -662,10 +662,10 @@ }, "bird_12_001.png": { "frame": { - "x": 948, - "y": 250, + "x": 1238, + "y": 1438, "w": 70, - "h": 33 + "h": 38 }, "rotated": false, "trimmed": true, @@ -673,7 +673,7 @@ "x": 0, "y": 0, "w": 70, - "h": 33 + "h": 38 }, "sourceSize": { "w": 70, @@ -682,18 +682,18 @@ }, "bird_12_2_001.png": { "frame": { - "x": 709, - "y": 753, + "x": 1019, + "y": 1452, "w": 66, - "h": 21 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 66, - "h": 21 + "h": 24 }, "sourceSize": { "w": 66, @@ -702,10 +702,10 @@ }, "bird_12_3_001.png": { "frame": { - "x": 1205, - "y": 1818, + "x": 165, + "y": 364, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -713,7 +713,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -722,10 +722,10 @@ }, "bird_13_001.png": { "frame": { - "x": 458, - "y": 792, + "x": 1204, + "y": 0, "w": 74, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, @@ -733,7 +733,7 @@ "x": 0, "y": 0, "w": 74, - "h": 31 + "h": 32 }, "sourceSize": { "w": 74, @@ -742,10 +742,10 @@ }, "bird_13_2_001.png": { "frame": { - "x": 223, - "y": 983, + "x": 467, + "y": 1167, "w": 70, - "h": 14 + "h": 22 }, "rotated": false, "trimmed": true, @@ -753,7 +753,7 @@ "x": 0, "y": 0, "w": 70, - "h": 14 + "h": 22 }, "sourceSize": { "w": 70, @@ -762,10 +762,10 @@ }, "bird_13_3_001.png": { "frame": { - "x": 1260, - "y": 1818, + "x": 220, + "y": 364, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -773,7 +773,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -782,10 +782,10 @@ }, "bird_14_001.png": { "frame": { - "x": 800, - "y": 160, + "x": 1204, + "y": 33, "w": 74, - "h": 38 + "h": 46 }, "rotated": false, "trimmed": true, @@ -793,7 +793,7 @@ "x": 0, "y": 0, "w": 74, - "h": 38 + "h": 46 }, "sourceSize": { "w": 74, @@ -802,10 +802,10 @@ }, "bird_14_2_001.png": { "frame": { - "x": 1134, - "y": 996, + "x": 1692, + "y": 849, "w": 64, - "h": 25 + "h": 44 }, "rotated": false, "trimmed": true, @@ -813,7 +813,7 @@ "x": 0, "y": 0, "w": 64, - "h": 25 + "h": 44 }, "sourceSize": { "w": 64, @@ -822,10 +822,10 @@ }, "bird_14_3_001.png": { "frame": { - "x": 1384, - "y": 1799, + "x": 315, + "y": 297, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -833,7 +833,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -842,10 +842,10 @@ }, "bird_15_001.png": { "frame": { - "x": 948, - "y": 284, + "x": 508, + "y": 1416, "w": 70, - "h": 46 + "h": 60 }, "rotated": false, "trimmed": true, @@ -853,7 +853,7 @@ "x": 0, "y": 0, "w": 70, - "h": 46 + "h": 60 }, "sourceSize": { "w": 70, @@ -862,18 +862,18 @@ }, "bird_15_2_001.png": { "frame": { - "x": 682, - "y": 1140, + "x": 620, + "y": 198, "w": 56, - "h": 27 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 56, - "h": 27 + "h": 28 }, "sourceSize": { "w": 56, @@ -882,10 +882,10 @@ }, "bird_15_3_001.png": { "frame": { - "x": 1502, - "y": 1798, + "x": 396, + "y": 0, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -893,7 +893,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -902,10 +902,10 @@ }, "bird_16_001.png": { "frame": { - "x": 166, - "y": 584, + "x": 508, + "y": 1008, "w": 80, - "h": 39 + "h": 46 }, "rotated": false, "trimmed": true, @@ -913,7 +913,7 @@ "x": 0, "y": 0, "w": 80, - "h": 39 + "h": 46 }, "sourceSize": { "w": 80, @@ -922,10 +922,10 @@ }, "bird_16_2_001.png": { "frame": { - "x": 1356, - "y": 1435, + "x": 1820, + "y": 888, "w": 60, - "h": 33 + "h": 44 }, "rotated": false, "trimmed": true, @@ -933,7 +933,7 @@ "x": 0, "y": 0, "w": 60, - "h": 33 + "h": 44 }, "sourceSize": { "w": 60, @@ -942,10 +942,10 @@ }, "bird_16_3_001.png": { "frame": { - "x": 1557, - "y": 1798, + "x": 392, + "y": 99, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -953,7 +953,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -962,10 +962,10 @@ }, "bird_17_001.png": { "frame": { - "x": 1090, - "y": 489, + "x": 140, + "y": 1548, "w": 68, - "h": 47 + "h": 64 }, "rotated": false, "trimmed": true, @@ -973,7 +973,7 @@ "x": 0, "y": 0, "w": 68, - "h": 47 + "h": 64 }, "sourceSize": { "w": 68, @@ -982,10 +982,10 @@ }, "bird_17_2_001.png": { "frame": { - "x": 1417, - "y": 1400, + "x": 252, + "y": 301, "w": 60, - "h": 36 + "h": 62 }, "rotated": false, "trimmed": true, @@ -993,7 +993,7 @@ "x": 0, "y": 0, "w": 60, - "h": 36 + "h": 62 }, "sourceSize": { "w": 60, @@ -1002,10 +1002,10 @@ }, "bird_17_3_001.png": { "frame": { - "x": 1612, - "y": 1798, + "x": 380, + "y": 198, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1013,7 +1013,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -1022,10 +1022,10 @@ }, "bird_18_001.png": { "frame": { - "x": 332, - "y": 558, + "x": 83, + "y": 1008, "w": 80, - "h": 38 + "h": 46 }, "rotated": false, "trimmed": true, @@ -1033,7 +1033,7 @@ "x": 0, "y": 0, "w": 80, - "h": 38 + "h": 46 }, "sourceSize": { "w": 80, @@ -1042,10 +1042,10 @@ }, "bird_18_2_001.png": { "frame": { - "x": 830, - "y": 427, + "x": 1767, + "y": 1964, "w": 44, - "h": 33 + "h": 38 }, "rotated": false, "trimmed": true, @@ -1053,7 +1053,7 @@ "x": 0, "y": 0, "w": 44, - "h": 33 + "h": 38 }, "sourceSize": { "w": 44, @@ -1062,10 +1062,10 @@ }, "bird_18_3_001.png": { "frame": { - "x": 1667, - "y": 1798, + "x": 370, + "y": 297, "w": 54, - "h": 36 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1073,7 +1073,7 @@ "x": 0, "y": 0, "w": 54, - "h": 36 + "h": 98 }, "sourceSize": { "w": 54, @@ -1082,18 +1082,18 @@ }, "bird_19_001.png": { "frame": { - "x": 798, - "y": 199, + "x": 1204, + "y": 80, "w": 74, - "h": 35 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 74, - "h": 35 + "h": 38 }, "sourceSize": { "w": 74, @@ -1102,18 +1102,18 @@ }, "bird_19_2_001.png": { "frame": { - "x": 878, - "y": 0, + "x": 1276, + "y": 438, "w": 72, - "h": 30 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, + "y": 0, "w": 72, - "h": 30 + "h": 38 }, "sourceSize": { "w": 72, @@ -1122,10 +1122,10 @@ }, "bird_19_3_001.png": { "frame": { - "x": 1361, - "y": 673, + "x": 451, + "y": 0, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1133,7 +1133,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1142,10 +1142,10 @@ }, "bird_20_001.png": { "frame": { - "x": 627, - "y": 353, + "x": 83, + "y": 1055, "w": 78, - "h": 38 + "h": 42 }, "rotated": false, "trimmed": true, @@ -1153,7 +1153,7 @@ "x": 0, "y": 0, "w": 78, - "h": 38 + "h": 42 }, "sourceSize": { "w": 78, @@ -1162,10 +1162,10 @@ }, "bird_20_2_001.png": { "frame": { - "x": 717, - "y": 230, + "x": 1121, + "y": 826, "w": 76, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, @@ -1173,7 +1173,7 @@ "x": 0, "y": 0, "w": 76, - "h": 36 + "h": 40 }, "sourceSize": { "w": 76, @@ -1182,10 +1182,10 @@ }, "bird_20_3_001.png": { "frame": { - "x": 1361, - "y": 713, + "x": 447, + "y": 99, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1193,7 +1193,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1202,18 +1202,18 @@ }, "bird_20_extra_001.png": { "frame": { - "x": 228, - "y": 1800, + "x": 1698, + "y": 1529, "w": 46, - "h": 24 + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, + "y": 0, "w": 46, - "h": 24 + "h": 34 }, "sourceSize": { "w": 46, @@ -1222,18 +1222,18 @@ }, "bird_21_001.png": { "frame": { - "x": 1298, - "y": 275, - "w": 63, - "h": 50 + "x": 1688, + "y": 1052, + "w": 64, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 63, - "h": 50 + "y": 0, + "w": 64, + "h": 58 }, "sourceSize": { "w": 64, @@ -1242,18 +1242,18 @@ }, "bird_21_2_001.png": { "frame": { - "x": 1904, - "y": 701, + "x": 1698, + "y": 1472, "w": 46, - "h": 33 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 23, + "y": 0, "w": 46, - "h": 33 + "h": 56 }, "sourceSize": { "w": 46, @@ -1262,10 +1262,10 @@ }, "bird_21_3_001.png": { "frame": { - "x": 1361, - "y": 753, + "x": 435, + "y": 198, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1273,7 +1273,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1282,8 +1282,8 @@ }, "bird_21_extra_001.png": { "frame": { - "x": 918, - "y": 1891, + "x": 1704, + "y": 1014, "w": 48, "h": 36 }, @@ -1302,10 +1302,10 @@ }, "bird_22_001.png": { "frame": { - "x": 295, - "y": 0, + "x": 707, + "y": 557, "w": 90, - "h": 35 + "h": 38 }, "rotated": false, "trimmed": true, @@ -1313,7 +1313,7 @@ "x": 0, "y": 0, "w": 90, - "h": 35 + "h": 38 }, "sourceSize": { "w": 90, @@ -1322,18 +1322,18 @@ }, "bird_22_2_001.png": { "frame": { - "x": 365, - "y": 905, + "x": 1702, + "y": 1296, "w": 54, - "h": 17 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 11, + "y": 0, "w": 54, - "h": 17 + "h": 28 }, "sourceSize": { "w": 54, @@ -1342,10 +1342,10 @@ }, "bird_22_3_001.png": { "frame": { - "x": 1361, - "y": 793, + "x": 425, + "y": 297, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1353,7 +1353,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1362,10 +1362,10 @@ }, "bird_22_extra_001.png": { "frame": { - "x": 104, - "y": 1857, + "x": 54, + "y": 2274, "w": 38, - "h": 24 + "h": 38 }, "rotated": false, "trimmed": true, @@ -1373,7 +1373,7 @@ "x": 0, "y": 0, "w": 38, - "h": 24 + "h": 38 }, "sourceSize": { "w": 38, @@ -1382,10 +1382,10 @@ }, "bird_23_001.png": { "frame": { - "x": 1080, - "y": 537, + "x": 1564, + "y": 461, "w": 68, - "h": 34 + "h": 36 }, "rotated": false, "trimmed": true, @@ -1393,7 +1393,7 @@ "x": 0, "y": 0, "w": 68, - "h": 34 + "h": 36 }, "sourceSize": { "w": 68, @@ -1402,18 +1402,18 @@ }, "bird_23_2_001.png": { "frame": { - "x": 138, - "y": 1171, + "x": 209, + "y": 1548, "w": 66, - "h": 27 + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 66, - "h": 27 + "h": 30 }, "sourceSize": { "w": 66, @@ -1422,10 +1422,10 @@ }, "bird_23_3_001.png": { "frame": { - "x": 1670, - "y": 1308, + "x": 0, + "y": 475, "w": 58, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1433,7 +1433,7 @@ "x": 0, "y": 0, "w": 58, - "h": 39 + "h": 98 }, "sourceSize": { "w": 58, @@ -1442,10 +1442,10 @@ }, "bird_23_extra_001.png": { "frame": { - "x": 0, - "y": 987, + "x": 1157, + "y": 1927, "w": 46, - "h": 10 + "h": 16 }, "rotated": false, "trimmed": true, @@ -1453,7 +1453,7 @@ "x": 0, "y": 0, "w": 46, - "h": 10 + "h": 16 }, "sourceSize": { "w": 46, @@ -1462,8 +1462,8 @@ }, "bird_24_001.png": { "frame": { - "x": 436, - "y": 417, + "x": 255, + "y": 972, "w": 82, "h": 34 }, @@ -1482,8 +1482,8 @@ }, "bird_24_2_001.png": { "frame": { - "x": 81, - "y": 591, + "x": 1041, + "y": 179, "w": 80, "h": 32 }, @@ -1502,10 +1502,10 @@ }, "bird_24_3_001.png": { "frame": { - "x": 1361, - "y": 833, + "x": 59, + "y": 475, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1513,7 +1513,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1522,10 +1522,10 @@ }, "bird_24_extra_001.png": { "frame": { - "x": 0, - "y": 862, + "x": 1495, + "y": 142, "w": 64, - "h": 6 + "h": 20 }, "rotated": false, "trimmed": true, @@ -1533,7 +1533,7 @@ "x": 0, "y": 0, "w": 64, - "h": 6 + "h": 20 }, "sourceSize": { "w": 64, @@ -1542,8 +1542,8 @@ }, "bird_25_001.png": { "frame": { - "x": 1080, - "y": 572, + "x": 1564, + "y": 498, "w": 68, "h": 34 }, @@ -1562,8 +1562,8 @@ }, "bird_25_2_001.png": { "frame": { - "x": 1149, - "y": 569, + "x": 1418, + "y": 1546, "w": 66, "h": 32 }, @@ -1582,10 +1582,10 @@ }, "bird_25_3_001.png": { "frame": { - "x": 1361, - "y": 873, + "x": 122, + "y": 475, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1593,7 +1593,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1602,10 +1602,10 @@ }, "bird_25_extra_001.png": { "frame": { - "x": 1362, - "y": 420, + "x": 1757, + "y": 1104, "w": 62, - "h": 25 + "h": 30 }, "rotated": false, "trimmed": true, @@ -1613,7 +1613,7 @@ "x": 0, "y": 0, "w": 62, - "h": 25 + "h": 30 }, "sourceSize": { "w": 62, @@ -1622,10 +1622,10 @@ }, "bird_26_001.png": { "frame": { - "x": 1149, - "y": 602, + "x": 1175, + "y": 1606, "w": 66, - "h": 40 + "h": 44 }, "rotated": false, "trimmed": true, @@ -1633,7 +1633,7 @@ "x": 0, "y": 0, "w": 66, - "h": 40 + "h": 44 }, "sourceSize": { "w": 66, @@ -1642,10 +1642,10 @@ }, "bird_26_2_001.png": { "frame": { - "x": 1670, - "y": 1348, + "x": 1037, + "y": 1927, "w": 58, - "h": 31 + "h": 44 }, "rotated": false, "trimmed": true, @@ -1653,7 +1653,7 @@ "x": 0, "y": 0, "w": 58, - "h": 31 + "h": 44 }, "sourceSize": { "w": 58, @@ -1662,10 +1662,10 @@ }, "bird_26_3_001.png": { "frame": { - "x": 1361, - "y": 913, + "x": 185, + "y": 463, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1673,7 +1673,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1682,10 +1682,10 @@ }, "bird_26_extra_001.png": { "frame": { - "x": 1670, - "y": 1380, + "x": 1399, + "y": 2007, "w": 58, - "h": 29 + "h": 40 }, "rotated": false, "trimmed": true, @@ -1693,7 +1693,7 @@ "x": 0, "y": 0, "w": 58, - "h": 29 + "h": 40 }, "sourceSize": { "w": 58, @@ -1702,8 +1702,8 @@ }, "bird_27_001.png": { "frame": { - "x": 599, - "y": 427, + "x": 80, + "y": 1098, "w": 78, "h": 34 }, @@ -1722,18 +1722,18 @@ }, "bird_27_2_001.png": { "frame": { - "x": 1149, - "y": 769, + "x": 1309, + "y": 1613, "w": 64, - "h": 27 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 64, - "h": 27 + "h": 32 }, "sourceSize": { "w": 64, @@ -1742,10 +1742,10 @@ }, "bird_27_3_001.png": { "frame": { - "x": 195, - "y": 1330, + "x": 248, + "y": 463, "w": 62, - "h": 45 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1753,7 +1753,7 @@ "x": 0, "y": 0, "w": 62, - "h": 45 + "h": 98 }, "sourceSize": { "w": 62, @@ -1762,10 +1762,10 @@ }, "bird_27_extra_001.png": { "frame": { - "x": 877, - "y": 1778, + "x": 2235, + "y": 1390, "w": 42, - "h": 19 + "h": 24 }, "rotated": false, "trimmed": true, @@ -1773,7 +1773,7 @@ "x": 0, "y": 0, "w": 42, - "h": 19 + "h": 24 }, "sourceSize": { "w": 42, @@ -1782,10 +1782,10 @@ }, "bird_28_001.png": { "frame": { - "x": 878, - "y": 31, + "x": 1276, + "y": 477, "w": 72, - "h": 48 + "h": 56 }, "rotated": false, "trimmed": true, @@ -1793,7 +1793,7 @@ "x": 0, "y": 0, "w": 72, - "h": 48 + "h": 56 }, "sourceSize": { "w": 72, @@ -1802,10 +1802,10 @@ }, "bird_28_2_001.png": { "frame": { - "x": 948, - "y": 331, + "x": 1322, + "y": 1026, "w": 70, - "h": 45 + "h": 54 }, "rotated": false, "trimmed": true, @@ -1813,7 +1813,7 @@ "x": 0, "y": 0, "w": 70, - "h": 45 + "h": 54 }, "sourceSize": { "w": 70, @@ -1822,10 +1822,10 @@ }, "bird_28_3_001.png": { "frame": { - "x": 1361, - "y": 953, + "x": 311, + "y": 396, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1833,7 +1833,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1842,10 +1842,10 @@ }, "bird_28_extra_001.png": { "frame": { - "x": 1080, - "y": 607, + "x": 1564, + "y": 533, "w": 68, - "h": 39 + "h": 46 }, "rotated": false, "trimmed": true, @@ -1853,7 +1853,7 @@ "x": 0, "y": 0, "w": 68, - "h": 39 + "h": 46 }, "sourceSize": { "w": 68, @@ -1862,10 +1862,10 @@ }, "bird_29_001.png": { "frame": { - "x": 794, - "y": 235, + "x": 1204, + "y": 119, "w": 74, - "h": 42 + "h": 52 }, "rotated": false, "trimmed": true, @@ -1873,7 +1873,7 @@ "x": 0, "y": 0, "w": 74, - "h": 42 + "h": 52 }, "sourceSize": { "w": 74, @@ -1882,10 +1882,10 @@ }, "bird_29_2_001.png": { "frame": { - "x": 948, - "y": 377, + "x": 1337, + "y": 770, "w": 70, - "h": 37 + "h": 46 }, "rotated": false, "trimmed": true, @@ -1893,7 +1893,7 @@ "x": 0, "y": 0, "w": 70, - "h": 37 + "h": 46 }, "sourceSize": { "w": 70, @@ -1902,10 +1902,10 @@ }, "bird_29_3_001.png": { "frame": { - "x": 129, - "y": 1332, + "x": 374, + "y": 396, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1913,7 +1913,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -1922,10 +1922,10 @@ }, "bird_29_extra_001.png": { "frame": { - "x": 1149, - "y": 643, + "x": 759, + "y": 1611, "w": 66, - "h": 27 + "h": 38 }, "rotated": false, "trimmed": true, @@ -1933,7 +1933,7 @@ "x": 0, "y": 0, "w": 66, - "h": 27 + "h": 38 }, "sourceSize": { "w": 66, @@ -1942,10 +1942,10 @@ }, "bird_30_001.png": { "frame": { - "x": 0, - "y": 662, + "x": 331, + "y": 1057, "w": 78, - "h": 57 + "h": 78 }, "rotated": false, "trimmed": true, @@ -1953,7 +1953,7 @@ "x": 0, "y": 0, "w": 78, - "h": 57 + "h": 78 }, "sourceSize": { "w": 78, @@ -1962,10 +1962,10 @@ }, "bird_30_2_001.png": { "frame": { - "x": 712, - "y": 698, + "x": 1121, + "y": 867, "w": 76, - "h": 54 + "h": 74 }, "rotated": false, "trimmed": true, @@ -1973,7 +1973,7 @@ "x": 0, "y": 0, "w": 76, - "h": 54 + "h": 74 }, "sourceSize": { "w": 76, @@ -1982,10 +1982,10 @@ }, "bird_30_3_001.png": { "frame": { - "x": 1661, - "y": 1410, + "x": 437, + "y": 396, "w": 58, - "h": 45 + "h": 98 }, "rotated": false, "trimmed": true, @@ -1993,7 +1993,7 @@ "x": 0, "y": 0, "w": 58, - "h": 45 + "h": 98 }, "sourceSize": { "w": 58, @@ -2002,8 +2002,8 @@ }, "bird_30_extra_001.png": { "frame": { - "x": 999, - "y": 1713, + "x": 901, + "y": 502, "w": 56, "h": 28 }, @@ -2022,10 +2022,10 @@ }, "bird_31_001.png": { "frame": { - "x": 717, - "y": 267, + "x": 1097, + "y": 942, "w": 76, - "h": 33 + "h": 36 }, "rotated": false, "trimmed": true, @@ -2033,7 +2033,7 @@ "x": 0, "y": 0, "w": 76, - "h": 33 + "h": 36 }, "sourceSize": { "w": 76, @@ -2042,10 +2042,10 @@ }, "bird_31_2_001.png": { "frame": { - "x": 1080, - "y": 647, + "x": 1564, + "y": 580, "w": 68, - "h": 32 + "h": 36 }, "rotated": false, "trimmed": true, @@ -2053,7 +2053,7 @@ "x": 0, "y": 0, "w": 68, - "h": 32 + "h": 36 }, "sourceSize": { "w": 68, @@ -2062,10 +2062,10 @@ }, "bird_31_3_001.png": { "frame": { - "x": 1361, - "y": 993, + "x": 488, + "y": 297, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2073,7 +2073,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2082,10 +2082,10 @@ }, "bird_32_001.png": { "frame": { - "x": 809, - "y": 612, + "x": 438, + "y": 1292, "w": 72, - "h": 42 + "h": 50 }, "rotated": false, "trimmed": true, @@ -2093,7 +2093,7 @@ "x": 0, "y": 0, "w": 72, - "h": 42 + "h": 50 }, "sourceSize": { "w": 72, @@ -2102,10 +2102,10 @@ }, "bird_32_2_001.png": { "frame": { - "x": 1732, - "y": 483, + "x": 1700, + "y": 567, "w": 56, - "h": 30 + "h": 34 }, "rotated": false, "trimmed": true, @@ -2113,7 +2113,7 @@ "x": 0, "y": 0, "w": 56, - "h": 30 + "h": 34 }, "sourceSize": { "w": 56, @@ -2122,10 +2122,10 @@ }, "bird_32_3_001.png": { "frame": { - "x": 1661, - "y": 1456, + "x": 498, + "y": 198, "w": 58, - "h": 45 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2133,7 +2133,7 @@ "x": 0, "y": 0, "w": 58, - "h": 45 + "h": 98 }, "sourceSize": { "w": 58, @@ -2142,10 +2142,10 @@ }, "bird_32_extra_001.png": { "frame": { - "x": 948, - "y": 415, + "x": 0, + "y": 1417, "w": 70, - "h": 34 + "h": 44 }, "rotated": false, "trimmed": true, @@ -2153,7 +2153,7 @@ "x": 0, "y": 0, "w": 70, - "h": 34 + "h": 44 }, "sourceSize": { "w": 70, @@ -2162,10 +2162,10 @@ }, "bird_33_001.png": { "frame": { - "x": 717, - "y": 301, + "x": 1097, + "y": 979, "w": 76, - "h": 50 + "h": 64 }, "rotated": false, "trimmed": true, @@ -2173,7 +2173,7 @@ "x": 0, "y": 0, "w": 76, - "h": 50 + "h": 64 }, "sourceSize": { "w": 76, @@ -2182,18 +2182,18 @@ }, "bird_33_2_001.png": { "frame": { - "x": 876, - "y": 80, + "x": 1276, + "y": 534, "w": 72, - "h": 27 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 72, - "h": 27 + "h": 32 }, "sourceSize": { "w": 72, @@ -2202,10 +2202,10 @@ }, "bird_33_3_001.png": { "frame": { - "x": 1361, - "y": 1033, + "x": 510, + "y": 99, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2213,7 +2213,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2222,10 +2222,10 @@ }, "bird_33_extra_001.png": { "frame": { - "x": 1196, - "y": 912, + "x": 883, + "y": 1988, "w": 22, - "h": 11 + "h": 18 }, "rotated": false, "trimmed": true, @@ -2233,7 +2233,7 @@ "x": 0, "y": 0, "w": 22, - "h": 11 + "h": 18 }, "sourceSize": { "w": 22, @@ -2242,10 +2242,10 @@ }, "bird_34_001.png": { "frame": { - "x": 708, - "y": 352, + "x": 0, + "y": 1137, "w": 76, - "h": 45 + "h": 54 }, "rotated": false, "trimmed": true, @@ -2253,7 +2253,7 @@ "x": 0, "y": 0, "w": 76, - "h": 45 + "h": 54 }, "sourceSize": { "w": 76, @@ -2262,10 +2262,10 @@ }, "bird_34_2_001.png": { "frame": { - "x": 876, - "y": 108, + "x": 1276, + "y": 567, "w": 72, - "h": 40 + "h": 50 }, "rotated": false, "trimmed": true, @@ -2273,7 +2273,7 @@ "x": 0, "y": 0, "w": 72, - "h": 40 + "h": 50 }, "sourceSize": { "w": 72, @@ -2282,10 +2282,10 @@ }, "bird_34_3_001.png": { "frame": { - "x": 1361, - "y": 1073, + "x": 514, + "y": 0, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2293,7 +2293,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2302,10 +2302,10 @@ }, "bird_34_extra_001.png": { "frame": { - "x": 948, - "y": 450, + "x": 146, + "y": 1417, "w": 70, - "h": 28 + "h": 30 }, "rotated": false, "trimmed": true, @@ -2313,7 +2313,7 @@ "x": 0, "y": 0, "w": 70, - "h": 28 + "h": 30 }, "sourceSize": { "w": 70, @@ -2322,8 +2322,8 @@ }, "bird_35_001.png": { "frame": { - "x": 938, - "y": 479, + "x": 874, + "y": 1416, "w": 70, "h": 34 }, @@ -2342,10 +2342,10 @@ }, "bird_35_2_001.png": { "frame": { - "x": 1149, - "y": 671, + "x": 1546, + "y": 1588, "w": 66, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, @@ -2353,7 +2353,7 @@ "x": 0, "y": 0, "w": 66, - "h": 26 + "h": 28 }, "sourceSize": { "w": 66, @@ -2362,10 +2362,10 @@ }, "bird_35_3_001.png": { "frame": { - "x": 1361, - "y": 1113, + "x": 496, + "y": 396, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2373,7 +2373,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2382,10 +2382,10 @@ }, "bird_35_extra_001.png": { "frame": { - "x": 1231, - "y": 1247, + "x": 1363, + "y": 1713, "w": 64, - "h": 19 + "h": 24 }, "rotated": false, "trimmed": true, @@ -2393,7 +2393,7 @@ "x": 0, "y": 0, "w": 64, - "h": 19 + "h": 24 }, "sourceSize": { "w": 64, @@ -2402,10 +2402,10 @@ }, "bird_36_001.png": { "frame": { - "x": 0, - "y": 509, + "x": 958, + "y": 138, "w": 82, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, @@ -2413,7 +2413,7 @@ "x": 0, "y": 0, "w": 82, - "h": 36 + "h": 40 }, "sourceSize": { "w": 82, @@ -2422,10 +2422,10 @@ }, "bird_36_2_001.png": { "frame": { - "x": 497, - "y": 587, + "x": 1041, + "y": 212, "w": 80, - "h": 34 + "h": 38 }, "rotated": false, "trimmed": true, @@ -2433,7 +2433,7 @@ "x": 0, "y": 0, "w": 80, - "h": 34 + "h": 38 }, "sourceSize": { "w": 80, @@ -2442,10 +2442,10 @@ }, "bird_36_3_001.png": { "frame": { - "x": 1361, - "y": 1153, + "x": 0, + "y": 574, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2453,7 +2453,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2462,10 +2462,10 @@ }, "bird_36_extra_001.png": { "frame": { - "x": 440, - "y": 391, + "x": 848, + "y": 1001, "w": 78, - "h": 23 + "h": 28 }, "rotated": false, "trimmed": true, @@ -2473,7 +2473,7 @@ "x": 0, "y": 0, "w": 78, - "h": 23 + "h": 28 }, "sourceSize": { "w": 78, @@ -2482,10 +2482,10 @@ }, "bird_37_001.png": { "frame": { - "x": 794, - "y": 278, + "x": 1201, + "y": 172, "w": 74, - "h": 35 + "h": 38 }, "rotated": false, "trimmed": true, @@ -2493,7 +2493,7 @@ "x": 0, "y": 0, "w": 74, - "h": 35 + "h": 38 }, "sourceSize": { "w": 74, @@ -2502,10 +2502,10 @@ }, "bird_37_2_001.png": { "frame": { - "x": 876, - "y": 149, + "x": 1275, + "y": 618, "w": 72, - "h": 33 + "h": 36 }, "rotated": false, "trimmed": true, @@ -2513,7 +2513,7 @@ "x": 0, "y": 0, "w": 72, - "h": 33 + "h": 36 }, "sourceSize": { "w": 72, @@ -2522,10 +2522,10 @@ }, "bird_37_3_001.png": { "frame": { - "x": 1361, - "y": 1193, + "x": 63, + "y": 574, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2533,7 +2533,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2542,10 +2542,10 @@ }, "bird_37_extra_001.png": { "frame": { - "x": 850, - "y": 850, + "x": 209, + "y": 1580, "w": 68, - "h": 14 + "h": 32 }, "rotated": false, "trimmed": true, @@ -2553,7 +2553,7 @@ "x": 0, "y": 0, "w": 68, - "h": 14 + "h": 32 }, "sourceSize": { "w": 68, @@ -2562,8 +2562,8 @@ }, "bird_38_001.png": { "frame": { - "x": 81, - "y": 660, + "x": 159, + "y": 1098, "w": 78, "h": 32 }, @@ -2582,18 +2582,18 @@ }, "bird_38_2_001.png": { "frame": { - "x": 751, - "y": 398, + "x": 1037, + "y": 1972, "w": 58, - "h": 24 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 58, - "h": 24 + "h": 28 }, "sourceSize": { "w": 58, @@ -2602,10 +2602,10 @@ }, "bird_38_3_001.png": { "frame": { - "x": 1361, - "y": 1233, + "x": 126, + "y": 574, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2613,7 +2613,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2622,10 +2622,10 @@ }, "bird_38_extra_001.png": { "frame": { - "x": 91, - "y": 355, + "x": 760, + "y": 1314, "w": 72, - "h": 13 + "h": 28 }, "rotated": false, "trimmed": true, @@ -2633,7 +2633,7 @@ "x": 0, "y": 0, "w": 72, - "h": 13 + "h": 28 }, "sourceSize": { "w": 72, @@ -2642,8 +2642,8 @@ }, "bird_39_001.png": { "frame": { - "x": 713, - "y": 657, + "x": 410, + "y": 1134, "w": 76, "h": 32 }, @@ -2662,9 +2662,9 @@ }, "bird_39_2_001.png": { "frame": { - "x": 249, - "y": 1899, - "w": 43, + "x": 511, + "y": 1314, + "w": 72, "h": 28 }, "rotated": false, @@ -2672,7 +2672,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 43, + "w": 72, "h": 28 }, "sourceSize": { @@ -2682,10 +2682,10 @@ }, "bird_39_3_001.png": { "frame": { - "x": 864, - "y": 1332, + "x": 189, + "y": 562, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2693,7 +2693,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2702,9 +2702,9 @@ }, "bird_39_extra_001.png": { "frame": { - "x": 1598, - "y": 1965, - "w": 30, + "x": 1820, + "y": 933, + "w": 60, "h": 28 }, "rotated": false, @@ -2712,7 +2712,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 30, + "w": 60, "h": 28 }, "sourceSize": { @@ -2722,10 +2722,10 @@ }, "bird_40_001.png": { "frame": { - "x": 247, - "y": 591, + "x": 1041, + "y": 251, "w": 80, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, @@ -2733,7 +2733,7 @@ "x": 0, "y": 0, "w": 80, - "h": 31 + "h": 32 }, "sourceSize": { "w": 80, @@ -2742,10 +2742,10 @@ }, "bird_40_2_001.png": { "frame": { - "x": 1297, - "y": 891, + "x": 1757, + "y": 301, "w": 62, - "h": 21 + "h": 24 }, "rotated": false, "trimmed": true, @@ -2753,7 +2753,7 @@ "x": 0, "y": 0, "w": 62, - "h": 21 + "h": 24 }, "sourceSize": { "w": 62, @@ -2762,10 +2762,10 @@ }, "bird_40_3_001.png": { "frame": { - "x": 258, - "y": 1332, + "x": 252, + "y": 562, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2773,7 +2773,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2782,10 +2782,10 @@ }, "bird_40_extra_001.png": { "frame": { - "x": 548, - "y": 765, + "x": 487, + "y": 1136, "w": 74, - "h": 17 + "h": 28 }, "rotated": false, "trimmed": true, @@ -2793,7 +2793,7 @@ "x": 0, "y": 0, "w": 74, - "h": 17 + "h": 28 }, "sourceSize": { "w": 74, @@ -2802,10 +2802,10 @@ }, "bird_41_001.png": { "frame": { - "x": 659, - "y": 538, + "x": 562, + "y": 1122, "w": 76, - "h": 37 + "h": 42 }, "rotated": false, "trimmed": true, @@ -2813,7 +2813,7 @@ "x": 0, "y": 0, "w": 76, - "h": 37 + "h": 42 }, "sourceSize": { "w": 76, @@ -2822,10 +2822,10 @@ }, "bird_41_2_001.png": { "frame": { - "x": 659, - "y": 576, + "x": 909, + "y": 1114, "w": 76, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, @@ -2833,7 +2833,7 @@ "x": 0, "y": 0, "w": 76, - "h": 36 + "h": 40 }, "sourceSize": { "w": 76, @@ -2842,10 +2842,10 @@ }, "bird_41_3_001.png": { "frame": { - "x": 927, - "y": 1332, + "x": 315, + "y": 495, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2853,7 +2853,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2862,10 +2862,10 @@ }, "bird_41_extra_001.png": { "frame": { - "x": 610, - "y": 1535, + "x": 793, + "y": 2048, "w": 58, - "h": 24 + "h": 34 }, "rotated": false, "trimmed": true, @@ -2873,7 +2873,7 @@ "x": 0, "y": 0, "w": 58, - "h": 24 + "h": 34 }, "sourceSize": { "w": 58, @@ -2882,10 +2882,10 @@ }, "bird_42_001.png": { "frame": { - "x": 794, - "y": 314, + "x": 1201, + "y": 211, "w": 74, - "h": 37 + "h": 42 }, "rotated": false, "trimmed": true, @@ -2893,7 +2893,7 @@ "x": 0, "y": 0, "w": 74, - "h": 37 + "h": 42 }, "sourceSize": { "w": 74, @@ -2902,18 +2902,18 @@ }, "bird_42_2_001.png": { "frame": { - "x": 150, - "y": 825, - "w": 73, - "h": 35 + "x": 1201, + "y": 254, + "w": 74, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 73, - "h": 35 + "w": 74, + "h": 40 }, "sourceSize": { "w": 74, @@ -2922,10 +2922,10 @@ }, "bird_42_3_001.png": { "frame": { - "x": 321, - "y": 1332, + "x": 378, + "y": 495, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -2933,7 +2933,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -2942,10 +2942,10 @@ }, "bird_42_extra_001.png": { "frame": { - "x": 680, - "y": 398, + "x": 1309, + "y": 1438, "w": 70, - "h": 24 + "h": 36 }, "rotated": false, "trimmed": true, @@ -2953,7 +2953,7 @@ "x": 0, "y": 0, "w": 70, - "h": 24 + "h": 36 }, "sourceSize": { "w": 70, @@ -2962,10 +2962,10 @@ }, "bird_43_001.png": { "frame": { - "x": 409, - "y": 635, + "x": 162, + "y": 1056, "w": 78, - "h": 35 + "h": 40 }, "rotated": false, "trimmed": true, @@ -2973,7 +2973,7 @@ "x": 0, "y": 0, "w": 78, - "h": 35 + "h": 40 }, "sourceSize": { "w": 78, @@ -2982,10 +2982,10 @@ }, "bird_43_2_001.png": { "frame": { - "x": 660, - "y": 462, + "x": 639, + "y": 1135, "w": 76, - "h": 34 + "h": 38 }, "rotated": false, "trimmed": true, @@ -2993,7 +2993,7 @@ "x": 0, "y": 0, "w": 76, - "h": 34 + "h": 38 }, "sourceSize": { "w": 76, @@ -3002,10 +3002,10 @@ }, "bird_43_3_001.png": { "frame": { - "x": 1149, - "y": 698, + "x": 441, + "y": 495, "w": 66, - "h": 44 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3013,7 +3013,7 @@ "x": 0, "y": 0, "w": 66, - "h": 44 + "h": 98 }, "sourceSize": { "w": 66, @@ -3022,18 +3022,18 @@ }, "bird_43_extra_001.png": { "frame": { - "x": 1752, - "y": 1836, - "w": 37, - "h": 23 + "x": 1201, + "y": 295, + "w": 74, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 37, - "h": 23 + "w": 74, + "h": 32 }, "sourceSize": { "w": 74, @@ -3042,8 +3042,8 @@ }, "bird_44_001.png": { "frame": { - "x": 601, - "y": 392, + "x": 238, + "y": 1097, "w": 78, "h": 32 }, @@ -3062,18 +3062,18 @@ }, "bird_44_2_001.png": { "frame": { - "x": 160, - "y": 671, + "x": 848, + "y": 1030, "w": 78, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 78, - "h": 31 + "h": 32 }, "sourceSize": { "w": 78, @@ -3082,10 +3082,10 @@ }, "bird_44_3_001.png": { "frame": { - "x": 990, - "y": 1332, + "x": 508, + "y": 495, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3093,7 +3093,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3102,10 +3102,10 @@ }, "bird_44_extra_001.png": { "frame": { - "x": 600, - "y": 907, + "x": 833, + "y": 1314, "w": 72, - "h": 15 + "h": 28 }, "rotated": false, "trimmed": true, @@ -3113,7 +3113,7 @@ "x": 0, "y": 0, "w": 72, - "h": 15 + "h": 28 }, "sourceSize": { "w": 72, @@ -3122,10 +3122,10 @@ }, "bird_45_001.png": { "frame": { - "x": 0, - "y": 625, + "x": 1041, + "y": 284, "w": 80, - "h": 36 + "h": 38 }, "rotated": false, "trimmed": true, @@ -3133,7 +3133,7 @@ "x": 0, "y": 0, "w": 80, - "h": 36 + "h": 38 }, "sourceSize": { "w": 80, @@ -3142,10 +3142,10 @@ }, "bird_45_2_001.png": { "frame": { - "x": 81, - "y": 624, + "x": 1041, + "y": 323, "w": 80, - "h": 35 + "h": 38 }, "rotated": false, "trimmed": true, @@ -3153,7 +3153,7 @@ "x": 0, "y": 0, "w": 80, - "h": 35 + "h": 38 }, "sourceSize": { "w": 80, @@ -3162,10 +3162,10 @@ }, "bird_45_3_001.png": { "frame": { - "x": 384, - "y": 1332, + "x": 551, + "y": 297, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3173,7 +3173,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3182,18 +3182,18 @@ }, "bird_45_extra_001.png": { "frame": { - "x": 1904, - "y": 1751, - "w": 42, - "h": 26 + "x": 414, + "y": 1025, + "w": 76, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 42, - "h": 26 + "w": 76, + "h": 30 }, "sourceSize": { "w": 76, @@ -3202,10 +3202,10 @@ }, "bird_46_001.png": { "frame": { - "x": 86, - "y": 417, + "x": 873, + "y": 825, "w": 84, - "h": 45 + "h": 56 }, "rotated": false, "trimmed": true, @@ -3213,7 +3213,7 @@ "x": 0, "y": 0, "w": 84, - "h": 45 + "h": 56 }, "sourceSize": { "w": 84, @@ -3222,10 +3222,10 @@ }, "bird_46_2_001.png": { "frame": { - "x": 0, - "y": 546, + "x": 958, + "y": 179, "w": 82, - "h": 44 + "h": 56 }, "rotated": false, "trimmed": true, @@ -3233,7 +3233,7 @@ "x": 0, "y": 0, "w": 82, - "h": 44 + "h": 56 }, "sourceSize": { "w": 82, @@ -3242,10 +3242,10 @@ }, "bird_46_3_001.png": { "frame": { - "x": 1053, - "y": 1332, + "x": 557, + "y": 198, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3253,7 +3253,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3262,10 +3262,10 @@ }, "bird_46_extra_001.png": { "frame": { - "x": 239, - "y": 671, + "x": 1018, + "y": 939, "w": 78, - "h": 31 + "h": 48 }, "rotated": false, "trimmed": true, @@ -3273,7 +3273,7 @@ "x": 0, "y": 0, "w": 78, - "h": 31 + "h": 48 }, "sourceSize": { "w": 78, @@ -3282,18 +3282,18 @@ }, "bird_47_001.png": { "frame": { - "x": 800, - "y": 75, - "w": 75, - "h": 38 + "x": 77, + "y": 1137, + "w": 76, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 75, - "h": 38 + "w": 76, + "h": 44 }, "sourceSize": { "w": 76, @@ -3302,10 +3302,10 @@ }, "bird_47_2_001.png": { "frame": { - "x": 790, - "y": 656, + "x": 1201, + "y": 328, "w": 74, - "h": 37 + "h": 44 }, "rotated": false, "trimmed": true, @@ -3313,7 +3313,7 @@ "x": 0, "y": 0, "w": 74, - "h": 37 + "h": 44 }, "sourceSize": { "w": 74, @@ -3322,10 +3322,10 @@ }, "bird_47_3_001.png": { "frame": { - "x": 447, - "y": 1332, + "x": 559, + "y": 396, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3333,7 +3333,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3342,18 +3342,18 @@ }, "bird_47_extra_001.png": { "frame": { - "x": 578, - "y": 618, - "w": 33, - "h": 3 + "x": 1579, + "y": 2179, + "w": 34, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 33, - "h": 3 + "w": 34, + "h": 18 }, "sourceSize": { "w": 34, @@ -3362,10 +3362,10 @@ }, "bird_48_001.png": { "frame": { - "x": 938, - "y": 514, + "x": 579, + "y": 1416, "w": 70, - "h": 36 + "h": 38 }, "rotated": false, "trimmed": true, @@ -3373,7 +3373,7 @@ "x": 0, "y": 0, "w": 70, - "h": 36 + "h": 38 }, "sourceSize": { "w": 70, @@ -3382,10 +3382,10 @@ }, "bird_48_2_001.png": { "frame": { - "x": 938, - "y": 551, + "x": 650, + "y": 1416, "w": 70, - "h": 34 + "h": 36 }, "rotated": false, "trimmed": true, @@ -3393,7 +3393,7 @@ "x": 0, "y": 0, "w": 70, - "h": 34 + "h": 36 }, "sourceSize": { "w": 70, @@ -3402,10 +3402,10 @@ }, "bird_48_3_001.png": { "frame": { - "x": 1116, - "y": 1332, + "x": 573, + "y": 99, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3413,7 +3413,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3422,10 +3422,10 @@ }, "bird_48_extra_001.png": { "frame": { - "x": 1149, - "y": 743, + "x": 1546, + "y": 1617, "w": 66, - "h": 25 + "h": 28 }, "rotated": false, "trimmed": true, @@ -3433,7 +3433,7 @@ "x": 0, "y": 0, "w": 66, - "h": 25 + "h": 28 }, "sourceSize": { "w": 66, @@ -3442,8 +3442,8 @@ }, "bird_49_001.png": { "frame": { - "x": 678, - "y": 425, + "x": 716, + "y": 1155, "w": 76, "h": 36 }, @@ -3462,8 +3462,8 @@ }, "bird_49_2_001.png": { "frame": { - "x": 660, - "y": 497, + "x": 793, + "y": 1155, "w": 76, "h": 34 }, @@ -3482,10 +3482,10 @@ }, "bird_49_3_001.png": { "frame": { - "x": 1179, - "y": 1332, + "x": 577, + "y": 0, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3493,7 +3493,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3502,10 +3502,10 @@ }, "bird_49_extra_001.png": { "frame": { - "x": 243, - "y": 645, + "x": 1275, + "y": 655, "w": 72, - "h": 24 + "h": 32 }, "rotated": false, "trimmed": true, @@ -3513,7 +3513,7 @@ "x": 0, "y": 0, "w": 72, - "h": 24 + "h": 32 }, "sourceSize": { "w": 72, @@ -3522,10 +3522,10 @@ }, "bird_50_001.png": { "frame": { - "x": 789, - "y": 694, + "x": 1201, + "y": 373, "w": 74, - "h": 44 + "h": 50 }, "rotated": false, "trimmed": true, @@ -3533,7 +3533,7 @@ "x": 0, "y": 0, "w": 74, - "h": 44 + "h": 50 }, "sourceSize": { "w": 74, @@ -3542,18 +3542,18 @@ }, "bird_50_2_001.png": { "frame": { - "x": 1597, - "y": 1586, + "x": 1219, + "y": 2045, "w": 58, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 58, - "h": 26 + "h": 28 }, "sourceSize": { "w": 58, @@ -3562,10 +3562,10 @@ }, "bird_50_3_001.png": { "frame": { - "x": 1242, - "y": 1332, + "x": 571, + "y": 495, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3573,7 +3573,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3582,10 +3582,10 @@ }, "bird_50_extra_001.png": { "frame": { - "x": 938, - "y": 586, + "x": 1424, + "y": 0, "w": 70, - "h": 28 + "h": 44 }, "rotated": false, "trimmed": true, @@ -3593,7 +3593,7 @@ "x": 0, "y": 0, "w": 70, - "h": 28 + "h": 44 }, "sourceSize": { "w": 70, @@ -3602,10 +3602,10 @@ }, "bird_51_001.png": { "frame": { - "x": 789, - "y": 739, + "x": 1201, + "y": 424, "w": 74, - "h": 37 + "h": 42 }, "rotated": false, "trimmed": true, @@ -3613,7 +3613,7 @@ "x": 0, "y": 0, "w": 74, - "h": 37 + "h": 42 }, "sourceSize": { "w": 74, @@ -3622,10 +3622,10 @@ }, "bird_51_2_001.png": { "frame": { - "x": 875, - "y": 183, + "x": 1275, + "y": 688, "w": 72, - "h": 35 + "h": 40 }, "rotated": false, "trimmed": true, @@ -3633,7 +3633,7 @@ "x": 0, "y": 0, "w": 72, - "h": 35 + "h": 40 }, "sourceSize": { "w": 72, @@ -3642,10 +3642,10 @@ }, "bird_51_3_001.png": { "frame": { - "x": 1305, - "y": 1332, + "x": 614, + "y": 297, "w": 62, - "h": 39 + "h": 98 }, "rotated": false, "trimmed": true, @@ -3653,7 +3653,7 @@ "x": 0, "y": 0, "w": 62, - "h": 39 + "h": 98 }, "sourceSize": { "w": 62, @@ -3662,10 +3662,10 @@ }, "bird_51_extra_001.png": { "frame": { - "x": 811, - "y": 596, + "x": 146, + "y": 1448, "w": 70, - "h": 14 + "h": 28 }, "rotated": false, "trimmed": true, @@ -3673,7 +3673,7 @@ "x": 0, "y": 0, "w": 70, - "h": 14 + "h": 28 }, "sourceSize": { "w": 70, @@ -3682,18 +3682,18 @@ }, "dart_01_001.png": { "frame": { - "x": 1844, - "y": 1190, + "x": 2182, + "y": 1010, "w": 52, - "h": 41 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 52, - "h": 41 + "h": 42 }, "sourceSize": { "w": 52, @@ -3702,9 +3702,9 @@ }, "dart_01_2_001.png": { "frame": { - "x": 1315, - "y": 1818, - "w": 10, + "x": 744, + "y": 1650, + "w": 42, "h": 20 }, "rotated": false, @@ -3712,7 +3712,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 10, + "w": 42, "h": 20 }, "sourceSize": { @@ -3722,18 +3722,18 @@ }, "dart_02_001.png": { "frame": { - "x": 1844, - "y": 859, + "x": 2182, + "y": 1053, "w": 52, - "h": 41 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 52, - "h": 41 + "h": 42 }, "sourceSize": { "w": 52, @@ -3742,9 +3742,9 @@ }, "dart_02_2_001.png": { "frame": { - "x": 1936, - "y": 1967, - "w": 29, + "x": 1096, + "y": 1986, + "w": 42, "h": 20 }, "rotated": false, @@ -3752,7 +3752,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 29, + "w": 42, "h": 20 }, "sourceSize": { @@ -3762,18 +3762,18 @@ }, "dart_03_001.png": { "frame": { - "x": 1661, - "y": 1502, - "w": 58, - "h": 41 + "x": 1374, + "y": 1613, + "w": 64, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 58, - "h": 41 + "y": 0, + "w": 64, + "h": 42 }, "sourceSize": { "w": 64, @@ -3782,9 +3782,9 @@ }, "dart_03_2_001.png": { "frame": { - "x": 1792, - "y": 257, - "w": 49, + "x": 650, + "y": 1453, + "w": 58, "h": 22 }, "rotated": false, @@ -3792,7 +3792,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 49, + "w": 58, "h": 22 }, "sourceSize": { @@ -3802,18 +3802,18 @@ }, "dart_04_001.png": { "frame": { - "x": 1844, - "y": 1232, + "x": 2182, + "y": 1096, "w": 52, - "h": 41 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 52, - "h": 41 + "h": 42 }, "sourceSize": { "w": 52, @@ -3822,9 +3822,9 @@ }, "dart_04_2_001.png": { "frame": { - "x": 1904, - "y": 1897, - "w": 41, + "x": 2235, + "y": 1186, + "w": 44, "h": 32 }, "rotated": false, @@ -3832,7 +3832,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 41, + "w": 44, "h": 32 }, "sourceSize": { @@ -3842,9 +3842,9 @@ }, "dart_05_001.png": { "frame": { - "x": 1452, - "y": 1683, - "w": 57, + "x": 1680, + "y": 1574, + "w": 64, "h": 40 }, "rotated": false, @@ -3852,7 +3852,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 57, + "w": 64, "h": 40 }, "sourceSize": { @@ -3862,9 +3862,9 @@ }, "dart_05_2_001.png": { "frame": { - "x": 765, - "y": 1857, - "w": 47, + "x": 1218, + "y": 1917, + "w": 54, "h": 26 }, "rotated": false, @@ -3872,7 +3872,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 47, + "w": 54, "h": 26 }, "sourceSize": { @@ -3882,18 +3882,18 @@ }, "dart_06_001.png": { "frame": { - "x": 1670, - "y": 725, - "w": 59, - "h": 41 + "x": 1242, + "y": 1613, + "w": 66, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 59, - "h": 41 + "y": 0, + "w": 66, + "h": 42 }, "sourceSize": { "w": 66, @@ -3902,9 +3902,9 @@ }, "dart_06_2_001.png": { "frame": { - "x": 1952, - "y": 577, - "w": 32, + "x": 620, + "y": 1650, + "w": 62, "h": 20 }, "rotated": false, @@ -3912,7 +3912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 32, + "w": 62, "h": 20 }, "sourceSize": { @@ -3922,18 +3922,18 @@ }, "dart_07_001.png": { "frame": { - "x": 1732, - "y": 514, - "w": 56, - "h": 41 + "x": 1820, + "y": 962, + "w": 60, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 56, - "h": 41 + "y": 0, + "w": 60, + "h": 42 }, "sourceSize": { "w": 60, @@ -3942,9 +3942,9 @@ }, "dart_07_2_001.png": { "frame": { - "x": 595, - "y": 380, - "w": 29, + "x": 816, + "y": 546, + "w": 36, "h": 10 }, "rotated": false, @@ -3952,7 +3952,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 29, + "w": 36, "h": 10 }, "sourceSize": { @@ -3962,9 +3962,9 @@ }, "dart_08_001.png": { "frame": { - "x": 1844, - "y": 901, - "w": 52, + "x": 1458, + "y": 2007, + "w": 58, "h": 48 }, "rotated": false, @@ -3972,7 +3972,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 52, + "w": 58, "h": 48 }, "sourceSize": { @@ -3982,9 +3982,9 @@ }, "dart_08_2_001.png": { "frame": { - "x": 1039, - "y": 1799, - "w": 34, + "x": 304, + "y": 1249, + "w": 54, "h": 18 }, "rotated": false, @@ -3992,7 +3992,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 34, + "w": 54, "h": 18 }, "sourceSize": { @@ -4002,18 +4002,18 @@ }, "dart_09_001.png": { "frame": { - "x": 1849, - "y": 0, - "w": 54, - "h": 41 + "x": 1700, + "y": 602, + "w": 56, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 54, - "h": 41 + "y": 0, + "w": 56, + "h": 42 }, "sourceSize": { "w": 56, @@ -4022,9 +4022,9 @@ }, "dart_09_2_001.png": { "frame": { - "x": 1192, - "y": 1855, - "w": 33, + "x": 1699, + "y": 826, + "w": 52, "h": 22 }, "rotated": false, @@ -4032,7 +4032,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 33, + "w": 52, "h": 22 }, "sourceSize": { @@ -4042,8 +4042,8 @@ }, "dart_10_001.png": { "frame": { - "x": 1844, - "y": 950, + "x": 2182, + "y": 1139, "w": 52, "h": 40 }, @@ -4062,9 +4062,9 @@ }, "dart_10_2_001.png": { "frame": { - "x": 293, - "y": 1899, - "w": 36, + "x": 2189, + "y": 2177, + "w": 46, "h": 24 }, "rotated": false, @@ -4072,7 +4072,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, + "w": 46, "h": 24 }, "sourceSize": { @@ -4082,18 +4082,18 @@ }, "dart_11_001.png": { "frame": { - "x": 1844, - "y": 991, + "x": 2182, + "y": 1180, "w": 52, - "h": 41 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 52, - "h": 41 + "h": 42 }, "sourceSize": { "w": 52, @@ -4102,8 +4102,8 @@ }, "dart_11_2_001.png": { "frame": { - "x": 1056, - "y": 1724, + "x": 1273, + "y": 1927, "w": 44, "h": 16 }, @@ -4122,9 +4122,9 @@ }, "dart_12_001.png": { "frame": { - "x": 1315, - "y": 1839, - "w": 51, + "x": 1767, + "y": 1925, + "w": 56, "h": 38 }, "rotated": false, @@ -4132,7 +4132,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 51, + "w": 56, "h": 38 }, "sourceSize": { @@ -4142,9 +4142,9 @@ }, "dart_12_2_001.png": { "frame": { - "x": 1950, - "y": 1087, - "w": 23, + "x": 2237, + "y": 326, + "w": 48, "h": 32 }, "rotated": false, @@ -4152,7 +4152,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 48, "h": 32 }, "sourceSize": { @@ -4162,17 +4162,17 @@ }, "dart_13_001.png": { "frame": { - "x": 1596, - "y": 1836, - "w": 51, + "x": 2182, + "y": 1223, + "w": 52, "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 51, + "w": 52, "h": 42 }, "sourceSize": { @@ -4182,9 +4182,9 @@ }, "dart_13_2_001.png": { "frame": { - "x": 1211, - "y": 1995, - "w": 18, + "x": 799, + "y": 1094, + "w": 30, "h": 18 }, "rotated": false, @@ -4192,7 +4192,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 18, + "w": 30, "h": 18 }, "sourceSize": { @@ -4202,9 +4202,9 @@ }, "dart_14_001.png": { "frame": { - "x": 1846, - "y": 698, - "w": 53, + "x": 2038, + "y": 2122, + "w": 54, "h": 44 }, "rotated": false, @@ -4212,7 +4212,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 53, + "w": 54, "h": 44 }, "sourceSize": { @@ -4222,9 +4222,9 @@ }, "dart_14_2_001.png": { "frame": { - "x": 1987, - "y": 831, - "w": 25, + "x": 2034, + "y": 2167, + "w": 52, "h": 30 }, "rotated": false, @@ -4232,7 +4232,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 52, "h": 30 }, "sourceSize": { @@ -4242,9 +4242,9 @@ }, "dart_15_001.png": { "frame": { - "x": 1843, - "y": 1356, - "w": 52, + "x": 1475, + "y": 2138, + "w": 54, "h": 42 }, "rotated": false, @@ -4252,7 +4252,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 52, + "w": 54, "h": 42 }, "sourceSize": { @@ -4262,18 +4262,18 @@ }, "dart_15_2_001.png": { "frame": { - "x": 1890, - "y": 1778, - "w": 42, - "h": 39 + "x": 2237, + "y": 359, + "w": 48, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 1, - "w": 42, - "h": 39 + "x": 0, + "y": 0, + "w": 48, + "h": 40 }, "sourceSize": { "w": 48, @@ -4282,18 +4282,18 @@ }, "dart_16_001.png": { "frame": { - "x": 1845, - "y": 743, - "w": 53, - "h": 43 - }, + "x": 2066, + "y": 1372, + "w": 56, + "h": 44 + }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 53, - "h": 43 + "y": 0, + "w": 56, + "h": 44 }, "sourceSize": { "w": 56, @@ -4302,18 +4302,18 @@ }, "dart_16_2_001.png": { "frame": { - "x": 1904, + "x": 2182, "y": 1266, - "w": 44, - "h": 41 + "w": 52, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 44, - "h": 41 + "y": 0, + "w": 52, + "h": 42 }, "sourceSize": { "w": 52, @@ -4322,18 +4322,18 @@ }, "dart_17_001.png": { "frame": { - "x": 1843, - "y": 1399, - "w": 52, - "h": 45 + "x": 2093, + "y": 2124, + "w": 54, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 52, - "h": 45 + "y": 0, + "w": 54, + "h": 46 }, "sourceSize": { "w": 54, @@ -4342,17 +4342,17 @@ }, "dart_17_2_001.png": { "frame": { - "x": 1952, - "y": 144, - "w": 35, + "x": 872, + "y": 1124, + "w": 36, "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 35, + "w": 36, "h": 30 }, "sourceSize": { @@ -4362,9 +4362,9 @@ }, "dart_18_001.png": { "frame": { - "x": 1844, - "y": 1097, - "w": 53, + "x": 2066, + "y": 1417, + "w": 56, "h": 40 }, "rotated": false, @@ -4372,7 +4372,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 53, + "w": 56, "h": 40 }, "sourceSize": { @@ -4382,9 +4382,9 @@ }, "dart_18_2_001.png": { "frame": { - "x": 1370, - "y": 1273, - "w": 52, + "x": 671, + "y": 2056, + "w": 54, "h": 26 }, "rotated": false, @@ -4392,7 +4392,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 52, + "w": 54, "h": 26 }, "sourceSize": { @@ -4402,9 +4402,9 @@ }, "dart_19_001.png": { "frame": { - "x": 1904, - "y": 482, - "w": 47, + "x": 2182, + "y": 0, + "w": 54, "h": 46 }, "rotated": false, @@ -4412,7 +4412,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 47, + "w": 54, "h": 46 }, "sourceSize": { @@ -4422,9 +4422,9 @@ }, "dart_19_2_001.png": { "frame": { - "x": 806, - "y": 1140, - "w": 35, + "x": 1685, + "y": 2198, + "w": 50, "h": 42 }, "rotated": false, @@ -4432,7 +4432,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 35, + "w": 50, "h": 42 }, "sourceSize": { @@ -4442,9 +4442,9 @@ }, "dart_20_001.png": { "frame": { - "x": 1844, - "y": 787, - "w": 53, + "x": 1435, + "y": 1162, + "w": 54, "h": 40 }, "rotated": false, @@ -4452,7 +4452,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 53, + "w": 54, "h": 40 }, "sourceSize": { @@ -4462,9 +4462,9 @@ }, "dart_20_2_001.png": { "frame": { - "x": 329, - "y": 305, - "w": 23, + "x": 1701, + "y": 438, + "w": 30, "h": 8 }, "rotated": false, @@ -4472,7 +4472,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 30, "h": 8 }, "sourceSize": { @@ -4482,9 +4482,9 @@ }, "dart_21_001.png": { "frame": { - "x": 663, - "y": 1882, - "w": 50, + "x": 2182, + "y": 1309, + "w": 52, "h": 44 }, "rotated": false, @@ -4492,7 +4492,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 50, + "w": 52, "h": 44 }, "sourceSize": { @@ -4502,9 +4502,9 @@ }, "dart_21_2_001.png": { "frame": { - "x": 1983, - "y": 1139, - "w": 29, + "x": 1645, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, @@ -4512,7 +4512,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 29, + "w": 34, "h": 18 }, "sourceSize": { @@ -4522,9 +4522,9 @@ }, "dart_22_001.png": { "frame": { - "x": 1648, - "y": 1836, - "w": 51, + "x": 1517, + "y": 2007, + "w": 58, "h": 36 }, "rotated": false, @@ -4532,7 +4532,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 51, + "w": 58, "h": 36 }, "sourceSize": { @@ -4542,9 +4542,9 @@ }, "dart_22_2_001.png": { "frame": { - "x": 1904, - "y": 529, - "w": 47, + "x": 2182, + "y": 47, + "w": 54, "h": 32 }, "rotated": false, @@ -4552,7 +4552,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 47, + "w": 54, "h": 32 }, "sourceSize": { @@ -4562,9 +4562,9 @@ }, "dart_23_001.png": { "frame": { - "x": 1849, - "y": 42, - "w": 54, + "x": 2066, + "y": 1458, + "w": 56, "h": 42 }, "rotated": false, @@ -4572,7 +4572,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 54, + "w": 56, "h": 42 }, "sourceSize": { @@ -4582,18 +4582,18 @@ }, "dart_23_2_001.png": { "frame": { - "x": 1700, - "y": 1836, - "w": 51, - "h": 37 + "x": 1747, + "y": 2158, + "w": 52, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 51, - "h": 37 + "y": 0, + "w": 52, + "h": 38 }, "sourceSize": { "w": 52, @@ -4602,9 +4602,9 @@ }, "dart_24_001.png": { "frame": { - "x": 449, - "y": 1886, - "w": 50, + "x": 2182, + "y": 1354, + "w": 52, "h": 40 }, "rotated": false, @@ -4612,7 +4612,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 50, + "w": 52, "h": 40 }, "sourceSize": { @@ -4622,9 +4622,9 @@ }, "dart_24_2_001.png": { "frame": { - "x": 1387, - "y": 1889, - "w": 46, + "x": 2237, + "y": 400, + "w": 48, "h": 38 }, "rotated": false, @@ -4632,7 +4632,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 46, + "w": 48, "h": 38 }, "sourceSize": { @@ -4642,17 +4642,17 @@ }, "dart_24_extra_001.png": { "frame": { - "x": 86, - "y": 463, - "w": 23, + "x": 93, + "y": 781, + "w": 40, "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, + "x": 0, "y": 0, - "w": 23, + "w": 40, "h": 4 }, "sourceSize": { @@ -4662,18 +4662,18 @@ }, "dart_25_001.png": { "frame": { - "x": 1648, - "y": 1873, - "w": 51, - "h": 36 + "x": 2182, + "y": 1395, + "w": 52, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 51, - "h": 36 + "y": 0, + "w": 52, + "h": 38 }, "sourceSize": { "w": 52, @@ -4682,17 +4682,17 @@ }, "dart_25_2_001.png": { "frame": { - "x": 1946, - "y": 1897, - "w": 33, + "x": 2232, + "y": 1731, + "w": 40, "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 33, + "w": 40, "h": 32 }, "sourceSize": { @@ -4702,9 +4702,9 @@ }, "dart_26_001.png": { "frame": { - "x": 1596, - "y": 1879, - "w": 51, + "x": 2182, + "y": 80, + "w": 54, "h": 40 }, "rotated": false, @@ -4712,7 +4712,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 51, + "w": 54, "h": 40 }, "sourceSize": { @@ -4722,9 +4722,9 @@ }, "dart_26_2_001.png": { "frame": { - "x": 1987, - "y": 1046, - "w": 25, + "x": 1352, + "y": 2278, + "w": 32, "h": 30 }, "rotated": false, @@ -4732,7 +4732,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 32, "h": 30 }, "sourceSize": { @@ -4742,18 +4742,18 @@ }, "dart_27_001.png": { "frame": { - "x": 1847, - "y": 1819, - "w": 53, - "h": 36 + "x": 2182, + "y": 121, + "w": 54, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 53, - "h": 36 + "w": 54, + "h": 40 }, "sourceSize": { "w": 54, @@ -4762,17 +4762,17 @@ }, "dart_27_2_001.png": { "frame": { - "x": 740, - "y": 1995, - "w": 25, + "x": 2284, + "y": 1050, + "w": 28, "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 25, + "w": 28, "h": 24 }, "sourceSize": { @@ -4782,17 +4782,17 @@ }, "dart_28_001.png": { "frame": { - "x": 1904, - "y": 562, - "w": 47, + "x": 2213, + "y": 2070, + "w": 48, "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 47, + "w": 48, "h": 42 }, "sourceSize": { @@ -4802,9 +4802,9 @@ }, "dart_28_2_001.png": { "frame": { - "x": 1952, - "y": 482, - "w": 35, + "x": 906, + "y": 1316, + "w": 40, "h": 24 }, "rotated": false, @@ -4812,7 +4812,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 35, + "w": 40, "h": 24 }, "sourceSize": { @@ -4822,9 +4822,9 @@ }, "dart_29_001.png": { "frame": { - "x": 1849, - "y": 85, - "w": 54, + "x": 1576, + "y": 2007, + "w": 58, "h": 42 }, "rotated": false, @@ -4832,7 +4832,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 54, + "w": 58, "h": 42 }, "sourceSize": { @@ -4842,9 +4842,9 @@ }, "dart_29_2_001.png": { "frame": { - "x": 1339, - "y": 1889, - "w": 47, + "x": 2182, + "y": 162, + "w": 54, "h": 38 }, "rotated": false, @@ -4852,7 +4852,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 47, + "w": 54, "h": 38 }, "sourceSize": { @@ -4862,9 +4862,9 @@ }, "dart_29_extra_001.png": { "frame": { - "x": 600, - "y": 826, - "w": 24, + "x": 1572, + "y": 997, + "w": 36, "h": 10 }, "rotated": false, @@ -4872,7 +4872,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, + "w": 36, "h": 10 }, "sourceSize": { @@ -4882,9 +4882,9 @@ }, "dart_30_001.png": { "frame": { - "x": 1854, - "y": 1856, - "w": 49, + "x": 870, + "y": 1155, + "w": 50, "h": 34 }, "rotated": false, @@ -4892,7 +4892,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 49, + "w": 50, "h": 34 }, "sourceSize": { @@ -4902,9 +4902,9 @@ }, "dart_30_2_001.png": { "frame": { - "x": 1904, - "y": 1688, - "w": 43, + "x": 2236, + "y": 2199, + "w": 46, "h": 30 }, "rotated": false, @@ -4912,7 +4912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 43, + "w": 46, "h": 30 }, "sourceSize": { @@ -4922,17 +4922,17 @@ }, "dart_30_extra_001.png": { "frame": { - "x": 548, - "y": 745, - "w": 6, + "x": 308, + "y": 1185, + "w": 12, "h": 6 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 6, + "w": 12, "h": 6 }, "sourceSize": { @@ -4942,18 +4942,18 @@ }, "dart_31_001.png": { "frame": { - "x": 1510, - "y": 1681, - "w": 57, - "h": 43 + "x": 1680, + "y": 1615, + "w": 64, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 57, - "h": 43 + "y": 0, + "w": 64, + "h": 44 }, "sourceSize": { "w": 64, @@ -4962,9 +4962,9 @@ }, "dart_31_2_001.png": { "frame": { - "x": 1849, - "y": 128, - "w": 54, + "x": 1757, + "y": 1135, + "w": 62, "h": 38 }, "rotated": false, @@ -4972,7 +4972,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 54, + "w": 62, "h": 38 }, "sourceSize": { @@ -4982,9 +4982,9 @@ }, "dart_31_extra_001.png": { "frame": { - "x": 186, - "y": 217, - "w": 3, + "x": 2160, + "y": 2115, + "w": 26, "h": 8 }, "rotated": false, @@ -4992,7 +4992,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 3, + "w": 26, "h": 8 }, "sourceSize": { @@ -5002,8 +5002,8 @@ }, "dart_32_001.png": { "frame": { - "x": 154, - "y": 1882, + "x": 2237, + "y": 439, "w": 48, "h": 40 }, @@ -5022,18 +5022,18 @@ }, "dart_32_2_001.png": { "frame": { - "x": 1480, - "y": 1889, + "x": 100, + "y": 2197, "w": 44, - "h": 37 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 44, - "h": 37 + "h": 38 }, "sourceSize": { "w": 44, @@ -5042,17 +5042,17 @@ }, "dart_32_extra_001.png": { "frame": { - "x": 1539, - "y": 1543, - "w": 26, + "x": 414, + "y": 1662, + "w": 32, "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 26, + "w": 32, "h": 8 }, "sourceSize": { @@ -5062,9 +5062,9 @@ }, "dart_33_001.png": { "frame": { - "x": 1849, - "y": 167, - "w": 54, + "x": 1517, + "y": 2044, + "w": 58, "h": 36 }, "rotated": false, @@ -5072,7 +5072,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 54, + "w": 58, "h": 36 }, "sourceSize": { @@ -5082,9 +5082,9 @@ }, "dart_33_2_001.png": { "frame": { - "x": 1854, - "y": 1891, - "w": 49, + "x": 455, + "y": 789, + "w": 56, "h": 32 }, "rotated": false, @@ -5092,7 +5092,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 49, + "w": 56, "h": 32 }, "sourceSize": { @@ -5102,18 +5102,18 @@ }, "dart_33_extra_001.png": { "frame": { - "x": 1117, - "y": 1957, - "w": 29, - "h": 31 + "x": 2232, + "y": 1764, + "w": 40, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, - "y": 1, - "w": 29, - "h": 31 + "x": 0, + "y": 0, + "w": 40, + "h": 32 }, "sourceSize": { "w": 40, @@ -5122,9 +5122,9 @@ }, "dart_34_001.png": { "frame": { - "x": 1732, - "y": 556, - "w": 56, + "x": 1820, + "y": 1005, + "w": 60, "h": 36 }, "rotated": false, @@ -5132,7 +5132,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 56, + "w": 60, "h": 36 }, "sourceSize": { @@ -5142,17 +5142,17 @@ }, "dart_34_2_001.png": { "frame": { - "x": 917, - "y": 1254, - "w": 32, + "x": 364, + "y": 704, + "w": 42, "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 32, + "w": 42, "h": 12 }, "sourceSize": { @@ -5162,18 +5162,18 @@ }, "dart_34_extra_001.png": { "frame": { - "x": 680, - "y": 392, - "w": 14, - "h": 5 + "x": 794, + "y": 491, + "w": 18, + "h": 10 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 14, - "h": 5 + "w": 18, + "h": 10 }, "sourceSize": { "w": 18, @@ -5182,8 +5182,8 @@ }, "dart_35_001.png": { "frame": { - "x": 1834, - "y": 1445, + "x": 2180, + "y": 1434, "w": 52, "h": 40 }, @@ -5202,9 +5202,9 @@ }, "dart_35_2_001.png": { "frame": { - "x": 714, - "y": 1928, - "w": 37, + "x": 2189, + "y": 2202, + "w": 46, "h": 28 }, "rotated": false, @@ -5212,7 +5212,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 37, + "w": 46, "h": 28 }, "sourceSize": { @@ -5222,17 +5222,17 @@ }, "dart_35_extra_001.png": { "frame": { - "x": 617, - "y": 1195, - "w": 25, + "x": 77, + "y": 1185, + "w": 32, "h": 6 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 25, + "w": 32, "h": 6 }, "sourceSize": { @@ -5242,8 +5242,8 @@ }, "fireBoost_001.png": { "frame": { - "x": 1950, - "y": 1120, + "x": 1309, + "y": 2242, "w": 24, "h": 32 }, @@ -5263,17 +5263,17 @@ "pack_01_001.png": { "frame": { "x": 0, - "y": 756, - "w": 76, - "h": 68 + "y": 935, + "w": 84, + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 76, - "h": 68 + "x": 0, + "y": 0, + "w": 84, + "h": 72 }, "sourceSize": { "w": 84, @@ -5282,18 +5282,18 @@ }, "pack_01_2_001.png": { "frame": { - "x": 819, - "y": 867, - "w": 72, - "h": 57 + "x": 935, + "y": 994, + "w": 80, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 72, - "h": 57 + "w": 80, + "h": 60 }, "sourceSize": { "w": 80, @@ -5302,8 +5302,8 @@ }, "player_00_001.png": { "frame": { - "x": 1417, - "y": 1437, + "x": 1818, + "y": 1042, "w": 60, "h": 60 }, @@ -5322,8 +5322,8 @@ }, "player_00_2_001.png": { "frame": { - "x": 833, - "y": 1985, + "x": 438, + "y": 1268, "w": 22, "h": 22 }, @@ -5342,8 +5342,8 @@ }, "player_01_001.png": { "frame": { - "x": 1490, - "y": 0, + "x": 1820, + "y": 1103, "w": 60, "h": 60 }, @@ -5362,8 +5362,8 @@ }, "player_01_2_001.png": { "frame": { - "x": 171, - "y": 217, + "x": 2048, + "y": 1993, "w": 14, "h": 14 }, @@ -5382,8 +5382,8 @@ }, "player_02_001.png": { "frame": { - "x": 1490, - "y": 61, + "x": 1780, + "y": 1799, "w": 60, "h": 60 }, @@ -5402,18 +5402,18 @@ }, "player_02_2_001.png": { "frame": { - "x": 816, - "y": 1924, + "x": 2232, + "y": 1797, "w": 40, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 40, - "h": 29 + "h": 30 }, "sourceSize": { "w": 40, @@ -5422,8 +5422,8 @@ }, "player_03_001.png": { "frame": { - "x": 1490, - "y": 122, + "x": 1810, + "y": 1475, "w": 60, "h": 60 }, @@ -5442,17 +5442,17 @@ }, "player_03_2_001.png": { "frame": { - "x": 1196, - "y": 855, - "w": 33, + "x": 2066, + "y": 1501, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, + "x": 0, "y": 0, - "w": 33, + "w": 56, "h": 56 }, "sourceSize": { @@ -5462,8 +5462,8 @@ }, "player_04_001.png": { "frame": { - "x": 1490, - "y": 183, + "x": 1810, + "y": 1536, "w": 60, "h": 60 }, @@ -5482,10 +5482,10 @@ }, "player_04_2_001.png": { "frame": { - "x": 1043, - "y": 1926, + "x": 619, + "y": 2240, "w": 36, - "h": 27 + "h": 34 }, "rotated": false, "trimmed": true, @@ -5493,7 +5493,7 @@ "x": 0, "y": 0, "w": 36, - "h": 27 + "h": 34 }, "sourceSize": { "w": 36, @@ -5502,8 +5502,8 @@ }, "player_05_001.png": { "frame": { - "x": 1490, - "y": 244, + "x": 1810, + "y": 1597, "w": 60, "h": 60 }, @@ -5522,10 +5522,10 @@ }, "player_05_2_001.png": { "frame": { - "x": 1425, - "y": 435, + "x": 93, + "y": 2274, "w": 34, - "h": 10 + "h": 38 }, "rotated": false, "trimmed": true, @@ -5533,7 +5533,7 @@ "x": 0, "y": 0, "w": 34, - "h": 10 + "h": 38 }, "sourceSize": { "w": 34, @@ -5542,8 +5542,8 @@ }, "player_06_001.png": { "frame": { - "x": 1490, - "y": 305, + "x": 1810, + "y": 1658, "w": 60, "h": 60 }, @@ -5562,8 +5562,8 @@ }, "player_06_2_001.png": { "frame": { - "x": 1732, - "y": 593, + "x": 2066, + "y": 1558, "w": 56, "h": 56 }, @@ -5582,8 +5582,8 @@ }, "player_07_001.png": { "frame": { - "x": 1485, - "y": 754, + "x": 1808, + "y": 1719, "w": 60, "h": 60 }, @@ -5602,10 +5602,10 @@ }, "player_07_2_001.png": { "frame": { - "x": 983, - "y": 1118, + "x": 241, + "y": 1056, "w": 10, - "h": 15 + "h": 28 }, "rotated": false, "trimmed": true, @@ -5613,7 +5613,7 @@ "x": 0, "y": 0, "w": 10, - "h": 15 + "h": 28 }, "sourceSize": { "w": 10, @@ -5622,8 +5622,8 @@ }, "player_08_001.png": { "frame": { - "x": 1487, - "y": 693, + "x": 0, + "y": 1866, "w": 60, "h": 60 }, @@ -5642,8 +5642,8 @@ }, "player_08_2_001.png": { "frame": { - "x": 1732, - "y": 650, + "x": 2066, + "y": 1615, "w": 56, "h": 56 }, @@ -5662,8 +5662,8 @@ }, "player_09_001.png": { "frame": { - "x": 1485, - "y": 1066, + "x": 61, + "y": 1866, "w": 60, "h": 60 }, @@ -5682,10 +5682,10 @@ }, "player_09_2_001.png": { "frame": { - "x": 1134, - "y": 1124, + "x": 1362, + "y": 2243, "w": 32, - "h": 10 + "h": 32 }, "rotated": false, "trimmed": true, @@ -5693,7 +5693,7 @@ "x": 0, "y": 0, "w": 32, - "h": 10 + "h": 32 }, "sourceSize": { "w": 32, @@ -5702,8 +5702,8 @@ }, "player_10_001.png": { "frame": { - "x": 1488, - "y": 366, + "x": 122, + "y": 1866, "w": 60, "h": 60 }, @@ -5722,10 +5722,10 @@ }, "player_10_2_001.png": { "frame": { - "x": 75, - "y": 858, + "x": 2235, + "y": 1415, "w": 42, - "h": 11 + "h": 30 }, "rotated": false, "trimmed": true, @@ -5733,7 +5733,7 @@ "x": 0, "y": 0, "w": 42, - "h": 11 + "h": 30 }, "sourceSize": { "w": 42, @@ -5742,8 +5742,8 @@ }, "player_100_001.png": { "frame": { - "x": 1488, - "y": 427, + "x": 183, + "y": 1866, "w": 60, "h": 60 }, @@ -5762,18 +5762,18 @@ }, "player_100_2_001.png": { "frame": { - "x": 0, - "y": 1857, + "x": 2179, + "y": 1684, "w": 52, - "h": 33 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, + "y": 0, "w": 52, - "h": 33 + "h": 40 }, "sourceSize": { "w": 52, @@ -5782,18 +5782,18 @@ }, "player_100_extra_001.png": { "frame": { - "x": 714, - "y": 1891, + "x": 1736, + "y": 2198, "w": 50, - "h": 36 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 50, - "h": 36 + "h": 40 }, "sourceSize": { "w": 50, @@ -5802,8 +5802,8 @@ }, "player_101_001.png": { "frame": { - "x": 1488, - "y": 488, + "x": 244, + "y": 1866, "w": 60, "h": 60 }, @@ -5822,10 +5822,10 @@ }, "player_101_2_001.png": { "frame": { - "x": 396, - "y": 1853, + "x": 2180, + "y": 1475, "w": 52, - "h": 37 + "h": 38 }, "rotated": false, "trimmed": true, @@ -5833,7 +5833,7 @@ "x": 0, "y": 0, "w": 52, - "h": 37 + "h": 38 }, "sourceSize": { "w": 52, @@ -5842,10 +5842,10 @@ }, "player_101_extra_001.png": { "frame": { - "x": 228, - "y": 1854, + "x": 2179, + "y": 1725, "w": 52, - "h": 36 + "h": 38 }, "rotated": false, "trimmed": true, @@ -5853,7 +5853,7 @@ "x": 0, "y": 0, "w": 52, - "h": 36 + "h": 38 }, "sourceSize": { "w": 52, @@ -5862,8 +5862,8 @@ }, "player_102_001.png": { "frame": { - "x": 1488, - "y": 549, + "x": 305, + "y": 1866, "w": 60, "h": 60 }, @@ -5882,8 +5882,8 @@ }, "player_102_2_001.png": { "frame": { - "x": 1849, - "y": 204, + "x": 2182, + "y": 201, "w": 54, "h": 54 }, @@ -5902,18 +5902,18 @@ }, "player_102_extra_001.png": { "frame": { - "x": 848, - "y": 1069, - "w": 41, - "h": 6 + "x": 2233, + "y": 1446, + "w": 42, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 41, - "h": 6 + "w": 42, + "h": 24 }, "sourceSize": { "w": 42, @@ -5922,8 +5922,8 @@ }, "player_103_001.png": { "frame": { - "x": 1488, - "y": 610, + "x": 366, + "y": 1866, "w": 60, "h": 60 }, @@ -5942,18 +5942,18 @@ }, "player_103_2_001.png": { "frame": { - "x": 47, - "y": 987, - "w": 25, - "h": 10 + "x": 1464, + "y": 1020, + "w": 26, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 36, - "w": 25, - "h": 10 + "x": 0, + "y": 0, + "w": 26, + "h": 46 }, "sourceSize": { "w": 26, @@ -5962,18 +5962,18 @@ }, "player_103_extra_001.png": { "frame": { - "x": 500, - "y": 1886, - "w": 50, - "h": 41 + "x": 2179, + "y": 1764, + "w": 52, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 50, - "h": 41 + "x": 0, + "y": 0, + "w": 52, + "h": 48 }, "sourceSize": { "w": 52, @@ -5982,8 +5982,8 @@ }, "player_104_001.png": { "frame": { - "x": 1487, - "y": 815, + "x": 427, + "y": 1866, "w": 60, "h": 60 }, @@ -6002,18 +6002,18 @@ }, "player_104_2_001.png": { "frame": { - "x": 1450, - "y": 1930, - "w": 24, - "h": 40 + "x": 926, + "y": 1671, + "w": 38, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 14, - "y": 6, - "w": 24, - "h": 40 + "x": 0, + "y": 0, + "w": 38, + "h": 46 }, "sourceSize": { "w": 38, @@ -6022,18 +6022,18 @@ }, "player_104_extra_001.png": { "frame": { - "x": 150, - "y": 870, - "w": 73, - "h": 47 + "x": 1201, + "y": 467, + "w": 74, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 73, - "h": 47 + "w": 74, + "h": 50 }, "sourceSize": { "w": 74, @@ -6042,18 +6042,18 @@ }, "player_105_001.png": { "frame": { - "x": 1298, - "y": 326, - "w": 63, - "h": 63 + "x": 1637, + "y": 0, + "w": 66, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 63, - "h": 63 + "x": 0, + "y": 0, + "w": 66, + "h": 66 }, "sourceSize": { "w": 66, @@ -6062,17 +6062,17 @@ }, "player_105_2_001.png": { "frame": { - "x": 1670, - "y": 767, - "w": 59, + "x": 1757, + "y": 326, + "w": 62, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 59, + "w": 62, "h": 56 }, "sourceSize": { @@ -6082,18 +6082,18 @@ }, "player_105_extra_001.png": { "frame": { - "x": 1086, - "y": 1878, - "w": 50, - "h": 49 + "x": 488, + "y": 1866, + "w": 58, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 50, - "h": 49 + "x": 0, + "y": 0, + "w": 58, + "h": 60 }, "sourceSize": { "w": 58, @@ -6102,8 +6102,8 @@ }, "player_106_001.png": { "frame": { - "x": 1487, - "y": 1127, + "x": 547, + "y": 1866, "w": 60, "h": 60 }, @@ -6122,8 +6122,8 @@ }, "player_106_2_001.png": { "frame": { - "x": 1731, - "y": 707, + "x": 2008, + "y": 1936, "w": 56, "h": 56 }, @@ -6142,8 +6142,8 @@ }, "player_106_extra_001.png": { "frame": { - "x": 1849, - "y": 259, + "x": 2182, + "y": 256, "w": 54, "h": 54 }, @@ -6162,8 +6162,8 @@ }, "player_107_001.png": { "frame": { - "x": 1487, - "y": 876, + "x": 608, + "y": 1866, "w": 60, "h": 60 }, @@ -6182,8 +6182,8 @@ }, "player_107_2_001.png": { "frame": { - "x": 1849, - "y": 314, + "x": 2182, + "y": 311, "w": 54, "h": 54 }, @@ -6202,10 +6202,10 @@ }, "player_108_001.png": { "frame": { - "x": 0, - "y": 1439, + "x": 1757, + "y": 1174, "w": 60, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, @@ -6213,7 +6213,7 @@ "x": 0, "y": 0, "w": 60, - "h": 61 + "h": 62 }, "sourceSize": { "w": 60, @@ -6222,18 +6222,18 @@ }, "player_108_2_001.png": { "frame": { - "x": 1904, - "y": 735, + "x": 2235, + "y": 1077, "w": 46, - "h": 32 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 46, - "h": 32 + "h": 36 }, "sourceSize": { "w": 46, @@ -6242,17 +6242,17 @@ }, "player_109_001.png": { "frame": { - "x": 61, - "y": 1439, - "w": 61, + "x": 1757, + "y": 383, + "w": 62, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -6262,18 +6262,18 @@ }, "player_109_2_001.png": { "frame": { - "x": 1272, - "y": 1765, - "w": 55, - "h": 52 + "x": 1635, + "y": 2007, + "w": 58, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 55, - "h": 52 + "x": 0, + "y": 0, + "w": 58, + "h": 56 }, "sourceSize": { "w": 58, @@ -6282,18 +6282,18 @@ }, "player_109_extra_001.png": { "frame": { - "x": 1950, - "y": 1153, - "w": 30, - "h": 32 + "x": 2065, + "y": 1672, + "w": 56, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, - "y": 22, - "w": 30, - "h": 32 + "x": 0, + "y": 0, + "w": 56, + "h": 54 }, "sourceSize": { "w": 56, @@ -6302,8 +6302,8 @@ }, "player_11_001.png": { "frame": { - "x": 1487, - "y": 1188, + "x": 669, + "y": 1866, "w": 60, "h": 60 }, @@ -6322,10 +6322,10 @@ }, "player_11_2_001.png": { "frame": { - "x": 566, - "y": 1786, + "x": 444, + "y": 2242, "w": 36, - "h": 13 + "h": 22 }, "rotated": false, "trimmed": true, @@ -6333,7 +6333,7 @@ "x": 0, "y": 0, "w": 36, - "h": 13 + "h": 22 }, "sourceSize": { "w": 36, @@ -6342,10 +6342,10 @@ }, "player_110_001.png": { "frame": { - "x": 1046, - "y": 1202, + "x": 1680, + "y": 1660, "w": 64, - "h": 63 + "h": 64 }, "rotated": false, "trimmed": true, @@ -6353,7 +6353,7 @@ "x": 0, "y": 0, "w": 64, - "h": 63 + "h": 64 }, "sourceSize": { "w": 64, @@ -6362,18 +6362,18 @@ }, "player_110_2_001.png": { "frame": { - "x": 504, - "y": 1426, - "w": 61, - "h": 59 + "x": 1757, + "y": 1237, + "w": 62, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, - "h": 59 + "w": 62, + "h": 60 }, "sourceSize": { "w": 62, @@ -6383,7 +6383,7 @@ "player_111_001.png": { "frame": { "x": 0, - "y": 1267, + "y": 1738, "w": 64, "h": 64 }, @@ -6402,8 +6402,8 @@ }, "player_111_2_001.png": { "frame": { - "x": 1487, - "y": 937, + "x": 730, + "y": 1866, "w": 60, "h": 60 }, @@ -6422,18 +6422,18 @@ }, "player_112_001.png": { "frame": { - "x": 123, - "y": 1439, - "w": 61, - "h": 61 + "x": 1757, + "y": 444, + "w": 62, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, - "h": 61 + "w": 62, + "h": 62 }, "sourceSize": { "w": 62, @@ -6442,18 +6442,18 @@ }, "player_112_2_001.png": { "frame": { - "x": 1661, - "y": 1544, + "x": 1694, + "y": 2007, "w": 58, - "h": 57 + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 58, - "h": 57 + "h": 58 }, "sourceSize": { "w": 58, @@ -6462,18 +6462,18 @@ }, "player_112_extra_001.png": { "frame": { - "x": 1730, - "y": 764, - "w": 56, - "h": 49 + "x": 1753, + "y": 2007, + "w": 58, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 56, - "h": 49 + "x": 0, + "y": 0, + "w": 58, + "h": 56 }, "sourceSize": { "w": 58, @@ -6482,17 +6482,17 @@ }, "player_113_001.png": { "frame": { - "x": 938, - "y": 615, - "w": 70, + "x": 1273, + "y": 892, + "w": 72, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 70, + "w": 72, "h": 60 }, "sourceSize": { @@ -6502,17 +6502,17 @@ }, "player_113_2_001.png": { "frame": { - "x": 280, - "y": 1140, - "w": 67, - "h": 56 + "x": 1424, + "y": 45, + "w": 70, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 67, + "w": 70, "h": 56 }, "sourceSize": { @@ -6522,17 +6522,17 @@ }, "player_113_extra_001.png": { "frame": { - "x": 416, - "y": 1140, - "w": 66, + "x": 1564, + "y": 617, + "w": 68, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 66, + "w": 68, "h": 56 }, "sourceSize": { @@ -6542,10 +6542,10 @@ }, "player_114_001.png": { "frame": { - "x": 0, - "y": 1377, + "x": 1757, + "y": 1298, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, @@ -6553,7 +6553,7 @@ "x": 0, "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -6562,8 +6562,8 @@ }, "player_114_2_001.png": { "frame": { - "x": 1730, - "y": 814, + "x": 2065, + "y": 1727, "w": 56, "h": 56 }, @@ -6582,18 +6582,18 @@ }, "player_114_extra_001.png": { "frame": { - "x": 551, - "y": 1921, - "w": 41, - "h": 26 + "x": 2065, + "y": 1784, + "w": 56, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 15, - "y": 26, - "w": 41, - "h": 26 + "x": 0, + "y": 0, + "w": 56, + "h": 52 }, "sourceSize": { "w": 56, @@ -6602,8 +6602,8 @@ }, "player_115_001.png": { "frame": { - "x": 63, - "y": 1377, + "x": 1757, + "y": 507, "w": 62, "h": 60 }, @@ -6622,8 +6622,8 @@ }, "player_115_2_001.png": { "frame": { - "x": 1487, - "y": 1249, + "x": 1276, + "y": 1864, "w": 60, "h": 58 }, @@ -6642,18 +6642,18 @@ }, "player_115_extra_001.png": { "frame": { - "x": 999, - "y": 1677, - "w": 57, - "h": 35 + "x": 1812, + "y": 1982, + "w": 58, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 21, - "w": 57, - "h": 35 + "x": 0, + "y": 0, + "w": 58, + "h": 56 }, "sourceSize": { "w": 58, @@ -6662,17 +6662,17 @@ }, "player_116_001.png": { "frame": { - "x": 348, - "y": 1140, - "w": 67, + "x": 278, + "y": 1548, + "w": 68, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 67, + "w": 68, "h": 60 }, "sourceSize": { @@ -6682,8 +6682,8 @@ }, "player_116_2_001.png": { "frame": { - "x": 605, - "y": 1251, + "x": 65, + "y": 1738, "w": 64, "h": 58 }, @@ -6702,17 +6702,17 @@ }, "player_116_extra_001.png": { "frame": { - "x": 1298, - "y": 390, - "w": 63, + "x": 130, + "y": 1738, + "w": 64, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 63, + "w": 64, "h": 56 }, "sourceSize": { @@ -6722,8 +6722,8 @@ }, "player_117_001.png": { "frame": { - "x": 1487, - "y": 998, + "x": 791, + "y": 1866, "w": 60, "h": 60 }, @@ -6742,8 +6742,8 @@ }, "player_117_2_001.png": { "frame": { - "x": 937, - "y": 1497, + "x": 1704, + "y": 957, "w": 44, "h": 56 }, @@ -6762,17 +6762,17 @@ }, "player_117_extra_001.png": { "frame": { - "x": 1830, - "y": 1494, - "w": 42, + "x": 2176, + "y": 1515, + "w": 44, "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 42, + "w": 44, "h": 54 }, "sourceSize": { @@ -6782,8 +6782,8 @@ }, "player_118_001.png": { "frame": { - "x": 1478, - "y": 1308, + "x": 1337, + "y": 1866, "w": 60, "h": 60 }, @@ -6802,8 +6802,8 @@ }, "player_118_2_001.png": { "frame": { - "x": 1478, - "y": 1369, + "x": 852, + "y": 1866, "w": 60, "h": 60 }, @@ -6822,18 +6822,18 @@ }, "player_118_extra_001.png": { "frame": { - "x": 1849, - "y": 369, + "x": 2182, + "y": 366, "w": 54, - "h": 30 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 16, + "y": 0, "w": 54, - "h": 30 + "h": 46 }, "sourceSize": { "w": 54, @@ -6842,8 +6842,8 @@ }, "player_119_001.png": { "frame": { - "x": 1478, - "y": 1430, + "x": 1398, + "y": 1866, "w": 60, "h": 60 }, @@ -6862,8 +6862,8 @@ }, "player_119_2_001.png": { "frame": { - "x": 1730, - "y": 871, + "x": 2065, + "y": 1837, "w": 56, "h": 56 }, @@ -6882,8 +6882,8 @@ }, "player_119_extra_001.png": { "frame": { - "x": 1834, - "y": 1301, + "x": 2182, + "y": 413, "w": 54, "h": 54 }, @@ -6902,8 +6902,8 @@ }, "player_12_001.png": { "frame": { - "x": 1356, - "y": 1469, + "x": 913, + "y": 1866, "w": 60, "h": 60 }, @@ -6922,18 +6922,18 @@ }, "player_12_2_001.png": { "frame": { - "x": 1901, - "y": 1818, + "x": 578, + "y": 2197, "w": 42, - "h": 35 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 42, - "h": 35 + "h": 40 }, "sourceSize": { "w": 42, @@ -6942,8 +6942,8 @@ }, "player_120_001.png": { "frame": { - "x": 0, - "y": 1501, + "x": 1459, + "y": 1866, "w": 60, "h": 60 }, @@ -6962,8 +6962,8 @@ }, "player_120_2_001.png": { "frame": { - "x": 1730, - "y": 928, + "x": 2065, + "y": 1894, "w": 56, "h": 56 }, @@ -6982,10 +6982,10 @@ }, "player_121_001.png": { "frame": { - "x": 1080, - "y": 680, + "x": 347, + "y": 1548, "w": 68, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, @@ -6993,7 +6993,7 @@ "x": 0, "y": 0, "w": 68, - "h": 61 + "h": 62 }, "sourceSize": { "w": 68, @@ -7002,10 +7002,10 @@ }, "player_121_2_001.png": { "frame": { - "x": 1307, - "y": 1273, + "x": 1757, + "y": 1361, "w": 62, - "h": 57 + "h": 58 }, "rotated": false, "trimmed": true, @@ -7013,7 +7013,7 @@ "x": 0, "y": 0, "w": 62, - "h": 57 + "h": 58 }, "sourceSize": { "w": 62, @@ -7022,18 +7022,18 @@ }, "player_121_extra_001.png": { "frame": { - "x": 765, - "y": 1884, - "w": 50, - "h": 42 + "x": 2179, + "y": 1813, + "w": 52, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 50, - "h": 42 + "w": 52, + "h": 44 }, "sourceSize": { "w": 52, @@ -7042,8 +7042,8 @@ }, "player_122_001.png": { "frame": { - "x": 126, - "y": 1377, + "x": 1757, + "y": 568, "w": 62, "h": 60 }, @@ -7062,8 +7062,8 @@ }, "player_122_2_001.png": { "frame": { - "x": 1730, - "y": 985, + "x": 2065, + "y": 1951, "w": 56, "h": 56 }, @@ -7082,8 +7082,8 @@ }, "player_123_001.png": { "frame": { - "x": 61, - "y": 1501, + "x": 974, + "y": 1866, "w": 60, "h": 60 }, @@ -7102,17 +7102,17 @@ }, "player_123_2_001.png": { "frame": { - "x": 1730, - "y": 1042, - "w": 49, + "x": 2048, + "y": 2008, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 49, + "w": 56, "h": 56 }, "sourceSize": { @@ -7122,8 +7122,8 @@ }, "player_124_001.png": { "frame": { - "x": 189, - "y": 1376, + "x": 1757, + "y": 629, "w": 62, "h": 62 }, @@ -7142,8 +7142,8 @@ }, "player_124_2_001.png": { "frame": { - "x": 122, - "y": 1501, + "x": 1520, + "y": 1866, "w": 60, "h": 60 }, @@ -7162,8 +7162,8 @@ }, "player_125_001.png": { "frame": { - "x": 183, - "y": 1501, + "x": 1035, + "y": 1866, "w": 60, "h": 60 }, @@ -7182,8 +7182,8 @@ }, "player_125_2_001.png": { "frame": { - "x": 1730, - "y": 1099, + "x": 0, + "y": 2083, "w": 56, "h": 56 }, @@ -7202,10 +7202,10 @@ }, "player_126_001.png": { "frame": { - "x": 1080, - "y": 742, + "x": 416, + "y": 1548, "w": 68, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, @@ -7213,7 +7213,7 @@ "x": 0, "y": 0, "w": 68, - "h": 61 + "h": 62 }, "sourceSize": { "w": 68, @@ -7222,10 +7222,10 @@ }, "player_126_2_001.png": { "frame": { - "x": 67, - "y": 1246, + "x": 195, + "y": 1738, "w": 64, - "h": 50 + "h": 56 }, "rotated": false, "trimmed": true, @@ -7233,7 +7233,7 @@ "x": 0, "y": 0, "w": 64, - "h": 50 + "h": 56 }, "sourceSize": { "w": 64, @@ -7242,8 +7242,8 @@ }, "player_127_001.png": { "frame": { - "x": 670, - "y": 1262, + "x": 260, + "y": 1738, "w": 64, "h": 60 }, @@ -7262,10 +7262,10 @@ }, "player_127_2_001.png": { "frame": { - "x": 1713, - "y": 1702, + "x": 1753, + "y": 2064, "w": 56, - "h": 38 + "h": 52 }, "rotated": false, "trimmed": true, @@ -7273,7 +7273,7 @@ "x": 0, "y": 0, "w": 56, - "h": 38 + "h": 52 }, "sourceSize": { "w": 56, @@ -7282,18 +7282,18 @@ }, "player_127_extra_001.png": { "frame": { - "x": 628, - "y": 1500, + "x": 1581, + "y": 1866, "w": 60, - "h": 34 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, + "y": 0, "w": 60, - "h": 34 + "h": 42 }, "sourceSize": { "w": 60, @@ -7302,18 +7302,18 @@ }, "player_128_001.png": { "frame": { - "x": 252, - "y": 1377, + "x": 1757, + "y": 692, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -7322,18 +7322,18 @@ }, "player_128_2_001.png": { "frame": { - "x": 1670, - "y": 824, - "w": 59, - "h": 57 + "x": 1096, + "y": 1866, + "w": 60, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 59, - "h": 57 + "x": 0, + "y": 0, + "w": 60, + "h": 58 }, "sourceSize": { "w": 60, @@ -7342,18 +7342,18 @@ }, "player_128_extra_001.png": { "frame": { - "x": 1904, - "y": 1053, - "w": 42, - "h": 45 + "x": 2191, + "y": 2115, + "w": 44, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 42, - "h": 45 + "y": 0, + "w": 44, + "h": 50 }, "sourceSize": { "w": 44, @@ -7362,8 +7362,8 @@ }, "player_129_001.png": { "frame": { - "x": 244, - "y": 1501, + "x": 1642, + "y": 1866, "w": 60, "h": 60 }, @@ -7382,8 +7382,8 @@ }, "player_129_2_001.png": { "frame": { - "x": 1384, - "y": 1836, + "x": 2179, + "y": 1858, "w": 52, "h": 52 }, @@ -7402,18 +7402,18 @@ }, "player_129_extra_001.png": { "frame": { - "x": 320, - "y": 1928, - "w": 37, - "h": 37 + "x": 2232, + "y": 1828, + "w": 40, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 37, - "h": 37 + "x": 0, + "y": 0, + "w": 40, + "h": 40 }, "sourceSize": { "w": 40, @@ -7422,8 +7422,8 @@ }, "player_13_001.png": { "frame": { - "x": 689, - "y": 1501, + "x": 1157, + "y": 1866, "w": 60, "h": 60 }, @@ -7442,10 +7442,10 @@ }, "player_13_2_001.png": { "frame": { - "x": 650, - "y": 1960, + "x": 1385, + "y": 2278, "w": 32, - "h": 10 + "h": 32 }, "rotated": false, "trimmed": true, @@ -7453,7 +7453,7 @@ "x": 0, "y": 0, "w": 32, - "h": 10 + "h": 32 }, "sourceSize": { "w": 32, @@ -7462,8 +7462,8 @@ }, "player_130_001.png": { "frame": { - "x": 305, - "y": 1501, + "x": 1703, + "y": 1864, "w": 60, "h": 60 }, @@ -7482,8 +7482,8 @@ }, "player_130_2_001.png": { "frame": { - "x": 1730, - "y": 1156, + "x": 57, + "y": 2083, "w": 56, "h": 56 }, @@ -7502,8 +7502,8 @@ }, "player_131_001.png": { "frame": { - "x": 750, - "y": 1501, + "x": 1764, + "y": 1864, "w": 60, "h": 60 }, @@ -7522,8 +7522,8 @@ }, "player_131_2_001.png": { "frame": { - "x": 1730, - "y": 1213, + "x": 114, + "y": 2083, "w": 56, "h": 56 }, @@ -7542,18 +7542,18 @@ }, "player_131_extra_001.png": { "frame": { - "x": 917, - "y": 1928, - "w": 37, - "h": 37 + "x": 128, + "y": 2274, + "w": 38, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 37, - "h": 37 + "x": 0, + "y": 0, + "w": 38, + "h": 38 }, "sourceSize": { "w": 38, @@ -7562,8 +7562,8 @@ }, "player_132_001.png": { "frame": { - "x": 366, - "y": 1501, + "x": 1879, + "y": 1042, "w": 60, "h": 60 }, @@ -7582,8 +7582,8 @@ }, "player_132_2_001.png": { "frame": { - "x": 1730, - "y": 1270, + "x": 1458, + "y": 2056, "w": 56, "h": 52 }, @@ -7602,8 +7602,8 @@ }, "player_133_001.png": { "frame": { - "x": 696, - "y": 1375, + "x": 1757, + "y": 755, "w": 62, "h": 62 }, @@ -7622,8 +7622,8 @@ }, "player_133_2_001.png": { "frame": { - "x": 1729, - "y": 1323, + "x": 171, + "y": 2083, "w": 56, "h": 56 }, @@ -7642,8 +7642,8 @@ }, "player_133_extra_001.png": { "frame": { - "x": 536, - "y": 660, + "x": 1561, + "y": 928, "w": 10, "h": 10 }, @@ -7662,8 +7662,8 @@ }, "player_134_001.png": { "frame": { - "x": 759, - "y": 1375, + "x": 1757, + "y": 818, "w": 62, "h": 62 }, @@ -7682,8 +7682,8 @@ }, "player_134_2_001.png": { "frame": { - "x": 1656, - "y": 1602, + "x": 1871, + "y": 2007, "w": 58, "h": 58 }, @@ -7702,10 +7702,10 @@ }, "player_135_001.png": { "frame": { - "x": 822, - "y": 1375, + "x": 325, + "y": 1738, "w": 60, - "h": 62 + "h": 64 }, "rotated": false, "trimmed": true, @@ -7713,7 +7713,7 @@ "x": 0, "y": 0, "w": 60, - "h": 62 + "h": 64 }, "sourceSize": { "w": 60, @@ -7722,10 +7722,10 @@ }, "player_135_2_001.png": { "frame": { - "x": 0, - "y": 1684, + "x": 1700, + "y": 447, "w": 56, - "h": 58 + "h": 60 }, "rotated": false, "trimmed": true, @@ -7733,7 +7733,7 @@ "x": 0, "y": 0, "w": 56, - "h": 58 + "h": 60 }, "sourceSize": { "w": 56, @@ -7742,8 +7742,8 @@ }, "player_136_001.png": { "frame": { - "x": 427, - "y": 1501, + "x": 1883, + "y": 0, "w": 60, "h": 60 }, @@ -7762,8 +7762,8 @@ }, "player_136_2_001.png": { "frame": { - "x": 57, - "y": 1684, + "x": 1930, + "y": 2007, "w": 58, "h": 58 }, @@ -7782,18 +7782,18 @@ }, "player_136_extra_001.png": { "frame": { - "x": 1966, - "y": 1964, - "w": 30, - "h": 29 + "x": 1635, + "y": 2064, + "w": 56, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, - "y": 3, - "w": 30, - "h": 29 + "x": 0, + "y": 0, + "w": 56, + "h": 32 }, "sourceSize": { "w": 56, @@ -7802,18 +7802,18 @@ }, "player_137_001.png": { "frame": { - "x": 1165, - "y": 0, - "w": 65, - "h": 67 + "x": 1199, + "y": 600, + "w": 68, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 65, - "h": 67 + "w": 68, + "h": 74 }, "sourceSize": { "w": 68, @@ -7822,18 +7822,18 @@ }, "player_137_2_001.png": { "frame": { - "x": 132, - "y": 1267, - "w": 62, - "h": 64 + "x": 1279, + "y": 0, + "w": 66, + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 62, - "h": 64 + "w": 66, + "h": 72 }, "sourceSize": { "w": 66, @@ -7842,18 +7842,18 @@ }, "player_137_extra_001.png": { "frame": { - "x": 1950, - "y": 1186, - "w": 32, - "h": 27 + "x": 1279, + "y": 73, + "w": 60, + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 28, + "x": 0, "y": 0, - "w": 32, - "h": 27 + "w": 60, + "h": 72 }, "sourceSize": { "w": 60, @@ -7862,8 +7862,8 @@ }, "player_138_001.png": { "frame": { - "x": 488, - "y": 1501, + "x": 1883, + "y": 1103, "w": 60, "h": 60 }, @@ -7882,8 +7882,8 @@ }, "player_138_2_001.png": { "frame": { - "x": 1837, - "y": 1042, + "x": 2182, + "y": 468, "w": 54, "h": 54 }, @@ -7902,8 +7902,8 @@ }, "player_138_extra_001.png": { "frame": { - "x": 1437, - "y": 1836, + "x": 2179, + "y": 1911, "w": 52, "h": 52 }, @@ -7922,8 +7922,8 @@ }, "player_139_001.png": { "frame": { - "x": 549, - "y": 1501, + "x": 1883, + "y": 61, "w": 60, "h": 60 }, @@ -7942,8 +7942,8 @@ }, "player_139_2_001.png": { "frame": { - "x": 1729, - "y": 1380, + "x": 228, + "y": 2083, "w": 56, "h": 56 }, @@ -7962,8 +7962,8 @@ }, "player_139_extra_001.png": { "frame": { - "x": 1847, - "y": 1549, + "x": 2182, + "y": 523, "w": 54, "h": 54 }, @@ -7982,8 +7982,8 @@ }, "player_14_001.png": { "frame": { - "x": 985, - "y": 1487, + "x": 1883, + "y": 1164, "w": 60, "h": 60 }, @@ -8002,8 +8002,8 @@ }, "player_14_2_001.png": { "frame": { - "x": 1904, - "y": 1854, + "x": 621, + "y": 2197, "w": 42, "h": 42 }, @@ -8022,8 +8022,8 @@ }, "player_140_001.png": { "frame": { - "x": 1171, - "y": 1477, + "x": 1883, + "y": 122, "w": 60, "h": 60 }, @@ -8042,8 +8042,8 @@ }, "player_140_2_001.png": { "frame": { - "x": 1720, - "y": 1437, + "x": 285, + "y": 2083, "w": 56, "h": 56 }, @@ -8062,8 +8062,8 @@ }, "player_141_001.png": { "frame": { - "x": 315, - "y": 1372, + "x": 0, + "y": 1803, "w": 62, "h": 62 }, @@ -8082,8 +8082,8 @@ }, "player_141_2_001.png": { "frame": { - "x": 116, - "y": 1684, + "x": 1989, + "y": 1997, "w": 58, "h": 58 }, @@ -8102,18 +8102,18 @@ }, "player_141_extra_001.png": { "frame": { - "x": 1290, - "y": 1878, + "x": 2237, + "y": 480, "w": 48, - "h": 47 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 48, - "h": 47 + "h": 48 }, "sourceSize": { "w": 48, @@ -8122,8 +8122,8 @@ }, "player_142_001.png": { "frame": { - "x": 811, - "y": 1500, + "x": 1883, + "y": 1225, "w": 60, "h": 60 }, @@ -8142,8 +8142,8 @@ }, "player_142_2_001.png": { "frame": { - "x": 1904, - "y": 768, + "x": 923, + "y": 2196, "w": 46, "h": 46 }, @@ -8162,18 +8162,18 @@ }, "player_142_extra_001.png": { "frame": { - "x": 1904, - "y": 1099, + "x": 1849, + "y": 2196, "w": 44, - "h": 45 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 44, - "h": 45 + "h": 46 }, "sourceSize": { "w": 44, @@ -8182,8 +8182,8 @@ }, "player_143_001.png": { "frame": { - "x": 1109, - "y": 1492, + "x": 1883, + "y": 183, "w": 60, "h": 60 }, @@ -8202,10 +8202,10 @@ }, "player_143_2_001.png": { "frame": { - "x": 1904, - "y": 815, + "x": 1966, + "y": 2198, "w": 46, - "h": 42 + "h": 44 }, "rotated": false, "trimmed": true, @@ -8213,7 +8213,7 @@ "x": 0, "y": 0, "w": 46, - "h": 42 + "h": 44 }, "sourceSize": { "w": 46, @@ -8222,8 +8222,8 @@ }, "player_144_001.png": { "frame": { - "x": 1232, - "y": 1500, + "x": 1883, + "y": 1286, "w": 60, "h": 60 }, @@ -8242,8 +8242,8 @@ }, "player_144_2_001.png": { "frame": { - "x": 1889, - "y": 1308, + "x": 145, + "y": 2197, "w": 44, "h": 44 }, @@ -8262,8 +8262,8 @@ }, "player_145_001.png": { "frame": { - "x": 872, - "y": 1500, + "x": 1883, + "y": 244, "w": 60, "h": 60 }, @@ -8282,8 +8282,8 @@ }, "player_145_2_001.png": { "frame": { - "x": 1847, - "y": 400, + "x": 2182, + "y": 578, "w": 54, "h": 54 }, @@ -8302,18 +8302,18 @@ }, "player_145_extra_001.png": { "frame": { - "x": 330, - "y": 1891, - "w": 43, - "h": 33 + "x": 2235, + "y": 1219, + "w": 44, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 43, - "h": 33 + "y": 0, + "w": 44, + "h": 36 }, "sourceSize": { "w": 44, @@ -8322,8 +8322,8 @@ }, "player_146_001.png": { "frame": { - "x": 1293, - "y": 1500, + "x": 1883, + "y": 1347, "w": 60, "h": 60 }, @@ -8342,18 +8342,18 @@ }, "player_146_2_001.png": { "frame": { - "x": 1904, - "y": 858, + "x": 2013, + "y": 2198, "w": 46, - "h": 25 + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 19, + "y": 0, "w": 46, - "h": 25 + "h": 44 }, "sourceSize": { "w": 46, @@ -8362,10 +8362,10 @@ }, "player_146_extra_001.png": { "frame": { - "x": 1393, - "y": 1725, + "x": 53, + "y": 2197, "w": 46, - "h": 16 + "h": 42 }, "rotated": false, "trimmed": true, @@ -8373,7 +8373,7 @@ "x": 0, "y": 0, "w": 46, - "h": 16 + "h": 42 }, "sourceSize": { "w": 46, @@ -8382,8 +8382,8 @@ }, "player_147_001.png": { "frame": { - "x": 1046, - "y": 1494, + "x": 1883, + "y": 305, "w": 60, "h": 60 }, @@ -8402,8 +8402,8 @@ }, "player_147_2_001.png": { "frame": { - "x": 1720, - "y": 1494, + "x": 1703, + "y": 301, "w": 52, "h": 56 }, @@ -8422,8 +8422,8 @@ }, "player_148_001.png": { "frame": { - "x": 735, - "y": 1267, + "x": 386, + "y": 1738, "w": 64, "h": 60 }, @@ -8442,10 +8442,10 @@ }, "player_148_2_001.png": { "frame": { - "x": 1847, - "y": 1604, + "x": 2182, + "y": 633, "w": 54, - "h": 49 + "h": 54 }, "rotated": false, "trimmed": true, @@ -8453,7 +8453,7 @@ "x": 0, "y": 0, "w": 54, - "h": 49 + "h": 54 }, "sourceSize": { "w": 54, @@ -8462,18 +8462,18 @@ }, "player_148_extra_001.png": { "frame": { - "x": 713, - "y": 690, + "x": 850, + "y": 2176, "w": 42, - "h": 7 + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, + "y": 0, "w": 42, - "h": 7 + "h": 16 }, "sourceSize": { "w": 42, @@ -8482,18 +8482,18 @@ }, "player_149_001.png": { "frame": { - "x": 1297, - "y": 447, + "x": 1631, + "y": 859, "w": 60, - "h": 63 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 60, - "h": 63 + "h": 66 }, "sourceSize": { "w": 60, @@ -8502,18 +8502,18 @@ }, "player_149_2_001.png": { "frame": { - "x": 1720, - "y": 1551, + "x": 342, + "y": 2083, "w": 56, - "h": 43 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, + "y": 0, "w": 56, - "h": 43 + "h": 56 }, "sourceSize": { "w": 56, @@ -8522,8 +8522,8 @@ }, "player_15_001.png": { "frame": { - "x": 1417, - "y": 1498, + "x": 1883, + "y": 1408, "w": 60, "h": 60 }, @@ -8542,8 +8542,8 @@ }, "player_15_2_001.png": { "frame": { - "x": 1720, - "y": 1595, + "x": 399, + "y": 2083, "w": 56, "h": 56 }, @@ -8562,8 +8562,8 @@ }, "player_150_001.png": { "frame": { - "x": 1478, - "y": 1491, + "x": 1883, + "y": 366, "w": 60, "h": 60 }, @@ -8582,8 +8582,8 @@ }, "player_150_2_001.png": { "frame": { - "x": 0, - "y": 1743, + "x": 456, + "y": 2083, "w": 56, "h": 56 }, @@ -8602,18 +8602,18 @@ }, "player_151_001.png": { "frame": { - "x": 1298, - "y": 511, - "w": 63, - "h": 61 + "x": 451, + "y": 1738, + "w": 64, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 63, - "h": 61 + "w": 64, + "h": 62 }, "sourceSize": { "w": 64, @@ -8622,18 +8622,18 @@ }, "player_151_2_001.png": { "frame": { - "x": 228, - "y": 1825, - "w": 55, - "h": 28 + "x": 513, + "y": 2083, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 55, - "h": 28 + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -8642,18 +8642,18 @@ }, "player_151_extra_001.png": { "frame": { - "x": 1947, - "y": 1751, - "w": 35, - "h": 26 + "x": 2232, + "y": 1869, + "w": 36, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 14, - "w": 35, - "h": 26 + "y": 0, + "w": 36, + "h": 40 }, "sourceSize": { "w": 36, @@ -8662,18 +8662,18 @@ }, "player_152_001.png": { "frame": { - "x": 938, - "y": 676, - "w": 70, - "h": 69 + "x": 0, + "y": 1192, + "w": 72, + "h": 76 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 70, - "h": 69 + "w": 72, + "h": 76 }, "sourceSize": { "w": 72, @@ -8682,18 +8682,18 @@ }, "player_152_2_001.png": { "frame": { - "x": 510, - "y": 1332, - "w": 57, - "h": 62 + "x": 1406, + "y": 817, + "w": 66, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 57, - "h": 62 + "w": 66, + "h": 70 }, "sourceSize": { "w": 66, @@ -8702,18 +8702,18 @@ }, "player_152_extra_001.png": { "frame": { - "x": 1953, - "y": 414, - "w": 30, - "h": 33 + "x": 386, + "y": 1799, + "w": 62, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 32, - "y": 21, - "w": 30, - "h": 33 + "x": 0, + "y": 0, + "w": 62, + "h": 54 }, "sourceSize": { "w": 62, @@ -8722,8 +8722,8 @@ }, "player_153_001.png": { "frame": { - "x": 1079, - "y": 804, + "x": 485, + "y": 1548, "w": 68, "h": 60 }, @@ -8742,9 +8742,9 @@ }, "player_153_2_001.png": { "frame": { - "x": 1231, - "y": 806, - "w": 65, + "x": 1637, + "y": 67, + "w": 66, "h": 56 }, "rotated": false, @@ -8752,7 +8752,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 65, + "w": 66, "h": 56 }, "sourceSize": { @@ -8762,18 +8762,18 @@ }, "player_153_extra_001.png": { "frame": { - "x": 420, - "y": 905, + "x": 366, + "y": 2062, "w": 36, - "h": 17 + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 36, - "h": 17 + "h": 20 }, "sourceSize": { "w": 36, @@ -8782,8 +8782,8 @@ }, "player_154_001.png": { "frame": { - "x": 1546, - "y": 754, + "x": 1883, + "y": 1469, "w": 60, "h": 60 }, @@ -8802,8 +8802,8 @@ }, "player_154_2_001.png": { "frame": { - "x": 57, - "y": 1743, + "x": 570, + "y": 2083, "w": 56, "h": 56 }, @@ -8822,18 +8822,18 @@ }, "player_154_extra_001.png": { "frame": { - "x": 281, - "y": 1856, + "x": 874, + "y": 2196, "w": 48, - "h": 42 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 48, - "h": 42 + "h": 46 }, "sourceSize": { "w": 48, @@ -8842,8 +8842,8 @@ }, "player_155_001.png": { "frame": { - "x": 1551, - "y": 0, + "x": 1883, + "y": 427, "w": 60, "h": 60 }, @@ -8862,8 +8862,8 @@ }, "player_155_2_001.png": { "frame": { - "x": 114, - "y": 1743, + "x": 627, + "y": 2083, "w": 56, "h": 56 }, @@ -8882,18 +8882,18 @@ }, "player_155_extra_001.png": { "frame": { - "x": 1904, - "y": 1353, + "x": 970, + "y": 2196, "w": 44, - "h": 40 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 44, - "h": 40 + "h": 46 }, "sourceSize": { "w": 44, @@ -8902,8 +8902,8 @@ }, "player_156_001.png": { "frame": { - "x": 1551, - "y": 61, + "x": 1883, + "y": 488, "w": 60, "h": 60 }, @@ -8922,8 +8922,8 @@ }, "player_156_2_001.png": { "frame": { - "x": 171, - "y": 1743, + "x": 684, + "y": 2083, "w": 56, "h": 56 }, @@ -8942,18 +8942,18 @@ }, "player_156_extra_001.png": { "frame": { - "x": 1700, - "y": 1874, - "w": 51, - "h": 51 + "x": 2179, + "y": 1964, + "w": 52, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 51, - "h": 51 + "x": 0, + "y": 0, + "w": 52, + "h": 52 }, "sourceSize": { "w": 52, @@ -8962,8 +8962,8 @@ }, "player_157_001.png": { "frame": { - "x": 1551, - "y": 122, + "x": 1883, + "y": 549, "w": 60, "h": 60 }, @@ -8982,18 +8982,18 @@ }, "player_157_2_001.png": { "frame": { - "x": 1452, - "y": 1724, + "x": 741, + "y": 2083, "w": 56, - "h": 55 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 56, - "h": 55 + "h": 56 }, "sourceSize": { "w": 56, @@ -9002,18 +9002,18 @@ }, "player_157_extra_001.png": { "frame": { - "x": 1904, - "y": 1145, - "w": 45, - "h": 41 + "x": 2179, + "y": 2017, + "w": 48, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 45, - "h": 41 + "w": 48, + "h": 52 }, "sourceSize": { "w": 48, @@ -9022,8 +9022,8 @@ }, "player_158_001.png": { "frame": { - "x": 883, - "y": 1372, + "x": 63, + "y": 1803, "w": 62, "h": 62 }, @@ -9042,8 +9042,8 @@ }, "player_158_2_001.png": { "frame": { - "x": 175, - "y": 1684, + "x": 2066, + "y": 0, "w": 58, "h": 58 }, @@ -9062,18 +9062,18 @@ }, "player_158_extra_001.png": { "frame": { - "x": 882, - "y": 596, - "w": 53, - "h": 58 + "x": 1698, + "y": 1111, + "w": 58, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 53, - "h": 58 + "x": 0, + "y": 0, + "w": 58, + "h": 64 }, "sourceSize": { "w": 58, @@ -9082,8 +9082,8 @@ }, "player_159_001.png": { "frame": { - "x": 378, - "y": 1372, + "x": 449, + "y": 1803, "w": 62, "h": 62 }, @@ -9102,8 +9102,8 @@ }, "player_159_2_001.png": { "frame": { - "x": 234, - "y": 1684, + "x": 2066, + "y": 59, "w": 58, "h": 58 }, @@ -9122,18 +9122,18 @@ }, "player_159_extra_001.png": { "frame": { - "x": 293, - "y": 1684, - "w": 56, - "h": 58 + "x": 1698, + "y": 1342, + "w": 58, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 56, - "h": 58 + "y": 0, + "w": 58, + "h": 64 }, "sourceSize": { "w": 58, @@ -9142,8 +9142,8 @@ }, "player_16_001.png": { "frame": { - "x": 1551, - "y": 183, + "x": 1883, + "y": 610, "w": 60, "h": 60 }, @@ -9162,8 +9162,8 @@ }, "player_16_2_001.png": { "frame": { - "x": 0, - "y": 1928, + "x": 664, + "y": 2197, "w": 42, "h": 42 }, @@ -9182,8 +9182,8 @@ }, "player_160_001.png": { "frame": { - "x": 946, - "y": 1372, + "x": 126, + "y": 1803, "w": 62, "h": 62 }, @@ -9202,8 +9202,8 @@ }, "player_160_2_001.png": { "frame": { - "x": 350, - "y": 1684, + "x": 2066, + "y": 118, "w": 58, "h": 58 }, @@ -9222,17 +9222,17 @@ }, "player_160_extra_001.png": { "frame": { - "x": 228, - "y": 1743, - "w": 54, + "x": 798, + "y": 2083, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 54, + "w": 56, "h": 56 }, "sourceSize": { @@ -9242,8 +9242,8 @@ }, "player_161_001.png": { "frame": { - "x": 441, - "y": 1372, + "x": 512, + "y": 1803, "w": 62, "h": 62 }, @@ -9262,8 +9262,8 @@ }, "player_161_2_001.png": { "frame": { - "x": 409, - "y": 1684, + "x": 2066, + "y": 177, "w": 58, "h": 58 }, @@ -9282,17 +9282,17 @@ }, "player_161_extra_001.png": { "frame": { - "x": 283, - "y": 1743, - "w": 54, + "x": 1989, + "y": 2056, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 54, + "w": 56, "h": 56 }, "sourceSize": { @@ -9302,8 +9302,8 @@ }, "player_162_001.png": { "frame": { - "x": 1009, - "y": 1372, + "x": 189, + "y": 1803, "w": 62, "h": 62 }, @@ -9322,8 +9322,8 @@ }, "player_162_2_001.png": { "frame": { - "x": 468, - "y": 1684, + "x": 2066, + "y": 236, "w": 58, "h": 58 }, @@ -9342,18 +9342,18 @@ }, "player_162_extra_001.png": { "frame": { - "x": 875, - "y": 1800, - "w": 52, - "h": 55 + "x": 516, + "y": 1738, + "w": 58, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 52, - "h": 55 + "x": 0, + "y": 0, + "w": 58, + "h": 64 }, "sourceSize": { "w": 58, @@ -9362,8 +9362,8 @@ }, "player_163_001.png": { "frame": { - "x": 1072, - "y": 1372, + "x": 575, + "y": 1803, "w": 62, "h": 62 }, @@ -9382,8 +9382,8 @@ }, "player_163_2_001.png": { "frame": { - "x": 527, - "y": 1684, + "x": 2066, + "y": 295, "w": 58, "h": 58 }, @@ -9402,18 +9402,18 @@ }, "player_163_extra_001.png": { "frame": { - "x": 884, - "y": 534, - "w": 53, - "h": 58 + "x": 1698, + "y": 1407, + "w": 58, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 53, - "h": 58 + "x": 0, + "y": 0, + "w": 58, + "h": 64 }, "sourceSize": { "w": 58, @@ -9422,10 +9422,10 @@ }, "player_164_001.png": { "frame": { - "x": 1064, - "y": 1135, + "x": 1249, + "y": 953, "w": 60, - "h": 66 + "h": 72 }, "rotated": false, "trimmed": true, @@ -9433,7 +9433,7 @@ "x": 0, "y": 0, "w": 60, - "h": 66 + "h": 72 }, "sourceSize": { "w": 60, @@ -9442,18 +9442,18 @@ }, "player_164_2_001.png": { "frame": { - "x": 1904, - "y": 0, + "x": 2237, + "y": 529, "w": 48, - "h": 45 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 48, - "h": 45 + "h": 48 }, "sourceSize": { "w": 48, @@ -9462,8 +9462,8 @@ }, "player_165_001.png": { "frame": { - "x": 195, - "y": 1267, + "x": 575, + "y": 1738, "w": 64, "h": 62 }, @@ -9482,18 +9482,18 @@ }, "player_165_2_001.png": { "frame": { - "x": 284, - "y": 1825, - "w": 55, - "h": 30 + "x": 1576, + "y": 2073, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 26, - "w": 55, - "h": 30 + "x": 0, + "y": 0, + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -9502,18 +9502,18 @@ }, "player_165_extra_001.png": { "frame": { - "x": 249, - "y": 552, - "w": 38, - "h": 5 + "x": 636, + "y": 148, + "w": 40, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 41, - "w": 38, - "h": 5 + "y": 0, + "w": 40, + "h": 46 }, "sourceSize": { "w": 40, @@ -9522,9 +9522,9 @@ }, "player_166_001.png": { "frame": { - "x": 1066, - "y": 865, - "w": 66, + "x": 1563, + "y": 674, + "w": 68, "h": 68 }, "rotated": false, @@ -9532,7 +9532,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, + "w": 68, "h": 68 }, "sourceSize": { @@ -9542,9 +9542,9 @@ }, "player_166_2_001.png": { "frame": { - "x": 1135, - "y": 1372, - "w": 62, + "x": 640, + "y": 1738, + "w": 64, "h": 62 }, "rotated": false, @@ -9552,7 +9552,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 62, + "w": 64, "h": 62 }, "sourceSize": { @@ -9562,8 +9562,8 @@ }, "player_167_001.png": { "frame": { - "x": 1551, - "y": 244, + "x": 1883, + "y": 671, "w": 60, "h": 60 }, @@ -9582,18 +9582,18 @@ }, "player_167_2_001.png": { "frame": { - "x": 586, - "y": 1738, + "x": 1810, + "y": 2082, "w": 56, - "h": 47 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, + "y": 0, "w": 56, - "h": 47 + "h": 56 }, "sourceSize": { "w": 56, @@ -9602,18 +9602,18 @@ }, "player_167_extra_001.png": { "frame": { - "x": 1591, - "y": 1920, + "x": 1530, + "y": 2138, "w": 36, - "h": 9 + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 35, + "y": 0, "w": 36, - "h": 9 + "h": 44 }, "sourceSize": { "w": 36, @@ -9622,8 +9622,8 @@ }, "player_168_001.png": { "frame": { - "x": 1125, - "y": 1135, + "x": 1637, + "y": 926, "w": 66, "h": 62 }, @@ -9642,17 +9642,17 @@ }, "player_168_2_001.png": { "frame": { - "x": 1231, - "y": 863, - "w": 65, + "x": 1637, + "y": 124, + "w": 66, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 65, + "w": 66, "h": 60 }, "sourceSize": { @@ -9662,18 +9662,18 @@ }, "player_168_extra_001.png": { "frame": { - "x": 1321, - "y": 958, - "w": 39, - "h": 16 + "x": 1680, + "y": 1725, + "w": 64, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 25, + "x": 0, "y": 0, - "w": 39, - "h": 16 + "w": 64, + "h": 32 }, "sourceSize": { "w": 64, @@ -9682,18 +9682,18 @@ }, "player_169_001.png": { "frame": { - "x": 736, - "y": 532, - "w": 74, - "h": 63 + "x": 73, + "y": 1192, + "w": 76, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 74, - "h": 63 + "w": 76, + "h": 64 }, "sourceSize": { "w": 76, @@ -9702,18 +9702,18 @@ }, "player_169_2_001.png": { "frame": { - "x": 483, - "y": 1140, - "w": 66, - "h": 56 + "x": 1563, + "y": 743, + "w": 68, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, - "h": 56 + "w": 68, + "h": 58 }, "sourceSize": { "w": 68, @@ -9722,8 +9722,8 @@ }, "player_17_001.png": { "frame": { - "x": 1551, - "y": 305, + "x": 1883, + "y": 732, "w": 60, "h": 60 }, @@ -9742,8 +9742,8 @@ }, "player_17_2_001.png": { "frame": { - "x": 338, - "y": 1743, + "x": 1867, + "y": 2082, "w": 56, "h": 56 }, @@ -9762,8 +9762,8 @@ }, "player_170_001.png": { "frame": { - "x": 1549, - "y": 366, + "x": 1883, + "y": 793, "w": 60, "h": 60 }, @@ -9782,8 +9782,8 @@ }, "player_170_2_001.png": { "frame": { - "x": 643, - "y": 1743, + "x": 855, + "y": 2062, "w": 56, "h": 56 }, @@ -9802,10 +9802,10 @@ }, "player_170_extra_001.png": { "frame": { - "x": 756, - "y": 1825, + "x": 2182, + "y": 688, "w": 54, - "h": 30 + "h": 32 }, "rotated": false, "trimmed": true, @@ -9813,7 +9813,7 @@ "x": 0, "y": 0, "w": 54, - "h": 30 + "h": 32 }, "sourceSize": { "w": 54, @@ -9822,8 +9822,8 @@ }, "player_171_001.png": { "frame": { - "x": 737, - "y": 462, + "x": 1201, + "y": 518, "w": 74, "h": 60 }, @@ -9842,18 +9842,18 @@ }, "player_171_2_001.png": { "frame": { - "x": 875, - "y": 219, + "x": 1249, + "y": 1026, "w": 72, - "h": 53 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 72, - "h": 53 + "h": 56 }, "sourceSize": { "w": 72, @@ -9862,18 +9862,18 @@ }, "player_172_001.png": { "frame": { - "x": 1298, - "y": 573, - "w": 63, - "h": 61 + "x": 1637, + "y": 989, + "w": 66, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 63, - "h": 61 + "x": 0, + "y": 0, + "w": 66, + "h": 62 }, "sourceSize": { "w": 66, @@ -9882,18 +9882,18 @@ }, "player_172_2_001.png": { "frame": { - "x": 1670, - "y": 882, - "w": 59, - "h": 57 + "x": 898, + "y": 1781, + "w": 62, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 59, - "h": 57 + "x": 0, + "y": 0, + "w": 62, + "h": 58 }, "sourceSize": { "w": 62, @@ -9902,18 +9902,18 @@ }, "player_173_001.png": { "frame": { - "x": 369, - "y": 923, - "w": 71, - "h": 68 + "x": 410, + "y": 1063, + "w": 78, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 71, - "h": 68 + "w": 78, + "h": 70 }, "sourceSize": { "w": 78, @@ -9922,18 +9922,18 @@ }, "player_173_2_001.png": { "frame": { - "x": 1134, - "y": 1059, - "w": 66, - "h": 64 + "x": 1200, + "y": 675, + "w": 74, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, - "h": 64 + "w": 74, + "h": 66 }, "sourceSize": { "w": 74, @@ -9942,18 +9942,18 @@ }, "player_173_extra_001.png": { "frame": { - "x": 171, - "y": 1856, - "w": 51, - "h": 25 + "x": 1881, + "y": 854, + "w": 60, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 51, - "h": 25 + "w": 60, + "h": 54 }, "sourceSize": { "w": 60, @@ -9962,10 +9962,10 @@ }, "player_174_001.png": { "frame": { - "x": 875, - "y": 273, + "x": 1209, + "y": 1225, "w": 72, - "h": 70 + "h": 72 }, "rotated": false, "trimmed": true, @@ -9973,7 +9973,7 @@ "x": 0, "y": 0, "w": 72, - "h": 70 + "h": 72 }, "sourceSize": { "w": 72, @@ -9982,10 +9982,10 @@ }, "player_174_2_001.png": { "frame": { - "x": 550, - "y": 1140, + "x": 1637, + "y": 185, "w": 66, - "h": 60 + "h": 64 }, "rotated": false, "trimmed": true, @@ -9993,7 +9993,7 @@ "x": 0, "y": 0, "w": 66, - "h": 60 + "h": 64 }, "sourceSize": { "w": 66, @@ -10002,18 +10002,18 @@ }, "player_174_extra_001.png": { "frame": { - "x": 1387, - "y": 1400, - "w": 23, - "h": 34 + "x": 1947, + "y": 1885, + "w": 24, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 23, - "h": 34 + "w": 24, + "h": 50 }, "sourceSize": { "w": 24, @@ -10022,18 +10022,18 @@ }, "player_175_001.png": { "frame": { - "x": 1090, - "y": 236, - "w": 69, - "h": 63 + "x": 1218, + "y": 1150, + "w": 72, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 69, - "h": 63 + "w": 72, + "h": 64 }, "sourceSize": { "w": 72, @@ -10042,18 +10042,18 @@ }, "player_175_2_001.png": { "frame": { - "x": 800, - "y": 1267, - "w": 64, - "h": 57 + "x": 898, + "y": 1612, + "w": 66, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 64, - "h": 57 + "w": 66, + "h": 58 }, "sourceSize": { "w": 66, @@ -10062,18 +10062,18 @@ }, "player_176_001.png": { "frame": { - "x": 566, - "y": 1439, - "w": 61, - "h": 61 + "x": 252, + "y": 1803, + "w": 62, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, - "h": 61 + "w": 62, + "h": 62 }, "sourceSize": { "w": 62, @@ -10082,8 +10082,8 @@ }, "player_176_2_001.png": { "frame": { - "x": 1549, - "y": 427, + "x": 1881, + "y": 909, "w": 60, "h": 60 }, @@ -10102,19 +10102,19 @@ }, "player_176_extra_001.png": { "frame": { - "x": 861, - "y": 1258, - "w": 40, - "h": 8 + "x": 0, + "y": 1988, + "w": 42, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 40, - "h": 8 - }, + "w": 42, + "h": 18 + }, "sourceSize": { "w": 42, "h": 18 @@ -10122,18 +10122,18 @@ }, "player_177_001.png": { "frame": { - "x": 1298, - "y": 635, - "w": 62, - "h": 63 + "x": 705, + "y": 1738, + "w": 64, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 62, - "h": 63 + "w": 64, + "h": 64 }, "sourceSize": { "w": 64, @@ -10142,18 +10142,18 @@ }, "player_177_2_001.png": { "frame": { - "x": 601, - "y": 1891, - "w": 48, - "h": 36 + "x": 1515, + "y": 2081, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 20, - "w": 48, - "h": 36 + "y": 0, + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -10162,8 +10162,8 @@ }, "player_178_001.png": { "frame": { - "x": 1198, - "y": 1372, + "x": 638, + "y": 1803, "w": 62, "h": 62 }, @@ -10182,18 +10182,18 @@ }, "player_178_2_001.png": { "frame": { - "x": 498, - "y": 1846, + "x": 2160, + "y": 2070, "w": 52, - "h": 39 + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 52, - "h": 39 + "h": 44 }, "sourceSize": { "w": 52, @@ -10202,10 +10202,10 @@ }, "player_179_001.png": { "frame": { - "x": 1298, - "y": 699, + "x": 770, + "y": 1738, "w": 62, - "h": 63 + "h": 64 }, "rotated": false, "trimmed": true, @@ -10213,7 +10213,7 @@ "x": 0, "y": 0, "w": 62, - "h": 63 + "h": 64 }, "sourceSize": { "w": 62, @@ -10222,18 +10222,18 @@ }, "player_179_2_001.png": { "frame": { - "x": 763, - "y": 1733, + "x": 912, + "y": 2081, "w": 56, - "h": 38 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 18, + "y": 0, "w": 56, - "h": 38 + "h": 56 }, "sourceSize": { "w": 56, @@ -10242,8 +10242,8 @@ }, "player_18_001.png": { "frame": { - "x": 1549, - "y": 488, + "x": 1881, + "y": 970, "w": 60, "h": 60 }, @@ -10262,8 +10262,8 @@ }, "player_18_2_001.png": { "frame": { - "x": 395, - "y": 1743, + "x": 969, + "y": 2081, "w": 56, "h": 56 }, @@ -10282,18 +10282,18 @@ }, "player_180_001.png": { "frame": { - "x": 185, - "y": 1439, - "w": 61, - "h": 61 + "x": 961, + "y": 1803, + "w": 62, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 61, - "h": 61 + "x": 0, + "y": 0, + "w": 62, + "h": 62 }, "sourceSize": { "w": 62, @@ -10302,18 +10302,18 @@ }, "player_180_2_001.png": { "frame": { - "x": 700, - "y": 1797, - "w": 55, - "h": 44 + "x": 1098, + "y": 2063, + "w": 56, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 10, - "w": 55, - "h": 44 + "x": 0, + "y": 0, + "w": 56, + "h": 54 }, "sourceSize": { "w": 56, @@ -10322,18 +10322,18 @@ }, "player_180_extra_001.png": { "frame": { - "x": 804, - "y": 1954, - "w": 36, - "h": 16 + "x": 41, + "y": 2243, + "w": 38, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 36, - "h": 16 + "w": 38, + "h": 30 }, "sourceSize": { "w": 38, @@ -10342,8 +10342,8 @@ }, "player_181_001.png": { "frame": { - "x": 1261, - "y": 1372, + "x": 315, + "y": 1803, "w": 62, "h": 62 }, @@ -10362,8 +10362,8 @@ }, "player_181_2_001.png": { "frame": { - "x": 1098, - "y": 1667, + "x": 2066, + "y": 354, "w": 58, "h": 56 }, @@ -10382,8 +10382,8 @@ }, "player_182_001.png": { "frame": { - "x": 1324, - "y": 1372, + "x": 701, + "y": 1803, "w": 62, "h": 62 }, @@ -10402,8 +10402,8 @@ }, "player_182_2_001.png": { "frame": { - "x": 820, - "y": 1743, + "x": 1155, + "y": 2081, "w": 56, "h": 56 }, @@ -10422,8 +10422,8 @@ }, "player_183_001.png": { "frame": { - "x": 1427, - "y": 0, + "x": 1024, + "y": 1803, "w": 62, "h": 62 }, @@ -10442,18 +10442,18 @@ }, "player_183_2_001.png": { "frame": { - "x": 340, - "y": 1800, - "w": 55, - "h": 53 + "x": 1212, + "y": 2081, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 55, - "h": 53 + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -10462,8 +10462,8 @@ }, "player_184_001.png": { "frame": { - "x": 1418, - "y": 446, + "x": 764, + "y": 1803, "w": 60, "h": 62 }, @@ -10482,18 +10482,18 @@ }, "player_184_2_001.png": { "frame": { - "x": 586, - "y": 1684, + "x": 2066, + "y": 411, "w": 58, - "h": 53 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 58, - "h": 53 + "h": 56 }, "sourceSize": { "w": 58, @@ -10502,18 +10502,18 @@ }, "player_185_001.png": { "frame": { - "x": 568, - "y": 1377, + "x": 1087, + "y": 1803, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -10522,18 +10522,18 @@ }, "player_185_2_001.png": { "frame": { - "x": 881, - "y": 1727, + "x": 1269, + "y": 2081, "w": 56, - "h": 50 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 56, - "h": 50 + "h": 56 }, "sourceSize": { "w": 56, @@ -10542,8 +10542,8 @@ }, "player_185_extra_001.png": { "frame": { - "x": 1216, - "y": 835, + "x": 1881, + "y": 2300, "w": 14, "h": 14 }, @@ -10562,18 +10562,18 @@ }, "player_186_001.png": { "frame": { - "x": 1298, - "y": 763, - "w": 61, - "h": 63 + "x": 1625, + "y": 1053, + "w": 62, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 61, - "h": 63 + "x": 0, + "y": 0, + "w": 62, + "h": 66 }, "sourceSize": { "w": 62, @@ -10582,18 +10582,18 @@ }, "player_186_2_001.png": { "frame": { - "x": 1987, - "y": 1357, - "w": 25, - "h": 16 + "x": 641, + "y": 1057, + "w": 26, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 25, - "h": 16 + "w": 26, + "h": 36 }, "sourceSize": { "w": 26, @@ -10602,8 +10602,8 @@ }, "player_187_001.png": { "frame": { - "x": 1427, - "y": 63, + "x": 825, + "y": 1803, "w": 62, "h": 62 }, @@ -10622,8 +10622,8 @@ }, "player_187_2_001.png": { "frame": { - "x": 452, - "y": 1743, + "x": 1326, + "y": 2081, "w": 56, "h": 56 }, @@ -10642,8 +10642,8 @@ }, "player_188_001.png": { "frame": { - "x": 1549, - "y": 549, + "x": 1825, + "y": 1860, "w": 60, "h": 60 }, @@ -10662,8 +10662,8 @@ }, "player_188_2_001.png": { "frame": { - "x": 509, - "y": 1743, + "x": 1383, + "y": 2081, "w": 56, "h": 56 }, @@ -10682,8 +10682,8 @@ }, "player_189_001.png": { "frame": { - "x": 1549, - "y": 610, + "x": 1871, + "y": 1530, "w": 60, "h": 60 }, @@ -10702,8 +10702,8 @@ }, "player_189_2_001.png": { "frame": { - "x": 938, - "y": 1742, + "x": 1692, + "y": 2066, "w": 56, "h": 56 }, @@ -10722,18 +10722,18 @@ }, "player_189_extra_001.png": { "frame": { - "x": 1266, - "y": 1032, - "w": 30, - "h": 20 + "x": 1395, + "y": 2243, + "w": 32, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 12, - "w": 30, - "h": 20 + "x": 0, + "y": 0, + "w": 32, + "h": 32 }, "sourceSize": { "w": 32, @@ -10742,8 +10742,8 @@ }, "player_19_001.png": { "frame": { - "x": 1548, - "y": 671, + "x": 1871, + "y": 1591, "w": 60, "h": 60 }, @@ -10762,8 +10762,8 @@ }, "player_19_2_001.png": { "frame": { - "x": 43, - "y": 1928, + "x": 707, + "y": 2197, "w": 42, "h": 42 }, @@ -10782,8 +10782,8 @@ }, "player_190_001.png": { "frame": { - "x": 1548, - "y": 815, + "x": 1871, + "y": 1652, "w": 60, "h": 60 }, @@ -10802,8 +10802,8 @@ }, "player_190_2_001.png": { "frame": { - "x": 995, - "y": 1742, + "x": 1924, + "y": 2066, "w": 56, "h": 56 }, @@ -10822,8 +10822,8 @@ }, "player_191_001.png": { "frame": { - "x": 1548, - "y": 876, + "x": 1871, + "y": 1713, "w": 60, "h": 60 }, @@ -10842,8 +10842,8 @@ }, "player_191_2_001.png": { "frame": { - "x": 1052, - "y": 1742, + "x": 1026, + "y": 2064, "w": 56, "h": 56 }, @@ -10862,8 +10862,8 @@ }, "player_192_001.png": { "frame": { - "x": 1427, - "y": 126, + "x": 1150, + "y": 1803, "w": 62, "h": 62 }, @@ -10882,9 +10882,9 @@ }, "player_192_2_001.png": { "frame": { - "x": 1734, - "y": 0, - "w": 57, + "x": 2066, + "y": 468, + "w": 58, "h": 56 }, "rotated": false, @@ -10892,7 +10892,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 57, + "w": 58, "h": 56 }, "sourceSize": { @@ -10902,18 +10902,18 @@ }, "player_193_001.png": { "frame": { - "x": 631, - "y": 1377, + "x": 1213, + "y": 1803, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -10922,18 +10922,18 @@ }, "player_193_2_001.png": { "frame": { - "x": 551, - "y": 1852, - "w": 52, - "h": 37 + "x": 1633, + "y": 2097, + "w": 56, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 52, - "h": 37 + "x": 0, + "y": 0, + "w": 56, + "h": 38 }, "sourceSize": { "w": 56, @@ -10942,17 +10942,17 @@ }, "player_194_001.png": { "frame": { - "x": 628, - "y": 1439, - "w": 61, + "x": 1276, + "y": 1803, + "w": 62, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -10962,18 +10962,18 @@ }, "player_194_2_001.png": { "frame": { - "x": 1079, - "y": 1855, - "w": 40, - "h": 22 + "x": 190, + "y": 2197, + "w": 44, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 18, - "w": 40, - "h": 22 + "x": 0, + "y": 0, + "w": 44, + "h": 40 }, "sourceSize": { "w": 44, @@ -10982,17 +10982,17 @@ }, "player_195_001.png": { "frame": { - "x": 1427, - "y": 189, - "w": 61, + "x": 1339, + "y": 1803, + "w": 62, "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 62 }, "sourceSize": { @@ -11002,18 +11002,18 @@ }, "player_195_2_001.png": { "frame": { - "x": 1953, - "y": 109, - "w": 34, - "h": 17 + "x": 750, + "y": 2197, + "w": 42, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 34, - "h": 17 + "w": 42, + "h": 34 }, "sourceSize": { "w": 42, @@ -11022,18 +11022,18 @@ }, "player_195_extra_001.png": { "frame": { - "x": 164, - "y": 360, - "w": 49, - "h": 8 + "x": 604, + "y": 2058, + "w": 52, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 49, - "h": 8 + "x": 0, + "y": 0, + "w": 52, + "h": 24 }, "sourceSize": { "w": 52, @@ -11042,17 +11042,17 @@ }, "player_196_001.png": { "frame": { - "x": 1200, - "y": 996, - "w": 65, + "x": 1636, + "y": 250, + "w": 66, "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 65, + "w": 66, "h": 62 }, "sourceSize": { @@ -11062,8 +11062,8 @@ }, "player_196_2_001.png": { "frame": { - "x": 1548, - "y": 937, + "x": 1869, + "y": 1774, "w": 60, "h": 56 }, @@ -11082,10 +11082,10 @@ }, "player_196_extra_001.png": { "frame": { - "x": 1354, - "y": 1530, + "x": 1581, + "y": 1909, "w": 60, - "h": 27 + "h": 34 }, "rotated": false, "trimmed": true, @@ -11093,7 +11093,7 @@ "x": 0, "y": 0, "w": 60, - "h": 27 + "h": 34 }, "sourceSize": { "w": 60, @@ -11102,9 +11102,9 @@ }, "player_197_001.png": { "frame": { - "x": 1134, - "y": 933, - "w": 66, + "x": 554, + "y": 1548, + "w": 68, "h": 62 }, "rotated": false, @@ -11112,7 +11112,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, + "w": 68, "h": 62 }, "sourceSize": { @@ -11122,18 +11122,18 @@ }, "player_197_2_001.png": { "frame": { - "x": 1275, - "y": 1734, - "w": 56, - "h": 30 + "x": 1402, + "y": 1803, + "w": 62, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 56, - "h": 30 + "w": 62, + "h": 56 }, "sourceSize": { "w": 62, @@ -11142,18 +11142,18 @@ }, "player_197_extra_001.png": { "frame": { - "x": 488, - "y": 660, - "w": 47, - "h": 10 + "x": 1440, + "y": 2109, + "w": 48, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 47, - "h": 10 + "x": 0, + "y": 0, + "w": 48, + "h": 28 }, "sourceSize": { "w": 48, @@ -11162,9 +11162,9 @@ }, "player_198_001.png": { "frame": { - "x": 1161, - "y": 187, - "w": 67, + "x": 623, + "y": 1548, + "w": 68, "h": 62 }, "rotated": false, @@ -11172,7 +11172,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 67, + "w": 68, "h": 62 }, "sourceSize": { @@ -11182,18 +11182,18 @@ }, "player_198_2_001.png": { "frame": { - "x": 1844, - "y": 1138, - "w": 53, - "h": 51 + "x": 2066, + "y": 525, + "w": 58, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 53, - "h": 51 + "y": 0, + "w": 58, + "h": 56 }, "sourceSize": { "w": 58, @@ -11202,8 +11202,8 @@ }, "player_199_001.png": { "frame": { - "x": 1548, - "y": 994, + "x": 1944, + "y": 0, "w": 60, "h": 60 }, @@ -11222,8 +11222,8 @@ }, "player_199_2_001.png": { "frame": { - "x": 1109, - "y": 1742, + "x": 2046, + "y": 2065, "w": 56, "h": 56 }, @@ -11242,8 +11242,8 @@ }, "player_20_001.png": { "frame": { - "x": 1548, - "y": 1055, + "x": 1944, + "y": 61, "w": 60, "h": 60 }, @@ -11262,8 +11262,8 @@ }, "player_20_2_001.png": { "frame": { - "x": 1904, - "y": 46, + "x": 2237, + "y": 578, "w": 48, "h": 48 }, @@ -11282,8 +11282,8 @@ }, "player_200_001.png": { "frame": { - "x": 1548, - "y": 1116, + "x": 1944, + "y": 122, "w": 60, "h": 60 }, @@ -11302,8 +11302,8 @@ }, "player_200_2_001.png": { "frame": { - "x": 1332, - "y": 1742, + "x": 2125, + "y": 0, "w": 56, "h": 56 }, @@ -11322,8 +11322,8 @@ }, "player_201_001.png": { "frame": { - "x": 1548, - "y": 1177, + "x": 1944, + "y": 183, "w": 60, "h": 60 }, @@ -11342,8 +11342,8 @@ }, "player_201_2_001.png": { "frame": { - "x": 1166, - "y": 1742, + "x": 2125, + "y": 57, "w": 56, "h": 56 }, @@ -11362,8 +11362,8 @@ }, "player_202_001.png": { "frame": { - "x": 1548, - "y": 1238, + "x": 1944, + "y": 244, "w": 60, "h": 60 }, @@ -11382,8 +11382,8 @@ }, "player_202_2_001.png": { "frame": { - "x": 1389, - "y": 1742, + "x": 2125, + "y": 114, "w": 56, "h": 56 }, @@ -11402,8 +11402,8 @@ }, "player_203_001.png": { "frame": { - "x": 1548, - "y": 1299, + "x": 1944, + "y": 305, "w": 60, "h": 60 }, @@ -11422,8 +11422,8 @@ }, "player_203_2_001.png": { "frame": { - "x": 1509, - "y": 1741, + "x": 2125, + "y": 171, "w": 56, "h": 56 }, @@ -11442,17 +11442,17 @@ }, "player_204_001.png": { "frame": { - "x": 247, - "y": 1439, - "w": 61, + "x": 1465, + "y": 1803, + "w": 62, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -11462,8 +11462,8 @@ }, "player_204_2_001.png": { "frame": { - "x": 704, - "y": 1740, + "x": 2125, + "y": 228, "w": 56, "h": 56 }, @@ -11482,17 +11482,17 @@ }, "player_204_extra_001.png": { "frame": { - "x": 666, - "y": 1800, - "w": 33, + "x": 1812, + "y": 2039, + "w": 58, "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 25, + "x": 0, "y": 0, - "w": 33, + "w": 58, "h": 42 }, "sourceSize": { @@ -11502,18 +11502,18 @@ }, "player_205_001.png": { "frame": { - "x": 260, - "y": 1267, + "x": 833, + "y": 1738, "w": 64, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 64, - "h": 61 + "h": 62 }, "sourceSize": { "w": 64, @@ -11522,8 +11522,8 @@ }, "player_205_2_001.png": { "frame": { - "x": 1566, - "y": 1741, + "x": 1702, + "y": 1239, "w": 52, "h": 56 }, @@ -11542,10 +11542,10 @@ }, "player_205_extra_001.png": { "frame": { - "x": 892, - "y": 978, + "x": 2221, + "y": 2243, "w": 30, - "h": 16 + "h": 24 }, "rotated": false, "trimmed": true, @@ -11553,7 +11553,7 @@ "x": 0, "y": 0, "w": 30, - "h": 16 + "h": 24 }, "sourceSize": { "w": 30, @@ -11562,8 +11562,8 @@ }, "player_206_001.png": { "frame": { - "x": 1539, - "y": 1360, + "x": 1944, + "y": 366, "w": 60, "h": 60 }, @@ -11582,8 +11582,8 @@ }, "player_206_2_001.png": { "frame": { - "x": 1904, - "y": 1394, + "x": 235, + "y": 2197, "w": 44, "h": 42 }, @@ -11602,8 +11602,8 @@ }, "player_207_001.png": { "frame": { - "x": 1539, - "y": 1421, + "x": 1944, + "y": 427, "w": 60, "h": 60 }, @@ -11622,8 +11622,8 @@ }, "player_207_2_001.png": { "frame": { - "x": 1619, - "y": 1741, + "x": 2125, + "y": 285, "w": 56, "h": 56 }, @@ -11642,8 +11642,8 @@ }, "player_208_001.png": { "frame": { - "x": 1427, - "y": 252, + "x": 1528, + "y": 1803, "w": 62, "h": 60 }, @@ -11662,18 +11662,18 @@ }, "player_208_2_001.png": { "frame": { - "x": 1257, - "y": 1967, + "x": 584, + "y": 1314, "w": 22, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 22, - "h": 26 + "h": 28 }, "sourceSize": { "w": 22, @@ -11682,10 +11682,10 @@ }, "player_208_extra_001.png": { "frame": { - "x": 580, - "y": 538, + "x": 2290, + "y": 1673, "w": 22, - "h": 5 + "h": 26 }, "rotated": false, "trimmed": true, @@ -11693,7 +11693,7 @@ "x": 0, "y": 0, "w": 22, - "h": 5 + "h": 26 }, "sourceSize": { "w": 22, @@ -11702,18 +11702,18 @@ }, "player_209_001.png": { "frame": { - "x": 1425, - "y": 509, + "x": 1591, + "y": 1803, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -11722,17 +11722,17 @@ }, "player_209_2_001.png": { "frame": { - "x": 1734, - "y": 57, - "w": 57, + "x": 2066, + "y": 582, + "w": 58, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 57, + "w": 58, "h": 56 }, "sourceSize": { @@ -11742,10 +11742,10 @@ }, "player_209_extra_001.png": { "frame": { - "x": 967, - "y": 1891, + "x": 2237, + "y": 627, "w": 48, - "h": 36 + "h": 38 }, "rotated": false, "trimmed": true, @@ -11753,7 +11753,7 @@ "x": 0, "y": 0, "w": 48, - "h": 36 + "h": 38 }, "sourceSize": { "w": 48, @@ -11762,8 +11762,8 @@ }, "player_21_001.png": { "frame": { - "x": 1539, - "y": 1482, + "x": 1944, + "y": 488, "w": 60, "h": 60 }, @@ -11782,8 +11782,8 @@ }, "player_21_2_001.png": { "frame": { - "x": 1676, - "y": 1741, + "x": 2125, + "y": 342, "w": 56, "h": 56 }, @@ -11802,8 +11802,8 @@ }, "player_210_001.png": { "frame": { - "x": 1425, - "y": 313, + "x": 1654, + "y": 1803, "w": 62, "h": 60 }, @@ -11822,8 +11822,8 @@ }, "player_210_2_001.png": { "frame": { - "x": 1733, - "y": 1741, + "x": 2125, + "y": 399, "w": 56, "h": 54 }, @@ -11842,8 +11842,8 @@ }, "player_211_001.png": { "frame": { - "x": 0, - "y": 1562, + "x": 1944, + "y": 549, "w": 60, "h": 60 }, @@ -11862,8 +11862,8 @@ }, "player_211_2_001.png": { "frame": { - "x": 1792, - "y": 0, + "x": 2125, + "y": 454, "w": 56, "h": 54 }, @@ -11882,10 +11882,10 @@ }, "player_211_extra_001.png": { "frame": { - "x": 1043, - "y": 1954, + "x": 167, + "y": 2274, "w": 36, - "h": 15 + "h": 38 }, "rotated": false, "trimmed": true, @@ -11893,7 +11893,7 @@ "x": 0, "y": 0, "w": 36, - "h": 15 + "h": 38 }, "sourceSize": { "w": 36, @@ -11902,8 +11902,8 @@ }, "player_212_001.png": { "frame": { - "x": 61, - "y": 1562, + "x": 1944, + "y": 610, "w": 60, "h": 60 }, @@ -11922,10 +11922,10 @@ }, "player_212_2_001.png": { "frame": { - "x": 361, - "y": 355, + "x": 2125, + "y": 509, "w": 56, - "h": 13 + "h": 50 }, "rotated": false, "trimmed": true, @@ -11933,7 +11933,7 @@ "x": 0, "y": 0, "w": 56, - "h": 13 + "h": 50 }, "sourceSize": { "w": 56, @@ -11942,8 +11942,8 @@ }, "player_213_001.png": { "frame": { - "x": 1425, - "y": 571, + "x": 1717, + "y": 1803, "w": 62, "h": 60 }, @@ -11962,8 +11962,8 @@ }, "player_213_2_001.png": { "frame": { - "x": 1780, - "y": 1042, + "x": 2125, + "y": 560, "w": 56, "h": 56 }, @@ -11982,8 +11982,8 @@ }, "player_214_001.png": { "frame": { - "x": 1425, - "y": 374, + "x": 1820, + "y": 0, "w": 62, "h": 60 }, @@ -12002,8 +12002,8 @@ }, "player_214_2_001.png": { "frame": { - "x": 645, - "y": 1684, + "x": 2066, + "y": 639, "w": 58, "h": 56 }, @@ -12022,8 +12022,8 @@ }, "player_215_001.png": { "frame": { - "x": 122, - "y": 1562, + "x": 1944, + "y": 671, "w": 60, "h": 60 }, @@ -12042,8 +12042,8 @@ }, "player_215_2_001.png": { "frame": { - "x": 1773, - "y": 1494, + "x": 2125, + "y": 617, "w": 56, "h": 56 }, @@ -12062,8 +12062,8 @@ }, "player_216_001.png": { "frame": { - "x": 183, - "y": 1562, + "x": 1944, + "y": 732, "w": 60, "h": 60 }, @@ -12082,18 +12082,18 @@ }, "player_216_2_001.png": { "frame": { - "x": 1080, - "y": 1928, + "x": 660, + "y": 2278, "w": 36, - "h": 34 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 36, - "h": 34 + "h": 36 }, "sourceSize": { "w": 36, @@ -12102,18 +12102,18 @@ }, "player_216_extra_001.png": { "frame": { - "x": 1873, - "y": 1525, + "x": 903, + "y": 2243, "w": 30, - "h": 22 + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 12, + "y": 0, "w": 30, - "h": 22 + "h": 34 }, "sourceSize": { "w": 30, @@ -12122,8 +12122,8 @@ }, "player_217_001.png": { "frame": { - "x": 244, - "y": 1562, + "x": 1944, + "y": 793, "w": 60, "h": 60 }, @@ -12142,8 +12142,8 @@ }, "player_217_2_001.png": { "frame": { - "x": 305, - "y": 1562, + "x": 1944, + "y": 854, "w": 60, "h": 60 }, @@ -12162,8 +12162,8 @@ }, "player_218_001.png": { "frame": { - "x": 366, - "y": 1562, + "x": 1944, + "y": 915, "w": 60, "h": 60 }, @@ -12182,8 +12182,8 @@ }, "player_218_2_001.png": { "frame": { - "x": 1792, - "y": 55, + "x": 2125, + "y": 674, "w": 56, "h": 56 }, @@ -12202,8 +12202,8 @@ }, "player_219_001.png": { "frame": { - "x": 427, - "y": 1562, + "x": 1944, + "y": 976, "w": 60, "h": 60 }, @@ -12222,18 +12222,18 @@ }, "player_219_2_001.png": { "frame": { - "x": 1792, - "y": 112, + "x": 2125, + "y": 731, "w": 56, - "h": 43 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, + "y": 0, "w": 56, - "h": 43 + "h": 56 }, "sourceSize": { "w": 56, @@ -12242,8 +12242,8 @@ }, "player_22_001.png": { "frame": { - "x": 488, - "y": 1562, + "x": 1944, + "y": 1037, "w": 60, "h": 60 }, @@ -12262,8 +12262,8 @@ }, "player_22_2_001.png": { "frame": { - "x": 1904, - "y": 95, + "x": 2237, + "y": 666, "w": 48, "h": 48 }, @@ -12282,8 +12282,8 @@ }, "player_220_001.png": { "frame": { - "x": 1425, - "y": 632, + "x": 1820, + "y": 61, "w": 62, "h": 60 }, @@ -12302,8 +12302,8 @@ }, "player_220_2_001.png": { "frame": { - "x": 1777, - "y": 1437, + "x": 2125, + "y": 788, "w": 56, "h": 56 }, @@ -12322,8 +12322,8 @@ }, "player_221_001.png": { "frame": { - "x": 1424, - "y": 693, + "x": 1820, + "y": 122, "w": 62, "h": 60 }, @@ -12342,8 +12342,8 @@ }, "player_221_2_001.png": { "frame": { - "x": 1792, - "y": 156, + "x": 2125, + "y": 845, "w": 56, "h": 56 }, @@ -12362,18 +12362,18 @@ }, "player_222_001.png": { "frame": { - "x": 1297, - "y": 1185, - "w": 63, - "h": 61 + "x": 898, + "y": 1718, + "w": 64, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 63, - "h": 61 + "x": 0, + "y": 0, + "w": 64, + "h": 62 }, "sourceSize": { "w": 64, @@ -12382,17 +12382,17 @@ }, "player_222_2_001.png": { "frame": { - "x": 1670, - "y": 940, - "w": 59, + "x": 1944, + "y": 1098, + "w": 60, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 59, + "w": 60, "h": 56 }, "sourceSize": { @@ -12402,18 +12402,18 @@ }, "player_223_001.png": { "frame": { - "x": 690, - "y": 1439, - "w": 61, - "h": 61 + "x": 1818, + "y": 1174, + "w": 62, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 61, - "h": 61 + "w": 62, + "h": 62 }, "sourceSize": { "w": 62, @@ -12422,10 +12422,10 @@ }, "player_223_2_001.png": { "frame": { - "x": 1792, - "y": 213, + "x": 2125, + "y": 902, "w": 56, - "h": 43 + "h": 50 }, "rotated": false, "trimmed": true, @@ -12433,7 +12433,7 @@ "x": 0, "y": 0, "w": 56, - "h": 43 + "h": 50 }, "sourceSize": { "w": 56, @@ -12442,18 +12442,18 @@ }, "player_223_extra_001.png": { "frame": { - "x": 928, - "y": 1846, - "w": 52, - "h": 42 + "x": 2125, + "y": 953, + "w": 56, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 52, - "h": 42 + "w": 56, + "h": 48 }, "sourceSize": { "w": 56, @@ -12462,8 +12462,8 @@ }, "player_224_001.png": { "frame": { - "x": 549, - "y": 1562, + "x": 1944, + "y": 1155, "w": 60, "h": 60 }, @@ -12482,17 +12482,17 @@ }, "player_224_2_001.png": { "frame": { - "x": 1786, - "y": 280, - "w": 55, + "x": 2125, + "y": 1002, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 55, + "w": 56, "h": 56 }, "sourceSize": { @@ -12502,18 +12502,18 @@ }, "player_225_001.png": { "frame": { - "x": 865, - "y": 1267, + "x": 963, + "y": 1738, "w": 64, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 64, - "h": 61 + "h": 62 }, "sourceSize": { "w": 64, @@ -12522,18 +12522,18 @@ }, "player_225_2_001.png": { "frame": { - "x": 1670, - "y": 997, - "w": 59, - "h": 57 + "x": 1944, + "y": 1216, + "w": 60, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 59, - "h": 57 + "y": 0, + "w": 60, + "h": 58 }, "sourceSize": { "w": 60, @@ -12542,10 +12542,10 @@ }, "player_225_extra_001.png": { "frame": { - "x": 1192, - "y": 1170, + "x": 204, + "y": 2274, "w": 38, - "h": 15 + "h": 38 }, "rotated": false, "trimmed": true, @@ -12553,7 +12553,7 @@ "x": 0, "y": 0, "w": 38, - "h": 15 + "h": 38 }, "sourceSize": { "w": 38, @@ -12562,10 +12562,10 @@ }, "player_226_001.png": { "frame": { - "x": 1424, - "y": 754, + "x": 1028, + "y": 1738, "w": 60, - "h": 62 + "h": 64 }, "rotated": false, "trimmed": true, @@ -12573,7 +12573,7 @@ "x": 0, "y": 0, "w": 60, - "h": 62 + "h": 64 }, "sourceSize": { "w": 60, @@ -12582,10 +12582,10 @@ }, "player_226_2_001.png": { "frame": { - "x": 1734, - "y": 114, + "x": 1704, + "y": 66, "w": 52, - "h": 57 + "h": 58 }, "rotated": false, "trimmed": true, @@ -12593,7 +12593,7 @@ "x": 0, "y": 0, "w": 52, - "h": 57 + "h": 58 }, "sourceSize": { "w": 52, @@ -12602,18 +12602,18 @@ }, "player_227_001.png": { "frame": { - "x": 1133, - "y": 865, - "w": 62, - "h": 67 + "x": 1200, + "y": 742, + "w": 64, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 62, - "h": 67 + "w": 64, + "h": 74 }, "sourceSize": { "w": 64, @@ -12622,18 +12622,18 @@ }, "player_227_2_001.png": { "frame": { - "x": 1263, - "y": 924, - "w": 57, - "h": 63 + "x": 1381, + "y": 949, + "w": 58, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 57, - "h": 63 + "w": 58, + "h": 70 }, "sourceSize": { "w": 58, @@ -12642,18 +12642,18 @@ }, "player_227_extra_001.png": { "frame": { - "x": 655, - "y": 960, - "w": 17, - "h": 17 + "x": 2148, + "y": 2124, + "w": 42, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 25, + "x": 0, "y": 0, - "w": 17, - "h": 17 + "w": 42, + "h": 52 }, "sourceSize": { "w": 42, @@ -12662,8 +12662,8 @@ }, "player_228_001.png": { "frame": { - "x": 610, - "y": 1562, + "x": 1944, + "y": 1275, "w": 60, "h": 60 }, @@ -12682,8 +12682,8 @@ }, "player_228_2_001.png": { "frame": { - "x": 1792, - "y": 337, + "x": 2125, + "y": 1059, "w": 56, "h": 56 }, @@ -12702,8 +12702,8 @@ }, "player_229_001.png": { "frame": { - "x": 671, - "y": 1562, + "x": 1944, + "y": 1336, "w": 60, "h": 60 }, @@ -12722,8 +12722,8 @@ }, "player_229_2_001.png": { "frame": { - "x": 1790, - "y": 1551, + "x": 2125, + "y": 1116, "w": 56, "h": 56 }, @@ -12742,10 +12742,10 @@ }, "player_229_extra_001.png": { "frame": { - "x": 984, - "y": 1799, + "x": 2182, + "y": 721, "w": 54, - "h": 18 + "h": 54 }, "rotated": false, "trimmed": true, @@ -12753,7 +12753,7 @@ "x": 0, "y": 0, "w": 54, - "h": 18 + "h": 54 }, "sourceSize": { "w": 54, @@ -12762,8 +12762,8 @@ }, "player_23_001.png": { "frame": { - "x": 732, - "y": 1562, + "x": 1944, + "y": 1397, "w": 60, "h": 60 }, @@ -12782,8 +12782,8 @@ }, "player_23_2_001.png": { "frame": { - "x": 1790, - "y": 394, + "x": 2125, + "y": 1173, "w": 56, "h": 56 }, @@ -12802,10 +12802,10 @@ }, "player_230_001.png": { "frame": { - "x": 0, - "y": 1202, + "x": 1636, + "y": 313, "w": 66, - "h": 64 + "h": 66 }, "rotated": false, "trimmed": true, @@ -12813,7 +12813,7 @@ "x": 0, "y": 0, "w": 66, - "h": 64 + "h": 66 }, "sourceSize": { "w": 66, @@ -12822,18 +12822,18 @@ }, "player_230_2_001.png": { "frame": { - "x": 716, - "y": 1856, + "x": 2237, + "y": 715, "w": 48, - "h": 31 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, + "y": 0, "w": 48, - "h": 31 + "h": 40 }, "sourceSize": { "w": 48, @@ -12842,18 +12842,18 @@ }, "player_230_extra_001.png": { "frame": { - "x": 704, - "y": 1684, - "w": 58, - "h": 55 + "x": 1944, + "y": 1458, + "w": 60, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 58, - "h": 55 + "w": 60, + "h": 60 }, "sourceSize": { "w": 60, @@ -12862,9 +12862,9 @@ }, "player_231_001.png": { "frame": { - "x": 1231, - "y": 1059, - "w": 65, + "x": 968, + "y": 1609, + "w": 66, "h": 60 }, "rotated": false, @@ -12872,7 +12872,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 65, + "w": 66, "h": 60 }, "sourceSize": { @@ -12882,10 +12882,10 @@ }, "player_231_2_001.png": { "frame": { - "x": 1734, - "y": 172, + "x": 1700, + "y": 508, "w": 56, - "h": 57 + "h": 58 }, "rotated": false, "trimmed": true, @@ -12893,7 +12893,7 @@ "x": 0, "y": 0, "w": 56, - "h": 57 + "h": 58 }, "sourceSize": { "w": 56, @@ -12902,8 +12902,8 @@ }, "player_232_001.png": { "frame": { - "x": 793, - "y": 1562, + "x": 1944, + "y": 1519, "w": 60, "h": 60 }, @@ -12922,8 +12922,8 @@ }, "player_232_2_001.png": { "frame": { - "x": 1790, - "y": 1608, + "x": 2125, + "y": 1230, "w": 56, "h": 56 }, @@ -12942,8 +12942,8 @@ }, "player_233_001.png": { "frame": { - "x": 937, - "y": 746, + "x": 1424, + "y": 102, "w": 70, "h": 60 }, @@ -12962,8 +12962,8 @@ }, "player_233_2_001.png": { "frame": { - "x": 924, - "y": 807, + "x": 1419, + "y": 888, "w": 70, "h": 60 }, @@ -12982,8 +12982,8 @@ }, "player_234_001.png": { "frame": { - "x": 325, - "y": 1267, + "x": 1089, + "y": 1738, "w": 64, "h": 60 }, @@ -13002,18 +13002,18 @@ }, "player_234_2_001.png": { "frame": { - "x": 1988, - "y": 96, + "x": 2262, + "y": 2066, "w": 24, - "h": 30 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 16, + "y": 0, "w": 24, - "h": 30 + "h": 46 }, "sourceSize": { "w": 24, @@ -13022,17 +13022,17 @@ }, "player_235_001.png": { "frame": { - "x": 930, - "y": 1267, - "w": 64, + "x": 692, + "y": 1548, + "w": 68, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 64, + "w": 68, "h": 60 }, "sourceSize": { @@ -13042,18 +13042,18 @@ }, "player_235_2_001.png": { "frame": { - "x": 143, - "y": 1857, - "w": 27, - "h": 10 + "x": 2232, + "y": 1910, + "w": 40, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 13, + "x": 0, "y": 0, - "w": 27, - "h": 10 + "w": 40, + "h": 26 }, "sourceSize": { "w": 40, @@ -13062,10 +13062,10 @@ }, "player_236_001.png": { "frame": { - "x": 1231, - "y": 1120, + "x": 1424, + "y": 163, "w": 62, - "h": 65 + "h": 70 }, "rotated": false, "trimmed": true, @@ -13073,7 +13073,7 @@ "x": 0, "y": 0, "w": 62, - "h": 65 + "h": 70 }, "sourceSize": { "w": 62, @@ -13082,18 +13082,18 @@ }, "player_236_2_001.png": { "frame": { - "x": 1904, - "y": 144, - "w": 47, - "h": 48 + "x": 1613, + "y": 1588, + "w": 52, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 47, - "h": 48 + "w": 52, + "h": 66 }, "sourceSize": { "w": 52, @@ -13102,8 +13102,8 @@ }, "player_237_001.png": { "frame": { - "x": 1170, - "y": 1538, + "x": 1932, + "y": 1580, "w": 60, "h": 60 }, @@ -13122,8 +13122,8 @@ }, "player_237_2_001.png": { "frame": { - "x": 854, - "y": 1561, + "x": 1932, + "y": 1641, "w": 60, "h": 60 }, @@ -13142,8 +13142,8 @@ }, "player_238_001.png": { "frame": { - "x": 1231, - "y": 1561, + "x": 1932, + "y": 1702, "w": 60, "h": 60 }, @@ -13162,8 +13162,8 @@ }, "player_238_2_001.png": { "frame": { - "x": 915, - "y": 1561, + "x": 1932, + "y": 1763, "w": 60, "h": 60 }, @@ -13182,18 +13182,18 @@ }, "player_238_extra_001.png": { "frame": { - "x": 950, - "y": 1254, - "w": 25, - "h": 12 + "x": 2182, + "y": 776, + "w": 54, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 29, + "x": 0, "y": 0, - "w": 25, - "h": 12 + "w": 54, + "h": 40 }, "sourceSize": { "w": 54, @@ -13202,8 +13202,8 @@ }, "player_239_001.png": { "frame": { - "x": 1292, - "y": 1561, + "x": 1930, + "y": 1824, "w": 60, "h": 60 }, @@ -13222,8 +13222,8 @@ }, "player_239_2_001.png": { "frame": { - "x": 1790, - "y": 451, + "x": 2125, + "y": 1287, "w": 56, "h": 56 }, @@ -13242,18 +13242,18 @@ }, "player_239_extra_001.png": { "frame": { - "x": 1648, - "y": 1910, + "x": 2235, + "y": 1256, "w": 44, - "h": 15 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 21, + "y": 0, "w": 44, - "h": 15 + "h": 36 }, "sourceSize": { "w": 44, @@ -13262,8 +13262,8 @@ }, "player_24_001.png": { "frame": { - "x": 1353, - "y": 1561, + "x": 1886, + "y": 1885, "w": 60, "h": 60 }, @@ -13282,8 +13282,8 @@ }, "player_24_2_001.png": { "frame": { - "x": 1953, - "y": 283, + "x": 934, + "y": 2243, "w": 34, "h": 34 }, @@ -13302,18 +13302,18 @@ }, "player_240_001.png": { "frame": { - "x": 1424, - "y": 817, + "x": 1820, + "y": 183, "w": 62, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 62, - "h": 61 + "h": 62 }, "sourceSize": { "w": 62, @@ -13322,8 +13322,8 @@ }, "player_240_2_001.png": { "frame": { - "x": 1790, - "y": 1665, + "x": 2125, + "y": 1344, "w": 56, "h": 56 }, @@ -13342,8 +13342,8 @@ }, "player_241_001.png": { "frame": { - "x": 1107, - "y": 1553, + "x": 1096, + "y": 1925, "w": 60, "h": 60 }, @@ -13362,18 +13362,18 @@ }, "player_241_2_001.png": { "frame": { - "x": 396, - "y": 1800, - "w": 55, - "h": 52 + "x": 2123, + "y": 1401, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 55, - "h": 52 + "x": 0, + "y": 0, + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -13382,10 +13382,10 @@ }, "player_241_extra_001.png": { "frame": { - "x": 682, - "y": 1168, + "x": 2123, + "y": 1458, "w": 56, - "h": 24 + "h": 56 }, "rotated": false, "trimmed": true, @@ -13393,7 +13393,7 @@ "x": 0, "y": 0, "w": 56, - "h": 24 + "h": 56 }, "sourceSize": { "w": 56, @@ -13402,9 +13402,9 @@ }, "player_242_001.png": { "frame": { - "x": 309, - "y": 1439, - "w": 61, + "x": 1820, + "y": 1237, + "w": 62, "h": 60 }, "rotated": false, @@ -13412,7 +13412,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -13422,18 +13422,18 @@ }, "player_242_2_001.png": { "frame": { - "x": 203, - "y": 1891, - "w": 45, - "h": 33 + "x": 2123, + "y": 1515, + "w": 52, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 45, - "h": 33 + "w": 52, + "h": 56 }, "sourceSize": { "w": 52, @@ -13442,18 +13442,18 @@ }, "player_243_001.png": { "frame": { - "x": 1297, - "y": 827, + "x": 1635, + "y": 1120, "w": 62, - "h": 63 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 62, - "h": 63 + "h": 66 }, "sourceSize": { "w": 62, @@ -13462,18 +13462,18 @@ }, "player_243_2_001.png": { "frame": { - "x": 1424, - "y": 879, + "x": 1154, + "y": 1738, "w": 60, - "h": 62 + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 60, - "h": 62 + "h": 64 }, "sourceSize": { "w": 60, @@ -13482,18 +13482,18 @@ }, "player_243_extra_001.png": { "frame": { - "x": 1953, - "y": 127, - "w": 34, - "h": 15 + "x": 1704, + "y": 894, + "w": 48, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 14, - "y": 47, - "w": 34, - "h": 15 + "x": 0, + "y": 0, + "w": 48, + "h": 62 }, "sourceSize": { "w": 48, @@ -13502,8 +13502,8 @@ }, "player_244_001.png": { "frame": { - "x": 1414, - "y": 1559, + "x": 1825, + "y": 1921, "w": 60, "h": 60 }, @@ -13522,18 +13522,18 @@ }, "player_244_2_001.png": { "frame": { - "x": 1117, - "y": 1928, - "w": 36, - "h": 28 + "x": 1919, + "y": 2178, + "w": 46, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, - "y": 22, - "w": 36, - "h": 28 + "x": 0, + "y": 0, + "w": 46, + "h": 50 }, "sourceSize": { "w": 46, @@ -13542,17 +13542,17 @@ }, "player_245_001.png": { "frame": { - "x": 752, - "y": 1438, - "w": 61, + "x": 1820, + "y": 246, + "w": 62, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -13562,18 +13562,18 @@ }, "player_245_2_001.png": { "frame": { - "x": 1715, - "y": 1652, + "x": 2123, + "y": 1572, "w": 56, - "h": 49 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, + "y": 0, "w": 56, - "h": 49 + "h": 56 }, "sourceSize": { "w": 56, @@ -13582,8 +13582,8 @@ }, "player_246_001.png": { "frame": { - "x": 1424, - "y": 942, + "x": 1820, + "y": 1298, "w": 60, "h": 62 }, @@ -13602,18 +13602,18 @@ }, "player_246_2_001.png": { "frame": { - "x": 452, - "y": 1800, - "w": 45, - "h": 55 + "x": 2123, + "y": 1629, + "w": 54, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 45, - "h": 55 + "x": 0, + "y": 0, + "w": 54, + "h": 56 }, "sourceSize": { "w": 54, @@ -13622,18 +13622,18 @@ }, "player_246_extra_001.png": { "frame": { - "x": 418, - "y": 355, - "w": 29, - "h": 9 + "x": 2060, + "y": 2226, + "w": 42, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 13, + "x": 0, "y": 0, - "w": 29, - "h": 9 + "w": 42, + "h": 16 }, "sourceSize": { "w": 42, @@ -13642,18 +13642,18 @@ }, "player_247_001.png": { "frame": { - "x": 814, - "y": 1438, + "x": 1820, + "y": 307, "w": 60, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 60, - "h": 61 + "h": 62 }, "sourceSize": { "w": 60, @@ -13662,18 +13662,18 @@ }, "player_247_2_001.png": { "frame": { - "x": 1953, - "y": 0, - "w": 34, - "h": 36 + "x": 2066, + "y": 696, + "w": 58, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 24, + "x": 0, "y": 0, - "w": 34, - "h": 36 + "w": 58, + "h": 54 }, "sourceSize": { "w": 58, @@ -13682,9 +13682,9 @@ }, "player_248_001.png": { "frame": { - "x": 1297, - "y": 988, - "w": 63, + "x": 1215, + "y": 1738, + "w": 64, "h": 60 }, "rotated": false, @@ -13692,7 +13692,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, + "w": 64, "h": 60 }, "sourceSize": { @@ -13702,18 +13702,18 @@ }, "player_248_2_001.png": { "frame": { - "x": 1475, - "y": 1930, - "w": 40, - "h": 33 + "x": 0, + "y": 2198, + "w": 52, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 40, - "h": 33 + "x": 0, + "y": 0, + "w": 52, + "h": 44 }, "sourceSize": { "w": 52, @@ -13722,8 +13722,8 @@ }, "player_25_001.png": { "frame": { - "x": 1475, - "y": 1559, + "x": 1886, + "y": 1946, "w": 60, "h": 60 }, @@ -13742,18 +13742,18 @@ }, "player_25_2_001.png": { "frame": { - "x": 1847, - "y": 455, - "w": 54, - "h": 54 + "x": 2122, + "y": 1686, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 54, - "h": 54 + "x": 0, + "y": 0, + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -13762,8 +13762,8 @@ }, "player_26_001.png": { "frame": { - "x": 976, - "y": 1555, + "x": 1157, + "y": 1944, "w": 60, "h": 60 }, @@ -13782,8 +13782,8 @@ }, "player_26_2_001.png": { "frame": { - "x": 1790, - "y": 1722, + "x": 2122, + "y": 1743, "w": 56, "h": 56 }, @@ -13802,8 +13802,8 @@ }, "player_27_001.png": { "frame": { - "x": 1037, - "y": 1555, + "x": 1218, + "y": 1944, "w": 60, "h": 60 }, @@ -13822,8 +13822,8 @@ }, "player_27_2_001.png": { "frame": { - "x": 1490, - "y": 1836, + "x": 1363, + "y": 2190, "w": 52, "h": 52 }, @@ -13842,8 +13842,8 @@ }, "player_28_001.png": { "frame": { - "x": 1536, - "y": 1552, + "x": 1279, + "y": 1944, "w": 60, "h": 60 }, @@ -13862,8 +13862,8 @@ }, "player_28_2_001.png": { "frame": { - "x": 1789, - "y": 508, + "x": 2122, + "y": 1800, "w": 56, "h": 56 }, @@ -13882,8 +13882,8 @@ }, "player_29_001.png": { "frame": { - "x": 1612, - "y": 0, + "x": 1340, + "y": 1944, "w": 60, "h": 60 }, @@ -13902,8 +13902,8 @@ }, "player_29_2_001.png": { "frame": { - "x": 1789, - "y": 565, + "x": 2122, + "y": 1857, "w": 56, "h": 56 }, @@ -13922,8 +13922,8 @@ }, "player_30_001.png": { "frame": { - "x": 1612, - "y": 61, + "x": 1401, + "y": 1944, "w": 60, "h": 60 }, @@ -13942,8 +13942,8 @@ }, "player_30_2_001.png": { "frame": { - "x": 1904, - "y": 884, + "x": 1015, + "y": 2196, "w": 46, "h": 46 }, @@ -13962,8 +13962,8 @@ }, "player_31_001.png": { "frame": { - "x": 1612, - "y": 122, + "x": 1462, + "y": 1944, "w": 60, "h": 60 }, @@ -13982,8 +13982,8 @@ }, "player_31_2_001.png": { "frame": { - "x": 1950, - "y": 1214, + "x": 1418, + "y": 2278, "w": 32, "h": 32 }, @@ -14002,8 +14002,8 @@ }, "player_32_001.png": { "frame": { - "x": 1612, - "y": 183, + "x": 1523, + "y": 1944, "w": 60, "h": 60 }, @@ -14022,10 +14022,10 @@ }, "player_32_2_001.png": { "frame": { - "x": 1057, - "y": 1677, + "x": 636, + "y": 99, "w": 40, - "h": 44 + "h": 48 }, "rotated": false, "trimmed": true, @@ -14033,7 +14033,7 @@ "x": 0, "y": 0, "w": 40, - "h": 44 + "h": 48 }, "sourceSize": { "w": 40, @@ -14042,8 +14042,8 @@ }, "player_33_001.png": { "frame": { - "x": 1612, - "y": 244, + "x": 1584, + "y": 1944, "w": 60, "h": 60 }, @@ -14062,8 +14062,8 @@ }, "player_33_2_001.png": { "frame": { - "x": 1789, - "y": 622, + "x": 2122, + "y": 1914, "w": 56, "h": 56 }, @@ -14082,8 +14082,8 @@ }, "player_34_001.png": { "frame": { - "x": 1612, - "y": 305, + "x": 0, + "y": 1927, "w": 60, "h": 60 }, @@ -14102,8 +14102,8 @@ }, "player_34_2_001.png": { "frame": { - "x": 1904, - "y": 193, + "x": 2237, + "y": 756, "w": 48, "h": 48 }, @@ -14122,8 +14122,8 @@ }, "player_35_001.png": { "frame": { - "x": 1610, - "y": 366, + "x": 1645, + "y": 1927, "w": 60, "h": 60 }, @@ -14142,8 +14142,8 @@ }, "player_35_2_001.png": { "frame": { - "x": 1789, - "y": 679, + "x": 2122, + "y": 1971, "w": 56, "h": 56 }, @@ -14162,8 +14162,8 @@ }, "player_36_001.png": { "frame": { - "x": 1610, - "y": 427, + "x": 61, + "y": 1927, "w": 60, "h": 60 }, @@ -14182,8 +14182,8 @@ }, "player_36_2_001.png": { "frame": { - "x": 759, - "y": 1328, + "x": 1062, + "y": 2196, "w": 32, "h": 46 }, @@ -14202,8 +14202,8 @@ }, "player_37_001.png": { "frame": { - "x": 1610, - "y": 488, + "x": 122, + "y": 1927, "w": 60, "h": 60 }, @@ -14222,8 +14222,8 @@ }, "player_37_2_001.png": { "frame": { - "x": 1788, - "y": 736, + "x": 2105, + "y": 2028, "w": 56, "h": 38 }, @@ -14242,8 +14242,8 @@ }, "player_38_001.png": { "frame": { - "x": 1610, - "y": 549, + "x": 183, + "y": 1927, "w": 60, "h": 60 }, @@ -14262,18 +14262,18 @@ }, "player_38_2_001.png": { "frame": { - "x": 1137, - "y": 1878, + "x": 2087, + "y": 2171, "w": 50, - "h": 49 + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 50, - "h": 49 + "h": 50 }, "sourceSize": { "w": 50, @@ -14282,8 +14282,8 @@ }, "player_39_001.png": { "frame": { - "x": 1610, - "y": 610, + "x": 244, + "y": 1927, "w": 60, "h": 60 }, @@ -14302,18 +14302,18 @@ }, "player_39_2_001.png": { "frame": { - "x": 650, - "y": 1928, + "x": 243, + "y": 2274, "w": 38, - "h": 31 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, + "y": 0, "w": 38, - "h": 31 + "h": 38 }, "sourceSize": { "w": 38, @@ -14322,8 +14322,8 @@ }, "player_40_001.png": { "frame": { - "x": 1609, - "y": 671, + "x": 305, + "y": 1927, "w": 60, "h": 60 }, @@ -14342,18 +14342,18 @@ }, "player_40_2_001.png": { "frame": { - "x": 1949, - "y": 1374, + "x": 1428, + "y": 2242, "w": 32, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 32, - "h": 26 + "h": 28 }, "sourceSize": { "w": 32, @@ -14362,8 +14362,8 @@ }, "player_41_001.png": { "frame": { - "x": 1609, - "y": 732, + "x": 366, + "y": 1927, "w": 60, "h": 60 }, @@ -14382,8 +14382,8 @@ }, "player_41_2_001.png": { "frame": { - "x": 86, - "y": 1928, + "x": 2233, + "y": 1471, "w": 42, "h": 42 }, @@ -14402,8 +14402,8 @@ }, "player_42_001.png": { "frame": { - "x": 1609, - "y": 793, + "x": 427, + "y": 1927, "w": 60, "h": 60 }, @@ -14422,18 +14422,18 @@ }, "player_42_2_001.png": { "frame": { - "x": 1516, - "y": 1930, + "x": 2221, + "y": 1514, "w": 40, - "h": 40 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 40, - "h": 40 + "h": 42 }, "sourceSize": { "w": 40, @@ -14442,8 +14442,8 @@ }, "player_43_001.png": { "frame": { - "x": 1609, - "y": 854, + "x": 488, + "y": 1927, "w": 60, "h": 60 }, @@ -14462,18 +14462,18 @@ }, "player_43_2_001.png": { "frame": { - "x": 1847, - "y": 1654, - "w": 54, - "h": 54 + "x": 2103, + "y": 2067, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 54, - "h": 54 + "x": 0, + "y": 0, + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -14482,8 +14482,8 @@ }, "player_44_001.png": { "frame": { - "x": 1609, - "y": 915, + "x": 549, + "y": 1927, "w": 60, "h": 60 }, @@ -14502,18 +14502,18 @@ }, "player_44_2_001.png": { "frame": { - "x": 1339, - "y": 1878, - "w": 33, - "h": 10 + "x": 969, + "y": 2243, + "w": 34, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 33, - "h": 10 + "w": 34, + "h": 34 }, "sourceSize": { "w": 34, @@ -14522,8 +14522,8 @@ }, "player_45_001.png": { "frame": { - "x": 1609, - "y": 976, + "x": 610, + "y": 1927, "w": 60, "h": 60 }, @@ -14542,18 +14542,18 @@ }, "player_45_2_001.png": { "frame": { - "x": 1787, - "y": 1099, + "x": 855, + "y": 2119, "w": 56, - "h": 51 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 56, - "h": 51 + "h": 56 }, "sourceSize": { "w": 56, @@ -14562,8 +14562,8 @@ }, "player_46_001.png": { "frame": { - "x": 1609, - "y": 1037, + "x": 671, + "y": 1927, "w": 60, "h": 60 }, @@ -14582,17 +14582,17 @@ }, "player_46_2_001.png": { "frame": { - "x": 1223, - "y": 1736, - "w": 48, + "x": 0, + "y": 2140, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 48, + "w": 56, "h": 56 }, "sourceSize": { @@ -14602,8 +14602,8 @@ }, "player_47_001.png": { "frame": { - "x": 1609, - "y": 1098, + "x": 732, + "y": 1927, "w": 60, "h": 60 }, @@ -14622,8 +14622,8 @@ }, "player_47_2_001.png": { "frame": { - "x": 1951, - "y": 605, + "x": 697, + "y": 2278, "w": 36, "h": 36 }, @@ -14642,8 +14642,8 @@ }, "player_48_001.png": { "frame": { - "x": 1609, - "y": 1159, + "x": 793, + "y": 1927, "w": 60, "h": 60 }, @@ -14662,18 +14662,18 @@ }, "player_48_2_001.png": { "frame": { - "x": 1223, - "y": 1793, - "w": 41, - "h": 24 + "x": 2232, + "y": 1557, + "w": 42, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 41, - "h": 24 + "w": 42, + "h": 34 }, "sourceSize": { "w": 42, @@ -14682,8 +14682,8 @@ }, "player_49_001.png": { "frame": { - "x": 1609, - "y": 1220, + "x": 854, + "y": 1927, "w": 60, "h": 60 }, @@ -14702,18 +14702,18 @@ }, "player_49_2_001.png": { "frame": { - "x": 1101, - "y": 1724, + "x": 57, + "y": 2140, "w": 42, - "h": 17 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 39, + "y": 0, "w": 42, - "h": 17 + "h": 56 }, "sourceSize": { "w": 42, @@ -14722,8 +14722,8 @@ }, "player_50_001.png": { "frame": { - "x": 1609, - "y": 1281, + "x": 915, + "y": 1927, "w": 60, "h": 60 }, @@ -14742,10 +14742,10 @@ }, "player_50_2_001.png": { "frame": { - "x": 1183, - "y": 1952, + "x": 1451, + "y": 2278, "w": 32, - "h": 15 + "h": 22 }, "rotated": false, "trimmed": true, @@ -14753,7 +14753,7 @@ "x": 0, "y": 0, "w": 32, - "h": 15 + "h": 22 }, "sourceSize": { "w": 32, @@ -14762,8 +14762,8 @@ }, "player_51_001.png": { "frame": { - "x": 1424, - "y": 1005, + "x": 1820, + "y": 1361, "w": 62, "h": 60 }, @@ -14782,8 +14782,8 @@ }, "player_51_2_001.png": { "frame": { - "x": 763, - "y": 1684, + "x": 2066, + "y": 751, "w": 58, "h": 48 }, @@ -14802,8 +14802,8 @@ }, "player_52_001.png": { "frame": { - "x": 390, - "y": 1267, + "x": 1280, + "y": 1738, "w": 64, "h": 60 }, @@ -14822,18 +14822,18 @@ }, "player_52_2_001.png": { "frame": { - "x": 1188, - "y": 1878, + "x": 2138, + "y": 2177, "w": 50, - "h": 46 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 50, - "h": 46 + "h": 48 }, "sourceSize": { "w": 50, @@ -14842,8 +14842,8 @@ }, "player_53_001.png": { "frame": { - "x": 1609, - "y": 1342, + "x": 976, + "y": 1927, "w": 60, "h": 60 }, @@ -14862,10 +14862,10 @@ }, "player_53_2_001.png": { "frame": { - "x": 1904, - "y": 1437, + "x": 280, + "y": 2197, "w": 44, - "h": 40 + "h": 42 }, "rotated": false, "trimmed": true, @@ -14873,7 +14873,7 @@ "x": 0, "y": 0, "w": 44, - "h": 40 + "h": 42 }, "sourceSize": { "w": 44, @@ -14882,8 +14882,8 @@ }, "player_54_001.png": { "frame": { - "x": 1600, - "y": 1403, + "x": 1706, + "y": 1925, "w": 60, "h": 60 }, @@ -14902,18 +14902,18 @@ }, "player_54_2_001.png": { "frame": { - "x": 981, - "y": 1855, + "x": 100, + "y": 2140, "w": 52, - "h": 35 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 21, + "y": 0, "w": 52, - "h": 35 + "h": 56 }, "sourceSize": { "w": 52, @@ -14922,8 +14922,8 @@ }, "player_55_001.png": { "frame": { - "x": 1600, - "y": 1464, + "x": 2005, + "y": 0, "w": 60, "h": 60 }, @@ -14942,18 +14942,18 @@ }, "player_55_2_001.png": { "frame": { - "x": 1904, - "y": 1187, - "w": 45, - "h": 45 + "x": 153, + "y": 2140, + "w": 56, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 45, - "h": 45 + "w": 56, + "h": 56 }, "sourceSize": { "w": 56, @@ -14962,8 +14962,8 @@ }, "player_56_001.png": { "frame": { - "x": 1600, - "y": 1525, + "x": 2005, + "y": 61, "w": 60, "h": 60 }, @@ -14982,18 +14982,18 @@ }, "player_56_2_001.png": { "frame": { - "x": 774, - "y": 867, - "w": 39, - "h": 9 + "x": 2236, + "y": 2230, + "w": 40, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 39, - "h": 9 + "w": 40, + "h": 12 }, "sourceSize": { "w": 40, @@ -15002,8 +15002,8 @@ }, "player_57_001.png": { "frame": { - "x": 0, - "y": 1623, + "x": 2005, + "y": 122, "w": 60, "h": 60 }, @@ -15022,18 +15022,18 @@ }, "player_57_2_001.png": { "frame": { - "x": 1904, - "y": 931, + "x": 2228, + "y": 2017, "w": 46, - "h": 30 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 18, + "y": 0, "w": 46, - "h": 30 + "h": 48 }, "sourceSize": { "w": 46, @@ -15042,8 +15042,8 @@ }, "player_58_001.png": { "frame": { - "x": 61, - "y": 1623, + "x": 2005, + "y": 183, "w": 60, "h": 60 }, @@ -15062,18 +15062,18 @@ }, "player_58_2_001.png": { "frame": { - "x": 1904, - "y": 242, + "x": 2237, + "y": 805, "w": 48, - "h": 43 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 48, - "h": 43 + "h": 48 }, "sourceSize": { "w": 48, @@ -15082,8 +15082,8 @@ }, "player_59_001.png": { "frame": { - "x": 122, - "y": 1623, + "x": 2005, + "y": 244, "w": 60, "h": 60 }, @@ -15102,18 +15102,18 @@ }, "player_59_2_001.png": { "frame": { - "x": 53, - "y": 1857, + "x": 2237, + "y": 0, "w": 50, - "h": 30 + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 20, + "y": 0, "w": 50, - "h": 30 + "h": 50 }, "sourceSize": { "w": 50, @@ -15122,8 +15122,8 @@ }, "player_60_001.png": { "frame": { - "x": 183, - "y": 1623, + "x": 2005, + "y": 305, "w": 60, "h": 60 }, @@ -15142,18 +15142,18 @@ }, "player_60_2_001.png": { "frame": { - "x": 1904, - "y": 1478, + "x": 1095, + "y": 2196, "w": 44, - "h": 44 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 44, - "h": 44 + "h": 46 }, "sourceSize": { "w": 44, @@ -15162,8 +15162,8 @@ }, "player_61_001.png": { "frame": { - "x": 244, - "y": 1623, + "x": 2005, + "y": 366, "w": 60, "h": 60 }, @@ -15182,18 +15182,18 @@ }, "player_61_2_001.png": { "frame": { - "x": 1904, - "y": 1719, - "w": 43, - "h": 31 + "x": 325, + "y": 2197, + "w": 44, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, - "w": 43, - "h": 31 + "y": 0, + "w": 44, + "h": 40 }, "sourceSize": { "w": 44, @@ -15202,17 +15202,17 @@ }, "player_62_001.png": { "frame": { - "x": 875, - "y": 1438, - "w": 61, + "x": 1820, + "y": 370, + "w": 62, "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, + "w": 62, "h": 60 }, "sourceSize": { @@ -15222,18 +15222,18 @@ }, "player_62_2_001.png": { "frame": { - "x": 737, - "y": 523, - "w": 43, - "h": 8 + "x": 1794, + "y": 1780, + "w": 44, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 43, - "h": 8 + "w": 44, + "h": 18 }, "sourceSize": { "w": 44, @@ -15242,8 +15242,8 @@ }, "player_63_001.png": { "frame": { - "x": 305, - "y": 1623, + "x": 2005, + "y": 427, "w": 60, "h": 60 }, @@ -15262,8 +15262,8 @@ }, "player_63_2_001.png": { "frame": { - "x": 1525, - "y": 1889, + "x": 2232, + "y": 1937, "w": 40, "h": 36 }, @@ -15282,8 +15282,8 @@ }, "player_64_001.png": { "frame": { - "x": 366, - "y": 1623, + "x": 2005, + "y": 488, "w": 60, "h": 60 }, @@ -15302,8 +15302,8 @@ }, "player_64_2_001.png": { "frame": { - "x": 1557, - "y": 1930, + "x": 2232, + "y": 1974, "w": 40, "h": 40 }, @@ -15322,8 +15322,8 @@ }, "player_65_001.png": { "frame": { - "x": 427, - "y": 1623, + "x": 2005, + "y": 549, "w": 60, "h": 60 }, @@ -15342,18 +15342,18 @@ }, "player_65_2_001.png": { "frame": { - "x": 1787, - "y": 775, + "x": 210, + "y": 2140, "w": 56, - "h": 43 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, + "y": 0, "w": 56, - "h": 43 + "h": 56 }, "sourceSize": { "w": 56, @@ -15362,8 +15362,8 @@ }, "player_66_001.png": { "frame": { - "x": 488, - "y": 1623, + "x": 2005, + "y": 610, "w": 60, "h": 60 }, @@ -15382,18 +15382,18 @@ }, "player_66_2_001.png": { "frame": { - "x": 938, - "y": 1730, - "w": 11, - "h": 11 + "x": 0, + "y": 2243, + "w": 40, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 11, - "h": 11 + "w": 40, + "h": 30 }, "sourceSize": { "w": 40, @@ -15402,8 +15402,8 @@ }, "player_67_001.png": { "frame": { - "x": 549, - "y": 1623, + "x": 2005, + "y": 671, "w": 60, "h": 60 }, @@ -15422,8 +15422,8 @@ }, "player_67_2_001.png": { "frame": { - "x": 1598, - "y": 1930, + "x": 1736, + "y": 2239, "w": 40, "h": 34 }, @@ -15442,8 +15442,8 @@ }, "player_68_001.png": { "frame": { - "x": 875, - "y": 344, + "x": 1224, + "y": 1083, "w": 72, "h": 60 }, @@ -15462,18 +15462,18 @@ }, "player_68_2_001.png": { "frame": { - "x": 1065, - "y": 934, + "x": 1563, + "y": 802, "w": 68, - "h": 42 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 14, + "y": 0, "w": 68, - "h": 42 + "h": 56 }, "sourceSize": { "w": 68, @@ -15482,8 +15482,8 @@ }, "player_69_001.png": { "frame": { - "x": 610, - "y": 1623, + "x": 2005, + "y": 732, "w": 60, "h": 60 }, @@ -15502,18 +15502,18 @@ }, "player_69_2_001.png": { "frame": { - "x": 1787, - "y": 1151, + "x": 267, + "y": 2140, "w": 56, - "h": 49 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, + "y": 0, "w": 56, - "h": 49 + "h": 56 }, "sourceSize": { "w": 56, @@ -15522,8 +15522,8 @@ }, "player_70_001.png": { "frame": { - "x": 671, - "y": 1623, + "x": 2005, + "y": 793, "w": 60, "h": 60 }, @@ -15542,18 +15542,18 @@ }, "player_70_2_001.png": { "frame": { - "x": 1904, - "y": 1523, + "x": 1140, + "y": 2196, "w": 44, - "h": 44 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 44, - "h": 44 + "h": 46 }, "sourceSize": { "w": 44, @@ -15562,8 +15562,8 @@ }, "player_71_001.png": { "frame": { - "x": 732, - "y": 1623, + "x": 2005, + "y": 854, "w": 60, "h": 60 }, @@ -15582,8 +15582,8 @@ }, "player_71_2_001.png": { "frame": { - "x": 1787, - "y": 819, + "x": 324, + "y": 2140, "w": 56, "h": 56 }, @@ -15602,8 +15602,8 @@ }, "player_72_001.png": { "frame": { - "x": 793, - "y": 1623, + "x": 2005, + "y": 915, "w": 60, "h": 60 }, @@ -15622,8 +15622,8 @@ }, "player_72_2_001.png": { "frame": { - "x": 1951, - "y": 642, + "x": 656, + "y": 2240, "w": 36, "h": 34 }, @@ -15642,8 +15642,8 @@ }, "player_73_001.png": { "frame": { - "x": 854, - "y": 1622, + "x": 2005, + "y": 976, "w": 60, "h": 60 }, @@ -15662,10 +15662,10 @@ }, "player_73_2_001.png": { "frame": { - "x": 1904, - "y": 605, + "x": 2237, + "y": 854, "w": 46, - "h": 47 + "h": 48 }, "rotated": false, "trimmed": true, @@ -15673,7 +15673,7 @@ "x": 0, "y": 0, "w": 46, - "h": 47 + "h": 48 }, "sourceSize": { "w": 46, @@ -15682,8 +15682,8 @@ }, "player_74_001.png": { "frame": { - "x": 995, - "y": 1267, + "x": 1345, + "y": 1738, "w": 64, "h": 60 }, @@ -15702,10 +15702,10 @@ }, "player_74_2_001.png": { "frame": { - "x": 1168, - "y": 1599, + "x": 2005, + "y": 1037, "w": 60, - "h": 46 + "h": 48 }, "rotated": false, "trimmed": true, @@ -15713,7 +15713,7 @@ "x": 0, "y": 0, "w": 60, - "h": 46 + "h": 48 }, "sourceSize": { "w": 60, @@ -15722,8 +15722,8 @@ }, "player_75_001.png": { "frame": { - "x": 915, - "y": 1622, + "x": 2005, + "y": 1086, "w": 60, "h": 60 }, @@ -15742,18 +15742,18 @@ }, "player_75_2_001.png": { "frame": { - "x": 1890, - "y": 1764, - "w": 13, - "h": 13 + "x": 1083, + "y": 2064, + "w": 14, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 13, - "h": 13 + "w": 14, + "h": 44 }, "sourceSize": { "w": 14, @@ -15762,8 +15762,8 @@ }, "player_76_001.png": { "frame": { - "x": 1229, - "y": 1622, + "x": 2005, + "y": 1147, "w": 60, "h": 60 }, @@ -15782,8 +15782,8 @@ }, "player_76_2_001.png": { "frame": { - "x": 1639, - "y": 1930, + "x": 750, + "y": 2232, "w": 40, "h": 40 }, @@ -15802,8 +15802,8 @@ }, "player_77_001.png": { "frame": { - "x": 1290, - "y": 1622, + "x": 2005, + "y": 1208, "w": 60, "h": 60 }, @@ -15822,18 +15822,18 @@ }, "player_77_2_001.png": { "frame": { - "x": 1239, - "y": 1878, + "x": 2237, + "y": 51, "w": 50, - "h": 49 + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 50, - "h": 49 + "h": 50 }, "sourceSize": { "w": 50, @@ -15842,8 +15842,8 @@ }, "player_78_001.png": { "frame": { - "x": 1351, - "y": 1622, + "x": 2005, + "y": 1269, "w": 60, "h": 60 }, @@ -15862,18 +15862,18 @@ }, "player_78_2_001.png": { "frame": { - "x": 1787, - "y": 1201, + "x": 381, + "y": 2140, "w": 56, - "h": 42 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 14, + "y": 0, "w": 56, - "h": 42 + "h": 56 }, "sourceSize": { "w": 56, @@ -15882,8 +15882,8 @@ }, "player_79_001.png": { "frame": { - "x": 1412, - "y": 1622, + "x": 2005, + "y": 1330, "w": 60, "h": 60 }, @@ -15902,8 +15902,8 @@ }, "player_79_2_001.png": { "frame": { - "x": 857, - "y": 1928, + "x": 282, + "y": 2274, "w": 38, "h": 38 }, @@ -15922,8 +15922,8 @@ }, "player_80_001.png": { "frame": { - "x": 455, - "y": 1267, + "x": 1410, + "y": 1738, "w": 64, "h": 60 }, @@ -15942,10 +15942,10 @@ }, "player_80_2_001.png": { "frame": { - "x": 1098, - "y": 1614, + "x": 2005, + "y": 1391, "w": 60, - "h": 52 + "h": 56 }, "rotated": false, "trimmed": true, @@ -15953,7 +15953,7 @@ "x": 0, "y": 0, "w": 60, - "h": 52 + "h": 56 }, "sourceSize": { "w": 60, @@ -15962,8 +15962,8 @@ }, "player_81_001.png": { "frame": { - "x": 1473, - "y": 1620, + "x": 2005, + "y": 1448, "w": 60, "h": 60 }, @@ -15982,10 +15982,10 @@ }, "player_81_2_001.png": { "frame": { - "x": 1178, - "y": 1968, + "x": 1142, + "y": 1044, "w": 26, - "h": 25 + "h": 38 }, "rotated": false, "trimmed": true, @@ -15993,7 +15993,7 @@ "x": 0, "y": 0, "w": 26, - "h": 25 + "h": 38 }, "sourceSize": { "w": 26, @@ -16002,8 +16002,8 @@ }, "player_82_001.png": { "frame": { - "x": 1534, - "y": 1620, + "x": 2005, + "y": 1509, "w": 60, "h": 60 }, @@ -16022,8 +16022,8 @@ }, "player_82_2_001.png": { "frame": { - "x": 1066, - "y": 852, + "x": 1812, + "y": 1964, "w": 12, "h": 12 }, @@ -16042,8 +16042,8 @@ }, "player_83_001.png": { "frame": { - "x": 976, - "y": 1616, + "x": 2005, + "y": 1570, "w": 60, "h": 60 }, @@ -16062,8 +16062,8 @@ }, "player_83_2_001.png": { "frame": { - "x": 1904, - "y": 962, + "x": 1185, + "y": 2196, "w": 46, "h": 46 }, @@ -16082,8 +16082,8 @@ }, "player_84_001.png": { "frame": { - "x": 1037, - "y": 1616, + "x": 1993, + "y": 1631, "w": 60, "h": 60 }, @@ -16102,8 +16102,8 @@ }, "player_84_2_001.png": { "frame": { - "x": 1282, - "y": 1483, + "x": 2052, + "y": 1906, "w": 12, "h": 12 }, @@ -16122,8 +16122,8 @@ }, "player_85_001.png": { "frame": { - "x": 1595, - "y": 1613, + "x": 1993, + "y": 1692, "w": 60, "h": 60 }, @@ -16142,8 +16142,8 @@ }, "player_85_2_001.png": { "frame": { - "x": 1787, - "y": 876, + "x": 438, + "y": 2140, "w": 56, "h": 56 }, @@ -16162,8 +16162,8 @@ }, "player_86_001.png": { "frame": { - "x": 1673, - "y": 0, + "x": 1993, + "y": 1753, "w": 60, "h": 60 }, @@ -16182,18 +16182,18 @@ }, "player_86_2_001.png": { "frame": { - "x": 1509, - "y": 1727, + "x": 1408, + "y": 802, "w": 54, - "h": 13 + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 54, - "h": 13 + "h": 14 }, "sourceSize": { "w": 54, @@ -16202,8 +16202,8 @@ }, "player_87_001.png": { "frame": { - "x": 1673, - "y": 61, + "x": 1993, + "y": 1814, "w": 60, "h": 60 }, @@ -16222,8 +16222,8 @@ }, "player_87_2_001.png": { "frame": { - "x": 1787, - "y": 1244, + "x": 495, + "y": 2140, "w": 56, "h": 56 }, @@ -16242,8 +16242,8 @@ }, "player_88_001.png": { "frame": { - "x": 1673, - "y": 122, + "x": 1991, + "y": 1875, "w": 60, "h": 60 }, @@ -16262,8 +16262,8 @@ }, "player_88_2_001.png": { "frame": { - "x": 1787, - "y": 933, + "x": 552, + "y": 2140, "w": 56, "h": 56 }, @@ -16282,8 +16282,8 @@ }, "player_89_001.png": { "frame": { - "x": 1673, - "y": 183, + "x": 1947, + "y": 1936, "w": 60, "h": 60 }, @@ -16302,8 +16302,8 @@ }, "player_89_2_001.png": { "frame": { - "x": 1847, - "y": 1709, + "x": 2182, + "y": 817, "w": 54, "h": 54 }, @@ -16322,10 +16322,10 @@ }, "player_90_001.png": { "frame": { - "x": 1424, - "y": 1066, + "x": 1475, + "y": 1735, "w": 60, - "h": 62 + "h": 64 }, "rotated": false, "trimmed": true, @@ -16333,7 +16333,7 @@ "x": 0, "y": 0, "w": 60, - "h": 62 + "h": 64 }, "sourceSize": { "w": 60, @@ -16342,10 +16342,10 @@ }, "player_90_2_001.png": { "frame": { - "x": 1847, - "y": 1764, + "x": 208, + "y": 202, "w": 42, - "h": 54 + "h": 60 }, "rotated": false, "trimmed": true, @@ -16353,7 +16353,7 @@ "x": 0, "y": 0, "w": 42, - "h": 54 + "h": 60 }, "sourceSize": { "w": 42, @@ -16362,8 +16362,8 @@ }, "player_91_001.png": { "frame": { - "x": 1673, - "y": 244, + "x": 0, + "y": 2007, "w": 60, "h": 60 }, @@ -16382,10 +16382,10 @@ }, "player_91_2_001.png": { "frame": { - "x": 160, - "y": 662, + "x": 2235, + "y": 1293, "w": 44, - "h": 8 + "h": 36 }, "rotated": false, "trimmed": true, @@ -16393,7 +16393,7 @@ "x": 0, "y": 0, "w": 44, - "h": 8 + "h": 36 }, "sourceSize": { "w": 44, @@ -16402,10 +16402,10 @@ }, "player_92_001.png": { "frame": { - "x": 77, - "y": 756, + "x": 150, + "y": 1192, "w": 76, - "h": 68 + "h": 76 }, "rotated": false, "trimmed": true, @@ -16413,7 +16413,7 @@ "x": 0, "y": 0, "w": 76, - "h": 68 + "h": 76 }, "sourceSize": { "w": 76, @@ -16422,10 +16422,10 @@ }, "player_92_2_001.png": { "frame": { - "x": 875, - "y": 405, + "x": 0, + "y": 1344, "w": 72, - "h": 59 + "h": 72 }, "rotated": false, "trimmed": true, @@ -16433,7 +16433,7 @@ "x": 0, "y": 0, "w": 72, - "h": 59 + "h": 72 }, "sourceSize": { "w": 72, @@ -16442,8 +16442,8 @@ }, "player_93_001.png": { "frame": { - "x": 865, - "y": 655, + "x": 363, + "y": 1337, "w": 72, "h": 60 }, @@ -16462,10 +16462,10 @@ }, "player_93_2_001.png": { "frame": { - "x": 69, - "y": 1196, + "x": 1635, + "y": 1187, "w": 66, - "h": 49 + "h": 54 }, "rotated": false, "trimmed": true, @@ -16473,7 +16473,7 @@ "x": 0, "y": 0, "w": 66, - "h": 49 + "h": 54 }, "sourceSize": { "w": 66, @@ -16482,8 +16482,8 @@ }, "player_94_001.png": { "frame": { - "x": 864, - "y": 716, + "x": 73, + "y": 1344, "w": 72, "h": 60 }, @@ -16502,10 +16502,10 @@ }, "player_94_2_001.png": { "frame": { - "x": 298, - "y": 905, + "x": 1635, + "y": 1242, "w": 66, - "h": 15 + "h": 32 }, "rotated": false, "trimmed": true, @@ -16513,7 +16513,7 @@ "x": 0, "y": 0, "w": 66, - "h": 15 + "h": 32 }, "sourceSize": { "w": 66, @@ -16522,8 +16522,8 @@ }, "player_95_001.png": { "frame": { - "x": 1673, - "y": 305, + "x": 61, + "y": 2007, "w": 60, "h": 60 }, @@ -16542,8 +16542,8 @@ }, "player_95_2_001.png": { "frame": { - "x": 765, - "y": 1927, + "x": 141, + "y": 2242, "w": 38, "h": 30 }, @@ -16562,8 +16562,8 @@ }, "player_96_001.png": { "frame": { - "x": 1671, - "y": 366, + "x": 122, + "y": 2007, "w": 60, "h": 60 }, @@ -16582,17 +16582,17 @@ }, "player_96_2_001.png": { "frame": { - "x": 1787, - "y": 1301, - "w": 46, + "x": 609, + "y": 2140, + "w": 56, "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 46, + "w": 56, "h": 56 }, "sourceSize": { @@ -16602,18 +16602,18 @@ }, "player_97_001.png": { "frame": { - "x": 892, - "y": 868, + "x": 1424, + "y": 234, "w": 70, - "h": 65 + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 70, - "h": 65 + "h": 70 }, "sourceSize": { "w": 70, @@ -16622,18 +16622,18 @@ }, "player_97_2_001.png": { "frame": { - "x": 1065, - "y": 977, + "x": 1562, + "y": 859, "w": 68, - "h": 44 + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 24, + "y": 0, "w": 68, - "h": 44 + "h": 68 }, "sourceSize": { "w": 68, @@ -16642,18 +16642,18 @@ }, "player_97_extra_001.png": { "frame": { - "x": 104, - "y": 1882, - "w": 49, - "h": 42 + "x": 1769, + "y": 187, + "w": 50, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 12, - "w": 49, - "h": 42 + "x": 0, + "y": 0, + "w": 50, + "h": 54 }, "sourceSize": { "w": 50, @@ -16662,8 +16662,8 @@ }, "player_98_001.png": { "frame": { - "x": 1671, - "y": 427, + "x": 183, + "y": 2007, "w": 60, "h": 60 }, @@ -16682,18 +16682,18 @@ }, "player_98_2_001.png": { "frame": { - "x": 1362, - "y": 1930, - "w": 41, - "h": 37 + "x": 666, + "y": 2140, + "w": 44, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 19, - "w": 41, - "h": 37 + "x": 0, + "y": 0, + "w": 44, + "h": 56 }, "sourceSize": { "w": 44, @@ -16702,18 +16702,18 @@ }, "player_98_extra_001.png": { "frame": { - "x": 1680, - "y": 1930, - "w": 40, - "h": 35 + "x": 2178, + "y": 1629, + "w": 42, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 19, - "w": 40, - "h": 35 + "x": 0, + "y": 0, + "w": 42, + "h": 54 }, "sourceSize": { "w": 42, @@ -16722,18 +16722,18 @@ }, "player_99_001.png": { "frame": { - "x": 0, - "y": 1140, + "x": 761, + "y": 1548, "w": 68, - "h": 61 + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 68, - "h": 61 + "h": 62 }, "sourceSize": { "w": 68, @@ -16742,18 +16742,18 @@ }, "player_99_2_001.png": { "frame": { - "x": 340, - "y": 1854, + "x": 711, + "y": 2140, "w": 52, - "h": 36 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 20, + "y": 0, "w": 52, - "h": 36 + "h": 56 }, "sourceSize": { "w": 52, @@ -16762,18 +16762,18 @@ }, "player_99_extra_001.png": { "frame": { - "x": 816, - "y": 1884, + "x": 1769, + "y": 130, "w": 50, - "h": 39 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 17, + "y": 0, "w": 50, - "h": 39 + "h": 56 }, "sourceSize": { "w": 50, @@ -16782,8 +16782,8 @@ }, "player_ball_00_001.png": { "frame": { - "x": 0, - "y": 998, + "x": 1423, + "y": 305, "w": 70, "h": 70 }, @@ -16802,8 +16802,8 @@ }, "player_ball_00_2_001.png": { "frame": { - "x": 1982, - "y": 1374, + "x": 2252, + "y": 2243, "w": 30, "h": 30 }, @@ -16822,8 +16822,8 @@ }, "player_ball_01_001.png": { "frame": { - "x": 71, - "y": 998, + "x": 1423, + "y": 376, "w": 70, "h": 70 }, @@ -16842,8 +16842,8 @@ }, "player_ball_01_2_001.png": { "frame": { - "x": 1951, - "y": 677, + "x": 734, + "y": 2278, "w": 36, "h": 36 }, @@ -16862,8 +16862,8 @@ }, "player_ball_02_001.png": { "frame": { - "x": 142, - "y": 998, + "x": 1422, + "y": 447, "w": 70, "h": 70 }, @@ -16882,18 +16882,18 @@ }, "player_ball_02_2_001.png": { "frame": { - "x": 371, - "y": 1435, - "w": 61, - "h": 44 + "x": 1635, + "y": 1275, + "w": 66, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 22, - "w": 61, - "h": 44 + "y": 0, + "w": 66, + "h": 66 }, "sourceSize": { "w": 66, @@ -16902,8 +16902,8 @@ }, "player_ball_03_001.png": { "frame": { - "x": 213, - "y": 998, + "x": 1422, + "y": 518, "w": 70, "h": 70 }, @@ -16922,8 +16922,8 @@ }, "player_ball_03_2_001.png": { "frame": { - "x": 1786, - "y": 1358, + "x": 764, + "y": 2140, "w": 56, "h": 56 }, @@ -16942,8 +16942,8 @@ }, "player_ball_04_001.png": { "frame": { - "x": 284, - "y": 998, + "x": 1422, + "y": 589, "w": 70, "h": 70 }, @@ -16962,8 +16962,8 @@ }, "player_ball_04_2_001.png": { "frame": { - "x": 0, - "y": 1800, + "x": 912, + "y": 2139, "w": 56, "h": 56 }, @@ -16982,8 +16982,8 @@ }, "player_ball_05_001.png": { "frame": { - "x": 355, - "y": 998, + "x": 1421, + "y": 660, "w": 70, "h": 70 }, @@ -17002,8 +17002,8 @@ }, "player_ball_05_2_001.png": { "frame": { - "x": 1904, - "y": 1568, + "x": 370, + "y": 2197, "w": 44, "h": 44 }, @@ -17022,8 +17022,8 @@ }, "player_ball_06_001.png": { "frame": { - "x": 426, - "y": 998, + "x": 1421, + "y": 731, "w": 70, "h": 70 }, @@ -17042,8 +17042,8 @@ }, "player_ball_06_2_001.png": { "frame": { - "x": 136, - "y": 1199, + "x": 1634, + "y": 380, "w": 66, "h": 66 }, @@ -17062,8 +17062,8 @@ }, "player_ball_07_001.png": { "frame": { - "x": 497, - "y": 998, + "x": 1355, + "y": 1205, "w": 70, "h": 70 }, @@ -17082,8 +17082,8 @@ }, "player_ball_07_2_001.png": { "frame": { - "x": 1904, - "y": 286, + "x": 2237, + "y": 903, "w": 48, "h": 48 }, @@ -17102,8 +17102,8 @@ }, "player_ball_08_001.png": { "frame": { - "x": 568, - "y": 998, + "x": 1393, + "y": 1020, "w": 70, "h": 70 }, @@ -17122,18 +17122,18 @@ }, "player_ball_08_2_001.png": { "frame": { - "x": 1297, - "y": 1049, - "w": 63, - "h": 61 + "x": 1633, + "y": 447, + "w": 66, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 61 + "w": 66, + "h": 66 }, "sourceSize": { "w": 66, @@ -17142,8 +17142,8 @@ }, "player_ball_09_001.png": { "frame": { - "x": 639, - "y": 998, + "x": 1385, + "y": 1276, "w": 70, "h": 70 }, @@ -17162,10 +17162,10 @@ }, "player_ball_09_2_001.png": { "frame": { - "x": 1201, - "y": 1059, + "x": 1456, + "y": 1276, "w": 28, - "h": 47 + "h": 66 }, "rotated": false, "trimmed": true, @@ -17173,7 +17173,7 @@ "x": 0, "y": 0, "w": 28, - "h": 47 + "h": 66 }, "sourceSize": { "w": 28, @@ -17182,8 +17182,8 @@ }, "player_ball_10_001.png": { "frame": { - "x": 710, - "y": 998, + "x": 1385, + "y": 1347, "w": 70, "h": 70 }, @@ -17202,8 +17202,8 @@ }, "player_ball_10_2_001.png": { "frame": { - "x": 1752, - "y": 1872, + "x": 2237, + "y": 102, "w": 50, "h": 50 }, @@ -17222,8 +17222,8 @@ }, "player_ball_11_001.png": { "frame": { - "x": 781, - "y": 998, + "x": 1370, + "y": 1091, "w": 70, "h": 70 }, @@ -17242,18 +17242,18 @@ }, "player_ball_11_2_001.png": { "frame": { - "x": 937, - "y": 1435, - "w": 47, - "h": 61 + "x": 1633, + "y": 514, + "w": 66, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 19, - "y": 5, - "w": 47, - "h": 61 + "x": 0, + "y": 0, + "w": 66, + "h": 66 }, "sourceSize": { "w": 66, @@ -17262,8 +17262,8 @@ }, "player_ball_12_001.png": { "frame": { - "x": 852, - "y": 998, + "x": 0, + "y": 1477, "w": 70, "h": 70 }, @@ -17282,8 +17282,8 @@ }, "player_ball_12_2_001.png": { "frame": { - "x": 203, - "y": 1199, + "x": 1633, + "y": 581, "w": 66, "h": 66 }, @@ -17302,8 +17302,8 @@ }, "player_ball_13_001.png": { "frame": { - "x": 923, - "y": 934, + "x": 71, + "y": 1477, "w": 70, "h": 70 }, @@ -17322,8 +17322,8 @@ }, "player_ball_13_2_001.png": { "frame": { - "x": 1125, - "y": 1198, + "x": 1441, + "y": 1091, "w": 48, "h": 66 }, @@ -17342,8 +17342,8 @@ }, "player_ball_14_001.png": { "frame": { - "x": 1023, - "y": 0, + "x": 142, + "y": 1477, "w": 70, "h": 70 }, @@ -17362,8 +17362,8 @@ }, "player_ball_14_2_001.png": { "frame": { - "x": 1174, - "y": 1198, + "x": 1633, + "y": 648, "w": 56, "h": 66 }, @@ -17382,8 +17382,8 @@ }, "player_ball_15_001.png": { "frame": { - "x": 1023, - "y": 71, + "x": 213, + "y": 1477, "w": 70, "h": 70 }, @@ -17402,8 +17402,8 @@ }, "player_ball_15_2_001.png": { "frame": { - "x": 57, - "y": 1800, + "x": 969, + "y": 2139, "w": 56, "h": 56 }, @@ -17422,9 +17422,9 @@ }, "player_ball_16_001.png": { "frame": { - "x": 1021, - "y": 142, - "w": 66, + "x": 284, + "y": 1477, + "w": 70, "h": 70 }, "rotated": false, @@ -17432,7 +17432,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, + "w": 70, "h": 70 }, "sourceSize": { @@ -17442,18 +17442,18 @@ }, "player_ball_16_2_001.png": { "frame": { - "x": 761, - "y": 1772, + "x": 1026, + "y": 2139, "w": 56, - "h": 52 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 56, - "h": 52 + "h": 56 }, "sourceSize": { "w": 56, @@ -17462,9 +17462,9 @@ }, "player_ball_17_001.png": { "frame": { - "x": 1019, - "y": 213, - "w": 66, + "x": 355, + "y": 1477, + "w": 70, "h": 70 }, "rotated": false, @@ -17472,7 +17472,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, + "w": 70, "h": 70 }, "sourceSize": { @@ -17482,18 +17482,18 @@ }, "player_ball_17_2_001.png": { "frame": { - "x": 358, - "y": 1928, - "w": 36, - "h": 37 + "x": 2235, + "y": 1114, + "w": 46, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 36, - "h": 37 + "w": 46, + "h": 38 }, "sourceSize": { "w": 46, @@ -17502,8 +17502,8 @@ }, "player_ball_18_001.png": { "frame": { - "x": 1019, - "y": 284, + "x": 426, + "y": 1477, "w": 70, "h": 70 }, @@ -17522,8 +17522,8 @@ }, "player_ball_18_2_001.png": { "frame": { - "x": 1060, - "y": 1267, + "x": 1536, + "y": 1735, "w": 64, "h": 64 }, @@ -17542,8 +17542,8 @@ }, "player_ball_19_001.png": { "frame": { - "x": 1019, - "y": 355, + "x": 497, + "y": 1477, "w": 70, "h": 70 }, @@ -17562,18 +17562,18 @@ }, "player_ball_19_2_001.png": { "frame": { - "x": 270, - "y": 1201, + "x": 1632, + "y": 715, "w": 66, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 66, - "h": 65 + "h": 66 }, "sourceSize": { "w": 66, @@ -17582,8 +17582,8 @@ }, "player_ball_20_001.png": { "frame": { - "x": 1019, - "y": 426, + "x": 568, + "y": 1477, "w": 70, "h": 70 }, @@ -17602,18 +17602,18 @@ }, "player_ball_20_2_001.png": { "frame": { - "x": 337, - "y": 1201, + "x": 1632, + "y": 782, "w": 66, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 66, - "h": 65 + "h": 66 }, "sourceSize": { "w": 66, @@ -17622,8 +17622,8 @@ }, "player_ball_21_001.png": { "frame": { - "x": 1009, - "y": 497, + "x": 639, + "y": 1477, "w": 70, "h": 70 }, @@ -17642,18 +17642,18 @@ }, "player_ball_21_2_001.png": { "frame": { - "x": 963, - "y": 868, + "x": 881, + "y": 424, "w": 18, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 18, - "h": 65 + "h": 66 }, "sourceSize": { "w": 18, @@ -17662,8 +17662,8 @@ }, "player_ball_22_001.png": { "frame": { - "x": 1009, - "y": 568, + "x": 710, + "y": 1477, "w": 70, "h": 70 }, @@ -17682,18 +17682,18 @@ }, "player_ball_22_2_001.png": { "frame": { - "x": 404, - "y": 1201, + "x": 1631, + "y": 1342, "w": 66, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 66, - "h": 65 + "h": 66 }, "sourceSize": { "w": 66, @@ -17702,8 +17702,8 @@ }, "player_ball_22_extra_001.png": { "frame": { - "x": 281, - "y": 1928, + "x": 321, + "y": 2274, "w": 38, "h": 38 }, @@ -17722,8 +17722,8 @@ }, "player_ball_23_001.png": { "frame": { - "x": 1009, - "y": 639, + "x": 781, + "y": 1477, "w": 70, "h": 70 }, @@ -17742,18 +17742,18 @@ }, "player_ball_23_2_001.png": { "frame": { - "x": 1290, - "y": 1926, - "w": 42, - "h": 31 + "x": 2235, + "y": 1330, + "w": 44, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 42, - "h": 31 + "w": 44, + "h": 32 }, "sourceSize": { "w": 44, @@ -17762,18 +17762,18 @@ }, "player_ball_23_extra_001.png": { "frame": { - "x": 1446, - "y": 1780, - "w": 55, - "h": 46 + "x": 1601, + "y": 1735, + "w": 62, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 55, - "h": 46 + "w": 62, + "h": 64 }, "sourceSize": { "w": 62, @@ -17782,8 +17782,8 @@ }, "player_ball_24_001.png": { "frame": { - "x": 1009, - "y": 710, + "x": 852, + "y": 1477, "w": 70, "h": 70 }, @@ -17802,18 +17802,18 @@ }, "player_ball_24_2_001.png": { "frame": { - "x": 471, - "y": 1201, + "x": 1631, + "y": 1409, "w": 66, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 66, - "h": 65 + "h": 66 }, "sourceSize": { "w": 66, @@ -17822,9 +17822,9 @@ }, "player_ball_24_extra_001.png": { "frame": { - "x": 1904, - "y": 1233, - "w": 45, + "x": 2235, + "y": 1153, + "w": 46, "h": 32 }, "rotated": false, @@ -17832,7 +17832,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 45, + "w": 46, "h": 32 }, "sourceSize": { @@ -17842,8 +17842,8 @@ }, "player_ball_25_001.png": { "frame": { - "x": 1008, - "y": 781, + "x": 923, + "y": 1477, "w": 70, "h": 70 }, @@ -17862,18 +17862,18 @@ }, "player_ball_25_2_001.png": { "frame": { - "x": 538, - "y": 1201, + "x": 1631, + "y": 1476, "w": 66, - "h": 65 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 66, - "h": 65 + "h": 66 }, "sourceSize": { "w": 66, @@ -17882,8 +17882,8 @@ }, "player_ball_25_extra_001.png": { "frame": { - "x": 1904, - "y": 1613, + "x": 415, + "y": 2197, "w": 44, "h": 44 }, @@ -17902,8 +17902,8 @@ }, "player_ball_26_001.png": { "frame": { - "x": 995, - "y": 852, + "x": 994, + "y": 1477, "w": 70, "h": 70 }, @@ -17922,18 +17922,18 @@ }, "player_ball_26_2_001.png": { "frame": { - "x": 433, - "y": 1435, - "w": 61, - "h": 61 + "x": 1546, + "y": 1646, + "w": 66, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 61, - "h": 61 + "y": 0, + "w": 66, + "h": 66 }, "sourceSize": { "w": 66, @@ -17942,8 +17942,8 @@ }, "player_ball_27_001.png": { "frame": { - "x": 994, - "y": 923, + "x": 1065, + "y": 1477, "w": 70, "h": 70 }, @@ -17962,18 +17962,18 @@ }, "player_ball_27_2_001.png": { "frame": { - "x": 129, - "y": 1928, - "w": 35, - "h": 42 + "x": 640, + "y": 31, + "w": 36, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 35, - "h": 42 + "w": 36, + "h": 46 }, "sourceSize": { "w": 36, @@ -17982,8 +17982,8 @@ }, "player_ball_28_001.png": { "frame": { - "x": 994, - "y": 994, + "x": 1136, + "y": 1477, "w": 70, "h": 70 }, @@ -18002,10 +18002,10 @@ }, "player_ball_28_2_001.png": { "frame": { - "x": 605, - "y": 1202, + "x": 1035, + "y": 1609, "w": 66, - "h": 48 + "h": 56 }, "rotated": false, "trimmed": true, @@ -18013,7 +18013,7 @@ "x": 0, "y": 0, "w": 66, - "h": 48 + "h": 56 }, "sourceSize": { "w": 66, @@ -18022,18 +18022,18 @@ }, "player_ball_28_extra_001.png": { "frame": { - "x": 1138, - "y": 1995, - "w": 23, - "h": 24 + "x": 772, + "y": 41, + "w": 24, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 12, - "w": 23, - "h": 24 + "x": 0, + "y": 0, + "w": 24, + "h": 36 }, "sourceSize": { "w": 24, @@ -18042,8 +18042,8 @@ }, "player_ball_29_001.png": { "frame": { - "x": 923, - "y": 1005, + "x": 1207, + "y": 1477, "w": 70, "h": 70 }, @@ -18062,8 +18062,8 @@ }, "player_ball_29_2_001.png": { "frame": { - "x": 672, - "y": 1195, + "x": 0, + "y": 1671, "w": 66, "h": 66 }, @@ -18082,8 +18082,8 @@ }, "player_ball_30_001.png": { "frame": { - "x": 0, - "y": 1069, + "x": 1278, + "y": 1477, "w": 70, "h": 70 }, @@ -18102,8 +18102,8 @@ }, "player_ball_30_2_001.png": { "frame": { - "x": 1803, - "y": 1872, + "x": 2237, + "y": 153, "w": 50, "h": 50 }, @@ -18122,18 +18122,18 @@ }, "player_ball_31_001.png": { "frame": { - "x": 1064, - "y": 1065, - "w": 69, - "h": 69 + "x": 1349, + "y": 1475, + "w": 70, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 69, - "h": 69 + "x": 0, + "y": 0, + "w": 70, + "h": 70 }, "sourceSize": { "w": 70, @@ -18142,8 +18142,8 @@ }, "player_ball_31_2_001.png": { "frame": { - "x": 114, - "y": 1800, + "x": 1083, + "y": 2139, "w": 56, "h": 56 }, @@ -18162,8 +18162,8 @@ }, "player_ball_32_001.png": { "frame": { - "x": 71, - "y": 1069, + "x": 1420, + "y": 1418, "w": 70, "h": 70 }, @@ -18182,8 +18182,8 @@ }, "player_ball_32_2_001.png": { "frame": { - "x": 1424, - "y": 1129, + "x": 1820, + "y": 431, "w": 62, "h": 62 }, @@ -18202,18 +18202,18 @@ }, "player_ball_33_001.png": { "frame": { - "x": 142, - "y": 1069, + "x": 1487, + "y": 163, "w": 70, - "h": 66 + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 70, - "h": 66 + "h": 70 }, "sourceSize": { "w": 70, @@ -18222,18 +18222,18 @@ }, "player_ball_33_2_001.png": { "frame": { - "x": 739, - "y": 1202, + "x": 67, + "y": 1671, "w": 66, - "h": 60 + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 66, - "h": 60 + "h": 66 }, "sourceSize": { "w": 66, @@ -18242,8 +18242,8 @@ }, "player_ball_34_001.png": { "frame": { - "x": 811, - "y": 523, + "x": 146, + "y": 1344, "w": 72, "h": 72 }, @@ -18262,8 +18262,8 @@ }, "player_ball_34_2_001.png": { "frame": { - "x": 806, - "y": 1195, + "x": 134, + "y": 1671, "w": 54, "h": 66 }, @@ -18282,8 +18282,8 @@ }, "player_ball_35_001.png": { "frame": { - "x": 213, - "y": 1069, + "x": 1440, + "y": 949, "w": 70, "h": 70 }, @@ -18302,8 +18302,8 @@ }, "player_ball_35_2_001.png": { "frame": { - "x": 818, - "y": 1800, + "x": 1140, + "y": 2139, "w": 56, "h": 56 }, @@ -18322,8 +18322,8 @@ }, "player_ball_35_extra_001.png": { "frame": { - "x": 139, - "y": 742, + "x": 1757, + "y": 1461, "w": 14, "h": 10 }, @@ -18342,8 +18342,8 @@ }, "player_ball_36_001.png": { "frame": { - "x": 284, - "y": 1069, + "x": 1495, + "y": 0, "w": 70, "h": 70 }, @@ -18362,8 +18362,8 @@ }, "player_ball_36_2_001.png": { "frame": { - "x": 1904, - "y": 335, + "x": 2237, + "y": 952, "w": 48, "h": 48 }, @@ -18382,8 +18382,8 @@ }, "player_ball_37_001.png": { "frame": { - "x": 355, - "y": 1069, + "x": 1495, + "y": 234, "w": 70, "h": 70 }, @@ -18402,8 +18402,8 @@ }, "player_ball_37_2_001.png": { "frame": { - "x": 822, - "y": 1684, + "x": 2066, + "y": 800, "w": 58, "h": 58 }, @@ -18422,8 +18422,8 @@ }, "player_ball_38_001.png": { "frame": { - "x": 851, - "y": 777, + "x": 436, + "y": 1343, "w": 72, "h": 72 }, @@ -18442,18 +18442,18 @@ }, "player_ball_38_2_001.png": { "frame": { - "x": 171, - "y": 1800, + "x": 1197, + "y": 2139, "w": 56, - "h": 55 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 56, - "h": 55 + "h": 56 }, "sourceSize": { "w": 56, @@ -18462,8 +18462,8 @@ }, "player_ball_39_001.png": { "frame": { - "x": 426, - "y": 1069, + "x": 1495, + "y": 71, "w": 70, "h": 70 }, @@ -18482,17 +18482,17 @@ }, "player_ball_39_2_001.png": { "frame": { - "x": 520, - "y": 1267, - "w": 47, + "x": 1497, + "y": 1656, + "w": 48, "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 47, + "w": 48, "h": 64 }, "sourceSize": { @@ -18502,8 +18502,8 @@ }, "player_ball_40_001.png": { "frame": { - "x": 746, - "y": 906, + "x": 219, + "y": 1343, "w": 72, "h": 72 }, @@ -18522,8 +18522,8 @@ }, "player_ball_40_2_001.png": { "frame": { - "x": 739, - "y": 1140, + "x": 1631, + "y": 1543, "w": 66, "h": 30 }, @@ -18542,8 +18542,8 @@ }, "player_ball_41_001.png": { "frame": { - "x": 497, - "y": 1069, + "x": 1494, + "y": 305, "w": 70, "h": 70 }, @@ -18562,8 +18562,8 @@ }, "player_ball_41_2_001.png": { "frame": { - "x": 1543, - "y": 1836, + "x": 1475, + "y": 2183, "w": 52, "h": 52 }, @@ -18582,17 +18582,17 @@ }, "player_ball_42_001.png": { "frame": { - "x": 568, - "y": 1069, - "w": 66, + "x": 1494, + "y": 376, + "w": 70, "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 66, + "w": 70, "h": 70 }, "sourceSize": { @@ -18602,17 +18602,17 @@ }, "player_ball_42_2_001.png": { "frame": { - "x": 917, - "y": 1187, - "w": 62, + "x": 189, + "y": 1671, + "w": 66, "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 62, + "w": 66, "h": 66 }, "sourceSize": { @@ -18622,8 +18622,8 @@ }, "player_ball_43_001.png": { "frame": { - "x": 635, - "y": 1069, + "x": 1493, + "y": 447, "w": 70, "h": 70 }, @@ -18642,18 +18642,18 @@ }, "player_ball_43_2_001.png": { "frame": { - "x": 1734, - "y": 230, - "w": 57, - "h": 49 + "x": 1102, + "y": 1612, + "w": 66, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 57, - "h": 49 + "x": 0, + "y": 0, + "w": 66, + "h": 54 }, "sourceSize": { "w": 66, @@ -18662,8 +18662,8 @@ }, "player_ball_44_001.png": { "frame": { - "x": 706, - "y": 1069, + "x": 1493, + "y": 518, "w": 70, "h": 70 }, @@ -18682,9 +18682,9 @@ }, "player_ball_44_2_001.png": { "frame": { - "x": 1165, - "y": 68, - "w": 65, + "x": 256, + "y": 1671, + "w": 66, "h": 66 }, "rotated": false, @@ -18692,7 +18692,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 65, + "w": 66, "h": 66 }, "sourceSize": { @@ -18702,8 +18702,8 @@ }, "player_ball_44_extra_001.png": { "frame": { - "x": 1157, - "y": 1683, + "x": 2066, + "y": 859, "w": 58, "h": 58 }, @@ -18722,18 +18722,18 @@ }, "player_ball_45_001.png": { "frame": { - "x": 441, - "y": 923, - "w": 71, - "h": 71 + "x": 509, + "y": 1343, + "w": 72, + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 71, - "h": 71 + "y": 0, + "w": 72, + "h": 72 }, "sourceSize": { "w": 72, @@ -18742,8 +18742,8 @@ }, "player_ball_45_2_001.png": { "frame": { - "x": 1231, - "y": 0, + "x": 1035, + "y": 1666, "w": 66, "h": 66 }, @@ -18762,18 +18762,18 @@ }, "player_ball_46_001.png": { "frame": { - "x": 673, - "y": 914, + "x": 582, + "y": 1343, "w": 72, - "h": 71 + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 72, - "h": 71 + "h": 72 }, "sourceSize": { "w": 72, @@ -18782,8 +18782,8 @@ }, "player_ball_46_2_001.png": { "frame": { - "x": 1231, - "y": 67, + "x": 323, + "y": 1671, "w": 66, "h": 66 }, @@ -18802,8 +18802,8 @@ }, "player_ball_47_001.png": { "frame": { - "x": 777, - "y": 1069, + "x": 1493, + "y": 589, "w": 70, "h": 70 }, @@ -18822,8 +18822,8 @@ }, "player_ball_47_2_001.png": { "frame": { - "x": 1231, - "y": 134, + "x": 390, + "y": 1671, "w": 66, "h": 66 }, @@ -18842,18 +18842,18 @@ }, "player_ball_48_001.png": { "frame": { - "x": 150, - "y": 918, + "x": 655, + "y": 1343, "w": 72, - "h": 71 + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 72, - "h": 71 + "h": 72 }, "sourceSize": { "w": 72, @@ -18862,8 +18862,8 @@ }, "player_ball_48_2_001.png": { "frame": { - "x": 1231, - "y": 201, + "x": 457, + "y": 1671, "w": 66, "h": 66 }, @@ -18882,8 +18882,8 @@ }, "player_ball_48_extra_001.png": { "frame": { - "x": 769, - "y": 775, + "x": 231, + "y": 1131, "w": 6, "h": 6 }, @@ -18902,9 +18902,9 @@ }, "player_ball_49_001.png": { "frame": { - "x": 513, - "y": 923, - "w": 71, + "x": 728, + "y": 1343, + "w": 72, "h": 70 }, "rotated": false, @@ -18912,7 +18912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 71, + "w": 72, "h": 70 }, "sourceSize": { @@ -18922,8 +18922,8 @@ }, "player_ball_49_2_001.png": { "frame": { - "x": 1231, - "y": 268, + "x": 524, + "y": 1671, "w": 66, "h": 66 }, @@ -18942,17 +18942,17 @@ }, "player_ball_49_extra_001.png": { "frame": { - "x": 1125, - "y": 1267, - "w": 64, + "x": 591, + "y": 1671, + "w": 66, "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 64, + "w": 66, "h": 64 }, "sourceSize": { @@ -18962,18 +18962,18 @@ }, "player_ball_50_001.png": { "frame": { - "x": 585, - "y": 923, - "w": 69, - "h": 71 + "x": 292, + "y": 1343, + "w": 70, + "h": 72 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 69, - "h": 71 + "y": 0, + "w": 70, + "h": 72 }, "sourceSize": { "w": 70, @@ -18982,8 +18982,8 @@ }, "player_ball_50_2_001.png": { "frame": { - "x": 1904, - "y": 384, + "x": 2236, + "y": 2113, "w": 48, "h": 48 }, @@ -19002,17 +19002,17 @@ }, "player_ball_50_extra_001.png": { "frame": { - "x": 1190, - "y": 1267, - "w": 56, + "x": 1757, + "y": 0, + "w": 62, "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 56, + "w": 62, "h": 64 }, "sourceSize": { @@ -19022,9 +19022,9 @@ }, "player_ball_51_001.png": { "frame": { - "x": 951, - "y": 0, - "w": 71, + "x": 801, + "y": 1343, + "w": 72, "h": 68 }, "rotated": false, @@ -19032,7 +19032,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 71, + "w": 72, "h": 68 }, "sourceSize": { @@ -19042,18 +19042,18 @@ }, "player_ball_51_2_001.png": { "frame": { - "x": 190, - "y": 1928, - "w": 40, - "h": 41 + "x": 1800, + "y": 2196, + "w": 48, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 40, - "h": 41 + "w": 48, + "h": 46 }, "sourceSize": { "w": 48, @@ -19062,18 +19062,18 @@ }, "player_ball_51_extra_001.png": { "frame": { - "x": 1231, - "y": 1186, - "w": 65, - "h": 60 + "x": 965, + "y": 1670, + "w": 66, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 65, - "h": 60 + "y": 0, + "w": 66, + "h": 62 }, "sourceSize": { "w": 66, @@ -19082,18 +19082,18 @@ }, "player_ball_52_001.png": { "frame": { - "x": 458, - "y": 843, - "w": 67, - "h": 73 + "x": 1198, + "y": 817, + "w": 70, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 67, - "h": 73 + "y": 0, + "w": 70, + "h": 74 }, "sourceSize": { "w": 70, @@ -19102,18 +19102,18 @@ }, "player_ball_52_2_001.png": { "frame": { - "x": 1670, - "y": 1055, - "w": 59, - "h": 52 + "x": 1511, + "y": 939, + "w": 60, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 59, - "h": 52 + "w": 60, + "h": 68 }, "sourceSize": { "w": 60, @@ -19122,18 +19122,18 @@ }, "player_ball_52_extra_001.png": { "frame": { - "x": 1201, - "y": 924, - "w": 61, - "h": 65 + "x": 1572, + "y": 928, + "w": 64, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 61, - "h": 65 + "y": 0, + "w": 64, + "h": 68 }, "sourceSize": { "w": 64, @@ -19142,8 +19142,8 @@ }, "player_ball_53_001.png": { "frame": { - "x": 819, - "y": 925, + "x": 874, + "y": 1343, "w": 72, "h": 72 }, @@ -19162,8 +19162,8 @@ }, "player_ball_53_2_001.png": { "frame": { - "x": 1904, - "y": 433, + "x": 2236, + "y": 1001, "w": 48, "h": 48 }, @@ -19182,8 +19182,8 @@ }, "player_ball_53_extra_001.png": { "frame": { - "x": 1721, - "y": 1930, + "x": 2103, + "y": 2231, "w": 40, "h": 40 }, @@ -19202,18 +19202,18 @@ }, "robot_01_01_001.png": { "frame": { - "x": 1846, - "y": 510, - "w": 54, - "h": 39 + "x": 1749, + "y": 2117, + "w": 56, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 54, - "h": 39 + "x": 0, + "y": 0, + "w": 56, + "h": 40 }, "sourceSize": { "w": 56, @@ -19222,18 +19222,18 @@ }, "robot_01_01_2_001.png": { "frame": { - "x": 449, - "y": 1856, + "x": 2236, + "y": 2162, "w": 48, - "h": 28 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, + "y": 0, "w": 48, - "h": 28 + "h": 36 }, "sourceSize": { "w": 48, @@ -19242,18 +19242,18 @@ }, "robot_01_01_glow_001.png": { "frame": { - "x": 881, - "y": 1683, - "w": 58, - "h": 43 + "x": 244, + "y": 2007, + "w": 60, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 58, - "h": 43 + "x": 0, + "y": 0, + "w": 60, + "h": 44 }, "sourceSize": { "w": 60, @@ -19262,9 +19262,9 @@ }, "robot_01_02_001.png": { "frame": { - "x": 669, - "y": 1535, - "w": 19, + "x": 2060, + "y": 2198, + "w": 20, "h": 26 }, "rotated": false, @@ -19272,7 +19272,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -19282,18 +19282,18 @@ }, "robot_01_02_2_001.png": { "frame": { - "x": 328, - "y": 591, - "w": 3, - "h": 3 + "x": 189, + "y": 661, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -19302,9 +19302,9 @@ }, "robot_01_02_glow_001.png": { "frame": { - "x": 1988, - "y": 512, - "w": 23, + "x": 2237, + "y": 2274, + "w": 24, "h": 30 }, "rotated": false, @@ -19312,7 +19312,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -19322,8 +19322,8 @@ }, "robot_01_03_001.png": { "frame": { - "x": 1722, - "y": 1798, + "x": 414, + "y": 986, "w": 10, "h": 26 }, @@ -19342,18 +19342,18 @@ }, "robot_01_03_2_001.png": { "frame": { - "x": 776, - "y": 753, + "x": 1871, + "y": 1982, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -19362,8 +19362,8 @@ }, "robot_01_03_glow_001.png": { "frame": { - "x": 533, - "y": 792, + "x": 392, + "y": 1136, "w": 14, "h": 30 }, @@ -19382,8 +19382,8 @@ }, "robot_01_04_001.png": { "frame": { - "x": 1169, - "y": 1799, + "x": 216, + "y": 1988, "w": 28, "h": 18 }, @@ -19402,18 +19402,18 @@ }, "robot_01_04_2_001.png": { "frame": { - "x": 162, - "y": 591, - "w": 3, - "h": 3 + "x": 1236, + "y": 1651, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -19422,8 +19422,8 @@ }, "robot_01_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1401, + "x": 1461, + "y": 2242, "w": 32, "h": 22 }, @@ -19442,9 +19442,9 @@ }, "robot_02_01_001.png": { "frame": { - "x": 1656, - "y": 1661, - "w": 58, + "x": 1757, + "y": 1420, + "w": 62, "h": 40 }, "rotated": false, @@ -19452,7 +19452,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 58, + "w": 62, "h": 40 }, "sourceSize": { @@ -19462,18 +19462,18 @@ }, "robot_02_01_2_001.png": { "frame": { - "x": 214, - "y": 360, - "w": 21, - "h": 8 + "x": 1318, + "y": 1927, + "w": 40, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 19, + "x": 0, "y": 0, - "w": 21, - "h": 8 + "w": 40, + "h": 16 }, "sourceSize": { "w": 40, @@ -19482,9 +19482,9 @@ }, "robot_02_01_glow_001.png": { "frame": { - "x": 0, - "y": 1332, - "w": 63, + "x": 1562, + "y": 1008, + "w": 68, "h": 44 }, "rotated": false, @@ -19492,7 +19492,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, + "w": 68, "h": 44 }, "sourceSize": { @@ -19502,18 +19502,18 @@ }, "robot_02_02_001.png": { "frame": { - "x": 916, - "y": 1966, + "x": 1489, + "y": 2109, "w": 20, - "h": 27 + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 20, - "h": 27 + "h": 28 }, "sourceSize": { "w": 20, @@ -19522,10 +19522,10 @@ }, "robot_02_02_2_001.png": { "frame": { - "x": 623, - "y": 765, + "x": 963, + "y": 2064, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -19533,7 +19533,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -19542,18 +19542,18 @@ }, "robot_02_02_glow_001.png": { "frame": { - "x": 1988, - "y": 0, + "x": 1484, + "y": 2278, "w": 24, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 24, - "h": 31 + "h": 32 }, "sourceSize": { "w": 24, @@ -19562,8 +19562,8 @@ }, "robot_02_03_001.png": { "frame": { - "x": 861, - "y": 1857, + "x": 1340, + "y": 73, "w": 10, "h": 26 }, @@ -19582,18 +19582,18 @@ }, "robot_02_03_2_001.png": { "frame": { - "x": 1479, - "y": 435, + "x": 657, + "y": 2058, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -19602,8 +19602,8 @@ }, "robot_02_03_glow_001.png": { "frame": { - "x": 1951, - "y": 836, + "x": 2273, + "y": 1731, "w": 14, "h": 30 }, @@ -19622,8 +19622,8 @@ }, "robot_02_04_001.png": { "frame": { - "x": 1568, - "y": 1723, + "x": 1464, + "y": 1067, "w": 26, "h": 16 }, @@ -19642,18 +19642,18 @@ }, "robot_02_04_2_001.png": { "frame": { - "x": 409, - "y": 597, - "w": 3, - "h": 3 + "x": 1363, + "y": 1707, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -19662,8 +19662,8 @@ }, "robot_02_04_glow_001.png": { "frame": { - "x": 683, - "y": 1966, + "x": 403, + "y": 2062, "w": 30, "h": 20 }, @@ -19682,18 +19682,18 @@ }, "robot_03_01_001.png": { "frame": { - "x": 1670, - "y": 1108, - "w": 59, - "h": 50 + "x": 305, + "y": 2007, + "w": 60, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 59, - "h": 50 + "w": 60, + "h": 56 }, "sourceSize": { "w": 60, @@ -19702,18 +19702,18 @@ }, "robot_03_01_2_001.png": { "frame": { - "x": 1790, - "y": 1831, - "w": 52, - "h": 40 + "x": 366, + "y": 2007, + "w": 60, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 52, - "h": 40 + "w": 60, + "h": 54 }, "sourceSize": { "w": 60, @@ -19722,18 +19722,18 @@ }, "robot_03_01_glow_001.png": { "frame": { - "x": 568, - "y": 1323, - "w": 63, - "h": 53 + "x": 1753, + "y": 894, + "w": 64, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 53 + "w": 64, + "h": 58 }, "sourceSize": { "w": 64, @@ -19742,9 +19742,9 @@ }, "robot_03_02_001.png": { "frame": { - "x": 297, - "y": 1967, - "w": 19, + "x": 2287, + "y": 2226, + "w": 20, "h": 26 }, "rotated": false, @@ -19752,7 +19752,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -19762,8 +19762,8 @@ }, "robot_03_02_2_001.png": { "frame": { - "x": 388, - "y": 645, + "x": 772, + "y": 140, "w": 16, "h": 24 }, @@ -19782,9 +19782,9 @@ }, "robot_03_02_glow_001.png": { "frame": { - "x": 1988, - "y": 1764, - "w": 23, + "x": 2262, + "y": 2274, + "w": 24, "h": 30 }, "rotated": false, @@ -19792,7 +19792,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -19802,8 +19802,8 @@ }, "robot_03_03_001.png": { "frame": { - "x": 804, - "y": 1927, + "x": 1337, + "y": 742, "w": 10, "h": 26 }, @@ -19822,18 +19822,18 @@ }, "robot_03_03_2_001.png": { "frame": { - "x": 393, - "y": 709, - "w": 3, - "h": 3 + "x": 687, + "y": 1611, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -19842,8 +19842,8 @@ }, "robot_03_03_glow_001.png": { "frame": { - "x": 578, - "y": 1948, + "x": 1527, + "y": 2236, "w": 14, "h": 30 }, @@ -19862,8 +19862,8 @@ }, "robot_03_04_001.png": { "frame": { - "x": 313, - "y": 1800, + "x": 2286, + "y": 902, "w": 26, "h": 16 }, @@ -19882,8 +19882,8 @@ }, "robot_03_04_2_001.png": { "frame": { - "x": 1988, - "y": 924, + "x": 693, + "y": 2263, "w": 24, "h": 14 }, @@ -19902,8 +19902,8 @@ }, "robot_03_04_glow_001.png": { "frame": { - "x": 1982, - "y": 1247, + "x": 1118, + "y": 2118, "w": 30, "h": 20 }, @@ -19922,8 +19922,8 @@ }, "robot_04_01_001.png": { "frame": { - "x": 1671, - "y": 488, + "x": 427, + "y": 2007, "w": 60, "h": 54 }, @@ -19942,18 +19942,18 @@ }, "robot_04_01_2_001.png": { "frame": { - "x": 1904, - "y": 1009, - "w": 46, - "h": 43 + "x": 1528, + "y": 2183, + "w": 50, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 46, - "h": 43 + "w": 50, + "h": 52 }, "sourceSize": { "w": 50, @@ -19962,17 +19962,17 @@ }, "robot_04_01_glow_001.png": { "frame": { - "x": 1298, - "y": 0, - "w": 64, + "x": 347, + "y": 1611, + "w": 66, "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 64, + "w": 66, "h": 58 }, "sourceSize": { @@ -19982,18 +19982,18 @@ }, "robot_04_02_001.png": { "frame": { - "x": 320, - "y": 1966, - "w": 19, - "h": 27 + "x": 1902, + "y": 1831, + "w": 20, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 19, - "h": 27 + "y": 0, + "w": 20, + "h": 28 }, "sourceSize": { "w": 20, @@ -20002,18 +20002,18 @@ }, "robot_04_02_2_001.png": { "frame": { - "x": 717, - "y": 207, - "w": 3, - "h": 3 + "x": 1704, + "y": 125, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -20022,9 +20022,9 @@ }, "robot_04_02_glow_001.png": { "frame": { - "x": 1988, - "y": 127, - "w": 23, + "x": 2274, + "y": 1700, + "w": 24, "h": 30 }, "rotated": false, @@ -20032,7 +20032,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -20042,8 +20042,8 @@ }, "robot_04_03_001.png": { "frame": { - "x": 1949, - "y": 1345, + "x": 304, + "y": 364, "w": 10, "h": 26 }, @@ -20062,18 +20062,18 @@ }, "robot_04_03_2_001.png": { "frame": { - "x": 1539, - "y": 1308, + "x": 198, + "y": 98, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -20082,8 +20082,8 @@ }, "robot_04_03_glow_001.png": { "frame": { - "x": 1216, - "y": 569, + "x": 497, + "y": 878, "w": 14, "h": 30 }, @@ -20102,8 +20102,8 @@ }, "robot_04_04_001.png": { "frame": { - "x": 1983, - "y": 1195, + "x": 1494, + "y": 2259, "w": 28, "h": 18 }, @@ -20122,18 +20122,18 @@ }, "robot_04_04_2_001.png": { "frame": { - "x": 513, - "y": 452, - "w": 3, - "h": 3 + "x": 1415, + "y": 1418, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -20142,8 +20142,8 @@ }, "robot_04_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1424, + "x": 1509, + "y": 2278, "w": 32, "h": 22 }, @@ -20162,18 +20162,18 @@ }, "robot_05_01_001.png": { "frame": { - "x": 610, - "y": 1843, + "x": 1416, + "y": 2191, "w": 52, - "h": 47 + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 52, - "h": 47 + "h": 50 }, "sourceSize": { "w": 52, @@ -20182,18 +20182,18 @@ }, "robot_05_01_2_001.png": { "frame": { - "x": 955, - "y": 1928, - "w": 21, - "h": 37 + "x": 2237, + "y": 204, + "w": 50, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 29, - "y": 3, - "w": 21, - "h": 37 + "x": 0, + "y": 0, + "w": 50, + "h": 40 }, "sourceSize": { "w": 50, @@ -20202,18 +20202,18 @@ }, "robot_05_01_glow_001.png": { "frame": { - "x": 1787, - "y": 990, + "x": 1690, + "y": 2123, "w": 56, - "h": 51 + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 56, - "h": 51 + "h": 54 }, "sourceSize": { "w": 56, @@ -20222,9 +20222,9 @@ }, "robot_05_02_001.png": { "frame": { - "x": 496, - "y": 1966, - "w": 19, + "x": 2287, + "y": 1965, + "w": 20, "h": 26 }, "rotated": false, @@ -20232,7 +20232,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -20242,18 +20242,18 @@ }, "robot_05_02_2_001.png": { "frame": { - "x": 1219, - "y": 1646, - "w": 9, - "h": 8 + "x": 1204, + "y": 1927, + "w": 10, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 9, - "h": 8 + "w": 10, + "h": 16 }, "sourceSize": { "w": 10, @@ -20262,9 +20262,9 @@ }, "robot_05_02_glow_001.png": { "frame": { - "x": 1988, - "y": 543, - "w": 23, + "x": 2288, + "y": 0, + "w": 24, "h": 30 }, "rotated": false, @@ -20272,7 +20272,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -20282,8 +20282,8 @@ }, "robot_05_03_001.png": { "frame": { - "x": 448, - "y": 305, + "x": 2054, + "y": 1631, "w": 10, "h": 26 }, @@ -20302,18 +20302,18 @@ }, "robot_05_03_2_001.png": { "frame": { - "x": 231, - "y": 752, - "w": 3, - "h": 3 + "x": 1752, + "y": 826, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -20322,8 +20322,8 @@ }, "robot_05_03_glow_001.png": { "frame": { - "x": 1216, - "y": 804, + "x": 491, + "y": 1025, "w": 14, "h": 30 }, @@ -20342,8 +20342,8 @@ }, "robot_05_04_001.png": { "frame": { - "x": 1983, - "y": 1214, + "x": 1542, + "y": 2259, "w": 28, "h": 18 }, @@ -20362,18 +20362,18 @@ }, "robot_05_04_2_001.png": { "frame": { - "x": 1478, - "y": 1552, - "w": 14, - "h": 6 + "x": 0, + "y": 2068, + "w": 26, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 14, - "h": 6 + "x": 0, + "y": 0, + "w": 26, + "h": 14 }, "sourceSize": { "w": 26, @@ -20382,8 +20382,8 @@ }, "robot_05_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1447, + "x": 1542, + "y": 2236, "w": 32, "h": 22 }, @@ -20402,18 +20402,18 @@ }, "robot_06_01_001.png": { "frame": { - "x": 800, - "y": 1325, - "w": 63, - "h": 49 + "x": 1492, + "y": 660, + "w": 70, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 63, - "h": 49 + "x": 0, + "y": 0, + "w": 70, + "h": 54 }, "sourceSize": { "w": 70, @@ -20422,18 +20422,18 @@ }, "robot_06_01_2_001.png": { "frame": { - "x": 1230, - "y": 1970, - "w": 25, - "h": 20 + "x": 2235, + "y": 1050, + "w": 48, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, - "y": 6, - "w": 25, - "h": 20 + "x": 0, + "y": 0, + "w": 48, + "h": 26 }, "sourceSize": { "w": 48, @@ -20442,18 +20442,18 @@ }, "robot_06_01_glow_001.png": { "frame": { - "x": 1160, - "y": 250, - "w": 67, - "h": 53 + "x": 1198, + "y": 892, + "w": 74, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 67, - "h": 53 + "x": 0, + "y": 0, + "w": 74, + "h": 58 }, "sourceSize": { "w": 74, @@ -20462,9 +20462,9 @@ }, "robot_06_02_001.png": { "frame": { - "x": 958, - "y": 1966, - "w": 19, + "x": 2287, + "y": 2253, + "w": 20, "h": 26 }, "rotated": false, @@ -20472,7 +20472,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -20482,10 +20482,10 @@ }, "robot_06_02_2_001.png": { "frame": { - "x": 1297, - "y": 913, + "x": 443, + "y": 808, "w": 10, - "h": 10 + "h": 18 }, "rotated": false, "trimmed": true, @@ -20493,7 +20493,7 @@ "x": 0, "y": 0, "w": 10, - "h": 10 + "h": 18 }, "sourceSize": { "w": 10, @@ -20502,9 +20502,9 @@ }, "robot_06_02_glow_001.png": { "frame": { - "x": 1986, - "y": 574, - "w": 23, + "x": 2288, + "y": 1731, + "w": 24, "h": 30 }, "rotated": false, @@ -20512,7 +20512,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -20522,8 +20522,8 @@ }, "robot_06_03_001.png": { "frame": { - "x": 2002, - "y": 313, + "x": 1340, + "y": 100, "w": 10, "h": 26 }, @@ -20542,18 +20542,18 @@ }, "robot_06_03_2_001.png": { "frame": { - "x": 794, - "y": 230, - "w": 3, - "h": 3 + "x": 1919, + "y": 2139, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -20562,8 +20562,8 @@ }, "robot_06_03_glow_001.png": { "frame": { - "x": 1216, - "y": 600, + "x": 309, + "y": 2240, "w": 14, "h": 30 }, @@ -20582,8 +20582,8 @@ }, "robot_06_04_001.png": { "frame": { - "x": 1982, - "y": 1405, + "x": 245, + "y": 1988, "w": 28, "h": 18 }, @@ -20602,18 +20602,18 @@ }, "robot_06_04_2_001.png": { "frame": { - "x": 243, - "y": 624, - "w": 3, - "h": 3 + "x": 1567, + "y": 2138, + "w": 4, + "h": 4 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 4, + "h": 4 }, "sourceSize": { "w": 4, @@ -20622,8 +20622,8 @@ }, "robot_06_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1470, + "x": 1542, + "y": 2278, "w": 32, "h": 22 }, @@ -20642,18 +20642,18 @@ }, "robot_07_01_001.png": { "frame": { - "x": 1231, - "y": 335, - "w": 66, - "h": 55 + "x": 1492, + "y": 715, + "w": 70, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 66, - "h": 55 + "w": 70, + "h": 62 }, "sourceSize": { "w": 70, @@ -20662,18 +20662,18 @@ }, "robot_07_01_2_001.png": { "frame": { - "x": 498, - "y": 1800, - "w": 55, - "h": 45 + "x": 488, + "y": 2007, + "w": 60, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 55, - "h": 45 + "w": 60, + "h": 60 }, "sourceSize": { "w": 60, @@ -20682,18 +20682,18 @@ }, "robot_07_01_glow_001.png": { "frame": { - "x": 848, - "y": 1076, - "w": 70, - "h": 59 + "x": 1174, + "y": 951, + "w": 74, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 70, - "h": 59 + "w": 74, + "h": 66 }, "sourceSize": { "w": 74, @@ -20702,9 +20702,9 @@ }, "robot_07_02_001.png": { "frame": { - "x": 360, - "y": 1966, - "w": 24, + "x": 2282, + "y": 1077, + "w": 30, "h": 26 }, "rotated": false, @@ -20712,7 +20712,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, + "w": 30, "h": 26 }, "sourceSize": { @@ -20722,18 +20722,18 @@ }, "robot_07_02_2_001.png": { "frame": { - "x": 298, - "y": 826, - "w": 9, - "h": 15 + "x": 1454, + "y": 1927, + "w": 28, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 9, - "h": 15 + "y": 0, + "w": 28, + "h": 16 }, "sourceSize": { "w": 28, @@ -20742,9 +20742,9 @@ }, "robot_07_02_glow_001.png": { "frame": { - "x": 1984, - "y": 411, - "w": 28, + "x": 1456, + "y": 1386, + "w": 34, "h": 30 }, "rotated": false, @@ -20752,7 +20752,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, + "w": 34, "h": 30 }, "sourceSize": { @@ -20762,8 +20762,8 @@ }, "robot_07_03_001.png": { "frame": { - "x": 884, - "y": 1967, + "x": 2054, + "y": 1658, "w": 10, "h": 26 }, @@ -20782,18 +20782,18 @@ }, "robot_07_03_2_001.png": { "frame": { - "x": 1600, - "y": 1360, + "x": 207, + "y": 98, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -20802,8 +20802,8 @@ }, "robot_07_03_glow_001.png": { "frame": { - "x": 1216, - "y": 631, + "x": 2162, + "y": 2028, "w": 14, "h": 30 }, @@ -20822,17 +20822,17 @@ }, "robot_07_04_001.png": { "frame": { - "x": 1981, - "y": 873, - "w": 31, + "x": 43, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 31, + "w": 34, "h": 18 }, "sourceSize": { @@ -20842,37 +20842,37 @@ }, "robot_07_04_2_001.png": { "frame": { - "x": 1536, - "y": 671, - "w": 11, - "h": 9 + "x": 71, + "y": 1565, + "w": 30, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 19, - "y": 5, - "w": 11, - "h": 9 - }, - "sourceSize": { + "x": 0, + "y": 0, + "w": 30, + "h": 14 + }, + "sourceSize": { "w": 30, "h": 14 } }, "robot_07_04_glow_001.png": { "frame": { - "x": 1120, - "y": 1855, - "w": 35, + "x": 231, + "y": 2240, + "w": 38, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 35, + "w": 38, "h": 22 }, "sourceSize": { @@ -20882,18 +20882,18 @@ }, "robot_08_01_001.png": { "frame": { - "x": 1790, - "y": 1779, - "w": 56, - "h": 51 + "x": 1757, + "y": 65, + "w": 58, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 56, - "h": 51 + "w": 58, + "h": 64 }, "sourceSize": { "w": 58, @@ -20902,18 +20902,18 @@ }, "robot_08_01_2_001.png": { "frame": { - "x": 1988, - "y": 350, - "w": 24, - "h": 28 + "x": 549, + "y": 2052, + "w": 54, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 30, - "y": 2, - "w": 24, - "h": 28 + "x": 0, + "y": 0, + "w": 54, + "h": 30 }, "sourceSize": { "w": 54, @@ -20922,18 +20922,18 @@ }, "robot_08_01_glow_001.png": { "frame": { - "x": 1671, - "y": 543, - "w": 60, - "h": 55 + "x": 1562, + "y": 1053, + "w": 62, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 60, - "h": 55 + "w": 62, + "h": 68 }, "sourceSize": { "w": 62, @@ -20942,9 +20942,9 @@ }, "robot_08_02_001.png": { "frame": { - "x": 516, - "y": 1966, - "w": 19, + "x": 2287, + "y": 1992, + "w": 20, "h": 26 }, "rotated": false, @@ -20952,7 +20952,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -20962,10 +20962,10 @@ }, "robot_08_02_2_001.png": { "frame": { - "x": 205, - "y": 662, + "x": 2221, + "y": 1667, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -20973,7 +20973,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -20982,9 +20982,9 @@ }, "robot_08_02_glow_001.png": { "frame": { - "x": 1988, - "y": 1795, - "w": 23, + "x": 2288, + "y": 31, + "w": 24, "h": 30 }, "rotated": false, @@ -20992,7 +20992,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -21002,8 +21002,8 @@ }, "robot_08_03_001.png": { "frame": { - "x": 982, - "y": 868, + "x": 2054, + "y": 1685, "w": 10, "h": 26 }, @@ -21022,8 +21022,8 @@ }, "robot_08_03_2_001.png": { "frame": { - "x": 172, - "y": 506, + "x": 772, + "y": 230, "w": 2, "h": 2 }, @@ -21042,8 +21042,8 @@ }, "robot_08_03_glow_001.png": { "frame": { - "x": 1216, - "y": 662, + "x": 1473, + "y": 837, "w": 14, "h": 30 }, @@ -21062,8 +21062,8 @@ }, "robot_08_04_001.png": { "frame": { - "x": 1982, - "y": 1424, + "x": 274, + "y": 1988, "w": 28, "h": 18 }, @@ -21082,18 +21082,18 @@ }, "robot_08_04_2_001.png": { "frame": { - "x": 1661, - "y": 1403, - "w": 6, - "h": 6 + "x": 867, + "y": 78, + "w": 10, + "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 6, - "h": 6 + "y": 0, + "w": 10, + "h": 8 }, "sourceSize": { "w": 10, @@ -21102,8 +21102,8 @@ }, "robot_08_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1493, + "x": 1575, + "y": 2278, "w": 32, "h": 22 }, @@ -21122,18 +21122,18 @@ }, "robot_09_01_001.png": { "frame": { - "x": 1595, - "y": 1674, - "w": 58, - "h": 52 + "x": 830, + "y": 1548, + "w": 68, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 58, - "h": 52 + "x": 0, + "y": 0, + "w": 68, + "h": 58 }, "sourceSize": { "w": 68, @@ -21142,18 +21142,18 @@ }, "robot_09_01_2_001.png": { "frame": { - "x": 1734, - "y": 280, - "w": 51, - "h": 57 + "x": 958, + "y": 236, + "w": 60, + "h": 82 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 51, - "h": 57 + "w": 60, + "h": 82 }, "sourceSize": { "w": 60, @@ -21162,18 +21162,18 @@ }, "robot_09_01_extra_001.png": { "frame": { - "x": 1034, - "y": 1878, - "w": 51, - "h": 47 + "x": 899, + "y": 1548, + "w": 68, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, + "x": 0, "y": 0, - "w": 51, - "h": 47 + "w": 68, + "h": 62 }, "sourceSize": { "w": 68, @@ -21182,18 +21182,18 @@ }, "robot_09_01_glow_001.png": { "frame": { - "x": 812, - "y": 352, - "w": 62, - "h": 74 + "x": 794, + "y": 78, + "w": 72, + "h": 86 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 62, - "h": 74 + "w": 72, + "h": 86 }, "sourceSize": { "w": 72, @@ -21202,9 +21202,9 @@ }, "robot_09_02_001.png": { "frame": { - "x": 978, - "y": 1966, - "w": 19, + "x": 2287, + "y": 2280, + "w": 20, "h": 26 }, "rotated": false, @@ -21212,7 +21212,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -21222,10 +21222,10 @@ }, "robot_09_02_2_001.png": { "frame": { - "x": 781, - "y": 523, + "x": 1539, + "y": 1927, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -21233,7 +21233,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -21242,9 +21242,9 @@ }, "robot_09_02_glow_001.png": { "frame": { - "x": 1988, - "y": 158, - "w": 23, + "x": 2288, + "y": 62, + "w": 24, "h": 30 }, "rotated": false, @@ -21252,7 +21252,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -21262,8 +21262,8 @@ }, "robot_09_03_001.png": { "frame": { - "x": 1052, - "y": 1136, + "x": 2054, + "y": 1712, "w": 10, "h": 26 }, @@ -21282,18 +21282,18 @@ }, "robot_09_03_2_001.png": { "frame": { - "x": 1098, - "y": 1555, + "x": 1556, + "y": 1179, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -21302,8 +21302,8 @@ }, "robot_09_03_glow_001.png": { "frame": { - "x": 1216, - "y": 693, + "x": 80, + "y": 2240, "w": 14, "h": 30 }, @@ -21322,8 +21322,8 @@ }, "robot_09_04_001.png": { "frame": { - "x": 1982, - "y": 1443, + "x": 303, + "y": 1988, "w": 28, "h": 18 }, @@ -21342,8 +21342,8 @@ }, "robot_09_04_2_001.png": { "frame": { - "x": 555, - "y": 148, + "x": 252, + "y": 980, "w": 2, "h": 2 }, @@ -21362,8 +21362,8 @@ }, "robot_09_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1516, + "x": 1575, + "y": 2241, "w": 32, "h": 22 }, @@ -21382,18 +21382,18 @@ }, "robot_10_01_001.png": { "frame": { - "x": 237, - "y": 709, - "w": 77, - "h": 46 + "x": 589, + "y": 1004, + "w": 80, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 77, - "h": 46 + "w": 80, + "h": 52 }, "sourceSize": { "w": 80, @@ -21402,18 +21402,18 @@ }, "robot_10_01_2_001.png": { "frame": { - "x": 813, - "y": 1857, - "w": 47, - "h": 25 + "x": 154, + "y": 1136, + "w": 76, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 29, + "x": 0, "y": 0, - "w": 47, - "h": 25 + "w": 76, + "h": 48 }, "sourceSize": { "w": 76, @@ -21422,18 +21422,18 @@ }, "robot_10_01_glow_001.png": { "frame": { - "x": 559, - "y": 43, - "w": 81, - "h": 51 + "x": 513, + "y": 876, + "w": 84, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 81, - "h": 51 + "w": 84, + "h": 58 }, "sourceSize": { "w": 84, @@ -21442,9 +21442,9 @@ }, "robot_10_02_001.png": { "frame": { - "x": 998, - "y": 1966, - "w": 24, + "x": 2282, + "y": 1104, + "w": 30, "h": 26 }, "rotated": false, @@ -21452,7 +21452,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, + "w": 30, "h": 26 }, "sourceSize": { @@ -21462,18 +21462,18 @@ }, "robot_10_02_2_001.png": { "frame": { - "x": 1009, - "y": 479, - "w": 9, - "h": 15 + "x": 2284, + "y": 885, + "w": 28, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 9, - "h": 15 + "y": 0, + "w": 28, + "h": 16 }, "sourceSize": { "w": 28, @@ -21482,9 +21482,9 @@ }, "robot_10_02_glow_001.png": { "frame": { - "x": 1983, - "y": 1077, - "w": 28, + "x": 1004, + "y": 2243, + "w": 34, "h": 30 }, "rotated": false, @@ -21492,7 +21492,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, + "w": 34, "h": 30 }, "sourceSize": { @@ -21502,8 +21502,8 @@ }, "robot_10_03_001.png": { "frame": { - "x": 1892, - "y": 1033, + "x": 2054, + "y": 1739, "w": 10, "h": 26 }, @@ -21522,18 +21522,18 @@ }, "robot_10_03_2_001.png": { "frame": { - "x": 1159, - "y": 1614, + "x": 919, + "y": 1451, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -21542,8 +21542,8 @@ }, "robot_10_03_glow_001.png": { "frame": { - "x": 1216, - "y": 724, + "x": 772, + "y": 272, "w": 14, "h": 30 }, @@ -21562,17 +21562,17 @@ }, "robot_10_04_001.png": { "frame": { - "x": 1074, - "y": 1799, - "w": 31, + "x": 305, + "y": 2064, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 31, + "w": 34, "h": 18 }, "sourceSize": { @@ -21582,18 +21582,18 @@ }, "robot_10_04_2_001.png": { "frame": { - "x": 1440, - "y": 1725, - "w": 11, - "h": 9 + "x": 1236, + "y": 1723, + "w": 30, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 19, - "y": 5, - "w": 11, - "h": 9 + "x": 0, + "y": 0, + "w": 30, + "h": 14 }, "sourceSize": { "w": 30, @@ -21602,17 +21602,17 @@ }, "robot_10_04_glow_001.png": { "frame": { - "x": 542, - "y": 1948, - "w": 35, + "x": 270, + "y": 2240, + "w": 38, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 35, + "w": 38, "h": 22 }, "sourceSize": { @@ -21622,18 +21622,18 @@ }, "robot_11_01_001.png": { "frame": { - "x": 1846, - "y": 550, - "w": 54, - "h": 42 + "x": 549, + "y": 2007, + "w": 60, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 54, - "h": 42 + "w": 60, + "h": 44 }, "sourceSize": { "w": 60, @@ -21642,18 +21642,18 @@ }, "robot_11_01_2_001.png": { "frame": { - "x": 867, - "y": 1884, - "w": 50, - "h": 40 + "x": 2182, + "y": 872, + "w": 54, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 50, - "h": 40 + "w": 54, + "h": 42 }, "sourceSize": { "w": 54, @@ -21662,18 +21662,18 @@ }, "robot_11_01_glow_001.png": { "frame": { - "x": 940, - "y": 1683, - "w": 58, - "h": 46 + "x": 1753, + "y": 953, + "w": 64, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 58, - "h": 46 + "w": 64, + "h": 48 }, "sourceSize": { "w": 64, @@ -21682,9 +21682,9 @@ }, "robot_11_02_001.png": { "frame": { - "x": 1023, - "y": 1966, - "w": 19, + "x": 2287, + "y": 2019, + "w": 20, "h": 26 }, "rotated": false, @@ -21692,7 +21692,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -21702,10 +21702,10 @@ }, "robot_11_02_2_001.png": { "frame": { - "x": 118, - "y": 861, + "x": 1556, + "y": 1204, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -21713,7 +21713,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -21722,9 +21722,9 @@ }, "robot_11_02_glow_001.png": { "frame": { - "x": 1988, - "y": 605, - "w": 23, + "x": 2288, + "y": 93, + "w": 24, "h": 30 }, "rotated": false, @@ -21732,7 +21732,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -21742,8 +21742,8 @@ }, "robot_11_03_001.png": { "frame": { - "x": 446, - "y": 870, + "x": 2054, + "y": 1766, "w": 10, "h": 26 }, @@ -21762,18 +21762,18 @@ }, "robot_11_03_2_001.png": { "frame": { - "x": 1720, - "y": 1410, + "x": 888, + "y": 1801, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -21782,8 +21782,8 @@ }, "robot_11_03_glow_001.png": { "frame": { - "x": 841, - "y": 1954, + "x": 772, + "y": 78, "w": 14, "h": 30 }, @@ -21802,8 +21802,8 @@ }, "robot_11_04_001.png": { "frame": { - "x": 1982, - "y": 1462, + "x": 332, + "y": 1988, "w": 28, "h": 18 }, @@ -21822,18 +21822,18 @@ }, "robot_11_04_2_001.png": { "frame": { - "x": 933, - "y": 1554, - "w": 6, - "h": 6 + "x": 616, + "y": 1165, + "w": 10, + "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 6, - "h": 6 + "y": 0, + "w": 10, + "h": 8 }, "sourceSize": { "w": 10, @@ -21842,8 +21842,8 @@ }, "robot_11_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1539, + "x": 1608, + "y": 2278, "w": 32, "h": 22 }, @@ -21862,18 +21862,18 @@ }, "robot_12_01_001.png": { "frame": { - "x": 1424, - "y": 1192, - "w": 62, - "h": 51 + "x": 1492, + "y": 778, + "w": 70, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 62, - "h": 51 + "w": 70, + "h": 60 }, "sourceSize": { "w": 70, @@ -21882,18 +21882,18 @@ }, "robot_12_01_2_001.png": { "frame": { - "x": 1949, - "y": 1562, - "w": 32, - "h": 20 + "x": 1820, + "y": 494, + "w": 62, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 30, + "x": 0, "y": 0, - "w": 32, - "h": 20 + "w": 62, + "h": 48 }, "sourceSize": { "w": 62, @@ -21902,18 +21902,18 @@ }, "robot_12_01_glow_001.png": { "frame": { - "x": 1231, - "y": 391, - "w": 66, - "h": 55 + "x": 1174, + "y": 1018, + "w": 74, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 66, - "h": 55 + "w": 74, + "h": 64 }, "sourceSize": { "w": 74, @@ -21922,9 +21922,9 @@ }, "robot_12_02_001.png": { "frame": { - "x": 0, - "y": 1994, - "w": 19, + "x": 2287, + "y": 2046, + "w": 20, "h": 26 }, "rotated": false, @@ -21932,7 +21932,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -21942,10 +21942,10 @@ }, "robot_12_02_2_001.png": { "frame": { - "x": 1187, - "y": 855, + "x": 816, + "y": 2261, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -21953,7 +21953,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -21962,9 +21962,9 @@ }, "robot_12_02_glow_001.png": { "frame": { - "x": 1988, - "y": 1826, - "w": 23, + "x": 2288, + "y": 124, + "w": 24, "h": 30 }, "rotated": false, @@ -21972,7 +21972,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -21982,8 +21982,8 @@ }, "robot_12_03_001.png": { "frame": { - "x": 20, - "y": 1994, + "x": 2054, + "y": 1793, "w": 10, "h": 26 }, @@ -22002,18 +22002,18 @@ }, "robot_12_03_2_001.png": { "frame": { - "x": 1834, - "y": 1415, + "x": 933, + "y": 1840, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -22022,8 +22022,8 @@ }, "robot_12_03_glow_001.png": { "frame": { - "x": 1972, - "y": 1849, + "x": 1019, + "y": 269, "w": 14, "h": 30 }, @@ -22042,18 +22042,18 @@ }, "robot_12_04_001.png": { "frame": { - "x": 1982, - "y": 1481, + "x": 361, + "y": 1988, "w": 28, - "h": 17 + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 28, - "h": 17 + "h": 18 }, "sourceSize": { "w": 28, @@ -22062,18 +22062,18 @@ }, "robot_12_04_2_001.png": { "frame": { - "x": 203, - "y": 1882, - "w": 15, - "h": 8 + "x": 1819, + "y": 2300, + "w": 24, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 15, - "h": 8 + "x": 0, + "y": 0, + "w": 24, + "h": 14 }, "sourceSize": { "w": 24, @@ -22082,18 +22082,18 @@ }, "robot_12_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1583, + "x": 1641, + "y": 2278, "w": 32, - "h": 21 + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 32, - "h": 21 + "h": 22 }, "sourceSize": { "w": 32, @@ -22102,18 +22102,18 @@ }, "robot_13_01_001.png": { "frame": { - "x": 985, - "y": 1435, - "w": 61, - "h": 51 + "x": 1753, + "y": 1002, + "w": 64, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 61, - "h": 51 + "x": 0, + "y": 0, + "w": 64, + "h": 52 }, "sourceSize": { "w": 64, @@ -22122,10 +22122,10 @@ }, "robot_13_01_2_001.png": { "frame": { - "x": 1733, - "y": 1796, + "x": 1572, + "y": 2130, "w": 56, - "h": 39 + "h": 48 }, "rotated": false, "trimmed": true, @@ -22133,7 +22133,7 @@ "x": 0, "y": 0, "w": 56, - "h": 39 + "h": 48 }, "sourceSize": { "w": 56, @@ -22142,18 +22142,18 @@ }, "robot_13_01_extra_001.png": { "frame": { - "x": 285, - "y": 152, - "w": 7, - "h": 6 + "x": 275, + "y": 450, + "w": 30, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, + "x": 0, "y": 0, - "w": 7, - "h": 6 + "w": 30, + "h": 12 }, "sourceSize": { "w": 30, @@ -22162,18 +22162,18 @@ }, "robot_13_01_glow_001.png": { "frame": { - "x": 980, - "y": 1202, - "w": 65, - "h": 55 + "x": 1562, + "y": 1122, + "w": 68, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 65, - "h": 55 + "x": 0, + "y": 0, + "w": 68, + "h": 56 }, "sourceSize": { "w": 68, @@ -22182,10 +22182,10 @@ }, "robot_13_02_001.png": { "frame": { - "x": 1988, - "y": 729, + "x": 2288, + "y": 155, "w": 22, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, @@ -22193,7 +22193,7 @@ "x": 0, "y": 0, "w": 22, - "h": 29 + "h": 30 }, "sourceSize": { "w": 22, @@ -22202,10 +22202,10 @@ }, "robot_13_02_2_001.png": { "frame": { - "x": 1843, - "y": 1856, + "x": 102, + "y": 1565, "w": 10, - "h": 12 + "h": 14 }, "rotated": false, "trimmed": true, @@ -22213,7 +22213,7 @@ "x": 0, "y": 0, "w": 10, - "h": 12 + "h": 14 }, "sourceSize": { "w": 10, @@ -22222,10 +22222,10 @@ }, "robot_13_02_glow_001.png": { "frame": { - "x": 673, - "y": 843, + "x": 793, + "y": 2197, "w": 26, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, @@ -22233,7 +22233,7 @@ "x": 0, "y": 0, "w": 26, - "h": 33 + "h": 34 }, "sourceSize": { "w": 26, @@ -22242,8 +22242,8 @@ }, "robot_13_03_001.png": { "frame": { - "x": 31, - "y": 1994, + "x": 2054, + "y": 1820, "w": 10, "h": 26 }, @@ -22262,18 +22262,18 @@ }, "robot_13_03_2_001.png": { "frame": { - "x": 1951, - "y": 910, + "x": 180, + "y": 2242, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -22282,8 +22282,8 @@ }, "robot_13_03_glow_001.png": { "frame": { - "x": 1997, - "y": 1857, + "x": 772, + "y": 303, "w": 14, "h": 30 }, @@ -22302,18 +22302,18 @@ }, "robot_13_04_001.png": { "frame": { - "x": 1949, - "y": 1605, - "w": 32, - "h": 19 + "x": 1278, + "y": 2060, + "w": 34, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 32, - "h": 19 + "w": 34, + "h": 20 }, "sourceSize": { "w": 34, @@ -22322,18 +22322,18 @@ }, "robot_13_04_2_001.png": { "frame": { - "x": 1889, - "y": 1300, - "w": 11, - "h": 7 + "x": 935, + "y": 882, + "w": 22, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 11, - "h": 7 + "w": 22, + "h": 12 }, "sourceSize": { "w": 22, @@ -22342,18 +22342,18 @@ }, "robot_13_04_glow_001.png": { "frame": { - "x": 1951, - "y": 714, - "w": 36, - "h": 23 + "x": 360, + "y": 2277, + "w": 38, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, - "h": 23 + "w": 38, + "h": 24 }, "sourceSize": { "w": 38, @@ -22362,18 +22362,18 @@ }, "robot_14_01_001.png": { "frame": { - "x": 1165, - "y": 135, - "w": 65, - "h": 51 + "x": 1491, + "y": 1020, + "w": 70, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 65, - "h": 51 + "w": 70, + "h": 62 }, "sourceSize": { "w": 70, @@ -22382,18 +22382,18 @@ }, "robot_14_01_2_001.png": { "frame": { - "x": 65, - "y": 1297, - "w": 63, - "h": 49 + "x": 968, + "y": 1548, + "w": 68, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 49 + "w": 68, + "h": 60 }, "sourceSize": { "w": 68, @@ -22402,18 +22402,18 @@ }, "robot_14_01_glow_001.png": { "frame": { - "x": 1090, - "y": 300, - "w": 69, - "h": 55 + "x": 1149, + "y": 1083, + "w": 74, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 69, - "h": 55 + "w": 74, + "h": 66 }, "sourceSize": { "w": 74, @@ -22422,18 +22422,18 @@ }, "robot_14_02_001.png": { "frame": { - "x": 1988, - "y": 759, - "w": 22, - "h": 29 + "x": 2288, + "y": 186, + "w": 24, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 22, - "h": 29 + "w": 24, + "h": 30 }, "sourceSize": { "w": 24, @@ -22442,8 +22442,8 @@ }, "robot_14_02_2_001.png": { "frame": { - "x": 494, - "y": 591, + "x": 80, + "y": 1057, "w": 2, "h": 2 }, @@ -22462,18 +22462,18 @@ }, "robot_14_02_glow_001.png": { "frame": { - "x": 1953, - "y": 448, - "w": 26, - "h": 33 + "x": 1039, + "y": 2243, + "w": 28, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 26, - "h": 33 + "w": 28, + "h": 34 }, "sourceSize": { "w": 28, @@ -22482,8 +22482,8 @@ }, "robot_14_03_001.png": { "frame": { - "x": 42, - "y": 1994, + "x": 2054, + "y": 1847, "w": 10, "h": 26 }, @@ -22502,18 +22502,18 @@ }, "robot_14_03_2_001.png": { "frame": { - "x": 1979, - "y": 73, + "x": 2280, + "y": 1187, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -22522,8 +22522,8 @@ }, "robot_14_03_glow_001.png": { "frame": { - "x": 1997, - "y": 1888, + "x": 772, + "y": 109, "w": 14, "h": 30 }, @@ -22542,8 +22542,8 @@ }, "robot_14_04_001.png": { "frame": { - "x": 1982, - "y": 1499, + "x": 390, + "y": 1988, "w": 28, "h": 18 }, @@ -22562,8 +22562,8 @@ }, "robot_14_04_2_001.png": { "frame": { - "x": 637, - "y": 181, + "x": 1122, + "y": 144, "w": 2, "h": 2 }, @@ -22582,8 +22582,8 @@ }, "robot_14_04_glow_001.png": { "frame": { - "x": 1949, - "y": 1625, + "x": 1671, + "y": 2241, "w": 32, "h": 22 }, @@ -22602,18 +22602,18 @@ }, "robot_15_01_001.png": { "frame": { - "x": 1846, - "y": 593, - "w": 54, - "h": 49 + "x": 2066, + "y": 918, + "w": 58, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 54, - "h": 49 + "x": 0, + "y": 0, + "w": 58, + "h": 50 }, "sourceSize": { "w": 58, @@ -22622,17 +22622,17 @@ }, "robot_15_01_2_001.png": { "frame": { - "x": 568, - "y": 1267, - "w": 36, + "x": 1629, + "y": 2136, + "w": 56, "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 20, + "x": 0, "y": 0, - "w": 36, + "w": 56, "h": 46 }, "sourceSize": { @@ -22642,17 +22642,17 @@ }, "robot_15_01_glow_001.png": { "frame": { - "x": 1216, - "y": 1683, - "w": 58, + "x": 1820, + "y": 1422, + "w": 62, "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 58, + "w": 62, "h": 52 }, "sourceSize": { @@ -22662,18 +22662,18 @@ }, "robot_15_02_001.png": { "frame": { - "x": 1988, - "y": 32, + "x": 1674, + "y": 2278, "w": 24, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 24, - "h": 31 + "h": 32 }, "sourceSize": { "w": 24, @@ -22682,10 +22682,10 @@ }, "robot_15_02_2_001.png": { "frame": { - "x": 1887, - "y": 1476, + "x": 1340, + "y": 127, "w": 10, - "h": 9 + "h": 16 }, "rotated": false, "trimmed": true, @@ -22693,7 +22693,7 @@ "x": 0, "y": 0, "w": 10, - "h": 9 + "h": 16 }, "sourceSize": { "w": 10, @@ -22702,18 +22702,18 @@ }, "robot_15_02_glow_001.png": { "frame": { - "x": 1954, - "y": 1778, + "x": 771, + "y": 2278, "w": 28, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 28, - "h": 35 + "h": 36 }, "sourceSize": { "w": 28, @@ -22722,8 +22722,8 @@ }, "robot_15_03_001.png": { "frame": { - "x": 53, - "y": 1994, + "x": 317, + "y": 102, "w": 10, "h": 26 }, @@ -22742,18 +22742,18 @@ }, "robot_15_03_2_001.png": { "frame": { - "x": 1979, - "y": 175, + "x": 2280, + "y": 1270, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -22762,8 +22762,8 @@ }, "robot_15_03_glow_001.png": { "frame": { - "x": 1997, - "y": 1919, + "x": 2275, + "y": 1660, "w": 14, "h": 30 }, @@ -22782,18 +22782,18 @@ }, "robot_15_04_001.png": { "frame": { - "x": 1949, - "y": 1648, - "w": 32, - "h": 19 + "x": 1083, + "y": 2118, + "w": 34, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 32, - "h": 19 + "w": 34, + "h": 20 }, "sourceSize": { "w": 34, @@ -22802,18 +22802,18 @@ }, "robot_15_04_2_001.png": { "frame": { - "x": 435, - "y": 784, - "w": 11, - "h": 7 + "x": 693, + "y": 1174, + "w": 22, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 11, - "h": 7 + "w": 22, + "h": 12 }, "sourceSize": { "w": 22, @@ -22822,18 +22822,18 @@ }, "robot_15_04_glow_001.png": { "frame": { - "x": 1951, - "y": 738, - "w": 36, - "h": 23 + "x": 366, + "y": 2242, + "w": 38, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, - "h": 23 + "w": 38, + "h": 24 }, "sourceSize": { "w": 38, @@ -22842,18 +22842,18 @@ }, "robot_16_01_001.png": { "frame": { - "x": 1734, - "y": 338, - "w": 57, - "h": 54 + "x": 658, + "y": 1671, + "w": 66, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 57, - "h": 54 + "w": 66, + "h": 62 }, "sourceSize": { "w": 66, @@ -22862,18 +22862,18 @@ }, "robot_16_01_2_001.png": { "frame": { - "x": 554, - "y": 1800, - "w": 55, - "h": 51 + "x": 1745, + "y": 1472, + "w": 64, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 55, - "h": 51 + "w": 64, + "h": 58 }, "sourceSize": { "w": 64, @@ -22882,17 +22882,17 @@ }, "robot_16_01_extra_001.png": { "frame": { - "x": 1439, - "y": 1827, - "w": 24, + "x": 149, + "y": 818, + "w": 60, "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 36, + "x": 0, "y": 0, - "w": 24, + "w": 60, "h": 8 }, "sourceSize": { @@ -22902,18 +22902,18 @@ }, "robot_16_01_glow_001.png": { "frame": { - "x": 1047, - "y": 1435, - "w": 61, - "h": 58 + "x": 1491, + "y": 1083, + "w": 70, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 61, - "h": 58 + "w": 70, + "h": 66 }, "sourceSize": { "w": 70, @@ -22922,18 +22922,18 @@ }, "robot_16_02_001.png": { "frame": { - "x": 1687, - "y": 1966, - "w": 19, - "h": 27 + "x": 2269, + "y": 1878, + "w": 20, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 19, - "h": 27 + "w": 20, + "h": 28 }, "sourceSize": { "w": 20, @@ -22942,8 +22942,8 @@ }, "robot_16_02_2_001.png": { "frame": { - "x": 519, - "y": 449, + "x": 1097, + "y": 939, "w": 2, "h": 2 }, @@ -22962,18 +22962,18 @@ }, "robot_16_02_glow_001.png": { "frame": { - "x": 1976, - "y": 1668, - "w": 23, - "h": 31 + "x": 1699, + "y": 2278, + "w": 24, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 23, - "h": 31 + "w": 24, + "h": 32 }, "sourceSize": { "w": 24, @@ -22982,8 +22982,8 @@ }, "robot_16_03_001.png": { "frame": { - "x": 64, - "y": 1994, + "x": 1692, + "y": 894, "w": 10, "h": 26 }, @@ -23002,8 +23002,8 @@ }, "robot_16_03_2_001.png": { "frame": { - "x": 656, - "y": 657, + "x": 1201, + "y": 153, "w": 2, "h": 2 }, @@ -23022,8 +23022,8 @@ }, "robot_16_03_glow_001.png": { "frame": { - "x": 1997, - "y": 1950, + "x": 2290, + "y": 1131, "w": 14, "h": 30 }, @@ -23042,18 +23042,18 @@ }, "robot_16_04_001.png": { "frame": { - "x": 1582, - "y": 732, + "x": 1715, + "y": 1986, "w": 26, - "h": 19 + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 19 + "h": 20 }, "sourceSize": { "w": 26, @@ -23062,18 +23062,18 @@ }, "robot_16_04_2_001.png": { "frame": { - "x": 1198, - "y": 1799, + "x": 359, + "y": 1249, "w": 24, - "h": 16 + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 24, - "h": 16 + "h": 18 }, "sourceSize": { "w": 24, @@ -23082,18 +23082,18 @@ }, "robot_16_04_glow_001.png": { "frame": { - "x": 1147, - "y": 1970, + "x": 2282, + "y": 1162, "w": 30, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 30, - "h": 23 + "h": 24 }, "sourceSize": { "w": 30, @@ -23102,18 +23102,18 @@ }, "robot_17_01_001.png": { "frame": { - "x": 1231, - "y": 447, - "w": 65, - "h": 66 + "x": 1149, + "y": 1150, + "w": 68, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 65, - "h": 66 + "w": 68, + "h": 74 }, "sourceSize": { "w": 68, @@ -23122,18 +23122,18 @@ }, "robot_17_01_2_001.png": { "frame": { - "x": 1363, - "y": 0, - "w": 63, - "h": 60 + "x": 0, + "y": 1269, + "w": 68, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 60 + "w": 68, + "h": 74 }, "sourceSize": { "w": 68, @@ -23142,18 +23142,18 @@ }, "robot_17_01_extra_001.png": { "frame": { - "x": 1988, - "y": 189, - "w": 24, - "h": 30 + "x": 1981, + "y": 2113, + "w": 56, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 32, - "y": 16, - "w": 24, - "h": 30 + "x": 0, + "y": 0, + "w": 56, + "h": 46 }, "sourceSize": { "w": 56, @@ -23162,18 +23162,18 @@ }, "robot_17_01_glow_001.png": { "frame": { - "x": 994, - "y": 1065, - "w": 69, - "h": 70 + "x": 489, + "y": 1057, + "w": 72, + "h": 78 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 69, - "h": 70 + "w": 72, + "h": 78 }, "sourceSize": { "w": 72, @@ -23182,18 +23182,18 @@ }, "robot_17_02_001.png": { "frame": { - "x": 1988, - "y": 64, + "x": 1704, + "y": 2241, "w": 24, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 24, - "h": 31 + "h": 32 }, "sourceSize": { "w": 24, @@ -23202,10 +23202,10 @@ }, "robot_17_02_2_001.png": { "frame": { - "x": 1373, - "y": 1870, + "x": 1548, + "y": 1927, "w": 10, - "h": 9 + "h": 16 }, "rotated": false, "trimmed": true, @@ -23213,7 +23213,7 @@ "x": 0, "y": 0, "w": 10, - "h": 9 + "h": 16 }, "sourceSize": { "w": 10, @@ -23222,18 +23222,18 @@ }, "robot_17_02_glow_001.png": { "frame": { - "x": 1949, - "y": 1266, + "x": 800, + "y": 2278, "w": 28, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 28, - "h": 35 + "h": 36 }, "sourceSize": { "w": 28, @@ -23242,8 +23242,8 @@ }, "robot_17_03_001.png": { "frame": { - "x": 75, - "y": 1994, + "x": 1871, + "y": 1475, "w": 10, "h": 26 }, @@ -23262,8 +23262,8 @@ }, "robot_17_03_2_001.png": { "frame": { - "x": 812, - "y": 462, + "x": 879, + "y": 777, "w": 2, "h": 2 }, @@ -23282,8 +23282,8 @@ }, "robot_17_03_glow_001.png": { "frame": { - "x": 1344, - "y": 1111, + "x": 2290, + "y": 1187, "w": 14, "h": 30 }, @@ -23302,18 +23302,18 @@ }, "robot_17_04_001.png": { "frame": { - "x": 680, - "y": 1987, + "x": 434, + "y": 2062, "w": 26, - "h": 19 + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 19 + "h": 20 }, "sourceSize": { "w": 26, @@ -23322,18 +23322,18 @@ }, "robot_17_04_2_001.png": { "frame": { - "x": 792, - "y": 2004, + "x": 340, + "y": 2064, "w": 24, - "h": 16 + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 24, - "h": 16 + "h": 18 }, "sourceSize": { "w": 24, @@ -23342,18 +23342,18 @@ }, "robot_17_04_glow_001.png": { "frame": { - "x": 1887, - "y": 1970, + "x": 2280, + "y": 1218, "w": 30, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 30, - "h": 23 + "h": 24 }, "sourceSize": { "w": 30, @@ -23362,18 +23362,18 @@ }, "robot_18_01_001.png": { "frame": { - "x": 1363, - "y": 61, - "w": 63, - "h": 45 + "x": 1753, + "y": 1055, + "w": 64, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 45 + "w": 64, + "h": 48 }, "sourceSize": { "w": 64, @@ -23382,18 +23382,18 @@ }, "robot_18_01_2_001.png": { "frame": { - "x": 1307, - "y": 1247, - "w": 53, - "h": 25 + "x": 1841, + "y": 1831, + "w": 60, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 53, - "h": 25 + "w": 60, + "h": 28 }, "sourceSize": { "w": 60, @@ -23402,18 +23402,18 @@ }, "robot_18_01_glow_001.png": { "frame": { - "x": 1160, - "y": 304, - "w": 67, - "h": 49 + "x": 1497, + "y": 1221, + "w": 68, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 67, - "h": 49 + "w": 68, + "h": 52 }, "sourceSize": { "w": 68, @@ -23422,18 +23422,18 @@ }, "robot_18_02_001.png": { "frame": { - "x": 593, - "y": 1928, - "w": 27, - "h": 41 + "x": 821, + "y": 2140, + "w": 28, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 27, - "h": 41 + "w": 28, + "h": 52 }, "sourceSize": { "w": 28, @@ -23442,10 +23442,10 @@ }, "robot_18_02_2_001.png": { "frame": { - "x": 1887, - "y": 1930, + "x": 770, + "y": 345, "w": 22, - "h": 39 + "h": 48 }, "rotated": false, "trimmed": true, @@ -23453,7 +23453,7 @@ "x": 0, "y": 0, "w": 22, - "h": 39 + "h": 48 }, "sourceSize": { "w": 22, @@ -23462,18 +23462,18 @@ }, "robot_18_02_glow_001.png": { "frame": { - "x": 1192, - "y": 1124, - "w": 31, - "h": 45 + "x": 1382, + "y": 1418, + "w": 32, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 31, - "h": 45 + "w": 32, + "h": 56 }, "sourceSize": { "w": 32, @@ -23482,10 +23482,10 @@ }, "robot_18_03_001.png": { "frame": { - "x": 708, - "y": 316, + "x": 1885, + "y": 2243, "w": 8, - "h": 25 + "h": 26 }, "rotated": false, "trimmed": true, @@ -23493,7 +23493,7 @@ "x": 0, "y": 0, "w": 8, - "h": 25 + "h": 26 }, "sourceSize": { "w": 8, @@ -23502,8 +23502,8 @@ }, "robot_18_03_2_001.png": { "frame": { - "x": 816, - "y": 979, + "x": 1279, + "y": 169, "w": 2, "h": 2 }, @@ -23522,10 +23522,10 @@ }, "robot_18_03_glow_001.png": { "frame": { - "x": 448, - "y": 275, + "x": 2052, + "y": 1875, "w": 12, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, @@ -23533,7 +23533,7 @@ "x": 0, "y": 0, "w": 12, - "h": 29 + "h": 30 }, "sourceSize": { "w": 12, @@ -23542,17 +23542,17 @@ }, "robot_18_04_001.png": { "frame": { - "x": 1201, - "y": 1107, - "w": 29, + "x": 1392, + "y": 1927, + "w": 30, "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 29, + "w": 30, "h": 16 }, "sourceSize": { @@ -23562,9 +23562,9 @@ }, "robot_18_04_2_001.png": { "frame": { - "x": 638, - "y": 1310, - "w": 20, + "x": 859, + "y": 217, + "w": 24, "h": 12 }, "rotated": false, @@ -23572,7 +23572,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 20, + "w": 24, "h": 12 }, "sourceSize": { @@ -23582,17 +23582,17 @@ }, "robot_18_04_glow_001.png": { "frame": { - "x": 1548, - "y": 732, - "w": 33, + "x": 640, + "y": 78, + "w": 34, "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 33, + "w": 34, "h": 20 }, "sourceSize": { @@ -23602,18 +23602,18 @@ }, "robot_19_01_001.png": { "frame": { - "x": 272, - "y": 314, - "w": 88, - "h": 54 + "x": 0, + "y": 65, + "w": 112, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 88, - "h": 54 + "w": 112, + "h": 58 }, "sourceSize": { "w": 112, @@ -23622,18 +23622,18 @@ }, "robot_19_01_2_001.png": { "frame": { - "x": 1298, - "y": 59, - "w": 64, - "h": 47 + "x": 1566, + "y": 1179, + "w": 68, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 64, - "h": 47 + "w": 68, + "h": 48 }, "sourceSize": { "w": 68, @@ -23642,18 +23642,18 @@ }, "robot_19_01_glow_001.png": { "frame": { - "x": 202, + "x": 0, "y": 0, - "w": 92, - "h": 59 + "w": 116, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 92, - "h": 59 + "w": 116, + "h": 64 }, "sourceSize": { "w": 116, @@ -23662,9 +23662,9 @@ }, "robot_19_02_001.png": { "frame": { - "x": 1205, - "y": 1968, - "w": 24, + "x": 2280, + "y": 1243, + "w": 30, "h": 26 }, "rotated": false, @@ -23672,7 +23672,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, + "w": 30, "h": 26 }, "sourceSize": { @@ -23682,18 +23682,18 @@ }, "robot_19_02_2_001.png": { "frame": { - "x": 1080, - "y": 497, - "w": 9, - "h": 15 + "x": 1483, + "y": 1927, + "w": 28, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 9, - "h": 15 + "y": 0, + "w": 28, + "h": 16 }, "sourceSize": { "w": 28, @@ -23702,9 +23702,9 @@ }, "robot_19_02_glow_001.png": { "frame": { - "x": 1983, - "y": 1108, - "w": 28, + "x": 1068, + "y": 2243, + "w": 34, "h": 30 }, "rotated": false, @@ -23712,7 +23712,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, + "w": 34, "h": 30 }, "sourceSize": { @@ -23722,8 +23722,8 @@ }, "robot_19_03_001.png": { "frame": { - "x": 86, - "y": 1994, + "x": 1932, + "y": 1530, "w": 10, "h": 26 }, @@ -23742,8 +23742,8 @@ }, "robot_19_03_2_001.png": { "frame": { - "x": 892, - "y": 865, + "x": 1235, + "y": 1460, "w": 2, "h": 2 }, @@ -23762,8 +23762,8 @@ }, "robot_19_03_glow_001.png": { "frame": { - "x": 1887, - "y": 1445, + "x": 2290, + "y": 1270, "w": 14, "h": 30 }, @@ -23782,17 +23782,17 @@ }, "robot_19_04_001.png": { "frame": { - "x": 1981, - "y": 981, - "w": 31, + "x": 1680, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 31, + "w": 34, "h": 18 }, "sourceSize": { @@ -23802,18 +23802,18 @@ }, "robot_19_04_2_001.png": { "frame": { - "x": 1628, - "y": 1920, - "w": 11, - "h": 9 + "x": 901, + "y": 531, + "w": 30, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 19, - "y": 5, - "w": 11, - "h": 9 + "x": 0, + "y": 0, + "w": 30, + "h": 14 }, "sourceSize": { "w": 30, @@ -23822,17 +23822,17 @@ }, "robot_19_04_glow_001.png": { "frame": { - "x": 1952, - "y": 507, - "w": 35, + "x": 1632, + "y": 2237, + "w": 38, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 35, + "w": 38, "h": 22 }, "sourceSize": { @@ -23842,18 +23842,18 @@ }, "robot_20_01_001.png": { "frame": { - "x": 224, - "y": 870, - "w": 73, - "h": 48 + "x": 562, + "y": 1063, + "w": 78, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 73, - "h": 48 + "w": 78, + "h": 58 }, "sourceSize": { "w": 78, @@ -23862,18 +23862,18 @@ }, "robot_20_01_2_001.png": { "frame": { - "x": 1160, - "y": 354, - "w": 67, - "h": 43 + "x": 238, + "y": 1130, + "w": 76, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 67, - "h": 43 + "w": 76, + "h": 52 }, "sourceSize": { "w": 76, @@ -23882,18 +23882,18 @@ }, "robot_20_01_glow_001.png": { "frame": { - "x": 634, - "y": 698, - "w": 77, - "h": 52 - }, - "rotated": false, + "x": 958, + "y": 319, + "w": 82, + "h": 62 + }, + "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 77, - "h": 52 + "w": 82, + "h": 62 }, "sourceSize": { "w": 82, @@ -23902,9 +23902,9 @@ }, "robot_20_02_001.png": { "frame": { - "x": 1987, - "y": 1328, - "w": 22, + "x": 2287, + "y": 1907, + "w": 24, "h": 28 }, "rotated": false, @@ -23912,7 +23912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 22, + "w": 24, "h": 28 }, "sourceSize": { @@ -23922,18 +23922,18 @@ }, "robot_20_02_2_001.png": { "frame": { - "x": 1272, - "y": 1994, - "w": 19, - "h": 19 + "x": 1313, + "y": 2060, + "w": 20, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, - "h": 19 + "w": 20, + "h": 20 }, "sourceSize": { "w": 20, @@ -23942,9 +23942,9 @@ }, "robot_20_02_glow_001.png": { "frame": { - "x": 1949, - "y": 1668, - "w": 26, + "x": 1724, + "y": 2278, + "w": 28, "h": 32 }, "rotated": false, @@ -23952,7 +23952,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 26, + "w": 28, "h": 32 }, "sourceSize": { @@ -23962,8 +23962,8 @@ }, "robot_20_03_001.png": { "frame": { - "x": 707, - "y": 1994, + "x": 1993, + "y": 1580, "w": 10, "h": 26 }, @@ -23982,18 +23982,18 @@ }, "robot_20_03_2_001.png": { "frame": { - "x": 1974, - "y": 1046, + "x": 2303, + "y": 413, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -24002,8 +24002,8 @@ }, "robot_20_03_glow_001.png": { "frame": { - "x": 1367, - "y": 1839, + "x": 2290, + "y": 1301, "w": 14, "h": 30 }, @@ -24022,17 +24022,17 @@ }, "robot_20_04_001.png": { "frame": { - "x": 1950, - "y": 1247, - "w": 31, + "x": 78, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 31, + "w": 34, "h": 18 }, "sourceSize": { @@ -24042,18 +24042,18 @@ }, "robot_20_04_2_001.png": { "frame": { - "x": 280, - "y": 859, - "w": 17, - "h": 10 + "x": 1423, + "y": 1927, + "w": 30, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 17, - "h": 10 + "x": 0, + "y": 0, + "w": 30, + "h": 16 }, "sourceSize": { "w": 30, @@ -24062,17 +24062,17 @@ }, "robot_20_04_glow_001.png": { "frame": { - "x": 1156, - "y": 1855, - "w": 35, + "x": 399, + "y": 2277, + "w": 38, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 35, + "w": 38, "h": 22 }, "sourceSize": { @@ -24082,18 +24082,18 @@ }, "robot_21_01_001.png": { "frame": { - "x": 1732, - "y": 393, - "w": 57, - "h": 52 + "x": 2066, + "y": 969, + "w": 58, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 57, - "h": 52 + "w": 58, + "h": 56 }, "sourceSize": { "w": 58, @@ -24102,18 +24102,18 @@ }, "robot_21_01_2_001.png": { "frame": { - "x": 610, - "y": 1800, - "w": 55, - "h": 42 + "x": 2066, + "y": 1026, + "w": 58, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 55, - "h": 42 + "w": 58, + "h": 54 }, "sourceSize": { "w": 58, @@ -24122,18 +24122,18 @@ }, "robot_21_01_glow_001.png": { "frame": { - "x": 1109, - "y": 1435, - "w": 61, - "h": 56 + "x": 1820, + "y": 543, + "w": 62, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 61, - "h": 56 + "w": 62, + "h": 60 }, "sourceSize": { "w": 62, @@ -24142,9 +24142,9 @@ }, "robot_21_02_001.png": { "frame": { - "x": 1230, - "y": 1994, - "w": 19, + "x": 2287, + "y": 2073, + "w": 20, "h": 26 }, "rotated": false, @@ -24152,7 +24152,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -24162,10 +24162,10 @@ }, "robot_21_02_2_001.png": { "frame": { - "x": 1772, - "y": 1683, + "x": 928, + "y": 1451, "w": 16, - "h": 15 + "h": 24 }, "rotated": false, "trimmed": true, @@ -24173,7 +24173,7 @@ "x": 0, "y": 0, "w": 16, - "h": 15 + "h": 24 }, "sourceSize": { "w": 16, @@ -24182,9 +24182,9 @@ }, "robot_21_02_glow_001.png": { "frame": { - "x": 1988, - "y": 636, - "w": 23, + "x": 2288, + "y": 217, + "w": 24, "h": 30 }, "rotated": false, @@ -24192,7 +24192,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -24202,8 +24202,8 @@ }, "robot_21_03_001.png": { "frame": { - "x": 97, - "y": 1994, + "x": 1440, + "y": 2081, "w": 10, "h": 26 }, @@ -24222,18 +24222,18 @@ }, "robot_21_03_2_001.png": { "frame": { - "x": 1988, - "y": 1911, + "x": 2303, + "y": 936, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -24242,8 +24242,8 @@ }, "robot_21_03_glow_001.png": { "frame": { - "x": 1980, - "y": 1880, + "x": 2290, + "y": 1332, "w": 14, "h": 30 }, @@ -24262,17 +24262,17 @@ }, "robot_21_04_001.png": { "frame": { - "x": 1138, - "y": 1799, - "w": 30, + "x": 113, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 30, + "w": 34, "h": 18 }, "sourceSize": { @@ -24282,18 +24282,18 @@ }, "robot_21_04_2_001.png": { "frame": { - "x": 1216, - "y": 755, - "w": 14, - "h": 12 + "x": 1359, + "y": 1927, + "w": 32, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 18, - "y": 4, - "w": 14, - "h": 12 + "x": 0, + "y": 0, + "w": 32, + "h": 16 }, "sourceSize": { "w": 32, @@ -24302,17 +24302,17 @@ }, "robot_21_04_glow_001.png": { "frame": { - "x": 1226, - "y": 1855, - "w": 33, + "x": 829, + "y": 2242, + "w": 36, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 33, + "w": 36, "h": 22 }, "sourceSize": { @@ -24322,18 +24322,18 @@ }, "robot_22_01_001.png": { "frame": { - "x": 1670, - "y": 1159, - "w": 59, - "h": 49 + "x": 610, + "y": 2007, + "w": 60, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 59, - "h": 49 + "x": 0, + "y": 0, + "w": 60, + "h": 50 }, "sourceSize": { "w": 60, @@ -24342,18 +24342,18 @@ }, "robot_22_01_2_001.png": { "frame": { - "x": 0, - "y": 1891, - "w": 51, - "h": 32 + "x": 2182, + "y": 915, + "w": 54, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 51, - "h": 32 + "w": 54, + "h": 40 }, "sourceSize": { "w": 54, @@ -24362,18 +24362,18 @@ }, "robot_22_01_glow_001.png": { "frame": { - "x": 632, - "y": 1323, - "w": 63, - "h": 53 + "x": 1745, + "y": 1531, + "w": 64, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 63, - "h": 53 + "x": 0, + "y": 0, + "w": 64, + "h": 54 }, "sourceSize": { "w": 64, @@ -24382,10 +24382,10 @@ }, "robot_22_02_001.png": { "frame": { - "x": 1982, - "y": 1518, + "x": 2290, + "y": 1363, "w": 22, - "h": 28 + "h": 30 }, "rotated": false, "trimmed": true, @@ -24393,7 +24393,7 @@ "x": 0, "y": 0, "w": 22, - "h": 28 + "h": 30 }, "sourceSize": { "w": 22, @@ -24402,10 +24402,10 @@ }, "robot_22_02_2_001.png": { "frame": { - "x": 924, - "y": 777, + "x": 1408, + "y": 770, "w": 12, - "h": 26 + "h": 28 }, "rotated": false, "trimmed": true, @@ -24413,7 +24413,7 @@ "x": 0, "y": 0, "w": 12, - "h": 26 + "h": 28 }, "sourceSize": { "w": 12, @@ -24422,10 +24422,10 @@ }, "robot_22_02_glow_001.png": { "frame": { - "x": 1953, - "y": 318, + "x": 829, + "y": 2278, "w": 26, - "h": 34 + "h": 36 }, "rotated": false, "trimmed": true, @@ -24433,7 +24433,7 @@ "x": 0, "y": 0, "w": 26, - "h": 34 + "h": 36 }, "sourceSize": { "w": 26, @@ -24442,8 +24442,8 @@ }, "robot_22_03_001.png": { "frame": { - "x": 718, - "y": 1994, + "x": 2278, + "y": 1390, "w": 10, "h": 26 }, @@ -24462,8 +24462,8 @@ }, "robot_22_03_2_001.png": { "frame": { - "x": 812, - "y": 520, + "x": 360, + "y": 1447, "w": 2, "h": 2 }, @@ -24482,8 +24482,8 @@ }, "robot_22_03_glow_001.png": { "frame": { - "x": 1344, - "y": 1142, + "x": 2290, + "y": 1394, "w": 14, "h": 30 }, @@ -24502,18 +24502,18 @@ }, "robot_22_04_001.png": { "frame": { - "x": 1983, - "y": 1158, - "w": 29, - "h": 19 + "x": 787, + "y": 1650, + "w": 32, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 29, - "h": 19 + "w": 32, + "h": 20 }, "sourceSize": { "w": 32, @@ -24522,18 +24522,18 @@ }, "robot_22_04_2_001.png": { "frame": { - "x": 806, - "y": 1183, - "w": 11, - "h": 11 + "x": 1512, + "y": 1927, + "w": 26, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 11, - "h": 11 + "y": 0, + "w": 26, + "h": 16 }, "sourceSize": { "w": 26, @@ -24542,18 +24542,18 @@ }, "robot_22_04_glow_001.png": { "frame": { - "x": 1952, - "y": 553, - "w": 33, - "h": 23 + "x": 481, + "y": 2242, + "w": 36, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 33, - "h": 23 + "w": 36, + "h": 24 }, "sourceSize": { "w": 36, @@ -24562,18 +24562,18 @@ }, "robot_23_01_001.png": { "frame": { - "x": 1275, - "y": 1683, - "w": 58, - "h": 50 + "x": 1820, + "y": 604, + "w": 62, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 58, - "h": 50 + "w": 62, + "h": 52 }, "sourceSize": { "w": 62, @@ -24582,18 +24582,18 @@ }, "robot_23_01_2_001.png": { "frame": { - "x": 928, - "y": 1799, - "w": 55, - "h": 46 + "x": 671, + "y": 2007, + "w": 60, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 55, - "h": 46 + "w": 60, + "h": 48 }, "sourceSize": { "w": 60, @@ -24602,18 +24602,18 @@ }, "robot_23_01_glow_001.png": { "frame": { - "x": 1424, - "y": 1244, - "w": 62, - "h": 55 + "x": 553, + "y": 1611, + "w": 66, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 62, - "h": 55 + "w": 66, + "h": 58 }, "sourceSize": { "w": 66, @@ -24622,9 +24622,9 @@ }, "robot_23_02_001.png": { "frame": { - "x": 856, - "y": 1967, - "w": 27, + "x": 2283, + "y": 2199, + "w": 28, "h": 26 }, "rotated": false, @@ -24632,7 +24632,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 27, + "w": 28, "h": 26 }, "sourceSize": { @@ -24642,18 +24642,18 @@ }, "robot_23_02_2_001.png": { "frame": { - "x": 1167, - "y": 1124, + "x": 2275, + "y": 1934, "w": 10, - "h": 10 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 14, + "y": 0, "w": 10, - "h": 10 + "h": 24 }, "sourceSize": { "w": 10, @@ -24662,9 +24662,9 @@ }, "robot_23_02_glow_001.png": { "frame": { - "x": 1080, - "y": 1963, - "w": 31, + "x": 1753, + "y": 2278, + "w": 32, "h": 30 }, "rotated": false, @@ -24672,7 +24672,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 31, + "w": 32, "h": 30 }, "sourceSize": { @@ -24682,8 +24682,8 @@ }, "robot_23_03_001.png": { "frame": { - "x": 1250, - "y": 1994, + "x": 2275, + "y": 1907, "w": 10, "h": 26 }, @@ -24702,8 +24702,8 @@ }, "robot_23_03_2_001.png": { "frame": { - "x": 739, - "y": 1199, + "x": 1242, + "y": 1610, "w": 2, "h": 2 }, @@ -24722,8 +24722,8 @@ }, "robot_23_03_glow_001.png": { "frame": { - "x": 610, - "y": 1501, + "x": 2290, + "y": 1425, "w": 14, "h": 30 }, @@ -24742,18 +24742,18 @@ }, "robot_23_04_001.png": { "frame": { - "x": 1786, - "y": 1415, - "w": 33, - "h": 20 + "x": 518, + "y": 2242, + "w": 36, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 33, - "h": 20 + "w": 36, + "h": 22 }, "sourceSize": { "w": 36, @@ -24762,18 +24762,18 @@ }, "robot_23_04_2_001.png": { "frame": { - "x": 532, - "y": 332, - "w": 12, - "h": 16 + "x": 1966, + "y": 2178, + "w": 14, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 12, - "h": 16 + "w": 14, + "h": 18 }, "sourceSize": { "w": 14, @@ -24782,18 +24782,18 @@ }, "robot_23_04_glow_001.png": { "frame": { - "x": 275, - "y": 1800, - "w": 37, - "h": 24 + "x": 578, + "y": 2238, + "w": 40, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 37, - "h": 24 + "w": 40, + "h": 26 }, "sourceSize": { "w": 40, @@ -24802,18 +24802,18 @@ }, "robot_24_01_001.png": { "frame": { - "x": 861, - "y": 1195, - "w": 55, - "h": 59 + "x": 1491, + "y": 1150, + "w": 64, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 55, - "h": 59 + "w": 64, + "h": 70 }, "sourceSize": { "w": 64, @@ -24822,18 +24822,18 @@ }, "robot_24_01_2_001.png": { "frame": { - "x": 374, - "y": 1891, - "w": 43, - "h": 34 - }, - "rotated": false, + "x": 732, + "y": 2007, + "w": 60, + "h": 38 + }, + "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, - "y": 4, - "w": 43, - "h": 34 + "x": 0, + "y": 0, + "w": 60, + "h": 38 }, "sourceSize": { "w": 60, @@ -24842,18 +24842,18 @@ }, "robot_24_01_glow_001.png": { "frame": { - "x": 1358, - "y": 447, - "w": 59, - "h": 63 + "x": 69, + "y": 1269, + "w": 68, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 59, - "h": 63 + "w": 68, + "h": 74 }, "sourceSize": { "w": 68, @@ -24862,9 +24862,9 @@ }, "robot_24_02_001.png": { "frame": { - "x": 108, - "y": 1994, - "w": 19, + "x": 2287, + "y": 2100, + "w": 20, "h": 26 }, "rotated": false, @@ -24872,7 +24872,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, + "w": 20, "h": 26 }, "sourceSize": { @@ -24882,10 +24882,10 @@ }, "robot_24_02_2_001.png": { "frame": { - "x": 542, - "y": 1928, + "x": 1032, + "y": 300, "w": 8, - "h": 8 + "h": 16 }, "rotated": false, "trimmed": true, @@ -24893,7 +24893,7 @@ "x": 0, "y": 0, "w": 8, - "h": 8 + "h": 16 }, "sourceSize": { "w": 8, @@ -24902,9 +24902,9 @@ }, "robot_24_02_glow_001.png": { "frame": { - "x": 1988, - "y": 220, - "w": 23, + "x": 2288, + "y": 248, + "w": 24, "h": 30 }, "rotated": false, @@ -24912,7 +24912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 30 }, "sourceSize": { @@ -24922,8 +24922,8 @@ }, "robot_24_03_001.png": { "frame": { - "x": 729, - "y": 1994, + "x": 317, + "y": 129, "w": 10, "h": 26 }, @@ -24942,18 +24942,18 @@ }, "robot_24_03_2_001.png": { "frame": { - "x": 439, - "y": 275, + "x": 942, + "y": 1840, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -24962,8 +24962,8 @@ }, "robot_24_03_glow_001.png": { "frame": { - "x": 1980, - "y": 251, + "x": 2290, + "y": 1456, "w": 14, "h": 30 }, @@ -24982,8 +24982,8 @@ }, "robot_24_04_001.png": { "frame": { - "x": 1982, - "y": 1547, + "x": 419, + "y": 1988, "w": 28, "h": 18 }, @@ -25002,18 +25002,18 @@ }, "robot_24_04_2_001.png": { "frame": { - "x": 982, - "y": 1548, - "w": 6, - "h": 6 + "x": 1174, + "y": 942, + "w": 10, + "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 6, - "h": 6 + "y": 0, + "w": 10, + "h": 8 }, "sourceSize": { "w": 10, @@ -25022,8 +25022,8 @@ }, "robot_24_04_glow_001.png": { "frame": { - "x": 1948, - "y": 1701, + "x": 1786, + "y": 2278, "w": 32, "h": 22 }, @@ -25042,18 +25042,18 @@ }, "robot_25_01_001.png": { "frame": { - "x": 1363, - "y": 107, - "w": 63, - "h": 45 + "x": 414, + "y": 1611, + "w": 66, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 45 + "w": 66, + "h": 50 }, "sourceSize": { "w": 66, @@ -25062,9 +25062,9 @@ }, "robot_25_01_2_001.png": { "frame": { - "x": 1159, - "y": 1646, - "w": 59, + "x": 732, + "y": 2046, + "w": 60, "h": 34 }, "rotated": false, @@ -25072,7 +25072,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 59, + "w": 60, "h": 34 }, "sourceSize": { @@ -25082,18 +25082,18 @@ }, "robot_25_01_glow_001.png": { "frame": { - "x": 1160, - "y": 398, - "w": 67, - "h": 49 + "x": 1426, + "y": 1221, + "w": 70, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 67, - "h": 49 + "w": 70, + "h": 54 }, "sourceSize": { "w": 70, @@ -25102,10 +25102,10 @@ }, "robot_25_02_001.png": { "frame": { - "x": 473, - "y": 1966, + "x": 2290, + "y": 1878, "w": 22, - "h": 27 + "h": 28 }, "rotated": false, "trimmed": true, @@ -25113,7 +25113,7 @@ "x": 0, "y": 0, "w": 22, - "h": 27 + "h": 28 }, "sourceSize": { "w": 22, @@ -25122,10 +25122,10 @@ }, "robot_25_02_2_001.png": { "frame": { - "x": 856, - "y": 2004, + "x": 2286, + "y": 386, "w": 20, - "h": 16 + "h": 26 }, "rotated": false, "trimmed": true, @@ -25133,7 +25133,7 @@ "x": 0, "y": 0, "w": 20, - "h": 16 + "h": 26 }, "sourceSize": { "w": 20, @@ -25142,10 +25142,10 @@ }, "robot_25_02_glow_001.png": { "frame": { - "x": 1986, - "y": 799, + "x": 1800, + "y": 2243, "w": 26, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, @@ -25153,7 +25153,7 @@ "x": 0, "y": 0, "w": 26, - "h": 31 + "h": 32 }, "sourceSize": { "w": 26, @@ -25162,8 +25162,8 @@ }, "robot_25_03_001.png": { "frame": { - "x": 1261, - "y": 1994, + "x": 1871, + "y": 1502, "w": 10, "h": 26 }, @@ -25182,18 +25182,18 @@ }, "robot_25_03_2_001.png": { "frame": { - "x": 1978, - "y": 1268, + "x": 2280, + "y": 1295, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -25202,8 +25202,8 @@ }, "robot_25_03_glow_001.png": { "frame": { - "x": 1016, - "y": 1891, + "x": 2290, + "y": 1487, "w": 14, "h": 30 }, @@ -25222,17 +25222,17 @@ }, "robot_25_04_001.png": { "frame": { - "x": 1106, - "y": 1799, - "w": 31, + "x": 148, + "y": 1988, + "w": 34, "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 31, + "w": 34, "h": 18 }, "sourceSize": { @@ -25242,18 +25242,18 @@ }, "robot_25_04_2_001.png": { "frame": { - "x": 1149, - "y": 537, - "w": 9, - "h": 10 + "x": 1267, + "y": 1723, + "w": 10, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, - "w": 9, - "h": 10 + "y": 0, + "w": 10, + "h": 14 }, "sourceSize": { "w": 10, @@ -25262,17 +25262,17 @@ }, "robot_25_04_glow_001.png": { "frame": { - "x": 1952, - "y": 530, - "w": 35, + "x": 405, + "y": 2242, + "w": 38, "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 35, + "w": 38, "h": 22 }, "sourceSize": { @@ -25282,18 +25282,18 @@ }, "robot_26_01_001.png": { "frame": { - "x": 1247, - "y": 1267, - "w": 59, - "h": 64 + "x": 1491, + "y": 1276, + "w": 70, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, + "x": 0, "y": 0, - "w": 59, - "h": 64 + "w": 70, + "h": 70 }, "sourceSize": { "w": 70, @@ -25302,18 +25302,18 @@ }, "robot_26_01_2_001.png": { "frame": { - "x": 1433, - "y": 1300, - "w": 42, - "h": 52 + "x": 1349, + "y": 1546, + "w": 68, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, + "x": 0, "y": 0, - "w": 42, - "h": 52 + "w": 68, + "h": 66 }, "sourceSize": { "w": 68, @@ -25322,18 +25322,18 @@ }, "robot_26_01_glow_001.png": { "frame": { - "x": 919, - "y": 1118, - "w": 63, - "h": 68 + "x": 138, + "y": 1269, + "w": 74, + "h": 74 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, + "x": 0, "y": 0, - "w": 63, - "h": 68 + "w": 74, + "h": 74 }, "sourceSize": { "w": 74, @@ -25342,18 +25342,18 @@ }, "robot_26_02_001.png": { "frame": { - "x": 1947, - "y": 1852, + "x": 1103, + "y": 2243, "w": 24, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 24, - "h": 33 + "h": 34 }, "sourceSize": { "w": 24, @@ -25362,18 +25362,18 @@ }, "robot_26_02_2_001.png": { "frame": { - "x": 1987, - "y": 1268, + "x": 2290, + "y": 1518, "w": 22, - "h": 29 + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 22, - "h": 29 + "h": 30 }, "sourceSize": { "w": 22, @@ -25382,18 +25382,18 @@ }, "robot_26_02_glow_001.png": { "frame": { - "x": 418, - "y": 1891, + "x": 438, + "y": 2274, "w": 28, - "h": 37 + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 28, - "h": 37 + "h": 38 }, "sourceSize": { "w": 28, @@ -25402,8 +25402,8 @@ }, "robot_26_03_001.png": { "frame": { - "x": 128, - "y": 1994, + "x": 2278, + "y": 1417, "w": 10, "h": 26 }, @@ -25422,18 +25422,18 @@ }, "robot_26_03_2_001.png": { "frame": { - "x": 495, - "y": 1435, + "x": 2303, + "y": 438, "w": 8, - "h": 23 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 8, - "h": 23 + "h": 24 }, "sourceSize": { "w": 8, @@ -25442,8 +25442,8 @@ }, "robot_26_03_glow_001.png": { "frame": { - "x": 1772, - "y": 1652, + "x": 2290, + "y": 1549, "w": 14, "h": 30 }, @@ -25462,18 +25462,18 @@ }, "robot_26_04_001.png": { "frame": { - "x": 1983, - "y": 1178, - "w": 29, - "h": 16 + "x": 183, + "y": 1988, + "w": 32, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 2, - "w": 29, - "h": 16 + "x": 0, + "y": 0, + "w": 32, + "h": 18 }, "sourceSize": { "w": 32, @@ -25482,18 +25482,18 @@ }, "robot_26_04_2_001.png": { "frame": { - "x": 716, - "y": 1842, - "w": 19, - "h": 13 + "x": 2286, + "y": 919, + "w": 26, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 3, - "w": 19, - "h": 13 + "x": 0, + "y": 0, + "w": 26, + "h": 16 }, "sourceSize": { "w": 26, @@ -25502,18 +25502,18 @@ }, "robot_26_04_glow_001.png": { "frame": { - "x": 1260, - "y": 1855, - "w": 33, - "h": 20 + "x": 856, + "y": 2278, + "w": 36, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 2, - "w": 33, - "h": 20 + "x": 0, + "y": 0, + "w": 36, + "h": 22 }, "sourceSize": { "w": 36, @@ -25522,10 +25522,10 @@ }, "ship_01_001.png": { "frame": { - "x": 776, - "y": 777, + "x": 462, + "y": 1245, "w": 74, - "h": 45 + "h": 46 }, "rotated": false, "trimmed": true, @@ -25533,7 +25533,7 @@ "x": 0, "y": 0, "w": 74, - "h": 45 + "h": 46 }, "sourceSize": { "w": 74, @@ -25542,18 +25542,18 @@ }, "ship_01_2_001.png": { "frame": { - "x": 1488, - "y": 671, - "w": 47, - "h": 21 + "x": 1579, + "y": 2198, + "w": 52, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 47, - "h": 21 + "w": 52, + "h": 42 }, "sourceSize": { "w": 52, @@ -25562,10 +25562,10 @@ }, "ship_02_001.png": { "frame": { - "x": 308, - "y": 824, + "x": 693, + "y": 1251, "w": 74, - "h": 44 + "h": 46 }, "rotated": false, "trimmed": true, @@ -25573,7 +25573,7 @@ "x": 0, "y": 0, "w": 74, - "h": 44 + "h": 46 }, "sourceSize": { "w": 74, @@ -25582,18 +25582,18 @@ }, "ship_02_2_001.png": { "frame": { - "x": 1328, - "y": 1799, - "w": 55, - "h": 39 + "x": 1820, + "y": 657, + "w": 62, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 55, - "h": 39 + "w": 62, + "h": 40 }, "sourceSize": { "w": 62, @@ -25602,18 +25602,18 @@ }, "ship_03_001.png": { "frame": { - "x": 474, - "y": 102, - "w": 83, - "h": 45 + "x": 699, + "y": 733, + "w": 90, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 83, - "h": 45 + "w": 90, + "h": 46 }, "sourceSize": { "w": 90, @@ -25622,18 +25622,18 @@ }, "ship_03_2_001.png": { "frame": { - "x": 519, - "y": 427, - "w": 78, - "h": 21 + "x": 715, + "y": 233, + "w": 86, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 17, - "w": 78, - "h": 21 + "y": 0, + "w": 86, + "h": 38 }, "sourceSize": { "w": 86, @@ -25642,18 +25642,18 @@ }, "ship_04_001.png": { "frame": { - "x": 295, - "y": 36, - "w": 90, - "h": 45 + "x": 511, + "y": 649, + "w": 94, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 90, - "h": 45 + "y": 0, + "w": 94, + "h": 50 }, "sourceSize": { "w": 94, @@ -25662,18 +25662,18 @@ }, "ship_04_2_001.png": { "frame": { - "x": 75, - "y": 923, - "w": 72, - "h": 33 + "x": 958, + "y": 382, + "w": 82, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, - "w": 72, - "h": 33 + "y": 0, + "w": 82, + "h": 46 }, "sourceSize": { "w": 82, @@ -25682,18 +25682,18 @@ }, "ship_05_001.png": { "frame": { - "x": 413, - "y": 591, - "w": 80, - "h": 43 + "x": 327, + "y": 874, + "w": 84, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 80, - "h": 43 + "x": 0, + "y": 0, + "w": 84, + "h": 48 }, "sourceSize": { "w": 84, @@ -25702,18 +25702,18 @@ }, "ship_05_2_001.png": { "frame": { - "x": 1159, - "y": 448, - "w": 67, - "h": 34 - }, - "rotated": false, + "x": 947, + "y": 1330, + "w": 72, + "h": 44 + }, + "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, - "w": 67, - "h": 34 + "y": 0, + "w": 72, + "h": 44 }, "sourceSize": { "w": 72, @@ -25722,18 +25722,18 @@ }, "ship_06_001.png": { "frame": { - "x": 353, - "y": 369, - "w": 86, - "h": 47 + "x": 677, + "y": 345, + "w": 92, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 1, - "w": 86, - "h": 47 + "x": 0, + "y": 0, + "w": 92, + "h": 48 }, "sourceSize": { "w": 92, @@ -25742,17 +25742,17 @@ }, "ship_06_2_001.png": { "frame": { - "x": 83, - "y": 509, - "w": 82, + "x": 513, + "y": 831, + "w": 88, "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 82, + "w": 88, "h": 44 }, "sourceSize": { @@ -25762,18 +25762,18 @@ }, "ship_07_001.png": { "frame": { - "x": 166, - "y": 509, - "w": 82, - "h": 40 + "x": 604, + "y": 749, + "w": 90, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 82, - "h": 40 + "x": 0, + "y": 0, + "w": 90, + "h": 44 }, "sourceSize": { "w": 90, @@ -25782,8 +25782,8 @@ }, "ship_07_2_001.png": { "frame": { - "x": 1654, - "y": 1702, + "x": 1399, + "y": 2048, "w": 58, "h": 32 }, @@ -25802,18 +25802,18 @@ }, "ship_08_001.png": { "frame": { - "x": 471, - "y": 148, - "w": 83, - "h": 44 + "x": 695, + "y": 780, + "w": 90, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 83, - "h": 44 + "x": 0, + "y": 0, + "w": 90, + "h": 46 }, "sourceSize": { "w": 90, @@ -25822,18 +25822,18 @@ }, "ship_08_2_001.png": { "frame": { - "x": 318, - "y": 671, - "w": 78, - "h": 37 + "x": 802, + "y": 230, + "w": 84, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 78, - "h": 37 + "w": 84, + "h": 40 }, "sourceSize": { "w": 84, @@ -25842,18 +25842,18 @@ }, "ship_09_001.png": { "frame": { - "x": 89, - "y": 370, - "w": 87, - "h": 46 + "x": 695, + "y": 827, + "w": 88, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 87, - "h": 46 + "x": 0, + "y": 0, + "w": 88, + "h": 52 }, "sourceSize": { "w": 88, @@ -25862,18 +25862,18 @@ }, "ship_09_2_001.png": { "frame": { - "x": 349, - "y": 470, - "w": 83, - "h": 37 + "x": 412, + "y": 878, + "w": 84, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 11, - "w": 83, - "h": 37 + "x": 0, + "y": 0, + "w": 84, + "h": 48 }, "sourceSize": { "w": 84, @@ -25882,18 +25882,18 @@ }, "ship_10_001.png": { "frame": { - "x": 328, - "y": 597, - "w": 80, - "h": 47 + "x": 816, + "y": 491, + "w": 84, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 80, - "h": 47 + "x": 0, + "y": 0, + "w": 84, + "h": 54 }, "sourceSize": { "w": 84, @@ -25902,18 +25902,18 @@ }, "ship_10_2_001.png": { "frame": { - "x": 75, - "y": 825, - "w": 73, - "h": 32 + "x": 921, + "y": 1263, + "w": 74, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 20, - "w": 73, - "h": 32 + "x": 0, + "y": 0, + "w": 74, + "h": 52 }, "sourceSize": { "w": 74, @@ -25922,18 +25922,18 @@ }, "ship_11_001.png": { "frame": { - "x": 177, - "y": 369, - "w": 87, - "h": 45 + "x": 606, + "y": 639, + "w": 94, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 87, - "h": 45 + "x": 0, + "y": 0, + "w": 94, + "h": 54 }, "sourceSize": { "w": 94, @@ -25942,18 +25942,18 @@ }, "ship_11_2_001.png": { "frame": { - "x": 1671, - "y": 599, - "w": 60, - "h": 32 + "x": 947, + "y": 1375, + "w": 72, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 60, - "h": 32 + "y": 0, + "w": 72, + "h": 34 }, "sourceSize": { "w": 72, @@ -25962,18 +25962,18 @@ }, "ship_12_001.png": { "frame": { - "x": 559, - "y": 95, - "w": 81, - "h": 47 + "x": 366, + "y": 751, + "w": 88, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 81, - "h": 47 + "x": 0, + "y": 0, + "w": 88, + "h": 56 }, "sourceSize": { "w": 88, @@ -25982,18 +25982,18 @@ }, "ship_12_2_001.png": { "frame": { - "x": 1159, - "y": 483, - "w": 67, - "h": 35 + "x": 1491, + "y": 1347, + "w": 70, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 67, - "h": 35 + "y": 0, + "w": 70, + "h": 36 }, "sourceSize": { "w": 70, @@ -26002,18 +26002,18 @@ }, "ship_13_001.png": { "frame": { - "x": 397, - "y": 671, - "w": 78, - "h": 43 + "x": 958, + "y": 429, + "w": 82, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 78, - "h": 43 + "x": 0, + "y": 0, + "w": 82, + "h": 46 }, "sourceSize": { "w": 82, @@ -26022,18 +26022,18 @@ }, "ship_13_2_001.png": { "frame": { - "x": 555, - "y": 733, - "w": 76, - "h": 31 + "x": 1041, + "y": 362, + "w": 80, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 13, - "w": 76, - "h": 31 + "x": 0, + "y": 0, + "w": 80, + "h": 44 }, "sourceSize": { "w": 80, @@ -26042,18 +26042,18 @@ }, "ship_14_001.png": { "frame": { - "x": 315, - "y": 709, - "w": 77, - "h": 42 + "x": 1041, + "y": 407, + "w": 80, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 77, - "h": 42 + "x": 0, + "y": 0, + "w": 80, + "h": 50 }, "sourceSize": { "w": 80, @@ -26062,18 +26062,18 @@ }, "ship_14_2_001.png": { "frame": { - "x": 755, - "y": 427, - "w": 74, - "h": 34 + "x": 751, + "y": 1049, + "w": 78, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 74, - "h": 34 + "x": 0, + "y": 0, + "w": 78, + "h": 44 }, "sourceSize": { "w": 78, @@ -26082,18 +26082,18 @@ }, "ship_15_001.png": { "frame": { - "x": 642, - "y": 0, - "w": 80, - "h": 45 + "x": 794, + "y": 272, + "w": 86, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 80, - "h": 45 + "x": 0, + "y": 0, + "w": 86, + "h": 50 }, "sourceSize": { "w": 86, @@ -26102,18 +26102,18 @@ }, "ship_15_2_001.png": { "frame": { - "x": 224, - "y": 826, - "w": 73, - "h": 32 + "x": 958, + "y": 476, + "w": 82, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 73, - "h": 32 + "x": 0, + "y": 0, + "w": 82, + "h": 36 }, "sourceSize": { "w": 82, @@ -26122,18 +26122,18 @@ }, "ship_16_001.png": { "frame": { - "x": 265, - "y": 369, - "w": 87, - "h": 44 + "x": 149, + "y": 827, + "w": 90, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 87, - "h": 44 + "x": 0, + "y": 0, + "w": 90, + "h": 52 }, "sourceSize": { "w": 90, @@ -26142,18 +26142,18 @@ }, "ship_16_2_001.png": { "frame": { - "x": 172, - "y": 468, - "w": 84, - "h": 37 + "x": 275, + "y": 708, + "w": 88, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 84, - "h": 37 + "x": 0, + "y": 0, + "w": 88, + "h": 40 }, "sourceSize": { "w": 88, @@ -26162,9 +26162,9 @@ }, "ship_17_001.png": { "frame": { - "x": 386, + "x": 798, "y": 0, - "w": 87, + "w": 88, "h": 38 }, "rotated": false, @@ -26172,7 +26172,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 87, + "w": 88, "h": 38 }, "sourceSize": { @@ -26182,18 +26182,18 @@ }, "ship_17_2_001.png": { "frame": { - "x": 393, - "y": 715, - "w": 77, - "h": 35 + "x": 794, + "y": 323, + "w": 86, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 77, - "h": 35 + "y": 0, + "w": 86, + "h": 36 }, "sourceSize": { "w": 86, @@ -26202,18 +26202,18 @@ }, "ship_18_001.png": { "frame": { - "x": 276, - "y": 269, - "w": 88, - "h": 35 + "x": 701, + "y": 0, + "w": 94, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 88, - "h": 35 + "x": 0, + "y": 0, + "w": 94, + "h": 40 }, "sourceSize": { "w": 94, @@ -26222,18 +26222,18 @@ }, "ship_18_2_001.png": { "frame": { - "x": 951, - "y": 69, - "w": 71, - "h": 31 - }, + "x": 670, + "y": 1055, + "w": 78, + "h": 36 + }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 71, - "h": 31 + "y": 0, + "w": 78, + "h": 36 }, "sourceSize": { "w": 78, @@ -26242,18 +26242,18 @@ }, "ship_19_001.png": { "frame": { - "x": 0, - "y": 275, - "w": 91, - "h": 39 + "x": 228, + "y": 61, + "w": 100, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 91, - "h": 39 + "x": 0, + "y": 0, + "w": 100, + "h": 40 }, "sourceSize": { "w": 100, @@ -26262,18 +26262,18 @@ }, "ship_19_2_001.png": { "frame": { - "x": 365, - "y": 275, - "w": 73, - "h": 29 + "x": 1041, + "y": 458, + "w": 80, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 73, - "h": 29 + "w": 80, + "h": 36 }, "sourceSize": { "w": 80, @@ -26282,18 +26282,18 @@ }, "ship_20_001.png": { "frame": { - "x": 384, - "y": 147, - "w": 86, - "h": 52 + "x": 216, + "y": 102, + "w": 100, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 14, + "x": 0, "y": 0, - "w": 86, - "h": 52 + "w": 100, + "h": 54 }, "sourceSize": { "w": 100, @@ -26302,18 +26302,18 @@ }, "ship_20_2_001.png": { "frame": { - "x": 1159, - "y": 519, - "w": 67, - "h": 49 + "x": 85, + "y": 935, + "w": 84, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, + "x": 0, "y": 0, - "w": 67, - "h": 49 + "w": 84, + "h": 52 }, "sourceSize": { "w": 84, @@ -26322,18 +26322,18 @@ }, "ship_21_001.png": { "frame": { - "x": 103, - "y": 0, - "w": 98, - "h": 41 + "x": 109, + "y": 124, + "w": 106, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 98, - "h": 41 + "y": 0, + "w": 106, + "h": 48 }, "sourceSize": { "w": 106, @@ -26342,18 +26342,18 @@ }, "ship_21_2_001.png": { "frame": { - "x": 723, - "y": 0, - "w": 77, - "h": 31 + "x": 798, + "y": 39, + "w": 88, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 77, - "h": 31 + "y": 0, + "w": 88, + "h": 38 }, "sourceSize": { "w": 88, @@ -26362,10 +26362,10 @@ }, "ship_22_001.png": { "frame": { - "x": 0, - "y": 370, + "x": 727, + "y": 502, "w": 88, - "h": 46 + "h": 54 }, "rotated": false, "trimmed": true, @@ -26373,7 +26373,7 @@ "x": 0, "y": 0, "w": 88, - "h": 46 + "h": 54 }, "sourceSize": { "w": 88, @@ -26382,18 +26382,18 @@ }, "ship_22_2_001.png": { "frame": { - "x": 192, - "y": 130, - "w": 7, - "h": 15 + "x": 683, + "y": 1650, + "w": 60, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 53, - "y": 5, - "w": 7, - "h": 15 + "x": 0, + "y": 0, + "w": 60, + "h": 20 }, "sourceSize": { "w": 60, @@ -26402,18 +26402,18 @@ }, "ship_23_001.png": { "frame": { - "x": 637, - "y": 207, - "w": 79, - "h": 53 + "x": 772, + "y": 165, + "w": 86, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 79, - "h": 53 + "w": 86, + "h": 64 }, "sourceSize": { "w": 86, @@ -26422,18 +26422,18 @@ }, "ship_23_2_001.png": { "frame": { - "x": 919, - "y": 1076, - "w": 70, - "h": 41 + "x": 830, + "y": 1063, + "w": 78, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 70, - "h": 41 + "w": 78, + "h": 60 }, "sourceSize": { "w": 78, @@ -26442,18 +26442,18 @@ }, "ship_24_001.png": { "frame": { - "x": 641, - "y": 46, - "w": 80, - "h": 41 + "x": 875, + "y": 780, + "w": 82, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 80, - "h": 41 + "w": 82, + "h": 44 }, "sourceSize": { "w": 82, @@ -26462,18 +26462,18 @@ }, "ship_24_2_001.png": { "frame": { - "x": 1298, - "y": 107, - "w": 64, - "h": 26 + "x": 1020, + "y": 1330, + "w": 72, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 64, - "h": 26 + "w": 72, + "h": 28 }, "sourceSize": { "w": 72, @@ -26482,18 +26482,18 @@ }, "ship_25_001.png": { "frame": { - "x": 96, - "y": 174, - "w": 93, - "h": 42 + "x": 612, + "y": 594, + "w": 94, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 93, - "h": 42 + "x": 0, + "y": 0, + "w": 94, + "h": 44 }, "sourceSize": { "w": 94, @@ -26502,18 +26502,18 @@ }, "ship_25_2_001.png": { "frame": { - "x": 1094, - "y": 0, - "w": 70, - "h": 26 + "x": 1020, + "y": 1359, + "w": 72, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 70, - "h": 26 + "w": 72, + "h": 36 }, "sourceSize": { "w": 72, @@ -26522,17 +26522,17 @@ }, "ship_26_001.png": { "frame": { - "x": 376, - "y": 200, - "w": 86, + "x": 701, + "y": 639, + "w": 94, "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 86, + "w": 94, "h": 48 }, "sourceSize": { @@ -26542,9 +26542,9 @@ }, "ship_26_2_001.png": { "frame": { - "x": 1298, - "y": 134, - "w": 64, + "x": 213, + "y": 1298, + "w": 74, "h": 44 }, "rotated": false, @@ -26552,7 +26552,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 64, + "w": 74, "h": 44 }, "sourceSize": { @@ -26562,18 +26562,18 @@ }, "ship_26_extra_001.png": { "frame": { - "x": 83, - "y": 554, - "w": 82, - "h": 36 + "x": 240, + "y": 827, + "w": 90, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 82, - "h": 36 + "x": 0, + "y": 0, + "w": 90, + "h": 44 }, "sourceSize": { "w": 90, @@ -26582,18 +26582,18 @@ }, "ship_27_001.png": { "frame": { - "x": 0, - "y": 417, - "w": 85, - "h": 43 + "x": 331, + "y": 827, + "w": 90, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, - "y": 3, - "w": 85, - "h": 43 + "x": 0, + "y": 0, + "w": 90, + "h": 46 }, "sourceSize": { "w": 90, @@ -26602,18 +26602,18 @@ }, "ship_27_2_001.png": { "frame": { - "x": 471, - "y": 193, - "w": 83, - "h": 40 + "x": 798, + "y": 557, + "w": 88, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 83, - "h": 40 + "x": 0, + "y": 0, + "w": 88, + "h": 44 }, "sourceSize": { "w": 88, @@ -26622,18 +26622,18 @@ }, "ship_27_extra_001.png": { "frame": { - "x": 247, - "y": 623, - "w": 80, - "h": 21 + "x": 0, + "y": 710, + "w": 84, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 80, - "h": 21 + "w": 84, + "h": 22 }, "sourceSize": { "w": 84, @@ -26642,18 +26642,18 @@ }, "ship_28_001.png": { "frame": { - "x": 463, - "y": 234, - "w": 83, - "h": 39 + "x": 794, + "y": 360, + "w": 86, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 7, - "w": 83, - "h": 39 + "x": 0, + "y": 0, + "w": 86, + "h": 46 }, "sourceSize": { "w": 86, @@ -26662,18 +26662,18 @@ }, "ship_28_2_001.png": { "frame": { - "x": 558, - "y": 143, - "w": 81, - "h": 37 + "x": 87, + "y": 880, + "w": 84, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 7, - "w": 81, - "h": 37 + "x": 0, + "y": 0, + "w": 84, + "h": 44 }, "sourceSize": { "w": 84, @@ -26682,38 +26682,38 @@ }, "ship_28_extra_001.png": { "frame": { - "x": 0, - "y": 0, - "w": 0, - "h": 0 + "x": 228, + "y": 49, + "w": 1, + "h": 1 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 0, - "h": 0 + "w": 1, + "h": 1 }, "sourceSize": { - "w": 0, - "h": 0 + "w": 1, + "h": 1 } }, "ship_29_001.png": { "frame": { - "x": 294, - "y": 82, - "w": 90, - "h": 39 + "x": 677, + "y": 41, + "w": 94, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 90, - "h": 39 + "y": 0, + "w": 94, + "h": 46 }, "sourceSize": { "w": 94, @@ -26722,18 +26722,18 @@ }, "ship_29_2_001.png": { "frame": { - "x": 632, - "y": 751, - "w": 76, - "h": 36 + "x": 794, + "y": 407, + "w": 86, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, - "w": 76, - "h": 36 + "y": 0, + "w": 86, + "h": 42 }, "sourceSize": { "w": 86, @@ -26742,18 +26742,18 @@ }, "ship_29_extra_001.png": { "frame": { - "x": 1953, - "y": 353, - "w": 34, - "h": 25 + "x": 1418, + "y": 1580, + "w": 68, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 34, - "y": 7, - "w": 34, - "h": 25 + "x": 0, + "y": 0, + "w": 68, + "h": 32 }, "sourceSize": { "w": 68, @@ -26762,18 +26762,18 @@ }, "ship_30_001.png": { "frame": { - "x": 201, - "y": 60, - "w": 92, - "h": 42 + "x": 315, + "y": 594, + "w": 98, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, - "w": 92, - "h": 42 + "y": 0, + "w": 98, + "h": 48 }, "sourceSize": { "w": 98, @@ -26782,18 +26782,18 @@ }, "ship_30_2_001.png": { "frame": { - "x": 1065, - "y": 1058, - "w": 28, - "h": 6 + "x": 2275, + "y": 1762, + "w": 30, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 16, - "w": 28, - "h": 6 + "x": 0, + "y": 0, + "w": 30, + "h": 22 }, "sourceSize": { "w": 30, @@ -26802,18 +26802,18 @@ }, "ship_30_extra_001.png": { "frame": { - "x": 249, - "y": 1891, - "w": 15, - "h": 7 + "x": 366, + "y": 808, + "w": 76, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 61, + "x": 0, "y": 0, - "w": 15, - "h": 7 + "w": 76, + "h": 18 }, "sourceSize": { "w": 76, @@ -26822,18 +26822,18 @@ }, "ship_31_001.png": { "frame": { - "x": 351, - "y": 417, - "w": 84, - "h": 52 + "x": 798, + "y": 602, + "w": 88, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 84, - "h": 52 + "w": 88, + "h": 64 }, "sourceSize": { "w": 88, @@ -26842,18 +26842,18 @@ }, "ship_31_2_001.png": { "frame": { - "x": 578, - "y": 587, - "w": 79, - "h": 30 + "x": 1041, + "y": 495, + "w": 80, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 8, - "w": 79, - "h": 30 + "x": 0, + "y": 0, + "w": 80, + "h": 38 }, "sourceSize": { "w": 80, @@ -26862,18 +26862,18 @@ }, "ship_31_extra_001.png": { "frame": { - "x": 1368, - "y": 1354, - "w": 18, - "h": 17 + "x": 113, + "y": 98, + "w": 84, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 66, - "y": 3, - "w": 18, - "h": 17 + "x": 0, + "y": 0, + "w": 84, + "h": 20 }, "sourceSize": { "w": 84, @@ -26882,18 +26882,18 @@ }, "ship_32_001.png": { "frame": { - "x": 103, - "y": 42, - "w": 97, - "h": 44 + "x": 117, + "y": 0, + "w": 112, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 15, - "y": 4, - "w": 97, - "h": 44 + "x": 0, + "y": 0, + "w": 112, + "h": 48 }, "sourceSize": { "w": 112, @@ -26902,18 +26902,18 @@ }, "ship_32_2_001.png": { "frame": { - "x": 476, - "y": 671, - "w": 78, - "h": 33 + "x": 670, + "y": 1008, + "w": 80, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, - "w": 78, - "h": 33 + "y": 0, + "w": 80, + "h": 46 }, "sourceSize": { "w": 80, @@ -26922,18 +26922,18 @@ }, "ship_32_extra_001.png": { "frame": { - "x": 298, - "y": 869, - "w": 73, - "h": 35 + "x": 0, + "y": 673, + "w": 96, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, - "y": 1, - "w": 73, - "h": 35 + "x": 0, + "y": 0, + "w": 96, + "h": 36 }, "sourceSize": { "w": 96, @@ -26942,18 +26942,18 @@ }, "ship_33_001.png": { "frame": { - "x": 200, - "y": 103, - "w": 92, - "h": 48 + "x": 0, + "y": 220, + "w": 102, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 92, - "h": 48 + "x": 0, + "y": 0, + "w": 102, + "h": 56 }, "sourceSize": { "w": 102, @@ -26962,18 +26962,18 @@ }, "ship_33_2_001.png": { "frame": { - "x": 92, - "y": 307, - "w": 89, - "h": 47 + "x": 414, + "y": 594, + "w": 98, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, - "y": 7, - "w": 89, - "h": 47 + "x": 0, + "y": 0, + "w": 98, + "h": 54 }, "sourceSize": { "w": 98, @@ -26982,18 +26982,18 @@ }, "ship_34_001.png": { "frame": { - "x": 461, - "y": 274, - "w": 83, - "h": 57 + "x": 796, + "y": 667, + "w": 88, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 83, - "h": 57 + "x": 0, + "y": 0, + "w": 88, + "h": 64 }, "sourceSize": { "w": 88, @@ -27002,18 +27002,18 @@ }, "ship_34_2_001.png": { "frame": { - "x": 231, - "y": 756, - "w": 75, - "h": 35 + "x": 794, + "y": 450, + "w": 86, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 75, - "h": 35 + "x": 0, + "y": 0, + "w": 86, + "h": 40 }, "sourceSize": { "w": 86, @@ -27023,17 +27023,17 @@ "ship_35_001.png": { "frame": { "x": 0, - "y": 0, - "w": 102, - "h": 41 + "y": 124, + "w": 108, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 102, - "h": 41 + "y": 0, + "w": 108, + "h": 48 }, "sourceSize": { "w": 108, @@ -27043,17 +27043,17 @@ "ship_35_2_001.png": { "frame": { "x": 0, - "y": 90, - "w": 100, - "h": 39 + "y": 173, + "w": 106, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 100, - "h": 39 + "y": 0, + "w": 106, + "h": 46 }, "sourceSize": { "w": 106, @@ -27062,18 +27062,18 @@ }, "ship_35_extra_001.png": { "frame": { - "x": 1536, - "y": 1613, - "w": 9, - "h": 6 + "x": 887, + "y": 658, + "w": 42, + "h": 8 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 33, + "x": 0, "y": 0, - "w": 9, - "h": 6 + "w": 42, + "h": 8 }, "sourceSize": { "w": 42, @@ -27082,18 +27082,18 @@ }, "ship_36_001.png": { "frame": { - "x": 0, - "y": 461, - "w": 85, - "h": 47 + "x": 93, + "y": 724, + "w": 90, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 85, - "h": 47 + "x": 0, + "y": 0, + "w": 90, + "h": 56 }, "sourceSize": { "w": 90, @@ -27102,18 +27102,18 @@ }, "ship_36_2_001.png": { "frame": { - "x": 723, - "y": 32, - "w": 77, - "h": 37 + "x": 909, + "y": 1063, + "w": 78, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, - "w": 77, - "h": 37 + "y": 0, + "w": 78, + "h": 50 }, "sourceSize": { "w": 78, @@ -27122,18 +27122,18 @@ }, "ship_36_extra_001.png": { "frame": { - "x": 551, - "y": 1891, - "w": 49, - "h": 29 + "x": 2066, + "y": 1081, + "w": 58, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 17, - "w": 49, - "h": 29 + "x": 0, + "y": 0, + "w": 58, + "h": 46 }, "sourceSize": { "w": 58, @@ -27142,18 +27142,18 @@ }, "ship_37_001.png": { "frame": { - "x": 293, - "y": 122, - "w": 90, - "h": 37 + "x": 701, + "y": 688, + "w": 94, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 90, - "h": 37 + "x": 0, + "y": 0, + "w": 94, + "h": 44 }, "sourceSize": { "w": 94, @@ -27162,18 +27162,18 @@ }, "ship_37_2_001.png": { "frame": { - "x": 374, - "y": 249, - "w": 86, - "h": 25 + "x": 707, + "y": 596, + "w": 90, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 86, - "h": 25 + "x": 0, + "y": 0, + "w": 90, + "h": 32 }, "sourceSize": { "w": 90, @@ -27182,18 +27182,18 @@ }, "ship_38_001.png": { "frame": { - "x": 285, - "y": 160, - "w": 90, - "h": 55 + "x": 701, + "y": 394, + "w": 92, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 90, - "h": 55 + "w": 92, + "h": 56 }, "sourceSize": { "w": 92, @@ -27202,18 +27202,18 @@ }, "ship_38_2_001.png": { "frame": { - "x": 361, - "y": 305, - "w": 86, - "h": 49 + "x": 784, + "y": 827, + "w": 88, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 86, - "h": 49 + "y": 0, + "w": 88, + "h": 52 }, "sourceSize": { "w": 88, @@ -27222,18 +27222,18 @@ }, "ship_38_extra_001.png": { "frame": { - "x": 1094, - "y": 27, - "w": 70, - "h": 25 + "x": 786, + "y": 780, + "w": 88, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 70, - "h": 25 + "x": 0, + "y": 0, + "w": 88, + "h": 44 }, "sourceSize": { "w": 88, @@ -27242,18 +27242,18 @@ }, "ship_39_001.png": { "frame": { - "x": 97, - "y": 130, - "w": 94, - "h": 43 + "x": 103, + "y": 220, + "w": 102, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 94, - "h": 43 + "w": 102, + "h": 44 }, "sourceSize": { "w": 102, @@ -27262,18 +27262,18 @@ }, "ship_39_2_001.png": { "frame": { - "x": 92, - "y": 275, - "w": 91, - "h": 31 + "x": 107, + "y": 173, + "w": 100, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 91, - "h": 31 + "y": 0, + "w": 100, + "h": 36 }, "sourceSize": { "w": 100, @@ -27282,18 +27282,18 @@ }, "ship_40_001.png": { "frame": { - "x": 184, - "y": 273, - "w": 91, - "h": 40 + "x": 97, + "y": 673, + "w": 96, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, - "w": 91, - "h": 40 + "y": 0, + "w": 96, + "h": 50 }, "sourceSize": { "w": 96, @@ -27302,38 +27302,38 @@ }, "ship_40_2_001.png": { "frame": { - "x": 641, - "y": 88, - "w": 80, - "h": 31 + "x": 149, + "y": 781, + "w": 90, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 80, - "h": 31 - }, - "sourceSize": { + "y": 0, + "w": 90, + "h": 36 + }, + "sourceSize": { "w": 90, "h": 36 } }, "ship_40_extra_001.png": { "frame": { - "x": 1148, - "y": 855, - "w": 38, - "h": 9 + "x": 1275, + "y": 729, + "w": 68, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 30, + "x": 0, "y": 0, - "w": 38, - "h": 9 + "w": 68, + "h": 12 }, "sourceSize": { "w": 68, @@ -27342,18 +27342,18 @@ }, "ship_41_001.png": { "frame": { - "x": 249, - "y": 506, - "w": 82, - "h": 45 + "x": 0, + "y": 880, + "w": 86, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, - "w": 82, - "h": 45 + "y": 0, + "w": 86, + "h": 54 }, "sourceSize": { "w": 86, @@ -27362,18 +27362,18 @@ }, "ship_41_2_001.png": { "frame": { - "x": 579, - "y": 544, - "w": 79, - "h": 42 + "x": 958, + "y": 513, + "w": 82, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, - "w": 79, - "h": 42 + "y": 0, + "w": 82, + "h": 52 }, "sourceSize": { "w": 82, @@ -27382,18 +27382,18 @@ }, "ship_41_extra_001.png": { "frame": { - "x": 471, - "y": 715, - "w": 4, - "h": 3 + "x": 410, + "y": 1056, + "w": 40, + "h": 6 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 36, - "y": 3, - "w": 4, - "h": 3 + "x": 0, + "y": 0, + "w": 40, + "h": 6 }, "sourceSize": { "w": 40, @@ -27402,18 +27402,18 @@ }, "ship_42_001.png": { "frame": { - "x": 103, - "y": 87, + "x": 194, + "y": 661, "w": 96, - "h": 42 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 4, + "y": 0, "w": 96, - "h": 42 + "h": 46 }, "sourceSize": { "w": 96, @@ -27422,18 +27422,18 @@ }, "ship_42_2_001.png": { "frame": { - "x": 386, - "y": 39, - "w": 87, - "h": 38 + "x": 677, + "y": 88, + "w": 94, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 87, - "h": 38 + "x": 0, + "y": 0, + "w": 94, + "h": 42 }, "sourceSize": { "w": 94, @@ -27442,18 +27442,18 @@ }, "ship_43_001.png": { "frame": { - "x": 182, - "y": 314, - "w": 89, - "h": 45 + "x": 701, + "y": 451, + "w": 92, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 5, - "w": 89, - "h": 45 + "x": 0, + "y": 0, + "w": 92, + "h": 50 }, "sourceSize": { "w": 92, @@ -27462,18 +27462,18 @@ }, "ship_43_2_001.png": { "frame": { - "x": 641, - "y": 120, - "w": 80, - "h": 43 + "x": 958, + "y": 566, + "w": 82, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 80, - "h": 43 + "y": 0, + "w": 82, + "h": 48 }, "sourceSize": { "w": 82, @@ -27482,18 +27482,18 @@ }, "ship_44_001.png": { "frame": { - "x": 0, - "y": 42, - "w": 102, - "h": 47 + "x": 117, + "y": 49, + "w": 110, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 102, - "h": 47 + "y": 0, + "w": 110, + "h": 48 }, "sourceSize": { "w": 110, @@ -27502,18 +27502,18 @@ }, "ship_44_2_001.png": { "frame": { - "x": 0, - "y": 130, - "w": 96, - "h": 43 + "x": 216, + "y": 157, + "w": 100, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 96, - "h": 43 + "y": 0, + "w": 100, + "h": 44 }, "sourceSize": { "w": 100, @@ -27522,18 +27522,18 @@ }, "ship_45_001.png": { "frame": { - "x": 433, - "y": 470, - "w": 83, - "h": 38 + "x": 170, + "y": 935, + "w": 84, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, - "w": 83, - "h": 38 + "y": 0, + "w": 84, + "h": 44 }, "sourceSize": { "w": 84, @@ -27542,18 +27542,18 @@ }, "ship_45_2_001.png": { "frame": { - "x": 555, - "y": 181, - "w": 81, - "h": 34 + "x": 958, + "y": 615, + "w": 82, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, - "w": 81, - "h": 34 + "y": 0, + "w": 82, + "h": 40 }, "sourceSize": { "w": 82, @@ -27562,18 +27562,18 @@ }, "ship_46_001.png": { "frame": { - "x": 192, - "y": 152, - "w": 92, - "h": 41 + "x": 513, + "y": 594, + "w": 98, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 92, - "h": 41 + "y": 0, + "w": 98, + "h": 44 }, "sourceSize": { "w": 98, @@ -27582,18 +27582,18 @@ }, "ship_46_2_001.png": { "frame": { - "x": 166, - "y": 550, - "w": 82, - "h": 33 + "x": 255, + "y": 935, + "w": 84, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 82, - "h": 33 + "x": 0, + "y": 0, + "w": 84, + "h": 36 }, "sourceSize": { "w": 84, @@ -27602,18 +27602,18 @@ }, "ship_47_001.png": { "frame": { - "x": 0, - "y": 174, - "w": 95, - "h": 57 + "x": 315, + "y": 643, + "w": 98, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 95, - "h": 57 + "w": 98, + "h": 60 }, "sourceSize": { "w": 98, @@ -27622,18 +27622,18 @@ }, "ship_47_2_001.png": { "frame": { - "x": 283, - "y": 216, - "w": 90, - "h": 52 + "x": 634, + "y": 502, + "w": 92, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 90, - "h": 52 + "w": 92, + "h": 54 }, "sourceSize": { "w": 92, @@ -27642,18 +27642,18 @@ }, "ship_47_extra_001.png": { "frame": { - "x": 875, - "y": 1856, - "w": 52, - "h": 27 + "x": 537, + "y": 1259, + "w": 74, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 22, + "x": 0, "y": 0, - "w": 52, - "h": 27 + "w": 74, + "h": 54 }, "sourceSize": { "w": 74, @@ -27662,18 +27662,18 @@ }, "ship_48_001.png": { "frame": { - "x": 0, - "y": 315, - "w": 90, - "h": 54 + "x": 230, + "y": 0, + "w": 102, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, - "w": 90, - "h": 54 + "y": 0, + "w": 102, + "h": 60 }, "sourceSize": { "w": 102, @@ -27682,18 +27682,18 @@ }, "ship_48_2_001.png": { "frame": { - "x": 265, - "y": 414, - "w": 85, - "h": 49 + "x": 677, + "y": 131, + "w": 94, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 85, - "h": 49 + "y": 0, + "w": 94, + "h": 56 }, "sourceSize": { "w": 94, @@ -27702,18 +27702,18 @@ }, "ship_48_extra_001.png": { "frame": { - "x": 513, - "y": 994, - "w": 3, - "h": 3 + "x": 1702, + "y": 1325, + "w": 54, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 51, + "x": 0, "y": 0, - "w": 3, - "h": 3 + "w": 54, + "h": 12 }, "sourceSize": { "w": 54, @@ -27722,17 +27722,17 @@ }, "ship_49_001.png": { "frame": { - "x": 177, - "y": 415, - "w": 85, + "x": 0, + "y": 733, + "w": 92, "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 85, + "w": 92, "h": 52 }, "sourceSize": { @@ -27742,18 +27742,18 @@ }, "ship_49_2_001.png": { "frame": { - "x": 332, - "y": 508, - "w": 82, - "h": 49 + "x": 422, + "y": 827, + "w": 90, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, - "y": 1, - "w": 82, - "h": 49 + "x": 0, + "y": 0, + "w": 90, + "h": 50 }, "sourceSize": { "w": 90, @@ -27762,18 +27762,18 @@ }, "ship_49_extra_001.png": { "frame": { - "x": 517, - "y": 489, - "w": 62, - "h": 14 + "x": 85, + "y": 988, + "w": 76, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 14, + "x": 0, "y": 0, - "w": 62, - "h": 14 + "w": 76, + "h": 18 }, "sourceSize": { "w": 76, @@ -27782,18 +27782,18 @@ }, "ship_50_001.png": { "frame": { - "x": 800, - "y": 114, - "w": 75, - "h": 45 + "x": 315, + "y": 1136, + "w": 76, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 75, - "h": 45 + "w": 76, + "h": 48 }, "sourceSize": { "w": 76, @@ -27802,18 +27802,18 @@ }, "ship_50_2_001.png": { "frame": { - "x": 1231, - "y": 514, - "w": 66, - "h": 40 + "x": 1093, + "y": 1320, + "w": 72, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, - "h": 40 + "w": 72, + "h": 42 }, "sourceSize": { "w": 72, @@ -27822,18 +27822,18 @@ }, "ship_50_extra_001.png": { "frame": { - "x": 1162, - "y": 1995, - "w": 24, - "h": 22 + "x": 213, + "y": 1269, + "w": 74, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 50, - "y": 6, - "w": 24, - "h": 22 + "x": 0, + "y": 0, + "w": 74, + "h": 28 }, "sourceSize": { "w": 74, @@ -27842,18 +27842,18 @@ }, "ship_51_001.png": { "frame": { - "x": 386, - "y": 78, - "w": 87, - "h": 51 + "x": 606, + "y": 694, + "w": 92, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 87, - "h": 51 + "w": 92, + "h": 54 }, "sourceSize": { "w": 92, @@ -27862,18 +27862,18 @@ }, "ship_51_2_001.png": { "frame": { - "x": 555, - "y": 216, - "w": 81, - "h": 47 + "x": 340, + "y": 935, + "w": 84, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 81, - "h": 47 + "w": 84, + "h": 50 }, "sourceSize": { "w": 84, @@ -27882,18 +27882,18 @@ }, "ship_52_001.png": { "frame": { - "x": 474, - "y": 0, - "w": 84, - "h": 51 + "x": 513, + "y": 751, + "w": 90, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 84, - "h": 51 + "w": 90, + "h": 58 }, "sourceSize": { "w": 90, @@ -27902,18 +27902,18 @@ }, "ship_52_2_001.png": { "frame": { - "x": 474, - "y": 52, - "w": 84, - "h": 49 + "x": 184, + "y": 724, + "w": 90, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 84, - "h": 49 + "w": 90, + "h": 56 }, "sourceSize": { "w": 90, @@ -27922,18 +27922,18 @@ }, "ship_52_extra_001.png": { "frame": { - "x": 142, - "y": 1136, - "w": 68, - "h": 34 + "x": 1093, + "y": 1363, + "w": 72, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 68, - "h": 34 + "w": 72, + "h": 50 }, "sourceSize": { "w": 72, @@ -27942,18 +27942,18 @@ }, "ship_53_001.png": { "frame": { - "x": 162, - "y": 624, - "w": 80, - "h": 37 + "x": 240, + "y": 872, + "w": 86, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 80, - "h": 37 + "x": 0, + "y": 0, + "w": 86, + "h": 48 }, "sourceSize": { "w": 86, @@ -27962,18 +27962,18 @@ }, "ship_53_2_001.png": { "frame": { - "x": 555, - "y": 660, - "w": 78, - "h": 35 + "x": 425, + "y": 927, + "w": 84, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 78, - "h": 35 + "x": 0, + "y": 0, + "w": 84, + "h": 46 }, "sourceSize": { "w": 84, @@ -27982,18 +27982,18 @@ }, "ship_53_extra_001.png": { "frame": { - "x": 276, - "y": 305, - "w": 52, - "h": 8 + "x": 1426, + "y": 1203, + "w": 64, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 12, + "x": 0, "y": 0, - "w": 52, - "h": 8 + "w": 64, + "h": 16 }, "sourceSize": { "w": 64, @@ -28002,18 +28002,18 @@ }, "ship_54_001.png": { "frame": { - "x": 154, - "y": 788, + "x": 231, + "y": 1183, "w": 76, - "h": 36 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 76, - "h": 36 + "h": 42 }, "sourceSize": { "w": 76, @@ -28022,18 +28022,18 @@ }, "ship_54_2_001.png": { "frame": { - "x": 739, - "y": 1171, - "w": 66, - "h": 27 + "x": 1166, + "y": 1320, + "w": 72, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 66, - "h": 27 + "y": 0, + "w": 72, + "h": 28 }, "sourceSize": { "w": 72, @@ -28042,18 +28042,18 @@ }, "ship_55_001.png": { "frame": { - "x": 0, - "y": 232, - "w": 92, - "h": 42 + "x": 677, + "y": 188, + "w": 94, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 92, - "h": 42 + "x": 0, + "y": 0, + "w": 94, + "h": 44 }, "sourceSize": { "w": 94, @@ -28062,18 +28062,18 @@ }, "ship_55_2_001.png": { "frame": { - "x": 93, - "y": 232, - "w": 92, - "h": 40 + "x": 620, + "y": 233, + "w": 94, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 92, - "h": 40 + "x": 0, + "y": 0, + "w": 94, + "h": 42 }, "sourceSize": { "w": 94, @@ -28082,18 +28082,18 @@ }, "ship_56_001.png": { "frame": { - "x": 634, - "y": 660, + "x": 641, + "y": 1094, "w": 78, - "h": 37 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, + "y": 0, "w": 78, - "h": 37 + "h": 40 }, "sourceSize": { "w": 78, @@ -28102,18 +28102,18 @@ }, "ship_56_2_001.png": { "frame": { - "x": 372, - "y": 870, - "w": 73, - "h": 34 + "x": 768, + "y": 1263, + "w": 74, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 73, - "h": 34 + "x": 0, + "y": 0, + "w": 74, + "h": 36 }, "sourceSize": { "w": 74, @@ -28122,18 +28122,18 @@ }, "ship_56_extra_001.png": { "frame": { - "x": 0, - "y": 924, + "x": 879, + "y": 752, "w": 72, - "h": 19 + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, + "y": 0, "w": 72, - "h": 19 + "h": 24 }, "sourceSize": { "w": 72, @@ -28142,18 +28142,18 @@ }, "ship_57_001.png": { "frame": { - "x": 547, - "y": 264, - "w": 81, - "h": 57 + "x": 510, + "y": 935, + "w": 84, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 81, - "h": 57 + "w": 84, + "h": 68 }, "sourceSize": { "w": 84, @@ -28162,18 +28162,18 @@ }, "ship_57_2_001.png": { "frame": { - "x": 545, - "y": 322, - "w": 81, - "h": 57 + "x": 595, + "y": 935, + "w": 84, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 81, - "h": 57 + "w": 84, + "h": 68 }, "sourceSize": { "w": 84, @@ -28182,18 +28182,18 @@ }, "ship_57_extra_001.png": { "frame": { - "x": 224, - "y": 859, - "w": 55, - "h": 9 + "x": 634, + "y": 491, + "w": 64, + "h": 10 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 55, - "h": 9 + "w": 64, + "h": 10 }, "sourceSize": { "w": 64, @@ -28202,18 +28202,18 @@ }, "ship_58_001.png": { "frame": { - "x": 263, - "y": 464, - "w": 85, - "h": 41 + "x": 790, + "y": 733, + "w": 88, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 5, - "w": 85, - "h": 41 + "x": 0, + "y": 0, + "w": 88, + "h": 46 }, "sourceSize": { "w": 88, @@ -28222,17 +28222,17 @@ }, "ship_58_2_001.png": { "frame": { - "x": 249, - "y": 558, - "w": 82, + "x": 364, + "y": 717, + "w": 86, "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 82, + "w": 86, "h": 32 }, "sourceSize": { @@ -28242,18 +28242,18 @@ }, "ship_58_extra_001.png": { "frame": { - "x": 1844, - "y": 1274, - "w": 52, - "h": 25 + "x": 958, + "y": 656, + "w": 82, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 30, - "y": 5, - "w": 52, - "h": 25 + "x": 0, + "y": 0, + "w": 82, + "h": 30 }, "sourceSize": { "w": 82, @@ -28262,18 +28262,18 @@ }, "ship_59_001.png": { "frame": { - "x": 494, - "y": 622, + "x": 252, + "y": 1007, "w": 80, - "h": 37 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, + "y": 0, "w": 80, - "h": 37 + "h": 46 }, "sourceSize": { "w": 80, @@ -28282,18 +28282,18 @@ }, "ship_59_2_001.png": { "frame": { - "x": 154, - "y": 752, + "x": 227, + "y": 1226, "w": 76, - "h": 33 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, + "y": 0, "w": 76, - "h": 33 + "h": 42 }, "sourceSize": { "w": 76, @@ -28302,10 +28302,10 @@ }, "ship_59_extra_001.png": { "frame": { - "x": 625, - "y": 825, + "x": 392, + "y": 1167, "w": 74, - "h": 17 + "h": 22 }, "rotated": false, "trimmed": true, @@ -28313,7 +28313,7 @@ "x": 0, "y": 0, "w": 74, - "h": 17 + "h": 22 }, "sourceSize": { "w": 74, @@ -28322,18 +28322,18 @@ }, "ship_60_001.png": { "frame": { - "x": 415, - "y": 550, - "w": 81, - "h": 40 + "x": 680, + "y": 914, + "w": 84, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 81, - "h": 40 + "y": 0, + "w": 84, + "h": 48 }, "sourceSize": { "w": 84, @@ -28342,18 +28342,18 @@ }, "ship_60_2_001.png": { "frame": { - "x": 555, - "y": 696, - "w": 78, - "h": 36 + "x": 1041, + "y": 534, + "w": 80, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 78, - "h": 36 + "y": 0, + "w": 80, + "h": 44 }, "sourceSize": { "w": 80, @@ -28362,18 +28362,18 @@ }, "ship_60_extra_001.png": { "frame": { - "x": 1321, - "y": 975, - "w": 27, - "h": 12 + "x": 1566, + "y": 1228, + "w": 68, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 41, - "y": 22, - "w": 27, - "h": 12 + "x": 0, + "y": 0, + "w": 68, + "h": 34 }, "sourceSize": { "w": 68, @@ -28382,18 +28382,18 @@ }, "ship_61_001.png": { "frame": { - "x": 580, - "y": 489, - "w": 79, - "h": 48 + "x": 958, + "y": 687, + "w": 82, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 79, - "h": 48 + "w": 82, + "h": 50 }, "sourceSize": { "w": 82, @@ -28402,17 +28402,17 @@ }, "ship_61_2_001.png": { "frame": { - "x": 733, - "y": 613, - "w": 75, + "x": 720, + "y": 1094, + "w": 78, "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 75, + "w": 78, "h": 42 }, "sourceSize": { @@ -28422,18 +28422,18 @@ }, "ship_61_extra_001.png": { "frame": { - "x": 1090, - "y": 356, - "w": 69, - "h": 28 + "x": 1166, + "y": 1349, + "w": 72, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 69, - "h": 28 + "w": 72, + "h": 42 }, "sourceSize": { "w": 72, @@ -28442,18 +28442,18 @@ }, "ship_62_001.png": { "frame": { - "x": 722, - "y": 70, - "w": 77, - "h": 52 - }, + "x": 1016, + "y": 994, + "w": 80, + "h": 60 + }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 77, - "h": 52 + "y": 0, + "w": 80, + "h": 60 }, "sourceSize": { "w": 80, @@ -28462,18 +28462,18 @@ }, "ship_62_2_001.png": { "frame": { - "x": 526, - "y": 826, - "w": 73, - "h": 48 + "x": 308, + "y": 1192, + "w": 76, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 73, - "h": 48 + "y": 0, + "w": 76, + "h": 56 }, "sourceSize": { "w": 76, @@ -28482,18 +28482,18 @@ }, "ship_62_extra_001.png": { "frame": { - "x": 746, - "y": 979, - "w": 69, - "h": 18 + "x": 1279, + "y": 146, + "w": 70, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 69, - "h": 18 + "x": 0, + "y": 0, + "w": 70, + "h": 22 }, "sourceSize": { "w": 70, @@ -28502,18 +28502,18 @@ }, "ship_63_001.png": { "frame": { - "x": 476, - "y": 705, - "w": 78, - "h": 39 + "x": 333, + "y": 1007, + "w": 80, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, - "w": 78, - "h": 39 + "y": 0, + "w": 80, + "h": 48 }, "sourceSize": { "w": 80, @@ -28522,18 +28522,18 @@ }, "ship_63_2_001.png": { "frame": { - "x": 949, - "y": 101, - "w": 71, - "h": 35 + "x": 1239, + "y": 1298, + "w": 72, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, - "w": 71, - "h": 35 + "y": 0, + "w": 72, + "h": 44 }, "sourceSize": { "w": 72, @@ -28542,18 +28542,18 @@ }, "ship_63_extra_001.png": { "frame": { - "x": 1188, - "y": 1925, - "w": 41, - "h": 26 + "x": 1239, + "y": 1343, + "w": 72, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 41, - "h": 26 + "y": 0, + "w": 72, + "h": 32 }, "sourceSize": { "w": 72, @@ -28562,18 +28562,18 @@ }, "ship_64_001.png": { "frame": { - "x": 190, - "y": 194, - "w": 92, - "h": 43 + "x": 677, + "y": 276, + "w": 94, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 25, - "w": 92, - "h": 43 + "x": 0, + "y": 0, + "w": 94, + "h": 68 }, "sourceSize": { "w": 94, @@ -28582,18 +28582,18 @@ }, "ship_64_2_001.png": { "frame": { - "x": 186, - "y": 238, - "w": 88, - "h": 32 + "x": 604, + "y": 794, + "w": 90, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 24, - "w": 88, - "h": 32 + "x": 0, + "y": 0, + "w": 90, + "h": 56 }, "sourceSize": { "w": 90, @@ -28602,18 +28602,18 @@ }, "ship_64_extra_001.png": { "frame": { - "x": 384, - "y": 130, - "w": 87, - "h": 16 + "x": 513, + "y": 810, + "w": 90, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 87, - "h": 16 + "x": 0, + "y": 0, + "w": 90, + "h": 20 }, "sourceSize": { "w": 90, @@ -28622,18 +28622,18 @@ }, "ship_65_001.png": { "frame": { - "x": 625, - "y": 788, - "w": 75, - "h": 36 + "x": 385, + "y": 1192, + "w": 76, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 10, - "w": 75, - "h": 36 + "x": 0, + "y": 0, + "w": 76, + "h": 46 }, "sourceSize": { "w": 76, @@ -28642,18 +28642,18 @@ }, "ship_65_2_001.png": { "frame": { - "x": 949, - "y": 137, - "w": 71, - "h": 32 + "x": 1351, + "y": 0, + "w": 72, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 10, - "w": 71, - "h": 32 + "x": 0, + "y": 0, + "w": 72, + "h": 42 }, "sourceSize": { "w": 72, @@ -28662,18 +28662,18 @@ }, "ship_65_extra_001.png": { "frame": { - "x": 709, - "y": 775, - "w": 59, - "h": 12 + "x": 1351, + "y": 43, + "w": 72, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 12, + "x": 0, "y": 0, - "w": 59, - "h": 12 + "w": 72, + "h": 22 }, "sourceSize": { "w": 72, @@ -28682,18 +28682,18 @@ }, "ship_66_001.png": { "frame": { - "x": 471, - "y": 745, + "x": 462, + "y": 1192, "w": 76, - "h": 46 + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 76, - "h": 46 + "h": 52 }, "sourceSize": { "w": 76, @@ -28702,18 +28702,18 @@ }, "ship_66_2_001.png": { "frame": { - "x": 0, - "y": 944, + "x": 1351, + "y": 66, "w": 72, - "h": 42 + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 72, - "h": 42 + "h": 48 }, "sourceSize": { "w": 72, @@ -28722,18 +28722,18 @@ }, "ship_66_extra_001.png": { "frame": { - "x": 599, - "y": 462, - "w": 59, - "h": 23 + "x": 1491, + "y": 1384, + "w": 70, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, + "x": 0, "y": 0, - "w": 59, - "h": 23 + "w": 70, + "h": 34 }, "sourceSize": { "w": 70, @@ -28742,18 +28742,18 @@ }, "ship_67_001.png": { "frame": { - "x": 0, - "y": 826, + "x": 843, + "y": 1267, "w": 74, - "h": 35 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 11, + "y": 0, "w": 74, - "h": 35 + "h": 46 }, "sourceSize": { "w": 74, @@ -28762,18 +28762,18 @@ }, "ship_67_2_001.png": { "frame": { - "x": 504, - "y": 1395, - "w": 62, - "h": 30 + "x": 1364, + "y": 1162, + "w": 70, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, - "w": 62, - "h": 30 + "y": 0, + "w": 70, + "h": 40 }, "sourceSize": { "w": 70, @@ -28782,18 +28782,18 @@ }, "ship_67_extra_001.png": { "frame": { - "x": 532, - "y": 380, - "w": 62, - "h": 10 + "x": 0, + "y": 1462, + "w": 68, + "h": 14 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, + "x": 0, "y": 0, - "w": 62, - "h": 10 + "w": 68, + "h": 14 }, "sourceSize": { "w": 68, @@ -28802,18 +28802,18 @@ }, "ship_68_001.png": { "frame": { - "x": 640, - "y": 164, - "w": 80, - "h": 42 + "x": 958, + "y": 738, + "w": 82, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 80, - "h": 42 + "y": 0, + "w": 82, + "h": 44 }, "sourceSize": { "w": 82, @@ -28822,9 +28822,9 @@ }, "ship_68_2_001.png": { "frame": { - "x": 1951, - "y": 762, - "w": 36, + "x": 620, + "y": 1611, + "w": 66, "h": 36 }, "rotated": false, @@ -28832,7 +28832,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, + "w": 66, "h": 36 }, "sourceSize": { @@ -28842,10 +28842,10 @@ }, "ship_68_extra_001.png": { "frame": { - "x": 96, - "y": 217, + "x": 598, + "y": 914, "w": 74, - "h": 14 + "h": 20 }, "rotated": false, "trimmed": true, @@ -28853,7 +28853,7 @@ "x": 0, "y": 0, "w": 74, - "h": 14 + "h": 20 }, "sourceSize": { "w": 74, @@ -28862,18 +28862,18 @@ }, "ship_69_001.png": { "frame": { - "x": 497, - "y": 550, - "w": 81, - "h": 36 + "x": 765, + "y": 880, + "w": 84, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 81, - "h": 36 + "x": 0, + "y": 0, + "w": 84, + "h": 46 }, "sourceSize": { "w": 84, @@ -28882,18 +28882,18 @@ }, "ship_69_2_001.png": { "frame": { - "x": 498, - "y": 509, - "w": 81, - "h": 34 + "x": 680, + "y": 963, + "w": 84, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 81, - "h": 34 + "x": 0, + "y": 0, + "w": 84, + "h": 44 }, "sourceSize": { "w": 84, @@ -28902,18 +28902,18 @@ }, "ship_69_extra_001.png": { "frame": { - "x": 949, - "y": 170, - "w": 71, - "h": 20 + "x": 1351, + "y": 115, + "w": 72, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 71, - "h": 20 + "x": 0, + "y": 0, + "w": 72, + "h": 22 }, "sourceSize": { "w": 72, @@ -28922,18 +28922,18 @@ }, "ship_70_001.png": { "frame": { - "x": 86, - "y": 468, - "w": 85, - "h": 40 + "x": 511, + "y": 700, + "w": 92, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, - "w": 85, - "h": 40 + "y": 0, + "w": 92, + "h": 50 }, "sourceSize": { "w": 92, @@ -28942,18 +28942,18 @@ }, "ship_70_2_001.png": { "frame": { - "x": 0, - "y": 720, - "w": 78, - "h": 35 + "x": 850, + "y": 882, + "w": 84, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 9, - "w": 78, - "h": 35 + "y": 0, + "w": 84, + "h": 44 }, "sourceSize": { "w": 84, @@ -28962,18 +28962,18 @@ }, "ship_70_extra_001.png": { "frame": { - "x": 436, - "y": 452, - "w": 76, - "h": 17 + "x": 958, + "y": 783, + "w": 82, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 5, - "w": 76, - "h": 17 + "y": 0, + "w": 82, + "h": 22 }, "sourceSize": { "w": 82, @@ -28982,18 +28982,18 @@ }, "ship_71_001.png": { "frame": { - "x": 415, - "y": 509, + "x": 958, + "y": 806, "w": 82, - "h": 40 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 6, + "y": 0, "w": 82, - "h": 40 + "h": 46 }, "sourceSize": { "w": 82, @@ -29002,18 +29002,18 @@ }, "ship_71_2_001.png": { "frame": { - "x": 722, - "y": 123, - "w": 77, - "h": 37 + "x": 988, + "y": 1055, + "w": 78, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 77, - "h": 37 + "y": 0, + "w": 78, + "h": 44 }, "sourceSize": { "w": 78, @@ -29022,18 +29022,18 @@ }, "ship_71_extra_001.png": { "frame": { - "x": 736, - "y": 596, - "w": 74, - "h": 15 + "x": 385, + "y": 1239, + "w": 76, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 74, - "h": 15 + "w": 76, + "h": 28 }, "sourceSize": { "w": 76, @@ -29042,18 +29042,18 @@ }, "ship_72_001.png": { "frame": { - "x": 517, - "y": 452, - "w": 81, - "h": 36 + "x": 958, + "y": 853, + "w": 82, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 81, - "h": 36 + "x": 0, + "y": 0, + "w": 82, + "h": 42 }, "sourceSize": { "w": 82, @@ -29062,18 +29062,18 @@ }, "ship_72_2_001.png": { "frame": { - "x": 519, - "y": 391, - "w": 81, - "h": 35 + "x": 935, + "y": 896, + "w": 82, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, - "y": 7, - "w": 81, - "h": 35 + "x": 0, + "y": 0, + "w": 82, + "h": 42 }, "sourceSize": { "w": 82, @@ -29082,18 +29082,18 @@ }, "ship_72_extra_001.png": { "frame": { - "x": 458, - "y": 824, - "w": 67, - "h": 14 + "x": 338, + "y": 986, + "w": 72, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 67, - "h": 14 + "w": 72, + "h": 20 }, "sourceSize": { "w": 72, @@ -29102,18 +29102,18 @@ }, "ship_73_001.png": { "frame": { - "x": 393, - "y": 751, + "x": 539, + "y": 1165, "w": 76, - "h": 32 + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 10, + "y": 0, "w": 76, - "h": 32 + "h": 42 }, "sourceSize": { "w": 76, @@ -29122,18 +29122,18 @@ }, "ship_73_2_001.png": { "frame": { - "x": 64, - "y": 1347, - "w": 62, - "h": 28 + "x": 1566, + "y": 1263, + "w": 68, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 6, - "y": 10, - "w": 62, - "h": 28 + "x": 0, + "y": 0, + "w": 68, + "h": 38 }, "sourceSize": { "w": 68, @@ -29142,18 +29142,18 @@ }, "ship_73_extra_001.png": { "frame": { - "x": 696, - "y": 1360, - "w": 61, - "h": 14 + "x": 71, + "y": 1548, + "w": 68, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 61, - "h": 14 + "w": 68, + "h": 16 }, "sourceSize": { "w": 68, @@ -29162,18 +29162,18 @@ }, "ship_74_001.png": { "frame": { - "x": 79, - "y": 693, + "x": 1125, + "y": 0, "w": 78, - "h": 48 + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, + "y": 0, "w": 78, - "h": 48 + "h": 56 }, "sourceSize": { "w": 78, @@ -29182,18 +29182,18 @@ }, "ship_74_2_001.png": { "frame": { - "x": 526, - "y": 875, - "w": 73, - "h": 42 + "x": 288, + "y": 1292, + "w": 74, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 73, - "h": 42 + "y": 0, + "w": 74, + "h": 50 }, "sourceSize": { "w": 74, @@ -29202,18 +29202,18 @@ }, "ship_74_extra_001.png": { "frame": { - "x": 1094, - "y": 53, - "w": 70, - "h": 24 + "x": 1351, + "y": 138, + "w": 72, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 70, - "h": 24 + "y": 0, + "w": 72, + "h": 34 }, "sourceSize": { "w": 72, @@ -29222,18 +29222,18 @@ }, "ship_75_001.png": { "frame": { - "x": 548, - "y": 788, + "x": 539, + "y": 1208, "w": 76, - "h": 37 + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, + "y": 0, "w": 76, - "h": 37 + "h": 50 }, "sourceSize": { "w": 76, @@ -29242,18 +29242,18 @@ }, "ship_75_2_001.png": { "frame": { - "x": 73, - "y": 957, + "x": 1351, + "y": 173, "w": 72, - "h": 33 + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 13, + "y": 0, "w": 72, - "h": 33 + "h": 46 }, "sourceSize": { "w": 72, @@ -29262,9 +29262,9 @@ }, "ship_75_extra_001.png": { "frame": { - "x": 371, - "y": 1480, - "w": 61, + "x": 1201, + "y": 579, + "w": 72, "h": 20 }, "rotated": false, @@ -29272,7 +29272,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 61, + "w": 72, "h": 20 }, "sourceSize": { @@ -29282,18 +29282,18 @@ }, "ship_76_001.png": { "frame": { - "x": 559, - "y": 0, + "x": 935, + "y": 939, "w": 82, - "h": 42 + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 12, + "y": 0, "w": 82, - "h": 42 + "h": 54 }, "sourceSize": { "w": 82, @@ -29302,18 +29302,18 @@ }, "ship_76_2_001.png": { "frame": { - "x": 315, - "y": 752, - "w": 76, - "h": 38 + "x": 1125, + "y": 57, + "w": 78, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 12, - "w": 76, - "h": 38 + "y": 0, + "w": 78, + "h": 50 }, "sourceSize": { "w": 78, @@ -29322,18 +29322,18 @@ }, "ship_76_extra_001.png": { "frame": { - "x": 1232, - "y": 1483, - "w": 49, - "h": 15 + "x": 244, + "y": 2052, + "w": 60, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 11, + "x": 0, "y": 0, - "w": 49, - "h": 15 + "w": 60, + "h": 24 }, "sourceSize": { "w": 60, @@ -29342,18 +29342,18 @@ }, "ship_77_001.png": { "frame": { - "x": 776, - "y": 823, - "w": 73, - "h": 43 + "x": 616, + "y": 1174, + "w": 76, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 73, - "h": 43 + "w": 76, + "h": 46 }, "sourceSize": { "w": 76, @@ -29362,18 +29362,18 @@ }, "ship_77_2_001.png": { "frame": { - "x": 605, - "y": 1310, - "w": 32, - "h": 12 + "x": 1576, + "y": 2050, + "w": 58, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, - "y": 10, - "w": 32, - "h": 12 + "x": 0, + "y": 0, + "w": 58, + "h": 22 }, "sourceSize": { "w": 58, @@ -29382,18 +29382,18 @@ }, "ship_77_extra_001.png": { "frame": { - "x": 1065, - "y": 1022, - "w": 67, - "h": 35 + "x": 1491, + "y": 1419, + "w": 70, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 67, - "h": 35 + "w": 70, + "h": 42 }, "sourceSize": { "w": 70, @@ -29402,18 +29402,18 @@ }, "ship_78_001.png": { "frame": { - "x": 575, - "y": 622, - "w": 80, - "h": 37 + "x": 0, + "y": 1008, + "w": 82, + "h": 48 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 11, - "w": 80, - "h": 37 + "y": 0, + "w": 82, + "h": 48 }, "sourceSize": { "w": 82, @@ -29422,18 +29422,18 @@ }, "ship_78_2_001.png": { "frame": { - "x": 231, - "y": 792, - "w": 76, - "h": 33 + "x": 1125, + "y": 108, + "w": 78, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 11, - "w": 76, - "h": 33 + "y": 0, + "w": 78, + "h": 44 }, "sourceSize": { "w": 78, @@ -29442,18 +29442,18 @@ }, "ship_78_extra_001.png": { "frame": { - "x": 79, - "y": 742, - "w": 59, - "h": 9 + "x": 1428, + "y": 1712, + "w": 62, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 59, - "h": 9 + "w": 62, + "h": 22 }, "sourceSize": { "w": 62, @@ -29462,18 +29462,18 @@ }, "ship_79_001.png": { "frame": { - "x": 158, - "y": 703, - "w": 78, - "h": 48 + "x": 1041, + "y": 579, + "w": 80, + "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 78, - "h": 48 + "w": 80, + "h": 50 }, "sourceSize": { "w": 80, @@ -29482,18 +29482,18 @@ }, "ship_79_2_001.png": { "frame": { - "x": 383, - "y": 826, - "w": 74, - "h": 43 + "x": 616, + "y": 1221, + "w": 76, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 74, - "h": 43 + "w": 76, + "h": 46 }, "sourceSize": { "w": 76, @@ -29502,18 +29502,18 @@ }, "ship_79_extra_001.png": { "frame": { - "x": 1231, - "y": 555, - "w": 66, - "h": 29 + "x": 1351, + "y": 220, + "w": 72, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, - "h": 29 + "w": 72, + "h": 44 }, "sourceSize": { "w": 72, @@ -29522,8 +29522,8 @@ }, "spider_01_01_001.png": { "frame": { - "x": 1671, - "y": 632, + "x": 793, + "y": 2007, "w": 60, "h": 40 }, @@ -29542,18 +29542,18 @@ }, "spider_01_01_2_001.png": { "frame": { - "x": 139, - "y": 1994, - "w": 19, - "h": 19 + "x": 2235, + "y": 1363, + "w": 44, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 25, + "x": 0, "y": 0, - "w": 19, - "h": 19 + "w": 44, + "h": 26 }, "sourceSize": { "w": 44, @@ -29562,18 +29562,18 @@ }, "spider_01_01_extra_001.png": { "frame": { - "x": 1332, - "y": 2001, - "w": 18, - "h": 17 + "x": 874, + "y": 1451, + "w": 44, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, + "x": 0, "y": 0, - "w": 18, - "h": 17 + "w": 44, + "h": 24 }, "sourceSize": { "w": 44, @@ -29582,8 +29582,8 @@ }, "spider_01_01_glow_001.png": { "frame": { - "x": 1298, - "y": 179, + "x": 1664, + "y": 1758, "w": 64, "h": 44 }, @@ -29602,18 +29602,18 @@ }, "spider_01_02_001.png": { "frame": { - "x": 1980, - "y": 448, + "x": 555, + "y": 2242, "w": 22, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 22, - "h": 31 + "h": 32 }, "sourceSize": { "w": 22, @@ -29622,8 +29622,8 @@ }, "spider_01_02_2_001.png": { "frame": { - "x": 980, - "y": 1187, + "x": 68, + "y": 1613, "w": 2, "h": 2 }, @@ -29642,18 +29642,18 @@ }, "spider_01_02_glow_001.png": { "frame": { - "x": 1960, - "y": 1302, + "x": 893, + "y": 2278, "w": 26, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 35 + "h": 36 }, "sourceSize": { "w": 26, @@ -29662,8 +29662,8 @@ }, "spider_01_03_001.png": { "frame": { - "x": 1933, - "y": 1778, + "x": 920, + "y": 2278, "w": 20, "h": 36 }, @@ -29682,8 +29682,8 @@ }, "spider_01_03_2_001.png": { "frame": { - "x": 129, - "y": 1297, + "x": 1102, + "y": 1609, "w": 2, "h": 2 }, @@ -29702,8 +29702,8 @@ }, "spider_01_03_glow_001.png": { "frame": { - "x": 1566, - "y": 1889, + "x": 1894, + "y": 2195, "w": 24, "h": 40 }, @@ -29722,8 +29722,8 @@ }, "spider_01_04_001.png": { "frame": { - "x": 1982, - "y": 1566, + "x": 448, + "y": 1988, "w": 28, "h": 18 }, @@ -29742,8 +29742,8 @@ }, "spider_01_04_2_001.png": { "frame": { - "x": 864, - "y": 1329, + "x": 965, + "y": 1611, "w": 2, "h": 2 }, @@ -29762,8 +29762,8 @@ }, "spider_01_04_glow_001.png": { "frame": { - "x": 1948, - "y": 1724, + "x": 693, + "y": 2240, "w": 32, "h": 22 }, @@ -29782,18 +29782,18 @@ }, "spider_02_01_001.png": { "frame": { - "x": 1148, - "y": 804, - "w": 67, - "h": 50 + "x": 1420, + "y": 1489, + "w": 70, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 67, - "h": 50 + "w": 70, + "h": 56 }, "sourceSize": { "w": 70, @@ -29802,18 +29802,18 @@ }, "spider_02_01_2_001.png": { "frame": { - "x": 1171, - "y": 1435, - "w": 61, - "h": 41 + "x": 1169, + "y": 1651, + "w": 66, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 61, - "h": 41 + "w": 66, + "h": 52 }, "sourceSize": { "w": 66, @@ -29822,18 +29822,18 @@ }, "spider_02_01_extra_001.png": { "frame": { - "x": 920, - "y": 1778, - "w": 17, - "h": 18 + "x": 888, + "y": 1840, + "w": 44, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 27, + "x": 0, "y": 0, - "w": 17, - "h": 18 + "w": 44, + "h": 24 }, "sourceSize": { "w": 44, @@ -29842,18 +29842,18 @@ }, "spider_02_01_glow_001.png": { "frame": { - "x": 812, - "y": 465, - "w": 71, - "h": 54 + "x": 612, + "y": 1268, + "w": 74, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 3, + "x": 0, "y": 0, - "w": 71, - "h": 54 + "w": 74, + "h": 60 }, "sourceSize": { "w": 74, @@ -29862,18 +29862,18 @@ }, "spider_02_02_001.png": { "frame": { - "x": 1988, - "y": 1700, + "x": 1608, + "y": 2241, "w": 22, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 22, - "h": 31 + "h": 32 }, "sourceSize": { "w": 22, @@ -29882,18 +29882,18 @@ }, "spider_02_02_2_001.png": { "frame": { - "x": 330, - "y": 1856, - "w": 9, - "h": 9 + "x": 816, + "y": 2242, + "w": 12, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 9, - "h": 9 + "w": 12, + "h": 18 }, "sourceSize": { "w": 12, @@ -29902,18 +29902,18 @@ }, "spider_02_02_glow_001.png": { "frame": { - "x": 1960, - "y": 1338, + "x": 941, + "y": 2278, "w": 26, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 35 + "h": 36 }, "sourceSize": { "w": 26, @@ -29922,8 +29922,8 @@ }, "spider_02_03_001.png": { "frame": { - "x": 1944, - "y": 1815, + "x": 968, + "y": 2278, "w": 20, "h": 36 }, @@ -29942,18 +29942,18 @@ }, "spider_02_03_2_001.png": { "frame": { - "x": 275, - "y": 238, - "w": 7, - "h": 12 + "x": 2286, + "y": 413, + "w": 16, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 7, - "h": 12 + "w": 16, + "h": 26 }, "sourceSize": { "w": 16, @@ -29962,8 +29962,8 @@ }, "spider_02_03_glow_001.png": { "frame": { - "x": 1762, - "y": 1930, + "x": 2262, + "y": 1514, "w": 24, "h": 40 }, @@ -29982,8 +29982,8 @@ }, "spider_02_04_001.png": { "frame": { - "x": 1982, - "y": 1585, + "x": 477, + "y": 1988, "w": 28, "h": 18 }, @@ -30002,8 +30002,8 @@ }, "spider_02_04_2_001.png": { "frame": { - "x": 260, - "y": 1329, + "x": 1032, + "y": 1670, "w": 2, "h": 2 }, @@ -30022,8 +30022,8 @@ }, "spider_02_04_glow_001.png": { "frame": { - "x": 0, - "y": 1971, + "x": 1494, + "y": 2236, "w": 32, "h": 22 }, @@ -30042,18 +30042,18 @@ }, "spider_03_01_001.png": { "frame": { - "x": 1846, - "y": 643, - "w": 54, - "h": 54 + "x": 1820, + "y": 698, + "w": 62, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 54, - "h": 54 + "w": 62, + "h": 60 }, "sourceSize": { "w": 62, @@ -30062,18 +30062,18 @@ }, "spider_03_01_2_001.png": { "frame": { - "x": 1351, - "y": 2001, - "w": 18, - "h": 17 + "x": 100, + "y": 2236, + "w": 40, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 22, + "x": 0, "y": 0, - "w": 18, - "h": 17 + "w": 40, + "h": 26 }, "sourceSize": { "w": 40, @@ -30082,18 +30082,18 @@ }, "spider_03_01_extra_001.png": { "frame": { - "x": 1904, - "y": 1658, - "w": 44, - "h": 29 + "x": 1924, + "y": 2123, + "w": 56, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 12, + "x": 0, "y": 0, - "w": 44, - "h": 29 + "w": 56, + "h": 54 }, "sourceSize": { "w": 56, @@ -30102,18 +30102,18 @@ }, "spider_03_01_glow_001.png": { "frame": { - "x": 1334, - "y": 1683, - "w": 58, - "h": 58 + "x": 1102, + "y": 1667, + "w": 66, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 58, - "h": 58 + "w": 66, + "h": 64 }, "sourceSize": { "w": 66, @@ -30122,18 +30122,18 @@ }, "spider_03_02_001.png": { "frame": { - "x": 1982, - "y": 947, + "x": 726, + "y": 2240, "w": 22, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 22, - "h": 31 + "h": 32 }, "sourceSize": { "w": 22, @@ -30142,18 +30142,18 @@ }, "spider_03_02_2_001.png": { "frame": { - "x": 2003, - "y": 442, - "w": 9, - "h": 9 + "x": 1019, + "y": 300, + "w": 12, + "h": 18 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 9, - "h": 9 + "w": 12, + "h": 18 }, "sourceSize": { "w": 12, @@ -30162,18 +30162,18 @@ }, "spider_03_02_glow_001.png": { "frame": { - "x": 1953, - "y": 37, + "x": 989, + "y": 2278, "w": 26, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 35 + "h": 36 }, "sourceSize": { "w": 26, @@ -30182,8 +30182,8 @@ }, "spider_03_03_001.png": { "frame": { - "x": 1965, - "y": 799, + "x": 1016, + "y": 2278, "w": 20, "h": 36 }, @@ -30202,18 +30202,18 @@ }, "spider_03_03_2_001.png": { "frame": { - "x": 376, - "y": 160, - "w": 7, - "h": 12 + "x": 2286, + "y": 936, + "w": 16, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 7, - "h": 12 + "w": 16, + "h": 26 }, "sourceSize": { "w": 16, @@ -30222,8 +30222,8 @@ }, "spider_03_03_glow_001.png": { "frame": { - "x": 1787, - "y": 1930, + "x": 791, + "y": 2232, "w": 24, "h": 40 }, @@ -30242,8 +30242,8 @@ }, "spider_03_04_001.png": { "frame": { - "x": 1982, - "y": 1604, + "x": 506, + "y": 1988, "w": 28, "h": 18 }, @@ -30262,8 +30262,8 @@ }, "spider_03_04_2_001.png": { "frame": { - "x": 192, - "y": 1332, + "x": 1215, + "y": 1800, "w": 2, "h": 2 }, @@ -30282,8 +30282,8 @@ }, "spider_03_04_glow_001.png": { "frame": { - "x": 33, - "y": 1971, + "x": 1819, + "y": 2277, "w": 32, "h": 22 }, @@ -30302,18 +30302,18 @@ }, "spider_04_01_001.png": { "frame": { - "x": 1670, - "y": 1209, - "w": 59, - "h": 47 + "x": 854, + "y": 2007, + "w": 60, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 59, - "h": 47 + "w": 60, + "h": 54 }, "sourceSize": { "w": 60, @@ -30322,18 +30322,18 @@ }, "spider_04_01_2_001.png": { "frame": { - "x": 896, - "y": 2004, - "w": 16, - "h": 16 + "x": 2232, + "y": 1592, + "w": 42, + "h": 24 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, + "x": 0, "y": 0, - "w": 16, - "h": 16 + "w": 42, + "h": 24 }, "sourceSize": { "w": 42, @@ -30342,18 +30342,18 @@ }, "spider_04_01_extra_001.png": { "frame": { - "x": 1111, - "y": 1202, - "w": 13, - "h": 14 + "x": 190, + "y": 2238, + "w": 40, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 27, + "x": 0, "y": 0, - "w": 13, - "h": 14 + "w": 40, + "h": 22 }, "sourceSize": { "w": 40, @@ -30362,18 +30362,18 @@ }, "spider_04_01_glow_001.png": { "frame": { - "x": 1363, - "y": 153, - "w": 63, - "h": 51 + "x": 1745, + "y": 1586, + "w": 64, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 63, - "h": 51 + "w": 64, + "h": 58 }, "sourceSize": { "w": 64, @@ -30382,18 +30382,18 @@ }, "spider_04_02_001.png": { "frame": { - "x": 1980, - "y": 318, - "w": 21, - "h": 31 + "x": 1827, + "y": 2243, + "w": 24, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 21, - "h": 31 + "y": 0, + "w": 24, + "h": 32 }, "sourceSize": { "w": 24, @@ -30402,8 +30402,8 @@ }, "spider_04_02_2_001.png": { "frame": { - "x": 864, - "y": 1372, + "x": 1428, + "y": 1735, "w": 2, "h": 2 }, @@ -30422,18 +30422,18 @@ }, "spider_04_02_glow_001.png": { "frame": { - "x": 1953, - "y": 175, - "w": 25, - "h": 35 + "x": 1037, + "y": 2278, + "w": 28, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 25, - "h": 35 + "y": 0, + "w": 28, + "h": 36 }, "sourceSize": { "w": 28, @@ -30442,18 +30442,18 @@ }, "spider_04_03_001.png": { "frame": { - "x": 689, - "y": 1927, + "x": 2144, + "y": 2231, "w": 24, - "h": 38 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 24, - "h": 38 + "h": 40 }, "sourceSize": { "w": 24, @@ -30462,8 +30462,8 @@ }, "spider_04_03_2_001.png": { "frame": { - "x": 883, - "y": 1435, + "x": 1642, + "y": 1927, "w": 2, "h": 2 }, @@ -30482,18 +30482,18 @@ }, "spider_04_03_glow_001.png": { "frame": { - "x": 1333, - "y": 1928, + "x": 240, + "y": 781, "w": 28, - "h": 42 + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, + "y": 0, "w": 28, - "h": 42 + "h": 44 }, "sourceSize": { "w": 28, @@ -30502,8 +30502,8 @@ }, "spider_04_04_001.png": { "frame": { - "x": 1982, - "y": 1623, + "x": 535, + "y": 1988, "w": 28, "h": 18 }, @@ -30522,8 +30522,8 @@ }, "spider_04_04_2_001.png": { "frame": { - "x": 1354, - "y": 1558, + "x": 1700, + "y": 645, "w": 2, "h": 2 }, @@ -30542,8 +30542,8 @@ }, "spider_04_04_glow_001.png": { "frame": { - "x": 66, - "y": 1971, + "x": 1852, + "y": 2243, "w": 32, "h": 22 }, @@ -30562,18 +30562,18 @@ }, "spider_05_01_001.png": { "frame": { - "x": 1370, - "y": 1300, - "w": 62, - "h": 53 + "x": 1491, + "y": 1462, + "w": 70, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 62, - "h": 53 + "w": 70, + "h": 62 }, "sourceSize": { "w": 70, @@ -30582,18 +30582,18 @@ }, "spider_05_01_2_001.png": { "frame": { - "x": 1670, - "y": 673, - "w": 60, - "h": 51 + "x": 1037, + "y": 1548, + "w": 68, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 60, - "h": 51 + "w": 68, + "h": 60 }, "sourceSize": { "w": 68, @@ -30602,18 +30602,18 @@ }, "spider_05_01_extra_001.png": { "frame": { - "x": 1951, - "y": 947, - "w": 30, - "h": 33 + "x": 1613, + "y": 1655, + "w": 66, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 36, + "x": 0, "y": 0, - "w": 30, - "h": 33 + "w": 66, + "h": 34 }, "sourceSize": { "w": 66, @@ -30622,18 +30622,18 @@ }, "spider_05_01_glow_001.png": { "frame": { - "x": 1231, - "y": 585, - "w": 66, - "h": 58 + "x": 363, + "y": 1268, + "w": 74, + "h": 68 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 66, - "h": 58 + "w": 74, + "h": 68 }, "sourceSize": { "w": 74, @@ -30642,9 +30642,9 @@ }, "spider_05_02_001.png": { "frame": { - "x": 1282, - "y": 1958, - "w": 25, + "x": 1852, + "y": 2277, + "w": 28, "h": 32 }, "rotated": false, @@ -30652,7 +30652,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 28, "h": 32 }, "sourceSize": { @@ -30662,9 +30662,9 @@ }, "spider_05_02_2_001.png": { "frame": { - "x": 1988, - "y": 667, - "w": 23, + "x": 2286, + "y": 326, + "w": 26, "h": 30 }, "rotated": false, @@ -30672,7 +30672,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 26, "h": 30 }, "sourceSize": { @@ -30682,9 +30682,9 @@ }, "spider_05_02_glow_001.png": { "frame": { - "x": 1936, - "y": 1930, - "w": 29, + "x": 1066, + "y": 2278, + "w": 32, "h": 36 }, "rotated": false, @@ -30692,7 +30692,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 29, + "w": 32, "h": 36 }, "sourceSize": { @@ -30702,18 +30702,18 @@ }, "spider_05_03_001.png": { "frame": { - "x": 395, - "y": 1926, - "w": 21, - "h": 37 + "x": 2169, + "y": 2231, + "w": 24, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 21, - "h": 37 + "y": 0, + "w": 24, + "h": 40 }, "sourceSize": { "w": 24, @@ -30722,19 +30722,19 @@ }, "spider_05_03_2_001.png": { "frame": { - "x": 1770, - "y": 1702, - "w": 19, - "h": 35 + "x": 1018, + "y": 896, + "w": 22, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 19, - "h": 35 - }, + "y": 0, + "w": 22, + "h": 38 + }, "sourceSize": { "w": 22, "h": 38 @@ -30742,18 +30742,18 @@ }, "spider_05_03_glow_001.png": { "frame": { - "x": 1568, - "y": 1681, - "w": 25, - "h": 41 + "x": 460, + "y": 2197, + "w": 28, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 25, - "h": 41 + "y": 0, + "w": 28, + "h": 44 }, "sourceSize": { "w": 28, @@ -30762,8 +30762,8 @@ }, "spider_05_04_001.png": { "frame": { - "x": 1982, - "y": 1642, + "x": 564, + "y": 1988, "w": 28, "h": 18 }, @@ -30782,8 +30782,8 @@ }, "spider_05_04_2_001.png": { "frame": { - "x": 599, - "y": 486, + "x": 852, + "y": 2062, "w": 2, "h": 2 }, @@ -30802,8 +30802,8 @@ }, "spider_05_04_glow_001.png": { "frame": { - "x": 99, - "y": 1971, + "x": 1881, + "y": 2277, "w": 32, "h": 22 }, @@ -30822,17 +30822,17 @@ }, "spider_06_01_001.png": { "frame": { - "x": 617, - "y": 1140, - "w": 64, + "x": 1350, + "y": 265, + "w": 72, "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 64, + "w": 72, "h": 54 }, "sourceSize": { @@ -30842,18 +30842,18 @@ }, "spider_06_01_2_001.png": { "frame": { - "x": 696, - "y": 1328, - "w": 62, - "h": 31 + "x": 1490, + "y": 839, + "w": 70, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 62, - "h": 31 + "w": 70, + "h": 40 }, "sourceSize": { "w": 70, @@ -30862,18 +30862,18 @@ }, "spider_06_01_extra_001.png": { "frame": { - "x": 817, - "y": 1990, - "w": 15, - "h": 16 + "x": 976, + "y": 2058, + "w": 48, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 33, + "x": 0, "y": 0, - "w": 15, - "h": 16 + "w": 48, + "h": 22 }, "sourceSize": { "w": 48, @@ -30882,17 +30882,17 @@ }, "spider_06_01_glow_001.png": { "frame": { - "x": 848, - "y": 1136, - "w": 68, + "x": 693, + "y": 1192, + "w": 76, "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 68, + "w": 76, "h": 58 }, "sourceSize": { @@ -30902,9 +30902,9 @@ }, "spider_06_02_001.png": { "frame": { - "x": 1308, - "y": 1958, - "w": 24, + "x": 1914, + "y": 2277, + "w": 26, "h": 32 }, "rotated": false, @@ -30912,7 +30912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, + "w": 26, "h": 32 }, "sourceSize": { @@ -30922,9 +30922,9 @@ }, "spider_06_02_2_001.png": { "frame": { - "x": 1988, - "y": 282, - "w": 22, + "x": 2288, + "y": 279, + "w": 24, "h": 30 }, "rotated": false, @@ -30932,7 +30932,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 22, + "w": 24, "h": 30 }, "sourceSize": { @@ -30942,9 +30942,9 @@ }, "spider_06_02_glow_001.png": { "frame": { - "x": 1154, - "y": 1928, - "w": 28, + "x": 1099, + "y": 2278, + "w": 30, "h": 36 }, "rotated": false, @@ -30952,7 +30952,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, + "w": 30, "h": 36 }, "sourceSize": { @@ -30962,18 +30962,18 @@ }, "spider_06_03_001.png": { "frame": { - "x": 1910, - "y": 1930, - "w": 25, - "h": 39 + "x": 1335, + "y": 2195, + "w": 26, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 25, - "h": 39 + "y": 0, + "w": 26, + "h": 40 }, "sourceSize": { "w": 26, @@ -30982,18 +30982,18 @@ }, "spider_06_03_2_001.png": { "frame": { - "x": 417, - "y": 1929, - "w": 23, - "h": 37 + "x": 467, + "y": 2274, + "w": 24, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 23, - "h": 37 + "y": 0, + "w": 24, + "h": 38 }, "sourceSize": { "w": 24, @@ -31002,18 +31002,18 @@ }, "spider_06_03_glow_001.png": { "frame": { - "x": 892, - "y": 934, - "w": 29, - "h": 43 + "x": 489, + "y": 2197, + "w": 30, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 29, - "h": 43 + "y": 0, + "w": 30, + "h": 44 }, "sourceSize": { "w": 30, @@ -31022,8 +31022,8 @@ }, "spider_06_04_001.png": { "frame": { - "x": 1498, - "y": 1971, + "x": 593, + "y": 1988, "w": 28, "h": 18 }, @@ -31042,8 +31042,8 @@ }, "spider_06_04_2_001.png": { "frame": { - "x": 1597, - "y": 1543, + "x": 1382, + "y": 1410, "w": 2, "h": 2 }, @@ -31062,8 +31062,8 @@ }, "spider_06_04_glow_001.png": { "frame": { - "x": 132, - "y": 1971, + "x": 1941, + "y": 2272, "w": 32, "h": 22 }, @@ -31082,18 +31082,18 @@ }, "spider_07_01_001.png": { "frame": { - "x": 1231, - "y": 644, - "w": 66, - "h": 53 + "x": 1490, + "y": 880, + "w": 70, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 66, - "h": 53 + "w": 70, + "h": 58 }, "sourceSize": { "w": 70, @@ -31102,18 +31102,18 @@ }, "spider_07_01_2_001.png": { "frame": { - "x": 52, - "y": 1891, - "w": 51, - "h": 34 + "x": 2066, + "y": 1128, + "w": 58, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 51, - "h": 34 + "w": 58, + "h": 36 }, "sourceSize": { "w": 58, @@ -31122,18 +31122,18 @@ }, "spider_07_01_extra_001.png": { "frame": { - "x": 1321, - "y": 913, - "w": 38, - "h": 44 + "x": 2066, + "y": 1165, + "w": 58, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 20, + "x": 0, "y": 0, - "w": 38, - "h": 44 + "w": 58, + "h": 58 }, "sourceSize": { "w": 58, @@ -31142,18 +31142,18 @@ }, "spider_07_01_glow_001.png": { "frame": { - "x": 1094, - "y": 78, - "w": 70, - "h": 57 + "x": 996, + "y": 1267, + "w": 74, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 70, - "h": 57 + "w": 74, + "h": 62 }, "sourceSize": { "w": 74, @@ -31162,18 +31162,18 @@ }, "spider_07_02_001.png": { "frame": { - "x": 937, - "y": 1966, - "w": 20, - "h": 27 + "x": 2284, + "y": 854, + "w": 28, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 20, - "h": 27 + "y": 0, + "w": 28, + "h": 30 }, "sourceSize": { "w": 28, @@ -31182,18 +31182,18 @@ }, "spider_07_02_2_001.png": { "frame": { - "x": 146, - "y": 990, - "w": 17, - "h": 7 + "x": 2286, + "y": 357, + "w": 26, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 21, - "w": 17, - "h": 7 + "y": 0, + "w": 26, + "h": 28 }, "sourceSize": { "w": 26, @@ -31202,18 +31202,18 @@ }, "spider_07_02_glow_001.png": { "frame": { - "x": 1988, - "y": 480, - "w": 24, - "h": 31 + "x": 1128, + "y": 2243, + "w": 32, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 3, - "w": 24, - "h": 31 + "y": 0, + "w": 32, + "h": 34 }, "sourceSize": { "w": 32, @@ -31222,18 +31222,18 @@ }, "spider_07_03_001.png": { "frame": { - "x": 1988, - "y": 698, - "w": 24, - "h": 30 + "x": 1456, + "y": 1343, + "w": 30, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 12, - "w": 24, - "h": 30 + "y": 0, + "w": 30, + "h": 42 }, "sourceSize": { "w": 30, @@ -31242,18 +31242,18 @@ }, "spider_07_03_2_001.png": { "frame": { - "x": 603, - "y": 1786, - "w": 16, - "h": 13 + "x": 1972, + "y": 1885, + "w": 18, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 27, - "w": 16, - "h": 13 + "y": 0, + "w": 18, + "h": 40 }, "sourceSize": { "w": 18, @@ -31262,18 +31262,18 @@ }, "spider_07_03_glow_001.png": { "frame": { - "x": 1953, - "y": 379, - "w": 29, - "h": 34 + "x": 1232, + "y": 2196, + "w": 36, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 12, - "w": 29, - "h": 34 + "y": 0, + "w": 36, + "h": 46 }, "sourceSize": { "w": 36, @@ -31282,77 +31282,77 @@ }, "spider_07_04_001.png": { "frame": { - "x": 0, - "y": 0, - "w": 0, - "h": 0 + "x": 315, + "y": 202, + "w": 1, + "h": 1 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 0, - "h": 0 + "w": 1, + "h": 1 }, "sourceSize": { - "w": 0, - "h": 0 + "w": 1, + "h": 1 } }, "spider_07_04_2_001.png": { "frame": { - "x": 0, - "y": 0, - "w": 0, - "h": 0 + "x": 677, + "y": 394, + "w": 1, + "h": 1 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 0, - "h": 0 + "w": 1, + "h": 1 }, "sourceSize": { - "w": 0, - "h": 0 + "w": 1, + "h": 1 } }, "spider_07_04_glow_001.png": { "frame": { - "x": 0, - "y": 0, - "w": 0, - "h": 0 + "x": 699, + "y": 694, + "w": 1, + "h": 1 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 0, - "h": 0 + "w": 1, + "h": 1 }, "sourceSize": { - "w": 0, - "h": 0 + "w": 1, + "h": 1 } }, "spider_08_01_001.png": { "frame": { - "x": 1090, - "y": 385, - "w": 69, + "x": 1122, + "y": 153, + "w": 78, "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 69, + "w": 78, "h": 46 }, "sourceSize": { @@ -31362,18 +31362,18 @@ }, "spider_08_01_2_001.png": { "frame": { - "x": 995, - "y": 807, - "w": 12, - "h": 24 + "x": 866, + "y": 2243, + "w": 36, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 12, - "h": 24 + "w": 36, + "h": 34 }, "sourceSize": { "w": 36, @@ -31382,18 +31382,18 @@ }, "spider_08_01_extra_001.png": { "frame": { - "x": 655, - "y": 986, - "w": 32, - "h": 11 + "x": 288, + "y": 1269, + "w": 74, + "h": 22 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 42, + "x": 0, "y": 0, - "w": 32, - "h": 11 + "w": 74, + "h": 22 }, "sourceSize": { "w": 74, @@ -31402,17 +31402,17 @@ }, "spider_08_01_glow_001.png": { "frame": { - "x": 700, - "y": 826, - "w": 73, + "x": 425, + "y": 974, + "w": 82, "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 73, + "w": 82, "h": 50 }, "sourceSize": { @@ -31422,18 +31422,18 @@ }, "spider_08_02_001.png": { "frame": { - "x": 1983, - "y": 379, - "w": 21, - "h": 31 + "x": 1974, + "y": 2272, + "w": 24, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 21, - "h": 31 + "y": 0, + "w": 24, + "h": 32 }, "sourceSize": { "w": 24, @@ -31442,18 +31442,18 @@ }, "spider_08_02_2_001.png": { "frame": { - "x": 896, - "y": 1964, - "w": 19, - "h": 29 + "x": 2290, + "y": 1580, + "w": 22, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 19, - "h": 29 + "y": 0, + "w": 22, + "h": 30 }, "sourceSize": { "w": 22, @@ -31462,18 +31462,18 @@ }, "spider_08_02_glow_001.png": { "frame": { - "x": 1953, - "y": 73, - "w": 25, - "h": 35 + "x": 1130, + "y": 2278, + "w": 28, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 25, - "h": 35 + "y": 0, + "w": 28, + "h": 36 }, "sourceSize": { "w": 28, @@ -31482,18 +31482,18 @@ }, "spider_08_03_001.png": { "frame": { - "x": 441, - "y": 1929, - "w": 20, - "h": 37 + "x": 1777, + "y": 2239, + "w": 22, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 20, - "h": 37 + "x": 0, + "y": 0, + "w": 22, + "h": 38 }, "sourceSize": { "w": 22, @@ -31502,8 +31502,8 @@ }, "spider_08_03_2_001.png": { "frame": { - "x": 884, - "y": 593, + "x": 2160, + "y": 2067, "w": 2, "h": 2 }, @@ -31522,18 +31522,18 @@ }, "spider_08_03_glow_001.png": { "frame": { - "x": 1404, - "y": 1928, - "w": 24, - "h": 41 + "x": 859, + "y": 174, + "w": 26, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 24, - "h": 41 + "x": 0, + "y": 0, + "w": 26, + "h": 42 }, "sourceSize": { "w": 26, @@ -31542,8 +31542,8 @@ }, "spider_08_04_001.png": { "frame": { - "x": 593, - "y": 1971, + "x": 622, + "y": 1988, "w": 28, "h": 18 }, @@ -31562,9 +31562,9 @@ }, "spider_08_04_2_001.png": { "frame": { - "x": 495, - "y": 1486, - "w": 25, + "x": 1155, + "y": 2066, + "w": 26, "h": 14 }, "rotated": false, @@ -31572,7 +31572,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 26, "h": 14 }, "sourceSize": { @@ -31582,8 +31582,8 @@ }, "spider_08_04_glow_001.png": { "frame": { - "x": 1333, - "y": 1971, + "x": 1944, + "y": 2243, "w": 32, "h": 22 }, @@ -31602,18 +31602,18 @@ }, "spider_09_01_001.png": { "frame": { - "x": 69, - "y": 1140, - "w": 68, - "h": 55 + "x": 1350, + "y": 320, + "w": 72, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 68, - "h": 55 + "w": 72, + "h": 66 }, "sourceSize": { "w": 72, @@ -31622,18 +31622,18 @@ }, "spider_09_01_2_001.png": { "frame": { - "x": 1904, - "y": 653, - "w": 42, - "h": 47 + "x": 0, + "y": 1548, + "w": 70, + "h": 64 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 28, + "x": 0, "y": 0, - "w": 42, - "h": 47 + "w": 70, + "h": 64 }, "sourceSize": { "w": 70, @@ -31642,18 +31642,18 @@ }, "spider_09_01_extra_001.png": { "frame": { - "x": 1981, - "y": 1000, - "w": 31, - "h": 20 + "x": 1169, + "y": 1704, + "w": 66, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 35, + "x": 0, "y": 0, - "w": 31, - "h": 20 + "w": 66, + "h": 26 }, "sourceSize": { "w": 66, @@ -31662,18 +31662,18 @@ }, "spider_09_01_glow_001.png": { "frame": { - "x": 223, - "y": 923, - "w": 72, - "h": 59 + "x": 770, + "y": 1192, + "w": 76, + "h": 70 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 72, - "h": 59 + "w": 76, + "h": 70 }, "sourceSize": { "w": 76, @@ -31682,18 +31682,18 @@ }, "spider_09_02_001.png": { "frame": { - "x": 1988, - "y": 1732, - "w": 21, - "h": 31 + "x": 1999, + "y": 2272, + "w": 24, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 21, - "h": 31 + "y": 0, + "w": 24, + "h": 32 }, "sourceSize": { "w": 24, @@ -31702,18 +31702,18 @@ }, "spider_09_02_2_001.png": { "frame": { - "x": 395, - "y": 1964, - "w": 19, - "h": 29 + "x": 2290, + "y": 1611, + "w": 22, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 19, - "h": 29 + "y": 0, + "w": 22, + "h": 30 }, "sourceSize": { "w": 22, @@ -31722,18 +31722,18 @@ }, "spider_09_02_glow_001.png": { "frame": { - "x": 1953, - "y": 211, - "w": 25, - "h": 35 + "x": 1159, + "y": 2278, + "w": 28, + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 25, - "h": 35 + "y": 0, + "w": 28, + "h": 36 }, "sourceSize": { "w": 28, @@ -31742,18 +31742,18 @@ }, "spider_09_03_001.png": { "frame": { - "x": 977, - "y": 1928, - "w": 20, - "h": 37 + "x": 291, + "y": 661, + "w": 22, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 20, - "h": 37 + "x": 0, + "y": 0, + "w": 22, + "h": 38 }, "sourceSize": { "w": 22, @@ -31762,8 +31762,8 @@ }, "spider_09_03_2_001.png": { "frame": { - "x": 1214, - "y": 769, + "x": 1473, + "y": 802, "w": 16, "h": 34 }, @@ -31782,18 +31782,18 @@ }, "spider_09_03_glow_001.png": { "frame": { - "x": 231, - "y": 1928, - "w": 24, - "h": 41 + "x": 1841, + "y": 1780, + "w": 26, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 24, - "h": 41 + "x": 0, + "y": 0, + "w": 26, + "h": 42 }, "sourceSize": { "w": 26, @@ -31802,8 +31802,8 @@ }, "spider_09_04_001.png": { "frame": { - "x": 1629, - "y": 1971, + "x": 651, + "y": 1988, "w": 28, "h": 18 }, @@ -31822,9 +31822,9 @@ }, "spider_09_04_2_001.png": { "frame": { - "x": 521, - "y": 1486, - "w": 25, + "x": 399, + "y": 2300, + "w": 26, "h": 14 }, "rotated": false, @@ -31832,7 +31832,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 26, "h": 14 }, "sourceSize": { @@ -31842,8 +31842,8 @@ }, "spider_09_04_glow_001.png": { "frame": { - "x": 165, - "y": 1971, + "x": 1977, + "y": 2243, "w": 32, "h": 22 }, @@ -31862,18 +31862,18 @@ }, "spider_10_01_001.png": { "frame": { - "x": 1094, - "y": 136, - "w": 70, - "h": 50 + "x": 1041, + "y": 630, + "w": 80, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 70, - "h": 50 + "w": 80, + "h": 58 }, "sourceSize": { "w": 80, @@ -31882,18 +31882,18 @@ }, "spider_10_01_2_001.png": { "frame": { - "x": 1732, - "y": 446, - "w": 57, - "h": 36 + "x": 1041, + "y": 689, + "w": 80, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, + "x": 0, "y": 0, - "w": 57, - "h": 36 + "w": 80, + "h": 56 }, "sourceSize": { "w": 80, @@ -31902,18 +31902,18 @@ }, "spider_10_01_extra_001.png": { "frame": { - "x": 237, - "y": 703, - "w": 23, - "h": 5 + "x": 620, + "y": 276, + "w": 56, + "h": 6 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 33, + "x": 0, "y": 0, - "w": 23, - "h": 5 + "w": 56, + "h": 6 }, "sourceSize": { "w": 56, @@ -31922,18 +31922,18 @@ }, "spider_10_01_glow_001.png": { "frame": { - "x": 0, - "y": 870, - "w": 74, - "h": 53 + "x": 765, + "y": 927, + "w": 84, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 74, - "h": 53 + "w": 84, + "h": 62 }, "sourceSize": { "w": 84, @@ -31942,18 +31942,18 @@ }, "spider_10_02_001.png": { "frame": { - "x": 1947, - "y": 1053, - "w": 23, - "h": 33 + "x": 1161, + "y": 2243, + "w": 26, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, - "h": 33 + "w": 26, + "h": 34 }, "sourceSize": { "w": 26, @@ -31962,18 +31962,18 @@ }, "spider_10_02_2_001.png": { "frame": { - "x": 938, - "y": 465, - "w": 9, - "h": 12 + "x": 1139, + "y": 1986, + "w": 12, + "h": 20 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 9, - "h": 12 + "w": 12, + "h": 20 }, "sourceSize": { "w": 12, @@ -31982,9 +31982,9 @@ }, "spider_10_02_glow_001.png": { "frame": { - "x": 1873, - "y": 1486, - "w": 28, + "x": 492, + "y": 2274, + "w": 30, "h": 38 }, "rotated": false, @@ -31992,7 +31992,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, + "w": 30, "h": 38 }, "sourceSize": { @@ -32002,18 +32002,18 @@ }, "spider_10_03_001.png": { "frame": { - "x": 1257, - "y": 1928, - "w": 24, - "h": 38 + "x": 2194, + "y": 2231, + "w": 26, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 24, - "h": 38 + "w": 26, + "h": 40 }, "sourceSize": { "w": 26, @@ -32022,18 +32022,18 @@ }, "spider_10_03_2_001.png": { "frame": { - "x": 1296, - "y": 1247, - "w": 10, - "h": 15 + "x": 1787, + "y": 2197, + "w": 12, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 10, - "h": 15 + "w": 12, + "h": 26 }, "sourceSize": { "w": 12, @@ -32042,18 +32042,18 @@ }, "spider_10_03_glow_001.png": { "frame": { - "x": 621, - "y": 1928, - "w": 28, - "h": 41 + "x": 1313, + "y": 1548, + "w": 30, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 28, - "h": 41 + "w": 30, + "h": 42 }, "sourceSize": { "w": 30, @@ -32062,8 +32062,8 @@ }, "spider_10_04_001.png": { "frame": { - "x": 804, - "y": 1971, + "x": 680, + "y": 1988, "w": 28, "h": 18 }, @@ -32082,9 +32082,9 @@ }, "spider_10_04_2_001.png": { "frame": { - "x": 1112, - "y": 1989, - "w": 25, + "x": 1614, + "y": 2183, + "w": 26, "h": 14 }, "rotated": false, @@ -32092,7 +32092,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, + "w": 26, "h": 14 }, "sourceSize": { @@ -32102,8 +32102,8 @@ }, "spider_10_04_glow_001.png": { "frame": { - "x": 1366, - "y": 1971, + "x": 2010, + "y": 2243, "w": 32, "h": 22 }, @@ -32122,18 +32122,18 @@ }, "spider_11_01_001.png": { "frame": { - "x": 1298, - "y": 224, - "w": 64, - "h": 50 + "x": 1562, + "y": 1302, + "w": 68, + "h": 56 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 64, - "h": 50 + "w": 68, + "h": 56 }, "sourceSize": { "w": 68, @@ -32142,18 +32142,18 @@ }, "spider_11_01_2_001.png": { "frame": { - "x": 1233, - "y": 1435, - "w": 61, - "h": 47 + "x": 725, + "y": 1671, + "w": 66, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 5, + "x": 0, "y": 0, - "w": 61, - "h": 47 + "w": 66, + "h": 52 }, "sourceSize": { "w": 66, @@ -32162,18 +32162,18 @@ }, "spider_11_01_extra_001.png": { "frame": { - "x": 660, - "y": 532, - "w": 19, - "h": 5 + "x": 1757, + "y": 881, + "w": 62, + "h": 12 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 43, + "x": 0, "y": 0, - "w": 19, - "h": 5 + "w": 62, + "h": 12 }, "sourceSize": { "w": 62, @@ -32182,18 +32182,18 @@ }, "spider_11_01_glow_001.png": { "frame": { - "x": 211, - "y": 1140, - "w": 68, - "h": 54 + "x": 1349, + "y": 387, + "w": 72, + "h": 60 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 68, - "h": 54 + "w": 72, + "h": 60 }, "sourceSize": { "w": 72, @@ -32202,18 +32202,18 @@ }, "spider_11_02_001.png": { "frame": { - "x": 1966, - "y": 1930, - "w": 21, - "h": 33 + "x": 1188, + "y": 2243, + "w": 22, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 21, - "h": 33 + "y": 0, + "w": 22, + "h": 34 }, "sourceSize": { "w": 22, @@ -32222,18 +32222,18 @@ }, "spider_11_02_2_001.png": { "frame": { - "x": 340, - "y": 1966, - "w": 19, - "h": 27 + "x": 2287, + "y": 1936, + "w": 20, + "h": 28 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, - "h": 27 + "w": 20, + "h": 28 }, "sourceSize": { "w": 20, @@ -32242,18 +32242,18 @@ }, "spider_11_02_glow_001.png": { "frame": { - "x": 462, - "y": 1928, - "w": 25, - "h": 37 + "x": 1335, + "y": 2236, + "w": 26, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 25, - "h": 37 + "y": 0, + "w": 26, + "h": 38 }, "sourceSize": { "w": 26, @@ -32262,18 +32262,18 @@ }, "spider_11_03_001.png": { "frame": { - "x": 998, - "y": 1928, - "w": 22, - "h": 37 + "x": 523, + "y": 2275, + "w": 24, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 22, - "h": 37 + "x": 0, + "y": 0, + "w": 24, + "h": 38 }, "sourceSize": { "w": 24, @@ -32282,18 +32282,18 @@ }, "spider_11_03_2_001.png": { "frame": { - "x": 566, - "y": 1743, - "w": 19, - "h": 31 + "x": 1019, + "y": 236, + "w": 20, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 19, - "h": 31 + "w": 20, + "h": 32 }, "sourceSize": { "w": 20, @@ -32302,18 +32302,18 @@ }, "spider_11_03_glow_001.png": { "frame": { - "x": 1230, - "y": 1928, - "w": 26, - "h": 41 + "x": 275, + "y": 364, + "w": 28, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 26, - "h": 41 + "x": 0, + "y": 0, + "w": 28, + "h": 42 }, "sourceSize": { "w": 28, @@ -32322,8 +32322,8 @@ }, "spider_11_04_001.png": { "frame": { - "x": 415, - "y": 1971, + "x": 709, + "y": 1988, "w": 28, "h": 18 }, @@ -32342,8 +32342,8 @@ }, "spider_11_04_2_001.png": { "frame": { - "x": 1272, - "y": 1736, + "x": 636, + "y": 195, "w": 2, "h": 2 }, @@ -32362,8 +32362,8 @@ }, "spider_11_04_glow_001.png": { "frame": { - "x": 198, - "y": 1971, + "x": 2024, + "y": 2272, "w": 32, "h": 22 }, @@ -32382,17 +32382,17 @@ }, "spider_12_01_001.png": { "frame": { - "x": 1670, - "y": 1257, - "w": 59, + "x": 792, + "y": 1671, + "w": 66, "h": 50 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 59, + "w": 66, "h": 50 }, "sourceSize": { @@ -32402,18 +32402,18 @@ }, "spider_12_01_2_001.png": { "frame": { - "x": 984, - "y": 1818, - "w": 55, - "h": 35 + "x": 1729, + "y": 1758, + "w": 64, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 9, + "x": 0, "y": 0, - "w": 55, - "h": 35 + "w": 64, + "h": 40 }, "sourceSize": { "w": 64, @@ -32422,17 +32422,17 @@ }, "spider_12_01_glow_001.png": { "frame": { - "x": 1363, - "y": 205, - "w": 63, + "x": 1491, + "y": 1525, + "w": 70, "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 63, + "w": 70, "h": 54 }, "sourceSize": { @@ -32442,10 +32442,10 @@ }, "spider_12_02_001.png": { "frame": { - "x": 1951, - "y": 981, + "x": 1211, + "y": 2243, "w": 22, - "h": 33 + "h": 34 }, "rotated": false, "trimmed": true, @@ -32453,7 +32453,7 @@ "x": 0, "y": 0, "w": 22, - "h": 33 + "h": 34 }, "sourceSize": { "w": 22, @@ -32462,8 +32462,8 @@ }, "spider_12_02_2_001.png": { "frame": { - "x": 551, - "y": 1846, + "x": 1273, + "y": 1917, "w": 2, "h": 2 }, @@ -32482,10 +32482,10 @@ }, "spider_12_02_glow_001.png": { "frame": { - "x": 488, - "y": 1928, + "x": 548, + "y": 2275, "w": 26, - "h": 37 + "h": 38 }, "rotated": false, "trimmed": true, @@ -32493,7 +32493,7 @@ "x": 0, "y": 0, "w": 26, - "h": 37 + "h": 38 }, "sourceSize": { "w": 26, @@ -32502,18 +32502,18 @@ }, "spider_12_03_001.png": { "frame": { - "x": 896, - "y": 1925, - "w": 20, - "h": 38 + "x": 1919, + "y": 2229, + "w": 24, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 20, - "h": 38 + "y": 0, + "w": 24, + "h": 40 }, "sourceSize": { "w": 24, @@ -32522,8 +32522,8 @@ }, "spider_12_03_2_001.png": { "frame": { - "x": 981, - "y": 1846, + "x": 800, + "y": 1474, "w": 2, "h": 2 }, @@ -32542,18 +32542,18 @@ }, "spider_12_03_glow_001.png": { "frame": { - "x": 165, - "y": 1928, - "w": 24, - "h": 42 + "x": 520, + "y": 2197, + "w": 28, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 24, - "h": 42 + "y": 0, + "w": 28, + "h": 44 }, "sourceSize": { "w": 28, @@ -32562,8 +32562,8 @@ }, "spider_12_04_001.png": { "frame": { - "x": 1527, - "y": 1971, + "x": 738, + "y": 1988, "w": 28, "h": 18 }, @@ -32582,8 +32582,8 @@ }, "spider_12_04_2_001.png": { "frame": { - "x": 53, - "y": 1888, + "x": 874, + "y": 2193, "w": 2, "h": 2 }, @@ -32602,8 +32602,8 @@ }, "spider_12_04_glow_001.png": { "frame": { - "x": 1399, - "y": 1971, + "x": 2043, + "y": 2243, "w": 32, "h": 22 }, @@ -32622,18 +32622,18 @@ }, "spider_13_01_001.png": { "frame": { - "x": 637, - "y": 261, - "w": 79, - "h": 54 + "x": 602, + "y": 851, + "w": 86, + "h": 62 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 79, - "h": 54 + "w": 86, + "h": 62 }, "sourceSize": { "w": 86, @@ -32642,18 +32642,18 @@ }, "spider_13_01_2_001.png": { "frame": { - "x": 663, - "y": 1843, - "w": 52, - "h": 38 + "x": 1613, + "y": 1690, + "w": 66, + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 14, - "y": 6, - "w": 52, - "h": 38 + "x": 0, + "y": 0, + "w": 66, + "h": 44 }, "sourceSize": { "w": 66, @@ -32662,18 +32662,18 @@ }, "spider_13_01_extra_001.png": { "frame": { - "x": 1034, - "y": 1855, - "w": 44, - "h": 22 + "x": 1311, + "y": 1410, + "w": 70, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, + "x": 0, "y": 0, - "w": 44, - "h": 22 + "w": 70, + "h": 26 }, "sourceSize": { "w": 70, @@ -32682,18 +32682,18 @@ }, "spider_13_01_glow_001.png": { "frame": { - "x": 448, - "y": 332, - "w": 83, - "h": 58 + "x": 275, + "y": 751, + "w": 90, + "h": 66 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 83, - "h": 58 + "w": 90, + "h": 66 }, "sourceSize": { "w": 90, @@ -32702,18 +32702,18 @@ }, "spider_13_02_001.png": { "frame": { - "x": 1988, - "y": 892, + "x": 2076, + "y": 2243, "w": 22, - "h": 31 + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 22, - "h": 31 + "h": 32 }, "sourceSize": { "w": 22, @@ -32722,8 +32722,8 @@ }, "spider_13_02_2_001.png": { "frame": { - "x": 714, - "y": 1888, + "x": 2229, + "y": 1557, "w": 2, "h": 2 }, @@ -32742,18 +32742,18 @@ }, "spider_13_02_glow_001.png": { "frame": { - "x": 1953, - "y": 247, + "x": 1188, + "y": 2278, "w": 26, - "h": 35 + "h": 36 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 26, - "h": 35 + "h": 36 }, "sourceSize": { "w": 26, @@ -32762,8 +32762,8 @@ }, "spider_13_03_001.png": { "frame": { - "x": 1966, - "y": 836, + "x": 1215, + "y": 2278, "w": 20, "h": 36 }, @@ -32782,8 +32782,8 @@ }, "spider_13_03_2_001.png": { "frame": { - "x": 449, - "y": 1853, + "x": 918, + "y": 1267, "w": 2, "h": 2 }, @@ -32802,8 +32802,8 @@ }, "spider_13_03_glow_001.png": { "frame": { - "x": 1812, - "y": 1930, + "x": 1894, + "y": 2236, "w": 24, "h": 40 }, @@ -32822,8 +32822,8 @@ }, "spider_13_04_001.png": { "frame": { - "x": 622, - "y": 1971, + "x": 767, + "y": 1988, "w": 28, "h": 18 }, @@ -32842,8 +32842,8 @@ }, "spider_13_04_2_001.png": { "frame": { - "x": 1889, - "y": 1353, + "x": 77, + "y": 1182, "w": 2, "h": 2 }, @@ -32862,8 +32862,8 @@ }, "spider_13_04_glow_001.png": { "frame": { - "x": 231, - "y": 1971, + "x": 2057, + "y": 2276, "w": 32, "h": 22 }, @@ -32882,18 +32882,18 @@ }, "spider_14_01_001.png": { "frame": { - "x": 296, - "y": 923, - "w": 72, - "h": 71 + "x": 0, + "y": 786, + "w": 74, + "h": 92 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 72, - "h": 71 + "w": 74, + "h": 92 }, "sourceSize": { "w": 74, @@ -32902,18 +32902,18 @@ }, "spider_14_01_2_001.png": { "frame": { - "x": 983, - "y": 1136, - "w": 68, - "h": 65 + "x": 887, + "y": 260, + "w": 70, + "h": 84 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 68, - "h": 65 + "w": 70, + "h": 84 }, "sourceSize": { "w": 70, @@ -32922,18 +32922,18 @@ }, "spider_14_01_glow_001.png": { "frame": { - "x": 801, - "y": 0, - "w": 76, - "h": 74 + "x": 622, + "y": 396, + "w": 78, + "h": 94 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 2, + "x": 0, "y": 0, - "w": 76, - "h": 74 + "w": 78, + "h": 94 }, "sourceSize": { "w": 78, @@ -32942,8 +32942,8 @@ }, "spider_14_02_001.png": { "frame": { - "x": 714, - "y": 1958, + "x": 2090, + "y": 2276, "w": 22, "h": 32 }, @@ -32962,18 +32962,18 @@ }, "spider_14_02_2_001.png": { "frame": { - "x": 1987, - "y": 1298, - "w": 19, - "h": 29 + "x": 2290, + "y": 1642, + "w": 20, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 19, - "h": 29 + "w": 20, + "h": 30 }, "sourceSize": { "w": 20, @@ -32982,8 +32982,8 @@ }, "spider_14_02_glow_001.png": { "frame": { - "x": 1954, - "y": 873, + "x": 1236, + "y": 2278, "w": 26, "h": 36 }, @@ -33002,18 +33002,18 @@ }, "spider_14_03_001.png": { "frame": { - "x": 1429, - "y": 1928, - "w": 20, - "h": 41 + "x": 275, + "y": 407, + "w": 28, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 20, - "h": 41 + "y": 0, + "w": 28, + "h": 42 }, "sourceSize": { "w": 28, @@ -33022,9 +33022,9 @@ }, "spider_14_03_2_001.png": { "frame": { - "x": 655, - "y": 923, - "w": 17, + "x": 1263, + "y": 2278, + "w": 24, "h": 36 }, "rotated": false, @@ -33032,7 +33032,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 17, + "w": 24, "h": 36 }, "sourceSize": { @@ -33042,18 +33042,18 @@ }, "spider_14_03_glow_001.png": { "frame": { - "x": 785, - "y": 352, - "w": 24, - "h": 45 + "x": 1269, + "y": 2195, + "w": 32, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, - "w": 24, - "h": 45 + "y": 0, + "w": 32, + "h": 46 }, "sourceSize": { "w": 32, @@ -33062,8 +33062,8 @@ }, "spider_14_04_001.png": { "frame": { - "x": 393, - "y": 1854, + "x": 1309, + "y": 2275, "w": 2, "h": 2 }, @@ -33082,8 +33082,8 @@ }, "spider_14_04_2_001.png": { "frame": { - "x": 1263, - "y": 988, + "x": 407, + "y": 1136, "w": 2, "h": 2 }, @@ -33102,8 +33102,8 @@ }, "spider_14_04_glow_001.png": { "frame": { - "x": 104, - "y": 1925, + "x": 510, + "y": 909, "w": 2, "h": 2 }, @@ -33122,18 +33122,18 @@ }, "spider_15_01_001.png": { "frame": { - "x": 1393, - "y": 1683, - "w": 58, - "h": 41 + "x": 1820, + "y": 759, + "w": 62, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 58, - "h": 41 + "w": 62, + "h": 42 }, "sourceSize": { "w": 62, @@ -33142,17 +33142,17 @@ }, "spider_15_01_2_001.png": { "frame": { - "x": 1434, - "y": 1889, - "w": 45, + "x": 1632, + "y": 2198, + "w": 52, "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 7, + "x": 0, "y": 0, - "w": 45, + "w": 52, "h": 38 }, "sourceSize": { @@ -33162,18 +33162,18 @@ }, "spider_15_01_extra_001.png": { "frame": { - "x": 766, - "y": 2004, - "w": 25, - "h": 16 + "x": 325, + "y": 2238, + "w": 40, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 15, + "x": 0, "y": 0, - "w": 25, - "h": 16 + "w": 40, + "h": 26 }, "sourceSize": { "w": 40, @@ -33182,18 +33182,18 @@ }, "spider_15_01_glow_001.png": { "frame": { - "x": 1387, - "y": 1354, - "w": 62, - "h": 45 + "x": 859, + "y": 1671, + "w": 66, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 4, + "x": 0, "y": 0, - "w": 62, - "h": 45 + "w": 66, + "h": 46 }, "sourceSize": { "w": 66, @@ -33202,18 +33202,18 @@ }, "spider_15_02_001.png": { "frame": { - "x": 737, - "y": 1958, - "w": 21, - "h": 32 + "x": 1234, + "y": 2243, + "w": 22, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 21, - "h": 32 + "w": 22, + "h": 34 }, "sourceSize": { "w": 22, @@ -33222,18 +33222,18 @@ }, "spider_15_02_2_001.png": { "frame": { - "x": 1997, - "y": 1981, - "w": 15, - "h": 19 + "x": 2286, + "y": 440, + "w": 16, + "h": 26 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 7, - "w": 15, - "h": 19 + "y": 0, + "w": 16, + "h": 26 }, "sourceSize": { "w": 16, @@ -33242,18 +33242,18 @@ }, "spider_15_02_glow_001.png": { "frame": { - "x": 1934, - "y": 1308, - "w": 25, - "h": 36 + "x": 575, + "y": 2275, + "w": 26, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 1, + "x": 0, "y": 0, - "w": 25, - "h": 36 + "w": 26, + "h": 38 }, "sourceSize": { "w": 26, @@ -33262,18 +33262,18 @@ }, "spider_15_03_001.png": { "frame": { - "x": 1021, - "y": 1928, - "w": 21, - "h": 37 + "x": 0, + "y": 2274, + "w": 28, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 21, - "h": 37 + "w": 28, + "h": 40 }, "sourceSize": { "w": 28, @@ -33282,18 +33282,18 @@ }, "spider_15_03_2_001.png": { "frame": { - "x": 1294, - "y": 1855, - "w": 15, - "h": 22 + "x": 2287, + "y": 1785, + "w": 20, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 8, - "w": 15, - "h": 22 + "y": 0, + "w": 20, + "h": 30 }, "sourceSize": { "w": 20, @@ -33302,18 +33302,18 @@ }, "spider_15_03_glow_001.png": { "frame": { - "x": 1837, - "y": 1930, - "w": 25, - "h": 40 + "x": 2221, + "y": 1624, + "w": 32, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 25, - "h": 40 + "w": 32, + "h": 42 }, "sourceSize": { "w": 32, @@ -33322,8 +33322,8 @@ }, "spider_15_04_001.png": { "frame": { - "x": 651, - "y": 1971, + "x": 796, + "y": 1988, "w": 28, "h": 18 }, @@ -33342,8 +33342,8 @@ }, "spider_15_04_2_001.png": { "frame": { - "x": 1230, - "y": 1925, + "x": 180, + "y": 2271, "w": 2, "h": 2 }, @@ -33362,8 +33362,8 @@ }, "spider_15_04_glow_001.png": { "frame": { - "x": 1432, - "y": 1971, + "x": 2113, + "y": 2272, "w": 32, "h": 22 }, @@ -33382,18 +33382,18 @@ }, "spider_16_01_001.png": { "frame": { - "x": 1294, - "y": 1120, - "w": 49, - "h": 64 + "x": 887, + "y": 546, + "w": 66, + "h": 82 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, + "x": 0, "y": 0, - "w": 49, - "h": 64 + "w": 66, + "h": 82 }, "sourceSize": { "w": 66, @@ -33402,38 +33402,38 @@ }, "spider_16_01_2_001.png": { "frame": { - "x": 1981, - "y": 1021, - "w": 31, - "h": 24 + "x": 2066, + "y": 1224, + "w": 58, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 27, - "y": 8, - "w": 31, - "h": 24 - }, - "sourceSize": { + "x": 0, + "y": 0, + "w": 58, + "h": 32 + }, + "sourceSize": { "w": 58, "h": 32 } }, "spider_16_01_extra_001.png": { "frame": { - "x": 1487, - "y": 1059, - "w": 19, - "h": 6 + "x": 912, + "y": 2064, + "w": 50, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 31, + "x": 0, "y": 0, - "w": 19, - "h": 6 + "w": 50, + "h": 16 }, "sourceSize": { "w": 50, @@ -33442,18 +33442,18 @@ }, "spider_16_01_glow_001.png": { "frame": { - "x": 884, - "y": 465, - "w": 53, - "h": 68 + "x": 887, + "y": 0, + "w": 70, + "h": 86 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 17, + "x": 0, "y": 0, - "w": 53, - "h": 68 + "w": 70, + "h": 86 }, "sourceSize": { "w": 70, @@ -33462,18 +33462,18 @@ }, "spider_16_02_001.png": { "frame": { - "x": 1951, - "y": 1015, - "w": 22, - "h": 33 + "x": 1257, + "y": 2243, + "w": 28, + "h": 34 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 22, - "h": 33 + "w": 28, + "h": 34 }, "sourceSize": { "w": 28, @@ -33482,18 +33482,18 @@ }, "spider_16_02_2_001.png": { "frame": { - "x": 877, - "y": 2004, - "w": 18, - "h": 15 + "x": 2287, + "y": 1816, + "w": 24, + "h": 30 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 15, - "w": 18, - "h": 15 + "y": 0, + "w": 24, + "h": 30 }, "sourceSize": { "w": 24, @@ -33502,18 +33502,18 @@ }, "spider_16_02_glow_001.png": { "frame": { - "x": 515, - "y": 1928, - "w": 26, - "h": 37 + "x": 602, + "y": 2275, + "w": 32, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, "y": 0, - "w": 26, - "h": 37 + "w": 32, + "h": 38 }, "sourceSize": { "w": 32, @@ -33522,18 +33522,18 @@ }, "spider_16_03_001.png": { "frame": { - "x": 1863, - "y": 1930, - "w": 23, - "h": 40 + "x": 2254, + "y": 1617, + "w": 28, + "h": 42 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 23, - "h": 40 + "y": 0, + "w": 28, + "h": 42 }, "sourceSize": { "w": 28, @@ -33542,18 +33542,18 @@ }, "spider_16_03_2_001.png": { "frame": { - "x": 1292, - "y": 2001, - "w": 19, - "h": 18 + "x": 635, + "y": 2275, + "w": 24, + "h": 38 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 20, - "w": 19, - "h": 18 + "y": 0, + "w": 24, + "h": 38 }, "sourceSize": { "w": 24, @@ -33562,18 +33562,18 @@ }, "spider_16_03_glow_001.png": { "frame": { - "x": 1450, - "y": 1353, - "w": 27, - "h": 44 + "x": 1302, + "y": 2195, + "w": 32, + "h": 46 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 2, - "w": 27, - "h": 44 + "y": 0, + "w": 32, + "h": 46 }, "sourceSize": { "w": 32, @@ -33582,8 +33582,8 @@ }, "spider_16_04_001.png": { "frame": { - "x": 1658, - "y": 1971, + "x": 825, + "y": 1988, "w": 28, "h": 18 }, @@ -33602,8 +33602,8 @@ }, "spider_16_04_2_001.png": { "frame": { - "x": 1480, - "y": 1927, + "x": 53, + "y": 2240, "w": 2, "h": 2 }, @@ -33622,8 +33622,8 @@ }, "spider_16_04_glow_001.png": { "frame": { - "x": 264, - "y": 1971, + "x": 2146, + "y": 2272, "w": 32, "h": 22 }, @@ -33642,18 +33642,18 @@ }, "spider_17_01_001.png": { "frame": { - "x": 1090, - "y": 187, - "w": 70, - "h": 48 + "x": 1122, + "y": 200, + "w": 78, + "h": 54 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 70, - "h": 48 + "w": 78, + "h": 54 }, "sourceSize": { "w": 78, @@ -33662,18 +33662,18 @@ }, "spider_17_01_2_001.png": { "frame": { - "x": 1231, - "y": 698, - "w": 66, - "h": 46 + "x": 1071, + "y": 1267, + "w": 74, + "h": 52 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 66, - "h": 46 + "w": 74, + "h": 52 }, "sourceSize": { "w": 74, @@ -33682,18 +33682,18 @@ }, "spider_17_01_extra_001.png": { "frame": { - "x": 498, - "y": 544, - "w": 26, - "h": 5 + "x": 1164, + "y": 1460, + "w": 70, + "h": 16 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 44, + "x": 0, "y": 0, - "w": 26, - "h": 5 + "w": 70, + "h": 16 }, "sourceSize": { "w": 70, @@ -33702,18 +33702,18 @@ }, "spider_17_01_glow_001.png": { "frame": { - "x": 75, - "y": 870, - "w": 74, - "h": 52 + "x": 765, + "y": 990, + "w": 82, + "h": 58 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 8, + "x": 0, "y": 0, - "w": 74, - "h": 52 + "w": 82, + "h": 58 }, "sourceSize": { "w": 82, @@ -33722,9 +33722,9 @@ }, "spider_17_02_001.png": { "frame": { - "x": 759, - "y": 1958, - "w": 23, + "x": 2179, + "y": 2272, + "w": 24, "h": 32 }, "rotated": false, @@ -33732,7 +33732,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 23, + "w": 24, "h": 32 }, "sourceSize": { @@ -33742,9 +33742,9 @@ }, "spider_17_02_2_001.png": { "frame": { - "x": 783, - "y": 1958, - "w": 20, + "x": 2287, + "y": 1847, + "w": 22, "h": 30 }, "rotated": false, @@ -33752,7 +33752,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 20, + "w": 22, "h": 30 }, "sourceSize": { @@ -33762,9 +33762,9 @@ }, "spider_17_02_glow_001.png": { "frame": { - "x": 1960, - "y": 910, - "w": 27, + "x": 1288, + "y": 2278, + "w": 28, "h": 36 }, "rotated": false, @@ -33772,7 +33772,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 27, + "w": 28, "h": 36 }, "sourceSize": { @@ -33782,18 +33782,18 @@ }, "spider_17_03_001.png": { "frame": { - "x": 256, - "y": 1928, + "x": 29, + "y": 2274, "w": 24, - "h": 39 + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 24, - "h": 39 + "h": 40 }, "sourceSize": { "w": 24, @@ -33802,9 +33802,9 @@ }, "spider_17_03_2_001.png": { "frame": { - "x": 1966, - "y": 1814, - "w": 21, + "x": 1286, + "y": 2242, + "w": 22, "h": 34 }, "rotated": false, @@ -33812,7 +33812,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 21, + "w": 22, "h": 34 }, "sourceSize": { @@ -33822,18 +33822,18 @@ }, "spider_17_03_glow_001.png": { "frame": { - "x": 1266, - "y": 988, + "x": 549, + "y": 2197, "w": 28, - "h": 43 + "h": 44 }, "rotated": false, "trimmed": true, "spriteSourceSize": { "x": 0, - "y": 1, + "y": 0, "w": 28, - "h": 43 + "h": 44 }, "sourceSize": { "w": 28, @@ -33842,8 +33842,8 @@ }, "spider_17_04_001.png": { "frame": { - "x": 444, - "y": 1971, + "x": 854, + "y": 1988, "w": 28, "h": 18 }, @@ -33862,8 +33862,8 @@ }, "spider_17_04_2_001.png": { "frame": { - "x": 293, - "y": 1925, + "x": 80, + "y": 2271, "w": 2, "h": 2 }, @@ -33882,8 +33882,8 @@ }, "spider_17_04_glow_001.png": { "frame": { - "x": 1465, - "y": 1971, + "x": 2204, + "y": 2272, "w": 32, "h": 22 }, @@ -33902,9 +33902,9 @@ }, "swing_01_001.png": { "frame": { - "x": 1231, - "y": 745, - "w": 66, + "x": 1349, + "y": 448, + "w": 72, "h": 60 }, "rotated": false, @@ -33912,7 +33912,7 @@ "spriteSourceSize": { "x": 0, "y": 0, - "w": 66, + "w": 72, "h": 60 }, "sourceSize": { @@ -33922,18 +33922,18 @@ }, "swing_01_2_001.png": { "frame": { - "x": 1312, - "y": 2001, - "w": 19, - "h": 19 + "x": 2232, + "y": 1667, + "w": 42, + "h": 32 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 23, + "x": 0, "y": 0, - "w": 19, - "h": 19 + "w": 42, + "h": 32 }, "sourceSize": { "w": 42, @@ -33942,33 +33942,2513 @@ }, "swing_01_extra_001.png": { "frame": { - "x": 1187, - "y": 1995, - "w": 23, - "h": 23 + "x": 2237, + "y": 245, + "w": 50, + "h": 40 }, "rotated": false, "trimmed": true, "spriteSourceSize": { - "x": 26, - "y": 1, - "w": 23, - "h": 23 + "x": 0, + "y": 0, + "w": 50, + "h": 40 }, "sourceSize": { "w": 50, "h": 40 } + }, + "swing_02_001.png": { + "frame": { + "x": 1566, + "y": 200, + "w": 69, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 69, + "h": 62 + }, + "sourceSize": { + "w": 69, + "h": 62 + } + }, + "swing_02_2_001.png": { + "frame": { + "x": 1159, + "y": 2007, + "w": 59, + "h": 58 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 59, + "h": 58 + }, + "sourceSize": { + "w": 59, + "h": 58 + } + }, + "swing_02_extra_001.png": { + "frame": { + "x": 0, + "y": 1613, + "w": 67, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 57 + }, + "sourceSize": { + "w": 67, + "h": 57 + } + }, + "swing_03_001.png": { + "frame": { + "x": 1041, + "y": 746, + "w": 79, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 79, + "h": 61 + }, + "sourceSize": { + "w": 79, + "h": 61 + } + }, + "swing_03_2_001.png": { + "frame": { + "x": 1020, + "y": 1396, + "w": 71, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 55 + }, + "sourceSize": { + "w": 71, + "h": 55 + } + }, + "swing_03_extra_001.png": { + "frame": { + "x": 1820, + "y": 802, + "w": 62, + "h": 46 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 62, + "h": 46 + }, + "sourceSize": { + "w": 62, + "h": 46 + } + }, + "swing_04_001.png": { + "frame": { + "x": 1041, + "y": 808, + "w": 79, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 79, + "h": 61 + }, + "sourceSize": { + "w": 79, + "h": 61 + } + }, + "swing_04_2_001.png": { + "frame": { + "x": 1562, + "y": 1359, + "w": 68, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 56 + }, + "sourceSize": { + "w": 68, + "h": 56 + } + }, + "swing_04_extra_001.png": { + "frame": { + "x": 172, + "y": 880, + "w": 67, + "h": 54 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 54 + }, + "sourceSize": { + "w": 67, + "h": 54 + } + }, + "swing_05_001.png": { + "frame": { + "x": 219, + "y": 1416, + "w": 71, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 60 + }, + "sourceSize": { + "w": 71, + "h": 60 + } + }, + "swing_05_2_001.png": { + "frame": { + "x": 821, + "y": 2193, + "w": 52, + "h": 48 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 52, + "h": 48 + }, + "sourceSize": { + "w": 52, + "h": 48 + } + }, + "swing_05_extra_001.png": { + "frame": { + "x": 1699, + "y": 769, + "w": 57, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 57, + "h": 56 + }, + "sourceSize": { + "w": 57, + "h": 56 + } + }, + "swing_06_001.png": { + "frame": { + "x": 881, + "y": 345, + "w": 75, + "h": 78 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 78 + }, + "sourceSize": { + "w": 75, + "h": 78 + } + }, + "swing_06_2_001.png": { + "frame": { + "x": 1067, + "y": 1055, + "w": 74, + "h": 78 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 74, + "h": 78 + }, + "sourceSize": { + "w": 74, + "h": 78 + } + }, + "swing_06_extra_001.png": { + "frame": { + "x": 1146, + "y": 1245, + "w": 62, + "h": 74 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 62, + "h": 74 + }, + "sourceSize": { + "w": 62, + "h": 74 + } + }, + "swing_07_001.png": { + "frame": { + "x": 1042, + "y": 0, + "w": 82, + "h": 81 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 82, + "h": 81 + }, + "sourceSize": { + "w": 82, + "h": 81 + } + }, + "swing_07_2_001.png": { + "frame": { + "x": 1122, + "y": 255, + "w": 78, + "h": 77 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 78, + "h": 77 + }, + "sourceSize": { + "w": 78, + "h": 77 + } + }, + "swing_07_extra_001.png": { + "frame": { + "x": 1042, + "y": 82, + "w": 82, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 82, + "h": 61 + }, + "sourceSize": { + "w": 82, + "h": 61 + } + }, + "swing_08_001.png": { + "frame": { + "x": 1349, + "y": 509, + "w": 72, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 60 + }, + "sourceSize": { + "w": 72, + "h": 60 + } + }, + "swing_08_2_001.png": { + "frame": { + "x": 1806, + "y": 2139, + "w": 55, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 56 + }, + "sourceSize": { + "w": 55, + "h": 56 + } + }, + "swing_08_extra_001.png": { + "frame": { + "x": 1745, + "y": 1645, + "w": 64, + "h": 58 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 64, + "h": 58 + }, + "sourceSize": { + "w": 64, + "h": 58 + } + }, + "swing_09_001.png": { + "frame": { + "x": 1349, + "y": 570, + "w": 72, + "h": 69 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 69 + }, + "sourceSize": { + "w": 72, + "h": 69 + } + }, + "swing_09_2_001.png": { + "frame": { + "x": 1566, + "y": 0, + "w": 70, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 70, + "h": 67 + }, + "sourceSize": { + "w": 70, + "h": 67 + } + }, + "swing_09_extra_001.png": { + "frame": { + "x": 1704, + "y": 0, + "w": 52, + "h": 65 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 52, + "h": 65 + }, + "sourceSize": { + "w": 52, + "h": 65 + } + }, + "swing_10_001.png": { + "frame": { + "x": 1122, + "y": 600, + "w": 76, + "h": 77 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 76, + "h": 77 + }, + "sourceSize": { + "w": 76, + "h": 77 + } + }, + "swing_10_2_001.png": { + "frame": { + "x": 1310, + "y": 953, + "w": 70, + "h": 72 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 70, + "h": 72 + }, + "sourceSize": { + "w": 70, + "h": 72 + } + }, + "swing_10_extra_001.png": { + "frame": { + "x": 455, + "y": 717, + "w": 55, + "h": 71 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 71 + }, + "sourceSize": { + "w": 55, + "h": 71 + } + }, + "swing_11_001.png": { + "frame": { + "x": 1239, + "y": 1376, + "w": 71, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 61 + }, + "sourceSize": { + "w": 71, + "h": 61 + } + }, + "swing_11_2_001.png": { + "frame": { + "x": 140, + "y": 1613, + "w": 67, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 57 + }, + "sourceSize": { + "w": 67, + "h": 57 + } + }, + "swing_11_extra_001.png": { + "frame": { + "x": 915, + "y": 2007, + "w": 60, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 60, + "h": 56 + }, + "sourceSize": { + "w": 60, + "h": 56 + } + }, + "swing_12_001.png": { + "frame": { + "x": 881, + "y": 87, + "w": 74, + "h": 86 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 74, + "h": 86 + }, + "sourceSize": { + "w": 74, + "h": 86 + } + }, + "swing_12_2_001.png": { + "frame": { + "x": 885, + "y": 667, + "w": 71, + "h": 84 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 84 + }, + "sourceSize": { + "w": 71, + "h": 84 + } + }, + "swing_12_extra_001.png": { + "frame": { + "x": 976, + "y": 2007, + "w": 60, + "h": 50 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 60, + "h": 50 + }, + "sourceSize": { + "w": 60, + "h": 50 + } + }, + "swing_13_001.png": { + "frame": { + "x": 436, + "y": 1416, + "w": 71, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 60 + }, + "sourceSize": { + "w": 71, + "h": 60 + } + }, + "swing_13_2_001.png": { + "frame": { + "x": 1562, + "y": 1416, + "w": 68, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 56 + }, + "sourceSize": { + "w": 68, + "h": 56 + } + }, + "swing_13_extra_001.png": { + "frame": { + "x": 1862, + "y": 2139, + "w": 56, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 55 + }, + "sourceSize": { + "w": 56, + "h": 55 + } + }, + "swing_14_001.png": { + "frame": { + "x": 850, + "y": 927, + "w": 84, + "h": 73 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 84, + "h": 73 + }, + "sourceSize": { + "w": 84, + "h": 73 + } + }, + "swing_14_2_001.png": { + "frame": { + "x": 1041, + "y": 870, + "w": 79, + "h": 68 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 79, + "h": 68 + }, + "sourceSize": { + "w": 79, + "h": 68 + } + }, + "swing_14_extra_001.png": { + "frame": { + "x": 1122, + "y": 333, + "w": 78, + "h": 64 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 78, + "h": 64 + }, + "sourceSize": { + "w": 78, + "h": 64 + } + }, + "swing_15_001.png": { + "frame": { + "x": 1348, + "y": 640, + "w": 72, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 67 + }, + "sourceSize": { + "w": 72, + "h": 67 + } + }, + "swing_15_2_001.png": { + "frame": { + "x": 1106, + "y": 1548, + "w": 68, + "h": 63 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 63 + }, + "sourceSize": { + "w": 68, + "h": 63 + } + }, + "swing_15_extra_001.png": { + "frame": { + "x": 1704, + "y": 130, + "w": 64, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 64, + "h": 57 + }, + "sourceSize": { + "w": 64, + "h": 57 + } + }, + "swing_16_001.png": { + "frame": { + "x": 1166, + "y": 1392, + "w": 71, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 67 + }, + "sourceSize": { + "w": 71, + "h": 67 + } + }, + "swing_16_2_001.png": { + "frame": { + "x": 830, + "y": 1607, + "w": 67, + "h": 63 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 63 + }, + "sourceSize": { + "w": 67, + "h": 63 + } + }, + "swing_16_extra_001.png": { + "frame": { + "x": 1702, + "y": 1176, + "w": 54, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 54, + "h": 62 + }, + "sourceSize": { + "w": 54, + "h": 62 + } + }, + "swing_17_001.png": { + "frame": { + "x": 1348, + "y": 708, + "w": 72, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 61 + }, + "sourceSize": { + "w": 72, + "h": 61 + } + }, + "swing_17_2_001.png": { + "frame": { + "x": 1566, + "y": 263, + "w": 69, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 69, + "h": 57 + }, + "sourceSize": { + "w": 69, + "h": 57 + } + }, + "swing_17_extra_001.png": { + "frame": { + "x": 1254, + "y": 2138, + "w": 54, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 54, + "h": 56 + }, + "sourceSize": { + "w": 54, + "h": 56 + } + }, + "swing_18_001.png": { + "frame": { + "x": 728, + "y": 1414, + "w": 71, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 61 + }, + "sourceSize": { + "w": 71, + "h": 61 + } + }, + "swing_18_2_001.png": { + "frame": { + "x": 208, + "y": 1613, + "w": 67, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 57 + }, + "sourceSize": { + "w": 67, + "h": 57 + } + }, + "swing_18_extra_001.png": { + "frame": { + "x": 1309, + "y": 2138, + "w": 53, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 53, + "h": 56 + }, + "sourceSize": { + "w": 53, + "h": 56 + } + }, + "swing_19_001.png": { + "frame": { + "x": 414, + "y": 649, + "w": 96, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 67 + }, + "sourceSize": { + "w": 96, + "h": 67 + } + }, + "swing_19_2_001.png": { + "frame": { + "x": 958, + "y": 0, + "w": 83, + "h": 63 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 83, + "h": 63 + }, + "sourceSize": { + "w": 83, + "h": 63 + } + }, + "swing_19_extra_001.png": { + "frame": { + "x": 1699, + "y": 706, + "w": 57, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 57, + "h": 62 + }, + "sourceSize": { + "w": 57, + "h": 62 + } + }, + "swing_20_001.png": { + "frame": { + "x": 958, + "y": 64, + "w": 83, + "h": 73 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 83, + "h": 73 + }, + "sourceSize": { + "w": 83, + "h": 73 + } + }, + "swing_20_2_001.png": { + "frame": { + "x": 1122, + "y": 398, + "w": 78, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 78, + "h": 67 + }, + "sourceSize": { + "w": 78, + "h": 67 + } + }, + "swing_20_extra_001.png": { + "frame": { + "x": 1236, + "y": 1656, + "w": 60, + "h": 66 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 60, + "h": 66 + }, + "sourceSize": { + "w": 60, + "h": 66 + } + }, + "swing_21_001.png": { + "frame": { + "x": 75, + "y": 786, + "w": 73, + "h": 91 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 73, + "h": 91 + }, + "sourceSize": { + "w": 73, + "h": 91 + } + }, + "swing_21_2_001.png": { + "frame": { + "x": 887, + "y": 174, + "w": 68, + "h": 85 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 85 + }, + "sourceSize": { + "w": 68, + "h": 85 + } + }, + "swing_21_extra_001.png": { + "frame": { + "x": 901, + "y": 424, + "w": 56, + "h": 77 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 77 + }, + "sourceSize": { + "w": 56, + "h": 77 + } + }, + "swing_22_001.png": { + "frame": { + "x": 1276, + "y": 234, + "w": 73, + "h": 73 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 73, + "h": 73 + }, + "sourceSize": { + "w": 73, + "h": 73 + } + }, + "swing_22_2_001.png": { + "frame": { + "x": 1565, + "y": 321, + "w": 68, + "h": 69 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 69 + }, + "sourceSize": { + "w": 68, + "h": 69 + } + }, + "swing_22_extra_001.png": { + "frame": { + "x": 1363, + "y": 2138, + "w": 55, + "h": 51 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 51 + }, + "sourceSize": { + "w": 55, + "h": 51 + } + }, + "swing_23_001.png": { + "frame": { + "x": 1265, + "y": 742, + "w": 71, + "h": 74 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 74 + }, + "sourceSize": { + "w": 71, + "h": 74 + } + }, + "swing_23_2_001.png": { + "frame": { + "x": 1565, + "y": 391, + "w": 67, + "h": 69 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 69 + }, + "sourceSize": { + "w": 67, + "h": 69 + } + }, + "swing_23_extra_001.png": { + "frame": { + "x": 1487, + "y": 1588, + "w": 58, + "h": 67 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 58, + "h": 67 + }, + "sourceSize": { + "w": 58, + "h": 67 + } + }, + "swing_24_001.png": { + "frame": { + "x": 998, + "y": 1135, + "w": 75, + "h": 74 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 74 + }, + "sourceSize": { + "w": 75, + "h": 74 + } + }, + "swing_24_2_001.png": { + "frame": { + "x": 1333, + "y": 817, + "w": 72, + "h": 70 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 70 + }, + "sourceSize": { + "w": 72, + "h": 70 + } + }, + "swing_24_extra_001.png": { + "frame": { + "x": 1566, + "y": 68, + "w": 70, + "h": 68 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 70, + "h": 68 + }, + "sourceSize": { + "w": 70, + "h": 68 + } + }, + "swing_25_001.png": { + "frame": { + "x": 0, + "y": 1057, + "w": 79, + "h": 79 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 79, + "h": 79 + }, + "sourceSize": { + "w": 79, + "h": 79 + } + }, + "swing_25_2_001.png": { + "frame": { + "x": 847, + "y": 1190, + "w": 73, + "h": 76 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 73, + "h": 76 + }, + "sourceSize": { + "w": 73, + "h": 76 + } + }, + "swing_26_001.png": { + "frame": { + "x": 1346, + "y": 888, + "w": 72, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 60 + }, + "sourceSize": { + "w": 72, + "h": 60 + } + }, + "swing_26_2_001.png": { + "frame": { + "x": 1769, + "y": 242, + "w": 42, + "h": 54 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 42, + "h": 54 + }, + "sourceSize": { + "w": 42, + "h": 54 + } + }, + "swing_26_extra_001.png": { + "frame": { + "x": 2237, + "y": 286, + "w": 50, + "h": 39 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 50, + "h": 39 + }, + "sourceSize": { + "w": 50, + "h": 39 + } + }, + "swing_27_001.png": { + "frame": { + "x": 1282, + "y": 1215, + "w": 72, + "h": 70 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 70 + }, + "sourceSize": { + "w": 72, + "h": 70 + } + }, + "swing_27_2_001.png": { + "frame": { + "x": 1297, + "y": 1656, + "w": 65, + "h": 66 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 65, + "h": 66 + }, + "sourceSize": { + "w": 65, + "h": 66 + } + }, + "swing_27_extra_001.png": { + "frame": { + "x": 2232, + "y": 1700, + "w": 41, + "h": 30 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 41, + "h": 30 + }, + "sourceSize": { + "w": 41, + "h": 30 + } + }, + "swing_28_001.png": { + "frame": { + "x": 1291, + "y": 1144, + "w": 72, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 60 + }, + "sourceSize": { + "w": 72, + "h": 60 + } + }, + "swing_28_2_001.png": { + "frame": { + "x": 1562, + "y": 1473, + "w": 68, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 57 + }, + "sourceSize": { + "w": 68, + "h": 57 + } + }, + "swing_29_001.png": { + "frame": { + "x": 947, + "y": 1410, + "w": 71, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 61 + }, + "sourceSize": { + "w": 71, + "h": 61 + } + }, + "swing_29_2_001.png": { + "frame": { + "x": 1704, + "y": 188, + "w": 64, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 64, + "h": 57 + }, + "sourceSize": { + "w": 64, + "h": 57 + } + }, + "swing_29_extra_001.png": { + "frame": { + "x": 1219, + "y": 2007, + "w": 59, + "h": 37 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 59, + "h": 37 + }, + "sourceSize": { + "w": 59, + "h": 37 + } + }, + "swing_30_001.png": { + "frame": { + "x": 1297, + "y": 1083, + "w": 72, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 60 + }, + "sourceSize": { + "w": 72, + "h": 60 + } + }, + "swing_30_2_001.png": { + "frame": { + "x": 1363, + "y": 1656, + "w": 66, + "h": 50 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 66, + "h": 50 + }, + "sourceSize": { + "w": 66, + "h": 50 + } + }, + "swing_30_extra_001.png": { + "frame": { + "x": 1562, + "y": 1531, + "w": 68, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 56 + }, + "sourceSize": { + "w": 68, + "h": 56 + } + }, + "swing_31_001.png": { + "frame": { + "x": 1312, + "y": 1286, + "w": 72, + "h": 60 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 60 + }, + "sourceSize": { + "w": 72, + "h": 60 + } + }, + "swing_31_2_001.png": { + "frame": { + "x": 1175, + "y": 1548, + "w": 68, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 57 + }, + "sourceSize": { + "w": 68, + "h": 57 + } + }, + "swing_31_extra_001.png": { + "frame": { + "x": 1439, + "y": 1613, + "w": 47, + "h": 40 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 47, + "h": 40 + }, + "sourceSize": { + "w": 47, + "h": 40 + } + }, + "swing_32_001.png": { + "frame": { + "x": 1244, + "y": 1548, + "w": 68, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 61 + }, + "sourceSize": { + "w": 68, + "h": 61 + } + }, + "swing_32_2_001.png": { + "frame": { + "x": 1690, + "y": 648, + "w": 65, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 65, + "h": 57 + }, + "sourceSize": { + "w": 65, + "h": 57 + } + }, + "swing_32_extra_001.png": { + "frame": { + "x": 2066, + "y": 1257, + "w": 58, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 58, + "h": 55 + }, + "sourceSize": { + "w": 58, + "h": 55 + } + }, + "swing_33_001.png": { + "frame": { + "x": 1312, + "y": 1347, + "w": 72, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 62 + }, + "sourceSize": { + "w": 72, + "h": 62 + } + }, + "swing_33_2_001.png": { + "frame": { + "x": 71, + "y": 1611, + "w": 68, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 57 + }, + "sourceSize": { + "w": 68, + "h": 57 + } + }, + "swing_33_extra_001.png": { + "frame": { + "x": 1037, + "y": 2007, + "w": 60, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 60, + "h": 56 + }, + "sourceSize": { + "w": 60, + "h": 56 + } + }, + "swing_34_001.png": { + "frame": { + "x": 73, + "y": 1405, + "w": 72, + "h": 59 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 59 + }, + "sourceSize": { + "w": 72, + "h": 59 + } + }, + "swing_34_2_001.png": { + "frame": { + "x": 485, + "y": 1609, + "w": 67, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 55 + }, + "sourceSize": { + "w": 67, + "h": 55 + } + }, + "swing_34_extra_001.png": { + "frame": { + "x": 1704, + "y": 246, + "w": 64, + "h": 54 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 64, + "h": 54 + }, + "sourceSize": { + "w": 64, + "h": 54 + } + }, + "swing_35_001.png": { + "frame": { + "x": 1092, + "y": 1414, + "w": 71, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 71, + "h": 62 + }, + "sourceSize": { + "w": 71, + "h": 62 + } + }, + "swing_35_2_001.png": { + "frame": { + "x": 1745, + "y": 1704, + "w": 62, + "h": 53 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 62, + "h": 53 + }, + "sourceSize": { + "w": 62, + "h": 53 + } + }, + "swing_35_extra_001.png": { + "frame": { + "x": 1317, + "y": 2278, + "w": 34, + "h": 28 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 34, + "h": 28 + }, + "sourceSize": { + "w": 34, + "h": 28 + } + }, + "swing_36_001.png": { + "frame": { + "x": 363, + "y": 1398, + "w": 72, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 62 + }, + "sourceSize": { + "w": 72, + "h": 62 + } + }, + "swing_36_2_001.png": { + "frame": { + "x": 1430, + "y": 1656, + "w": 66, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 66, + "h": 55 + }, + "sourceSize": { + "w": 66, + "h": 55 + } + }, + "swing_36_extra_001.png": { + "frame": { + "x": 1279, + "y": 2007, + "w": 59, + "h": 52 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 59, + "h": 52 + }, + "sourceSize": { + "w": 59, + "h": 52 + } + }, + "swing_37_001.png": { + "frame": { + "x": 1566, + "y": 137, + "w": 70, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 70, + "h": 62 + }, + "sourceSize": { + "w": 70, + "h": 62 + } + }, + "swing_37_2_001.png": { + "frame": { + "x": 2066, + "y": 1313, + "w": 58, + "h": 58 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 58, + "h": 58 + }, + "sourceSize": { + "w": 58, + "h": 58 + } + }, + "swing_37_extra_001.png": { + "frame": { + "x": 1701, + "y": 380, + "w": 55, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 57 + }, + "sourceSize": { + "w": 55, + "h": 57 + } + }, + "swing_38_001.png": { + "frame": { + "x": 921, + "y": 1155, + "w": 76, + "h": 62 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 76, + "h": 62 + }, + "sourceSize": { + "w": 76, + "h": 62 + } + }, + "swing_38_2_001.png": { + "frame": { + "x": 1339, + "y": 2007, + "w": 59, + "h": 57 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 59, + "h": 57 + }, + "sourceSize": { + "w": 59, + "h": 57 + } + }, + "swing_38_extra_001.png": { + "frame": { + "x": 2182, + "y": 956, + "w": 53, + "h": 53 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 53, + "h": 53 + }, + "sourceSize": { + "w": 53, + "h": 53 + } + }, + "swing_39_001.png": { + "frame": { + "x": 1276, + "y": 172, + "w": 74, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 74, + "h": 61 + }, + "sourceSize": { + "w": 74, + "h": 61 + } + }, + "swing_39_2_001.png": { + "frame": { + "x": 278, + "y": 1609, + "w": 68, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 68, + "h": 55 + }, + "sourceSize": { + "w": 68, + "h": 55 + } + }, + "swing_39_extra_001.png": { + "frame": { + "x": 1419, + "y": 2138, + "w": 55, + "h": 52 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 52 + }, + "sourceSize": { + "w": 55, + "h": 52 + } + }, + "swing_40_001.png": { + "frame": { + "x": 801, + "y": 1412, + "w": 72, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 72, + "h": 61 + }, + "sourceSize": { + "w": 72, + "h": 61 + } + }, + "swing_40_2_001.png": { + "frame": { + "x": 1218, + "y": 1866, + "w": 57, + "h": 50 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 57, + "h": 50 + }, + "sourceSize": { + "w": 57, + "h": 50 + } + }, + "swing_40_extra_001.png": { + "frame": { + "x": 2180, + "y": 1570, + "w": 48, + "h": 53 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 53 + }, + "sourceSize": { + "w": 48, + "h": 53 + } + }, + "swing_41_001.png": { + "frame": { + "x": 1122, + "y": 678, + "w": 77, + "h": 65 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 77, + "h": 65 + }, + "sourceSize": { + "w": 77, + "h": 65 + } + }, + "swing_41_2_001.png": { + "frame": { + "x": 1276, + "y": 308, + "w": 73, + "h": 61 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 73, + "h": 61 + }, + "sourceSize": { + "w": 73, + "h": 61 + } + }, + "swing_41_extra_001.png": { + "frame": { + "x": 1098, + "y": 2007, + "w": 60, + "h": 55 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 60, + "h": 55 + }, + "sourceSize": { + "w": 60, + "h": 55 + } + }, + "swing_42_001.png": { + "frame": { + "x": 1122, + "y": 466, + "w": 78, + "h": 76 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 78, + "h": 76 + }, + "sourceSize": { + "w": 78, + "h": 76 + } + }, + "swing_42_2_001.png": { + "frame": { + "x": 998, + "y": 1210, + "w": 75, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 56 + }, + "sourceSize": { + "w": 75, + "h": 56 + } + }, + "swing_42_extra_001.png": { + "frame": { + "x": 1074, + "y": 1134, + "w": 67, + "h": 75 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 67, + "h": 75 + }, + "sourceSize": { + "w": 67, + "h": 75 + } + }, + "swing_43_001.png": { + "frame": { + "x": 170, + "y": 980, + "w": 81, + "h": 75 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 81, + "h": 75 + }, + "sourceSize": { + "w": 81, + "h": 75 + } + }, + "swing_43_2_001.png": { + "frame": { + "x": 1122, + "y": 543, + "w": 78, + "h": 56 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 78, + "h": 56 + }, + "sourceSize": { + "w": 78, + "h": 56 + } + }, + "swing_43_extra_001.png": { + "frame": { + "x": 1269, + "y": 817, + "w": 63, + "h": 74 + }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 63, + "h": 74 + }, + "sourceSize": { + "w": 63, + "h": 74 + } } }, "meta": { "app": "https://gdcolon.com/gdsplitter/", "version": "1.0", - "image": "GJ_GameSheetIcons-hd.png", + "image": "GJ_GameSheetIcons.png", "format": "RGBA8888", "size": { - "w": 2012, - "h": 2020 + "w": 2312, + "h": 2314 }, "scale": 1 } diff --git a/assets/sheets/GJ_GameSheetIcons.png b/assets/sheets/GJ_GameSheetIcons.png index 9767a486..cb1df7b6 100644 Binary files a/assets/sheets/GJ_GameSheetIcons.png and b/assets/sheets/GJ_GameSheetIcons.png differ