diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 0000000..460f782 --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,43 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy static content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire repository + path: '.' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/README.md b/README.md index 44a7a05..8b5f5ed 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ - **Different Gamemodes** - Multiple working gamemodes such as the Ball, Wave, Cube, UFO, Mini portals and Speed portals! - **Practice Mode** - Practice mode is still very buggy at the time. Currently, you can press Z to add a checkpoint, or X to delete a checkpoint, and P to enable and disable Practice mode! - **Extra Settingss** - You can enable and disable Noclip or Show Hitboxes from the pause menu in a level, along with other settings, like the level percentage! +- **Low Detail Mode (LDM)** - Automatically enables on low-performance devices to improve frame rate by disabling particle effects and optimizing rendering. Can be manually controlled via URL parameter (?ldm) or localStorage. ## What we hope to see added in the future: - **All Gamemodes** - This will allow every official main level to be playable, along with others that require currently un-implemented gamemodes. diff --git a/assets/scripts/core/game-scene.js b/assets/scripts/core/game-scene.js index c9180b7..61335b6 100644 --- a/assets/scripts/core/game-scene.js +++ b/assets/scripts/core/game-scene.js @@ -169,31 +169,33 @@ class GameScene extends Phaser.Scene { 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); + if (!window.lowDetailMode) { + 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.additiveContainer.setVisible(false); @@ -278,33 +280,35 @@ this._menuUpdateLogBtn = this.add.image(screenWidth - 30 - 50, 33, "GJ_WebSheet" this._makeBouncyButton(this._menuNewgroundsBtn, 0.8, () => { 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); + if (!window.lowDetailMode) { + 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_WebSheet", "GJ_playBtn_001.png").setScrollFactor(0).setDepth(30).setInteractive(); this._playBtnPressed = false; this._makeBouncyButton(this._playBtn, 1, () => { @@ -2262,10 +2266,12 @@ this._menuUpdateLogBtn = this.add.image(screenWidth - 30 - 50, 33, "GJ_WebSheet" this._restartLevel(); } toggleGlitter(_0x34c21a) { - if (_0x34c21a) { - this._glitterEmitter.start(); - } else { - this._glitterEmitter.stop(); + if (this._glitterEmitter) { + if (_0x34c21a) { + this._glitterEmitter.start(); + } else { + this._glitterEmitter.stop(); + } } } _setParticleTimeScale(timeScale) { @@ -2569,6 +2575,23 @@ _buildSettingsPopup() { () => window.solidWave, (v) => window.solidWave = v ); + createToggle(container, column1X, startY + (spacingY * 4), "Low Detail Mode (Refresh Required)", + () => window.lowDetailMode, + (v) => { + window.lowDetailMode = v; + localStorage.setItem("lowDetailMode", v); + let S = v ? Phaser.BlendModes.NORMAL : Phaser.BlendModes.ADD; + if (this.game && this.game.renderer) { + this.game.renderer.pipelines && this.game.renderer.gl && ( + this.game.renderer.gl.disable(this.game.renderer.gl.BLEND) + ); + } + if (this.game && this.game.canvas) { + const ctx = this.game.canvas.getContext('2d'); + if (ctx) ctx.imageSmoothingEnabled = !v; + } + } + ); }; const buildPage = (idx) => { @@ -2599,7 +2622,8 @@ _buildSettingsPopup() { hitboxTrail: window.showHitboxTrail, showFPS: this._fpsText.visible, solidWaveTrail: window.solidWave, - noclipAccuracy: window.noClipAccuracy + noclipAccuracy: window.noClipAccuracy, + lowDetailMode: window.lowDetailMode }; localStorage.setItem("gd_settings", JSON.stringify(settings)); } @@ -2614,7 +2638,8 @@ _buildSettingsPopup() { hitboxTrail: false, showFPS: false, solidWaveTrail: false, - noclipAccuracy: false + noclipAccuracy: false, + lowDetailMode: window.lowDetailMode }; const data = saved ? JSON.parse(saved) : defaults; @@ -2628,6 +2653,14 @@ _buildSettingsPopup() { this._fpsText.visible = data.showFPS; window.solidWave = data.solidWaveTrail; window.noClipAccuracy = data.noclipAccuracy; + // lowDetailMode already set by config.js; only override if explicitly saved + if (data.lowDetailMode !== undefined && saved) { + window.lowDetailMode = data.lowDetailMode; + } + if (window.lowDetailMode && this.game && this.game.canvas) { + const ctx = this.game.canvas.getContext('2d'); + if (ctx) ctx.imageSmoothingEnabled = false; + } } _buildInfoPopup() { @@ -2664,7 +2697,7 @@ _buildSettingsPopup() { const _0x3cdf70c = this.add.bitmapText(xPos, yPos, "goldFont", "bog, AntiMatter, arbstro, aloaf", 40).setOrigin(0.5, 0.5).setScale(0.6); this._infoPopup.add(_0x3cdf70c); yPos += 35; - const _0x3cdf70d = this.add.bitmapText(xPos, yPos, "goldFont", "t0nchi7 and Lasokar.", 40).setOrigin(0.5, 0.5).setScale(0.6); + const _0x3cdf70d = this.add.bitmapText(xPos, yPos, "goldFont", "t0nchi7, Lasokar & POW_Boy1.", 40).setOrigin(0.5, 0.5).setScale(0.6); this._infoPopup.add(_0x3cdf70d); yPos += 35; const _0x97b2a9 = this.add.text(xPos, 463, "© 2026 RobTop Games. All rights reserved.", { @@ -2715,22 +2748,17 @@ _buildSettingsPopup() { bounceContainer.add(contentContainer); /* colors for reference 0xff6666 - 0xff9944 + 0xff9944 - important notes 0xaaddff - fun messages from me :) 0xff00ff - pink dev entries + 0xd98282 - POW_Boy1 entries */ const updateEntries = [ { text: "Update Log", scale: 0.85, font: "goldFont" }, - { text: "Accurate Featured tab demo.", scale: 0.65 }, - { text: "Info popups.", scale: 0.65 }, - { text: "Main menu buttons.", scale: 0.65 }, - { text: "Settings, Stats and Newgrounds.", scale: 0.65 }, - { text: "Fixed being able to go to the level selector while in menus.", scale: 0.35 }, - { text: "GD accurate loading screen.", scale: 0.65 }, - { text: "UI tweaks.", scale: 0.65 }, - { text: "Bug fixes.", scale: 0.65 }, - { text: "is this update finally out?", scale: 0.65, color: 0xaaddff }, - { text: "- rohanis0000", scale: 0.65, color: 0xaaddff }, + { text: "Added LDM (Low Detail Mode).", scale: 0.65 }, + { text: "LDM is automatically enabled on trash devices.", scale: 0.45, color: 0xff9944 }, + { text: "WSP People!", scale: 0.65, color: 0xd98282 }, + { text: "- POW_Boy1", scale: 0.65, color: 0xd98282 }, ]; let yPos = 0; const lineItems = []; @@ -3453,7 +3481,9 @@ _buildSettingsPopup() { this._player2.setShipVisible(false); this._player2.setBallVisible(false); this._player2.setWaveVisible(false); - this._glitterEmitter.stop(); + if (this._glitterEmitter) { + this._glitterEmitter.stop(); + } let speedKey = parseInt(window.settingsMap["kA4"] || "0"); if (speedKey == 0) { playerSpeed = SpeedPortal.ONE_TIMES; @@ -4040,50 +4070,52 @@ _buildSettingsPopup() { } } 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); + if (!window.lowDetailMode) { + 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) {} } - } catch(e) {} } } let quantizedDelta = this._quantizeDelta(deltaTime); @@ -4329,10 +4361,12 @@ _applyMirrorEffect() { 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)); + if (!window.lowDetailMode) { + 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); } - circleEffect(this, _0x356782, _0x2d967b, 10, 1000, 500, true, false, window.mainColor); this._showCompleteEffect(); } _showCompleteEffect() { @@ -4418,7 +4452,9 @@ _applyMirrorEffect() { } }); })(this, this._level.endXPos - this._cameraX + 60, b(this._endPortalGameY) + this._cameraY, window.mainColor); - this.cameras.main.shake(1950, 0.004); + if (!window.lowDetailMode) { + this.cameras.main.shake(1950, 0.004); + } this.time.delayedCall(1950, () => this._showCompleteText()); } _showCompleteText() { @@ -4445,49 +4481,53 @@ _applyMirrorEffect() { } }); 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); + if (!window.lowDetailMode) { + 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)); + if (!window.lowDetailMode) { + 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()); } @@ -4990,33 +5030,35 @@ _applyMirrorEffect() { 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); + if (!window.lowDetailMode) { + 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 @@ -5567,4 +5609,4 @@ _applyMirrorEffect() { duration: 500 }); } -} +} \ No newline at end of file diff --git a/assets/scripts/core/level.js b/assets/scripts/core/level.js index 25c64ac..661693d 100644 --- a/assets/scripts/core/level.js +++ b/assets/scripts/core/level.js @@ -787,109 +787,113 @@ window.LevelObject = class LevelObject { for (let levelObj of _0x35f1ae) { let objectDef = getObjectFromId(levelObj.id); if (objectDef && objectDef.type === triggerType) { - if (levelObj.id === 29 || levelObj.id === 30) { - this._colorTriggers.push({ - x: levelObj.x * 2, - index: levelObj.id === 29 ? 1000 : 1001, - color: { - r: parseInt(levelObj._raw[7] ?? 255, 10), - g: parseInt(levelObj._raw[8] ?? 255, 10), - b: parseInt(levelObj._raw[9] ?? 255, 10) - }, - duration: parseFloat(levelObj._raw[10] ?? 0), - tintGround: levelObj._raw[14] === "1" - }); - } - if (objectDef.enterEffect) { - this._enterEffectTriggers.push({ - x: levelObj.x * 2, - effect: objectDef.enterEffect - }); - } - if (levelObj.id === 901) { - const _raw = levelObj._raw; - this._moveTriggers.push({ - x: levelObj.x * 2, - duration: parseFloat(_raw[10] ?? 0), - easingType: parseInt(_raw[30] ?? 0, 10), - easingRate: parseFloat(_raw[85] ?? 2), - targetGroup: parseInt(_raw[51] ?? 0, 10), - offsetX: parseFloat(_raw[28] ?? 0) * 2, - offsetY: parseFloat(_raw[29] ?? 0) * 2, - lockX: _raw[58] === '1', - lockY: _raw[59] === '1', - }); - } - if (levelObj.id === 1007) { - const _raw = levelObj._raw; - this._alphaTriggers.push({ - x: levelObj.x * 2, - duration: parseFloat(_raw[10] ?? 0), - targetGroup: parseInt(_raw[51] ?? 0, 10), - targetOpacity: Math.max(0, Math.min(1, parseFloat(_raw[35] ?? 1))), + // Always load start positions even in LDM + if (levelObj.id === 31) { + this._startPositions.push({ + x: 2 * levelObj.x, + y: 2 * levelObj.y, + gameMode: levelObj.gameMode, + miniMode: levelObj.miniMode, + speed: levelObj.speed, + mirrored: levelObj.mirrored, + gravityFlipped: levelObj.flipGravity }); } - if (levelObj.id === 899) { - const _raw = levelObj._raw; - const targetChannel = parseInt(_raw[23] ?? 0, 10); - if (targetChannel > 0) { + // Skip other triggers in LDM mode + if (!window.lowDetailMode) { + if (levelObj.id === 29 || levelObj.id === 30) { this._colorTriggers.push({ x: levelObj.x * 2, - index: targetChannel, + index: levelObj.id === 29 ? 1000 : 1001, + color: { + r: parseInt(levelObj._raw[7] ?? 255, 10), + g: parseInt(levelObj._raw[8] ?? 255, 10), + b: parseInt(levelObj._raw[9] ?? 255, 10) + }, + duration: parseFloat(levelObj._raw[10] ?? 0), + tintGround: levelObj._raw[14] === "1" + }); + } + if (objectDef.enterEffect) { + this._enterEffectTriggers.push({ + x: levelObj.x * 2, + effect: objectDef.enterEffect + }); + } + if (levelObj.id === 901) { + const _raw = levelObj._raw; + this._moveTriggers.push({ + x: levelObj.x * 2, + duration: parseFloat(_raw[10] ?? 0), + easingType: parseInt(_raw[30] ?? 0, 10), + easingRate: parseFloat(_raw[85] ?? 2), + targetGroup: parseInt(_raw[51] ?? 0, 10), + offsetX: parseFloat(_raw[28] ?? 0) * 2, + offsetY: parseFloat(_raw[29] ?? 0) * 2, + lockX: _raw[58] === '1', + lockY: _raw[59] === '1', + }); + } + if (levelObj.id === 1007) { + const _raw = levelObj._raw; + this._alphaTriggers.push({ + x: levelObj.x * 2, + duration: parseFloat(_raw[10] ?? 0), + targetGroup: parseInt(_raw[51] ?? 0, 10), + targetOpacity: Math.max(0, Math.min(1, parseFloat(_raw[35] ?? 1))), + }); + } + if (levelObj.id === 899) { + const _raw = levelObj._raw; + const targetChannel = parseInt(_raw[23] ?? 0, 10); + if (targetChannel > 0) { + this._colorTriggers.push({ + x: levelObj.x * 2, + index: targetChannel, + color: { + r: parseInt(_raw[7] ?? 255, 10), + g: parseInt(_raw[8] ?? 255, 10), + b: parseInt(_raw[9] ?? 255, 10) + }, + duration: parseFloat(_raw[10] ?? 0), + tintGround: _raw[14] === "1", + opacity: parseFloat(_raw[35] ?? 1) + }); + } + } + if (levelObj.id === 1346) { + const _raw = levelObj._raw; + this._rotateTriggers.push({ + x: levelObj.x * 2, + targetGroup: parseInt(_raw[51] ?? 0, 10), + degrees: parseFloat(_raw[68] ?? 0), + duration: parseFloat(_raw[10] ?? 0), + easingType: parseInt(_raw[30] ?? 0, 10), + easingRate: parseFloat(_raw[85] ?? 2), + lockRotation: _raw[70] === '1', + times360: parseInt(_raw[69] ?? 0, 10), + centerGroup: parseInt(_raw[71] ?? 0, 10), + }); + } + if (levelObj.id === 1006) { + const _raw = levelObj._raw; + const targetType = parseInt(_raw[52] ?? 0, 10); + this._pulseTriggers.push({ + x: levelObj.x * 2, + targetGroup: targetType === 1 ? parseInt(_raw[51] ?? 0, 10) : 0, + targetChannel: targetType === 0 ? parseInt(_raw[51] ?? 0, 10) : 0, + targetType: targetType, color: { r: parseInt(_raw[7] ?? 255, 10), g: parseInt(_raw[8] ?? 255, 10), b: parseInt(_raw[9] ?? 255, 10) }, - duration: parseFloat(_raw[10] ?? 0), - tintGround: _raw[14] === "1", - opacity: parseFloat(_raw[35] ?? 1) + fadeIn: parseFloat(_raw[45] ?? 0), + hold: parseFloat(_raw[46] ?? 0), + fadeOut: parseFloat(_raw[47] ?? 0), }); } } - if (levelObj.id === 1346) { - const _raw = levelObj._raw; - this._rotateTriggers.push({ - x: levelObj.x * 2, - targetGroup: parseInt(_raw[51] ?? 0, 10), - degrees: parseFloat(_raw[68] ?? 0), - duration: parseFloat(_raw[10] ?? 0), - easingType: parseInt(_raw[30] ?? 0, 10), - easingRate: parseFloat(_raw[85] ?? 2), - lockRotation: _raw[70] === '1', - times360: parseInt(_raw[69] ?? 0, 10), - centerGroup: parseInt(_raw[71] ?? 0, 10), - }); - } - if (levelObj.id === 1006) { - const _raw = levelObj._raw; - const targetType = parseInt(_raw[52] ?? 0, 10); - this._pulseTriggers.push({ - x: levelObj.x * 2, - targetGroup: targetType === 1 ? parseInt(_raw[51] ?? 0, 10) : 0, - targetChannel: targetType === 0 ? parseInt(_raw[51] ?? 0, 10) : 0, - targetType: targetType, - color: { - r: parseInt(_raw[7] ?? 255, 10), - g: parseInt(_raw[8] ?? 255, 10), - b: parseInt(_raw[9] ?? 255, 10) - }, - fadeIn: parseFloat(_raw[45] ?? 0), - hold: parseFloat(_raw[46] ?? 0), - fadeOut: parseFloat(_raw[47] ?? 0), - }); - } - if (levelObj.id === 31) { - this._startPositions.push({ - x: 2 * levelObj.x, - y: 2 * levelObj.y, - gameMode: levelObj.gameMode, - miniMode: levelObj.miniMode, - speed: levelObj.speed, - mirrored: levelObj.mirrored, - gravityFlipped: levelObj.flipGravity - }); - } continue; } let worldX = levelObj.x * 2; @@ -950,7 +954,7 @@ window.LevelObject = class LevelObject { } } let _0xOrbGlow = null; - if (objectDef.glow) { + if (!window.lowDetailMode && objectDef.glow) { _0xOrbGlow = this._addGlowSprite(scene, spriteWorldX, baseY, frameName, levelObj, worldX); if (_0xOrbGlow) { _0xOrbGlow._eeZDepth = _objZDepth - 0.003; @@ -1104,7 +1108,7 @@ window.LevelObject = class LevelObject { if (levelObj.id === 1331) { } } - if (objectDef && objectDef.portalParticle && frameName) { + if (objectDef && objectDef.portalParticle && frameName && !window.lowDetailMode) { let _0x3a9438 = worldX; let _0x2e9079 = b(worldY); const _0x143187 = 2; @@ -1267,7 +1271,7 @@ window.LevelObject = class LevelObject { _registerCollider(padObj); this.objects.push(padObj); this._addCollisionToSection(padObj); - } else if (objectDef.type === ringType) { + } else if (!window.lowDetailMode && objectDef.type === ringType) { let orbW = objectDef.gridW * a; let orbH = objectDef.gridH * a; let orbObj = new Collider(jumpRingType, worldX, worldY, orbW, orbH, levelObj.rot || 0); @@ -1348,51 +1352,53 @@ window.LevelObject = class LevelObject { this._endPortalShine.setTint(window.mainColor); this._endPortalShine.setScale(1, 960 / _0x3e25a9); this.additiveContainer.add(this._endPortalShine); - const _0x58cedb = _0x3b56d4 - 30; - const _0x4f52b7 = { - getRandomPoint: _0x4f04dd => { - const _0x53ec71 = (85 + Math.random() * 190) * Math.PI / 180; - const _0x42e60c = 320 + (Math.random() * 2 - 1) * 80; - _0x4f04dd.x = Math.cos(_0x53ec71) * _0x42e60c; - _0x4f04dd.y = Math.sin(_0x53ec71) * _0x42e60c; - return _0x4f04dd; - } - }; - this._endPortalEmitter = _0x41fbdb.add.particles(_0x58cedb, _0x1c3aea, "GJ_WebSheet", { - frame: "square.png", - lifespan: { - min: 200, - max: 1000 - }, - speed: 0, - scale: { - start: 0.75, - end: 0.125 - }, - alpha: { - start: 1, - end: 0 - }, - tint: window.mainColor, - blendMode: Phaser.BlendModes.ADD, - frequency: 10, - maxParticles: 100, - emitting: true, - emitZone: { - type: "random", - source: _0x4f52b7 - }, - emitCallback: _0x2daff4 => { - const _0x5e30d8 = -_0x2daff4.x; - const _0x17ba71 = -_0x2daff4.y; - const _0x3c5c52 = Math.sqrt(_0x5e30d8 * _0x5e30d8 + _0x17ba71 * _0x17ba71) || 1; - const _0x279521 = (_0x3c5c52 - 20) / (_0x2daff4.life / 1000 || 0.3); - _0x2daff4.velocityX = _0x5e30d8 / _0x3c5c52 * _0x279521; - _0x2daff4.velocityY = _0x17ba71 / _0x3c5c52 * _0x279521; - } - }); - this._endPortalEmitter.setDepth(14); - this.topContainer.add(this._endPortalEmitter); + if (!window.lowDetailMode) { + const _0x58cedb = _0x3b56d4 - 30; + const _0x4f52b7 = { + getRandomPoint: _0x4f04dd => { + const _0x53ec71 = (85 + Math.random() * 190) * Math.PI / 180; + const _0x42e60c = 320 + (Math.random() * 2 - 1) * 80; + _0x4f04dd.x = Math.cos(_0x53ec71) * _0x42e60c; + _0x4f04dd.y = Math.sin(_0x53ec71) * _0x42e60c; + return _0x4f04dd; + } + }; + this._endPortalEmitter = _0x41fbdb.add.particles(_0x58cedb, _0x1c3aea, "GJ_WebSheet", { + frame: "square.png", + lifespan: { + min: 200, + max: 1000 + }, + speed: 0, + scale: { + start: 0.75, + end: 0.125 + }, + alpha: { + start: 1, + end: 0 + }, + tint: window.mainColor, + blendMode: Phaser.BlendModes.ADD, + frequency: 10, + maxParticles: 100, + emitting: true, + emitZone: { + type: "random", + source: _0x4f52b7 + }, + emitCallback: _0x2daff4 => { + const _0x5e30d8 = -_0x2daff4.x; + const _0x17ba71 = -_0x2daff4.y; + const _0x3c5c52 = Math.sqrt(_0x5e30d8 * _0x5e30d8 + _0x17ba71 * _0x17ba71) || 1; + const _0x279521 = (_0x3c5c52 - 20) / (_0x2daff4.life / 1000 || 0.3); + _0x2daff4.velocityX = _0x5e30d8 / _0x3c5c52 * _0x279521; + _0x2daff4.velocityY = _0x17ba71 / _0x3c5c52 * _0x279521; + } + }); + this._endPortalEmitter.setDepth(14); + this.topContainer.add(this._endPortalEmitter); + } this._endPortalGameY = 240; } updateEndPortalY(_0x26f0ab, _0x43c4d1) { @@ -1405,7 +1411,9 @@ window.LevelObject = class LevelObject { const _0x32e645 = b(_0x1be4c3); this._endPortalContainer.y = _0x32e645; this._endPortalShine.y = _0x32e645; - this._endPortalEmitter.y = _0x32e645; + if (this._endPortalEmitter) { + this._endPortalEmitter.y = _0x32e645; + } this._endPortalGameY = _0x1be4c3; } checkColorTriggers(_0x2b00ce) { diff --git a/assets/scripts/core/main.js b/assets/scripts/core/main.js index 4106d94..ee76ccf 100644 --- a/assets/scripts/core/main.js +++ b/assets/scripts/core/main.js @@ -44,7 +44,7 @@ const phaserConfig = { height: screenHeight, resolution: 1, fps: { - smoothStep: true + smoothStep: !window.lowDetailMode }, backgroundColor: "#000000", parent: document.body, @@ -52,7 +52,9 @@ const phaserConfig = { windowEvents: false }, render: { - powerPreference: "default" + powerPreference: window.lowDetailMode ? "low-power" : "default", + antialias: !window.lowDetailMode, + desynchronized: window.vsyncDisabled }, scale: { mode: Phaser.Scale.FIT, @@ -77,4 +79,4 @@ window.getCacheInfo = () => { return window.gameCache.getCacheStats(); } return null; -}; +}; \ No newline at end of file diff --git a/assets/scripts/core/player.js b/assets/scripts/core/player.js index f824aa2..82ed24a 100644 --- a/assets/scripts/core/player.js +++ b/assets/scripts/core/player.js @@ -456,176 +456,179 @@ class PlayerObject { } } _initParticles(scene) { - this._particleEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 110, - max: 190 - }, - angle: { - min: 225, - max: 315 - }, - lifespan: { - min: 150, - max: 450 - }, - scale: { - start: 0.5, - end: 0 - }, - gravityY: 600, - frequency: 1000 / 30, - blendMode: "ADD", - alpha: { - start: 1, - end: 0 - }, - tint: window.mainColor - }); - this._particleEmitter.stop(); - this._particleEmitter.setDepth(9); - this._gameLayer.container.add(this._particleEmitter); - this._flyParticleEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 22, - max: 38 - }, - angle: { - min: 225, - max: 315 - }, - lifespan: { - min: 150, - max: 450 - }, - scale: { - start: 0.5, - end: 0 - }, - gravityY: 600, - frequency: 1000 / 30, - blendMode: "ADD", - tint: { - start: 16737280, - end: 16711680 - }, - alpha: { - start: 1, - end: 0 - } - }); - this._flyParticleEmitter.stop(); - this._flyParticleEmitter.setDepth(9); - this._gameLayer.container.add(this._flyParticleEmitter); - this._flyParticle2Emitter = scene.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 220, - max: 380 - }, - angle: { - min: 180, - max: 360 - }, - lifespan: { - min: 150, - max: 450 - }, - scale: { - start: 0.75, - end: 0 - }, - gravityY: 600, - frequency: 1000 / 30, - blendMode: "ADD", - tint: { - start: 16760320, - end: 16711680 - }, - alpha: { - start: 1, - end: 0 - } - }); - this._flyParticle2Emitter.stop(); - this._flyParticle2Emitter.setDepth(9); - this._gameLayer.container.add(this._flyParticle2Emitter); - this._shipDragEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { - frame: "square.png", - x: { - min: -18, - max: 18 - }, - speed: { - min: 223.79999999999998, - max: 343.79999999999995 - }, - angle: { - min: 205, - max: 295 - }, - lifespan: { - min: 80, - max: 220 - }, - scale: { - start: 0.375, - end: 0 - }, - gravityX: -700, - gravityY: 600, - frequency: 25, - blendMode: "ADD", - alpha: { - start: 1, - end: 0 - } - }); - this._shipDragEmitter.stop(); - this._shipDragEmitter.setDepth(22); + if (!window.lowDetailMode) { + const freq = 1000 / 30; + this._particleEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 110, + max: 190 + }, + angle: { + min: 225, + max: 315 + }, + lifespan: { + min: 150, + max: 450 + }, + scale: { + start: 0.5, + end: 0 + }, + gravityY: 600, + frequency: freq, + blendMode: "ADD", + alpha: { + start: 1, + end: 0 + }, + tint: window.mainColor + }); + this._particleEmitter.stop(); + this._particleEmitter.setDepth(9); + this._gameLayer.container.add(this._particleEmitter); + this._flyParticleEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 22, + max: 38 + }, + angle: { + min: 225, + max: 315 + }, + lifespan: { + min: 150, + max: 450 + }, + scale: { + start: 0.5, + end: 0 + }, + gravityY: 600, + frequency: freq, + blendMode: "ADD", + tint: { + start: 16737280, + end: 16711680 + }, + alpha: { + start: 1, + end: 0 + } + }); + this._flyParticleEmitter.stop(); + this._flyParticleEmitter.setDepth(9); + this._gameLayer.container.add(this._flyParticleEmitter); + this._flyParticle2Emitter = scene.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 220, + max: 380 + }, + angle: { + min: 180, + max: 360 + }, + lifespan: { + min: 150, + max: 450 + }, + scale: { + start: 0.75, + end: 0 + }, + gravityY: 600, + frequency: freq, + blendMode: "ADD", + tint: { + start: 16760320, + end: 16711680 + }, + alpha: { + start: 1, + end: 0 + } + }); + this._flyParticle2Emitter.stop(); + this._flyParticle2Emitter.setDepth(9); + this._gameLayer.container.add(this._flyParticle2Emitter); + this._shipDragEmitter = scene.add.particles(0, 0, "GJ_WebSheet", { + frame: "square.png", + x: { + min: -18, + max: 18 + }, + speed: { + min: 223.79999999999998, + max: 343.79999999999995 + }, + angle: { + min: 205, + max: 295 + }, + lifespan: { + min: 80, + max: 220 + }, + scale: { + start: 0.375, + end: 0 + }, + gravityX: -700, + gravityY: 600, + frequency: 25, + blendMode: "ADD", + alpha: { + start: 1, + end: 0 + } + }); + this._shipDragEmitter.stop(); + this._shipDragEmitter.setDepth(22); + const _0x57911a = { + frame: "square.png", + speed: { + min: 250, + max: 350 + }, + angle: { + min: 210, + max: 330 + }, + lifespan: { + min: 50, + max: 600 + }, + scale: { + start: 0.625, + end: 0 + }, + gravityY: 1000, + blendMode: "ADD", + alpha: { + start: 1, + end: 0 + }, + tint: window.mainColor, + emitting: false + }; + this._landEmitter1 = scene.add.particles(0, 0, "GJ_WebSheet", { + ..._0x57911a + }); + this._landEmitter2 = scene.add.particles(0, 0, "GJ_WebSheet", { + ..._0x57911a + }); + this._gameLayer.topContainer.add(this._landEmitter1); + this._gameLayer.topContainer.add(this._landEmitter2); + } this._shipDragActive = false; this._particleActive = false; this._flyParticle2Active = false; this._flyParticleActive = false; - const _0x57911a = { - frame: "square.png", - speed: { - min: 250, - max: 350 - }, - angle: { - min: 210, - max: 330 - }, - lifespan: { - min: 50, - max: 600 - }, - scale: { - start: 0.625, - end: 0 - }, - gravityY: 1000, - blendMode: "ADD", - alpha: { - start: 1, - end: 0 - }, - tint: window.mainColor, - emitting: false - }; - this._landEmitter1 = scene.add.particles(0, 0, "GJ_WebSheet", { - ..._0x57911a - }); - this._landEmitter2 = scene.add.particles(0, 0, "GJ_WebSheet", { - ..._0x57911a - }); this._aboveContainer = scene.add.container(0, 0); this._aboveContainer.setDepth(13); - this._gameLayer.topContainer.add(this._landEmitter1); - this._gameLayer.topContainer.add(this._landEmitter2); this._landIdx = false; this._streak = new StreakManager(this._scene, "streak_01", 0.231, 10, 8, 100, window.secondaryColor, 0.7); this._streak.addToContainer(this._gameLayer.container, 8); @@ -633,6 +636,7 @@ class PlayerObject { this._waveTrail.addToContainer(this._gameLayer.container, 9); } _updateParticles(_0xc43238, _0x52b718, _0x5af874) { + if (!this._particleEmitter) return; if (this.p.isDead) { return; } @@ -921,7 +925,7 @@ if (this.p.isFlying || this.p.isUfo) { this.p.isJumping = false; this.stopRotation(); this._rotation = 0; - this._particleEmitter.stop(); + if (this._particleEmitter) this._particleEmitter.stop(); this._flyParticle2Active = false; this._streak.reset(); this._streak.start(); @@ -948,11 +952,11 @@ if (this.p.isFlying || this.p.isUfo) { this.p.isJumping = false; this.stopRotation(); this._rotation = 0; - this._flyParticleEmitter.stop(); + if (this._flyParticleEmitter) this._flyParticleEmitter.stop(); this._flyParticleActive = false; - this._flyParticle2Emitter.stop(); + if (this._flyParticle2Emitter) this._flyParticle2Emitter.stop(); this._flyParticle2Active = false; - this._shipDragEmitter.stop(); + if (this._shipDragEmitter) this._shipDragEmitter.stop(); this._shipDragActive = false; this._particleActive = false; this._streak.stop(); @@ -1104,7 +1108,7 @@ if (this.p.isFlying || this.p.isUfo) { this.p.isJumping = false; this.stopRotation(); this._rotation = 0; - this._particleEmitter.stop(); + if (this._particleEmitter) this._particleEmitter.stop(); this._streak.reset(); this._streak.start(); this.setBallVisible(false); @@ -1134,7 +1138,7 @@ if (this.p.isFlying || this.p.isUfo) { this.p.isJumping = false; this.stopRotation(); this._rotation = 0; - this._flyParticleEmitter.stop(); + if (this._flyParticleEmitter) this._flyParticleEmitter.stop(); this.setCubeVisible(!this.p.isBall && !this.p.isFlying); this.setBallVisible(this.p.isBall); this.setShipVisible(this.p.isFlying); @@ -1173,9 +1177,11 @@ if (this.p.isFlying || this.p.isUfo) { if (_0x4a38a5 && !this.p.isFlying && !this.p.isWave && !this.p.isSpider) { this._landIdx = !this._landIdx; const _0x31584b = this._landIdx ? this._landEmitter1 : this._landEmitter2; - const _0x2248d5 = this._scene._playerWorldX; - const _0x17e0bb = this.p.gravityFlipped ? b(this.p.y) - 30 : b(this.p.y) + 30; - _0x31584b.explode(10, _0x2248d5, _0x17e0bb); + if (_0x31584b) { + const _0x2248d5 = this._scene._playerWorldX; + const _0x17e0bb = this.p.gravityFlipped ? b(this.p.y) - 30 : b(this.p.y) + 30; + _0x31584b.explode(10, _0x2248d5, _0x17e0bb); + } } } killPlayer() { @@ -1184,13 +1190,13 @@ if (this.p.isFlying || this.p.isUfo) { } this.p.isDead = true; this._scene.toggleGlitter(false); - this._particleEmitter.stop(); + if (this._particleEmitter) this._particleEmitter.stop(); this._particleActive = false; - this._flyParticleEmitter.stop(); + if (this._flyParticleEmitter) this._flyParticleEmitter.stop(); this._flyParticleActive = false; - this._flyParticle2Emitter.stop(); + if (this._flyParticle2Emitter) this._flyParticle2Emitter.stop(); this._flyParticle2Active = false; - this._shipDragEmitter.stop(); + if (this._shipDragEmitter) this._shipDragEmitter.stop(); this._shipDragActive = false; this._streak.stop(); this._streak.reset(); @@ -1198,7 +1204,8 @@ if (this.p.isFlying || this.p.isUfo) { const _0x3f0446 = _0x3f4b84._getMirrorXOffset(_0x3f4b84._playerWorldX - _0x3f4b84._cameraX); const _0x53ac5b = b(this.p.y) + this._lastCameraY; const _0x281e43 = 0.9; - _0x3f4b84.add.particles(_0x3f0446, _0x53ac5b, "GJ_WebSheet", { + if (!window.lowDetailMode) { + _0x3f4b84.add.particles(_0x3f0446, _0x53ac5b, "GJ_WebSheet", { frame: "square.png", speed: { min: 200, @@ -1233,6 +1240,7 @@ if (this.p.isFlying || this.p.isUfo) { max: 20 } }).setScrollFactor(0).setDepth(15); + } const _0x438d80 = _0x3f4b84.add.graphics().setScrollFactor(0).setDepth(15).setBlendMode(S); const _0x4683eb = { t: 0 @@ -1338,7 +1346,7 @@ if (this.p.isFlying || this.p.isUfo) { _0xba83f5.y = -(_0x20396e + _0x20847a / 2 - sliderBar / 2); this._explosionContainer.add(_0xba83f5); let _0x298d34 = null; - if (_0x156c8b % 2 == 0) { + if (_0x156c8b % 2 == 0 && !window.lowDetailMode) { const _0x367bdb = 200 + Math.random() * 200; const _0x5e5fa8 = _0xba83f5; _0x298d34 = _0x44acaf.add.particles(0, 0, "GJ_WebSheet", { @@ -1795,9 +1803,11 @@ _updateBallJump(_0x2fe319) { this.p.onGround = false; this.p.canJump = false; this.p.isJumping = true; - try { - this._flyParticle2Emitter.explode(6, this._scene._playerWorldX, b(this.p.y) + (this.p.gravityFlipped ? -18 : 18)); - } catch(e) {} + if (this._flyParticle2Emitter) { + try { + this._flyParticle2Emitter.explode(6, this._scene._playerWorldX, b(this.p.y) + (this.p.gravityFlipped ? -18 : 18)); + } catch(e) {} + } } if (!this.p.wasBoosted) { const _ufoMaxUp = this.p.isMini ? 18.824 : 16; @@ -2674,10 +2684,10 @@ _updateBallJump(_0x2fe319) { const _0x8bc9f4 = _0x568b25 + 300; const _0x11b580 = [this._playerSpriteLayer, this._playerGlowLayer, this._playerOverlayLayer, this._playerExtraLayer, this._ballSpriteLayer, this._ballGlowLayer, this._ballOverlayLayer, this._waveSpriteLayer, this._waveOverlayLayer, this._waveExtraLayer, this._waveGlowLayer, this._shipSpriteLayer, this._shipGlowLayer, this._shipOverlayLayer, this._shipExtraLayer].filter(_0x3e9c62 => _0x3e9c62 && _0x3e9c62.sprite.visible).map(_0x5cedeb => _0x5cedeb.sprite); this._startPercent = (this._scene._playerWorldX / this._scene._level.endXPos) * 100; - this._particleEmitter.stop(); - this._flyParticleEmitter.stop(); - this._flyParticle2Emitter.stop(); - this._shipDragEmitter.stop(); + if (this._particleEmitter) this._particleEmitter.stop(); + if (this._flyParticleEmitter) this._flyParticleEmitter.stop(); + if (this._flyParticle2Emitter) this._flyParticle2Emitter.stop(); + if (this._shipDragEmitter) this._shipDragEmitter.stop(); const _0x154798 = this.p.isFlying; const _0x3793a4 = [this._shipSpriteLayer, this._shipGlowLayer, this._shipOverlayLayer, this._shipExtraLayer]; const _0xbd676f = [this._playerSpriteLayer, this._playerGlowLayer, this._playerOverlayLayer, this._playerExtraLayer]; @@ -2774,13 +2784,13 @@ _updateBallJump(_0x2fe319) { _0x1e656c.sprite.setScale(1); } } - this._particleEmitter.stop(); + if (this._particleEmitter) this._particleEmitter.stop(); this._particleActive = false; - this._flyParticleEmitter.stop(); + if (this._flyParticleEmitter) this._flyParticleEmitter.stop(); this._flyParticleActive = false; - this._flyParticle2Emitter.stop(); + if (this._flyParticle2Emitter) this._flyParticle2Emitter.stop(); this._flyParticle2Active = false; - this._shipDragEmitter.stop(); + if (this._shipDragEmitter) this._shipDragEmitter.stop(); this._shipDragActive = false; this._streak.stop(); this._streak.reset(); diff --git a/assets/scripts/core/triggers.js b/assets/scripts/core/triggers.js index 7c00285..32e0af9 100644 --- a/assets/scripts/core/triggers.js +++ b/assets/scripts/core/triggers.js @@ -188,38 +188,40 @@ function particleEffect(gameScene, color1 = 16777215, color2 = 16777215) { const xPos = basePos + (screenWidth - 400) * Math.random(); const yPos = basePos + Math.random() * 240; circleEffect(gameScene, xPos, yPos, 40, 140 + Math.random() * 60, 500, true, true, color2); - gameScene.add.particles(xPos, yPos, "GJ_WebSheet", { - frame: "square.png", - speed: { - min: 520, - max: 920 - }, - angle: { - min: 0, - max: 360 - }, - scale: { - start: 0.4, - end: 0.13 - }, - alpha: { - start: 1, - end: 0 - }, - lifespan: { - min: 0, - max: 500 - }, - stopAfter: 25, - blendMode: S, - tint: color1, - x: { - min: -20, - max: 20 - }, - y: { - min: -20, - max: 20 - } - }).setScrollFactor(0).setDepth(57); + if (!window.lowDetailMode) { + gameScene.add.particles(xPos, yPos, "GJ_WebSheet", { + frame: "square.png", + speed: { + min: 520, + max: 920 + }, + angle: { + min: 0, + max: 360 + }, + scale: { + start: 0.4, + end: 0.13 + }, + alpha: { + start: 1, + end: 0 + }, + lifespan: { + min: 0, + max: 500 + }, + stopAfter: 25, + blendMode: S, + tint: color1, + x: { + min: -20, + max: 20 + }, + y: { + min: -20, + max: 20 + } + }).setScrollFactor(0).setDepth(57); + } } diff --git a/assets/scripts/utils/config.js b/assets/scripts/utils/config.js index 9bb07d7..9d4d1c9 100644 --- a/assets/scripts/utils/config.js +++ b/assets/scripts/utils/config.js @@ -27,6 +27,17 @@ if (urlParams.has('id')) { window.levelID = urlParams.get('id'); } +window.lowDetailMode = localStorage.getItem("lowDetailMode") === "true" || urlParams.has('ldm'); + +window.vsyncDisabled = localStorage.getItem("vsyncDisabled") === "true"; + +if (!window.lowDetailMode) { + const cores = navigator.hardwareConcurrency || 2; + const memory = navigator.deviceMemory || 4; + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|ChromeOS|IEMobile|Opera Mini/i.test(navigator.userAgent); + window.lowDetailMode = cores < 4 || memory < 4 || isMobile; +} + // ------------------------------- function hexToHexadecimal(str) { @@ -65,7 +76,7 @@ const T = 460; function b(y) { return T - y; } -let S = Phaser.BlendModes.ADD; +let S = window.lowDetailMode ? Phaser.BlendModes.NORMAL : Phaser.BlendModes.ADD; let E = Phaser.BlendModes.NORMAL; const fs = 1000; @@ -107,4 +118,4 @@ function addImageToScene(scene, x, y, textureName) { } else { return null; } -} +} \ No newline at end of file diff --git a/assets/scripts/utils/performance-optimizer.js b/assets/scripts/utils/performance-optimizer.js deleted file mode 100644 index 7d459b9..0000000 --- a/assets/scripts/utils/performance-optimizer.js +++ /dev/null @@ -1 +0,0 @@ -// working on this in a test branch.