Screen & Viewport
The Screen is useful for for controlling the shape and behavior of you screen.
Basic Screen
For many games specifying a static width and height is all you need. This example is the default DisplayMode, fixed.
typescript
const game = new ex.Engine({width: 800,height: 600});
typescript
const game = new ex.Engine({width: 800,height: 600});
The above snippet has the affect of setting the logical resolution to 800x600 and the viewport css pixels to 800x600.
Understanding Viewport & Resolution
Excalibur has a screen abstraction for dealing with Screen.viewport size, and Screen.resolution. It also handles HiDPI scaling, the browser fullscreen API, and translation of screen coordinates into game world coordinates.
The Screen.viewport represents the size of the window into the game work in CSS pixels on the screen. Another way to think about viewport is it represents the actual size of the "window" into the game on the computer screen.
The Screen.resolution represents the number of logical pixels stretched across the viewport.
For example, a screen with resolution 100x100 and a resolution of 1000x1000 stretches, 100 logical game pixels across 1000 pixels of the screen.
The screen resolution and viewport can be set and accessed of the engine constructor.
typescript
const game = new ex.Engine({// set the viewport dimensionsviewport: { width: 800, height: 600 },// sets the resolutionresolution: ex.Resolution.GameBoy});const screen = game.screen;
typescript
const game = new ex.Engine({// set the viewport dimensionsviewport: { width: 800, height: 600 },// sets the resolutionresolution: ex.Resolution.GameBoy});const screen = game.screen;
HiDPI scaling
Excalibur will automatically detect HiDPI devices and scale the internal canvas resolution. This prevents an issue that causes graphics to look blurry because images are spread across at least twice as many physical pixels. Read more about this on MDN.
This automatic scaling can be disabled with the suppressHiDPIScaling: true
in the Engine constructor.
You may wish to disable this scaling for a few reasons:
- Large resolutions in addition to the scaling can cause games to break on mobile (4k pixels in width or height will cause mobile devices to fail loading to the GPU).
- Performance, a smaller resolution means the game does not need to drive as many pixels.
Large resolutions (Commonly in the range 4000x4000) can cause problems on HiDPI screens (aka Retina), the underlying WebGL technology will limit the size.
If you need large resolutions you may need to suppress HiDPI
typescript
const game = new ex.Engine({// set the viewport dimensionsviewport: { width: 800, height: 600 },// sets the resolutionresolution: { width: 3000, height: 3000 },suppressHiDPIScaling: true});
typescript
const game = new ex.Engine({// set the viewport dimensionsviewport: { width: 800, height: 600 },// sets the resolutionresolution: { width: 3000, height: 3000 },suppressHiDPIScaling: true});
Coordinate systems
In Excalibur, due to HTML canvas native and scaled resolution, there are essentially two kinds of coordinates: a screen coordinate and a world coordinate.
Screen coordinates
A screen coordinate is a point on a user's physical screen. (0, 0)
in screen coordinates is the top-left of the canvas. Excalibur translates mouse event positions into screen coordinates for you. Screen coordinates ignore the game camera, think of it like where the user is physically pointing on top of your game.
World coordinates
A world coordinate is a point in the game world relative to a scene's camera. The world space is the default place where actors operate. By default the camera is centered such that the origin is in the top left. If the camera is not moved (0, 0)
in the game world will be the top left of your game, but if you move the camera to (0, 0)
the actor will now be center screen.
Converting between coordinates
Usually, your game logic should only deal in terms of world coordinates because this is the coordinate system you're positioning actors in or drawing in. Sometimes though, you need to convert between systems when interfacing with input.
Excalibur provides two methods to convert between systems, Engine.screenToWorldCoordinates and Engine.worldToScreenCoordinates. Use these methods to convert between coordinate systems as they take into account all the information Excalibur collects to appropriately do the math for you including scaling, device pixel ratio, and more.
Game resolution
An HTML canvas element has a "native" resolution which is specified using the width
and height
HTML attributes. In Excalibur, these can be set using canvasWidth and canvasHeight respectively.
Native Resolution
If you don't explicitly set canvasWidth
or canvasHeight
Excalibur will manage the values for you, meaning that the "native" resolution will be the physical screen width/height so there is no "scaling" happening. This means your game logic must be responsive if the resolution of the game changes and you cannot depend on a "fixed" width/height coordinate system. Games which can be played on mobile devices and desktop will work, since your game logic can detect what screen size the game is being played on and respond accordingly.