2013-04-18 13:16:18 +00:00
|
|
|
/// <reference path="../Game.ts" />
|
2013-05-29 14:45:34 +00:00
|
|
|
/// <reference path="../core/Vec2.ts" />
|
2013-05-28 20:38:37 +00:00
|
|
|
/// <reference path="../core/Rectangle.ts" />
|
|
|
|
/// <reference path="../components/animation/AnimationManager.ts" />
|
|
|
|
/// <reference path="../components/sprite/Texture.ts" />
|
2013-06-01 01:49:41 +00:00
|
|
|
/// <reference path="../components/sprite/Input.ts" />
|
|
|
|
/// <reference path="../components/sprite/Events.ts" />
|
2013-05-31 14:13:03 +00:00
|
|
|
/// <reference path="../physics/Body.ts" />
|
2013-04-18 13:16:18 +00:00
|
|
|
|
|
|
|
/**
|
2013-04-18 15:49:08 +00:00
|
|
|
* Phaser - Sprite
|
|
|
|
*
|
2013-04-18 13:16:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
module Phaser {
|
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
export class Sprite implements IGameObject {
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
|
|
|
* Create a new <code>Sprite</code>.
|
|
|
|
*
|
|
|
|
* @param game {Phaser.Game} Current game instance.
|
2013-05-04 16:18:45 +00:00
|
|
|
* @param [x] {number} the initial x position of the sprite.
|
|
|
|
* @param [y] {number} the initial y position of the sprite.
|
|
|
|
* @param [key] {string} Key of the graphic you want to load for this sprite.
|
2013-05-31 14:13:03 +00:00
|
|
|
* @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-31 14:13:03 +00:00
|
|
|
constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, bodyType?: number = Phaser.Types.BODY_DISABLED) {
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-28 20:38:37 +00:00
|
|
|
this.game = game;
|
|
|
|
this.type = Phaser.Types.SPRITE;
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-28 20:38:37 +00:00
|
|
|
this.exists = true;
|
|
|
|
this.active = true;
|
|
|
|
this.visible = true;
|
|
|
|
this.alive = true;
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-31 14:13:03 +00:00
|
|
|
// We give it a default size of 16x16 but when the texture loads (if given) it will reset this
|
|
|
|
this.frameBounds = new Rectangle(x, y, 16, 16);
|
2013-05-28 20:38:37 +00:00
|
|
|
this.scrollFactor = new Phaser.Vec2(1, 1);
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-29 11:24:25 +00:00
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
2013-06-02 02:47:54 +00:00
|
|
|
this.z = -1;
|
|
|
|
this.group = null;
|
2013-06-03 02:08:24 +00:00
|
|
|
this.screen = new Point;
|
2013-05-29 11:24:25 +00:00
|
|
|
|
2013-06-01 00:30:36 +00:00
|
|
|
// If a texture has been given the body will be set to that size, otherwise 16x16
|
|
|
|
this.body = new Phaser.Physics.Body(this, bodyType);
|
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
this.animations = new Phaser.Components.AnimationManager(this);
|
|
|
|
this.texture = new Phaser.Components.Texture(this, key);
|
2013-06-01 01:49:41 +00:00
|
|
|
this.input = new Phaser.Components.Input(this);
|
|
|
|
this.events = new Phaser.Components.Events(this);
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
this.cameraBlacklist = [];
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
// Transform related (if we add any more then move to a component)
|
2013-05-29 16:31:57 +00:00
|
|
|
this.origin = new Phaser.Vec2(0, 0);
|
2013-05-29 14:45:34 +00:00
|
|
|
this.scale = new Phaser.Vec2(1, 1);
|
|
|
|
this.skew = new Phaser.Vec2(0, 0);
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* Reference to the main game object
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public game: Game;
|
2013-05-16 01:36:58 +00:00
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* The type of game object.
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public type: number;
|
2013-04-19 17:53:21 +00:00
|
|
|
|
2013-06-02 02:47:54 +00:00
|
|
|
/**
|
|
|
|
* The Group this Sprite belongs to.
|
|
|
|
*/
|
|
|
|
public group: Group;
|
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* Controls if both <code>update</code> and render are called by the core game loop.
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public exists: bool;
|
2013-05-16 01:36:58 +00:00
|
|
|
|
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* Controls if <code>update()</code> is automatically called by the core game loop.
|
2013-05-16 01:36:58 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public active: bool;
|
2013-05-16 01:36:58 +00:00
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* Controls if this Sprite is rendered or skipped during the core game loop.
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public visible: bool;
|
2013-05-16 01:36:58 +00:00
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
*
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public alive: bool;
|
2013-05-16 01:36:58 +00:00
|
|
|
|
2013-05-29 20:39:08 +00:00
|
|
|
/**
|
2013-05-31 14:13:03 +00:00
|
|
|
* Sprite physics body.
|
2013-05-29 20:39:08 +00:00
|
|
|
*/
|
2013-05-31 14:13:03 +00:00
|
|
|
public body: Phaser.Physics.Body;
|
2013-05-29 20:39:08 +00:00
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* The texture used to render the Sprite.
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public texture: Phaser.Components.Texture;
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-06-01 01:49:41 +00:00
|
|
|
/**
|
|
|
|
* The Input component
|
|
|
|
*/
|
|
|
|
public input: Phaser.Components.Input;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Events component
|
|
|
|
*/
|
|
|
|
public events: Phaser.Components.Events;
|
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
/**
|
|
|
|
* This manages animations of the sprite. You can modify animations though it. (see AnimationManager)
|
|
|
|
* @type AnimationManager
|
|
|
|
*/
|
|
|
|
public animations: Phaser.Components.AnimationManager;
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
/**
|
|
|
|
* An Array of Cameras to which this GameObject won't render
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
public cameraBlacklist: number[];
|
|
|
|
|
2013-05-04 12:02:12 +00:00
|
|
|
/**
|
2013-05-28 20:38:37 +00:00
|
|
|
* The frame boundary around this Sprite.
|
|
|
|
* For non-animated sprites this matches the loaded texture dimensions.
|
|
|
|
* For animated sprites it will be updated as part of the animation loop, changing to the dimensions of the current animation frame.
|
2013-05-04 12:02:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public frameBounds: Phaser.Rectangle;
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
/**
|
|
|
|
* Scale of the Sprite. A scale of 1.0 is the original size. 0.5 half size. 2.0 double sized.
|
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public scale: Phaser.Vec2;
|
2013-05-29 01:58:56 +00:00
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
/**
|
|
|
|
* Skew the Sprite along the x and y axis. A skew value of 0 is no skew.
|
|
|
|
*/
|
|
|
|
public skew: Phaser.Vec2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
|
|
|
|
*/
|
|
|
|
public modified: bool = false;
|
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
/**
|
|
|
|
* The influence of camera movement upon the Sprite.
|
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public scrollFactor: Phaser.Vec2;
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
/**
|
2013-05-29 11:24:25 +00:00
|
|
|
* The Sprite origin is the point around which scale and rotation takes place.
|
2013-05-29 01:58:56 +00:00
|
|
|
*/
|
|
|
|
public origin: Phaser.Vec2;
|
|
|
|
|
2013-06-03 02:08:24 +00:00
|
|
|
/**
|
|
|
|
* A Point holding the x/y coordinate of this Sprite relative to the screen. It uses the default created world
|
|
|
|
* camera to calculate its values. If you have changed the default camera (i.e. resized it, deleted it) this value
|
|
|
|
* will be incorrect and should be ignored.
|
|
|
|
*/
|
|
|
|
public screen: Point;
|
|
|
|
|
2013-05-29 11:24:25 +00:00
|
|
|
/**
|
|
|
|
* x value of the object.
|
|
|
|
*/
|
|
|
|
public x: number = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* y value of the object.
|
|
|
|
*/
|
|
|
|
public y: number = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* z order value of the object.
|
|
|
|
*/
|
|
|
|
public z: number = 0;
|
|
|
|
|
2013-06-03 11:03:34 +00:00
|
|
|
/**
|
|
|
|
* Render iteration
|
|
|
|
*/
|
|
|
|
public renderOrderID: number = 0;
|
|
|
|
|
2013-05-29 11:24:25 +00:00
|
|
|
/**
|
2013-05-31 14:13:03 +00:00
|
|
|
* This value is added to the angle of the Sprite.
|
2013-05-29 11:24:25 +00:00
|
|
|
* For example if you had a sprite graphic drawn facing straight up then you could set
|
2013-05-31 14:13:03 +00:00
|
|
|
* angleOffset to 90 and it would correspond correctly with Phasers right-handed coordinate system.
|
2013-05-29 11:24:25 +00:00
|
|
|
* @type {number}
|
|
|
|
*/
|
2013-05-31 14:13:03 +00:00
|
|
|
public angleOffset: number = 0;
|
2013-05-29 11:24:25 +00:00
|
|
|
|
|
|
|
/**
|
2013-05-31 14:13:03 +00:00
|
|
|
* The angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
|
2013-05-29 11:24:25 +00:00
|
|
|
*/
|
2013-05-31 14:13:03 +00:00
|
|
|
public get angle(): number {
|
|
|
|
return this.body.angle;
|
2013-05-29 11:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-05-31 14:13:03 +00:00
|
|
|
* Set the angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
|
2013-05-29 11:24:25 +00:00
|
|
|
* The value is automatically wrapped to be between 0 and 360.
|
|
|
|
*/
|
2013-05-31 14:13:03 +00:00
|
|
|
public set angle(value: number) {
|
|
|
|
this.body.angle = this.game.math.wrap(value, 360, 0);
|
2013-05-29 11:24:25 +00:00
|
|
|
}
|
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
/**
|
|
|
|
* Set the animation frame by frame number.
|
|
|
|
*/
|
|
|
|
public set frame(value: number) {
|
|
|
|
this.animations.frame = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the animation frame number.
|
|
|
|
*/
|
|
|
|
public get frame(): number {
|
|
|
|
return this.animations.frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the animation frame by frame name.
|
|
|
|
*/
|
|
|
|
public set frameName(value: string) {
|
|
|
|
this.animations.frameName = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the animation frame name.
|
|
|
|
*/
|
|
|
|
public get frameName(): string {
|
|
|
|
return this.animations.frameName;
|
|
|
|
}
|
|
|
|
|
2013-05-30 04:34:35 +00:00
|
|
|
public set width(value: number) {
|
|
|
|
this.frameBounds.width = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get width(): number {
|
|
|
|
return this.frameBounds.width;
|
|
|
|
}
|
|
|
|
|
|
|
|
public set height(value: number) {
|
|
|
|
this.frameBounds.height = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get height(): number {
|
|
|
|
return this.frameBounds.height;
|
|
|
|
}
|
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
/**
|
|
|
|
* Pre-update is called right before update() on each object in the game loop.
|
|
|
|
*/
|
|
|
|
public preUpdate() {
|
|
|
|
|
2013-05-29 20:39:08 +00:00
|
|
|
this.frameBounds.x = this.x;
|
|
|
|
this.frameBounds.y = this.y;
|
2013-05-29 01:58:56 +00:00
|
|
|
|
2013-06-03 02:08:24 +00:00
|
|
|
this.screen.x = this.x - (this.game.world.cameras.default.worldView.x * this.scrollFactor.x);
|
|
|
|
this.screen.y = this.y - (this.game.world.cameras.default.worldView.y * this.scrollFactor.y);
|
|
|
|
|
2013-05-31 14:13:03 +00:00
|
|
|
if (this.modified == false && (!this.scale.equals(1) || !this.skew.equals(0) || this.angle != 0 || this.angleOffset != 0 || this.texture.flippedX || this.texture.flippedY))
|
2013-05-29 14:45:34 +00:00
|
|
|
{
|
|
|
|
this.modified = true;
|
|
|
|
}
|
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override this function to update your class's position and appearance.
|
|
|
|
*/
|
|
|
|
public update() {
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Automatically called after update() by the game loop.
|
|
|
|
*/
|
|
|
|
public postUpdate() {
|
|
|
|
|
|
|
|
this.animations.update();
|
2013-05-31 14:13:03 +00:00
|
|
|
this.body.postUpdate();
|
2013-05-29 01:58:56 +00:00
|
|
|
|
2013-05-29 14:45:34 +00:00
|
|
|
/*
|
2013-05-29 01:58:56 +00:00
|
|
|
if (this.worldBounds != null)
|
|
|
|
{
|
|
|
|
if (this.outOfBoundsAction == GameObject.OUT_OF_BOUNDS_KILL)
|
|
|
|
{
|
|
|
|
if (this.x < this.worldBounds.x || this.x > this.worldBounds.right || this.y < this.worldBounds.y || this.y > this.worldBounds.bottom)
|
|
|
|
{
|
|
|
|
this.kill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this.x < this.worldBounds.x)
|
|
|
|
{
|
|
|
|
this.x = this.worldBounds.x;
|
|
|
|
}
|
|
|
|
else if (this.x > this.worldBounds.right)
|
|
|
|
{
|
|
|
|
this.x = this.worldBounds.right;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.y < this.worldBounds.y)
|
|
|
|
{
|
|
|
|
this.y = this.worldBounds.y;
|
|
|
|
}
|
|
|
|
else if (this.y > this.worldBounds.bottom)
|
|
|
|
{
|
|
|
|
this.y = this.worldBounds.bottom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
if (this.modified == true && this.scale.equals(1) && this.skew.equals(0) && this.angle == 0 && this.angleOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false)
|
2013-05-29 14:45:34 +00:00
|
|
|
{
|
|
|
|
this.modified = false;
|
|
|
|
}
|
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clean up memory.
|
|
|
|
*/
|
|
|
|
public destroy() {
|
2013-06-03 11:03:34 +00:00
|
|
|
|
|
|
|
//this.input.destroy();
|
|
|
|
|
2013-06-02 02:47:54 +00:00
|
|
|
|
2013-05-29 01:58:56 +00:00
|
|
|
}
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
/**
|
|
|
|
* Handy for "killing" game objects.
|
|
|
|
* Default behavior is to flag them as nonexistent AND dead.
|
|
|
|
* However, if you want the "corpse" to remain in the game,
|
|
|
|
* like to animate an effect or whatever, you should override this,
|
|
|
|
* setting only alive to false, and leaving exists true.
|
|
|
|
*/
|
2013-06-02 02:47:54 +00:00
|
|
|
public kill(removeFromGroup:bool = false) {
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
this.alive = false;
|
|
|
|
this.exists = false;
|
2013-06-02 02:47:54 +00:00
|
|
|
|
|
|
|
if (removeFromGroup && this.group)
|
|
|
|
{
|
|
|
|
this.group.remove(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.events.onKilled.dispatch(this);
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
|
|
|
|
* In practice, this is most often called by <code>Object.reset()</code>.
|
|
|
|
*/
|
|
|
|
public revive() {
|
2013-06-02 02:47:54 +00:00
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
this.alive = true;
|
|
|
|
this.exists = true;
|
2013-06-02 02:47:54 +00:00
|
|
|
|
|
|
|
this.events.onRevived.dispatch(this);
|
|
|
|
|
2013-05-31 17:21:32 +00:00
|
|
|
}
|
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|