Skip to content

Commit 7a23378

Browse files
committed
Unified use of roundPixels, antialias and pixelArt modes
1 parent a6ab61d commit 7a23378

15 files changed

Lines changed: 66 additions & 40 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@
2626
* `CameraManager.getTotal` is a new method that will return the total number of Cameras being managed, with an optional `isVisible` argument, that only counts visible cameras if set.
2727
* `CameraManager.remove` can now take an array of cameras to be removed from the manager, as well as a single camera.
2828
* `CameraManager.remove` would previously not allow you to remove a camera if it meant there would be no cameras left in the Camera Manager. This restriction has been removed. A Camera Manager can now run even with zero cameras. Your game obviously won't display anything, but it's still now possible.
29+
* `CameraManager.remove` will now return the total number of Cameras removed.
30+
31+
### Round Pixels Changes
32+
33+
Before explaining the changes it's worth covering what the three different game config properties do:
34+
35+
`roundPixels` - this will cause the renderer to draw most Game Objects at whole integer positions. Their actual positions can be anything, but the renderer will floor the values to ensure they are integers immediately before drawing. It only works on texture based Game Objects. Graphics objects, for instance, ignore this property.
36+
37+
`antialias` - when set to `true` WebGL textures are created using `gl.LINEAR`, which allows WebGL to try its best to interpolate the texture when rendered at non-texture frame sizes. This can happen if you scale a Game Object, or zoom a Camera. In both cases it will need to interpolate the pixel values to accommodate the new size. If this property is set to `false` then it will use `gl.NEAREST` instead. This uses a nearest neighbor method of interpolation, and is nearly always the better option if you need to keep the textures crisp, such as when using scaled pixel art. Disabling `antialias` invokes nearest-neighbor interpolation on the game canvas itself as well. If you need a mixture of aliased and anti-aliased textures in your game, then you can change them on a per-texture basis by using `Texture.setFilter`.
38+
39+
There is a third game config property called `pixelArt`. If set to `true` it's the same thing as enabling `roundPixels` and disabling `antialias`. This is the optimum setting for pixel art games.
40+
41+
* Both renderers will now check for `pixelArt` OR `antialias` before setting the canvas scale mode. Both values are checked during texture creation as well.
42+
* If in your game config you have enabled either pixel art mode or roundPixels, then all Cameras will have their `roundPixels` values set to `true` by default. You can toggle this by changing the `CameraManager.roundPixels` property, or change it on a camera-by-camera basis, as needed.
43+
* `Camera.roundPixels` is now used across all rendering code for both Canvas and WebGL. Previously, it would check the renderer config value, but now all renderer code uses the camera value to decide if it should floor the drawing position or not.
2944

3045
### New Features
3146

