diff --git a/Phaser/Game.ts b/Phaser/Game.ts index 62fab329..2e78c96d 100644 --- a/Phaser/Game.ts +++ b/Phaser/Game.ts @@ -25,7 +25,7 @@ /// /// /// -/// +/// /// /// @@ -368,12 +368,12 @@ module Phaser { switch (type) { case Phaser.Types.RENDERER_AUTO_DETECT: - this.renderer = new Phaser.HeadlessRenderer(this); + this.renderer = new Phaser.Renderer.Headless.HeadlessRenderer(this); break; case Phaser.Types.RENDERER_AUTO_DETECT: case Phaser.Types.RENDERER_CANVAS: - this.renderer = new Phaser.CanvasRenderer(this); + this.renderer = new Phaser.Renderer.Canvas.CanvasRenderer(this); break; // WebGL coming soon :) diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj index 38ac7d55..be0de927 100644 --- a/Phaser/Phaser.csproj +++ b/Phaser/Phaser.csproj @@ -152,7 +152,6 @@ - @@ -204,6 +203,34 @@ Manager.ts + + + + + CameraRenderer.ts + + + CanvasRenderer.ts + + + + + GeometryRenderer.ts + + + GroupRenderer.ts + + + + ScrollZoneRenderer.ts + + + SpriteRenderer.ts + + + + TilemapRenderer.ts + HeadlessRenderer.ts @@ -214,9 +241,6 @@ Statics.ts - - CanvasRenderer.ts - OrientationScreen.ts diff --git a/Phaser/Stage.ts b/Phaser/Stage.ts index 42c4bf0e..b14f4e54 100644 --- a/Phaser/Stage.ts +++ b/Phaser/Stage.ts @@ -203,6 +203,8 @@ module Phaser { this.scale.update(); + this.context.setTransform(1, 0, 0, 1, 0, 0); + if (this.clear || (this._game.paused && this.disablePauseScreen == false)) { if (this.patchAndroidClearRectBug) diff --git a/Phaser/Statics.ts b/Phaser/Statics.ts index af1e0e3e..e44fd5a8 100644 --- a/Phaser/Statics.ts +++ b/Phaser/Statics.ts @@ -10,6 +10,33 @@ module Phaser { static RENDERER_CANVAS: number = 2; static RENDERER_WEBGL: number = 3; + static CAMERA_TYPE_ORTHOGRAPHIC: number = 0; + static CAMERA_TYPE_ISOMETRIC: number = 1; + + /** + * Camera "follow" style preset: camera has no deadzone, just tracks the focus object directly. + * @type {number} + */ + public static CAMERA_FOLLOW_LOCKON: number = 0; + + /** + * Camera "follow" style preset: camera deadzone is narrow but tall. + * @type {number} + */ + public static CAMERA_FOLLOW_PLATFORMER: number = 1; + + /** + * Camera "follow" style preset: camera deadzone is a medium-size square around the focus object. + * @type {number} + */ + public static CAMERA_FOLLOW_TOPDOWN: number = 2; + + /** + * Camera "follow" style preset: camera deadzone is a small square around the focus object. + * @type {number} + */ + public static CAMERA_FOLLOW_TOPDOWN_TIGHT: number = 3; + static GROUP: number = 0; static SPRITE: number = 1; static GEOMSPRITE: number = 2; @@ -21,7 +48,7 @@ module Phaser { static GEOM_POINT: number = 0; static GEOM_CIRCLE: number = 1; - static GEOM_Rectangle: number = 2; + static GEOM_RECTANGLE: number = 2; static GEOM_LINE: number = 3; static GEOM_POLYGON: number = 4; diff --git a/Phaser/cameras/Camera.ts b/Phaser/cameras/Camera.ts index c4375c39..5367df2f 100644 --- a/Phaser/cameras/Camera.ts +++ b/Phaser/cameras/Camera.ts @@ -51,9 +51,17 @@ module Phaser { this.transform = new Phaser.Components.TransformManager(this); this.texture = new Phaser.Display.Texture(this); - this.texture.opaque = false; + // We create a hidden canvas for our camera the size of the game (we use the screenView to clip the render to the camera size) + this.texture.canvas = document.createElement('canvas'); + this.texture.canvas.width = width; + this.texture.canvas.height = height; + this.texture.context = this.texture.canvas.getContext('2d'); - this.checkClip(); + // Handy proxies + this.scale = this.transform.scale; + this.alpha = this.texture.alpha; + this.origin = this.transform.origin; + this.crop = this.texture.crop; } @@ -81,39 +89,44 @@ module Phaser { public transform: Phaser.Components.TransformManager; /** - * Camera "follow" style preset: camera has no deadzone, just tracks the focus object directly. - * @type {number} - */ - public static STYLE_LOCKON: number = 0; + * The scale of the Sprite. A value of 1 is original scale. 0.5 is half size. 2 is double the size. + * This is a reference to Sprite.transform.scale + */ + public scale: Phaser.Vec2; /** - * Camera "follow" style preset: camera deadzone is narrow but tall. - * @type {number} + * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it. + * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored. + * This is a reference to Sprite.texture.crop + * @type {Phaser.Rectangle} */ - public static STYLE_PLATFORMER: number = 1; + public crop: Phaser.Rectangle; /** - * Camera "follow" style preset: camera deadzone is a medium-size square around the focus object. - * @type {number} - */ - public static STYLE_TOPDOWN: number = 2; + * The origin of the Sprite around which rotation and positioning takes place. + * This is a reference to Sprite.transform.origin + */ + public origin: Phaser.Vec2; /** - * Camera "follow" style preset: camera deadzone is a small square around the focus object. - * @type {number} - */ - public static STYLE_TOPDOWN_TIGHT: number = 3; + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + public set alpha(value: number) { + this.texture.alpha = value; + } + + /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + public get alpha(): number { + return this.texture.alpha; + } /** * Identity of this camera. */ public ID: number; - /** - * Controls if this camera is clipped or not when rendering. You shouldn't usually set this value directly. - */ - public clip: bool = false; - /** * Camera view Rectangle in world coordinate. * @type {Rectangle} @@ -143,12 +156,6 @@ module Phaser { */ public deadzone: Rectangle = null; - /** - * Disable the automatic camera canvas clipping when Camera is non-Stage sized. - * @type {Boolean} - */ - public disableClipping: bool = false; - /** * Whether this camera is visible or not. (default is true) * @type {boolean} @@ -168,10 +175,7 @@ module Phaser { */ public hide(object) { - if (this.isHidden(object) == false) - { - object.texture['cameraBlacklist'].push(this.ID); - } + object.texture.hideFromCamera(this); } @@ -181,7 +185,7 @@ module Phaser { * @param object {Sprite/Group} The object to check. */ public isHidden(object): bool { - return (object.texture['cameraBlacklist'] && object.texture['cameraBlacklist'].length > 0 && object.texture['cameraBlacklist'].indexOf(this.ID) == -1); + return object.texture.isHidden(this); } /** @@ -192,10 +196,7 @@ module Phaser { */ public show(object) { - if (this.isHidden(object) == true) - { - object.texture['cameraBlacklist'].slice(object.texture['cameraBlacklist'].indexOf(this.ID), 1); - } + object.texture.showToCamera(this); } @@ -204,7 +205,7 @@ module Phaser { * @param target {Sprite} The object you want the camera to track. Set to null to not follow anything. * @param [style] {number} Leverage one of the existing "deadzone" presets. If you use a custom deadzone, ignore this parameter and manually specify the deadzone after calling follow(). */ - public follow(target: Sprite, style?: number = Camera.STYLE_LOCKON) { + public follow(target: Sprite, style?: number = Phaser.Types.CAMERA_FOLLOW_LOCKON) { this._target = target; @@ -212,20 +213,20 @@ module Phaser { switch (style) { - case Camera.STYLE_PLATFORMER: + case Phaser.Types.CAMERA_FOLLOW_PLATFORMER: var w: number = this.width / 8; var h: number = this.height / 3; this.deadzone = new Rectangle((this.width - w) / 2, (this.height - h) / 2 - h * 0.25, w, h); break; - case Camera.STYLE_TOPDOWN: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN: helper = Math.max(this.width, this.height) / 4; this.deadzone = new Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_TOPDOWN_TIGHT: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT: helper = Math.max(this.width, this.height) / 8; this.deadzone = new Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_LOCKON: + case Phaser.Types.CAMERA_FOLLOW_LOCKON: default: this.deadzone = null; break; @@ -364,6 +365,8 @@ module Phaser { } } + this.worldView.floor(); + this.plugins.update(); } @@ -388,7 +391,7 @@ module Phaser { if (this.worldView.x > this.worldBounds.right - this.width) { - this.worldView.x = (this.worldBounds.right - this.width) + 1; + this.worldView.x = this.worldBounds.right - this.width; } if (this.worldView.y < this.worldBounds.top) @@ -398,10 +401,12 @@ module Phaser { if (this.worldView.y > this.worldBounds.bottom - this.height) { - this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + this.worldView.y = this.worldBounds.bottom - this.height; } } + this.worldView.floor(); + this.plugins.postUpdate(); } @@ -440,27 +445,53 @@ module Phaser { } public set width(value: number) { + this.screenView.width = value; this.worldView.width = value; + + if (value !== this.texture.canvas.width) + { + this.texture.canvas.width = value; + } + } public set height(value: number) { + this.screenView.height = value; this.worldView.height = value; + + if (value !== this.texture.canvas.height) + { + this.texture.canvas.height = value; + } + } public setPosition(x: number, y: number) { + this.screenView.x = x; this.screenView.y = y; - this.checkClip(); + } public setSize(width: number, height: number) { + this.screenView.width = width * this.transform.scale.x; this.screenView.height = height * this.transform.scale.y; this.worldView.width = width; this.worldView.height = height; - this.checkClip(); + + if (width !== this.texture.canvas.width) + { + this.texture.canvas.width = width; + } + + if (height !== this.texture.canvas.height) + { + this.texture.canvas.height = height; + } + } /** @@ -478,19 +509,6 @@ module Phaser { this.transform.rotation = this.game.math.wrap(value, 360, 0); } - private checkClip() { - - if (this.screenView.x != 0 || this.screenView.y != 0 || this.screenView.width < this.game.stage.width || this.screenView.height < this.game.stage.height) - { - this.clip = true; - } - else - { - this.clip = false; - } - - } - } } \ No newline at end of file diff --git a/Phaser/cameras/CameraManager.ts b/Phaser/cameras/CameraManager.ts index 9a1429e5..b4094778 100644 --- a/Phaser/cameras/CameraManager.ts +++ b/Phaser/cameras/CameraManager.ts @@ -28,6 +28,7 @@ module Phaser { this._cameras = []; this.defaultCamera = this.addCamera(x, y, width, height); + this.current = this.defaultCamera; } @@ -57,9 +58,6 @@ module Phaser { */ private _sortOrder: number; - public static CAMERA_TYPE_ORTHOGRAPHIC: number = 0; - public static CAMERA_TYPE_ISOMETRIC: number = 1; - /** * Currently used camera. */ @@ -112,7 +110,7 @@ module Phaser { * @param height {number} Height of the new camera. * @returns {Camera} The newly created camera object. */ - public addCamera(x: number, y: number, width: number, height: number, type: number = CameraManager.CAMERA_TYPE_ORTHOGRAPHIC): Camera { + public addCamera(x: number, y: number, width: number, height: number): Camera { var newCam: Camera = new Camera(this._game, this._cameraInstance, x, y, width, height); diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts index 1839a54c..3da9ffbb 100644 --- a/Phaser/core/Group.ts +++ b/Phaser/core/Group.ts @@ -236,7 +236,7 @@ module Phaser { return; } - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; @@ -252,12 +252,12 @@ module Phaser { } else { - this.game.renderer.renderGameObject(this._member); + this.game.renderer.renderGameObject(camera, this._member); } } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); } @@ -267,7 +267,7 @@ module Phaser { */ public directRender(camera: Camera) { - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; @@ -288,7 +288,7 @@ module Phaser { } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); } diff --git a/Phaser/display/Texture.ts b/Phaser/display/Texture.ts index 769fa48f..8fc32f75 100644 --- a/Phaser/display/Texture.ts +++ b/Phaser/display/Texture.ts @@ -32,9 +32,15 @@ module Phaser.Display { this._height = 16; this.cameraBlacklist = []; + this._blacklist = 0; } + /** + * Camera Blacklist length + */ + private _blacklist: number; + /** * Private _width - use the width getter/setter instead */ @@ -167,6 +173,51 @@ module Phaser.Display { */ public crop: Phaser.Rectangle; + /** + * Hides an object from this Camera. Hidden objects are not rendered. + * + * @param object {Camera} The camera this object should ignore. + */ + public hideFromCamera(camera: Camera) { + + if (this.isHidden(camera) == false) + { + this.cameraBlacklist.push(camera.ID); + this._blacklist++; + } + + } + + /** + * Returns true if this texture is hidden from rendering to the given camera, otherwise false. + */ + public isHidden(camera: Camera): bool { + + if (this._blacklist && this.cameraBlacklist.indexOf(camera.ID) !== -1) + { + return true; + } + + return false; + + } + + /** + * Un-hides an object previously hidden to this Camera. + * The object must implement a public cameraBlacklist property. + * + * @param object {Sprite/Group} The object this camera should display. + */ + public showToCamera(camera: Camera) { + + if (this.isHidden(camera)) + { + this.cameraBlacklist.slice(this.cameraBlacklist.indexOf(camera.ID), 1); + this._blacklist--; + } + + } + /** * Updates the texture being used to render the Sprite. * Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture. diff --git a/Phaser/geom/Rectangle.ts b/Phaser/geom/Rectangle.ts index a9a8f22a..5f9f609a 100644 --- a/Phaser/geom/Rectangle.ts +++ b/Phaser/geom/Rectangle.ts @@ -300,6 +300,17 @@ module Phaser { } + /** + * Runs Math.floor() on both the x and y values of this Rectangle. + * @method floor + **/ + public floor() { + + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + + } + /** * Copies the x, y, width and height properties from any given object to this Rectangle. * @method copyFrom diff --git a/Phaser/renderers/CanvasRenderer.ts b/Phaser/renderers/CanvasRenderer.ts deleted file mode 100644 index bb14ff97..00000000 --- a/Phaser/renderers/CanvasRenderer.ts +++ /dev/null @@ -1,829 +0,0 @@ -/// -/// -/// -/// -/// - -module Phaser { - - export class CanvasRenderer implements Phaser.IRenderer { - - constructor(game: Phaser.Game) { - this._game = game; - } - - /** - * The essential reference to the main game object - */ - private _game: Phaser.Game; - - // Local rendering related temp vars to help avoid gc spikes through var creation - private _ga: number = 1; - private _sx: number = 0; - private _sy: number = 0; - private _sw: number = 0; - private _sh: number = 0; - private _dx: number = 0; - private _dy: number = 0; - private _dw: number = 0; - private _dh: number = 0; - private _fx: number = 1; - private _fy: number = 1; - private _tx: number = 0; - private _ty: number = 0; - private _sin: number = 0; - private _cos: number = 1; - private _maxX: number = 0; - private _maxY: number = 0; - private _startX: number = 0; - private _startY: number = 0; - private _columnData; - private _cameraList; - private _camera: Camera; - private _groupLength: number; - - private _count: number; - - public renderTotal: number; - - public render() { - - // Get a list of all the active cameras - - this._cameraList = this._game.world.getAllCameras(); - - this._count = 0; - - // Then iterate through world.group on them all (where not blacklisted, etc) - for (var c = 0; c < this._cameraList.length; c++) - { - this._camera = this._cameraList[c]; - - this.preRenderCamera(this._camera); - - this._game.world.group.render(this._camera); - - this.postRenderCamera(this._camera); - } - - this.renderTotal = this._count; - - } - - public renderGameObject(object) { - - if (object.type == Types.SPRITE || object.type == Types.BUTTON) - { - this.renderSprite(this._camera, object); - } - else if (object.type == Types.SCROLLZONE) - { - this.renderScrollZone(this._camera, object); - } - else if (object.type == Types.TILEMAP) - { - this.renderTilemap(this._camera, object); - } - - } - - public preRenderGroup(camera: Camera, group: Group) { - - if (camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) - { - return false; - } - - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = group.texture.width; - this._sh = group.texture.height; - this._fx = group.transform.scale.x; - this._fy = group.transform.scale.y; - this._sin = 0; - this._cos = 1; - //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); - //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); - this._dx = 0; - this._dy = 0; - this._dw = group.texture.width; - this._dh = group.texture.height; - - // Global Composite Ops - if (group.texture.globalCompositeOperation) - { - group.texture.context.save(); - group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; - } - - // Alpha - if (group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) - { - this._ga = group.texture.context.globalAlpha; - group.texture.context.globalAlpha = group.texture.alpha; - } - - // Flip X - if (group.texture.flippedX) - { - this._fx = -group.transform.scale.x; - } - - // Flip Y - if (group.texture.flippedY) - { - this._fy = -group.transform.scale.y; - } - - // Rotation and Flipped - if (group.modified) - { - if (group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) - { - this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); - this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); - } - - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - - group.texture.context.save(); - group.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + group.transform.skew.x, -(this._sin * this._fy) + group.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - - this._dx = -group.transform.origin.x; - this._dy = -group.transform.origin.y; - } - else - { - if (!group.transform.origin.equals(0)) - { - this._dx -= group.transform.origin.x; - this._dy -= group.transform.origin.y; - } - } - - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - - if (group.texture.opaque) - { - group.texture.context.fillStyle = group.texture.backgroundColor; - group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - - if (group.texture.loaded) - { - group.texture.context.drawImage( - group.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh // Destination Height (always same as Source Height unless scaled) - ); - } - - return true; - - } - - public postRenderGroup(camera: Camera, group: Group) { - - if (group.modified || group.texture.globalCompositeOperation) - { - group.texture.context.restore(); - } - - // This could have been over-written by a sprite, need to store elsewhere - if (this._ga > -1) - { - group.texture.context.globalAlpha = this._ga; - } - - } - - /** - * Check whether this object is visible in a specific camera Rectangle. - * @param camera {Rectangle} The Rectangle you want to check. - * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. - */ - public inCamera(camera: Camera, sprite: Sprite): bool { - - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if (sprite.transform.scrollFactor.equals(0)) - { - return true; - } - - return RectangleUtils.intersects(sprite.cameraView, camera.screenView); - - } - - public inScreen(camera: Camera): bool { - - return true; - - } - - /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - public preRenderCamera(camera: Camera): bool { - - if (camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) - { - return false; - } - - camera.plugins.preRender(); - - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = camera.width; - this._sh = camera.height; - this._fx = camera.transform.scale.x; - this._fy = camera.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x; - this._dy = camera.screenView.y; - this._dw = camera.width; - this._dh = camera.height; - - // Global Composite Ops - if (camera.texture.globalCompositeOperation) - { - camera.texture.context.save(); - camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; - } - - // Alpha - if (camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) - { - this._ga = camera.texture.context.globalAlpha; - camera.texture.context.globalAlpha = camera.texture.alpha; - } - - // Sprite Flip X - if (camera.texture.flippedX) - { - this._fx = -camera.transform.scale.x; - } - - // Sprite Flip Y - if (camera.texture.flippedY) - { - this._fy = -camera.transform.scale.y; - } - - // Rotation and Flipped - if (camera.modified) - { - if (camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) - { - this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - } - - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - - camera.texture.context.save(); - camera.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + camera.transform.skew.x, -(this._sin * this._fy) + camera.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - - this._dx = -camera.transform.origin.x; - this._dy = -camera.transform.origin.y; - } - else - { - if (!camera.transform.origin.equals(0)) - { - this._dx -= camera.transform.origin.x; - this._dy -= camera.transform.origin.y; - } - } - - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - - // Clip the camera so we don't get sprites appearing outside the edges - if (camera.clip == true && camera.disableClipping == false) - { - camera.texture.context.beginPath(); - camera.texture.context.rect(camera.screenView.x, camera.screenView.x, camera.screenView.width, camera.screenView.height); - camera.texture.context.closePath(); - camera.texture.context.clip(); - } - - if (camera.texture.opaque) - { - camera.texture.context.fillStyle = camera.texture.backgroundColor; - camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - - if (camera.texture.loaded) - { - camera.texture.context.drawImage( - camera.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh // Destination Height (always same as Source Height unless scaled) - ); - } - - camera.plugins.render(); - - return true; - - } - - public postRenderCamera(camera: Camera) { - - if (camera.modified || camera.texture.globalCompositeOperation) - { - camera.texture.context.restore(); - } - - // This could have been over-written by a sprite, need to store elsewhere - if (this._ga > -1) - { - camera.texture.context.globalAlpha = this._ga; - } - - camera.plugins.postRender(); - - } - - public renderCircle(camera: Camera, circle: Circle, context, outline?: bool = false, fill?: bool = true, lineColor?: string = 'rgb(0,255,0)', fillColor?: string = 'rgba(0,100,0.0.3)', lineWidth?: number = 1): bool { - - this._count++; - - // Reset our temp vars - this._sx = 0; - this._sy = 0; - this._sw = circle.diameter; - this._sh = circle.diameter; - this._fx = 1; - this._fy = 1; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x + circle.x - camera.worldView.x; - this._dy = camera.screenView.y + circle.y - camera.worldView.y; - this._dw = circle.diameter; - this._dh = circle.diameter; - - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - - this._game.stage.saveCanvasValues(); - - context.save(); - context.lineWidth = lineWidth; - context.strokeStyle = lineColor; - context.fillStyle = fillColor; - - context.beginPath(); - context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); - context.closePath(); - - if (outline) - { - //context.stroke(); - } - - if (fill) - { - context.fill(); - } - - context.restore(); - - this._game.stage.restoreCanvasValues(); - - return true; - - } - - /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - public renderSprite(camera: Camera, sprite: Sprite): bool { - - Phaser.SpriteUtils.updateCameraView(camera, sprite); - - if (sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) - { - return false; - } - - sprite.renderOrderID = this._count; - - this._count++; - - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = sprite.texture.width; - this._sh = sprite.texture.height; - this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); - this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); - this._dw = sprite.texture.width; - this._dh = sprite.texture.height; - - if (sprite.animations.currentFrame !== null) - { - this._sx = sprite.animations.currentFrame.x; - this._sy = sprite.animations.currentFrame.y; - - if (sprite.animations.currentFrame.trimmed) - { - this._dx += sprite.animations.currentFrame.spriteSourceSizeX; - this._dy += sprite.animations.currentFrame.spriteSourceSizeY; - this._sw = sprite.animations.currentFrame.spriteSourceSizeW; - this._sh = sprite.animations.currentFrame.spriteSourceSizeH; - this._dw = sprite.animations.currentFrame.spriteSourceSizeW; - this._dh = sprite.animations.currentFrame.spriteSourceSizeH; - } - } - - if (sprite.modified) - { - sprite.texture.context.save(); - - sprite.texture.context.setTransform( - sprite.transform.local.data[0], // scale x - sprite.transform.local.data[3], // skew x - sprite.transform.local.data[1], // skew y - sprite.transform.local.data[4], // scale y - this._dx, // translate x - this._dy // translate y - ); - - this._dx = sprite.transform.origin.x * -this._dw; - this._dy = sprite.transform.origin.y * -this._dh; - } - else - { - this._dx -= (this._dw * sprite.transform.origin.x); - this._dy -= (this._dh * sprite.transform.origin.y); - } - - if (sprite.crop) - { - this._sx += sprite.crop.x * sprite.transform.scale.x; - this._sy += sprite.crop.y * sprite.transform.scale.y; - this._sw = sprite.crop.width * sprite.transform.scale.x; - this._sh = sprite.crop.height * sprite.transform.scale.y; - this._dx += sprite.crop.x * sprite.transform.scale.x; - this._dy += sprite.crop.y * sprite.transform.scale.y; - this._dw = sprite.crop.width * sprite.transform.scale.x; - this._dh = sprite.crop.height * sprite.transform.scale.y; - //this._sx += sprite.crop.x; - //this._sy += sprite.crop.y; - //this._sw = sprite.crop.width; - //this._sh = sprite.crop.height; - //this._dx += sprite.crop.x; - //this._dy += sprite.crop.y; - //this._dw = sprite.crop.width; - //this._dh = sprite.crop.height; - } - - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - - if (this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) - { - return false; - } - - // Global Composite Ops - if (sprite.texture.globalCompositeOperation) - { - sprite.texture.context.save(); - sprite.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; - } - - // Alpha - if (sprite.texture.alpha !== 1 && sprite.texture.context.globalAlpha != sprite.texture.alpha) - { - this._ga = sprite.texture.context.globalAlpha; - sprite.texture.context.globalAlpha = sprite.texture.alpha; - } - - if (sprite.texture.opaque) - { - sprite.texture.context.fillStyle = sprite.texture.backgroundColor; - sprite.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - - if (sprite.texture.loaded) - { - sprite.texture.context.drawImage( - sprite.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh // Destination Height (always same as Source Height unless scaled) - ); - } - - if (sprite.modified || sprite.texture.globalCompositeOperation) - { - sprite.texture.context.restore(); - } - - if (this._ga > -1) - { - sprite.texture.context.globalAlpha = this._ga; - } - - return true; - - } - - public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool { - - if (scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) - { - return false; - } - - this._count++; - - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = scrollZone.width; - this._sh = scrollZone.height; - this._fx = scrollZone.transform.scale.x; - this._fy = scrollZone.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); - this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); - this._dw = scrollZone.width; - this._dh = scrollZone.height; - - // Alpha - if (scrollZone.texture.alpha !== 1) - { - this._ga = scrollZone.texture.context.globalAlpha; - scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; - } - - // Sprite Flip X - if (scrollZone.texture.flippedX) - { - this._fx = -scrollZone.transform.scale.x; - } - - // Sprite Flip Y - if (scrollZone.texture.flippedY) - { - this._fy = -scrollZone.transform.scale.y; - } - - // Rotation and Flipped - if (scrollZone.modified) - { - if (scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) - { - this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - } - - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - - scrollZone.texture.context.save(); - scrollZone.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + scrollZone.transform.skew.x, -(this._sin * this._fy) + scrollZone.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - - this._dx = -scrollZone.transform.origin.x; - this._dy = -scrollZone.transform.origin.y; - } - else - { - if (!scrollZone.transform.origin.equals(0)) - { - this._dx -= scrollZone.transform.origin.x; - this._dy -= scrollZone.transform.origin.y; - } - } - - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - - for (var i = 0; i < scrollZone.regions.length; i++) - { - if (scrollZone.texture.isDynamic) - { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } - else - { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } - } - - if (scrollZone.modified) - { - scrollZone.texture.context.restore(); - } - - if (this._ga > -1) - { - scrollZone.texture.context.globalAlpha = this._ga; - } - - return true; - - } - - - /** - * Render a tilemap to a specific camera. - * @param camera {Camera} The camera this tilemap will be rendered to. - */ - public renderTilemap(camera: Camera, tilemap: Tilemap): bool { - - // Loop through the layers - for (var i = 0; i < tilemap.layers.length; i++) - { - var layer: TilemapLayer = tilemap.layers[i]; - - if (layer.visible == false || layer.alpha < 0.1) - { - continue; - } - - // Work out how many tiles we can fit into our camera and round it up for the edges - this._maxX = this._game.math.ceil(camera.width / layer.tileWidth) + 1; - this._maxY = this._game.math.ceil(camera.height / layer.tileHeight) + 1; - - // And now work out where in the tilemap the camera actually is - this._startX = this._game.math.floor(camera.worldView.x / layer.tileWidth); - this._startY = this._game.math.floor(camera.worldView.y / layer.tileHeight); - - // Tilemap bounds check - if (this._startX < 0) - { - this._startX = 0; - } - - if (this._startY < 0) - { - this._startY = 0; - } - - if (this._maxX > layer.widthInTiles) - { - this._maxX = layer.widthInTiles; - } - - if (this._maxY > layer.heightInTiles) - { - this._maxY = layer.heightInTiles; - } - - if (this._startX + this._maxX > layer.widthInTiles) - { - this._startX = layer.widthInTiles - this._maxX; - } - - if (this._startY + this._maxY > layer.heightInTiles) - { - this._startY = layer.heightInTiles - this._maxY; - } - - // Finally get the offset to avoid the blocky movement - //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); - //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); - //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); - //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); - this._dx = 0; - this._dy = 0; - - this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); - this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); - - this._tx = this._dx; - this._ty = this._dy; - - // Alpha - if (layer.texture.alpha !== 1) - { - this._ga = layer.texture.context.globalAlpha; - layer.texture.context.globalAlpha = layer.texture.alpha; - } - - for (var row = this._startY; row < this._startY + this._maxY; row++) - { - this._columnData = layer.mapData[row]; - - for (var tile = this._startX; tile < this._startX + this._maxX; tile++) - { - if (layer.tileOffsets[this._columnData[tile]]) - { - layer.texture.context.drawImage( - layer.texture.texture, - layer.tileOffsets[this._columnData[tile]].x, - layer.tileOffsets[this._columnData[tile]].y, - layer.tileWidth, - layer.tileHeight, - this._tx, - this._ty, - layer.tileWidth, - layer.tileHeight - ); - - } - - this._tx += layer.tileWidth; - - } - - this._tx = this._dx; - this._ty += layer.tileHeight; - - } - - if (this._ga > -1) - { - layer.texture.context.globalAlpha = this._ga; - } - } - - return true; - - } - - } - -} \ No newline at end of file diff --git a/Phaser/renderers/HeadlessRenderer.ts b/Phaser/renderers/HeadlessRenderer.ts index f130147e..d911ba52 100644 --- a/Phaser/renderers/HeadlessRenderer.ts +++ b/Phaser/renderers/HeadlessRenderer.ts @@ -2,37 +2,31 @@ /// /// -module Phaser { +module Phaser.Renderer.Headless { export class HeadlessRenderer implements Phaser.IRenderer { constructor(game: Phaser.Game) { - this._game = game; + this.game = game; } - private _game: Phaser.Game; + public game: Phaser.Game; + public renderCount: number; - public render() {} - - public inCamera(camera: Camera, sprite: Sprite): bool { return true; } - - public renderGameObject(object) {} - - public renderSprite(camera: Camera, sprite: Sprite): bool { return true; } - - public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool { return true; } - - public renderCircle(camera: Camera, circle: Circle, context, outline?: bool = true, fill?: bool = true, lineColor?: string = 'rgb(0,255,0)', fillColor?: string = 'rgba(0,100,0.0.3)', lineWidth?: number = 1): bool { - return true; + public render() { + // Nothing, headless remember? } - public preRenderCamera(camera: Camera) { } + public renderGameObject(camera, object) { + // Nothing, headless remember? + }; - public postRenderCamera(camera: Camera) { } - - public preRenderGroup(camera: Camera, group: Group) { } - - public postRenderGroup(camera: Camera, group: Group) { } + public cameraRenderer; + public groupRenderer; + public spriteRenderer; + public geometryRenderer; + public scrollZoneRenderer; + public tilemapRenderer; } diff --git a/Phaser/renderers/IRenderer.ts b/Phaser/renderers/IRenderer.ts index 07fd14d9..84909771 100644 --- a/Phaser/renderers/IRenderer.ts +++ b/Phaser/renderers/IRenderer.ts @@ -5,16 +5,17 @@ module Phaser { export interface IRenderer { render(); - renderGameObject(object); - renderSprite(camera: Camera, sprite: Sprite): bool; - renderScrollZone(camera: Camera, sprite: ScrollZone): bool; - renderCircle(camera: Camera, circle: Circle, context, outline?: bool, fill?: bool, lineColor?: string, fillColor?: string, lineWidth?: number); - preRenderGroup(camera: Camera, group: Group); - postRenderGroup(camera: Camera, group: Group); - preRenderCamera(camera: Camera); - postRenderCamera(camera: Camera); - - inCamera(camera: Camera, sprite: Sprite): bool; + + renderCount: number; + + renderGameObject; + + cameraRenderer; + groupRenderer; + spriteRenderer; + geometryRenderer; + scrollZoneRenderer; + tilemapRenderer; } diff --git a/Phaser/renderers/canvas/CameraRenderer.ts b/Phaser/renderers/canvas/CameraRenderer.ts new file mode 100644 index 00000000..dda16d88 --- /dev/null +++ b/Phaser/renderers/canvas/CameraRenderer.ts @@ -0,0 +1,181 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class CameraRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + private _fx: number = 1; + private _fy: number = 1; + private _tx: number = 0; + private _ty: number = 0; + private _gac: number = 1; + private _sin: number = 0; + private _cos: number = 1; + + public preRender(camera: Camera): bool { + + if (camera.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) + { + return false; + } + + camera.texture.context.clearRect(0, 0, camera.width, camera.height); + + // Alpha + if (camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) + { + this._ga = camera.texture.context.globalAlpha; + camera.texture.context.globalAlpha = camera.texture.alpha; + } + + if (camera.texture.opaque) + { + camera.texture.context.fillStyle = camera.texture.backgroundColor; + camera.texture.context.fillRect(0, 0, camera.width, camera.height); + } + + //if (camera.texture.loaded) + //{ + // camera.texture.context.drawImage( + // camera.texture.texture, // Source Image + // this._sx, // Source X (location within the source image) + // this._sy, // Source Y + // this._sw, // Source Width + // this._sh, // Source Height + // 0, // Destination X (where on the canvas it'll be drawn) + // 0, // Destination Y + // this._dw, // Destination Width (always same as Source Width unless scaled) + // this._dh // Destination Height (always same as Source Height unless scaled) + // ); + //} + + // Global Composite Ops + if (camera.texture.globalCompositeOperation) + { + camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; + } + + camera.plugins.preRender(); + + } + + public postRender(camera: Camera) { + + // This could have been over-written by a sprite, need to store elsewhere + if (this._ga > -1) + { + camera.texture.context.globalAlpha = this._ga; + } + + camera.plugins.postRender(); + + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = camera.width; + this._sh = camera.height; + this._fx = camera.transform.scale.x; + this._fy = camera.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x; + this._dy = camera.screenView.y; + this._dw = camera.width; + this._dh = camera.height; + + this.game.stage.context.save(); + + // Flip X + if (camera.texture.flippedX) + { + this._fx = -camera.transform.scale.x; + } + + // Flip Y + if (camera.texture.flippedY) + { + this._fy = -camera.transform.scale.y; + } + + // Rotation and Flipped + if (camera.modified) + { + if (camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) + { + this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + } + + this.game.stage.context.setTransform( + this._cos * this._fx, // scale x + (this._sin * this._fx) + camera.transform.skew.x, // skew x + -(this._sin * this._fy) + camera.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy // translate y + ); + + this._dx = camera.transform.origin.x * -this._dw; + this._dy = camera.transform.origin.y * -this._dh; + } + else + { + this._dx -= (this._dw * camera.transform.origin.x); + this._dy -= (this._dh * camera.transform.origin.y); + } + + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + + if (this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) + { + this.game.stage.context.restore(); + return false; + } + + this.game.stage.context.drawImage( + camera.texture.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh // Destination Height (always same as Source Height unless scaled) + ); + + this.game.stage.context.restore(); + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/CanvasRenderer.ts b/Phaser/renderers/canvas/CanvasRenderer.ts new file mode 100644 index 00000000..45620ae5 --- /dev/null +++ b/Phaser/renderers/canvas/CanvasRenderer.ts @@ -0,0 +1,87 @@ +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class CanvasRenderer implements Phaser.IRenderer { + + constructor(game: Phaser.Game) { + + this.game = game; + + this.cameraRenderer = new CameraRenderer(game); + this.groupRenderer = new GroupRenderer(game); + this.spriteRenderer = new SpriteRenderer(game); + this.geometryRenderer = new GeometryRenderer(game); + this.scrollZoneRenderer = new ScrollZoneRenderer(game); + this.tilemapRenderer = new TilemapRenderer(game); + + } + + public game: Phaser.Game; + + private _c: number = 0; + private _cameraList: Phaser.Camera[]; + private _camera: Camera; + + public cameraRenderer: Phaser.Renderer.Canvas.CameraRenderer; + public groupRenderer: Phaser.Renderer.Canvas.GroupRenderer; + public spriteRenderer: Phaser.Renderer.Canvas.SpriteRenderer; + public geometryRenderer: Phaser.Renderer.Canvas.GeometryRenderer; + public scrollZoneRenderer: Phaser.Renderer.Canvas.ScrollZoneRenderer; + public tilemapRenderer: Phaser.Renderer.Canvas.TilemapRenderer; + + public renderCount: number; + public renderTotal: number; + + public render() { + + this._cameraList = this.game.world.getAllCameras(); + this.renderCount = 0; + + // Then iterate through world.group on them all (where not blacklisted, etc) + for (this._c = 0; this._c < this._cameraList.length; this._c++) + { + if (this._cameraList[this._c].visible) + { + this.cameraRenderer.preRender(this._cameraList[this._c]); + + this.game.world.group.render(this._cameraList[this._c]); + + this.cameraRenderer.postRender(this._cameraList[this._c]); + } + } + + this.renderTotal = this.renderCount; + + } + + public renderGameObject(camera, object) { + + if (object.type == Types.SPRITE || object.type == Types.BUTTON) + { + this.spriteRenderer.render(camera, object); + } + else if (object.type == Types.SCROLLZONE) + { + this.scrollZoneRenderer.render(camera, object); + } + else if (object.type == Types.TILEMAP) + { + this.tilemapRenderer.render(camera, object); + } + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/GeometryRenderer.ts b/Phaser/renderers/canvas/GeometryRenderer.ts new file mode 100644 index 00000000..949e3fc9 --- /dev/null +++ b/Phaser/renderers/canvas/GeometryRenderer.ts @@ -0,0 +1,89 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class GeometryRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + // Local rendering related temp vars to help avoid gc spikes through constant var creation + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + private _fx: number = 1; + private _fy: number = 1; + private _sin: number = 0; + private _cos: number = 1; + + public renderCircle(camera: Camera, circle: Circle, context, outline?: bool = false, fill?: bool = true, lineColor?: string = 'rgb(0,255,0)', fillColor?: string = 'rgba(0,100,0.0.3)', lineWidth?: number = 1): bool { + + // Reset our temp vars + this._sx = 0; + this._sy = 0; + this._sw = circle.diameter; + this._sh = circle.diameter; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x + circle.x - camera.worldView.x; + this._dy = camera.screenView.y + circle.y - camera.worldView.y; + this._dw = circle.diameter; + this._dh = circle.diameter; + + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + + this.game.stage.saveCanvasValues(); + + context.save(); + context.lineWidth = lineWidth; + context.strokeStyle = lineColor; + context.fillStyle = fillColor; + + context.beginPath(); + context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); + context.closePath(); + + if (outline) + { + //context.stroke(); + } + + if (fill) + { + context.fill(); + } + + context.restore(); + + this.game.stage.restoreCanvasValues(); + + return true; + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/GroupRenderer.ts b/Phaser/renderers/canvas/GroupRenderer.ts new file mode 100644 index 00000000..ae85d2d6 --- /dev/null +++ b/Phaser/renderers/canvas/GroupRenderer.ts @@ -0,0 +1,165 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class GroupRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + // Local rendering related temp vars to help avoid gc spikes through var creation + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + private _fx: number = 1; + private _fy: number = 1; + private _sin: number = 0; + private _cos: number = 1; + + public preRender(camera: Camera, group: Group) { + + if (group.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) + { + return false; + } + + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = group.texture.width; + this._sh = group.texture.height; + this._fx = group.transform.scale.x; + this._fy = group.transform.scale.y; + this._sin = 0; + this._cos = 1; + //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); + //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); + this._dx = 0; + this._dy = 0; + this._dw = group.texture.width; + this._dh = group.texture.height; + + // Global Composite Ops + if (group.texture.globalCompositeOperation) + { + group.texture.context.save(); + group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; + } + + // Alpha + if (group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) + { + this._ga = group.texture.context.globalAlpha; + group.texture.context.globalAlpha = group.texture.alpha; + } + + // Flip X + if (group.texture.flippedX) + { + this._fx = -group.transform.scale.x; + } + + // Flip Y + if (group.texture.flippedY) + { + this._fy = -group.transform.scale.y; + } + + // Rotation and Flipped + if (group.modified) + { + if (group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) + { + this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + } + + group.texture.context.save(); + + group.texture.context.setTransform( + this._cos * this._fx, // scale x + (this._sin * this._fx) + group.transform.skew.x, // skew x + -(this._sin * this._fy) + group.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy // translate y + ); + + this._dx = -group.transform.origin.x; + this._dy = -group.transform.origin.y; + } + else + { + if (!group.transform.origin.equals(0)) + { + this._dx -= group.transform.origin.x; + this._dy -= group.transform.origin.y; + } + } + + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + + if (group.texture.opaque) + { + group.texture.context.fillStyle = group.texture.backgroundColor; + group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + + if (group.texture.loaded) + { + group.texture.context.drawImage( + group.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh // Destination Height (always same as Source Height unless scaled) + ); + } + + return true; + + } + + public postRender(camera: Camera, group: Group) { + + if (group.modified || group.texture.globalCompositeOperation) + { + group.texture.context.restore(); + } + + if (this._ga > -1) + { + group.texture.context.globalAlpha = this._ga; + } + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/ScrollZoneRenderer.ts b/Phaser/renderers/canvas/ScrollZoneRenderer.ts new file mode 100644 index 00000000..60a0ff88 --- /dev/null +++ b/Phaser/renderers/canvas/ScrollZoneRenderer.ts @@ -0,0 +1,163 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class ScrollZoneRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + // Local rendering related temp vars to help avoid gc spikes through constant var creation + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + private _fx: number = 1; + private _fy: number = 1; + private _sin: number = 0; + private _cos: number = 1; + + /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + public inCamera(camera: Camera, scrollZone: ScrollZone): bool { + + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if (scrollZone.transform.scrollFactor.equals(0)) + { + return true; + } + + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + + } + + public render(camera: Camera, scrollZone: ScrollZone): bool { + + if (scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) + { + return false; + } + + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = scrollZone.width; + this._sh = scrollZone.height; + this._fx = scrollZone.transform.scale.x; + this._fy = scrollZone.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); + this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); + this._dw = scrollZone.width; + this._dh = scrollZone.height; + + // Alpha + if (scrollZone.texture.alpha !== 1) + { + this._ga = scrollZone.texture.context.globalAlpha; + scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; + } + + // Sprite Flip X + if (scrollZone.texture.flippedX) + { + this._fx = -scrollZone.transform.scale.x; + } + + // Sprite Flip Y + if (scrollZone.texture.flippedY) + { + this._fy = -scrollZone.transform.scale.y; + } + + // Rotation and Flipped + if (scrollZone.modified) + { + if (scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) + { + this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + } + + scrollZone.texture.context.save(); + + scrollZone.texture.context.setTransform( + this._cos * this._fx, // scale x + (this._sin * this._fx) + scrollZone.transform.skew.x, // skew x + -(this._sin * this._fy) + scrollZone.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy // translate y + ); + + this._dx = -scrollZone.transform.origin.x; + this._dy = -scrollZone.transform.origin.y; + } + else + { + if (!scrollZone.transform.origin.equals(0)) + { + this._dx -= scrollZone.transform.origin.x; + this._dy -= scrollZone.transform.origin.y; + } + } + + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + + for (var i = 0; i < scrollZone.regions.length; i++) + { + if (scrollZone.texture.isDynamic) + { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } + else + { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } + } + + if (scrollZone.modified) + { + scrollZone.texture.context.restore(); + } + + if (this._ga > -1) + { + scrollZone.texture.context.globalAlpha = this._ga; + } + + this.game.renderer.renderCount++; + + return true; + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/SpriteRenderer.ts b/Phaser/renderers/canvas/SpriteRenderer.ts new file mode 100644 index 00000000..a2053bbe --- /dev/null +++ b/Phaser/renderers/canvas/SpriteRenderer.ts @@ -0,0 +1,194 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class SpriteRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + // Local rendering related temp vars to help avoid gc spikes through constant var creation + //private _c: number = 0; + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + + /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + public inCamera(camera: Camera, sprite: Sprite): bool { + + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if (sprite.transform.scrollFactor.equals(0)) + { + return true; + } + + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + + } + + /** + * Render this sprite to specific camera. Called by game loop after update(). + * @param camera {Camera} Camera this sprite will be rendered to. + * @return {boolean} Return false if not rendered, otherwise return true. + */ + public render(camera: Camera, sprite: Sprite): bool { + + Phaser.SpriteUtils.updateCameraView(camera, sprite); + + if (sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) + { + return false; + } + + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = sprite.texture.width; + this._sh = sprite.texture.height; + //this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dx = sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + this._dy = sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dw = sprite.texture.width; + this._dh = sprite.texture.height; + + if (sprite.animations.currentFrame !== null) + { + this._sx = sprite.animations.currentFrame.x; + this._sy = sprite.animations.currentFrame.y; + + if (sprite.animations.currentFrame.trimmed) + { + this._dx += sprite.animations.currentFrame.spriteSourceSizeX; + this._dy += sprite.animations.currentFrame.spriteSourceSizeY; + this._sw = sprite.animations.currentFrame.spriteSourceSizeW; + this._sh = sprite.animations.currentFrame.spriteSourceSizeH; + this._dw = sprite.animations.currentFrame.spriteSourceSizeW; + this._dh = sprite.animations.currentFrame.spriteSourceSizeH; + } + } + + if (sprite.modified) + { + camera.texture.context.save(); + + camera.texture.context.setTransform( + sprite.transform.local.data[0], // scale x + sprite.transform.local.data[3], // skew x + sprite.transform.local.data[1], // skew y + sprite.transform.local.data[4], // scale y + this._dx, // translate x + this._dy // translate y + ); + + this._dx = sprite.transform.origin.x * -this._dw; + this._dy = sprite.transform.origin.y * -this._dh; + } + else + { + this._dx -= (this._dw * sprite.transform.origin.x); + this._dy -= (this._dh * sprite.transform.origin.y); + } + + if (sprite.crop) + { + this._sx += sprite.crop.x * sprite.transform.scale.x; + this._sy += sprite.crop.y * sprite.transform.scale.y; + this._sw = sprite.crop.width * sprite.transform.scale.x; + this._sh = sprite.crop.height * sprite.transform.scale.y; + this._dx += sprite.crop.x * sprite.transform.scale.x; + this._dy += sprite.crop.y * sprite.transform.scale.y; + this._dw = sprite.crop.width * sprite.transform.scale.x; + this._dh = sprite.crop.height * sprite.transform.scale.y; + } + + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + + if (this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) + { + return false; + } + + // Global Composite Ops + if (sprite.texture.globalCompositeOperation) + { + camera.texture.context.save(); + camera.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; + } + + // Alpha + if (sprite.texture.alpha !== 1 && camera.texture.context.globalAlpha != sprite.texture.alpha) + { + this._ga = sprite.texture.context.globalAlpha; + camera.texture.context.globalAlpha = sprite.texture.alpha; + } + + if (sprite.texture.opaque) + { + camera.texture.context.fillStyle = sprite.texture.backgroundColor; + camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + + if (sprite.texture.loaded) + { + camera.texture.context.drawImage( + sprite.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh // Destination Height (always same as Source Height unless scaled) + ); + } + + if (sprite.modified || sprite.texture.globalCompositeOperation) + { + camera.texture.context.restore(); + } + + if (this._ga > -1) + { + camera.texture.context.globalAlpha = this._ga; + } + + sprite.renderOrderID = this.game.renderer.renderCount; + + this.game.renderer.renderCount++; + + return true; + + } + + } + +} \ No newline at end of file diff --git a/Phaser/renderers/canvas/TilemapRenderer.ts b/Phaser/renderers/canvas/TilemapRenderer.ts new file mode 100644 index 00000000..7b2c5c82 --- /dev/null +++ b/Phaser/renderers/canvas/TilemapRenderer.ts @@ -0,0 +1,159 @@ +/// +/// +/// + +module Phaser.Renderer.Canvas { + + export class TilemapRenderer { + + constructor(game: Phaser.Game) { + this.game = game; + } + + /** + * The essential reference to the main game object + */ + public game: Phaser.Game; + + // Local rendering related temp vars to help avoid gc spikes through constant var creation + private _ga: number = 1; + private _sx: number = 0; + private _sy: number = 0; + private _sw: number = 0; + private _sh: number = 0; + private _dx: number = 0; + private _dy: number = 0; + private _dw: number = 0; + private _dh: number = 0; + private _fx: number = 1; + private _fy: number = 1; + private _tx: number = 0; + private _ty: number = 0; + private _sin: number = 0; + private _cos: number = 1; + private _maxX: number = 0; + private _maxY: number = 0; + private _startX: number = 0; + private _startY: number = 0; + private _columnData; + + /** + * Render a tilemap to a specific camera. + * @param camera {Camera} The camera this tilemap will be rendered to. + */ + public render(camera: Camera, tilemap: Tilemap): bool { + + // Loop through the layers + for (var i = 0; i < tilemap.layers.length; i++) + { + var layer: TilemapLayer = tilemap.layers[i]; + + if (layer.visible == false || layer.alpha < 0.1) + { + continue; + } + + // Work out how many tiles we can fit into our camera and round it up for the edges + this._maxX = this.game.math.ceil(camera.width / layer.tileWidth) + 1; + this._maxY = this.game.math.ceil(camera.height / layer.tileHeight) + 1; + + // And now work out where in the tilemap the camera actually is + this._startX = this.game.math.floor(camera.worldView.x / layer.tileWidth); + this._startY = this.game.math.floor(camera.worldView.y / layer.tileHeight); + + // Tilemap bounds check + if (this._startX < 0) + { + this._startX = 0; + } + + if (this._startY < 0) + { + this._startY = 0; + } + + if (this._maxX > layer.widthInTiles) + { + this._maxX = layer.widthInTiles; + } + + if (this._maxY > layer.heightInTiles) + { + this._maxY = layer.heightInTiles; + } + + if (this._startX + this._maxX > layer.widthInTiles) + { + this._startX = layer.widthInTiles - this._maxX; + } + + if (this._startY + this._maxY > layer.heightInTiles) + { + this._startY = layer.heightInTiles - this._maxY; + } + + // Finally get the offset to avoid the blocky movement + //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); + //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); + //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); + //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); + this._dx = 0; + this._dy = 0; + + this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); + this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); + + this._tx = this._dx; + this._ty = this._dy; + + // Alpha + if (layer.texture.alpha !== 1) + { + this._ga = layer.texture.context.globalAlpha; + layer.texture.context.globalAlpha = layer.texture.alpha; + } + + for (var row = this._startY; row < this._startY + this._maxY; row++) + { + this._columnData = layer.mapData[row]; + + for (var tile = this._startX; tile < this._startX + this._maxX; tile++) + { + if (layer.tileOffsets[this._columnData[tile]]) + { + layer.texture.context.drawImage( + layer.texture.texture, + layer.tileOffsets[this._columnData[tile]].x, + layer.tileOffsets[this._columnData[tile]].y, + layer.tileWidth, + layer.tileHeight, + this._tx, + this._ty, + layer.tileWidth, + layer.tileHeight + ); + + } + + this._tx += layer.tileWidth; + + } + + this._tx = this._dx; + this._ty += layer.tileHeight; + + } + + if (this._ga > -1) + { + layer.texture.context.globalAlpha = this._ga; + } + } + + return true; + + } + + } + +} \ No newline at end of file diff --git a/Phaser/utils/DebugUtils.ts b/Phaser/utils/DebugUtils.ts index fc5d38af..b8419b51 100644 --- a/Phaser/utils/DebugUtils.ts +++ b/Phaser/utils/DebugUtils.ts @@ -114,8 +114,8 @@ module Phaser { start(x, y, color); line('Camera ID: ' + camera.ID + ' (' + camera.screenView.width + ' x ' + camera.screenView.height + ')'); - line('X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' rotation: ' + camera.transform.rotation); - line('World X: ' + camera.worldView.x + ' World Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height + ' R: ' + camera.worldView.right + ' B: ' + camera.worldView.bottom); + line('X: ' + camera.x + ' Y: ' + camera.y + ' Rotation: ' + camera.transform.rotation); + line('WorldView X: ' + camera.worldView.x + ' Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height); line('ScreenView X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' W: ' + camera.screenView.width + ' H: ' + camera.screenView.height); if (camera.worldBounds) @@ -219,9 +219,8 @@ module Phaser { line('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1)); line('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1)); line('center x: ' + sprite.transform.center.x + ' y: ' + sprite.transform.center.y); - //line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height + ' bottom: ' + sprite.cameraView.bottom + ' right: ' + sprite.cameraView.right); line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height); - line('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite)); + line('inCamera: ' + DebugUtils.game.renderer.spriteRenderer.inCamera(DebugUtils.game.camera, sprite)); } diff --git a/Phaser/utils/SpriteUtils.ts b/Phaser/utils/SpriteUtils.ts index eac43747..3ded1d44 100644 --- a/Phaser/utils/SpriteUtils.ts +++ b/Phaser/utils/SpriteUtils.ts @@ -30,8 +30,8 @@ module Phaser { if (sprite.rotation == 0 || sprite.texture.renderRotation == false) { // Easy out - sprite.cameraView.x = Math.round(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); - sprite.cameraView.y = Math.round(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); + sprite.cameraView.x = Math.floor(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); + sprite.cameraView.y = Math.floor(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); sprite.cameraView.width = sprite.width; sprite.cameraView.height = sprite.height; } diff --git a/Plugins/CameraFX/Border.js b/Plugins/CameraFX/Border.js index 814eda7f..3be0f00f 100644 --- a/Plugins/CameraFX/Border.js +++ b/Plugins/CameraFX/Border.js @@ -19,10 +19,10 @@ var Phaser; function Border(game, parent) { _super.call(this, game, parent); /** - * Whether render border of this camera or not. (default is false) + * Whether render border of this camera or not. (default is true) * @type {boolean} */ - this.showBorder = false; + this.showBorder = true; /** * Color of border of this camera. (in css color string) * @type {string} diff --git a/Plugins/CameraFX/Border.ts b/Plugins/CameraFX/Border.ts index c8250c32..2dc82753 100644 --- a/Plugins/CameraFX/Border.ts +++ b/Plugins/CameraFX/Border.ts @@ -21,10 +21,10 @@ module Phaser.Plugins.CameraFX { public camera: Phaser.Camera; /** - * Whether render border of this camera or not. (default is false) + * Whether render border of this camera or not. (default is true) * @type {boolean} */ - public showBorder: bool = false; + public showBorder: bool = true; /** * Color of border of this camera. (in css color string) diff --git a/README.md b/README.md index d597d276..8ae9cc8e 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,27 @@ Latest Update TODO: +*** Render each camera to its own canvas - then I can apply filters (?), easily rotate it, scale it, etc without worrying about children +* Default camera (camera 0) could be the stage camera, renders to stage? +* Inject game into a
+* Add ability to create extra
s within the game container, layered above/below the canvas +* One single canvas +* Inject Pixi.js into this fully? Use it for all rendering? A lot of work, but could be interesting? At least pixi is quite small. + + + + * Investigate why tweens don't restart after the game pauses * Fix bug in Tween yoyo + loop combo * Check that tween pausing works with the new performance.now * Game.Time should monitor pause duration * Investigate bug re: tilemap collision and animation frames -* Update tests that use arrow keys and include touch/mouse support (FlxControlHandler style) * Pointer.getWorldX(camera) needs to take camera scale into consideration * Add clip support + shape options to Texture Component. * Need to be able to set the current tilemap layer, then the getTileXY default layer uses that one if no other given * Sprite collision events * Check bounds/edge points when sprite is only 1x1 sized :) * QuadTree.physics.checkHullIntersection -* Add visible toggle if tween property is alpha <> 01 -* Camera.isHidden uses an array and length check, faster to swap for a single counter, also try to remove indexOf check * Tilemap.render - move layers length to var * Tilemap.destroy needs doing * Sprite.transform.bottomRight/Left doesn't seem to take origin into account diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index ed534820..8d6bd7e8 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -90,15 +90,23 @@ basic camera 1.ts - - - - - - - - - + + + + + + + + + + + + camera alpha.ts + + + + camera rotation.ts + scrollfactor 1.ts @@ -110,7 +118,7 @@ - + world sprite.ts diff --git a/Tests/cameras/basic camera 1.js b/Tests/cameras/basic camera 1.js index 98299658..47778f9f 100644 --- a/Tests/cameras/basic camera 1.js +++ b/Tests/cameras/basic camera 1.js @@ -12,12 +12,25 @@ for(var i = 0; i < 100; i++) { game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); } - } + //game.camera.texture.alpha = 0.5; + //game.camera.width = 400; + game.camera.texture.opaque = true; + game.camera.texture.backgroundColor = 'rgb(200,0,0)'; + game.camera.transform.origin.setTo(0.5, 0.5); + game.camera.setPosition(game.stage.centerX, game.stage.centerY); + //game.camera.setPosition(0, 0); + //console.log('cam', game.camera.width, game.camera.height); + } function update() { + game.camera.rotation++; if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { - game.camera.x -= 4; + //game.camera.x -= 4; + game.camera.transform.scale.x -= 0.1; + game.camera.transform.scale.y -= 0.1; } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { - game.camera.x += 4; + //game.camera.x += 4; + game.camera.transform.scale.x += 0.1; + game.camera.transform.scale.y += 0.1; } if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { game.camera.y -= 4; diff --git a/Tests/cameras/basic camera 1.ts b/Tests/cameras/basic camera 1.ts index 5c81129a..3b5e5c69 100644 --- a/Tests/cameras/basic camera 1.ts +++ b/Tests/cameras/basic camera 1.ts @@ -24,17 +24,32 @@ game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); } + //game.camera.texture.alpha = 0.5; + //game.camera.width = 400; + game.camera.texture.opaque = true; + game.camera.texture.backgroundColor = 'rgb(200,0,0)'; + game.camera.transform.origin.setTo(0.5, 0.5); + game.camera.setPosition(game.stage.centerX, game.stage.centerY); + //game.camera.setPosition(0, 0); + //console.log('cam', game.camera.width, game.camera.height); + } function update() { + game.camera.rotation++; + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { - game.camera.x -= 4; + //game.camera.x -= 4; + game.camera.transform.scale.x -= 0.1; + game.camera.transform.scale.y -= 0.1; } else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { - game.camera.x += 4; + //game.camera.x += 4; + game.camera.transform.scale.x += 0.1; + game.camera.transform.scale.y += 0.1; } if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) diff --git a/Tests/cameras/basic follow.js b/Tests/cameras/basic follow.js index 7416f066..24a217f3 100644 --- a/Tests/cameras/basic follow.js +++ b/Tests/cameras/basic follow.js @@ -1,10 +1,8 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, update); - var ufo; var speed = 4; - function init() { game.world.setSize(1280, 600, true); game.load.image('ground', 'assets/tests/ground-2x.png'); @@ -13,51 +11,38 @@ game.load.image('cloud0', 'assets/tests/cloud-big-2x.png'); game.load.image('cloud1', 'assets/tests/cloud-narrow-2x.png'); game.load.image('cloud2', 'assets/tests/cloud-small-2x.png'); - game.load.spritesheet('ufo', 'assets/sprites/ufo.png', 24, 21); - game.load.start(); } function create() { // background images - game.add.sprite(0, 0, 'sky') - .transform.scrollFactor.setTo(0, 0); - game.add.sprite(0, 360, 'ground') - .transform.scrollFactor.setTo(0.5, 0.5); - game.add.sprite(0, 400, 'river') - .transform.scrollFactor.setTo(1.3, 1.3); - game.add.sprite(200, 120, 'cloud0') - .transform.scrollFactor.setTo(0.3, 0.3); - game.add.sprite(-60, 120, 'cloud1') - .transform.scrollFactor.setTo(0.5, 0.3); - game.add.sprite(900, 170, 'cloud2') - .transform.scrollFactor.setTo(0.7, 0.3); - + game.add.sprite(0, 0, 'sky').transform.scrollFactor.setTo(0, 0); + game.add.sprite(0, 360, 'ground').transform.scrollFactor.setTo(0.5, 0.5); + game.add.sprite(0, 400, 'river').transform.scrollFactor.setTo(1.3, 1.3); + game.add.sprite(200, 120, 'cloud0').transform.scrollFactor.setTo(0.3, 0.3); + game.add.sprite(-60, 120, 'cloud1').transform.scrollFactor.setTo(0.5, 0.3); + game.add.sprite(900, 170, 'cloud2').transform.scrollFactor.setTo(0.7, 0.3); // ufo spirte ufo = game.add.sprite(320, 240, 'ufo'); ufo.animations.add('fly', null, 30, false); ufo.animations.play('fly'); ufo.transform.origin.setTo(0.5, 0.5); - // make camera follows ufo game.camera.follow(ufo); } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { ufo.x -= speed; ufo.rotation = -15; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { ufo.x += speed; ufo.rotation = 15; - } - else { + } else { ufo.rotation = 0; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { ufo.y -= speed; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { ufo.y += speed; } } diff --git a/Tests/cameras/basic follow.ts b/Tests/cameras/basic follow.ts index 3c4522ee..2b1187fc 100644 --- a/Tests/cameras/basic follow.ts +++ b/Tests/cameras/basic follow.ts @@ -3,7 +3,7 @@ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update); var ufo: Phaser.Sprite; - var speed: Number = 4; + var speed: number = 4; function init() { game.world.setSize(1280, 600, true); diff --git a/Tests/cameras/camera alpha.js b/Tests/cameras/camera alpha.js new file mode 100644 index 00000000..cc60628b --- /dev/null +++ b/Tests/cameras/camera alpha.js @@ -0,0 +1,59 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + function init() { + game.load.image('grid', 'assets/tests/debug-grid-1920x1920.png'); + game.load.image('car', 'assets/sprites/car90.png'); + game.load.start(); + } + var car; + var miniCam; + function create() { + game.world.setSize(2240, 2240, true); + game.add.sprite(0, 0, 'grid'); + car = game.add.sprite(400, 300, 'car'); + game.camera.follow(car, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN); + miniCam = game.add.camera(0, 0, 300, 300); + miniCam.follow(car, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT); + miniCam.setBounds(0, 0, game.world.width, game.world.height); + miniCam.texture.alpha = 0.7; + } + function update() { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + car.x -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + car.x += 4; + } + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + car.y -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + car.y += 4; + } + /* + car.velocity.x = 0; + car.velocity.y = 0; + car.angularVelocity = 0; + car.angularAcceleration = 0; + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + car.angularVelocity = -200; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + car.angularVelocity = 200; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + var motion:Phaser.Point = game.motion.velocityFromAngle(car.angle, 300); + + car.velocity.copyFrom(motion); + } + */ + } + function render() { + Phaser.DebugUtils.renderSpriteInfo(car, 32, 32); + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 300); + } +})(); diff --git a/Tests/cameras/camera alpha.ts b/Tests/cameras/camera alpha.ts new file mode 100644 index 00000000..f9d3700d --- /dev/null +++ b/Tests/cameras/camera alpha.ts @@ -0,0 +1,88 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + + function init() { + + game.load.image('grid', 'assets/tests/debug-grid-1920x1920.png'); + game.load.image('car', 'assets/sprites/car90.png'); + + game.load.start(); + + } + + var car: Phaser.Sprite; + var miniCam: Phaser.Camera; + + function create() { + + game.world.setSize(2240, 2240, true); + + game.add.sprite(0, 0, 'grid'); + + car = game.add.sprite(400, 300, 'car'); + + game.camera.follow(car, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN); + + miniCam = game.add.camera(0, 0, 300, 300); + miniCam.follow(car, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT); + miniCam.setBounds(0, 0, game.world.width, game.world.height); + miniCam.texture.alpha = 0.7; + + } + + function update() { + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + car.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + car.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + car.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + car.y += 4; + } + + /* + car.velocity.x = 0; + car.velocity.y = 0; + car.angularVelocity = 0; + car.angularAcceleration = 0; + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + car.angularVelocity = -200; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + car.angularVelocity = 200; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + var motion:Phaser.Point = game.motion.velocityFromAngle(car.angle, 300); + + car.velocity.copyFrom(motion); + } + */ + + } + + function render() { + + Phaser.DebugUtils.renderSpriteInfo(car, 32, 32); + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 300); + + } + +})(); diff --git a/Tests/cameras/camera fx 1.js b/Tests/cameras/camera fx 1.js index 7b8cd30f..10aaba44 100644 --- a/Tests/cameras/camera fx 1.js +++ b/Tests/cameras/camera fx 1.js @@ -1,25 +1,21 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); - var btn1, btn2, btn3; var fx; - function init() { game.world.setSize(800, 600, true); game.load.image('blue', 'assets/tests/blue-circle.png'); game.load.image('yellow', 'assets/tests/yellow-circle.png'); game.load.image('magenta', 'assets/tests/magenta-circle.png'); - game.load.start(); } function create() { btn1 = game.add.button(114, 34, 'blue', simpleFade, this); btn2 = game.add.button(426, 86, 'yellow', forceFade, this); btn3 = game.add.button(221, 318, 'magenta', fadeWithCallback, this); - - fx = game.camera.fx.add(Phaser.FX.Camera.Fade); - } + //fx = game.camera.fx.add(Phaser.FX.Camera.Fade); + } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; Phaser.DebugUtils.context.fillText('Press to fade.', 114 + 90, 34 + 130); @@ -36,7 +32,7 @@ } function fadeWithCallback() { // Popup a alert window when fade finished. - fx.start(0x333300, 0.5, function() { + fx.start(0x333300, 0.5, function () { alert('Fade finished!'); }); } diff --git a/Tests/cameras/camera fx 1.ts b/Tests/cameras/camera fx 1.ts index be681867..1af3d70d 100644 --- a/Tests/cameras/camera fx 1.ts +++ b/Tests/cameras/camera fx 1.ts @@ -20,7 +20,7 @@ btn2 = game.add.button(426, 86, 'yellow', forceFade, this); btn3 = game.add.button(221, 318, 'magenta', fadeWithCallback, this); - fx = game.camera.fx.add(Phaser.FX.Camera.Fade); + //fx = game.camera.fx.add(Phaser.FX.Camera.Fade); } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; diff --git a/Tests/cameras/camera fx 2.js b/Tests/cameras/camera fx 2.js index f700830e..37338163 100644 --- a/Tests/cameras/camera fx 2.js +++ b/Tests/cameras/camera fx 2.js @@ -1,26 +1,22 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); - var btn1, btn2, btn3; var fx; - function init() { game.world.setSize(800, 600, true); game.load.image('blue', 'assets/tests/blue-circle.png'); game.load.image('yellow', 'assets/tests/yellow-circle.png'); game.load.image('magenta', 'assets/tests/magenta-circle.png'); - game.load.start(); } function create() { btn1 = game.add.button(114, 34, 'blue', simpleFlash, this); btn2 = game.add.button(426, 86, 'yellow', forceFlash, this); btn3 = game.add.button(221, 318, 'magenta', flashWithCallback, this); - // Usage of flash fx is the same as fade. - fx = game.camera.fx.add(Phaser.FX.Camera.Flash); - } + //fx = game.camera.fx.add(Phaser.FX.Camera.Flash); + } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; Phaser.DebugUtils.context.fillText('Press to flash.', 114 + 90, 34 + 130); @@ -37,7 +33,7 @@ } function flashWithCallback() { // Popup a alert window when flash finished. - fx.start(0x333300, 0.5, function() { + fx.start(0x333300, 0.5, function () { alert('Flash finished!'); }); } diff --git a/Tests/cameras/camera fx 2.ts b/Tests/cameras/camera fx 2.ts index 6e35fdc8..4bc11687 100644 --- a/Tests/cameras/camera fx 2.ts +++ b/Tests/cameras/camera fx 2.ts @@ -21,7 +21,7 @@ btn3 = game.add.button(221, 318, 'magenta', flashWithCallback, this); // Usage of flash fx is the same as fade. - fx = game.camera.fx.add(Phaser.FX.Camera.Flash); + //fx = game.camera.fx.add(Phaser.FX.Camera.Flash); } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; diff --git a/Tests/cameras/camera fx 3.js b/Tests/cameras/camera fx 3.js index b15a0652..ffb32d51 100644 --- a/Tests/cameras/camera fx 3.js +++ b/Tests/cameras/camera fx 3.js @@ -1,26 +1,22 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); - var btn1, btn2, btn3; var fx; - function init() { game.world.setSize(800, 600, true); game.load.image('blue', 'assets/tests/blue-circle.png'); game.load.image('yellow', 'assets/tests/yellow-circle.png'); game.load.image('magenta', 'assets/tests/magenta-circle.png'); - game.load.start(); } function create() { btn1 = game.add.button(114, 34, 'blue', simpleShake, this); btn2 = game.add.button(426, 86, 'yellow', forceShake, this); btn3 = game.add.button(221, 318, 'magenta', shakeWithCallback, this); - // Usage of shake fx is the same as fade and flash. - fx = game.camera.fx.add(Phaser.FX.Camera.Shake); - } + //fx = game.camera.fx.add(Phaser.FX.Camera.Shake); + } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; Phaser.DebugUtils.context.fillText('Press to shake.', 114 + 90, 34 + 130); @@ -37,7 +33,7 @@ } function shakeWithCallback() { // Popup a alert window when shake finished. - fx.start(0x333300, 0.5, function() { + fx.start(0x333300, 0.5, function () { alert('Shake finished!'); }); } diff --git a/Tests/cameras/camera fx 3.ts b/Tests/cameras/camera fx 3.ts index 49459a83..770a0c51 100644 --- a/Tests/cameras/camera fx 3.ts +++ b/Tests/cameras/camera fx 3.ts @@ -21,7 +21,7 @@ btn3 = game.add.button(221, 318, 'magenta', shakeWithCallback, this); // Usage of shake fx is the same as fade and flash. - fx = game.camera.fx.add(Phaser.FX.Camera.Shake); + //fx = game.camera.fx.add(Phaser.FX.Camera.Shake); } function render() { Phaser.DebugUtils.context.fillStyle = '#fff'; diff --git a/Tests/cameras/camera rotation.js b/Tests/cameras/camera rotation.js new file mode 100644 index 00000000..222e213e --- /dev/null +++ b/Tests/cameras/camera rotation.js @@ -0,0 +1,38 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + function init() { + game.load.image('melon', 'assets/sprites/melon.png'); + game.load.start(); + } + var car; + var miniCam; + function create() { + game.world.setSize(3000, 3000, true); + game.stage.backgroundColor = 'rgb(20,20,50)'; + for(var i = 0; i < 1000; i++) { + game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + } + game.camera.transform.origin.setTo(0.5, 0.5); + game.camera.texture.opaque = true; + game.camera.texture.backgroundColor = 'rgb(0,0,0)'; + game.camera.setPosition(game.stage.centerX, game.stage.centerY); + //game.camera.setPosition(200, 0); + game.camera.setSize(320, 320); + } + function update() { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + game.camera.rotation -= 2; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + game.camera.rotation += 2; + } + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + game.camera.y -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + game.camera.y += 4; + } + } + function render() { + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + } +})(); diff --git a/Tests/cameras/camera rotation.ts b/Tests/cameras/camera rotation.ts new file mode 100644 index 00000000..3514d7a3 --- /dev/null +++ b/Tests/cameras/camera rotation.ts @@ -0,0 +1,65 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + + function init() { + + game.load.image('melon', 'assets/sprites/melon.png'); + + game.load.start(); + + } + + var car: Phaser.Sprite; + var miniCam: Phaser.Camera; + + function create() { + + game.world.setSize(3000, 3000, true); + game.stage.backgroundColor = 'rgb(20,20,50)'; + + for (var i = 0; i < 1000; i++) + { + game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + } + + game.camera.transform.origin.setTo(0.5, 0.5); + game.camera.texture.opaque = true; + game.camera.texture.backgroundColor = 'rgb(0,0,0)'; + game.camera.setPosition(game.stage.centerX, game.stage.centerY); + //game.camera.setPosition(200, 0); + game.camera.setSize(320, 320); + + } + + function update() { + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + game.camera.rotation -= 2; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + game.camera.rotation += 2; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.camera.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + game.camera.y += 4; + } + + } + + function render() { + + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + + } + +})(); diff --git a/Tests/cameras/camera scale.js b/Tests/cameras/camera scale.js index dd132d85..36a73b63 100644 --- a/Tests/cameras/camera scale.js +++ b/Tests/cameras/camera scale.js @@ -1,21 +1,15 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); - var zombieCamera; - var zombie; - var walkSpeed = 2, - direction = 1; - + var walkSpeed = 2, direction = 1; function init() { game.world.setSize(1280, 600, true); game.load.image('ground', 'assets/tests/ground-2x.png'); game.load.image('river', 'assets/tests/river-2x.png'); game.load.image('sky', 'assets/tests/sky-2x.png'); - game.load.spritesheet('zombie', 'assets/sprites/metalslug_monster39x40.png', 39, 40); - game.load.start(); } function create() { @@ -23,12 +17,10 @@ game.add.sprite(0, 0, 'sky'); game.add.sprite(0, 360, 'ground'); game.add.sprite(0, 400, 'river'); - // Create zombie spirte zombie = game.add.sprite(480, 336, 'zombie'); zombie.animations.add('walk', null, 30, true); zombie.animations.play('walk'); - // Create a small camera which looks at the zombie. // Use the same settings as the default camera. zombieCamera = game.add.camera(0, 0, 800, 600); @@ -44,21 +36,19 @@ zombieCamera.setPosition(0, 0); } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { zombieCamera.x -= 2; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { zombieCamera.x += 2; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { zombieCamera.y -= 2; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { zombieCamera.y += 2; } // zombie wandering update zombie.x += walkSpeed * direction; - if (zombie.x > 540 || zombie.x < 440) { + if(zombie.x > 540 || zombie.x < 440) { // Change walk direction. direction *= -1; // Flip zombie's animation. @@ -66,7 +56,7 @@ } } function render() { - game.camera.renderDebugInfo(32, 32); - zombieCamera.renderDebugInfo(32, 128); + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + Phaser.DebugUtils.renderCameraInfo(zombieCamera, 32, 128); } })(); diff --git a/Tests/cameras/camera scale.ts b/Tests/cameras/camera scale.ts index 0c487213..d4314f50 100644 --- a/Tests/cameras/camera scale.ts +++ b/Tests/cameras/camera scale.ts @@ -5,8 +5,8 @@ var zombieCamera: Phaser.Camera; var zombie: Phaser.Sprite; - var walkSpeed: Number = 2, - direction: Number = 1; + var walkSpeed: number = 2, + direction: number = 1; function init() { game.world.setSize(1280, 600, true); @@ -66,7 +66,8 @@ } } function render() { - game.camera.renderDebugInfo(32, 32); - zombieCamera.renderDebugInfo(32, 128); + + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + Phaser.DebugUtils.renderCameraInfo(zombieCamera, 32, 128); } })(); diff --git a/Tests/cameras/camera texture.js b/Tests/cameras/camera texture.js index 5a95701a..5595890b 100644 --- a/Tests/cameras/camera texture.js +++ b/Tests/cameras/camera texture.js @@ -1,11 +1,9 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); - function init() { game.world.setSize(800, 600, true); game.load.image('background', 'assets/misc/water_texture.jpg'); - game.load.start(); } function create() { @@ -13,7 +11,6 @@ } function render() { Phaser.DebugUtils.context.fillStyle = 'rgb(255, 255, 255)'; - Phaser.DebugUtils.context.fillText('Draw background image using camera.texture property.', - 196, 320); + Phaser.DebugUtils.context.fillText('Draw background image using camera.texture property.', 196, 320); } })(); diff --git a/Tests/cameras/follow styles.js b/Tests/cameras/follow styles.js index 223286e3..acafdf89 100644 --- a/Tests/cameras/follow styles.js +++ b/Tests/cameras/follow styles.js @@ -1,13 +1,9 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); - - var ufo, - speed = 4; - + var ufo, speed = 4; var btn0, btn1, btn2, btn3; var style = 'default'; - function init() { game.world.setSize(1280, 800, true); game.load.image('ground', 'assets/tests/ground-2x.png'); @@ -16,36 +12,25 @@ game.load.image('cloud0', 'assets/tests/cloud-big-2x.png'); game.load.image('cloud1', 'assets/tests/cloud-narrow-2x.png'); game.load.image('cloud2', 'assets/tests/cloud-small-2x.png'); - game.load.spritesheet('button', 'assets/buttons/follow-style-button.png', 224, 70); - game.load.spritesheet('ufo', 'assets/sprites/ufo.png', 24, 21); - game.load.start(); } function create() { // background images - game.add.sprite(0, 0, 'sky') - .transform.scrollFactor.setTo(0, 0); - game.add.sprite(0, 360, 'ground') - .transform.scrollFactor.setTo(0.5, 0.1); - game.add.sprite(0, 400, 'river') - .transform.scrollFactor.setTo(1.3, 0.16); - game.add.sprite(200, 120, 'cloud0') - .transform.scrollFactor.setTo(0.3, 0.1); - game.add.sprite(-60, 120, 'cloud1') - .transform.scrollFactor.setTo(0.5, 0.1); - game.add.sprite(900, 170, 'cloud2') - .transform.scrollFactor.setTo(0.7, 0.1); + game.add.sprite(0, 0, 'sky').transform.scrollFactor.setTo(0, 0); + game.add.sprite(0, 360, 'ground').transform.scrollFactor.setTo(0.5, 0.1); + game.add.sprite(0, 400, 'river').transform.scrollFactor.setTo(1.3, 0.16); + game.add.sprite(200, 120, 'cloud0').transform.scrollFactor.setTo(0.3, 0.1); + game.add.sprite(-60, 120, 'cloud1').transform.scrollFactor.setTo(0.5, 0.1); + game.add.sprite(900, 170, 'cloud2').transform.scrollFactor.setTo(0.7, 0.1); // ufo spirte ufo = game.add.sprite(360, 240, 'ufo'); ufo.animations.add('fly', null, 30, false); ufo.animations.play('fly'); ufo.transform.origin.setTo(0.5, 0.5); - // make camera follows ufo game.camera.follow(ufo); - // follow style switch buttons btn0 = game.add.button(16, 40, 'button', lockonFollow, 0, 0, 0); btn1 = game.add.button(16, 120, 'button', platformerFollow, 1, 1, 1); @@ -53,26 +38,23 @@ btn3 = game.add.button(16, 280, 'button', topdownTightFollow, 3, 3, 3); } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { ufo.x -= speed; ufo.rotation = -15; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { ufo.x += speed; ufo.rotation = 15; - } - else { + } else { ufo.rotation = 0; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { ufo.y -= speed; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { ufo.y += speed; } } function render() { - if (game.camera.deadzone) { + if(game.camera.deadzone) { Phaser.DebugUtils.renderRectangle(game.camera.deadzone, 'rgba(240, 112, 111, 0.4)'); } // game.camera.renderDebugInfo(400, 16); diff --git a/Tests/cameras/follow styles.ts b/Tests/cameras/follow styles.ts index 8063f5d7..89319b98 100644 --- a/Tests/cameras/follow styles.ts +++ b/Tests/cameras/follow styles.ts @@ -3,13 +3,13 @@ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); var ufo: Phaser.Sprite, - speed: Number = 4; + speed: number = 4; var btn0: Phaser.UI.Button, btn1: Phaser.UI.Button, btn2: Phaser.UI.Button, btn3: Phaser.UI.Button; - var style: String = 'default'; + var style: string = 'default'; function init() { game.world.setSize(1280, 800, true); @@ -84,19 +84,19 @@ Phaser.DebugUtils.context.fillText('Current style: ' + style, 360, 48); } function lockonFollow() { - game.camera.follow(ufo, Phaser.Camera.STYLE_LOCKON); + game.camera.follow(ufo, Phaser.Phaser.Types.CAMERA_FOLLOW_LOCKON); style = 'STYLE_LOCKON'; } function platformerFollow() { - game.camera.follow(ufo, Phaser.Camera.STYLE_PLATFORMER); + game.camera.follow(ufo, Phaser.Phaser.Types.CAMERA_FOLLOW_PLATFORMER); style = 'STYLE_PLATFORMER'; } function topdownFollow() { - game.camera.follow(ufo, Phaser.Camera.STYLE_TOPDOWN); + game.camera.follow(ufo, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN); style = 'STYLE_TOPDOWN'; } function topdownTightFollow() { - game.camera.follow(ufo, Phaser.Camera.STYLE_TOPDOWN_TIGHT); + game.camera.follow(ufo, Phaser.Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT); style = 'STYLE_TOPDOWN_TIGHT'; } })(); diff --git a/Tests/cameras/hide from camera.js b/Tests/cameras/hide from camera.js index 231d1125..b330fef3 100644 --- a/Tests/cameras/hide from camera.js +++ b/Tests/cameras/hide from camera.js @@ -1,53 +1,45 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); - var radar; var ships = []; - var enemyCamera; - function init() { - game.world.setSize(800, 600, true); game.load.image('radar-surface', 'assets/tests/radar-surface.png'); game.load.image('ship', 'assets/sprites/asteroids_ship_white.png'); game.load.image('enemy-ship', 'assets/sprites/asteroids_ship.png'); - game.load.start(); } function create() { // Add enemies and our ship the the world. - for (var i = 0; i < 4; i++) { + for(var i = 0; i < 4; i++) { ships.push(game.add.sprite(100 + i * 10, 280 + i * 16, 'enemy-ship')); } var ourShip = game.add.sprite(160, 300, 'ship'); ships.push(ourShip); - // Radar sprite is a HUD. radar = game.add.sprite(0, 0, 'radar-surface'); - radar.transform.scrollFactor.setTo(0, 0); - // Make the default camera rendered on the left half screen. game.camera.setSize(400, 600); + game.camera.texture.backgroundColor = 'rgb(0,50,100)'; + game.camera.texture.opaque = true; // Add a new camera and render it on the right half screen. // The newly created is the enemies' camera, which cannot "see" our ship. - enemyCamera = game.add.camera(0, 0, 800, 600); - enemyCamera.setSize(400, 600); - enemyCamera.setPosition(400, 0); - + enemyCamera = game.add.camera(400, 0, 400, 600); + enemyCamera.texture.backgroundColor = 'rgb(100,0,50)'; + enemyCamera.texture.opaque = true; // Hide our ship on the enemies' camera. enemyCamera.hide(ourShip); } function update() { - for (var i = 0; i < ships.length; i++) { - ships[i].x += 1; - if (ships[i].x > 400) { + for(var i = 0; i < ships.length; i++) { + ships[i].x += 4; + if(ships[i].x > 400) { ships[i].x = 40; } } } function render() { - Phaser.DebugUtils.context.fillStyle = '#fff'; - Phaser.DebugUtils.context.fillText('Left is the player\'s camera, and right is the enemies\' camera.', 32, 100); + Phaser.DebugUtils.renderText('Left is the player\'s camera and right is the enemies\' camera.', 32, 32); } })(); diff --git a/Tests/cameras/hide from camera.ts b/Tests/cameras/hide from camera.ts index e0909327..5155994a 100644 --- a/Tests/cameras/hide from camera.ts +++ b/Tests/cameras/hide from camera.ts @@ -1,53 +1,66 @@ /// (function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); var radar: Phaser.Sprite; var ships: Phaser.Sprite[] = []; - var enemyCamera; + var enemyCamera: Phaser.Camera; function init() { - game.world.setSize(800, 600, true); + game.load.image('radar-surface', 'assets/tests/radar-surface.png'); game.load.image('ship', 'assets/sprites/asteroids_ship_white.png'); game.load.image('enemy-ship', 'assets/sprites/asteroids_ship.png'); game.load.start(); } + function create() { + // Add enemies and our ship the the world. for (var i = 0; i < 4; i++) { ships.push(game.add.sprite(100 + i * 10, 280 + i * 16, 'enemy-ship')); } + var ourShip: Phaser.Sprite = game.add.sprite(160, 300, 'ship'); ships.push(ourShip); // Radar sprite is a HUD. radar = game.add.sprite(0, 0, 'radar-surface'); - radar.transform.scrollFactor.setTo(0, 0); // Make the default camera rendered on the left half screen. game.camera.setSize(400, 600); + game.camera.texture.backgroundColor = 'rgb(0,50,100)'; + game.camera.texture.opaque = true; + // Add a new camera and render it on the right half screen. // The newly created is the enemies' camera, which cannot "see" our ship. - enemyCamera = game.add.camera(0, 0, 800, 600); - enemyCamera.setSize(400, 600); - enemyCamera.setPosition(400, 0); + enemyCamera = game.add.camera(400, 0, 400, 600); + enemyCamera.texture.backgroundColor = 'rgb(100,0,50)'; + enemyCamera.texture.opaque = true; // Hide our ship on the enemies' camera. enemyCamera.hide(ourShip); + } + function update() { + for (var i = 0; i < ships.length; i++) { - ships[i].x += 1; + + ships[i].x += 4; + if (ships[i].x > 400) { ships[i].x = 40; } } + } + function render() { - Phaser.DebugUtils.context.fillStyle = '#fff'; - Phaser.DebugUtils.context.fillText('Left is the player\'s camera, and right is the enemies\' camera.', 32, 100); + Phaser.DebugUtils.renderText('Left is the player\'s camera and right is the enemies\' camera.', 32, 32); } + })(); diff --git a/Tests/cameras/multi camera.js b/Tests/cameras/multi camera.js index d98d8244..2b1ce94d 100644 --- a/Tests/cameras/multi camera.js +++ b/Tests/cameras/multi camera.js @@ -1,21 +1,15 @@ /// (function () { var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); - var zombieCamera; - var zombie; - var walkSpeed = 2, - direction = 1; - + var walkSpeed = 2, direction = 1; function init() { game.world.setSize(1280, 600, true); game.load.image('ground', 'assets/tests/ground-2x.png'); game.load.image('river', 'assets/tests/river-2x.png'); game.load.image('sky', 'assets/tests/sky-2x.png'); - game.load.spritesheet('zombie', 'assets/sprites/metalslug_monster39x40.png', 39, 40); - game.load.start(); } function create() { @@ -23,12 +17,10 @@ game.add.sprite(0, 0, 'sky'); game.add.sprite(0, 360, 'ground'); game.add.sprite(0, 400, 'river'); - // Create zombie spirte zombie = game.add.sprite(480, 336, 'zombie'); zombie.animations.add('walk', null, 30, true); zombie.animations.play('walk'); - // Create a small camera which looks at the zombie. // Use the same settings as the default camera. zombieCamera = game.add.camera(0, 0, 800, 600); @@ -42,21 +34,19 @@ zombieCamera.setPosition(0, 0); } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { zombieCamera.x -= 2; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { zombieCamera.x += 2; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { zombieCamera.y -= 2; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { zombieCamera.y += 2; } // zombie wandering update zombie.x += walkSpeed * direction; - if (zombie.x > 540 || zombie.x < 440) { + if(zombie.x > 540 || zombie.x < 440) { // Change walk direction. direction *= -1; // Flip zombie's animation. @@ -64,7 +54,7 @@ } } function render() { - game.camera.renderDebugInfo(32, 32); - zombieCamera.renderDebugInfo(32, 128); + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + Phaser.DebugUtils.renderCameraInfo(zombieCamera, 32, 128); } })(); diff --git a/Tests/cameras/multi camera.ts b/Tests/cameras/multi camera.ts index 5484466d..e3adbe3c 100644 --- a/Tests/cameras/multi camera.ts +++ b/Tests/cameras/multi camera.ts @@ -5,8 +5,8 @@ var zombieCamera: Phaser.Camera; var zombie: Phaser.Sprite; - var walkSpeed: Number = 2, - direction: Number = 1; + var walkSpeed: number = 2, + direction: number = 1; function init() { game.world.setSize(1280, 600, true); @@ -64,7 +64,7 @@ } } function render() { - game.camera.renderDebugInfo(32, 32); - zombieCamera.renderDebugInfo(32, 128); + Phaser.DebugUtils.renderCameraInfo(game.camera, 32, 32); + Phaser.DebugUtils.renderCameraInfo(zombieCamera, 32, 128); } })(); diff --git a/Tests/cameras/scrollfactor compare.js b/Tests/cameras/scrollfactor compare.js index 07b499a1..f0b2ba98 100644 --- a/Tests/cameras/scrollfactor compare.js +++ b/Tests/cameras/scrollfactor compare.js @@ -13,32 +13,23 @@ } function create() { // background sky, which does not move at all - game.add.sprite(0, 0, 'sky') - .transform.scrollFactor.setTo(0, 0); - + game.add.sprite(0, 0, 'sky').transform.scrollFactor.setTo(0, 0); // clouds with different scroll factor which moves slower than camera - game.add.sprite(200, 120, 'cloud0') - .transform.scrollFactor.setTo(0.3, 0.3); - game.add.sprite(-60, 120, 'cloud1') - .transform.scrollFactor.setTo(0.5, 0.3); - game.add.sprite(900, 170, 'cloud2') - .transform.scrollFactor.setTo(0.7, 0.3); - + game.add.sprite(200, 120, 'cloud0').transform.scrollFactor.setTo(0.3, 0.3); + game.add.sprite(-60, 120, 'cloud1').transform.scrollFactor.setTo(0.5, 0.3); + game.add.sprite(900, 170, 'cloud2').transform.scrollFactor.setTo(0.7, 0.3); // forground objects which moves equal or faster than camera - game.add.sprite(0, 360, 'ground') - .transform.scrollFactor.setTo(0.5, 0.5); - game.add.sprite(0, 400, 'river') - .transform.scrollFactor.setTo(1.3, 1.3); + game.add.sprite(0, 360, 'ground').transform.scrollFactor.setTo(0.5, 0.5); + game.add.sprite(0, 400, 'river').transform.scrollFactor.setTo(1.3, 1.3); } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { game.camera.x -= 3; - } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { game.camera.x += 3; } } function render() { // game.camera.renderDebugInfo(32, 32); - } + } })(); diff --git a/Tests/phaser.js b/Tests/phaser.js index 4f6bf951..b2e5af22 100644 --- a/Tests/phaser.js +++ b/Tests/phaser.js @@ -327,6 +327,14 @@ var Phaser; this.height = height; return this; }; + Rectangle.prototype.floor = /** + * Runs Math.floor() on both the x and y values of this Rectangle. + * @method floor + **/ + function () { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + }; Rectangle.prototype.copyFrom = /** * Copies the x, y, width and height properties from any given object to this Rectangle. * @method copyFrom @@ -1267,6 +1275,12 @@ var Phaser; Types.RENDERER_HEADLESS = 1; Types.RENDERER_CANVAS = 2; Types.RENDERER_WEBGL = 3; + Types.CAMERA_TYPE_ORTHOGRAPHIC = 0; + Types.CAMERA_TYPE_ISOMETRIC = 1; + Types.CAMERA_FOLLOW_LOCKON = 0; + Types.CAMERA_FOLLOW_PLATFORMER = 1; + Types.CAMERA_FOLLOW_TOPDOWN = 2; + Types.CAMERA_FOLLOW_TOPDOWN_TIGHT = 3; Types.GROUP = 0; Types.SPRITE = 1; Types.GEOMSPRITE = 2; @@ -1277,7 +1291,7 @@ var Phaser; Types.BUTTON = 7; Types.GEOM_POINT = 0; Types.GEOM_CIRCLE = 1; - Types.GEOM_Rectangle = 2; + Types.GEOM_RECTANGLE = 2; Types.GEOM_LINE = 3; Types.GEOM_POLYGON = 4; Types.BODY_DISABLED = 0; @@ -2493,7 +2507,6 @@ var Phaser; this._pointerData[pointer.id].isDragged = true; if(this.dragFromCenter) { this._parent.transform.centerOn(pointer.worldX(), pointer.worldY()); - //this._dragPoint.setTo(this._parent.x - this._parent.transform.center.x, this._parent.y - this._parent.transform.center.y); this._dragPoint.setTo(this._parent.x - pointer.x, this._parent.y - pointer.y); } else { this._dragPoint.setTo(this._parent.x - pointer.x, this._parent.y - pointer.y); @@ -2977,7 +2990,6 @@ var Phaser; * Doesn't change the origin of the sprite. */ function (x, y) { - console.log('centerOn', x, y); this.parent.x = x + (this.parent.x - this.center.x); this.parent.y = y + (this.parent.y - this.center.y); this.setCache(); @@ -5113,8 +5125,8 @@ var Phaser; function updateCameraView(camera, sprite) { if(sprite.rotation == 0 || sprite.texture.renderRotation == false) { // Easy out - sprite.cameraView.x = Math.round(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); - sprite.cameraView.y = Math.round(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); + sprite.cameraView.x = Math.floor(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); + sprite.cameraView.y = Math.floor(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); sprite.cameraView.width = sprite.width; sprite.cameraView.height = sprite.height; } else { @@ -6138,7 +6150,40 @@ var Phaser; this._width = 16; this._height = 16; this.cameraBlacklist = []; + this._blacklist = 0; } + Texture.prototype.hideFromCamera = /** + * Hides an object from this Camera. Hidden objects are not rendered. + * + * @param object {Camera} The camera this object should ignore. + */ + function (camera) { + if(this.isHidden(camera) == false) { + this.cameraBlacklist.push(camera.ID); + this._blacklist++; + } + }; + Texture.prototype.isHidden = /** + * Returns true if this texture is hidden from rendering to the given camera, otherwise false. + */ + function (camera) { + if(this._blacklist && this.cameraBlacklist.indexOf(camera.ID) !== -1) { + return true; + } + return false; + }; + Texture.prototype.showToCamera = /** + * Un-hides an object previously hidden to this Camera. + * The object must implement a public cameraBlacklist property. + * + * @param object {Sprite/Group} The object this camera should display. + */ + function (camera) { + if(this.isHidden(camera)) { + this.cameraBlacklist.slice(this.cameraBlacklist.indexOf(camera.ID), 1); + this._blacklist--; + } + }; Texture.prototype.setTo = /** * Updates the texture being used to render the Sprite. * Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture. @@ -6360,7 +6405,7 @@ var Phaser; if(camera.isHidden(this) == true) { return; } - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; while(this._i < this.length) { this._member = this.members[this._i++]; @@ -6368,18 +6413,18 @@ var Phaser; if(this._member.type == Phaser.Types.GROUP) { this._member.render(camera); } else { - this.game.renderer.renderGameObject(this._member); + this.game.renderer.renderGameObject(camera, this._member); } } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); }; Group.prototype.directRender = /** * Calls render on all members of this Group regardless of their visible status and also ignores the camera blacklist. * Use this when the Group objects render to hidden canvases for example. */ function (camera) { - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; while(this._i < this.length) { this._member = this.members[this._i++]; @@ -6391,7 +6436,7 @@ var Phaser; } } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); }; Object.defineProperty(Group.prototype, "maxSize", { get: /** @@ -9570,10 +9615,6 @@ var Phaser; function Camera(game, id, x, y, width, height) { this._target = null; /** - * Controls if this camera is clipped or not when rendering. You shouldn't usually set this value directly. - */ - this.clip = false; - /** * Camera worldBounds. * @type {Rectangle} */ @@ -9588,11 +9629,6 @@ var Phaser; */ this.deadzone = null; /** - * Disable the automatic camera canvas clipping when Camera is non-Stage sized. - * @type {Boolean} - */ - this.disableClipping = false; - /** * Whether this camera is visible or not. (default is true) * @type {boolean} */ @@ -9614,13 +9650,33 @@ var Phaser; this.plugins = new Phaser.PluginManager(this.game, this); this.transform = new Phaser.Components.TransformManager(this); this.texture = new Phaser.Display.Texture(this); - this.texture.opaque = false; - this.checkClip(); + // We create a hidden canvas for our camera the size of the game (we use the screenView to clip the render to the camera size) + this.texture.canvas = document.createElement('canvas'); + this.texture.canvas.width = width; + this.texture.canvas.height = height; + this.texture.context = this.texture.canvas.getContext('2d'); + // Handy proxies + this.scale = this.transform.scale; + this.alpha = this.texture.alpha; + this.origin = this.transform.origin; + this.crop = this.texture.crop; } - Camera.STYLE_LOCKON = 0; - Camera.STYLE_PLATFORMER = 1; - Camera.STYLE_TOPDOWN = 2; - Camera.STYLE_TOPDOWN_TIGHT = 3; + Object.defineProperty(Camera.prototype, "alpha", { + get: /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + function () { + return this.texture.alpha; + }, + set: /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + function (value) { + this.texture.alpha = value; + }, + enumerable: true, + configurable: true + }); Camera.prototype.hide = /** * Hides an object from this Camera. Hidden objects are not rendered. * The object must implement a public cameraBlacklist property. @@ -9628,9 +9684,7 @@ var Phaser; * @param object {Sprite/Group} The object this camera should ignore. */ function (object) { - if(this.isHidden(object) == false) { - object.texture['cameraBlacklist'].push(this.ID); - } + object.texture.hideFromCamera(this); }; Camera.prototype.isHidden = /** * Returns true if the object is hidden from this Camera. @@ -9638,7 +9692,7 @@ var Phaser; * @param object {Sprite/Group} The object to check. */ function (object) { - return (object.texture['cameraBlacklist'] && object.texture['cameraBlacklist'].length > 0 && object.texture['cameraBlacklist'].indexOf(this.ID) == -1); + return object.texture.isHidden(this); }; Camera.prototype.show = /** * Un-hides an object previously hidden to this Camera. @@ -9647,9 +9701,7 @@ var Phaser; * @param object {Sprite/Group} The object this camera should display. */ function (object) { - if(this.isHidden(object) == true) { - object.texture['cameraBlacklist'].slice(object.texture['cameraBlacklist'].indexOf(this.ID), 1); - } + object.texture.showToCamera(this); }; Camera.prototype.follow = /** * Tells this camera object what sprite to track. @@ -9657,24 +9709,24 @@ var Phaser; * @param [style] {number} Leverage one of the existing "deadzone" presets. If you use a custom deadzone, ignore this parameter and manually specify the deadzone after calling follow(). */ function (target, style) { - if (typeof style === "undefined") { style = Camera.STYLE_LOCKON; } + if (typeof style === "undefined") { style = Phaser.Types.CAMERA_FOLLOW_LOCKON; } this._target = target; var helper; switch(style) { - case Camera.STYLE_PLATFORMER: + case Phaser.Types.CAMERA_FOLLOW_PLATFORMER: var w = this.width / 8; var h = this.height / 3; this.deadzone = new Phaser.Rectangle((this.width - w) / 2, (this.height - h) / 2 - h * 0.25, w, h); break; - case Camera.STYLE_TOPDOWN: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN: helper = Math.max(this.width, this.height) / 4; this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_TOPDOWN_TIGHT: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT: helper = Math.max(this.width, this.height) / 8; this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_LOCKON: + case Phaser.Types.CAMERA_FOLLOW_LOCKON: default: this.deadzone = null; break; @@ -9770,6 +9822,7 @@ var Phaser; this.worldView.y = (this.worldBounds.bottom - this.height) + 1; } } + this.worldView.floor(); this.plugins.update(); }; Camera.prototype.postUpdate = /** @@ -9785,15 +9838,16 @@ var Phaser; this.worldView.x = this.worldBounds.left; } if(this.worldView.x > this.worldBounds.right - this.width) { - this.worldView.x = (this.worldBounds.right - this.width) + 1; + this.worldView.x = this.worldBounds.right - this.width; } if(this.worldView.y < this.worldBounds.top) { this.worldView.y = this.worldBounds.top; } if(this.worldView.y > this.worldBounds.bottom - this.height) { - this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + this.worldView.y = this.worldBounds.bottom - this.height; } } + this.worldView.floor(); this.plugins.postUpdate(); }; Camera.prototype.destroy = /** @@ -9830,6 +9884,9 @@ var Phaser; set: function (value) { this.screenView.width = value; this.worldView.width = value; + if(value !== this.texture.canvas.width) { + this.texture.canvas.width = value; + } }, enumerable: true, configurable: true @@ -9841,6 +9898,9 @@ var Phaser; set: function (value) { this.screenView.height = value; this.worldView.height = value; + if(value !== this.texture.canvas.height) { + this.texture.canvas.height = value; + } }, enumerable: true, configurable: true @@ -9848,14 +9908,18 @@ var Phaser; Camera.prototype.setPosition = function (x, y) { this.screenView.x = x; this.screenView.y = y; - this.checkClip(); }; Camera.prototype.setSize = function (width, height) { this.screenView.width = width * this.transform.scale.x; this.screenView.height = height * this.transform.scale.y; this.worldView.width = width; this.worldView.height = height; - this.checkClip(); + if(width !== this.texture.canvas.width) { + this.texture.canvas.width = width; + } + if(height !== this.texture.canvas.height) { + this.texture.canvas.height = height; + } }; Object.defineProperty(Camera.prototype, "rotation", { get: /** @@ -9874,13 +9938,6 @@ var Phaser; enumerable: true, configurable: true }); - Camera.prototype.checkClip = function () { - if(this.screenView.x != 0 || this.screenView.y != 0 || this.screenView.width < this.game.stage.width || this.screenView.height < this.game.stage.height) { - this.clip = true; - } else { - this.clip = false; - } - }; return Camera; })(); Phaser.Camera = Camera; @@ -9919,8 +9976,6 @@ var Phaser; this.defaultCamera = this.addCamera(x, y, width, height); this.current = this.defaultCamera; } - CameraManager.CAMERA_TYPE_ORTHOGRAPHIC = 0; - CameraManager.CAMERA_TYPE_ISOMETRIC = 1; CameraManager.prototype.getAll = /** * Get all the cameras. * @@ -9954,8 +10009,7 @@ var Phaser; * @param height {number} Height of the new camera. * @returns {Camera} The newly created camera object. */ - function (x, y, width, height, type) { - if (typeof type === "undefined") { type = CameraManager.CAMERA_TYPE_ORTHOGRAPHIC; } + function (x, y, width, height) { var newCam = new Phaser.Camera(this._game, this._cameraInstance, x, y, width, height); this._cameras.push(newCam); this._cameraInstance++; @@ -14085,6 +14139,7 @@ var Phaser; */ function () { this.scale.update(); + this.context.setTransform(1, 0, 0, 1, 0, 0); if(this.clear || (this._game.paused && this.disablePauseScreen == false)) { if(this.patchAndroidClearRectBug) { this.context.fillStyle = 'rgb(0,0,0)'; @@ -17261,629 +17316,812 @@ var Phaser; })(); Phaser.InputManager = InputManager; })(Phaser || (Phaser = {})); -/// -/// -/// var Phaser; (function (Phaser) { - var HeadlessRenderer = (function () { - function HeadlessRenderer(game) { - this._game = game; - } - HeadlessRenderer.prototype.render = function () { - }; - HeadlessRenderer.prototype.inCamera = function (camera, sprite) { - return true; - }; - HeadlessRenderer.prototype.renderGameObject = function (object) { - }; - HeadlessRenderer.prototype.renderSprite = function (camera, sprite) { - return true; - }; - HeadlessRenderer.prototype.renderScrollZone = function (camera, scrollZone) { - return true; - }; - HeadlessRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { - if (typeof outline === "undefined") { outline = true; } - if (typeof fill === "undefined") { fill = true; } - if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } - if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } - if (typeof lineWidth === "undefined") { lineWidth = 1; } - return true; - }; - HeadlessRenderer.prototype.preRenderCamera = function (camera) { - }; - HeadlessRenderer.prototype.postRenderCamera = function (camera) { - }; - HeadlessRenderer.prototype.preRenderGroup = function (camera, group) { - }; - HeadlessRenderer.prototype.postRenderGroup = function (camera, group) { - }; - return HeadlessRenderer; - })(); - Phaser.HeadlessRenderer = HeadlessRenderer; + (function (Renderer) { + /// + /// + /// + (function (Headless) { + var HeadlessRenderer = (function () { + function HeadlessRenderer(game) { + this.game = game; + } + HeadlessRenderer.prototype.render = function () { + // Nothing, headless remember? + }; + HeadlessRenderer.prototype.renderGameObject = function (camera, object) { + // Nothing, headless remember? + }; + return HeadlessRenderer; + })(); + Headless.HeadlessRenderer = HeadlessRenderer; + })(Renderer.Headless || (Renderer.Headless = {})); + var Headless = Renderer.Headless; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; })(Phaser || (Phaser = {})); -/// -/// -/// -/// -/// var Phaser; (function (Phaser) { - var CanvasRenderer = (function () { - function CanvasRenderer(game) { - // Local rendering related temp vars to help avoid gc spikes through var creation - this._ga = 1; - this._sx = 0; - this._sy = 0; - this._sw = 0; - this._sh = 0; - this._dx = 0; - this._dy = 0; - this._dw = 0; - this._dh = 0; - this._fx = 1; - this._fy = 1; - this._tx = 0; - this._ty = 0; - this._sin = 0; - this._cos = 1; - this._maxX = 0; - this._maxY = 0; - this._startX = 0; - this._startY = 0; - this._game = game; - } - CanvasRenderer.prototype.render = function () { - // Get a list of all the active cameras - this._cameraList = this._game.world.getAllCameras(); - this._count = 0; - // Then iterate through world.group on them all (where not blacklisted, etc) - for(var c = 0; c < this._cameraList.length; c++) { - this._camera = this._cameraList[c]; - this.preRenderCamera(this._camera); - this._game.world.group.render(this._camera); - this.postRenderCamera(this._camera); - } - this.renderTotal = this._count; - }; - CanvasRenderer.prototype.renderGameObject = function (object) { - if(object.type == Phaser.Types.SPRITE || object.type == Phaser.Types.BUTTON) { - this.renderSprite(this._camera, object); - } else if(object.type == Phaser.Types.SCROLLZONE) { - this.renderScrollZone(this._camera, object); - } else if(object.type == Phaser.Types.TILEMAP) { - this.renderTilemap(this._camera, object); - } - }; - CanvasRenderer.prototype.preRenderGroup = function (camera, group) { - if(camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) { - return false; - } - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = group.texture.width; - this._sh = group.texture.height; - this._fx = group.transform.scale.x; - this._fy = group.transform.scale.y; - this._sin = 0; - this._cos = 1; - //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); - //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); - this._dx = 0; - this._dy = 0; - this._dw = group.texture.width; - this._dh = group.texture.height; - // Global Composite Ops - if(group.texture.globalCompositeOperation) { - group.texture.context.save(); - group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; - } - // Alpha - if(group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) { - this._ga = group.texture.context.globalAlpha; - group.texture.context.globalAlpha = group.texture.alpha; - } - // Flip X - if(group.texture.flippedX) { - this._fx = -group.transform.scale.x; - } - // Flip Y - if(group.texture.flippedY) { - this._fy = -group.transform.scale.y; - } - // Rotation and Flipped - if(group.modified) { - if(group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) { - this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); - this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var CameraRenderer = (function () { + function CameraRenderer(game) { + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._tx = 0; + this._ty = 0; + this._gac = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - group.texture.context.save(); - group.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + group.transform.skew.x, -(this._sin * this._fy) + group.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -group.transform.origin.x; - this._dy = -group.transform.origin.y; - } else { - if(!group.transform.origin.equals(0)) { - this._dx -= group.transform.origin.x; - this._dy -= group.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - if(group.texture.opaque) { - group.texture.context.fillStyle = group.texture.backgroundColor; - group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(group.texture.loaded) { - group.texture.context.drawImage(group.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - return true; - }; - CanvasRenderer.prototype.postRenderGroup = function (camera, group) { - if(group.modified || group.texture.globalCompositeOperation) { - group.texture.context.restore(); - } - // This could have been over-written by a sprite, need to store elsewhere - if(this._ga > -1) { - group.texture.context.globalAlpha = this._ga; - } - }; - CanvasRenderer.prototype.inCamera = /** - * Check whether this object is visible in a specific camera Rectangle. - * @param camera {Rectangle} The Rectangle you want to check. - * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. - */ - function (camera, sprite) { - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if(sprite.transform.scrollFactor.equals(0)) { - return true; - } - return Phaser.RectangleUtils.intersects(sprite.cameraView, camera.screenView); - }; - CanvasRenderer.prototype.inScreen = function (camera) { - return true; - }; - CanvasRenderer.prototype.preRenderCamera = /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - function (camera) { - if(camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) { - return false; - } - camera.plugins.preRender(); - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = camera.width; - this._sh = camera.height; - this._fx = camera.transform.scale.x; - this._fy = camera.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x; - this._dy = camera.screenView.y; - this._dw = camera.width; - this._dh = camera.height; - // Global Composite Ops - if(camera.texture.globalCompositeOperation) { - camera.texture.context.save(); - camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; - } - // Alpha - if(camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) { - this._ga = camera.texture.context.globalAlpha; - camera.texture.context.globalAlpha = camera.texture.alpha; - } - // Sprite Flip X - if(camera.texture.flippedX) { - this._fx = -camera.transform.scale.x; - } - // Sprite Flip Y - if(camera.texture.flippedY) { - this._fy = -camera.transform.scale.y; - } - // Rotation and Flipped - if(camera.modified) { - if(camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) { - this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - camera.texture.context.save(); - camera.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + camera.transform.skew.x, -(this._sin * this._fy) + camera.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -camera.transform.origin.x; - this._dy = -camera.transform.origin.y; - } else { - if(!camera.transform.origin.equals(0)) { - this._dx -= camera.transform.origin.x; - this._dy -= camera.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - // Clip the camera so we don't get sprites appearing outside the edges - if(camera.clip == true && camera.disableClipping == false) { - camera.texture.context.beginPath(); - camera.texture.context.rect(camera.screenView.x, camera.screenView.x, camera.screenView.width, camera.screenView.height); - camera.texture.context.closePath(); - camera.texture.context.clip(); - } - if(camera.texture.opaque) { - camera.texture.context.fillStyle = camera.texture.backgroundColor; - camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(camera.texture.loaded) { - camera.texture.context.drawImage(camera.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - camera.plugins.render(); - return true; - }; - CanvasRenderer.prototype.postRenderCamera = function (camera) { - if(camera.modified || camera.texture.globalCompositeOperation) { - camera.texture.context.restore(); - } - // This could have been over-written by a sprite, need to store elsewhere - if(this._ga > -1) { - camera.texture.context.globalAlpha = this._ga; - } - camera.plugins.postRender(); - }; - CanvasRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { - if (typeof outline === "undefined") { outline = false; } - if (typeof fill === "undefined") { fill = true; } - if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } - if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } - if (typeof lineWidth === "undefined") { lineWidth = 1; } - this._count++; - // Reset our temp vars - this._sx = 0; - this._sy = 0; - this._sw = circle.diameter; - this._sh = circle.diameter; - this._fx = 1; - this._fy = 1; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x + circle.x - camera.worldView.x; - this._dy = camera.screenView.y + circle.y - camera.worldView.y; - this._dw = circle.diameter; - this._dh = circle.diameter; - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - this._game.stage.saveCanvasValues(); - context.save(); - context.lineWidth = lineWidth; - context.strokeStyle = lineColor; - context.fillStyle = fillColor; - context.beginPath(); - context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); - context.closePath(); - if(outline) { - //context.stroke(); - } - if(fill) { - context.fill(); - } - context.restore(); - this._game.stage.restoreCanvasValues(); - return true; - }; - CanvasRenderer.prototype.renderSprite = /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - function (camera, sprite) { - Phaser.SpriteUtils.updateCameraView(camera, sprite); - if(sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { - return false; - } - sprite.renderOrderID = this._count; - this._count++; - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = sprite.texture.width; - this._sh = sprite.texture.height; - this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); - this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); - this._dw = sprite.texture.width; - this._dh = sprite.texture.height; - if(sprite.animations.currentFrame !== null) { - this._sx = sprite.animations.currentFrame.x; - this._sy = sprite.animations.currentFrame.y; - if(sprite.animations.currentFrame.trimmed) { - this._dx += sprite.animations.currentFrame.spriteSourceSizeX; - this._dy += sprite.animations.currentFrame.spriteSourceSizeY; - this._sw = sprite.animations.currentFrame.spriteSourceSizeW; - this._sh = sprite.animations.currentFrame.spriteSourceSizeH; - this._dw = sprite.animations.currentFrame.spriteSourceSizeW; - this._dh = sprite.animations.currentFrame.spriteSourceSizeH; - } - } - if(sprite.modified) { - sprite.texture.context.save(); - sprite.texture.context.setTransform(sprite.transform.local.data[0], // scale x - sprite.transform.local.data[3], // skew x - sprite.transform.local.data[1], // skew y - sprite.transform.local.data[4], // scale y - this._dx, // translate x - this._dy); - // translate y - this._dx = sprite.transform.origin.x * -this._dw; - this._dy = sprite.transform.origin.y * -this._dh; - } else { - this._dx -= (this._dw * sprite.transform.origin.x); - this._dy -= (this._dh * sprite.transform.origin.y); - } - if(sprite.crop) { - this._sx += sprite.crop.x * sprite.transform.scale.x; - this._sy += sprite.crop.y * sprite.transform.scale.y; - this._sw = sprite.crop.width * sprite.transform.scale.x; - this._sh = sprite.crop.height * sprite.transform.scale.y; - this._dx += sprite.crop.x * sprite.transform.scale.x; - this._dy += sprite.crop.y * sprite.transform.scale.y; - this._dw = sprite.crop.width * sprite.transform.scale.x; - this._dh = sprite.crop.height * sprite.transform.scale.y; - //this._sx += sprite.crop.x; - //this._sy += sprite.crop.y; - //this._sw = sprite.crop.width; - //this._sh = sprite.crop.height; - //this._dx += sprite.crop.x; - //this._dy += sprite.crop.y; - //this._dw = sprite.crop.width; - //this._dh = sprite.crop.height; - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { - return false; - } - // Global Composite Ops - if(sprite.texture.globalCompositeOperation) { - sprite.texture.context.save(); - sprite.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; - } - // Alpha - if(sprite.texture.alpha !== 1 && sprite.texture.context.globalAlpha != sprite.texture.alpha) { - this._ga = sprite.texture.context.globalAlpha; - sprite.texture.context.globalAlpha = sprite.texture.alpha; - } - if(sprite.texture.opaque) { - sprite.texture.context.fillStyle = sprite.texture.backgroundColor; - sprite.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(sprite.texture.loaded) { - sprite.texture.context.drawImage(sprite.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - if(sprite.modified || sprite.texture.globalCompositeOperation) { - sprite.texture.context.restore(); - } - if(this._ga > -1) { - sprite.texture.context.globalAlpha = this._ga; - } - return true; - }; - CanvasRenderer.prototype.renderScrollZone = function (camera, scrollZone) { - if(scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) { - return false; - } - this._count++; - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = scrollZone.width; - this._sh = scrollZone.height; - this._fx = scrollZone.transform.scale.x; - this._fy = scrollZone.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); - this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); - this._dw = scrollZone.width; - this._dh = scrollZone.height; - // Alpha - if(scrollZone.texture.alpha !== 1) { - this._ga = scrollZone.texture.context.globalAlpha; - scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; - } - // Sprite Flip X - if(scrollZone.texture.flippedX) { - this._fx = -scrollZone.transform.scale.x; - } - // Sprite Flip Y - if(scrollZone.texture.flippedY) { - this._fy = -scrollZone.transform.scale.y; - } - // Rotation and Flipped - if(scrollZone.modified) { - if(scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) { - this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - scrollZone.texture.context.save(); - scrollZone.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + scrollZone.transform.skew.x, -(this._sin * this._fy) + scrollZone.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -scrollZone.transform.origin.x; - this._dy = -scrollZone.transform.origin.y; - } else { - if(!scrollZone.transform.origin.equals(0)) { - this._dx -= scrollZone.transform.origin.x; - this._dy -= scrollZone.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - for(var i = 0; i < scrollZone.regions.length; i++) { - if(scrollZone.texture.isDynamic) { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } else { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } - } - if(scrollZone.modified) { - scrollZone.texture.context.restore(); - } - if(this._ga > -1) { - scrollZone.texture.context.globalAlpha = this._ga; - } - return true; - }; - CanvasRenderer.prototype.renderTilemap = /** - * Render a tilemap to a specific camera. - * @param camera {Camera} The camera this tilemap will be rendered to. - */ - function (camera, tilemap) { - // Loop through the layers - for(var i = 0; i < tilemap.layers.length; i++) { - var layer = tilemap.layers[i]; - if(layer.visible == false || layer.alpha < 0.1) { - continue; - } - // Work out how many tiles we can fit into our camera and round it up for the edges - this._maxX = this._game.math.ceil(camera.width / layer.tileWidth) + 1; - this._maxY = this._game.math.ceil(camera.height / layer.tileHeight) + 1; - // And now work out where in the tilemap the camera actually is - this._startX = this._game.math.floor(camera.worldView.x / layer.tileWidth); - this._startY = this._game.math.floor(camera.worldView.y / layer.tileHeight); - // Tilemap bounds check - if(this._startX < 0) { - this._startX = 0; - } - if(this._startY < 0) { - this._startY = 0; - } - if(this._maxX > layer.widthInTiles) { - this._maxX = layer.widthInTiles; - } - if(this._maxY > layer.heightInTiles) { - this._maxY = layer.heightInTiles; - } - if(this._startX + this._maxX > layer.widthInTiles) { - this._startX = layer.widthInTiles - this._maxX; - } - if(this._startY + this._maxY > layer.heightInTiles) { - this._startY = layer.heightInTiles - this._maxY; - } - // Finally get the offset to avoid the blocky movement - //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); - //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); - //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); - //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); - this._dx = 0; - this._dy = 0; - this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); - this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); - this._tx = this._dx; - this._ty = this._dy; - // Alpha - if(layer.texture.alpha !== 1) { - this._ga = layer.texture.context.globalAlpha; - layer.texture.context.globalAlpha = layer.texture.alpha; - } - for(var row = this._startY; row < this._startY + this._maxY; row++) { - this._columnData = layer.mapData[row]; - for(var tile = this._startX; tile < this._startX + this._maxX; tile++) { - if(layer.tileOffsets[this._columnData[tile]]) { - layer.texture.context.drawImage(layer.texture.texture, layer.tileOffsets[this._columnData[tile]].x, layer.tileOffsets[this._columnData[tile]].y, layer.tileWidth, layer.tileHeight, this._tx, this._ty, layer.tileWidth, layer.tileHeight); - } - this._tx += layer.tileWidth; + CameraRenderer.prototype.preRender = function (camera) { + if(camera.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) { + return false; } - this._tx = this._dx; - this._ty += layer.tileHeight; + camera.texture.context.clearRect(0, 0, camera.width, camera.height); + // Alpha + if(camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) { + this._ga = camera.texture.context.globalAlpha; + camera.texture.context.globalAlpha = camera.texture.alpha; + } + if(camera.texture.opaque) { + camera.texture.context.fillStyle = camera.texture.backgroundColor; + camera.texture.context.fillRect(0, 0, camera.width, camera.height); + } + //if (camera.texture.loaded) + //{ + // camera.texture.context.drawImage( + // camera.texture.texture, // Source Image + // this._sx, // Source X (location within the source image) + // this._sy, // Source Y + // this._sw, // Source Width + // this._sh, // Source Height + // 0, // Destination X (where on the canvas it'll be drawn) + // 0, // Destination Y + // this._dw, // Destination Width (always same as Source Width unless scaled) + // this._dh // Destination Height (always same as Source Height unless scaled) + // ); + //} + // Global Composite Ops + if(camera.texture.globalCompositeOperation) { + camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; + } + camera.plugins.preRender(); + }; + CameraRenderer.prototype.postRender = function (camera) { + // This could have been over-written by a sprite, need to store elsewhere + if(this._ga > -1) { + camera.texture.context.globalAlpha = this._ga; + } + camera.plugins.postRender(); + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = camera.width; + this._sh = camera.height; + this._fx = camera.transform.scale.x; + this._fy = camera.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x; + this._dy = camera.screenView.y; + this._dw = camera.width; + this._dh = camera.height; + this.game.stage.context.save(); + // Flip X + if(camera.texture.flippedX) { + this._fx = -camera.transform.scale.x; + } + // Flip Y + if(camera.texture.flippedY) { + this._fy = -camera.transform.scale.y; + } + // Rotation and Flipped + if(camera.modified) { + if(camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) { + this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + } + this.game.stage.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + camera.transform.skew.x, // skew x + -(this._sin * this._fy) + camera.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = camera.transform.origin.x * -this._dw; + this._dy = camera.transform.origin.y * -this._dh; + } else { + this._dx -= (this._dw * camera.transform.origin.x); + this._dy -= (this._dh * camera.transform.origin.y); + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { + this.game.stage.context.restore(); + return false; + } + this.game.stage.context.drawImage(camera.texture.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + this.game.stage.context.restore(); + }; + return CameraRenderer; + })(); + Canvas.CameraRenderer = CameraRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var GeometryRenderer = (function () { + function GeometryRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - if(this._ga > -1) { - layer.texture.context.globalAlpha = this._ga; + GeometryRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { + if (typeof outline === "undefined") { outline = false; } + if (typeof fill === "undefined") { fill = true; } + if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } + if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } + if (typeof lineWidth === "undefined") { lineWidth = 1; } + // Reset our temp vars + this._sx = 0; + this._sy = 0; + this._sw = circle.diameter; + this._sh = circle.diameter; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x + circle.x - camera.worldView.x; + this._dy = camera.screenView.y + circle.y - camera.worldView.y; + this._dw = circle.diameter; + this._dh = circle.diameter; + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + this.game.stage.saveCanvasValues(); + context.save(); + context.lineWidth = lineWidth; + context.strokeStyle = lineColor; + context.fillStyle = fillColor; + context.beginPath(); + context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); + context.closePath(); + if(outline) { + //context.stroke(); + } + if(fill) { + context.fill(); + } + context.restore(); + this.game.stage.restoreCanvasValues(); + return true; + }; + return GeometryRenderer; + })(); + Canvas.GeometryRenderer = GeometryRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var GroupRenderer = (function () { + function GroupRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - } - return true; - }; - return CanvasRenderer; - })(); - Phaser.CanvasRenderer = CanvasRenderer; + GroupRenderer.prototype.preRender = function (camera, group) { + if(group.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = group.texture.width; + this._sh = group.texture.height; + this._fx = group.transform.scale.x; + this._fy = group.transform.scale.y; + this._sin = 0; + this._cos = 1; + //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); + //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); + this._dx = 0; + this._dy = 0; + this._dw = group.texture.width; + this._dh = group.texture.height; + // Global Composite Ops + if(group.texture.globalCompositeOperation) { + group.texture.context.save(); + group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; + } + // Alpha + if(group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) { + this._ga = group.texture.context.globalAlpha; + group.texture.context.globalAlpha = group.texture.alpha; + } + // Flip X + if(group.texture.flippedX) { + this._fx = -group.transform.scale.x; + } + // Flip Y + if(group.texture.flippedY) { + this._fy = -group.transform.scale.y; + } + // Rotation and Flipped + if(group.modified) { + if(group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) { + this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + } + group.texture.context.save(); + group.texture.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + group.transform.skew.x, // skew x + -(this._sin * this._fy) + group.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = -group.transform.origin.x; + this._dy = -group.transform.origin.y; + } else { + if(!group.transform.origin.equals(0)) { + this._dx -= group.transform.origin.x; + this._dy -= group.transform.origin.y; + } + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(group.texture.opaque) { + group.texture.context.fillStyle = group.texture.backgroundColor; + group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + if(group.texture.loaded) { + group.texture.context.drawImage(group.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + } + return true; + }; + GroupRenderer.prototype.postRender = function (camera, group) { + if(group.modified || group.texture.globalCompositeOperation) { + group.texture.context.restore(); + } + if(this._ga > -1) { + group.texture.context.globalAlpha = this._ga; + } + }; + return GroupRenderer; + })(); + Canvas.GroupRenderer = GroupRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var ScrollZoneRenderer = (function () { + function ScrollZoneRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; + } + ScrollZoneRenderer.prototype.inCamera = /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + function (camera, scrollZone) { + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if(scrollZone.transform.scrollFactor.equals(0)) { + return true; + } + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + }; + ScrollZoneRenderer.prototype.render = function (camera, scrollZone) { + if(scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = scrollZone.width; + this._sh = scrollZone.height; + this._fx = scrollZone.transform.scale.x; + this._fy = scrollZone.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); + this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); + this._dw = scrollZone.width; + this._dh = scrollZone.height; + // Alpha + if(scrollZone.texture.alpha !== 1) { + this._ga = scrollZone.texture.context.globalAlpha; + scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; + } + // Sprite Flip X + if(scrollZone.texture.flippedX) { + this._fx = -scrollZone.transform.scale.x; + } + // Sprite Flip Y + if(scrollZone.texture.flippedY) { + this._fy = -scrollZone.transform.scale.y; + } + // Rotation and Flipped + if(scrollZone.modified) { + if(scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) { + this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + } + scrollZone.texture.context.save(); + scrollZone.texture.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + scrollZone.transform.skew.x, // skew x + -(this._sin * this._fy) + scrollZone.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = -scrollZone.transform.origin.x; + this._dy = -scrollZone.transform.origin.y; + } else { + if(!scrollZone.transform.origin.equals(0)) { + this._dx -= scrollZone.transform.origin.x; + this._dy -= scrollZone.transform.origin.y; + } + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + for(var i = 0; i < scrollZone.regions.length; i++) { + if(scrollZone.texture.isDynamic) { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } else { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } + } + if(scrollZone.modified) { + scrollZone.texture.context.restore(); + } + if(this._ga > -1) { + scrollZone.texture.context.globalAlpha = this._ga; + } + this.game.renderer.renderCount++; + return true; + }; + return ScrollZoneRenderer; + })(); + Canvas.ScrollZoneRenderer = ScrollZoneRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var SpriteRenderer = (function () { + function SpriteRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + //private _c: number = 0; + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this.game = game; + } + SpriteRenderer.prototype.inCamera = /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + function (camera, sprite) { + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if(sprite.transform.scrollFactor.equals(0)) { + return true; + } + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + }; + SpriteRenderer.prototype.render = /** + * Render this sprite to specific camera. Called by game loop after update(). + * @param camera {Camera} Camera this sprite will be rendered to. + * @return {boolean} Return false if not rendered, otherwise return true. + */ + function (camera, sprite) { + Phaser.SpriteUtils.updateCameraView(camera, sprite); + if(sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = sprite.texture.width; + this._sh = sprite.texture.height; + //this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dx = sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + this._dy = sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dw = sprite.texture.width; + this._dh = sprite.texture.height; + if(sprite.animations.currentFrame !== null) { + this._sx = sprite.animations.currentFrame.x; + this._sy = sprite.animations.currentFrame.y; + if(sprite.animations.currentFrame.trimmed) { + this._dx += sprite.animations.currentFrame.spriteSourceSizeX; + this._dy += sprite.animations.currentFrame.spriteSourceSizeY; + this._sw = sprite.animations.currentFrame.spriteSourceSizeW; + this._sh = sprite.animations.currentFrame.spriteSourceSizeH; + this._dw = sprite.animations.currentFrame.spriteSourceSizeW; + this._dh = sprite.animations.currentFrame.spriteSourceSizeH; + } + } + if(sprite.modified) { + camera.texture.context.save(); + camera.texture.context.setTransform(sprite.transform.local.data[0], // scale x + sprite.transform.local.data[3], // skew x + sprite.transform.local.data[1], // skew y + sprite.transform.local.data[4], // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = sprite.transform.origin.x * -this._dw; + this._dy = sprite.transform.origin.y * -this._dh; + } else { + this._dx -= (this._dw * sprite.transform.origin.x); + this._dy -= (this._dh * sprite.transform.origin.y); + } + if(sprite.crop) { + this._sx += sprite.crop.x * sprite.transform.scale.x; + this._sy += sprite.crop.y * sprite.transform.scale.y; + this._sw = sprite.crop.width * sprite.transform.scale.x; + this._sh = sprite.crop.height * sprite.transform.scale.y; + this._dx += sprite.crop.x * sprite.transform.scale.x; + this._dy += sprite.crop.y * sprite.transform.scale.y; + this._dw = sprite.crop.width * sprite.transform.scale.x; + this._dh = sprite.crop.height * sprite.transform.scale.y; + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { + return false; + } + // Global Composite Ops + if(sprite.texture.globalCompositeOperation) { + camera.texture.context.save(); + camera.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; + } + // Alpha + if(sprite.texture.alpha !== 1 && camera.texture.context.globalAlpha != sprite.texture.alpha) { + this._ga = sprite.texture.context.globalAlpha; + camera.texture.context.globalAlpha = sprite.texture.alpha; + } + if(sprite.texture.opaque) { + camera.texture.context.fillStyle = sprite.texture.backgroundColor; + camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + if(sprite.texture.loaded) { + camera.texture.context.drawImage(sprite.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + } + if(sprite.modified || sprite.texture.globalCompositeOperation) { + camera.texture.context.restore(); + } + if(this._ga > -1) { + camera.texture.context.globalAlpha = this._ga; + } + sprite.renderOrderID = this.game.renderer.renderCount; + this.game.renderer.renderCount++; + return true; + }; + return SpriteRenderer; + })(); + Canvas.SpriteRenderer = SpriteRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var TilemapRenderer = (function () { + function TilemapRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._tx = 0; + this._ty = 0; + this._sin = 0; + this._cos = 1; + this._maxX = 0; + this._maxY = 0; + this._startX = 0; + this._startY = 0; + this.game = game; + } + TilemapRenderer.prototype.render = /** + * Render a tilemap to a specific camera. + * @param camera {Camera} The camera this tilemap will be rendered to. + */ + function (camera, tilemap) { + // Loop through the layers + for(var i = 0; i < tilemap.layers.length; i++) { + var layer = tilemap.layers[i]; + if(layer.visible == false || layer.alpha < 0.1) { + continue; + } + // Work out how many tiles we can fit into our camera and round it up for the edges + this._maxX = this.game.math.ceil(camera.width / layer.tileWidth) + 1; + this._maxY = this.game.math.ceil(camera.height / layer.tileHeight) + 1; + // And now work out where in the tilemap the camera actually is + this._startX = this.game.math.floor(camera.worldView.x / layer.tileWidth); + this._startY = this.game.math.floor(camera.worldView.y / layer.tileHeight); + // Tilemap bounds check + if(this._startX < 0) { + this._startX = 0; + } + if(this._startY < 0) { + this._startY = 0; + } + if(this._maxX > layer.widthInTiles) { + this._maxX = layer.widthInTiles; + } + if(this._maxY > layer.heightInTiles) { + this._maxY = layer.heightInTiles; + } + if(this._startX + this._maxX > layer.widthInTiles) { + this._startX = layer.widthInTiles - this._maxX; + } + if(this._startY + this._maxY > layer.heightInTiles) { + this._startY = layer.heightInTiles - this._maxY; + } + // Finally get the offset to avoid the blocky movement + //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); + //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); + //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); + //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); + this._dx = 0; + this._dy = 0; + this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); + this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); + this._tx = this._dx; + this._ty = this._dy; + // Alpha + if(layer.texture.alpha !== 1) { + this._ga = layer.texture.context.globalAlpha; + layer.texture.context.globalAlpha = layer.texture.alpha; + } + for(var row = this._startY; row < this._startY + this._maxY; row++) { + this._columnData = layer.mapData[row]; + for(var tile = this._startX; tile < this._startX + this._maxX; tile++) { + if(layer.tileOffsets[this._columnData[tile]]) { + layer.texture.context.drawImage(layer.texture.texture, layer.tileOffsets[this._columnData[tile]].x, layer.tileOffsets[this._columnData[tile]].y, layer.tileWidth, layer.tileHeight, this._tx, this._ty, layer.tileWidth, layer.tileHeight); + } + this._tx += layer.tileWidth; + } + this._tx = this._dx; + this._ty += layer.tileHeight; + } + if(this._ga > -1) { + layer.texture.context.globalAlpha = this._ga; + } + } + return true; + }; + return TilemapRenderer; + })(); + Canvas.TilemapRenderer = TilemapRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + (function (Canvas) { + var CanvasRenderer = (function () { + function CanvasRenderer(game) { + this._c = 0; + this.game = game; + this.cameraRenderer = new Canvas.CameraRenderer(game); + this.groupRenderer = new Canvas.GroupRenderer(game); + this.spriteRenderer = new Canvas.SpriteRenderer(game); + this.geometryRenderer = new Canvas.GeometryRenderer(game); + this.scrollZoneRenderer = new Canvas.ScrollZoneRenderer(game); + this.tilemapRenderer = new Canvas.TilemapRenderer(game); + } + CanvasRenderer.prototype.render = function () { + this._cameraList = this.game.world.getAllCameras(); + this.renderCount = 0; + // Then iterate through world.group on them all (where not blacklisted, etc) + for(this._c = 0; this._c < this._cameraList.length; this._c++) { + if(this._cameraList[this._c].visible) { + this.cameraRenderer.preRender(this._cameraList[this._c]); + this.game.world.group.render(this._cameraList[this._c]); + this.cameraRenderer.postRender(this._cameraList[this._c]); + } + } + this.renderTotal = this.renderCount; + }; + CanvasRenderer.prototype.renderGameObject = function (camera, object) { + if(object.type == Phaser.Types.SPRITE || object.type == Phaser.Types.BUTTON) { + this.spriteRenderer.render(camera, object); + } else if(object.type == Phaser.Types.SCROLLZONE) { + this.scrollZoneRenderer.render(camera, object); + } else if(object.type == Phaser.Types.TILEMAP) { + this.tilemapRenderer.render(camera, object); + } + }; + return CanvasRenderer; + })(); + Canvas.CanvasRenderer = CanvasRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; })(Phaser || (Phaser = {})); /// /// @@ -17967,8 +18205,8 @@ var Phaser; if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } DebugUtils.start(x, y, color); DebugUtils.line('Camera ID: ' + camera.ID + ' (' + camera.screenView.width + ' x ' + camera.screenView.height + ')'); - DebugUtils.line('X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' rotation: ' + camera.transform.rotation); - DebugUtils.line('World X: ' + camera.worldView.x + ' World Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height + ' R: ' + camera.worldView.right + ' B: ' + camera.worldView.bottom); + DebugUtils.line('X: ' + camera.x + ' Y: ' + camera.y + ' Rotation: ' + camera.transform.rotation); + DebugUtils.line('WorldView X: ' + camera.worldView.x + ' Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height); DebugUtils.line('ScreenView X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' W: ' + camera.screenView.width + ' H: ' + camera.screenView.height); if(camera.worldBounds) { DebugUtils.line('Bounds: ' + camera.worldBounds.width + ' x ' + camera.worldBounds.height); @@ -18054,9 +18292,8 @@ var Phaser; DebugUtils.line('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1)); DebugUtils.line('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1)); DebugUtils.line('center x: ' + sprite.transform.center.x + ' y: ' + sprite.transform.center.y); - //line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height + ' bottom: ' + sprite.cameraView.bottom + ' right: ' + sprite.cameraView.right); DebugUtils.line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height); - DebugUtils.line('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite)); + DebugUtils.line('inCamera: ' + DebugUtils.game.renderer.spriteRenderer.inCamera(DebugUtils.game.camera, sprite)); }; DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) { if (typeof camera === "undefined") { camera = null; } @@ -18134,7 +18371,7 @@ var Phaser; /// /// /// -/// +/// /// /// /** @@ -18332,11 +18569,11 @@ var Phaser; Game.prototype.setRenderer = function (type) { switch(type) { case Phaser.Types.RENDERER_AUTO_DETECT: - this.renderer = new Phaser.HeadlessRenderer(this); + this.renderer = new Phaser.Renderer.Headless.HeadlessRenderer(this); break; case Phaser.Types.RENDERER_AUTO_DETECT: case Phaser.Types.RENDERER_CANVAS: - this.renderer = new Phaser.CanvasRenderer(this); + this.renderer = new Phaser.Renderer.Canvas.CanvasRenderer(this); break; // WebGL coming soon :) } diff --git a/build/phaser.d.ts b/build/phaser.d.ts index c9426c2f..d1455747 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -211,6 +211,11 @@ module Phaser { **/ public setTo(x: number, y: number, width: number, height: number): Rectangle; /** + * Runs Math.floor() on both the x and y values of this Rectangle. + * @method floor + **/ + public floor(): void; + /** * Copies the x, y, width and height properties from any given object to this Rectangle. * @method copyFrom * @param {any} source - The object to copy from. @@ -839,6 +844,28 @@ module Phaser { static RENDERER_HEADLESS: number; static RENDERER_CANVAS: number; static RENDERER_WEBGL: number; + static CAMERA_TYPE_ORTHOGRAPHIC: number; + static CAMERA_TYPE_ISOMETRIC: number; + /** + * Camera "follow" style preset: camera has no deadzone, just tracks the focus object directly. + * @type {number} + */ + static CAMERA_FOLLOW_LOCKON: number; + /** + * Camera "follow" style preset: camera deadzone is narrow but tall. + * @type {number} + */ + static CAMERA_FOLLOW_PLATFORMER: number; + /** + * Camera "follow" style preset: camera deadzone is a medium-size square around the focus object. + * @type {number} + */ + static CAMERA_FOLLOW_TOPDOWN: number; + /** + * Camera "follow" style preset: camera deadzone is a small square around the focus object. + * @type {number} + */ + static CAMERA_FOLLOW_TOPDOWN_TIGHT: number; static GROUP: number; static SPRITE: number; static GEOMSPRITE: number; @@ -849,7 +876,7 @@ module Phaser { static BUTTON: number; static GEOM_POINT: number; static GEOM_CIRCLE: number; - static GEOM_Rectangle: number; + static GEOM_RECTANGLE: number; static GEOM_LINE: number; static GEOM_POLYGON: number; static BODY_DISABLED: number; @@ -3052,6 +3079,10 @@ module Phaser.Display { */ constructor(parent); /** + * Camera Blacklist length + */ + private _blacklist; + /** * Private _width - use the width getter/setter instead */ private _width; @@ -3162,6 +3193,23 @@ module Phaser.Display { */ public crop: Rectangle; /** + * Hides an object from this Camera. Hidden objects are not rendered. + * + * @param object {Camera} The camera this object should ignore. + */ + public hideFromCamera(camera: Camera): void; + /** + * Returns true if this texture is hidden from rendering to the given camera, otherwise false. + */ + public isHidden(camera: Camera): bool; + /** + * Un-hides an object previously hidden to this Camera. + * The object must implement a public cameraBlacklist property. + * + * @param object {Sprite/Group} The object this camera should display. + */ + public showToCamera(camera: Camera): void; + /** * Updates the texture being used to render the Sprite. * Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture. */ @@ -4904,34 +4952,34 @@ module Phaser { */ public transform: Components.TransformManager; /** - * Camera "follow" style preset: camera has no deadzone, just tracks the focus object directly. - * @type {number} + * The scale of the Sprite. A value of 1 is original scale. 0.5 is half size. 2 is double the size. + * This is a reference to Sprite.transform.scale */ - static STYLE_LOCKON: number; + public scale: Vec2; /** - * Camera "follow" style preset: camera deadzone is narrow but tall. - * @type {number} + * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it. + * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored. + * This is a reference to Sprite.texture.crop + * @type {Phaser.Rectangle} */ - static STYLE_PLATFORMER: number; + public crop: Rectangle; /** - * Camera "follow" style preset: camera deadzone is a medium-size square around the focus object. - * @type {number} + * The origin of the Sprite around which rotation and positioning takes place. + * This is a reference to Sprite.transform.origin */ - static STYLE_TOPDOWN: number; + public origin: Vec2; /** - * Camera "follow" style preset: camera deadzone is a small square around the focus object. - * @type {number} + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. */ - static STYLE_TOPDOWN_TIGHT: number; + /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + public alpha : number; /** * Identity of this camera. */ public ID: number; /** - * Controls if this camera is clipped or not when rendering. You shouldn't usually set this value directly. - */ - public clip: bool; - /** * Camera view Rectangle in world coordinate. * @type {Rectangle} */ @@ -4956,11 +5004,6 @@ module Phaser { */ public deadzone: Rectangle; /** - * Disable the automatic camera canvas clipping when Camera is non-Stage sized. - * @type {Boolean} - */ - public disableClipping: bool; - /** * Whether this camera is visible or not. (default is true) * @type {boolean} */ @@ -5041,7 +5084,6 @@ module Phaser { * The value is automatically wrapped to be between 0 and 360. */ public rotation : number; - private checkClip(); } } /** @@ -5082,8 +5124,6 @@ module Phaser { * Helper for sort. */ private _sortOrder; - static CAMERA_TYPE_ORTHOGRAPHIC: number; - static CAMERA_TYPE_ISOMETRIC: number; /** * Currently used camera. */ @@ -5115,7 +5155,7 @@ module Phaser { * @param height {number} Height of the new camera. * @returns {Camera} The newly created camera object. */ - public addCamera(x: number, y: number, width: number, height: number, type?: number): Camera; + public addCamera(x: number, y: number, width: number, height: number): Camera; /** * Remove a new camera with its id. * @@ -9154,40 +9194,171 @@ module Phaser { module Phaser { interface IRenderer { render(); - renderGameObject(object); - renderSprite(camera: Camera, sprite: Sprite): bool; - renderScrollZone(camera: Camera, sprite: ScrollZone): bool; - renderCircle(camera: Camera, circle: Circle, context, outline?: bool, fill?: bool, lineColor?: string, fillColor?: string, lineWidth?: number); - preRenderGroup(camera: Camera, group: Group); - postRenderGroup(camera: Camera, group: Group); - preRenderCamera(camera: Camera); - postRenderCamera(camera: Camera); - inCamera(camera: Camera, sprite: Sprite): bool; + renderCount: number; + renderGameObject; + cameraRenderer; + groupRenderer; + spriteRenderer; + geometryRenderer; + scrollZoneRenderer; + tilemapRenderer; } } -module Phaser { +module Phaser.Renderer.Headless { class HeadlessRenderer implements IRenderer { constructor(game: Game); - private _game; + public game: Game; + public renderCount: number; public render(): void; - public inCamera(camera: Camera, sprite: Sprite): bool; - public renderGameObject(object): void; - public renderSprite(camera: Camera, sprite: Sprite): bool; - public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool; - public renderCircle(camera: Camera, circle: Circle, context, outline?: bool, fill?: bool, lineColor?: string, fillColor?: string, lineWidth?: number): bool; - public preRenderCamera(camera: Camera): void; - public postRenderCamera(camera: Camera): void; - public preRenderGroup(camera: Camera, group: Group): void; - public postRenderGroup(camera: Camera, group: Group): void; + public renderGameObject(camera, object): void; + public cameraRenderer; + public groupRenderer; + public spriteRenderer; + public geometryRenderer; + public scrollZoneRenderer; + public tilemapRenderer; } } -module Phaser { - class CanvasRenderer implements IRenderer { +module Phaser.Renderer.Canvas { + class CameraRenderer { constructor(game: Game); /** * The essential reference to the main game object */ - private _game; + public game: Game; + private _ga; + private _sx; + private _sy; + private _sw; + private _sh; + private _dx; + private _dy; + private _dw; + private _dh; + private _fx; + private _fy; + private _tx; + private _ty; + private _gac; + private _sin; + private _cos; + public preRender(camera: Camera): bool; + public postRender(camera: Camera): bool; + } +} +module Phaser.Renderer.Canvas { + class GeometryRenderer { + constructor(game: Game); + /** + * The essential reference to the main game object + */ + public game: Game; + private _ga; + private _sx; + private _sy; + private _sw; + private _sh; + private _dx; + private _dy; + private _dw; + private _dh; + private _fx; + private _fy; + private _sin; + private _cos; + public renderCircle(camera: Camera, circle: Circle, context, outline?: bool, fill?: bool, lineColor?: string, fillColor?: string, lineWidth?: number): bool; + } +} +module Phaser.Renderer.Canvas { + class GroupRenderer { + constructor(game: Game); + /** + * The essential reference to the main game object + */ + public game: Game; + private _ga; + private _sx; + private _sy; + private _sw; + private _sh; + private _dx; + private _dy; + private _dw; + private _dh; + private _fx; + private _fy; + private _sin; + private _cos; + public preRender(camera: Camera, group: Group): bool; + public postRender(camera: Camera, group: Group): void; + } +} +module Phaser.Renderer.Canvas { + class ScrollZoneRenderer { + constructor(game: Game); + /** + * The essential reference to the main game object + */ + public game: Game; + private _ga; + private _sx; + private _sy; + private _sw; + private _sh; + private _dx; + private _dy; + private _dw; + private _dh; + private _fx; + private _fy; + private _sin; + private _cos; + /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + public inCamera(camera: Camera, scrollZone: ScrollZone): bool; + public render(camera: Camera, scrollZone: ScrollZone): bool; + } +} +module Phaser.Renderer.Canvas { + class SpriteRenderer { + constructor(game: Game); + /** + * The essential reference to the main game object + */ + public game: Game; + private _ga; + private _sx; + private _sy; + private _sw; + private _sh; + private _dx; + private _dy; + private _dw; + private _dh; + /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + public inCamera(camera: Camera, sprite: Sprite): bool; + /** + * Render this sprite to specific camera. Called by game loop after update(). + * @param camera {Camera} Camera this sprite will be rendered to. + * @return {boolean} Return false if not rendered, otherwise return true. + */ + public render(camera: Camera, sprite: Sprite): bool; + } +} +module Phaser.Renderer.Canvas { + class TilemapRenderer { + constructor(game: Game); + /** + * The essential reference to the main game object + */ + public game: Game; private _ga; private _sx; private _sy; @@ -9208,42 +9379,30 @@ module Phaser { private _startX; private _startY; private _columnData; - private _cameraList; - private _camera; - private _groupLength; - private _count; - public renderTotal: number; - public render(): void; - public renderGameObject(object): void; - public preRenderGroup(camera: Camera, group: Group): bool; - public postRenderGroup(camera: Camera, group: Group): void; - /** - * Check whether this object is visible in a specific camera Rectangle. - * @param camera {Rectangle} The Rectangle you want to check. - * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. - */ - public inCamera(camera: Camera, sprite: Sprite): bool; - public inScreen(camera: Camera): bool; - /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - public preRenderCamera(camera: Camera): bool; - public postRenderCamera(camera: Camera): void; - public renderCircle(camera: Camera, circle: Circle, context, outline?: bool, fill?: bool, lineColor?: string, fillColor?: string, lineWidth?: number): bool; - /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - public renderSprite(camera: Camera, sprite: Sprite): bool; - public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool; /** * Render a tilemap to a specific camera. * @param camera {Camera} The camera this tilemap will be rendered to. */ - public renderTilemap(camera: Camera, tilemap: Tilemap): bool; + public render(camera: Camera, tilemap: Tilemap): bool; + } +} +module Phaser.Renderer.Canvas { + class CanvasRenderer implements IRenderer { + constructor(game: Game); + public game: Game; + private _c; + private _cameraList; + private _camera; + public cameraRenderer: CameraRenderer; + public groupRenderer: GroupRenderer; + public spriteRenderer: SpriteRenderer; + public geometryRenderer: GeometryRenderer; + public scrollZoneRenderer: ScrollZoneRenderer; + public tilemapRenderer: TilemapRenderer; + public renderCount: number; + public renderTotal: number; + public render(): void; + public renderGameObject(camera, object): void; } } /** diff --git a/build/phaser.js b/build/phaser.js index 4f6bf951..b2e5af22 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -327,6 +327,14 @@ var Phaser; this.height = height; return this; }; + Rectangle.prototype.floor = /** + * Runs Math.floor() on both the x and y values of this Rectangle. + * @method floor + **/ + function () { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + }; Rectangle.prototype.copyFrom = /** * Copies the x, y, width and height properties from any given object to this Rectangle. * @method copyFrom @@ -1267,6 +1275,12 @@ var Phaser; Types.RENDERER_HEADLESS = 1; Types.RENDERER_CANVAS = 2; Types.RENDERER_WEBGL = 3; + Types.CAMERA_TYPE_ORTHOGRAPHIC = 0; + Types.CAMERA_TYPE_ISOMETRIC = 1; + Types.CAMERA_FOLLOW_LOCKON = 0; + Types.CAMERA_FOLLOW_PLATFORMER = 1; + Types.CAMERA_FOLLOW_TOPDOWN = 2; + Types.CAMERA_FOLLOW_TOPDOWN_TIGHT = 3; Types.GROUP = 0; Types.SPRITE = 1; Types.GEOMSPRITE = 2; @@ -1277,7 +1291,7 @@ var Phaser; Types.BUTTON = 7; Types.GEOM_POINT = 0; Types.GEOM_CIRCLE = 1; - Types.GEOM_Rectangle = 2; + Types.GEOM_RECTANGLE = 2; Types.GEOM_LINE = 3; Types.GEOM_POLYGON = 4; Types.BODY_DISABLED = 0; @@ -2493,7 +2507,6 @@ var Phaser; this._pointerData[pointer.id].isDragged = true; if(this.dragFromCenter) { this._parent.transform.centerOn(pointer.worldX(), pointer.worldY()); - //this._dragPoint.setTo(this._parent.x - this._parent.transform.center.x, this._parent.y - this._parent.transform.center.y); this._dragPoint.setTo(this._parent.x - pointer.x, this._parent.y - pointer.y); } else { this._dragPoint.setTo(this._parent.x - pointer.x, this._parent.y - pointer.y); @@ -2977,7 +2990,6 @@ var Phaser; * Doesn't change the origin of the sprite. */ function (x, y) { - console.log('centerOn', x, y); this.parent.x = x + (this.parent.x - this.center.x); this.parent.y = y + (this.parent.y - this.center.y); this.setCache(); @@ -5113,8 +5125,8 @@ var Phaser; function updateCameraView(camera, sprite) { if(sprite.rotation == 0 || sprite.texture.renderRotation == false) { // Easy out - sprite.cameraView.x = Math.round(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); - sprite.cameraView.y = Math.round(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); + sprite.cameraView.x = Math.floor(sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x) - (sprite.width * sprite.transform.origin.x)); + sprite.cameraView.y = Math.floor(sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y) - (sprite.height * sprite.transform.origin.y)); sprite.cameraView.width = sprite.width; sprite.cameraView.height = sprite.height; } else { @@ -6138,7 +6150,40 @@ var Phaser; this._width = 16; this._height = 16; this.cameraBlacklist = []; + this._blacklist = 0; } + Texture.prototype.hideFromCamera = /** + * Hides an object from this Camera. Hidden objects are not rendered. + * + * @param object {Camera} The camera this object should ignore. + */ + function (camera) { + if(this.isHidden(camera) == false) { + this.cameraBlacklist.push(camera.ID); + this._blacklist++; + } + }; + Texture.prototype.isHidden = /** + * Returns true if this texture is hidden from rendering to the given camera, otherwise false. + */ + function (camera) { + if(this._blacklist && this.cameraBlacklist.indexOf(camera.ID) !== -1) { + return true; + } + return false; + }; + Texture.prototype.showToCamera = /** + * Un-hides an object previously hidden to this Camera. + * The object must implement a public cameraBlacklist property. + * + * @param object {Sprite/Group} The object this camera should display. + */ + function (camera) { + if(this.isHidden(camera)) { + this.cameraBlacklist.slice(this.cameraBlacklist.indexOf(camera.ID), 1); + this._blacklist--; + } + }; Texture.prototype.setTo = /** * Updates the texture being used to render the Sprite. * Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture. @@ -6360,7 +6405,7 @@ var Phaser; if(camera.isHidden(this) == true) { return; } - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; while(this._i < this.length) { this._member = this.members[this._i++]; @@ -6368,18 +6413,18 @@ var Phaser; if(this._member.type == Phaser.Types.GROUP) { this._member.render(camera); } else { - this.game.renderer.renderGameObject(this._member); + this.game.renderer.renderGameObject(camera, this._member); } } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); }; Group.prototype.directRender = /** * Calls render on all members of this Group regardless of their visible status and also ignores the camera blacklist. * Use this when the Group objects render to hidden canvases for example. */ function (camera) { - this.game.renderer.preRenderGroup(camera, this); + this.game.renderer.groupRenderer.preRender(camera, this); this._i = 0; while(this._i < this.length) { this._member = this.members[this._i++]; @@ -6391,7 +6436,7 @@ var Phaser; } } } - this.game.renderer.postRenderGroup(camera, this); + this.game.renderer.groupRenderer.postRender(camera, this); }; Object.defineProperty(Group.prototype, "maxSize", { get: /** @@ -9570,10 +9615,6 @@ var Phaser; function Camera(game, id, x, y, width, height) { this._target = null; /** - * Controls if this camera is clipped or not when rendering. You shouldn't usually set this value directly. - */ - this.clip = false; - /** * Camera worldBounds. * @type {Rectangle} */ @@ -9588,11 +9629,6 @@ var Phaser; */ this.deadzone = null; /** - * Disable the automatic camera canvas clipping when Camera is non-Stage sized. - * @type {Boolean} - */ - this.disableClipping = false; - /** * Whether this camera is visible or not. (default is true) * @type {boolean} */ @@ -9614,13 +9650,33 @@ var Phaser; this.plugins = new Phaser.PluginManager(this.game, this); this.transform = new Phaser.Components.TransformManager(this); this.texture = new Phaser.Display.Texture(this); - this.texture.opaque = false; - this.checkClip(); + // We create a hidden canvas for our camera the size of the game (we use the screenView to clip the render to the camera size) + this.texture.canvas = document.createElement('canvas'); + this.texture.canvas.width = width; + this.texture.canvas.height = height; + this.texture.context = this.texture.canvas.getContext('2d'); + // Handy proxies + this.scale = this.transform.scale; + this.alpha = this.texture.alpha; + this.origin = this.transform.origin; + this.crop = this.texture.crop; } - Camera.STYLE_LOCKON = 0; - Camera.STYLE_PLATFORMER = 1; - Camera.STYLE_TOPDOWN = 2; - Camera.STYLE_TOPDOWN_TIGHT = 3; + Object.defineProperty(Camera.prototype, "alpha", { + get: /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + function () { + return this.texture.alpha; + }, + set: /** + * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque. + */ + function (value) { + this.texture.alpha = value; + }, + enumerable: true, + configurable: true + }); Camera.prototype.hide = /** * Hides an object from this Camera. Hidden objects are not rendered. * The object must implement a public cameraBlacklist property. @@ -9628,9 +9684,7 @@ var Phaser; * @param object {Sprite/Group} The object this camera should ignore. */ function (object) { - if(this.isHidden(object) == false) { - object.texture['cameraBlacklist'].push(this.ID); - } + object.texture.hideFromCamera(this); }; Camera.prototype.isHidden = /** * Returns true if the object is hidden from this Camera. @@ -9638,7 +9692,7 @@ var Phaser; * @param object {Sprite/Group} The object to check. */ function (object) { - return (object.texture['cameraBlacklist'] && object.texture['cameraBlacklist'].length > 0 && object.texture['cameraBlacklist'].indexOf(this.ID) == -1); + return object.texture.isHidden(this); }; Camera.prototype.show = /** * Un-hides an object previously hidden to this Camera. @@ -9647,9 +9701,7 @@ var Phaser; * @param object {Sprite/Group} The object this camera should display. */ function (object) { - if(this.isHidden(object) == true) { - object.texture['cameraBlacklist'].slice(object.texture['cameraBlacklist'].indexOf(this.ID), 1); - } + object.texture.showToCamera(this); }; Camera.prototype.follow = /** * Tells this camera object what sprite to track. @@ -9657,24 +9709,24 @@ var Phaser; * @param [style] {number} Leverage one of the existing "deadzone" presets. If you use a custom deadzone, ignore this parameter and manually specify the deadzone after calling follow(). */ function (target, style) { - if (typeof style === "undefined") { style = Camera.STYLE_LOCKON; } + if (typeof style === "undefined") { style = Phaser.Types.CAMERA_FOLLOW_LOCKON; } this._target = target; var helper; switch(style) { - case Camera.STYLE_PLATFORMER: + case Phaser.Types.CAMERA_FOLLOW_PLATFORMER: var w = this.width / 8; var h = this.height / 3; this.deadzone = new Phaser.Rectangle((this.width - w) / 2, (this.height - h) / 2 - h * 0.25, w, h); break; - case Camera.STYLE_TOPDOWN: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN: helper = Math.max(this.width, this.height) / 4; this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_TOPDOWN_TIGHT: + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT: helper = Math.max(this.width, this.height) / 8; this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); break; - case Camera.STYLE_LOCKON: + case Phaser.Types.CAMERA_FOLLOW_LOCKON: default: this.deadzone = null; break; @@ -9770,6 +9822,7 @@ var Phaser; this.worldView.y = (this.worldBounds.bottom - this.height) + 1; } } + this.worldView.floor(); this.plugins.update(); }; Camera.prototype.postUpdate = /** @@ -9785,15 +9838,16 @@ var Phaser; this.worldView.x = this.worldBounds.left; } if(this.worldView.x > this.worldBounds.right - this.width) { - this.worldView.x = (this.worldBounds.right - this.width) + 1; + this.worldView.x = this.worldBounds.right - this.width; } if(this.worldView.y < this.worldBounds.top) { this.worldView.y = this.worldBounds.top; } if(this.worldView.y > this.worldBounds.bottom - this.height) { - this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + this.worldView.y = this.worldBounds.bottom - this.height; } } + this.worldView.floor(); this.plugins.postUpdate(); }; Camera.prototype.destroy = /** @@ -9830,6 +9884,9 @@ var Phaser; set: function (value) { this.screenView.width = value; this.worldView.width = value; + if(value !== this.texture.canvas.width) { + this.texture.canvas.width = value; + } }, enumerable: true, configurable: true @@ -9841,6 +9898,9 @@ var Phaser; set: function (value) { this.screenView.height = value; this.worldView.height = value; + if(value !== this.texture.canvas.height) { + this.texture.canvas.height = value; + } }, enumerable: true, configurable: true @@ -9848,14 +9908,18 @@ var Phaser; Camera.prototype.setPosition = function (x, y) { this.screenView.x = x; this.screenView.y = y; - this.checkClip(); }; Camera.prototype.setSize = function (width, height) { this.screenView.width = width * this.transform.scale.x; this.screenView.height = height * this.transform.scale.y; this.worldView.width = width; this.worldView.height = height; - this.checkClip(); + if(width !== this.texture.canvas.width) { + this.texture.canvas.width = width; + } + if(height !== this.texture.canvas.height) { + this.texture.canvas.height = height; + } }; Object.defineProperty(Camera.prototype, "rotation", { get: /** @@ -9874,13 +9938,6 @@ var Phaser; enumerable: true, configurable: true }); - Camera.prototype.checkClip = function () { - if(this.screenView.x != 0 || this.screenView.y != 0 || this.screenView.width < this.game.stage.width || this.screenView.height < this.game.stage.height) { - this.clip = true; - } else { - this.clip = false; - } - }; return Camera; })(); Phaser.Camera = Camera; @@ -9919,8 +9976,6 @@ var Phaser; this.defaultCamera = this.addCamera(x, y, width, height); this.current = this.defaultCamera; } - CameraManager.CAMERA_TYPE_ORTHOGRAPHIC = 0; - CameraManager.CAMERA_TYPE_ISOMETRIC = 1; CameraManager.prototype.getAll = /** * Get all the cameras. * @@ -9954,8 +10009,7 @@ var Phaser; * @param height {number} Height of the new camera. * @returns {Camera} The newly created camera object. */ - function (x, y, width, height, type) { - if (typeof type === "undefined") { type = CameraManager.CAMERA_TYPE_ORTHOGRAPHIC; } + function (x, y, width, height) { var newCam = new Phaser.Camera(this._game, this._cameraInstance, x, y, width, height); this._cameras.push(newCam); this._cameraInstance++; @@ -14085,6 +14139,7 @@ var Phaser; */ function () { this.scale.update(); + this.context.setTransform(1, 0, 0, 1, 0, 0); if(this.clear || (this._game.paused && this.disablePauseScreen == false)) { if(this.patchAndroidClearRectBug) { this.context.fillStyle = 'rgb(0,0,0)'; @@ -17261,629 +17316,812 @@ var Phaser; })(); Phaser.InputManager = InputManager; })(Phaser || (Phaser = {})); -/// -/// -/// var Phaser; (function (Phaser) { - var HeadlessRenderer = (function () { - function HeadlessRenderer(game) { - this._game = game; - } - HeadlessRenderer.prototype.render = function () { - }; - HeadlessRenderer.prototype.inCamera = function (camera, sprite) { - return true; - }; - HeadlessRenderer.prototype.renderGameObject = function (object) { - }; - HeadlessRenderer.prototype.renderSprite = function (camera, sprite) { - return true; - }; - HeadlessRenderer.prototype.renderScrollZone = function (camera, scrollZone) { - return true; - }; - HeadlessRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { - if (typeof outline === "undefined") { outline = true; } - if (typeof fill === "undefined") { fill = true; } - if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } - if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } - if (typeof lineWidth === "undefined") { lineWidth = 1; } - return true; - }; - HeadlessRenderer.prototype.preRenderCamera = function (camera) { - }; - HeadlessRenderer.prototype.postRenderCamera = function (camera) { - }; - HeadlessRenderer.prototype.preRenderGroup = function (camera, group) { - }; - HeadlessRenderer.prototype.postRenderGroup = function (camera, group) { - }; - return HeadlessRenderer; - })(); - Phaser.HeadlessRenderer = HeadlessRenderer; + (function (Renderer) { + /// + /// + /// + (function (Headless) { + var HeadlessRenderer = (function () { + function HeadlessRenderer(game) { + this.game = game; + } + HeadlessRenderer.prototype.render = function () { + // Nothing, headless remember? + }; + HeadlessRenderer.prototype.renderGameObject = function (camera, object) { + // Nothing, headless remember? + }; + return HeadlessRenderer; + })(); + Headless.HeadlessRenderer = HeadlessRenderer; + })(Renderer.Headless || (Renderer.Headless = {})); + var Headless = Renderer.Headless; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; })(Phaser || (Phaser = {})); -/// -/// -/// -/// -/// var Phaser; (function (Phaser) { - var CanvasRenderer = (function () { - function CanvasRenderer(game) { - // Local rendering related temp vars to help avoid gc spikes through var creation - this._ga = 1; - this._sx = 0; - this._sy = 0; - this._sw = 0; - this._sh = 0; - this._dx = 0; - this._dy = 0; - this._dw = 0; - this._dh = 0; - this._fx = 1; - this._fy = 1; - this._tx = 0; - this._ty = 0; - this._sin = 0; - this._cos = 1; - this._maxX = 0; - this._maxY = 0; - this._startX = 0; - this._startY = 0; - this._game = game; - } - CanvasRenderer.prototype.render = function () { - // Get a list of all the active cameras - this._cameraList = this._game.world.getAllCameras(); - this._count = 0; - // Then iterate through world.group on them all (where not blacklisted, etc) - for(var c = 0; c < this._cameraList.length; c++) { - this._camera = this._cameraList[c]; - this.preRenderCamera(this._camera); - this._game.world.group.render(this._camera); - this.postRenderCamera(this._camera); - } - this.renderTotal = this._count; - }; - CanvasRenderer.prototype.renderGameObject = function (object) { - if(object.type == Phaser.Types.SPRITE || object.type == Phaser.Types.BUTTON) { - this.renderSprite(this._camera, object); - } else if(object.type == Phaser.Types.SCROLLZONE) { - this.renderScrollZone(this._camera, object); - } else if(object.type == Phaser.Types.TILEMAP) { - this.renderTilemap(this._camera, object); - } - }; - CanvasRenderer.prototype.preRenderGroup = function (camera, group) { - if(camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) { - return false; - } - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = group.texture.width; - this._sh = group.texture.height; - this._fx = group.transform.scale.x; - this._fy = group.transform.scale.y; - this._sin = 0; - this._cos = 1; - //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); - //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); - this._dx = 0; - this._dy = 0; - this._dw = group.texture.width; - this._dh = group.texture.height; - // Global Composite Ops - if(group.texture.globalCompositeOperation) { - group.texture.context.save(); - group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; - } - // Alpha - if(group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) { - this._ga = group.texture.context.globalAlpha; - group.texture.context.globalAlpha = group.texture.alpha; - } - // Flip X - if(group.texture.flippedX) { - this._fx = -group.transform.scale.x; - } - // Flip Y - if(group.texture.flippedY) { - this._fy = -group.transform.scale.y; - } - // Rotation and Flipped - if(group.modified) { - if(group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) { - this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); - this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var CameraRenderer = (function () { + function CameraRenderer(game) { + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._tx = 0; + this._ty = 0; + this._gac = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - group.texture.context.save(); - group.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + group.transform.skew.x, -(this._sin * this._fy) + group.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -group.transform.origin.x; - this._dy = -group.transform.origin.y; - } else { - if(!group.transform.origin.equals(0)) { - this._dx -= group.transform.origin.x; - this._dy -= group.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - if(group.texture.opaque) { - group.texture.context.fillStyle = group.texture.backgroundColor; - group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(group.texture.loaded) { - group.texture.context.drawImage(group.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - return true; - }; - CanvasRenderer.prototype.postRenderGroup = function (camera, group) { - if(group.modified || group.texture.globalCompositeOperation) { - group.texture.context.restore(); - } - // This could have been over-written by a sprite, need to store elsewhere - if(this._ga > -1) { - group.texture.context.globalAlpha = this._ga; - } - }; - CanvasRenderer.prototype.inCamera = /** - * Check whether this object is visible in a specific camera Rectangle. - * @param camera {Rectangle} The Rectangle you want to check. - * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. - */ - function (camera, sprite) { - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if(sprite.transform.scrollFactor.equals(0)) { - return true; - } - return Phaser.RectangleUtils.intersects(sprite.cameraView, camera.screenView); - }; - CanvasRenderer.prototype.inScreen = function (camera) { - return true; - }; - CanvasRenderer.prototype.preRenderCamera = /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - function (camera) { - if(camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1 || this.inScreen(camera) == false) { - return false; - } - camera.plugins.preRender(); - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = camera.width; - this._sh = camera.height; - this._fx = camera.transform.scale.x; - this._fy = camera.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x; - this._dy = camera.screenView.y; - this._dw = camera.width; - this._dh = camera.height; - // Global Composite Ops - if(camera.texture.globalCompositeOperation) { - camera.texture.context.save(); - camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; - } - // Alpha - if(camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) { - this._ga = camera.texture.context.globalAlpha; - camera.texture.context.globalAlpha = camera.texture.alpha; - } - // Sprite Flip X - if(camera.texture.flippedX) { - this._fx = -camera.transform.scale.x; - } - // Sprite Flip Y - if(camera.texture.flippedY) { - this._fy = -camera.transform.scale.y; - } - // Rotation and Flipped - if(camera.modified) { - if(camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) { - this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); - } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - camera.texture.context.save(); - camera.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + camera.transform.skew.x, -(this._sin * this._fy) + camera.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -camera.transform.origin.x; - this._dy = -camera.transform.origin.y; - } else { - if(!camera.transform.origin.equals(0)) { - this._dx -= camera.transform.origin.x; - this._dy -= camera.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - // Clip the camera so we don't get sprites appearing outside the edges - if(camera.clip == true && camera.disableClipping == false) { - camera.texture.context.beginPath(); - camera.texture.context.rect(camera.screenView.x, camera.screenView.x, camera.screenView.width, camera.screenView.height); - camera.texture.context.closePath(); - camera.texture.context.clip(); - } - if(camera.texture.opaque) { - camera.texture.context.fillStyle = camera.texture.backgroundColor; - camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(camera.texture.loaded) { - camera.texture.context.drawImage(camera.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - camera.plugins.render(); - return true; - }; - CanvasRenderer.prototype.postRenderCamera = function (camera) { - if(camera.modified || camera.texture.globalCompositeOperation) { - camera.texture.context.restore(); - } - // This could have been over-written by a sprite, need to store elsewhere - if(this._ga > -1) { - camera.texture.context.globalAlpha = this._ga; - } - camera.plugins.postRender(); - }; - CanvasRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { - if (typeof outline === "undefined") { outline = false; } - if (typeof fill === "undefined") { fill = true; } - if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } - if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } - if (typeof lineWidth === "undefined") { lineWidth = 1; } - this._count++; - // Reset our temp vars - this._sx = 0; - this._sy = 0; - this._sw = circle.diameter; - this._sh = circle.diameter; - this._fx = 1; - this._fy = 1; - this._sin = 0; - this._cos = 1; - this._dx = camera.screenView.x + circle.x - camera.worldView.x; - this._dy = camera.screenView.y + circle.y - camera.worldView.y; - this._dw = circle.diameter; - this._dh = circle.diameter; - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - this._game.stage.saveCanvasValues(); - context.save(); - context.lineWidth = lineWidth; - context.strokeStyle = lineColor; - context.fillStyle = fillColor; - context.beginPath(); - context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); - context.closePath(); - if(outline) { - //context.stroke(); - } - if(fill) { - context.fill(); - } - context.restore(); - this._game.stage.restoreCanvasValues(); - return true; - }; - CanvasRenderer.prototype.renderSprite = /** - * Render this sprite to specific camera. Called by game loop after update(). - * @param camera {Camera} Camera this sprite will be rendered to. - * @return {boolean} Return false if not rendered, otherwise return true. - */ - function (camera, sprite) { - Phaser.SpriteUtils.updateCameraView(camera, sprite); - if(sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { - return false; - } - sprite.renderOrderID = this._count; - this._count++; - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = sprite.texture.width; - this._sh = sprite.texture.height; - this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); - this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); - this._dw = sprite.texture.width; - this._dh = sprite.texture.height; - if(sprite.animations.currentFrame !== null) { - this._sx = sprite.animations.currentFrame.x; - this._sy = sprite.animations.currentFrame.y; - if(sprite.animations.currentFrame.trimmed) { - this._dx += sprite.animations.currentFrame.spriteSourceSizeX; - this._dy += sprite.animations.currentFrame.spriteSourceSizeY; - this._sw = sprite.animations.currentFrame.spriteSourceSizeW; - this._sh = sprite.animations.currentFrame.spriteSourceSizeH; - this._dw = sprite.animations.currentFrame.spriteSourceSizeW; - this._dh = sprite.animations.currentFrame.spriteSourceSizeH; - } - } - if(sprite.modified) { - sprite.texture.context.save(); - sprite.texture.context.setTransform(sprite.transform.local.data[0], // scale x - sprite.transform.local.data[3], // skew x - sprite.transform.local.data[1], // skew y - sprite.transform.local.data[4], // scale y - this._dx, // translate x - this._dy); - // translate y - this._dx = sprite.transform.origin.x * -this._dw; - this._dy = sprite.transform.origin.y * -this._dh; - } else { - this._dx -= (this._dw * sprite.transform.origin.x); - this._dy -= (this._dh * sprite.transform.origin.y); - } - if(sprite.crop) { - this._sx += sprite.crop.x * sprite.transform.scale.x; - this._sy += sprite.crop.y * sprite.transform.scale.y; - this._sw = sprite.crop.width * sprite.transform.scale.x; - this._sh = sprite.crop.height * sprite.transform.scale.y; - this._dx += sprite.crop.x * sprite.transform.scale.x; - this._dy += sprite.crop.y * sprite.transform.scale.y; - this._dw = sprite.crop.width * sprite.transform.scale.x; - this._dh = sprite.crop.height * sprite.transform.scale.y; - //this._sx += sprite.crop.x; - //this._sy += sprite.crop.y; - //this._sw = sprite.crop.width; - //this._sh = sprite.crop.height; - //this._dx += sprite.crop.x; - //this._dy += sprite.crop.y; - //this._dw = sprite.crop.width; - //this._dh = sprite.crop.height; - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { - return false; - } - // Global Composite Ops - if(sprite.texture.globalCompositeOperation) { - sprite.texture.context.save(); - sprite.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; - } - // Alpha - if(sprite.texture.alpha !== 1 && sprite.texture.context.globalAlpha != sprite.texture.alpha) { - this._ga = sprite.texture.context.globalAlpha; - sprite.texture.context.globalAlpha = sprite.texture.alpha; - } - if(sprite.texture.opaque) { - sprite.texture.context.fillStyle = sprite.texture.backgroundColor; - sprite.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); - } - if(sprite.texture.loaded) { - sprite.texture.context.drawImage(sprite.texture.texture, // Source Image - this._sx, // Source X (location within the source image) - this._sy, // Source Y - this._sw, // Source Width - this._sh, // Source Height - this._dx, // Destination X (where on the canvas it'll be drawn) - this._dy, // Destination Y - this._dw, // Destination Width (always same as Source Width unless scaled) - this._dh); - // Destination Height (always same as Source Height unless scaled) - } - if(sprite.modified || sprite.texture.globalCompositeOperation) { - sprite.texture.context.restore(); - } - if(this._ga > -1) { - sprite.texture.context.globalAlpha = this._ga; - } - return true; - }; - CanvasRenderer.prototype.renderScrollZone = function (camera, scrollZone) { - if(scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) { - return false; - } - this._count++; - // Reset our temp vars - this._ga = -1; - this._sx = 0; - this._sy = 0; - this._sw = scrollZone.width; - this._sh = scrollZone.height; - this._fx = scrollZone.transform.scale.x; - this._fy = scrollZone.transform.scale.y; - this._sin = 0; - this._cos = 1; - this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); - this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); - this._dw = scrollZone.width; - this._dh = scrollZone.height; - // Alpha - if(scrollZone.texture.alpha !== 1) { - this._ga = scrollZone.texture.context.globalAlpha; - scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; - } - // Sprite Flip X - if(scrollZone.texture.flippedX) { - this._fx = -scrollZone.transform.scale.x; - } - // Sprite Flip Y - if(scrollZone.texture.flippedY) { - this._fy = -scrollZone.transform.scale.y; - } - // Rotation and Flipped - if(scrollZone.modified) { - if(scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) { - this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); - } - // setTransform(a, b, c, d, e, f); - // a = scale x - // b = skew x - // c = skew y - // d = scale y - // e = translate x - // f = translate y - scrollZone.texture.context.save(); - scrollZone.texture.context.setTransform(this._cos * this._fx, (this._sin * this._fx) + scrollZone.transform.skew.x, -(this._sin * this._fy) + scrollZone.transform.skew.y, this._cos * this._fy, this._dx, this._dy); - this._dx = -scrollZone.transform.origin.x; - this._dy = -scrollZone.transform.origin.y; - } else { - if(!scrollZone.transform.origin.equals(0)) { - this._dx -= scrollZone.transform.origin.x; - this._dy -= scrollZone.transform.origin.y; - } - } - this._sx = Math.floor(this._sx); - this._sy = Math.floor(this._sy); - this._sw = Math.floor(this._sw); - this._sh = Math.floor(this._sh); - this._dx = Math.floor(this._dx); - this._dy = Math.floor(this._dy); - this._dw = Math.floor(this._dw); - this._dh = Math.floor(this._dh); - for(var i = 0; i < scrollZone.regions.length; i++) { - if(scrollZone.texture.isDynamic) { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } else { - scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); - } - } - if(scrollZone.modified) { - scrollZone.texture.context.restore(); - } - if(this._ga > -1) { - scrollZone.texture.context.globalAlpha = this._ga; - } - return true; - }; - CanvasRenderer.prototype.renderTilemap = /** - * Render a tilemap to a specific camera. - * @param camera {Camera} The camera this tilemap will be rendered to. - */ - function (camera, tilemap) { - // Loop through the layers - for(var i = 0; i < tilemap.layers.length; i++) { - var layer = tilemap.layers[i]; - if(layer.visible == false || layer.alpha < 0.1) { - continue; - } - // Work out how many tiles we can fit into our camera and round it up for the edges - this._maxX = this._game.math.ceil(camera.width / layer.tileWidth) + 1; - this._maxY = this._game.math.ceil(camera.height / layer.tileHeight) + 1; - // And now work out where in the tilemap the camera actually is - this._startX = this._game.math.floor(camera.worldView.x / layer.tileWidth); - this._startY = this._game.math.floor(camera.worldView.y / layer.tileHeight); - // Tilemap bounds check - if(this._startX < 0) { - this._startX = 0; - } - if(this._startY < 0) { - this._startY = 0; - } - if(this._maxX > layer.widthInTiles) { - this._maxX = layer.widthInTiles; - } - if(this._maxY > layer.heightInTiles) { - this._maxY = layer.heightInTiles; - } - if(this._startX + this._maxX > layer.widthInTiles) { - this._startX = layer.widthInTiles - this._maxX; - } - if(this._startY + this._maxY > layer.heightInTiles) { - this._startY = layer.heightInTiles - this._maxY; - } - // Finally get the offset to avoid the blocky movement - //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); - //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); - //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); - //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); - this._dx = 0; - this._dy = 0; - this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); - this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); - this._tx = this._dx; - this._ty = this._dy; - // Alpha - if(layer.texture.alpha !== 1) { - this._ga = layer.texture.context.globalAlpha; - layer.texture.context.globalAlpha = layer.texture.alpha; - } - for(var row = this._startY; row < this._startY + this._maxY; row++) { - this._columnData = layer.mapData[row]; - for(var tile = this._startX; tile < this._startX + this._maxX; tile++) { - if(layer.tileOffsets[this._columnData[tile]]) { - layer.texture.context.drawImage(layer.texture.texture, layer.tileOffsets[this._columnData[tile]].x, layer.tileOffsets[this._columnData[tile]].y, layer.tileWidth, layer.tileHeight, this._tx, this._ty, layer.tileWidth, layer.tileHeight); - } - this._tx += layer.tileWidth; + CameraRenderer.prototype.preRender = function (camera) { + if(camera.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) { + return false; } - this._tx = this._dx; - this._ty += layer.tileHeight; + camera.texture.context.clearRect(0, 0, camera.width, camera.height); + // Alpha + if(camera.texture.alpha !== 1 && camera.texture.context.globalAlpha != camera.texture.alpha) { + this._ga = camera.texture.context.globalAlpha; + camera.texture.context.globalAlpha = camera.texture.alpha; + } + if(camera.texture.opaque) { + camera.texture.context.fillStyle = camera.texture.backgroundColor; + camera.texture.context.fillRect(0, 0, camera.width, camera.height); + } + //if (camera.texture.loaded) + //{ + // camera.texture.context.drawImage( + // camera.texture.texture, // Source Image + // this._sx, // Source X (location within the source image) + // this._sy, // Source Y + // this._sw, // Source Width + // this._sh, // Source Height + // 0, // Destination X (where on the canvas it'll be drawn) + // 0, // Destination Y + // this._dw, // Destination Width (always same as Source Width unless scaled) + // this._dh // Destination Height (always same as Source Height unless scaled) + // ); + //} + // Global Composite Ops + if(camera.texture.globalCompositeOperation) { + camera.texture.context.globalCompositeOperation = camera.texture.globalCompositeOperation; + } + camera.plugins.preRender(); + }; + CameraRenderer.prototype.postRender = function (camera) { + // This could have been over-written by a sprite, need to store elsewhere + if(this._ga > -1) { + camera.texture.context.globalAlpha = this._ga; + } + camera.plugins.postRender(); + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = camera.width; + this._sh = camera.height; + this._fx = camera.transform.scale.x; + this._fy = camera.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x; + this._dy = camera.screenView.y; + this._dw = camera.width; + this._dh = camera.height; + this.game.stage.context.save(); + // Flip X + if(camera.texture.flippedX) { + this._fx = -camera.transform.scale.x; + } + // Flip Y + if(camera.texture.flippedY) { + this._fy = -camera.transform.scale.y; + } + // Rotation and Flipped + if(camera.modified) { + if(camera.transform.rotation !== 0 || camera.transform.rotationOffset !== 0) { + this._sin = Math.sin(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + this._cos = Math.cos(camera.game.math.degreesToRadians(camera.transform.rotationOffset + camera.transform.rotation)); + } + this.game.stage.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + camera.transform.skew.x, // skew x + -(this._sin * this._fy) + camera.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = camera.transform.origin.x * -this._dw; + this._dy = camera.transform.origin.y * -this._dh; + } else { + this._dx -= (this._dw * camera.transform.origin.x); + this._dy -= (this._dh * camera.transform.origin.y); + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { + this.game.stage.context.restore(); + return false; + } + this.game.stage.context.drawImage(camera.texture.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + this.game.stage.context.restore(); + }; + return CameraRenderer; + })(); + Canvas.CameraRenderer = CameraRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var GeometryRenderer = (function () { + function GeometryRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - if(this._ga > -1) { - layer.texture.context.globalAlpha = this._ga; + GeometryRenderer.prototype.renderCircle = function (camera, circle, context, outline, fill, lineColor, fillColor, lineWidth) { + if (typeof outline === "undefined") { outline = false; } + if (typeof fill === "undefined") { fill = true; } + if (typeof lineColor === "undefined") { lineColor = 'rgb(0,255,0)'; } + if (typeof fillColor === "undefined") { fillColor = 'rgba(0,100,0.0.3)'; } + if (typeof lineWidth === "undefined") { lineWidth = 1; } + // Reset our temp vars + this._sx = 0; + this._sy = 0; + this._sw = circle.diameter; + this._sh = circle.diameter; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this._dx = camera.screenView.x + circle.x - camera.worldView.x; + this._dy = camera.screenView.y + circle.y - camera.worldView.y; + this._dw = circle.diameter; + this._dh = circle.diameter; + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + this.game.stage.saveCanvasValues(); + context.save(); + context.lineWidth = lineWidth; + context.strokeStyle = lineColor; + context.fillStyle = fillColor; + context.beginPath(); + context.arc(this._dx, this._dy, circle.radius, 0, Math.PI * 2); + context.closePath(); + if(outline) { + //context.stroke(); + } + if(fill) { + context.fill(); + } + context.restore(); + this.game.stage.restoreCanvasValues(); + return true; + }; + return GeometryRenderer; + })(); + Canvas.GeometryRenderer = GeometryRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var GroupRenderer = (function () { + function GroupRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; } - } - return true; - }; - return CanvasRenderer; - })(); - Phaser.CanvasRenderer = CanvasRenderer; + GroupRenderer.prototype.preRender = function (camera, group) { + if(group.visible == false || camera.transform.scale.x == 0 || camera.transform.scale.y == 0 || camera.texture.alpha < 0.1) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = group.texture.width; + this._sh = group.texture.height; + this._fx = group.transform.scale.x; + this._fy = group.transform.scale.y; + this._sin = 0; + this._cos = 1; + //this._dx = (camera.screenView.x * camera.scrollFactor.x) + camera.frameBounds.x - (camera.worldView.x * camera.scrollFactor.x); + //this._dy = (camera.screenView.y * camera.scrollFactor.y) + camera.frameBounds.y - (camera.worldView.y * camera.scrollFactor.y); + this._dx = 0; + this._dy = 0; + this._dw = group.texture.width; + this._dh = group.texture.height; + // Global Composite Ops + if(group.texture.globalCompositeOperation) { + group.texture.context.save(); + group.texture.context.globalCompositeOperation = group.texture.globalCompositeOperation; + } + // Alpha + if(group.texture.alpha !== 1 && group.texture.context.globalAlpha !== group.texture.alpha) { + this._ga = group.texture.context.globalAlpha; + group.texture.context.globalAlpha = group.texture.alpha; + } + // Flip X + if(group.texture.flippedX) { + this._fx = -group.transform.scale.x; + } + // Flip Y + if(group.texture.flippedY) { + this._fy = -group.transform.scale.y; + } + // Rotation and Flipped + if(group.modified) { + if(group.transform.rotation !== 0 || group.transform.rotationOffset !== 0) { + this._sin = Math.sin(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + this._cos = Math.cos(group.game.math.degreesToRadians(group.transform.rotationOffset + group.transform.rotation)); + } + group.texture.context.save(); + group.texture.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + group.transform.skew.x, // skew x + -(this._sin * this._fy) + group.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = -group.transform.origin.x; + this._dy = -group.transform.origin.y; + } else { + if(!group.transform.origin.equals(0)) { + this._dx -= group.transform.origin.x; + this._dy -= group.transform.origin.y; + } + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(group.texture.opaque) { + group.texture.context.fillStyle = group.texture.backgroundColor; + group.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + if(group.texture.loaded) { + group.texture.context.drawImage(group.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + } + return true; + }; + GroupRenderer.prototype.postRender = function (camera, group) { + if(group.modified || group.texture.globalCompositeOperation) { + group.texture.context.restore(); + } + if(this._ga > -1) { + group.texture.context.globalAlpha = this._ga; + } + }; + return GroupRenderer; + })(); + Canvas.GroupRenderer = GroupRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var ScrollZoneRenderer = (function () { + function ScrollZoneRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._sin = 0; + this._cos = 1; + this.game = game; + } + ScrollZoneRenderer.prototype.inCamera = /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + function (camera, scrollZone) { + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if(scrollZone.transform.scrollFactor.equals(0)) { + return true; + } + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + }; + ScrollZoneRenderer.prototype.render = function (camera, scrollZone) { + if(scrollZone.transform.scale.x == 0 || scrollZone.transform.scale.y == 0 || scrollZone.texture.alpha < 0.1 || this.inCamera(camera, scrollZone) == false) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = scrollZone.width; + this._sh = scrollZone.height; + this._fx = scrollZone.transform.scale.x; + this._fy = scrollZone.transform.scale.y; + this._sin = 0; + this._cos = 1; + this._dx = (camera.screenView.x * scrollZone.transform.scrollFactor.x) + scrollZone.x - (camera.worldView.x * scrollZone.transform.scrollFactor.x); + this._dy = (camera.screenView.y * scrollZone.transform.scrollFactor.y) + scrollZone.y - (camera.worldView.y * scrollZone.transform.scrollFactor.y); + this._dw = scrollZone.width; + this._dh = scrollZone.height; + // Alpha + if(scrollZone.texture.alpha !== 1) { + this._ga = scrollZone.texture.context.globalAlpha; + scrollZone.texture.context.globalAlpha = scrollZone.texture.alpha; + } + // Sprite Flip X + if(scrollZone.texture.flippedX) { + this._fx = -scrollZone.transform.scale.x; + } + // Sprite Flip Y + if(scrollZone.texture.flippedY) { + this._fy = -scrollZone.transform.scale.y; + } + // Rotation and Flipped + if(scrollZone.modified) { + if(scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.transform.rotationOffset !== 0)) { + this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.transform.rotationOffset + scrollZone.rotation)); + } + scrollZone.texture.context.save(); + scrollZone.texture.context.setTransform(this._cos * this._fx, // scale x + (this._sin * this._fx) + scrollZone.transform.skew.x, // skew x + -(this._sin * this._fy) + scrollZone.transform.skew.y, // skew y + this._cos * this._fy, // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = -scrollZone.transform.origin.x; + this._dy = -scrollZone.transform.origin.y; + } else { + if(!scrollZone.transform.origin.equals(0)) { + this._dx -= scrollZone.transform.origin.x; + this._dy -= scrollZone.transform.origin.y; + } + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + for(var i = 0; i < scrollZone.regions.length; i++) { + if(scrollZone.texture.isDynamic) { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } else { + scrollZone.regions[i].render(scrollZone.texture.context, scrollZone.texture.texture, this._dx, this._dy, this._dw, this._dh); + } + } + if(scrollZone.modified) { + scrollZone.texture.context.restore(); + } + if(this._ga > -1) { + scrollZone.texture.context.globalAlpha = this._ga; + } + this.game.renderer.renderCount++; + return true; + }; + return ScrollZoneRenderer; + })(); + Canvas.ScrollZoneRenderer = ScrollZoneRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var SpriteRenderer = (function () { + function SpriteRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + //private _c: number = 0; + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this.game = game; + } + SpriteRenderer.prototype.inCamera = /** + * Check whether this object is visible in a specific camera Rectangle. + * @param camera {Rectangle} The Rectangle you want to check. + * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. + */ + function (camera, sprite) { + // Object fixed in place regardless of the camera scrolling? Then it's always visible + if(sprite.transform.scrollFactor.equals(0)) { + return true; + } + //return RectangleUtils.intersects(sprite.cameraView, camera.screenView); + return true; + }; + SpriteRenderer.prototype.render = /** + * Render this sprite to specific camera. Called by game loop after update(). + * @param camera {Camera} Camera this sprite will be rendered to. + * @return {boolean} Return false if not rendered, otherwise return true. + */ + function (camera, sprite) { + Phaser.SpriteUtils.updateCameraView(camera, sprite); + if(sprite.transform.scale.x == 0 || sprite.transform.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { + return false; + } + // Reset our temp vars + this._ga = -1; + this._sx = 0; + this._sy = 0; + this._sw = sprite.texture.width; + this._sh = sprite.texture.height; + //this._dx = camera.screenView.x + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //this._dy = camera.screenView.y + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dx = sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + this._dy = sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + this._dw = sprite.texture.width; + this._dh = sprite.texture.height; + if(sprite.animations.currentFrame !== null) { + this._sx = sprite.animations.currentFrame.x; + this._sy = sprite.animations.currentFrame.y; + if(sprite.animations.currentFrame.trimmed) { + this._dx += sprite.animations.currentFrame.spriteSourceSizeX; + this._dy += sprite.animations.currentFrame.spriteSourceSizeY; + this._sw = sprite.animations.currentFrame.spriteSourceSizeW; + this._sh = sprite.animations.currentFrame.spriteSourceSizeH; + this._dw = sprite.animations.currentFrame.spriteSourceSizeW; + this._dh = sprite.animations.currentFrame.spriteSourceSizeH; + } + } + if(sprite.modified) { + camera.texture.context.save(); + camera.texture.context.setTransform(sprite.transform.local.data[0], // scale x + sprite.transform.local.data[3], // skew x + sprite.transform.local.data[1], // skew y + sprite.transform.local.data[4], // scale y + this._dx, // translate x + this._dy); + // translate y + this._dx = sprite.transform.origin.x * -this._dw; + this._dy = sprite.transform.origin.y * -this._dh; + } else { + this._dx -= (this._dw * sprite.transform.origin.x); + this._dy -= (this._dh * sprite.transform.origin.y); + } + if(sprite.crop) { + this._sx += sprite.crop.x * sprite.transform.scale.x; + this._sy += sprite.crop.y * sprite.transform.scale.y; + this._sw = sprite.crop.width * sprite.transform.scale.x; + this._sh = sprite.crop.height * sprite.transform.scale.y; + this._dx += sprite.crop.x * sprite.transform.scale.x; + this._dy += sprite.crop.y * sprite.transform.scale.y; + this._dw = sprite.crop.width * sprite.transform.scale.x; + this._dh = sprite.crop.height * sprite.transform.scale.y; + } + this._sx = Math.floor(this._sx); + this._sy = Math.floor(this._sy); + this._sw = Math.floor(this._sw); + this._sh = Math.floor(this._sh); + this._dx = Math.floor(this._dx); + this._dy = Math.floor(this._dy); + this._dw = Math.floor(this._dw); + this._dh = Math.floor(this._dh); + if(this._sw <= 0 || this._sh <= 0 || this._dw <= 0 || this._dh <= 0) { + return false; + } + // Global Composite Ops + if(sprite.texture.globalCompositeOperation) { + camera.texture.context.save(); + camera.texture.context.globalCompositeOperation = sprite.texture.globalCompositeOperation; + } + // Alpha + if(sprite.texture.alpha !== 1 && camera.texture.context.globalAlpha != sprite.texture.alpha) { + this._ga = sprite.texture.context.globalAlpha; + camera.texture.context.globalAlpha = sprite.texture.alpha; + } + if(sprite.texture.opaque) { + camera.texture.context.fillStyle = sprite.texture.backgroundColor; + camera.texture.context.fillRect(this._dx, this._dy, this._dw, this._dh); + } + if(sprite.texture.loaded) { + camera.texture.context.drawImage(sprite.texture.texture, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._sw, // Source Width + this._sh, // Source Height + this._dx, // Destination X (where on the canvas it'll be drawn) + this._dy, // Destination Y + this._dw, // Destination Width (always same as Source Width unless scaled) + this._dh); + // Destination Height (always same as Source Height unless scaled) + } + if(sprite.modified || sprite.texture.globalCompositeOperation) { + camera.texture.context.restore(); + } + if(this._ga > -1) { + camera.texture.context.globalAlpha = this._ga; + } + sprite.renderOrderID = this.game.renderer.renderCount; + this.game.renderer.renderCount++; + return true; + }; + return SpriteRenderer; + })(); + Canvas.SpriteRenderer = SpriteRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + (function (Canvas) { + var TilemapRenderer = (function () { + function TilemapRenderer(game) { + // Local rendering related temp vars to help avoid gc spikes through constant var creation + this._ga = 1; + this._sx = 0; + this._sy = 0; + this._sw = 0; + this._sh = 0; + this._dx = 0; + this._dy = 0; + this._dw = 0; + this._dh = 0; + this._fx = 1; + this._fy = 1; + this._tx = 0; + this._ty = 0; + this._sin = 0; + this._cos = 1; + this._maxX = 0; + this._maxY = 0; + this._startX = 0; + this._startY = 0; + this.game = game; + } + TilemapRenderer.prototype.render = /** + * Render a tilemap to a specific camera. + * @param camera {Camera} The camera this tilemap will be rendered to. + */ + function (camera, tilemap) { + // Loop through the layers + for(var i = 0; i < tilemap.layers.length; i++) { + var layer = tilemap.layers[i]; + if(layer.visible == false || layer.alpha < 0.1) { + continue; + } + // Work out how many tiles we can fit into our camera and round it up for the edges + this._maxX = this.game.math.ceil(camera.width / layer.tileWidth) + 1; + this._maxY = this.game.math.ceil(camera.height / layer.tileHeight) + 1; + // And now work out where in the tilemap the camera actually is + this._startX = this.game.math.floor(camera.worldView.x / layer.tileWidth); + this._startY = this.game.math.floor(camera.worldView.y / layer.tileHeight); + // Tilemap bounds check + if(this._startX < 0) { + this._startX = 0; + } + if(this._startY < 0) { + this._startY = 0; + } + if(this._maxX > layer.widthInTiles) { + this._maxX = layer.widthInTiles; + } + if(this._maxY > layer.heightInTiles) { + this._maxY = layer.heightInTiles; + } + if(this._startX + this._maxX > layer.widthInTiles) { + this._startX = layer.widthInTiles - this._maxX; + } + if(this._startY + this._maxY > layer.heightInTiles) { + this._startY = layer.heightInTiles - this._maxY; + } + // Finally get the offset to avoid the blocky movement + //this._dx = (camera.screenView.x * layer.transform.scrollFactor.x) - (camera.worldView.x * layer.transform.scrollFactor.x); + //this._dy = (camera.screenView.y * layer.transform.scrollFactor.y) - (camera.worldView.y * layer.transform.scrollFactor.y); + //this._dx = (camera.screenView.x * this.scrollFactor.x) + this.x - (camera.worldView.x * this.scrollFactor.x); + //this._dy = (camera.screenView.y * this.scrollFactor.y) + this.y - (camera.worldView.y * this.scrollFactor.y); + this._dx = 0; + this._dy = 0; + this._dx += -(camera.worldView.x - (this._startX * layer.tileWidth)); + this._dy += -(camera.worldView.y - (this._startY * layer.tileHeight)); + this._tx = this._dx; + this._ty = this._dy; + // Alpha + if(layer.texture.alpha !== 1) { + this._ga = layer.texture.context.globalAlpha; + layer.texture.context.globalAlpha = layer.texture.alpha; + } + for(var row = this._startY; row < this._startY + this._maxY; row++) { + this._columnData = layer.mapData[row]; + for(var tile = this._startX; tile < this._startX + this._maxX; tile++) { + if(layer.tileOffsets[this._columnData[tile]]) { + layer.texture.context.drawImage(layer.texture.texture, layer.tileOffsets[this._columnData[tile]].x, layer.tileOffsets[this._columnData[tile]].y, layer.tileWidth, layer.tileHeight, this._tx, this._ty, layer.tileWidth, layer.tileHeight); + } + this._tx += layer.tileWidth; + } + this._tx = this._dx; + this._ty += layer.tileHeight; + } + if(this._ga > -1) { + layer.texture.context.globalAlpha = this._ga; + } + } + return true; + }; + return TilemapRenderer; + })(); + Canvas.TilemapRenderer = TilemapRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; +})(Phaser || (Phaser = {})); +var Phaser; +(function (Phaser) { + (function (Renderer) { + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + (function (Canvas) { + var CanvasRenderer = (function () { + function CanvasRenderer(game) { + this._c = 0; + this.game = game; + this.cameraRenderer = new Canvas.CameraRenderer(game); + this.groupRenderer = new Canvas.GroupRenderer(game); + this.spriteRenderer = new Canvas.SpriteRenderer(game); + this.geometryRenderer = new Canvas.GeometryRenderer(game); + this.scrollZoneRenderer = new Canvas.ScrollZoneRenderer(game); + this.tilemapRenderer = new Canvas.TilemapRenderer(game); + } + CanvasRenderer.prototype.render = function () { + this._cameraList = this.game.world.getAllCameras(); + this.renderCount = 0; + // Then iterate through world.group on them all (where not blacklisted, etc) + for(this._c = 0; this._c < this._cameraList.length; this._c++) { + if(this._cameraList[this._c].visible) { + this.cameraRenderer.preRender(this._cameraList[this._c]); + this.game.world.group.render(this._cameraList[this._c]); + this.cameraRenderer.postRender(this._cameraList[this._c]); + } + } + this.renderTotal = this.renderCount; + }; + CanvasRenderer.prototype.renderGameObject = function (camera, object) { + if(object.type == Phaser.Types.SPRITE || object.type == Phaser.Types.BUTTON) { + this.spriteRenderer.render(camera, object); + } else if(object.type == Phaser.Types.SCROLLZONE) { + this.scrollZoneRenderer.render(camera, object); + } else if(object.type == Phaser.Types.TILEMAP) { + this.tilemapRenderer.render(camera, object); + } + }; + return CanvasRenderer; + })(); + Canvas.CanvasRenderer = CanvasRenderer; + })(Renderer.Canvas || (Renderer.Canvas = {})); + var Canvas = Renderer.Canvas; + })(Phaser.Renderer || (Phaser.Renderer = {})); + var Renderer = Phaser.Renderer; })(Phaser || (Phaser = {})); /// /// @@ -17967,8 +18205,8 @@ var Phaser; if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } DebugUtils.start(x, y, color); DebugUtils.line('Camera ID: ' + camera.ID + ' (' + camera.screenView.width + ' x ' + camera.screenView.height + ')'); - DebugUtils.line('X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' rotation: ' + camera.transform.rotation); - DebugUtils.line('World X: ' + camera.worldView.x + ' World Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height + ' R: ' + camera.worldView.right + ' B: ' + camera.worldView.bottom); + DebugUtils.line('X: ' + camera.x + ' Y: ' + camera.y + ' Rotation: ' + camera.transform.rotation); + DebugUtils.line('WorldView X: ' + camera.worldView.x + ' Y: ' + camera.worldView.y + ' W: ' + camera.worldView.width + ' H: ' + camera.worldView.height); DebugUtils.line('ScreenView X: ' + camera.screenView.x + ' Y: ' + camera.screenView.y + ' W: ' + camera.screenView.width + ' H: ' + camera.screenView.height); if(camera.worldBounds) { DebugUtils.line('Bounds: ' + camera.worldBounds.width + ' x ' + camera.worldBounds.height); @@ -18054,9 +18292,8 @@ var Phaser; DebugUtils.line('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1)); DebugUtils.line('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1)); DebugUtils.line('center x: ' + sprite.transform.center.x + ' y: ' + sprite.transform.center.y); - //line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height + ' bottom: ' + sprite.cameraView.bottom + ' right: ' + sprite.cameraView.right); DebugUtils.line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height); - DebugUtils.line('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite)); + DebugUtils.line('inCamera: ' + DebugUtils.game.renderer.spriteRenderer.inCamera(DebugUtils.game.camera, sprite)); }; DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) { if (typeof camera === "undefined") { camera = null; } @@ -18134,7 +18371,7 @@ var Phaser; /// /// /// -/// +/// /// /// /** @@ -18332,11 +18569,11 @@ var Phaser; Game.prototype.setRenderer = function (type) { switch(type) { case Phaser.Types.RENDERER_AUTO_DETECT: - this.renderer = new Phaser.HeadlessRenderer(this); + this.renderer = new Phaser.Renderer.Headless.HeadlessRenderer(this); break; case Phaser.Types.RENDERER_AUTO_DETECT: case Phaser.Types.RENDERER_CANVAS: - this.renderer = new Phaser.CanvasRenderer(this); + this.renderer = new Phaser.Renderer.Canvas.CanvasRenderer(this); break; // WebGL coming soon :) }