Game Title: Kilo Man Genre: 2D Platformer (Side-scrolling) Tech Stack: Next.js 16, React 19, Tailwind CSS v4, HTML5 Canvas. Theme: "Pretty, 3D-seeming" aesthetics with depth, gradients, and parallax.
We will utilize the existing app/ directory structure but expand the internal logic of GameCanvas.
app/
├── page.tsx # Main entry point
└── components/
└── Game/
├── GameContainer.tsx # Manages high-level state (UI + Canvas)
├── GameCanvas.tsx # Handles Game Loop, Physics, Camera, and Rendering
├── UIOverlay.tsx # HUD, Jump Slider, Win/Loss screens
├── levelData.ts # Expanded level data (World size, Entities, Monsters)
└── types.ts # Updated TypeScript interfaces
The game world will now be larger than the canvas. We need a Camera system to track the player.
- State:
camera = { x: 0, y: 0 } - Logic:
- Center camera on player:
targetX = player.x - (canvasWidth / 2) - Smooth follow (optional) or direct lock.
- Clamping: Ensure camera doesn't show out-of-bounds areas (0 to
levelWidth - canvasWidth).
- Center camera on player:
- Rendering: All entities are drawn at
entity.x - camera.x.
We will introduce a more robust entity system to handle moving obstacles.
- Types:
Player,Platform,Hazard,Goal,Monster. - Monster Behavior:
- Simple AI: Patrols between two points (
patrolStart,patrolEnd). - Collision: If player touches monster -> Game Over.
- Simple AI: Patrols between two points (
To achieve a "pretty" look without external assets, we will use advanced Canvas drawing techniques.
- Parallax Background:
- Multiple layers (Sky, Distant Mountains, Near Hills).
- Move at different speeds relative to the camera (
camera.x * parallaxFactor).
- 2.5D Platforms:
- Draw the "face" of the platform.
- Draw a "top" surface with a lighter color to simulate depth/perspective.
- Drop shadows.
- Procedural Characters:
- Player: Humanoid shape composed of geometric primitives (Head, Torso, Limbs).
- Animation: Simple leg oscillation based on movement.
- Monsters: Distinct shape (e.g., Spiky, Red/Dark) to clearly indicate danger.
export type EntityType = 'platform' | 'hazard' | 'goal' | 'start' | 'monster';
export interface LevelEntity {
id: string;
x: number;
y: number;
w: number;
h: number;
type: EntityType;
// Visual properties
color?: string;
// Monster specific
patrolRange?: number; // Distance to move back and forth
speed?: number;
}
export interface GameConfig {
// ... existing physics ...
levelWidth: number; // Total width of the world
}- Camera Implementation:
- Modify
drawfunction to accept a camera offset. - Update
updateloop to calculate camera position based on player.
- Modify
- Level Expansion:
- Update
levelData.tsto define a world ~3000px wide (approx 30s traversal). - Add boundaries to physics to prevent falling off the "world" edges.
- Update
- Monster Logic:
- Add
monstersarray to state refs. - Update monster positions in game loop.
- Add collision check for Player vs Monster.
- Add
- Parallax Background:
- Create
drawBackground(ctx, cameraX)function. - Implement gradient sky and scrolling layers.
- Create
- Platform Styling:
- Replace
fillRectwithdrawPlatform(ctx, entity, cameraX)helper. - Add depth effects (top/side faces).
- Replace
- Character Art:
- Replace square player with
drawHumanoid(ctx, x, y)function. - Add simple animation state (frame counter).
- Replace square player with
GRAVITY: 0.6FRICTION: 0.85MOVE_SPEED: 0.8 (Slower acceleration for weight)MAX_SPEED: 8.0JUMP_FORCE: -14