src/boot/Config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ var Config = new Class({
341341
/**
342342
* @const {boolean} Phaser.Boot.Config#roundPixels - [description]
343343
*/
344-
this.roundPixels = GetValue(renderConfig, 'roundPixels', false);
344+
this.roundPixels = GetValue(renderConfig, 'roundPixels', this.pixelArt);
345345

346346
/**
347347
* @const {boolean} Phaser.Boot.Config#transparent - [description]

src/boot/CreateRenderer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ var CreateRenderer = function (game)
4848
}
4949

5050
// Pixel Art mode?
51-
if (config.pixelArt)
51+
if (config.pixelArt || !config.antialias)
5252
{
5353
CanvasPool.disableSmoothing();
5454
}
@@ -70,7 +70,7 @@ var CreateRenderer = function (game)
7070
}
7171

7272
// Pixel Art mode?
73-
if (config.pixelArt)
73+
if (config.pixelArt || !config.antialias)
7474
{
7575
CanvasInterpolation.setCrisp(game.canvas);
7676
}

src/cameras/2d/Camera.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,8 +1462,9 @@ var Camera = new Class({
14621462
},
14631463

14641464
/**
1465-
* Should the Camera round pixel values to whole integers when scrolling?
1466-
* In some types of game this is required to prevent sub-pixel aliasing.
1465+
* Should the Camera round pixel values to whole integers when rendering Game Objects?
1466+
*
1467+
* In some types of game, especially with pixel art, this is required to prevent sub-pixel aliasing.
14671468
*
14681469
* @method Phaser.Cameras.Scene2D.Camera#setRoundPixels
14691470
* @since 3.0.0

src/cameras/2d/CameraManager.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ var CameraManager = new Class({
9393
*/
9494
this.systems = scene.sys;
9595

96+
/**
97+
* All Cameras created by, or added to, this Camera Manager, will have their `roundPixels`
98+
* property set to match this value. By default it is set to match the value set in the
99+
* game configuration, but can be changed at any point. Equally, individual cameras can
100+
* also be changed as needed.
101+
*
102+
* @name Phaser.Cameras.Scene2D.CameraManager#roundPixels
103+
* @type {boolean}
104+
* @since 3.11.0
105+
*/
106+
this.roundPixels = scene.sys.game.config.roundPixels;
107+
96108
/**
97109
* An Array of the Camera objects being managed by this Camera Manager.
98110
* The Cameras are updated and rendered in the same order in which they appear in this array.
@@ -197,6 +209,10 @@ var CameraManager = new Class({
197209
* By default Cameras are transparent and will render anything that they can see based on their `scrollX`
198210
* and `scrollY` values. Game Objects can be set to be ignored by a Camera by using the `Camera.ignore` method.
199211
*
212+
* Please note that it will have its `roundPixels` propery set to whatever is set on the game and renderer
213+
* configuration. So if you've got a game config with `pixelArt: true` in it, then `roundPixels` will always
214+
* be set to `true` on the new Camera.
215+
*
200216
* See the Camera class documentation for more details.
201217
*
202218
* @method Phaser.Cameras.Scene2D.CameraManager#add
@@ -224,6 +240,7 @@ var CameraManager = new Class({
224240

225241
camera.setName(name);
226242
camera.setScene(this.scene);
243+
camera.setRoundPixels(this.roundPixels);
227244

228245
camera.id = this.getNextID();
229246

@@ -242,6 +259,10 @@ var CameraManager = new Class({
242259
*
243260
* The Camera should either be a `Phaser.Cameras.Scene2D.Camera` instance, or a class that extends from it.
244261
*
262+
* Please note that it will have its `roundPixels` propery set to whatever is set on the game and renderer
263+
* configuration. So if you've got a game config with `pixelArt: true` in it, then `roundPixels` will always
264+
* be set to `true` on the Camera added to this Camera Manager.
265+
*
245266
* The Camera will be assigned an ID, which is used for Game Object exclusion and then added to the
246267
* manager. As long as it doesn't already exist in the manager it will be added then returned.
247268
*
@@ -265,6 +286,8 @@ var CameraManager = new Class({
265286
{
266287
camera.id = this.getNextID();
267288

289+
camera.setRoundPixels(this.roundPixels);
290+
268291
this.cameras.push(camera);
269292

270293
if (makeMain)

src/gameobjects/bitmaptext/dynamic/DynamicBitmapTextCanvasRenderer.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ var DynamicBitmapTextCanvasRenderer = function (renderer, src, interpolationPerc
127127
ctx.clip();
128128
}
129129

130-
var roundPixels = renderer.config.roundPixels;
131-
132130
for (var index = 0; index < textLength; ++index)
133131
{
134132
// Reset the scale (in case the callback changed it)
@@ -186,7 +184,7 @@ var DynamicBitmapTextCanvasRenderer = function (renderer, src, interpolationPerc
186184
x -= cameraScrollX;
187185
y -= cameraScrollY;
188186

189-
if (roundPixels)
187+
if (camera.roundPixels)
190188
{
191189
x |= 0;
192190
y |= 0;

src/gameobjects/bitmaptext/static/BitmapTextCanvasRenderer.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,10 @@ var BitmapTextCanvasRenderer = function (renderer, src, interpolationPercentage,
9191
renderer.currentScaleMode = src.scaleMode;
9292
}
9393

94-
var roundPixels = renderer.config.roundPixels;
95-
9694
var tx = (src.x - camera.scrollX * src.scrollFactorX) + src.frame.x;
9795
var ty = (src.y - camera.scrollY * src.scrollFactorY) + src.frame.y;
9896

99-
if (roundPixels)
97+
if (camera.roundPixels)
10098
{
10199
tx |= 0;
102100
ty |= 0;
@@ -167,7 +165,7 @@ var BitmapTextCanvasRenderer = function (renderer, src, interpolationPercentage,
167165
continue;
168166
}
169167

170-
if (roundPixels)
168+
if (camera.roundPixels)
171169
{
172170
x |= 0;
173171
y |= 0;

src/gameobjects/particles/ParticleManagerCanvasRenderer.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ var ParticleManagerCanvasRenderer = function (renderer, emitterManager, interpol
6464
ctx.globalCompositeOperation = renderer.blendModes[emitter.blendMode];
6565
}
6666

67-
var roundPixels = renderer.config.roundPixels;
68-
6967
for (var index = 0; index < length; ++index)
7068
{
7169
var particle = particles[index];
@@ -90,7 +88,7 @@ var ParticleManagerCanvasRenderer = function (renderer, emitterManager, interpol
9088
var tx = particle.x - cameraScrollX;
9189
var ty = particle.y - cameraScrollY;
9290

93-
if (roundPixels)
91+
if (camera.roundPixels)
9492
{
9593
tx |= 0;
9694
ty |= 0;

src/gameobjects/text/static/TextCanvasRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ var TextCanvasRenderer = function (renderer, src, interpolationPercentage, camer
7373
var tx = src.x - camera.scrollX * src.scrollFactorX;
7474
var ty = src.y - camera.scrollY * src.scrollFactorY;
7575

76-
if (renderer.config.roundPixels)
76+
if (camera.roundPixels)
7777
{
7878
tx |= 0;
7979
ty |= 0;

src/gameobjects/tilesprite/TileSpriteCanvasRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ var TileSpriteCanvasRenderer = function (renderer, src, interpolationPercentage,
8686
dy += src.height;
8787
}
8888

89-
if (renderer.config.roundPixels)
89+
if (camera.roundPixels)
9090
{
9191
dx |= 0;
9292
dy |= 0;

0 commit comments

Comments
 (0)