Skip to content

Commit 7102a34

Browse files
committed
Camera.flash is a new function that makes the camera 'flash' over the top of your game. It works by filling the game with the solid fill color specified, and then fading it away to alpha 0 over the duration given. This is great for things like hit effects. You can listen for the Camera.onflashComplete Signal.
Camera.fade is a new function that makes the camera fade to the color given, over the course of the duration specified. This is great for things like transitioning from one State to another. You can listen for the Camera.onFadeComplete Signal. Camera.resetFX resets any active FX, such as a fade or flash and immediately clears it. Useful to calling after a fade in order to remove the fade from the Stage. Phaser.Camera.ENABLE_FX is a const that controls if the Camera FX are available or not. It's `true` by default, but if you set it to `false` before boot then it won't create the Graphics object required to process the effects.
1 parent 2ea94c8 commit 7102a34

4 files changed

Lines changed: 230 additions & 13 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ You can read all about the philosophy behind Lazer [here](http://phaser.io/news/
332332
* You can now pass a TilemapLayer as a Texture to a TileSprite. A limitation of this is that if you pass it to a TileSprite it will make a fill pattern from the TilemapLayer at that instant it's passed, and it won't keep track of the layer in future should it update (thanks @jdnichollsc #1989)
333333
* Camera has a new property: `lerp`. This is a Point object, that allows you to control the amount of horizontal and vertical smoothing to be applied to the camera when it tracks a Sprite. It works both with and without deadzones, and is turned off by default. Set it to low values such as 0.1 for really smooth motion tracking (thanks to @WombatTurkey for the idea of adding this)
334334
* Camera.shake is a new function that creates a camera shake effect. You can specify the intensity, duration and direction of the effect. You can also set if it should shake the camera out of bounds or not.
335+
* Camera.flash is a new function that makes the camera 'flash' over the top of your game. It works by filling the game with the solid fill color specified, and then fading it away to alpha 0 over the duration given. This is great for things like hit effects. You can listen for the Camera.onflashComplete Signal.
336+
* Camera.fade is a new function that makes the camera fade to the color given, over the course of the duration specified. This is great for things like transitioning from one State to another. You can listen for the Camera.onFadeComplete Signal.
337+
* Camera.resetFX resets any active FX, such as a fade or flash and immediately clears it. Useful to calling after a fade in order to remove the fade from the Stage.
338+
* Phaser.Camera.ENABLE_FX is a const that controls if the Camera FX are available or not. It's `true` by default, but if you set it to `false` before boot then it won't create the Graphics object required to process the effects.
335339

336340
### New Arcade Physics Features
337341

src/core/Camera.js

Lines changed: 216 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ Phaser.Camera = function (game, id, x, y, width, height) {
8282
this.target = null;
8383

8484
/**
85-
* @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot
85+
* @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot.
8686
*/
8787
this.displayObject = null;
8888

8989
/**
90-
* @property {Phaser.Point} scale - The scale of the display object to which all game objects are added. Set by World.boot
90+
* @property {Phaser.Point} scale - The scale of the display object to which all game objects are added. Set by World.boot.
9191
*/
9292
this.scale = null;
9393

@@ -109,9 +109,30 @@ Phaser.Camera = function (game, id, x, y, width, height) {
109109
this.lerp = new Phaser.Point(1, 1);
110110

111111
/**
112-
* @property {Phaser.Signal} shakeOnComplete - This signal is dispatched when the camera shake effect completes.
112+
* @property {Phaser.Signal} onShakeComplete - This signal is dispatched when the camera shake effect completes.
113113
*/
114-
this.shakeOnComplete = new Phaser.Signal();
114+
this.onShakeComplete = new Phaser.Signal();
115+
116+
/**
117+
* @property {Phaser.Signal} onFlashComplete - This signal is dispatched when the camera flash effect completes.
118+
*/
119+
this.onFlashComplete = new Phaser.Signal();
120+
121+
/**
122+
* This signal is dispatched when the camera fade effect completes.
123+
* When the fade effect completes you will be left with the screen black (or whatever
124+
* color you faded to). In order to reset this call `Camera.resetFX`. This is called
125+
* automatically when you change State.
126+
* @property {Phaser.Signal} onFadeComplete
127+
*/
128+
this.onFadeComplete = new Phaser.Signal();
129+
130+
/**
131+
* The Graphics object used to handle camera fx such as fade and flash.
132+
* @property {Phaser.Graphics} fx
133+
* @protected
134+
*/
135+
this.fx = null;
115136

116137
/**
117138
* @property {Phaser.Point} _targetPosition - Internal point used to calculate target position.
@@ -147,6 +168,18 @@ Phaser.Camera = function (game, id, x, y, width, height) {
147168
y: 0
148169
};
149170

171+
/**
172+
* @property {number} _fxDuration - FX duration timer.
173+
* @private
174+
*/
175+
this._fxDuration = 0;
176+
177+
/**
178+
* @property {number} _fxType - The FX type running.
179+
* @private
180+
*/
181+
this._fxType = 0;
182+
150183
};
151184

152185
/**
@@ -191,8 +224,37 @@ Phaser.Camera.SHAKE_HORIZONTAL = 5;
191224
*/
192225
Phaser.Camera.SHAKE_VERTICAL = 6;
193226

227+
/**
228+
* @constant
229+
* @type {boolean}
230+
*/
231+
Phaser.Camera.ENABLE_FX = true;
232+
194233
Phaser.Camera.prototype = {
195234

235+
/**
236+
* Called automatically by Phaser.World.
237+
*
238+
* @method Phaser.Camera#boot
239+
* @private
240+
*/
241+
boot: function () {
242+
243+
this.displayObject = this.game.world;
244+
245+
this.scale = this.game.world.scale;
246+
247+
this.game.camera = this;
248+
249+
if (Phaser.Graphics && Phaser.Camera.ENABLE_FX)
250+
{
251+
this.fx = new Phaser.Graphics(this.game);
252+
253+
this.game.stage.addChild(this.fx);
254+
}
255+
256+
},
257+
196258
/**
197259
* Camera preUpdate. Sets the total view counter to zero.
198260
*
@@ -298,7 +360,7 @@ Phaser.Camera.prototype = {
298360
* spacing on the x and y axis each frame. You can control the intensity and duration
299361
* of the effect, and if it should effect both axis or just one.
300362
*
301-
* When the shake effect ends the signal Camera.shakeOnComplete is dispatched.
363+
* When the shake effect ends the signal Camera.onShakeComplete is dispatched.
302364
*
303365
* @method Phaser.Camera#shake
304366
* @param {float} [intensity=0.05] - The intensity of the camera shake. Given as a percentage of the camera size representing the maximum distance that the camera can move while shaking.
@@ -336,6 +398,91 @@ Phaser.Camera.prototype = {
336398

337399
},
338400

401+
/**
402+
* This creates a camera flash effect. It works by filling the game with the solid fill
403+
* color specified, and then fading it away to alpha 0 over the duration given.
404+
*
405+
* You can use this for things such as hit feedback effects.
406+
*
407+
* When the effect ends the signal Camera.onFlashComplete is dispatched.
408+
*
409+
* @method Phaser.Camera#flash
410+
* @param {numer} [color=0xffffff] - The color of the flash effect. I.e. 0xffffff for white, 0xff0000 for red, etc.
411+
* @param {number} [duration=500] - The duration of the flash effect in milliseconds.
412+
* @param {boolean} [force=false] - If a camera flash or fade effect is already running and force is true it will replace the previous effect, resetting the duration.
413+
* @return {boolean} True if the effect was started, otherwise false.
414+
*/
415+
flash: function (color, duration, force) {
416+
417+
if (color === undefined) { color = 0xffffff; }
418+
if (duration === undefined) { duration = 500; }
419+
if (force === undefined) { force = false; }
420+
421+
if (!this.fx || (!force && this._fxDuration > 0))
422+
{
423+
return false;
424+
}
425+
426+
this.fx.clear();
427+
428+
this.fx.beginFill(color);
429+
this.fx.drawRect(0, 0, this.width, this.height);
430+
this.fx.endFill();
431+
432+
this.fx.alpha = 1;
433+
434+
this._fxDuration = duration;
435+
this._fxType = 0;
436+
437+
return true;
438+
439+
},
440+
441+
/**
442+
* This creates a camera fade effect. It works by filling the game with the
443+
* color specified, over the duration given, ending with a solid fill.
444+
*
445+
* You can use this for things such as transitioning to a new scene.
446+
*
447+
* The game will be left 'filled' at the end of this effect, likely obscuring
448+
* everything. In order to reset it you can call `Camera.resetFX` and it will clear the
449+
* fade. Or you can call `Camera.flash` with the same color as the fade, and it will
450+
* reverse the process, bringing the game back into view again.
451+
*
452+
* When the effect ends the signal Camera.onFadeComplete is dispatched.
453+
*
454+
* @method Phaser.Camera#fade
455+
* @param {numer} [color=0x000000] - The color the game will fade to. I.e. 0x000000 for black, 0xff0000 for red, etc.
456+
* @param {number} [duration=500] - The duration of the fade in milliseconds.
457+
* @param {boolean} [force=false] - If a camera flash or fade effect is already running and force is true it will replace the previous effect, resetting the duration.
458+
* @return {boolean} True if the effect was started, otherwise false.
459+
*/
460+
fade: function (color, duration, force) {
461+
462+
if (color === undefined) { color = 0x000000; }
463+
if (duration === undefined) { duration = 500; }
464+
if (force === undefined) { force = false; }
465+
466+
if (!this.fx || (!force && this._fxDuration > 0))
467+
{
468+
return false;
469+
}
470+
471+
this.fx.clear();
472+
473+
this.fx.beginFill(color);
474+
this.fx.drawRect(0, 0, this.width, this.height);
475+
this.fx.endFill();
476+
477+
this.fx.alpha = 0;
478+
479+
this._fxDuration = duration;
480+
this._fxType = 1;
481+
482+
return true;
483+
484+
},
485+
339486
/**
340487
* The camera update loop. This is called automatically by the core game loop.
341488
*
@@ -344,6 +491,11 @@ Phaser.Camera.prototype = {
344491
*/
345492
update: function () {
346493

494+
if (this._fxDuration > 0)
495+
{
496+
this.updateFX();
497+
}
498+
347499
if (this.target)
348500
{
349501
this.updateTarget();
@@ -371,6 +523,41 @@ Phaser.Camera.prototype = {
371523

372524
},
373525

526+
/**
527+
* Update the camera flash and fade effects.
528+
*
529+
* @method Phaser.Camera#updateFX
530+
* @private
531+
*/
532+
updateFX: function () {
533+
534+
if (this._fxType === 0)
535+
{
536+
// flash
537+
this.fx.alpha -= this.game.time.elapsedMS / this._fxDuration;
538+
539+
if (this.fx.alpha <= 0)
540+
{
541+
this._fxDuration = 0;
542+
this.fx.alpha = 0;
543+
this.onFlashComplete.dispatch();
544+
}
545+
}
546+
else
547+
{
548+
// fade
549+
this.fx.alpha += this.game.time.elapsedMS / this._fxDuration;
550+
551+
if (this.fx.alpha >= 1)
552+
{
553+
this._fxDuration = 0;
554+
this.fx.alpha = 1;
555+
this.onFadeComplete.dispatch();
556+
}
557+
}
558+
559+
},
560+
374561
/**
375562
* Update the camera shake effect.
376563
*
@@ -383,7 +570,7 @@ Phaser.Camera.prototype = {
383570

384571
if (this._shake.duration <= 0)
385572
{
386-
this.shakeOnComplete.dispatch();
573+
this.onShakeComplete.dispatch();
387574
this._shake.x = 0;
388575
this._shake.y = 0;
389576
}
@@ -562,15 +749,38 @@ Phaser.Camera.prototype = {
562749

563750
/**
564751
* Resets the camera back to 0,0 and un-follows any object it may have been tracking.
752+
* Also immediately resets any camera effects that may have been running such as
753+
* shake, flash or fade.
565754
*
566755
* @method Phaser.Camera#reset
567756
*/
568757
reset: function () {
569758

570759
this.target = null;
760+
571761
this.view.x = 0;
572762
this.view.y = 0;
573763

764+
this._shake.duration = 0;
765+
766+
this.resetFX();
767+
768+
},
769+
770+
/**
771+
* Resets any active FX, such as a fade or flash and immediately clears it.
772+
* Useful to calling after a fade in order to remove the fade from the Stage.
773+
*
774+
* @method Phaser.Camera#resetFX
775+
*/
776+
resetFX: function () {
777+
778+
this.fx.clear();
779+
780+
this.fx.alpha = 0;
781+
782+
this._fxDuration = 0;
783+
574784
}
575785

576786
};

src/core/World.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,10 @@ Phaser.World.prototype.boot = function () {
6767

6868
this.camera = new Phaser.Camera(this.game, 0, 0, 0, this.game.width, this.game.height);
6969

70-
this.camera.displayObject = this;
71-
72-
this.camera.scale = this.scale;
73-
74-
this.game.camera = this.camera;
75-
7670
this.game.stage.addChild(this);
7771

72+
this.camera.boot();
73+
7874
};
7975

8076
/**

typescript/phaser.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,19 +583,23 @@ declare module Phaser {
583583
static SHAKE_BOTH: number;
584584
static SHAKE_HORIZONTAL: number;
585585
static SHAKE_VERTICAL: number;
586+
static ENABLE_FX: number;
586587

587588
atLimit: { x: boolean; y: boolean; };
588589
bounds: Phaser.Rectangle;
589590
deadzone: Phaser.Rectangle;
590591
displayObject: PIXI.DisplayObject;
591592
id: number;
593+
fx: Phaser.Graphics;
592594
game: Phaser.Game;
593595
height: number;
594596
lerp: Phaser.Point;
595597
position: Phaser.Point;
596598
roundPx: boolean;
597599
scale: Phaser.Point;
598-
shakeOnComplete: Phaser.Signal;
600+
onFadeComplete: Phaser.Signal;
601+
onFlashComplete: Phaser.Signal;
602+
onShakeComplete: Phaser.Signal;
599603
target: Phaser.Sprite;
600604
totalInView: number;
601605
view: Phaser.Rectangle;
@@ -606,10 +610,13 @@ declare module Phaser {
606610
y: number;
607611

608612
checkBounds(): void;
613+
fade(color?: number, duration?: number, force?: boolean): boolean;
614+
flash(color?: number, duration?: number, force?: boolean): boolean;
609615
focusOn(displayObject: PIXI.DisplayObject): void;
610616
focusOnXY(x: number, y: number): void;
611617
follow(target: Phaser.Sprite, style?: number, lerpX?: number, lerpY?: number): void;
612618
reset(): void;
619+
resetFX(): void;
613620
setBoundsToWorld(): void;
614621
setPosition(x: number, y: number): void;
615622
setSize(width: number, height: number): void;

0 commit comments

Comments
 (0)