mafia / frontend /README.md
Alfaxad's picture
Migrate Mafia game to ZeroGPU Gradio Space
c670567 verified
|
Raw
History Blame Contribute Delete
8.65 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade

Phaser 3 Game Template

A standardized Phaser 3 game template for rapid 2D web game development. This template provides a consistent architecture and pre-built components that AI coding agents can use to generate games efficiently.

Quick Start

# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build

Project Structure

src/
β”œβ”€β”€ main.ts                 # Game entry point & Phaser configuration
β”œβ”€β”€ gameConfig.json         # All game parameters (health, speed, damage, etc.)
β”œβ”€β”€ LevelManager.ts         # Level flow management
β”œβ”€β”€ utils.ts                # CRITICAL utility functions (DO NOT MODIFY)
β”œβ”€β”€ characters/             # Player and enemy classes
β”‚   β”œβ”€β”€ ExamplePlayer.ts    # Template - copy then delete/rename
β”‚   └── ExampleEnemy.ts     # Template - copy then delete/rename
β”œβ”€β”€ scenes/
β”‚   β”œβ”€β”€ Preloader.ts        # Asset loading (STANDARD - minimal changes)
β”‚   β”œβ”€β”€ TitleScreen.ts      # Start screen (customize UI only)
β”‚   β”œβ”€β”€ BaseLevelScene.ts   # Optional level base class
β”‚   β”œβ”€β”€ UIScene.ts          # In-game HUD
β”‚   β”œβ”€β”€ VictoryUIScene.ts   # Level complete screen
β”‚   β”œβ”€β”€ GameOverUIScene.ts  # Death/failure screen
β”‚   └── GameCompleteUIScene.ts # All levels complete screen
β”œβ”€β”€ styles/
β”‚   └── tailwind.css        # Tailwind CSS for UI styling
└── test/
    └── setup.ts            # Test configuration

public/assets/
β”œβ”€β”€ asset-pack.json         # Asset manifest for Preloader
└── animations.json         # Animation definitions with origin data

Key Files Reference

main.ts

  • Configures Phaser game instance
  • Imports and registers all scenes in order:
    1. Preloader (auto-start)
    2. TitleScreen
    3. Level scenes
    4. UI scenes

gameConfig.json

All game parameters use { "value": X } wrapper format (self-documenting):

{
  "configGroup": {
    "parameterName": {
      "value": 100,
      "type": "number",
      "description": "What this does"
    }
  }
}

Access in code: configGroup.parameterName.value

utils.ts - CRITICAL FUNCTIONS

DO NOT MODIFY these functions. They solve Phaser quirks.

Function Usage
initScale() ALWAYS use for sprite scaling. Never use setScale() directly.
resetOriginAndOffset() ALWAYS call after play() animation.
initUIDom() ALWAYS use for UI scene DOM elements.
addCollider() / addOverlap() ALWAYS use instead of scene.physics.add.collider/overlap.
createTrigger() Create attack/detection zones.
updateMeleeTrigger() Update melee attack zone position.
createDecoration() Create decorative elements.
computeRotation() Calculate projectile rotation.

LevelManager.ts

Manages level progression:

// Add your level scene keys here
static readonly LEVEL_ORDER: string[] = [
  "Level1Scene",
  "Level2Scene",
  // ...
];

Animation Format (animations.json)

{
  "anims": [
    {
      "key": "player_idle_anim",
      "type": "frame",
      "frames": [
        { "key": "player_idle_01", "duration": 400 } // idle: 1 frame only
      ],
      "repeat": -1,
      "originX": 0.5,
      "originY": 1.0
    },
    {
      "key": "player_run_anim",
      "type": "frame",
      "frames": [
        { "key": "player_run_01", "duration": 400 }, // run: 2 frames
        { "key": "player_run_02", "duration": 400 }
      ],
      "repeat": -1,
      "originX": 0.5,
      "originY": 1.0
    }
  ]
}

Important: originX and originY are REQUIRED for utils.resetOriginAndOffset() to work correctly. Different animations may have different origins (e.g., attack animations often shift left/right).

Asset Pack Format (asset-pack.json)

