From d0140de19a68339c6fa21f0b35ec17c91b9dbc20 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sun, 27 Apr 2025 11:46:30 +0700 Subject: [PATCH] refactor: use default format from vite web bundler --- .github/workflows/deploy.yml | 28 ++++++----- package-lock.json | 8 +-- {assets => public/assets}/levels/level1.json | 0 {assets => public/assets}/levels/level2.json | 0 {assets => public/assets}/levels/level3.json | 0 src/game/main.js | 51 ++++++++++++++++++++ src/{ => game}/scenes/LevelScene.js | 22 ++++----- src/{ => game}/scenes/MainScene.js | 29 ++++++++--- src/{ => game}/scenes/MenuScene.js | 1 - src/main.js | 35 ++------------ src/utils/assetUtils.js | 12 ----- vite/config.dev.mjs | 2 +- 12 files changed, 108 insertions(+), 80 deletions(-) rename {assets => public/assets}/levels/level1.json (100%) rename {assets => public/assets}/levels/level2.json (100%) rename {assets => public/assets}/levels/level3.json (100%) create mode 100644 src/game/main.js rename src/{ => game}/scenes/LevelScene.js (81%) rename src/{ => game}/scenes/MainScene.js (94%) rename src/{ => game}/scenes/MenuScene.js (97%) delete mode 100644 src/utils/assetUtils.js diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 38a03bc..d2e486c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,8 +2,8 @@ name: Deploy to GitHub Pages on: push: - branches: - - main # Set this to your default branch + branches: [ main ] + workflow_dispatch: permissions: contents: read @@ -16,35 +16,39 @@ concurrency: cancel-in-progress: true jobs: - build-and-deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} + build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - - name: Set up Node.js + + - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - + - name: Install dependencies run: npm ci - + - name: Build run: npm run build - + - name: Setup Pages uses: actions/configure-pages@v4 - + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: './dist' + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 diff --git a/package-lock.json b/package-lock.json index b666636..9303155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "template-vite", - "version": "1.4.0", + "name": "sokoban", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "template-vite", - "version": "1.4.0", + "name": "sokoban", + "version": "1.0.0", "license": "MIT", "dependencies": { "phaser": "^3.88.2" diff --git a/assets/levels/level1.json b/public/assets/levels/level1.json similarity index 100% rename from assets/levels/level1.json rename to public/assets/levels/level1.json diff --git a/assets/levels/level2.json b/public/assets/levels/level2.json similarity index 100% rename from assets/levels/level2.json rename to public/assets/levels/level2.json diff --git a/assets/levels/level3.json b/public/assets/levels/level3.json similarity index 100% rename from assets/levels/level3.json rename to public/assets/levels/level3.json diff --git a/src/game/main.js b/src/game/main.js new file mode 100644 index 0000000..1ba66d9 --- /dev/null +++ b/src/game/main.js @@ -0,0 +1,51 @@ +import { AUTO, Game } from 'phaser'; +import MenuScene from './scenes/MenuScene'; +import LevelScene from './scenes/LevelScene'; +import MainScene from './scenes/MainScene'; + +const config = { + type: AUTO, + width: 1024, + height: 768, + parent: 'game-container', + backgroundColor: '#028af8', + scale: { + mode: Phaser.Scale.FIT, + autoCenter: Phaser.Scale.CENTER_BOTH + }, + physics: { + default: 'arcade', + arcade: { + debug: false, + gravity: { y: 0 } + } + }, + scene: [MenuScene, LevelScene, MainScene], +}; + +class GameManager extends Game { + constructor(config) { + super(config); + + // Initialize game state in registry + this.registry.set('gameState', { + currentLevel: 0, + totalLevels: 3, + levelCompleted: [false, false, false] + }); + + // Add methods to manage game state + this.registry.set('updateGameState', (updates) => { + const currentState = this.registry.get('gameState'); + const newState = { ...currentState, ...updates }; + this.registry.set('gameState', newState); + return newState; + }); + } +} + +const StartGame = (parent) => { + return new GameManager({ ...config, parent }); +}; + +export default StartGame; diff --git a/src/scenes/LevelScene.js b/src/game/scenes/LevelScene.js similarity index 81% rename from src/scenes/LevelScene.js rename to src/game/scenes/LevelScene.js index 1507be5..4a76973 100644 --- a/src/scenes/LevelScene.js +++ b/src/game/scenes/LevelScene.js @@ -1,16 +1,10 @@ import Phaser from 'phaser'; -import game from '../main.js'; -import { getAssetPath } from '../utils/assetUtils.js'; class LevelScene extends Phaser.Scene { constructor() { super({ key: 'LevelScene' }); } - preload() { - // Load any assets needed for the level selection - } - create() { // Add background this.cameras.main.setBackgroundColor('#f0f0f0'); @@ -67,7 +61,12 @@ class LevelScene extends Phaser.Scene { const startX = this.cameras.main.centerX - buttonWidth - padding / 2; const startY = this.cameras.main.centerY - buttonHeight / 2; - for (let i = 0; i < game.globals.totalLevels; i++) { + // Access gameState through the registry instead of globals + const gameState = this.game.registry.get('gameState'); + const totalLevels = gameState.totalLevels; + const levelCompleted = gameState.levelCompleted; + + for (let i = 0; i < totalLevels; i++) { const x = startX + (i % 3) * (buttonWidth + padding); const y = startY + Math.floor(i / 3) * (buttonHeight + padding); @@ -77,7 +76,7 @@ class LevelScene extends Phaser.Scene { y + buttonHeight / 2, buttonWidth, buttonHeight, - game.globals.levelCompleted[i] ? 0x4CAF50 : 0x3498db + levelCompleted[i] ? 0x4CAF50 : 0x3498db ); buttonBg.setInteractive({ useHandCursor: true }); @@ -96,17 +95,18 @@ class LevelScene extends Phaser.Scene { // Add click event buttonBg.on('pointerdown', () => { - game.globals.currentLevel = i; + // Update currentLevel in gameState + this.game.registry.get('updateGameState')({ currentLevel: i }); this.scene.start('MainScene'); }); // Add hover effect buttonBg.on('pointerover', () => { - buttonBg.setFillStyle(game.globals.levelCompleted[i] ? 0x45a049 : 0x2980b9); + buttonBg.setFillStyle(levelCompleted[i] ? 0x45a049 : 0x2980b9); }); buttonBg.on('pointerout', () => { - buttonBg.setFillStyle(game.globals.levelCompleted[i] ? 0x4CAF50 : 0x3498db); + buttonBg.setFillStyle(levelCompleted[i] ? 0x4CAF50 : 0x3498db); }); } } diff --git a/src/scenes/MainScene.js b/src/game/scenes/MainScene.js similarity index 94% rename from src/scenes/MainScene.js rename to src/game/scenes/MainScene.js index c5a8c62..0260464 100644 --- a/src/scenes/MainScene.js +++ b/src/game/scenes/MainScene.js @@ -1,6 +1,5 @@ import Phaser from 'phaser'; import game from '../main.js'; -import { getAssetPath } from '../utils/assetUtils.js'; class MainScene extends Phaser.Scene { constructor() { @@ -34,9 +33,9 @@ class MainScene extends Phaser.Scene { preload() { // Load level data - this.load.json('level1', getAssetPath('assets/levels/level1.json')); - this.load.json('level2', getAssetPath('assets/levels/level2.json')); - this.load.json('level3', getAssetPath('assets/levels/level3.json')); + this.load.json('level1', 'assets/levels/level1.json'); + this.load.json('level2', 'assets/levels/level2.json'); + this.load.json('level3', 'assets/levels/level3.json'); } create() { @@ -70,8 +69,11 @@ class MainScene extends Phaser.Scene { }); try { + // Get game state from registry + const gameState = this.game.registry.get('gameState'); + // Load level data - const levelNumber = game.globals.currentLevel + 1; + const levelNumber = gameState.currentLevel + 1; this.levelData = this.cache.json.get(`level${levelNumber}`); if (!this.levelData || !this.levelData.tiles) { @@ -255,11 +257,14 @@ class MainScene extends Phaser.Scene { } createUI() { + // Get game state from registry + const gameState = this.game.registry.get('gameState'); + // Add level text const levelText = this.add.text( 20, 20, - `LEVEL ${game.globals.currentLevel + 1}`, + `LEVEL ${gameState.currentLevel + 1}`, { fontSize: '24px', fill: '#000' @@ -503,8 +508,16 @@ class MainScene extends Phaser.Scene { }); if (allBoxesOnTargets && this.boxes.getChildren().length > 0) { - // Mark level as completed - game.globals.levelCompleted[game.globals.currentLevel] = true; + // Get current game state and update function from registry + const gameState = this.game.registry.get('gameState'); + const updateGameState = this.game.registry.get('updateGameState'); + + // Create new levelCompleted array with current level marked as completed + const levelCompleted = [...gameState.levelCompleted]; + levelCompleted[gameState.currentLevel] = true; + + // Update the game state + updateGameState({ levelCompleted }); // Show win message const winText = this.add.text( diff --git a/src/scenes/MenuScene.js b/src/game/scenes/MenuScene.js similarity index 97% rename from src/scenes/MenuScene.js rename to src/game/scenes/MenuScene.js index 7df67df..7452098 100644 --- a/src/scenes/MenuScene.js +++ b/src/game/scenes/MenuScene.js @@ -1,5 +1,4 @@ import Phaser from 'phaser'; -import { getAssetPath } from '../utils/assetUtils.js'; class MenuScene extends Phaser.Scene { constructor() { diff --git a/src/main.js b/src/main.js index 2b8d52e..3af41eb 100644 --- a/src/main.js +++ b/src/main.js @@ -1,34 +1,7 @@ -import {Game, AUTO} from 'phaser'; -import MenuScene from './scenes/MenuScene'; -import LevelScene from './scenes/LevelScene'; -import MainScene from './scenes/MainScene'; +import StartGame from './game/main'; -// Game configuration -const config = { - type: AUTO, - width: 800, - height: 600, - parent: 'game-container', - backgroundColor: '#f9f9f9', - scene: [MenuScene, LevelScene, MainScene], - physics: { - default: 'arcade', - arcade: { - gravity: {y: 0}, - debug: false - } - }, - pixelArt: true -}; +document.addEventListener('DOMContentLoaded', () => { -// Create the game instance -const game = new Game(config); + StartGame('game-container'); -// Global game variables -game.globals = { - currentLevel: 0, - totalLevels: 3, // We'll create 3 levels for now - levelCompleted: [false, false, false] -}; - -export default game; +}); \ No newline at end of file diff --git a/src/utils/assetUtils.js b/src/utils/assetUtils.js deleted file mode 100644 index 067a6d9..0000000 --- a/src/utils/assetUtils.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Utility function to get the correct asset path based on the environment - * This helps ensure assets load correctly both locally and on GitHub Pages - * - * @param {string} path - The relative path to the asset - * @returns {string} The correct path to use for loading the asset - */ -export function getAssetPath(path) { - // The path should be used as-is since Vite handles the base path - // during build based on the config.base setting - return path; -} diff --git a/vite/config.dev.mjs b/vite/config.dev.mjs index 34a5b6c..71e0cc8 100644 --- a/vite/config.dev.mjs +++ b/vite/config.dev.mjs @@ -1,7 +1,7 @@ import { defineConfig } from 'vite'; export default defineConfig({ - base: '/', + base: './', build: { rollupOptions: { output: {