Physics based arcade game
/SKILLUse this skill when working with Arcade Physics in Phaser 4. It covers enabling physics, velocity, acceleration, and
--- name: physics-arcade description: "Use this skill when using Arcade Physics in Phaser 4. Covers enabling physics, velocity, acceleration, gravity, collisions, overlap, world bounds, physics groups, static bodies, and collision categories. Triggers on: physics, arcade, velocity, gravity, collide, overlap, bounce, physics body." --- # Arcade Physics > Setting up and using Arcade Physics in Phaser 4 -- enabling physics in GameConfig, creating physics-enabled sprites/images/groups, velocity, acceleration, gravity, collisions (collide/overlap), world bounds, body properties, and collision categories. Key source paths: src/physics/arcade/ArcadePhysics.js, src/physics/arcade/World.js, src/physics/arcade/Body.js, src/physics/arcade/StaticBody.js, src/physics/arcade/Factory.js, src/physics/arcade/components/, src/physics/arcade/events/ Related skills: ../game-setup-and-config/SKILL.md, ../sprites-and-images/SKILL.md, ../tilemaps/SKILL.md, ../groups-and-containers/SKILL.md ## Quick Start ``js class GameScene extends Phaser.Scene { create() { // Physics sprite (dynamic body, affected by gravity) this.player = this.physics.add.sprite(100, 300, 'player'); this.player.setCollideWorldBounds(true); this.player.setBounce(0.2); // Static group (immovable platforms) this.platforms = this.physics.add.staticGroup(); this.platforms.create(400, 568, 'ground').setScale(2).refreshBody(); // Register a persistent collider (checked every frame automatically) this.physics.add.collider(this.player, this.platforms); this.cursors = this.input.keyboard.createCursorKeys(); } update() { if (this.cursors.left.isDown) { this.player.setVelocityX(-160); } else if (this.cursors.right.isDown) { this.player.setVelocityX(160); } else { this.player.setVelocityX(0); } } } // Enable Arcade Physics in game config const config = { type: Phaser.AUTO, width: 800, height: 600, physics: { default: 'arcade', arcade: { gravity: { y: 300 }, debug: false } }, scene: GameScene }; const game = new Phaser.Game(config); ` ## Core Concepts ### World (this.physics.world) The Phaser.Physics.Arcade.World manages all bodies in the simulation. Accessed via this.physics.world in a Scene. - **gravity** -- Vector2 applied to all dynamic bodies each step. Set via config or this.physics.world.gravity.y = 300. - **bounds** -- Rectangle defining the world boundary. Defaults to game canvas size. - **bodies** -- Set of all dynamic Body instances. - **staticBodies** -- Set of all StaticBody instances. - **colliders** -- ProcessQueue of registered Collider objects (from this.physics.add.collider / this.physics.add.overlap). - **fps** -- Physics steps per second (default 60). Read-only; change via world.setFPS(120). - **fixedStep** -- true (default) uses fixed timestep; false syncs to render fps. - **timeScale** -- Scaling factor: 1.0 = normal, 2.0 = half speed, 0.5 = double speed. - **isPaused** -- When true, no bodies update and no colliders run. Toggle via world.pause() / world.resume(). - **useTree** -- true (default) uses RTree spatial index for dynamic bodies. Disable for 5000+ bodies. - **drawDebug** -- Enables debug rendering when true. Set via config debug: true. ### Bodies (Body) A dynamic body is created automatically when you use this.physics.add.sprite() or this.physics.add.image(). Access it via gameObject.body. Key properties (all on Body): - **velocity** -- Vector2, pixels/sec - **acceleration** -- Vector2, pixels/sec^2 - **drag** -- Vector2, deceleration (applied only when acceleration is zero) - **gravity** -- Vector2, per-body gravity added to world gravity - **bounce** -- Vector2, rebound factor relative to 1 - **friction** -- Vector2, default (1, 0) -- velocity imparted by immovable body to riding body - **maxVelocity** -- Vector2, default (10000, 10000) | **maxSpeed** -- scalar cap, default -1 (none) - **mass** -- default 1, affects collision momentum exchange - **immovable** -- false; if true, never moved by collisions - **pushable** -- true; if false, reflects velocity to colliding body - **moves** -- true; if false, position/rotation not updated by physics - **enable** -- true; false removes from simulation - **useDamping** -- false; when true, drag is a multiplier (0-1) instead of linear - **collideWorldBounds** -- false; **onWorldBounds/onCollide/onOverlap** -- false, set true to emit events Shape: **isCircle** (set via setCircle), **width/height**, **offset** (Vector2), **center** (read-only midpoint). Collision state (read-only, reset each step): **touching** / **blocked** / **wasTouching** -- { none, up, down, left, right }`. embedded -- both overlapping with zero v