{
  "assetPack": {
    "files": [
      { "type": "json", "key": "animations", "url": "assets/animations.json" },
      {
        "type": "image",
        "key": "player_idle_01",
        "url": "assets/player_idle_01.png"
      },
      {
        "type": "image",
        "key": "player_run_01",
        "url": "assets/player_run_01.png"
      },
      {
        "type": "image",
        "key": "player_run_02",
        "url": "assets/player_run_02.png"
      },
      {
        "type": "tilemapTiledJSON",
        "key": "level1_map",
        "url": "assets/level1_map.json"
      }
    ]
  }
}

Creating a New Game

1. Define Game Config

Edit gameConfig.json to add your game's parameters.

2. Create Player Class

Copy ExamplePlayer.ts to create your player (e.g., Player.ts), then delete ExamplePlayer.ts:

  • Load config values
  • Implement movement in update()
  • Implement takeDamage() and die()
  • Add animations

3. Create Enemy Classes

Copy ExampleEnemy.ts for each enemy type (e.g., EnemySoldier.ts), then delete ExampleEnemy.ts:

  • Configure stats
  • Implement AI in executeAI()
  • Add unique behaviors

4. Create Level Scenes

Either extend BaseLevelScene or create from scratch:

export class Level1Scene extends BaseLevelScene {
  constructor() {
    super({ key: 'Level1Scene' });
  }

  create() {
    this.createBaseElements();
    // Level-specific setup
  }

  update(time, delta) {
    this.baseUpdate(time, delta);
    // Level-specific updates
  }

  // Implement abstract methods...
}

5. Register Levels

  1. Import in main.ts
  2. Add to game.scene.add()
  3. Add key to LevelManager.LEVEL_ORDER

6. Customize UI

Modify the createDOMUI() methods in:

  • TitleScreen.ts - Start screen design
  • UIScene.ts - In-game HUD
  • Victory/GameOver scenes - End screens

Standard Dimensions

Element Standard Height Notes
Player 128px Standard human-sized character
Small enemy 48-64px Knee to waist height
Medium enemy 80-100px Slightly smaller than player
Large enemy/Boss 150-256px 1.5x to 2x player size
Tile size 64px Standard tile dimension

UI Styling

UI uses Tailwind CSS with custom pixel-art styled components:

  • game-pixel-container-* - Pixel-styled containers
  • game-pixel-container-slot-* - Progress bar backgrounds
  • game-pixel-container-progress-fill-* - Progress bar fills
  • game-pixel-container-clickable-* - Clickable buttons

Scene Lifecycle

  1. Preloader β†’ Loads all assets
  2. TitleScreen β†’ Press Enter to start
  3. Level1Scene + UIScene (parallel) β†’ Gameplay
  4. On victory: VictoryUIScene β†’ Next level OR GameCompleteUIScene β†’ Title
  5. On death: GameOverUIScene β†’ Restart level

Common Patterns

Playing Animations

// CORRECT - always use this pattern
playAnimation(animKey: string): void {
  this.play(animKey, true);
  utils.resetOriginAndOffset(this, this.facingDirection);
}

Scaling Sprites

// CORRECT - always use initScale
utils.initScale(
  sprite,
  { x: 0.5, y: 1.0 }, // origin
  undefined, // maxWidth (optional)
  128, // maxHeight
  0.6, // body width factor
  0.85, // body height factor
);

// WRONG - never do this
sprite.setScale(2);
sprite.setDisplaySize(100, 100);

Adding Collisions

// CORRECT - guaranteed parameter order
utils.addCollider(this, player, enemies, (player, enemy) => {
  player.takeDamage(enemy.damage);
});

// WRONG - parameter order may be swapped
this.physics.add.collider(player, enemies, callback);

Development Tips

  1. Always test animations - Make sure originX/Y in animations.json are correct
  2. Use groups - Add enemies/decorations to groups for easy management
  3. Check health - Use getHealthPercentage() for UI updates
  4. Clean up events - Always remove event listeners in cleanupEventListeners()
  5. Prevent double-triggers - Use flags like isStarting, isRestarting

License

MIT