Get exam-ready
Every one of the 50 exam questions is grouped by topic below, with a live, interactive Phaser demo for each section. Play with the controls to see exactly how each API behaves — then check the questions and explanations underneath.
Scene Lifecycle
Every Phaser Scene runs three setup hooks (init → preload → create) once, then update() fires every frame. Knowing what belongs in each is the fastest way to stop fighting the engine.
Live demo
Try:The first three labels light up once. update() ticks every frame.
Exam questions in this topic
Q1.Which Phaser.Scene method is intended for loading assets before the scene starts?
beginner · mcq- Acreate
- ✓preload
- Cupdate
- Drender
Why: preload() runs first and is where you call this.load.image(), this.load.audio(), etc.
Q2.Phaser.Scene's `update()` method is called once per frame while the scene is active.
beginner · tfAnswertrue
Why: update() is invoked every frame by the game loop after the scene becomes active.
Q3.Fill in the blank to load an image during preload():
beginner · fillthis.load.____('player', 'player.png');Answerimage
Why: this.load.image(key, url) loads a single image asset.
Q4.What is the correct order of Scene lifecycle methods on first run?
beginner · mcq- Apreload → init → create
- ✓init → preload → create
- Ccreate → preload → update
- Dpreload → create → init
Why: init() runs first, then preload(), then create(); update() runs every frame after that.
Q5.By default a Phaser game targets a 60 FPS update loop.
beginner · tfAnswertrue
Why: Phaser uses requestAnimationFrame, which typically targets 60 FPS on most displays.
Q6.What does `this.scene.start("GameOver")` do?
moderate · mcq- APauses the current scene and overlays GameOver
- ✓Shuts down the current scene and starts the GameOver scene
- CLoads GameOver into the asset cache
- DAdds GameOver to the active scenes list, leaving current scene running
Why: scene.start() shuts down the current scene and starts the named one. Use scene.launch() to overlay.
Q7.What is the key difference between `this.scene.launch("UI")` and `this.scene.start("UI")`?
moderate · mcq- Alaunch loads assets, start does not
- ✓start replaces the current scene; launch runs UI in parallel on top of the current scene
- Claunch is async, start is sync
- Dlaunch is deprecated
Why: start shuts down the current scene and switches to the target. launch keeps the current scene running and adds the target alongside it (useful for HUDs).
Q8.From a UI scene, which call freezes the GameScene's update loop without unloading it?
moderate · mcq- Athis.scene.stop("GameScene")
- ✓this.scene.pause("GameScene")
- Cthis.scene.remove("GameScene")
- Dthis.scene.kill("GameScene")
Why: pause halts the update/render of the target scene but keeps its state in memory. resume restores it. (sleep does similar plus hides display.)
Sprites & Display
Sprites, text, images, and tileSprites are how you put things on screen. setOrigin moves the anchor point; setScale resizes; setText changes content live.
Live demo
Try:Move the sliders to see how setOrigin shifts the anchor and setScale resizes the sprite.
Exam questions in this topic
Q1.How do you add a non-physics sprite at (100, 200) inside `create()`?
beginner · mcq- Anew Phaser.Sprite(this, 100, 200, "key")
- ✓this.add.sprite(100, 200, "key")
- Cthis.physics.add.sprite(100, 200, "key")
- Dthis.load.sprite(100, 200, "key")
Why: this.add.sprite() is the GameObjectFactory method for a plain display sprite.
Q2.In Phaser's default 2D coordinate system, the Y axis increases downward.
beginner · tfAnswertrue
Why: Like the DOM, +Y points down by default.
Q3.Which call adds a text object at (10, 10) showing "Score: 0"?
beginner · mcq- Anew Phaser.Text(this, 10, 10, "Score: 0")
- ✓this.add.text(10, 10, "Score: 0")
- Cthis.text.add(10, 10, "Score: 0")
- Dthis.make.text({ x: 10, y: 10 })
Why: this.add.text(x, y, content, style?) is the GameObjectFactory method for a Text GameObject.
Q4.Given `const score = this.add.text(10, 10, "Score: 0")`, fill in the blank to change the displayed text:
beginner · fillscore.____('Score: 5');AnswersetText
Why: Phaser.GameObjects.Text#setText replaces the text content.
Q5.Which call loads a spritesheet with 32×32 frames?
beginner · mcq- ✓this.load.spritesheet('hero', 'hero.png', { frameWidth: 32, frameHeight: 32 })
- Bthis.load.image('hero', 'hero.png', 32, 32)
- Cthis.load.atlas('hero', 'hero.png', 32, 32)
- Dthis.load.sprites('hero', 'hero.png', { width: 32, height: 32 })
Why: load.spritesheet takes a frame config that tells Phaser how to slice the image.
Q6.`sprite.setOrigin(0.5, 0.5)` centers the sprite's origin (its rotation / position anchor) at its middle.
beginner · tfAnswertrue
Why: Origin is a 0–1 ratio. (0,0) is top-left, (1,1) bottom-right, (0.5, 0.5) is the center.
Q7.What does `sprite.setScale(2)` do?
beginner · mcq- ADoubles only the width
- ✓Doubles both width and height (uniform scale)
- CSets the sprite to exactly 2 pixels
- DResets scale to the default
Why: A single argument applies the same factor to both X and Y. Pass two arguments for non-uniform scale.
Q8.Which call creates an infinitely scrollable repeating background covering an 800×600 region?
moderate · mcq- Athis.add.image(400, 300, 'bg').setScale(25, 19)
- ✓this.add.tileSprite(400, 300, 800, 600, 'bg')
- Cthis.add.sprite(0, 0, 'bg').setRepeat(true)
- Dthis.add.tileLayer(0, 0, 800, 600, 'bg')
Why: TileSprite tiles its texture across its bounds. Animate `tilePositionX` or `tilePositionY` to scroll.
Arcade Physics
Arcade is the default 2D physics. physics.add.sprite gives an object a body; colliders register pairs that should bounce off each other; setCollideWorldBounds keeps it inside the world.
Live demo
Try:Toggle world bounds off and the ball flies off the canvas. Nudge to give it a fresh velocity.
Exam questions in this topic
Q1.Which physics engine is built into Phaser 3 and does NOT require an extra plugin?
beginner · mcq- AMatter.js only
- BBox2D
- ✓Arcade Physics
- DCannon.js
Why: Arcade Physics is the lightweight built-in. Matter.js is bundled too but Arcade is the simplest default.
Q2.Fill in the blank to create an Arcade-physics-enabled sprite:
beginner · fillthis.player = this.physics.add.____(100, 100, 'player');
Answersprite
Why: this.physics.add.sprite() returns a Sprite already equipped with an Arcade body.
Q3.How do you make two Arcade physics objects collide?
moderate · mcq- Athis.physics.collide(a, b)
- ✓this.physics.add.collider(a, b)
- Ca.collide(b)
- Dthis.add.collider(a, b)
Why: this.physics.add.collider() registers a collision check that runs each frame in Arcade Physics.
Q4.Which call keeps an Arcade-physics sprite from leaving the game world bounds?
beginner · mcq- Asprite.body.immovable = true
- ✓sprite.setCollideWorldBounds(true)
- Cthis.physics.world.attach(sprite)
- Dsprite.body.setBounce(0)
Why: setCollideWorldBounds(true) is a sprite-level shortcut that enables the body flag. Combine with this.physics.world.setBounds for custom bounds.
Q5.How do you opt a Phaser.Game into the Matter.js physics engine instead of Arcade?
moderate · mcq- ✓physics: { default: 'matter' }
- Bphysics: 'matter'
- CuseMatter: true
- Dengine: 'matter'
Why: Game config's `physics.default` selects the engine ('arcade' is the implicit default).
Input
createCursorKeys gives you the four arrow keys as one object. Pointer (mouse/touch) events fire on input.on. Per-sprite clicks need setInteractive. Specific keys use keydown-KEYNAME.
Live demo
Try:Click the canvas first to give it focus. Arrow keys move, SPACE flashes, mouse spawns dots.
Exam questions in this topic
Q1.What is the easiest way to get an object exposing `.up`, `.down`, `.left`, `.right` keys?
beginner · mcq- Athis.input.keyboard.addKey("UP")
- ✓this.input.keyboard.createCursorKeys()
- Cthis.input.cursor()
- Dnew Phaser.Input.CursorKeys()
Why: createCursorKeys() returns a CursorKeys object with the four arrow keys plus space and shift.
Q2.Which Phaser API schedules a callback to fire once after 1000 ms?
beginner · mcq- ✓this.time.delayedCall(1000, callback)
- Bthis.time.addEvent({ delay: 1000, loop: true, callback })
- CPhaser.Timer.set(1000, callback)
- Dthis.tweens.delayedCall(1000, callback)
Why: delayedCall is a shortcut for a single-shot timer event. addEvent with loop:true would repeat.
Q3.Fill in the blank to listen for a click anywhere on the screen:
beginner · fillthis.input.on('____', (pointer) => { console.log(pointer.x, pointer.y); });Answerpointerdown
Why: 'pointerdown' fires when the mouse is pressed or a touch begins.
Q4.A sprite will not respond to `pointerdown` events until you call:
beginner · mcq- Asprite.enableInput()
- ✓sprite.setInteractive()
- Csprite.acceptPointer()
- DNothing — input is enabled by default
Why: setInteractive() registers the GameObject with the input system and gives it a default hit area.
Q5.`this.input.keyboard.on('keydown-SPACE', handler)` listens for the space bar being pressed.
beginner · tfAnswertrue
Why: Keyboard events use the keydown-KEYNAME pattern with key names from KeyCodes (SPACE, A, LEFT, …).
Animations
A Phaser animation is just an ordered list of spritesheet frames played at a chosen frame rate. anims.create defines it once globally; sprite.anims.play runs it on a sprite.
Live demo
Try:Frame rate slider re-times the same 4 frames. Pause freezes on whatever frame is showing.
Exam questions in this topic
Q1.Given a sprite with an animation named "walk", how do you play it?
beginner · mcq- Asprite.play("walk")
- ✓sprite.anims.play("walk")
- Cthis.anims.play("walk", sprite)
- Dsprite.animations.play("walk")
Why: sprite.anims.play(key) is the modern Phaser 3 API. (sprite.play also works as a shortcut.)
Q2.Which call defines an animation from frames of a spritesheet named "dude"?
moderate · mcq- Athis.anims.add({ key: "walk", frames: "dude" })
- ✓this.anims.create({ key: "walk", frames: this.anims.generateFrameNumbers("dude", { start: 0, end: 3 }), frameRate: 10, repeat: -1 })
- Cthis.add.animation("walk", "dude", 0, 3)
- Dnew Phaser.Animation("walk", "dude")
Why: this.anims.create() with generateFrameNumbers is the canonical pattern for spritesheet-based anims.
Tweens
A tween smoothly interpolates a property over time. yoyo plays it forward then back; repeat: -1 loops forever; ease shapes the curve; onComplete fires once at the end.
Live demo
Try:Toggle yoyo + repeat. Try a Bounce or Elastic ease. With repeat off, onComplete logs once.
Exam questions in this topic
Q1.Fill in the blank to start a tween:
moderate · fillthis.tweens.____({ targets: sprite, x: 400, duration: 1000 });Answeradd
Why: this.tweens.add(config) creates and starts a new tween on the given targets.
Q2.Fill in the blank so this tween bounces between start and end forever:
moderate · fillthis.tweens.add({ targets: sprite, x: 400, duration: 1000, yoyo: true, repeat: ____, });Answer-1
Why: repeat: -1 means infinite. yoyo: true makes it ping-pong.
Q3.Which tween config key fires a callback the moment the tween (and all its repeats) finishes?
moderate · mcq- AonYoyo
- BonUpdate
- ✓onComplete
- DonStop
Why: onComplete fires once when the tween fully ends. onUpdate fires every frame; onYoyo fires each yoyo reversal.
Cameras
cameras.main is your viewport. startFollow locks it onto a sprite; setZoom multiplies the rendered scale (2 = 200%, 0.5 = half size).
Live demo
Try:The camera follows the dot. Zoom slider scales rendering — 2× shows half as much world.
Exam questions in this topic
Q1.How do you make the main camera follow the player sprite?
beginner · mcq- Athis.cameras.main.follow(player)
- ✓this.cameras.main.startFollow(player)
- Cthis.cameras.main.lockOn(player)
- Dplayer.attachCamera(this.cameras.main)
Why: Camera2D#startFollow attaches the camera so it tracks the target each frame.
Q2.`this.cameras.main.setZoom(2)` doubles the camera zoom level.
beginner · tfAnswertrue
Why: setZoom takes a multiplier: 1 is default, 2 is 2× zoom, 0.5 zooms out.
Sound
Audio is preloaded with load.audio in preload(), then sound.add(key).play() to hear it and .stop() to halt it. Volume can be set per-sound.
Live demo
Try:Browsers block audio until you interact — click the canvas, then Play. Volume is live.
Exam questions in this topic
Q1.Fill in the blank to preload an audio file:
beginner · fillthis.load.____('jump', 'jump.mp3');Answeraudio
Why: this.load.audio(key, urls) loads a sound. You can also pass an array of URLs for format fallbacks.
Q2.Fill in the blank. `sound` was returned from `this.sound.add("bgm")`. Stop playback:
moderate · fillsound.____();
Answerstop
Why: BaseSound#stop() stops the sound and resets it to the beginning.
Q3.Fill in the blank. `bgm` was returned from `this.sound.add("bgm")`. Start playback:
beginner · fillbgm.____();
Answerplay
Why: BaseSound#play starts (or restarts) the sound. Pass a config object to override volume, loop, rate, etc.
Math Utilities
Phaser ships with handy helpers. Math.Between(a,b) is inclusive on both ends. Clamp pins a value into a range. DegToRad converts angles. Wrap is modulo for any range.
Live demo
Try:Roll Between, drag Clamp past 50 to see it pin, spin DegToRad, and push Wrap past 100.
Exam questions in this topic
Q1.What is logged?
moderate · outputconsole.log(Phaser.Math.Between(5, 5));
- A0
- ✓5
- C"5"
- Da random value
Why: Phaser.Math.Between is inclusive on both ends, so Between(5,5) always returns 5.
Q2.What is logged?
moderate · outputconst r = new Phaser.Geom.Rectangle(0, 0, 100, 100); console.log(Phaser.Geom.Rectangle.Contains(r, 50, 50));
- ✓true
- Bfalse
- Cundefined
- Dan error
Why: The point (50, 50) lies inside the rectangle (0,0,100,100), so Contains returns true.
Q3.What does `Phaser.Math.Clamp(150, 0, 100)` return?
beginner · mcq- A0
- ✓100
- C150
- Dundefined
Why: Clamp(value, min, max) constrains value to [min, max]. 150 is above 100, so it clamps down to 100.
Q4.What is logged?
beginner · outputconsole.log(Phaser.Math.DegToRad(180).toFixed(2));
- A"1.57"
- ✓"3.14"
- C"180.00"
- D"6.28"
Why: 180° in radians is π ≈ 3.14159, which formats to "3.14".
Q5.What is logged?
moderate · outputconsole.log(Phaser.Math.Wrap(370, 0, 360));
- A0
- ✓10
- C370
- D360
Why: Wrap brings a value into the half-open range [min, max). 370 wraps to 10.
Game Config & Scaling
The Phaser.Game config object sets renderer (Phaser.AUTO picks WebGL else Canvas), dimensions, scale mode, physics default, and parent DOM node.
Live demo
Try:Drag the slider to resize the Phaser canvas. Scale.FIT keeps the 480×280 aspect ratio inside the container.
Exam questions in this topic
Q1.Which value of the `type` property in a Phaser.Game config lets Phaser auto-pick WebGL or Canvas?
beginner · mcq- APhaser.CANVAS
- BPhaser.WEBGL
- ✓Phaser.AUTO
- DPhaser.HEADLESS
Why: Phaser.AUTO tries WebGL first and falls back to Canvas if unavailable.
Q2.What value is logged?
beginner · outputconst game = new Phaser.Game({ width: 800, height: 600, scene: [] }); console.log(game.config.width);- Aundefined
- ✓800
- C600
- D"800"
Why: game.config.width is the numeric width passed in the Game config.
Q3.Phaser is primarily designed for building:
beginner · mcq- A3D AAA games
- ✓2D HTML5 games
- CMobile-native AR apps
- DBackend game servers
Why: Phaser is a fast, free, fun open-source HTML5 framework focused on 2D games.
Q4.In the Game config `scale.mode`, what does Phaser.Scale.FIT do?
moderate · mcq- AStretches the canvas to fill the parent, ignoring aspect ratio
- ✓Scales the canvas to fit inside its parent while preserving aspect ratio
- CLocks the canvas to its original size, no scaling
- DResizes the game world to match the browser
Why: FIT keeps aspect ratio and may letterbox; ENVELOP fills and crops; RESIZE resizes the actual game.
Tilemaps
Tilemaps render large grid worlds efficiently. make.tilemap creates the map, addTilesetImage links the texture, createLayer renders a named layer.
Live demo
Try:Hover any cell — the readout below shows its (x,y), tile index, and label.
Exam questions in this topic
Q1.Which two methods are typically used to assemble a tilemap layer from JSON + a tileset image?
beginner · mcq- Athis.load.json + this.add.sprite
- ✓this.make.tilemap + addTilesetImage / createLayer
- Cthis.tilemap.load + this.tilemap.draw
- DPhaser.Tilemap.fromJSON only
Why: After this.load.tilemapTiledJSON, you call this.make.tilemap(), addTilesetImage(), then createLayer().
Containers & Groups
A Container groups display objects so you can move/rotate them as one. A Group is for game-logic batching — apply velocity or properties to many sprites at once.
Live demo
Try:The 3 dots on the left rotate as one Container. The 4 dots on the right got velocity from the Group.
Exam questions in this topic
Q1.Calling `group.setVelocityX(100)` on an Arcade Physics Group sets the X velocity on every child body.
moderate · tfAnswertrue
Why: Arcade Physics Groups expose helpers like setVelocityX that iterate over their children.
Q2.Fill in the blank to group a sprite and a text under one parent at world (200, 100):
moderate · fillconst ui = this.add.____(200, 100, [sprite, label]);
Answercontainer
Why: Containers position their children in local coordinates, making it easy to move, scale, or destroy a group as a unit.
Depth & Time
setDepth(n) controls draw order — higher renders on top regardless of creation order. update(time, delta) gets a delta value in milliseconds since the last frame.
Live demo
Try:Click any of the overlapping cards to bring it to the front. Watch the delta readout — that's the dt argument.
Exam questions in this topic
Q1.What does `sprite.setDepth(10)` control?
moderate · mcq- AHow fast the sprite falls under gravity
- BHow many layers of physics bodies the sprite has
- ✓The render order — higher depth draws on top of lower-depth objects
- DThe size of the sprite along the Z axis
Why: Depth is purely a display-list sorting key; higher renders on top within the same display list.
Q2.A Scene's `update(time, delta)` is called every frame. What does `delta` represent?
moderate · mcq- AThe total elapsed time since the scene started, in seconds
- ✓The time in milliseconds since the previous frame
- CThe current frame number
- DThe number of physics steps performed this frame
Why: delta is the inter-frame gap in ms. Multiply movement by delta to get frame-rate-independent motion.