Added todo items to repo

This commit is contained in:
Richard Davey
2013-07-13 12:38:59 +01:00
parent dcce99ec60
commit b3fff37faf
241 changed files with 20429 additions and 140 deletions
+4
View File
@@ -30,6 +30,10 @@ module Phaser {
static BODY_KINETIC: number = 2;
static BODY_DYNAMIC: number = 3;
static OUT_OF_BOUNDS_KILL: number = 0;
static OUT_OF_BOUNDS_DESTROY: number = 1;
static OUT_OF_BOUNDS_PERSIST: number = 2;
/**
* Flag used to allow GameObjects to collide on their left side
* @type {number}
+4
View File
@@ -23,6 +23,7 @@ module Phaser.Components.Sprite {
this.onRemovedFromGroup = new Phaser.Signal;
this.onKilled = new Phaser.Signal;
this.onRevived = new Phaser.Signal;
this.onOutOfBounds = new Phaser.Signal;
}
@@ -101,6 +102,9 @@ module Phaser.Components.Sprite {
*/
public onAnimationLoop: Phaser.Signal;
/**
* Dispatched by the Sprite when it first leaves the world bounds
*/
public onOutOfBounds: Phaser.Signal;
}
+8 -3
View File
@@ -19,9 +19,14 @@ module Phaser {
* Create a new <code>Button</code> object.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the button.
* @param [y] {number} the initial y position of the button.
* @param [key] {string} Key of the graphic you want to load for this button.
* @param [x] {number} X position of the button.
* @param [y] {number} Y position of the button.
* @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this button.
* @param [callback] {function} The function to call when this button is pressed
* @param [callbackContext] {object} The context in which the callback will be called (usually 'this')
* @param [overFrame] {string|number} This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
* @param [outFrame] {string|number} This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
* @param [downFrame] {string|number} This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
*/
constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, callback? = null, callbackContext? = null, overFrame? = null, outFrame? = null, downFrame? = null) {
+16 -4
View File
@@ -182,13 +182,14 @@ module Phaser {
}
/**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param obj Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
public tween(obj): Tween {
return this._game.tweens.create(obj);
public tween(obj, localReference?:bool = false): Tween {
return this._game.tweens.create(obj, localReference);
}
/**
@@ -202,6 +203,17 @@ module Phaser {
return this._world.group.add(sprite);
}
/**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
* @param button The Button to add to the Game World
* @return {Phaser.Button} The Button object
*/
public existingButton(button: Button): Button {
return this._world.group.add(button);
}
/**
* Add an existing GeomSprite to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
+36 -27
View File
@@ -81,6 +81,9 @@ module Phaser {
this.transform.setCache();
this.outOfBounds = false;
this.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_KILL;
// Handy proxies
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
@@ -128,6 +131,17 @@ module Phaser {
*/
public alive: bool;
/**
* Is the Sprite out of the world bounds or not?
*/
public outOfBounds: bool;
/**
* The action to be taken when the sprite is fully out of the world bounds
* Defaults to Phaser.Types.OUT_OF_BOUNDS_KILL
*/
public outOfBoundsAction: number;
/**
* Sprite physics body.
*/
@@ -171,6 +185,11 @@ module Phaser {
*/
public cameraView: Phaser.Rectangle;
/**
* A local tween variable. Used by the TweenManager when setting a tween on this sprite or a property of it.
*/
public tween: Phaser.Tween;
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
@@ -314,44 +333,34 @@ module Phaser {
}
/**
* Automatically called after update() by the game loop.
* Automatically called after update() by the game loop for all 'alive' objects.
*/
public postUpdate() {
this.animations.update();
/*
if (this.worldBounds != null)
if (Phaser.RectangleUtils.intersects(this.worldView, this.game.world.bounds))
{
if (this.outOfBoundsAction == GameObject.OUT_OF_BOUNDS_KILL)
this.outOfBounds = false;
}
else
{
if (this.outOfBounds == false)
{
if (this.x < this.worldBounds.x || this.x > this.worldBounds.right || this.y < this.worldBounds.y || this.y > this.worldBounds.bottom)
{
this.kill();
}
this.events.onOutOfBounds.dispatch(this);
}
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;
}
this.outOfBounds = true;
if (this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_KILL)
{
this.kill();
}
else if (this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_DESTROY)
{
this.destroy();
}
}
*/
if (this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false)
{
+10
View File
@@ -340,6 +340,16 @@ module Phaser.Physics {
}
private _newPosition: Phaser.Vec2 = new Phaser.Vec2;
public setPosition(x: number, y: number) {
this._newPosition.setTo(this.game.physics.pixelsToMeters(x), this.game.physics.pixelsToMeters(y));
this.setTransform(this._newPosition, this.angle);
}
public setTransform(pos:Phaser.Vec2, angle:number) {
// inject the transform into this.position
+14 -5
View File
@@ -56,19 +56,28 @@ module Phaser {
}
/**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param object {object} Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
public create(object): Phaser.Tween {
public create(object, localReference?:bool = false): Phaser.Tween {
return new Phaser.Tween(object, this._game);
if (localReference)
{
object['tween'] = new Phaser.Tween(object, this._game);
return object['tween'];
}
else
{
return new Phaser.Tween(object, this._game);
}
}
/**
* Add an exist tween object to the manager.
* Add a new tween into the TweenManager.
*
* @param tween {Phaser.Tween} The tween object you want to add.
* @return {Phaser.Tween} The tween object you added to the manager.
-2
View File
@@ -58,13 +58,11 @@ module Phaser {
if (body.shapes[0].verts.length > 0)
{
DebugUtils.context.fillText('Vert 1 x: ' + (body.shapes[0].verts[0].x * 50) + ' y: ' + (body.shapes[0].verts[0].y * 50), x, y + 56);
DebugUtils.context.fillText('Vert 2 x: ' + (body.shapes[0].verts[1].x * 50) + ' y: ' + (body.shapes[0].verts[1].y * 50), x, y + 70);
DebugUtils.context.fillText('Vert 3 x: ' + (body.shapes[0].tverts[2].x * 50) + ' y: ' + (body.shapes[0].tverts[2].y * 50), x, y + 84);
DebugUtils.context.fillText('Vert 4 x: ' + (body.shapes[0].tverts[3].x * 50) + ' y: ' + (body.shapes[0].tverts[3].y * 50), x, y + 98);
/*
DebugUtils.context.fillText('Vert 1 x: ' + body.shapes[0].verts[0].x.toFixed(1) + ' y: ' + body.shapes[0].verts[0].y.toFixed(1), x, y + 56);
DebugUtils.context.fillText('Vert 2 x: ' + body.shapes[0].verts[1].x.toFixed(1) + ' y: ' + body.shapes[0].verts[1].y.toFixed(1), x, y + 70);
+1
View File
@@ -142,6 +142,7 @@ V1.0.0
* Fixed bug where Sprite.alpha wasn't properly reflecting Sprite.texture.alpha.
* Fixed bug where the hand cursor would be reset on input up, even if the mouse was still over the sprite.
* Fixed bug where pressing down then moving out of the sprite area wouldn't properly reset the input state next time you moved over the sprite.
* Added the Sprite.tween property, really useful to avoid creating new tween vars in your local scope if you don't need them.
V0.9.6
+43 -36
View File
@@ -1284,6 +1284,9 @@ var Phaser;
Types.BODY_STATIC = 1;
Types.BODY_KINETIC = 2;
Types.BODY_DYNAMIC = 3;
Types.OUT_OF_BOUNDS_KILL = 0;
Types.OUT_OF_BOUNDS_DESTROY = 1;
Types.OUT_OF_BOUNDS_PERSIST = 2;
Types.LEFT = 0x0001;
Types.RIGHT = 0x0010;
Types.UP = 0x0100;
@@ -3961,6 +3964,7 @@ var Phaser;
this.onRemovedFromGroup = new Phaser.Signal();
this.onKilled = new Phaser.Signal();
this.onRevived = new Phaser.Signal();
this.onOutOfBounds = new Phaser.Signal();
}
return Events;
})();
@@ -6710,6 +6714,7 @@ var Phaser;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.stepCount = 0;
this._newPosition = new Phaser.Vec2();
this.id = Phaser.Physics.Manager.bodyCounter++;
this.name = 'body' + this.id;
this.type = type;
@@ -6888,6 +6893,10 @@ var Phaser;
this.inertia = inertia;
this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
};
Body.prototype.setPosition = function (x, y) {
this._newPosition.setTo(this.game.physics.pixelsToMeters(x), this.game.physics.pixelsToMeters(y));
this.setTransform(this._newPosition, this.angle);
};
Body.prototype.setTransform = function (pos, angle) {
// inject the transform into this.position
this.transform.setTo(pos, angle);
@@ -7233,6 +7242,8 @@ var Phaser;
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
this.cameraView = new Phaser.Rectangle(x, y, this.width, this.height);
this.transform.setCache();
this.outOfBounds = false;
this.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_KILL;
// Handy proxies
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
@@ -7345,42 +7356,23 @@ var Phaser;
function () {
};
Sprite.prototype.postUpdate = /**
* Automatically called after update() by the game loop.
* Automatically called after update() by the game loop for all 'alive' objects.
*/
function () {
this.animations.update();
/*
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();
if(Phaser.RectangleUtils.intersects(this.worldView, this.game.world.bounds)) {
this.outOfBounds = false;
} else {
if(this.outOfBounds == false) {
this.events.onOutOfBounds.dispatch(this);
}
this.outOfBounds = true;
if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_KILL) {
this.kill();
} else if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_DESTROY) {
this.destroy();
}
}
}
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;
}
}
}
*/
if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) {
this.modified = false;
}
@@ -12502,9 +12494,14 @@ var Phaser;
* Create a new <code>Button</code> object.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the button.
* @param [y] {number} the initial y position of the button.
* @param [key] {string} Key of the graphic you want to load for this button.
* @param [x] {number} X position of the button.
* @param [y] {number} Y position of the button.
* @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this button.
* @param [callback] {function} The function to call when this button is pressed
* @param [callbackContext] {object} The context in which the callback will be called (usually 'this')
* @param [overFrame] {string|number} This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
* @param [outFrame] {string|number} This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
* @param [downFrame] {string|number} This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
*/
function Button(game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) {
if (typeof x === "undefined") { x = 0; }
@@ -13910,6 +13907,16 @@ var Phaser;
function (sprite) {
return this._world.group.add(sprite);
};
GameObjectFactory.prototype.existingButton = /**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
* @param button The Button to add to the Game World
* @return {Phaser.Button} The Button object
*/
function (button) {
return this._world.group.add(button);
};
GameObjectFactory.prototype.existingEmitter = /**
* Add an existing GeomSprite to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
@@ -15253,7 +15260,7 @@ var Phaser;
return new Phaser.Tween(object, this._game);
};
TweenManager.prototype.add = /**
* Add an exist tween object to the manager.
* Add a new tween into the TweenManager.
*
* @param tween {Phaser.Tween} The tween object you want to add.
* @return {Phaser.Tween} The tween object you added to the manager.
+14 -3
View File
@@ -16,15 +16,26 @@
atari = game.add.physicsSprite(300, 450, 'atari', null, Phaser.Types.BODY_STATIC);
//atari.rotation = 10;
//atari.body.transform.setRotation(1);
atari.body.angle = 1;
//atari.body.angle = 1;
atari.body.setTransform(atari.body.position, 1);
atari.body.syncTransform();
// atari = 220px width (110 = center x)
// ball = 32px width (16 = center x)
// Ball will be a dynamic body and fall based on gravity
ball = game.add.physicsSprite(300 - 20, 0, 'ball');
ball.body.angle = 1;
//ball.body.angle = 1;
//ball.body.transform.setRotation(1);
//ball.body.fixedRotation = true;
}
// limit the velocity or things can go nuts
ball.body.linearDamping = 0.5;
ball.body.angularDamping = 0.5;
// when the ball bounces out of the game world, call the resetBall function
ball.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_PERSIST;
ball.events.onOutOfBounds.add(resetBall, this);
}
function resetBall() {
ball.body.setPosition(300, 0);
}
function render() {
Phaser.DebugUtils.renderPhysicsBodyInfo(atari.body, 32, 32);
Phaser.DebugUtils.renderPhysicsBodyInfo(ball.body, 320, 32);
+16 -2
View File
@@ -25,17 +25,31 @@
atari = game.add.physicsSprite(300, 450, 'atari', null, Phaser.Types.BODY_STATIC);
//atari.rotation = 10;
//atari.body.transform.setRotation(1);
atari.body.angle = 1;
//atari.body.angle = 1;
atari.body.setTransform(atari.body.position, 1);
atari.body.syncTransform();
// atari = 220px width (110 = center x)
// ball = 32px width (16 = center x)
// Ball will be a dynamic body and fall based on gravity
ball = game.add.physicsSprite(300-20, 0, 'ball');
ball.body.angle = 1;
//ball.body.angle = 1;
//ball.body.transform.setRotation(1);
//ball.body.fixedRotation = true;
// limit the velocity or things can go nuts
ball.body.linearDamping = 0.5;
ball.body.angularDamping = 0.5;
// when the ball bounces out of the game world, call the resetBall function
ball.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_PERSIST;
ball.events.onOutOfBounds.add(resetBall, this);
}
function resetBall() {
ball.body.setPosition(300, 0);
}
function render() {
+3 -3
View File
@@ -6,10 +6,10 @@
game.load.image('bunny', 'assets/sprites/bunny.png');
game.load.start();
}
var bunny;
function create() {
// Here we'll assign the new sprite to the local smallBunny variable
bunny = game.add.sprite(0, 0, 'bunny');
// Here we'll assign the new sprite to the local bunny variable
var bunny = game.add.sprite(0, 0, 'bunny');
// And this sets the alpha of the sprite to 0.5, which is 50% opaque
bunny.alpha = 0.5;
}
})();
+47 -11
View File
@@ -856,6 +856,9 @@ module Phaser {
static BODY_STATIC: number;
static BODY_KINETIC: number;
static BODY_DYNAMIC: number;
static OUT_OF_BOUNDS_KILL: number;
static OUT_OF_BOUNDS_DESTROY: number;
static OUT_OF_BOUNDS_PERSIST: number;
/**
* Flag used to allow GameObjects to collide on their left side
* @type {number}
@@ -2384,6 +2387,9 @@ module Phaser.Components.Sprite {
* Dispatched by the Animation component when the Sprite animation loops
*/
public onAnimationLoop: Signal;
/**
* Dispatched by the Sprite when it first leaves the world bounds
*/
public onOutOfBounds: Signal;
}
}
@@ -3176,6 +3182,8 @@ module Phaser.Physics {
public removeShape(shape): void;
private setMass(mass);
private setInertia(inertia);
private _newPosition;
public setPosition(x: number, y: number): void;
public setTransform(pos: Vec2, angle: number): void;
public syncTransform(): void;
public getWorldPoint(p: Vec2): Vec2;
@@ -3252,6 +3260,15 @@ module Phaser {
*/
public alive: bool;
/**
* Is the Sprite out of the world bounds or not?
*/
public outOfBounds: bool;
/**
* The action to be taken when the sprite is fully out of the world bounds
* Defaults to Phaser.Types.OUT_OF_BOUNDS_KILL
*/
public outOfBoundsAction: number;
/**
* Sprite physics body.
*/
public body: Physics.Body;
@@ -3287,6 +3304,10 @@ module Phaser {
*/
public cameraView: Rectangle;
/**
* A local tween variable. Used by the TweenManager when setting a tween on this sprite or a property of it.
*/
public tween: Tween;
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
public modified: bool;
@@ -3356,7 +3377,7 @@ module Phaser {
*/
public update(): void;
/**
* Automatically called after update() by the game loop.
* Automatically called after update() by the game loop for all 'alive' objects.
*/
public postUpdate(): void;
/**
@@ -5998,9 +6019,14 @@ module Phaser {
* Create a new <code>Button</code> object.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the button.
* @param [y] {number} the initial y position of the button.
* @param [key] {string} Key of the graphic you want to load for this button.
* @param [x] {number} X position of the button.
* @param [y] {number} Y position of the button.
* @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this button.
* @param [callback] {function} The function to call when this button is pressed
* @param [callbackContext] {object} The context in which the callback will be called (usually 'this')
* @param [overFrame] {string|number} This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
* @param [outFrame] {string|number} This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
* @param [downFrame] {string|number} This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
*/
constructor(game: Game, x?: number, y?: number, key?: string, callback?, callbackContext?, overFrame?, outFrame?, downFrame?);
private _onOverFrameName;
@@ -6846,12 +6872,13 @@ module Phaser {
*/
public tilemap(key: string, mapData: string, format: number, resizeWorld?: bool, tileWidth?: number, tileHeight?: number): Tilemap;
/**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param obj Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
public tween(obj): Tween;
public tween(obj, localReference?: bool): Tween;
/**
* Add an existing Sprite to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
@@ -6861,6 +6888,14 @@ module Phaser {
*/
public existingSprite(sprite: Sprite): Sprite;
/**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
* @param button The Button to add to the Game World
* @return {Phaser.Button} The Button object
*/
public existingButton(button: Button): Button;
/**
* Add an existing Emitter to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
@@ -7656,14 +7691,15 @@ module Phaser {
*/
public removeAll(): void;
/**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param object {object} Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
public create(object): Tween;
public create(object, localReference?: bool): Tween;
/**
* Add an exist tween object to the manager.
* Add a new tween into the TweenManager.
*
* @param tween {Phaser.Tween} The tween object you want to add.
* @return {Phaser.Tween} The tween object you added to the manager.
+60 -44
View File
@@ -1284,6 +1284,9 @@ var Phaser;
Types.BODY_STATIC = 1;
Types.BODY_KINETIC = 2;
Types.BODY_DYNAMIC = 3;
Types.OUT_OF_BOUNDS_KILL = 0;
Types.OUT_OF_BOUNDS_DESTROY = 1;
Types.OUT_OF_BOUNDS_PERSIST = 2;
Types.LEFT = 0x0001;
Types.RIGHT = 0x0010;
Types.UP = 0x0100;
@@ -3961,6 +3964,7 @@ var Phaser;
this.onRemovedFromGroup = new Phaser.Signal();
this.onKilled = new Phaser.Signal();
this.onRevived = new Phaser.Signal();
this.onOutOfBounds = new Phaser.Signal();
}
return Events;
})();
@@ -6710,6 +6714,7 @@ var Phaser;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.stepCount = 0;
this._newPosition = new Phaser.Vec2();
this.id = Phaser.Physics.Manager.bodyCounter++;
this.name = 'body' + this.id;
this.type = type;
@@ -6888,6 +6893,10 @@ var Phaser;
this.inertia = inertia;
this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
};
Body.prototype.setPosition = function (x, y) {
this._newPosition.setTo(this.game.physics.pixelsToMeters(x), this.game.physics.pixelsToMeters(y));
this.setTransform(this._newPosition, this.angle);
};
Body.prototype.setTransform = function (pos, angle) {
// inject the transform into this.position
this.transform.setTo(pos, angle);
@@ -7233,6 +7242,8 @@ var Phaser;
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
this.cameraView = new Phaser.Rectangle(x, y, this.width, this.height);
this.transform.setCache();
this.outOfBounds = false;
this.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_KILL;
// Handy proxies
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
@@ -7345,42 +7356,23 @@ var Phaser;
function () {
};
Sprite.prototype.postUpdate = /**
* Automatically called after update() by the game loop.
* Automatically called after update() by the game loop for all 'alive' objects.
*/
function () {
this.animations.update();
/*
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();
if(Phaser.RectangleUtils.intersects(this.worldView, this.game.world.bounds)) {
this.outOfBounds = false;
} else {
if(this.outOfBounds == false) {
this.events.onOutOfBounds.dispatch(this);
}
this.outOfBounds = true;
if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_KILL) {
this.kill();
} else if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_DESTROY) {
this.destroy();
}
}
}
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;
}
}
}
*/
if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) {
this.modified = false;
}
@@ -12502,9 +12494,14 @@ var Phaser;
* Create a new <code>Button</code> object.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the button.
* @param [y] {number} the initial y position of the button.
* @param [key] {string} Key of the graphic you want to load for this button.
* @param [x] {number} X position of the button.
* @param [y] {number} Y position of the button.
* @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this button.
* @param [callback] {function} The function to call when this button is pressed
* @param [callbackContext] {object} The context in which the callback will be called (usually 'this')
* @param [overFrame] {string|number} This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
* @param [outFrame] {string|number} This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
* @param [downFrame] {string|number} This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
*/
function Button(game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) {
if (typeof x === "undefined") { x = 0; }
@@ -13892,13 +13889,15 @@ var Phaser;
return this._world.group.add(new Phaser.Tilemap(this._game, key, mapData, format, resizeWorld, tileWidth, tileHeight));
};
GameObjectFactory.prototype.tween = /**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param obj Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
function (obj) {
return this._game.tweens.create(obj);
function (obj, localReference) {
if (typeof localReference === "undefined") { localReference = false; }
return this._game.tweens.create(obj, localReference);
};
GameObjectFactory.prototype.existingSprite = /**
* Add an existing Sprite to the current world.
@@ -13910,6 +13909,16 @@ var Phaser;
function (sprite) {
return this._world.group.add(sprite);
};
GameObjectFactory.prototype.existingButton = /**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
* @param button The Button to add to the Game World
* @return {Phaser.Button} The Button object
*/
function (button) {
return this._world.group.add(button);
};
GameObjectFactory.prototype.existingEmitter = /**
* Add an existing GeomSprite to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
@@ -15244,16 +15253,23 @@ var Phaser;
this._tweens.length = 0;
};
TweenManager.prototype.create = /**
* Create a tween object for a specific object.
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
* @param object {object} Object you wish the tween will affect.
* @param obj {object} Object the tween will be run on.
* @param [localReference] {bool} If true the tween will be stored in the object.tween property so long as it exists. If already set it'll be over-written.
* @return {Phaser.Tween} The newly created tween object.
*/
function (object) {
return new Phaser.Tween(object, this._game);
function (object, localReference) {
if (typeof localReference === "undefined") { localReference = false; }
if(localReference) {
object['tween'] = new Phaser.Tween(object, this._game);
return object['tween'];
} else {
return new Phaser.Tween(object, this._game);
}
};
TweenManager.prototype.add = /**
* Add an exist tween object to the manager.
* Add a new tween into the TweenManager.
*
* @param tween {Phaser.Tween} The tween object you want to add.
* @return {Phaser.Tween} The tween object you added to the manager.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+777
View File
@@ -0,0 +1,777 @@
var Phaser;
(function (Phaser) {
var Collision = (function () {
function Collision(game) {
this._game = game;
Collision.T_VECTORS = [];
for(var i = 0; i < 10; i++) {
Collision.T_VECTORS.push(new Vector2());
}
Collision.T_ARRAYS = [];
for(var i = 0; i < 5; i++) {
Collision.T_ARRAYS.push([]);
}
}
Collision.LEFT = 0x0001;
Collision.RIGHT = 0x0010;
Collision.UP = 0x0100;
Collision.DOWN = 0x1000;
Collision.NONE = 0;
Collision.CEILING = Phaser.Collision.UP;
Collision.FLOOR = Phaser.Collision.DOWN;
Collision.WALL = Phaser.Collision.LEFT | Phaser.Collision.RIGHT;
Collision.ANY = Phaser.Collision.LEFT | Phaser.Collision.RIGHT | Phaser.Collision.UP | Phaser.Collision.DOWN;
Collision.OVERLAP_BIAS = 4;
Collision.TILE_OVERLAP = false;
Collision.lineToLine = function lineToLine(line1, line2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var denominator = (line1.x1 - line1.x2) * (line2.y1 - line2.y2) - (line1.y1 - line1.y2) * (line2.x1 - line2.x2);
if(denominator !== 0) {
output.result = true;
output.x = ((line1.x1 * line1.y2 - line1.y1 * line1.x2) * (line2.x1 - line2.x2) - (line1.x1 - line1.x2) * (line2.x1 * line2.y2 - line2.y1 * line2.x2)) / denominator;
output.y = ((line1.x1 * line1.y2 - line1.y1 * line1.x2) * (line2.y1 - line2.y2) - (line1.y1 - line1.y2) * (line2.x1 * line2.y2 - line2.y1 * line2.x2)) / denominator;
}
return output;
};
Collision.lineToLineSegment = function lineToLineSegment(line, seg, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var denominator = (line.x1 - line.x2) * (seg.y1 - seg.y2) - (line.y1 - line.y2) * (seg.x1 - seg.x2);
if(denominator !== 0) {
output.x = ((line.x1 * line.y2 - line.y1 * line.x2) * (seg.x1 - seg.x2) - (line.x1 - line.x2) * (seg.x1 * seg.y2 - seg.y1 * seg.x2)) / denominator;
output.y = ((line.x1 * line.y2 - line.y1 * line.x2) * (seg.y1 - seg.y2) - (line.y1 - line.y2) * (seg.x1 * seg.y2 - seg.y1 * seg.x2)) / denominator;
var maxX = Math.max(seg.x1, seg.x2);
var minX = Math.min(seg.x1, seg.x2);
var maxY = Math.max(seg.y1, seg.y2);
var minY = Math.min(seg.y1, seg.y2);
if((output.x <= maxX && output.x >= minX) === true || (output.y <= maxY && output.y >= minY) === true) {
output.result = true;
}
}
return output;
};
Collision.lineToRawSegment = function lineToRawSegment(line, x1, y1, x2, y2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var denominator = (line.x1 - line.x2) * (y1 - y2) - (line.y1 - line.y2) * (x1 - x2);
if(denominator !== 0) {
output.x = ((line.x1 * line.y2 - line.y1 * line.x2) * (x1 - x2) - (line.x1 - line.x2) * (x1 * y2 - y1 * x2)) / denominator;
output.y = ((line.x1 * line.y2 - line.y1 * line.x2) * (y1 - y2) - (line.y1 - line.y2) * (x1 * y2 - y1 * x2)) / denominator;
var maxX = Math.max(x1, x2);
var minX = Math.min(x1, x2);
var maxY = Math.max(y1, y2);
var minY = Math.min(y1, y2);
if((output.x <= maxX && output.x >= minX) === true || (output.y <= maxY && output.y >= minY) === true) {
output.result = true;
}
}
return output;
};
Collision.lineToRay = function lineToRay(line1, ray, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var denominator = (line1.x1 - line1.x2) * (ray.y1 - ray.y2) - (line1.y1 - line1.y2) * (ray.x1 - ray.x2);
if(denominator !== 0) {
output.x = ((line1.x1 * line1.y2 - line1.y1 * line1.x2) * (ray.x1 - ray.x2) - (line1.x1 - line1.x2) * (ray.x1 * ray.y2 - ray.y1 * ray.x2)) / denominator;
output.y = ((line1.x1 * line1.y2 - line1.y1 * line1.x2) * (ray.y1 - ray.y2) - (line1.y1 - line1.y2) * (ray.x1 * ray.y2 - ray.y1 * ray.x2)) / denominator;
output.result = true;
if(!(ray.x1 >= ray.x2) && output.x < ray.x1) {
output.result = false;
}
if(!(ray.y1 >= ray.y2) && output.y < ray.y1) {
output.result = false;
}
}
return output;
};
Collision.lineToCircle = function lineToCircle(line, circle, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
if(line.perp(circle.x, circle.y).length <= circle.radius) {
output.result = true;
}
return output;
};
Collision.lineToRectangle = function lineToRectangle(line, rect, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
Phaser.Collision.lineToRawSegment(line, rect.x, rect.y, rect.right, rect.y, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(line, rect.x, rect.y, rect.x, rect.bottom, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(line, rect.x, rect.bottom, rect.right, rect.bottom, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(line, rect.right, rect.y, rect.right, rect.bottom, output);
return output;
};
Collision.lineSegmentToLineSegment = function lineSegmentToLineSegment(line1, line2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
Phaser.Collision.lineToLineSegment(line1, line2);
if(output.result === true) {
if(!(output.x >= Math.min(line1.x1, line1.x2) && output.x <= Math.max(line1.x1, line1.x2) && output.y >= Math.min(line1.y1, line1.y2) && output.y <= Math.max(line1.y1, line1.y2))) {
output.result = false;
}
}
return output;
};
Collision.lineSegmentToRay = function lineSegmentToRay(line, ray, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
Phaser.Collision.lineToRay(line, ray, output);
if(output.result === true) {
if(!(output.x >= Math.min(line.x1, line.x2) && output.x <= Math.max(line.x1, line.x2) && output.y >= Math.min(line.y1, line.y2) && output.y <= Math.max(line.y1, line.y2))) {
output.result = false;
}
}
return output;
};
Collision.lineSegmentToCircle = function lineSegmentToCircle(seg, circle, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var perp = seg.perp(circle.x, circle.y);
if(perp.length <= circle.radius) {
var maxX = Math.max(seg.x1, seg.x2);
var minX = Math.min(seg.x1, seg.x2);
var maxY = Math.max(seg.y1, seg.y2);
var minY = Math.min(seg.y1, seg.y2);
if((perp.x2 <= maxX && perp.x2 >= minX) && (perp.y2 <= maxY && perp.y2 >= minY)) {
output.result = true;
} else {
if(Phaser.Collision.circleContainsPoint(circle, {
x: seg.x1,
y: seg.y1
}) || Phaser.Collision.circleContainsPoint(circle, {
x: seg.x2,
y: seg.y2
})) {
output.result = true;
}
}
}
return output;
};
Collision.lineSegmentToRectangle = function lineSegmentToRectangle(seg, rect, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
if(rect.contains(seg.x1, seg.y1) && rect.contains(seg.x2, seg.y2)) {
output.result = true;
} else {
Phaser.Collision.lineToRawSegment(seg, rect.x, rect.y, rect.right, rect.bottom, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(seg, rect.x, rect.y, rect.x, rect.bottom, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(seg, rect.x, rect.bottom, rect.right, rect.bottom, output);
if(output.result === true) {
return output;
}
Phaser.Collision.lineToRawSegment(seg, rect.right, rect.y, rect.right, rect.bottom, output);
return output;
}
return output;
};
Collision.rayToRectangle = function rayToRectangle(ray, rect, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
Phaser.Collision.lineToRectangle(ray, rect, output);
return output;
};
Collision.rayToLineSegment = function rayToLineSegment(rayX1, rayY1, rayX2, rayY2, lineX1, lineY1, lineX2, lineY2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var r;
var s;
var d;
if((rayY2 - rayY1) / (rayX2 - rayX1) != (lineY2 - lineY1) / (lineX2 - lineX1)) {
d = (((rayX2 - rayX1) * (lineY2 - lineY1)) - (rayY2 - rayY1) * (lineX2 - lineX1));
if(d != 0) {
r = (((rayY1 - lineY1) * (lineX2 - lineX1)) - (rayX1 - lineX1) * (lineY2 - lineY1)) / d;
s = (((rayY1 - lineY1) * (rayX2 - rayX1)) - (rayX1 - lineX1) * (rayY2 - rayY1)) / d;
if(r >= 0) {
if(s >= 0 && s <= 1) {
output.result = true;
output.x = rayX1 + r * (rayX2 - rayX1);
output.y = rayY1 + r * (rayY2 - rayY1);
}
}
}
}
return output;
};
Collision.pointToRectangle = function pointToRectangle(point, rect, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
output.setTo(point.x, point.y);
output.result = rect.containsPoint(point);
return output;
};
Collision.rectangleToRectangle = function rectangleToRectangle(rect1, rect2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var leftX = Math.max(rect1.x, rect2.x);
var rightX = Math.min(rect1.right, rect2.right);
var topY = Math.max(rect1.y, rect2.y);
var bottomY = Math.min(rect1.bottom, rect2.bottom);
output.setTo(leftX, topY, rightX - leftX, bottomY - topY, rightX - leftX, bottomY - topY);
var cx = output.x + output.width * .5;
var cy = output.y + output.height * .5;
if((cx > rect1.x && cx < rect1.right) && (cy > rect1.y && cy < rect1.bottom)) {
output.result = true;
}
return output;
};
Collision.rectangleToCircle = function rectangleToCircle(rect, circle, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
return Phaser.Collision.circleToRectangle(circle, rect, output);
};
Collision.circleToCircle = function circleToCircle(circle1, circle2, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
output.result = ((circle1.radius + circle2.radius) * (circle1.radius + circle2.radius)) >= Phaser.Collision.distanceSquared(circle1.x, circle1.y, circle2.x, circle2.y);
return output;
};
Collision.circleToRectangle = function circleToRectangle(circle, rect, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
var inflatedRect = rect.clone();
inflatedRect.inflate(circle.radius, circle.radius);
output.result = inflatedRect.contains(circle.x, circle.y);
return output;
};
Collision.circleContainsPoint = function circleContainsPoint(circle, point, output) {
if (typeof output === "undefined") { output = new Phaser.IntersectResult(); }
output.result = circle.radius * circle.radius >= Phaser.Collision.distanceSquared(circle.x, circle.y, point.x, point.y);
return output;
};
Collision.prototype.overlap = function (object1, object2, notifyCallback, processCallback, context) {
if (typeof object1 === "undefined") { object1 = null; }
if (typeof object2 === "undefined") { object2 = null; }
if (typeof notifyCallback === "undefined") { notifyCallback = null; }
if (typeof processCallback === "undefined") { processCallback = null; }
if (typeof context === "undefined") { context = null; }
if(object1 == null) {
object1 = this._game.world.group;
}
if(object2 == object1) {
object2 = null;
}
Phaser.QuadTree.divisions = this._game.world.worldDivisions;
var quadTree = new Phaser.QuadTree(this._game.world.bounds.x, this._game.world.bounds.y, this._game.world.bounds.width, this._game.world.bounds.height);
quadTree.load(object1, object2, notifyCallback, processCallback, context);
var result = quadTree.execute();
quadTree.destroy();
quadTree = null;
return result;
};
Collision.separate = function separate(object1, object2) {
object1.collisionMask.update();
object2.collisionMask.update();
var separatedX = Phaser.Collision.separateX(object1, object2);
var separatedY = Phaser.Collision.separateY(object1, object2);
return separatedX || separatedY;
};
Collision.separateTile = function separateTile(object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
object.collisionMask.update();
var separatedX = Phaser.Collision.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
var separatedY = Phaser.Collision.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
return separatedX || separatedY;
};
Collision.separateTileX = function separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separate) {
if(object.immovable) {
return false;
}
var overlap = 0;
var objDelta = object.x - object.last.x;
if(objDelta != 0) {
var objDeltaAbs = (objDelta > 0) ? objDelta : -objDelta;
var objBounds = new Phaser.Quad(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
if((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height)) {
var maxOverlap = objDeltaAbs + Phaser.Collision.OVERLAP_BIAS;
if(objDelta > 0) {
overlap = object.x + object.width - x;
if((overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.RIGHT) || collideLeft == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.RIGHT;
}
} else if(objDelta < 0) {
overlap = object.x - width - x;
if((-overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.LEFT) || collideRight == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.LEFT;
}
}
}
}
if(overlap != 0) {
if(separate == true) {
object.x = object.x - overlap;
object.velocity.x = -(object.velocity.x * object.elasticity);
}
Phaser.Collision.TILE_OVERLAP = true;
return true;
} else {
return false;
}
};
Collision.separateTileY = function separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separate) {
if(object.immovable) {
return false;
}
var overlap = 0;
var objDelta = object.y - object.last.y;
if(objDelta != 0) {
var objDeltaAbs = (objDelta > 0) ? objDelta : -objDelta;
var objBounds = new Phaser.Quad(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
if((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height)) {
var maxOverlap = objDeltaAbs + Phaser.Collision.OVERLAP_BIAS;
if(objDelta > 0) {
overlap = object.y + object.height - y;
if((overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.DOWN) || collideUp == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.DOWN;
}
} else if(objDelta < 0) {
overlap = object.y - height - y;
if((-overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.UP) || collideDown == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.UP;
}
}
}
}
if(overlap != 0) {
if(separate == true) {
object.y = object.y - overlap;
object.velocity.y = -(object.velocity.y * object.elasticity);
}
Phaser.Collision.TILE_OVERLAP = true;
return true;
} else {
return false;
}
};
Collision.NEWseparateTileX = function NEWseparateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separate) {
if(object.immovable) {
return false;
}
var overlap = 0;
if(object.collisionMask.deltaX != 0) {
if(object.collisionMask.intersectsRaw(x, x + width, y, y + height)) {
var maxOverlap = object.collisionMask.deltaXAbs + Phaser.Collision.OVERLAP_BIAS;
if(object.collisionMask.deltaX > 0) {
overlap = object.collisionMask.right - x;
if((overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.RIGHT) || collideLeft == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.RIGHT;
}
} else if(object.collisionMask.deltaX < 0) {
overlap = object.collisionMask.x - width - x;
if((-overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.LEFT) || collideRight == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.LEFT;
}
}
}
}
if(overlap != 0) {
if(separate == true) {
object.x = object.x - overlap;
object.velocity.x = -(object.velocity.x * object.elasticity);
}
Phaser.Collision.TILE_OVERLAP = true;
return true;
} else {
return false;
}
};
Collision.NEWseparateTileY = function NEWseparateTileY(object, x, y, width, height, mass, collideUp, collideDown, separate) {
if(object.immovable) {
return false;
}
var overlap = 0;
if(object.collisionMask.deltaY != 0) {
if(object.collisionMask.intersectsRaw(x, x + width, y, y + height)) {
var maxOverlap = object.collisionMask.deltaYAbs + Phaser.Collision.OVERLAP_BIAS;
if(object.collisionMask.deltaY > 0) {
overlap = object.collisionMask.bottom - y;
if((overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.DOWN) || collideUp == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.DOWN;
}
} else if(object.collisionMask.deltaY < 0) {
overlap = object.collisionMask.y - height - y;
if((-overlap > maxOverlap) || !(object.allowCollisions & Phaser.Collision.UP) || collideDown == false) {
overlap = 0;
} else {
object.touching |= Phaser.Collision.UP;
}
}
}
}
if(overlap != 0) {
if(separate == true) {
object.y = object.y - overlap;
object.velocity.y = -(object.velocity.y * object.elasticity);
}
Phaser.Collision.TILE_OVERLAP = true;
return true;
} else {
return false;
}
};
Collision.separateX = function separateX(object1, object2) {
if(object1.immovable && object2.immovable) {
return false;
}
var overlap = 0;
if(object1.collisionMask.deltaX != object2.collisionMask.deltaX) {
if(object1.collisionMask.intersects(object2.collisionMask)) {
var maxOverlap = object1.collisionMask.deltaXAbs + object2.collisionMask.deltaXAbs + Phaser.Collision.OVERLAP_BIAS;
if(object1.collisionMask.deltaX > object2.collisionMask.deltaX) {
overlap = object1.collisionMask.right - object2.collisionMask.x;
if((overlap > maxOverlap) || !(object1.allowCollisions & Phaser.Collision.RIGHT) || !(object2.allowCollisions & Phaser.Collision.LEFT)) {
overlap = 0;
} else {
object1.touching |= Phaser.Collision.RIGHT;
object2.touching |= Phaser.Collision.LEFT;
}
} else if(object1.collisionMask.deltaX < object2.collisionMask.deltaX) {
overlap = object1.collisionMask.x - object2.collisionMask.width - object2.collisionMask.x;
if((-overlap > maxOverlap) || !(object1.allowCollisions & Phaser.Collision.LEFT) || !(object2.allowCollisions & Phaser.Collision.RIGHT)) {
overlap = 0;
} else {
object1.touching |= Phaser.Collision.LEFT;
object2.touching |= Phaser.Collision.RIGHT;
}
}
}
}
if(overlap != 0) {
var obj1Velocity = object1.velocity.x;
var obj2Velocity = object2.velocity.x;
if(!object1.immovable && !object2.immovable) {
overlap *= 0.5;
object1.x = object1.x - overlap;
object2.x += overlap;
var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1);
var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1);
var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
obj1NewVelocity -= average;
obj2NewVelocity -= average;
object1.velocity.x = average + obj1NewVelocity * object1.elasticity;
object2.velocity.x = average + obj2NewVelocity * object2.elasticity;
} else if(!object1.immovable) {
object1.x = object1.x - overlap;
object1.velocity.x = obj2Velocity - obj1Velocity * object1.elasticity;
} else if(!object2.immovable) {
object2.x += overlap;
object2.velocity.x = obj1Velocity - obj2Velocity * object2.elasticity;
}
return true;
} else {
return false;
}
};
Collision.separateY = function separateY(object1, object2) {
if(object1.immovable && object2.immovable) {
return false;
}
var overlap = 0;
if(object1.collisionMask.deltaY != object2.collisionMask.deltaY) {
if(object1.collisionMask.intersects(object2.collisionMask)) {
var maxOverlap = object1.collisionMask.deltaYAbs + object2.collisionMask.deltaYAbs + Phaser.Collision.OVERLAP_BIAS;
if(object1.collisionMask.deltaY > object2.collisionMask.deltaY) {
overlap = object1.collisionMask.bottom - object2.collisionMask.y;
if((overlap > maxOverlap) || !(object1.allowCollisions & Phaser.Collision.DOWN) || !(object2.allowCollisions & Phaser.Collision.UP)) {
overlap = 0;
} else {
object1.touching |= Phaser.Collision.DOWN;
object2.touching |= Phaser.Collision.UP;
}
} else if(object1.collisionMask.deltaY < object2.collisionMask.deltaY) {
overlap = object1.collisionMask.y - object2.collisionMask.height - object2.collisionMask.y;
if((-overlap > maxOverlap) || !(object1.allowCollisions & Phaser.Collision.UP) || !(object2.allowCollisions & Phaser.Collision.DOWN)) {
overlap = 0;
} else {
object1.touching |= Phaser.Collision.UP;
object2.touching |= Phaser.Collision.DOWN;
}
}
}
}
if(overlap != 0) {
var obj1Velocity = object1.velocity.y;
var obj2Velocity = object2.velocity.y;
if(!object1.immovable && !object2.immovable) {
overlap *= 0.5;
object1.y = object1.y - overlap;
object2.y += overlap;
var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1);
var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1);
var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
obj1NewVelocity -= average;
obj2NewVelocity -= average;
object1.velocity.y = average + obj1NewVelocity * object1.elasticity;
object2.velocity.y = average + obj2NewVelocity * object2.elasticity;
} else if(!object1.immovable) {
object1.y = object1.y - overlap;
object1.velocity.y = obj2Velocity - obj1Velocity * object1.elasticity;
if(object2.active && object2.moves && (object1.collisionMask.deltaY > object2.collisionMask.deltaY)) {
object1.x += object2.x - object2.last.x;
}
} else if(!object2.immovable) {
object2.y += overlap;
object2.velocity.y = obj1Velocity - obj2Velocity * object2.elasticity;
if(object1.active && object1.moves && (object1.collisionMask.deltaY < object2.collisionMask.deltaY)) {
object2.x += object1.x - object1.last.x;
}
}
return true;
} else {
return false;
}
};
Collision.distance = function distance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
};
Collision.distanceSquared = function distanceSquared(x1, y1, x2, y2) {
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
};
Collision.flattenPointsOn = function flattenPointsOn(points, normal, result) {
var min = Number.MAX_VALUE;
var max = -Number.MAX_VALUE;
var len = points.length;
for(var i = 0; i < len; i++) {
var dot = points[i].dot(normal);
if(dot < min) {
min = dot;
}
if(dot > max) {
max = dot;
}
}
result[0] = min;
result[1] = max;
};
Collision.isSeparatingAxis = function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) {
if (typeof response === "undefined") { response = null; }
var rangeA = Phaser.Collision.T_ARRAYS.pop();
var rangeB = Phaser.Collision.T_ARRAYS.pop();
var offsetV = Phaser.Collision.T_VECTORS.pop().copyFrom(bPos).sub(aPos);
var projectedOffset = offsetV.dot(axis);
Phaser.Collision.flattenPointsOn(aPoints, axis, rangeA);
Phaser.Collision.flattenPointsOn(bPoints, axis, rangeB);
rangeB[0] += projectedOffset;
rangeB[1] += projectedOffset;
if(rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) {
Phaser.Collision.T_VECTORS.push(offsetV);
Phaser.Collision.T_ARRAYS.push(rangeA);
Phaser.Collision.T_ARRAYS.push(rangeB);
return true;
}
if(response) {
var overlap = 0;
if(rangeA[0] < rangeB[0]) {
response.aInB = false;
if(rangeA[1] < rangeB[1]) {
overlap = rangeA[1] - rangeB[0];
response.bInA = false;
} else {
var option1 = rangeA[1] - rangeB[0];
var option2 = rangeB[1] - rangeA[0];
overlap = option1 < option2 ? option1 : -option2;
}
} else {
response.bInA = false;
if(rangeA[1] > rangeB[1]) {
overlap = rangeA[0] - rangeB[1];
response.aInB = false;
} else {
var option1 = rangeA[1] - rangeB[0];
var option2 = rangeB[1] - rangeA[0];
overlap = option1 < option2 ? option1 : -option2;
}
}
var absOverlap = Math.abs(overlap);
if(absOverlap < response.overlap) {
response.overlap = absOverlap;
response.overlapN.copyFrom(axis);
if(overlap < 0) {
response.overlapN.reverse();
}
}
}
Phaser.Collision.T_VECTORS.push(offsetV);
Phaser.Collision.T_ARRAYS.push(rangeA);
Phaser.Collision.T_ARRAYS.push(rangeB);
return false;
};
Collision.LEFT_VORNOI_REGION = -1;
Collision.MIDDLE_VORNOI_REGION = 0;
Collision.RIGHT_VORNOI_REGION = 1;
Collision.vornoiRegion = function vornoiRegion(line, point) {
var len2 = line.length2();
var dp = point.dot(line);
if(dp < 0) {
return Phaser.Collision.LEFT_VORNOI_REGION;
} else if(dp > len2) {
return Phaser.Collision.RIGHT_VORNOI_REGION;
} else {
return Phaser.Collision.MIDDLE_VORNOI_REGION;
}
};
Collision.testCircleCircle = function testCircleCircle(a, b, response) {
if (typeof response === "undefined") { response = null; }
var differenceV = Phaser.Collision.T_VECTORS.pop().copyFrom(b.pos).sub(a.pos);
var totalRadius = a.radius + b.radius;
var totalRadiusSq = totalRadius * totalRadius;
var distanceSq = differenceV.length2();
if(distanceSq > totalRadiusSq) {
Phaser.Collision.T_VECTORS.push(differenceV);
return false;
}
if(response) {
var dist = Math.sqrt(distanceSq);
response.a = a;
response.b = b;
response.overlap = totalRadius - dist;
response.overlapN.copyFrom(differenceV.normalize());
response.overlapV.copyFrom(differenceV).scale(response.overlap);
response.aInB = a.radius <= b.radius && dist <= b.radius - a.radius;
response.bInA = b.radius <= a.radius && dist <= a.radius - b.radius;
}
Phaser.Collision.T_VECTORS.push(differenceV);
return true;
};
Collision.testPolygonCircle = function testPolygonCircle(polygon, circle, response) {
if (typeof response === "undefined") { response = null; }
var circlePos = Phaser.Collision.T_VECTORS.pop().copyFrom(circle.pos).sub(polygon.pos);
var radius = circle.radius;
var radius2 = radius * radius;
var points = polygon.points;
var len = points.length;
var edge = Collision.T_VECTORS.pop();
var point = Collision.T_VECTORS.pop();
for(var i = 0; i < len; i++) {
var next = i === len - 1 ? 0 : i + 1;
var prev = i === 0 ? len - 1 : i - 1;
var overlap = 0;
var overlapN = null;
edge.copyFrom(polygon.edges[i]);
point.copyFrom(circlePos).sub(points[i]);
if(response && point.length2() > radius2) {
response.aInB = false;
}
var region = Collision.vornoiRegion(edge, point);
if(region === Phaser.Collision.LEFT_VORNOI_REGION) {
edge.copyFrom(polygon.edges[prev]);
var point2 = Phaser.Collision.T_VECTORS.pop().copyFrom(circlePos).sub(points[prev]);
region = Collision.vornoiRegion(edge, point2);
if(region === Phaser.Collision.RIGHT_VORNOI_REGION) {
var dist = point.length2();
if(dist > radius) {
Phaser.Collision.T_VECTORS.push(circlePos);
Phaser.Collision.T_VECTORS.push(edge);
Phaser.Collision.T_VECTORS.push(point);
Phaser.Collision.T_VECTORS.push(point2);
return false;
} else if(response) {
response.bInA = false;
overlapN = point.normalize();
overlap = radius - dist;
}
}
Phaser.Collision.T_VECTORS.push(point2);
} else if(region === Phaser.Collision.RIGHT_VORNOI_REGION) {
edge.copyFrom(polygon.edges[next]);
point.copyFrom(circlePos).sub(points[next]);
region = Collision.vornoiRegion(edge, point);
if(region === Phaser.Collision.LEFT_VORNOI_REGION) {
var dist = point.length2();
if(dist > radius) {
Phaser.Collision.T_VECTORS.push(circlePos);
Phaser.Collision.T_VECTORS.push(edge);
Phaser.Collision.T_VECTORS.push(point);
return false;
} else if(response) {
response.bInA = false;
overlapN = point.normalize();
overlap = radius - dist;
}
}
} else {
var normal = edge.perp().normalize();
var dist = point.dot(normal);
var distAbs = Math.abs(dist);
if(dist > 0 && distAbs > radius) {
Phaser.Collision.T_VECTORS.push(circlePos);
Phaser.Collision.T_VECTORS.push(normal);
Phaser.Collision.T_VECTORS.push(point);
return false;
} else if(response) {
overlapN = normal;
overlap = radius - dist;
if(dist >= 0 || overlap < 2 * radius) {
response.bInA = false;
}
}
}
if(overlapN && response && Math.abs(overlap) < Math.abs(response.overlap)) {
response.overlap = overlap;
response.overlapN.copyFrom(overlapN);
}
}
if(response) {
response.a = polygon;
response.b = circle;
response.overlapV.copyFrom(response.overlapN).scale(response.overlap);
}
Phaser.Collision.T_VECTORS.push(circlePos);
Phaser.Collision.T_VECTORS.push(edge);
Phaser.Collision.T_VECTORS.push(point);
return true;
};
Collision.testCirclePolygon = function testCirclePolygon(circle, polygon, response) {
if (typeof response === "undefined") { response = null; }
var result = Phaser.Collision.testPolygonCircle(polygon, circle, response);
if(result && response) {
var a = response.a;
var aInB = response.aInB;
response.overlapN.reverse();
response.overlapV.reverse();
response.a = response.b;
response.b = a;
response.aInB = response.bInA;
response.bInA = aInB;
}
return result;
};
Collision.testPolygonPolygon = function testPolygonPolygon(a, b, response) {
if (typeof response === "undefined") { response = null; }
var aPoints = a.points;
var aLen = aPoints.length;
var bPoints = b.points;
var bLen = bPoints.length;
for(var i = 0; i < aLen; i++) {
if(Phaser.Collision.isSeparatingAxis(a.pos, b.pos, aPoints, bPoints, a.normals[i], response)) {
return false;
}
}
for(var i = 0; i < bLen; i++) {
if(Phaser.Collision.isSeparatingAxis(a.pos, b.pos, aPoints, bPoints, b.normals[i], response)) {
return false;
}
}
if(response) {
response.a = a;
response.b = b;
response.overlapV.copyFrom(response.overlapN).scale(response.overlap);
}
return true;
};
return Collision;
})();
Phaser.Collision = Collision;
})(Phaser || (Phaser = {}));
File diff suppressed because it is too large Load Diff
+365
View File
@@ -0,0 +1,365 @@
/// <reference path="../Game.ts" />
/**
* Phaser - CollisionMask
*/
var Phaser;
(function (Phaser) {
var CollisionMask = (function () {
/**
* CollisionMask constructor. Creates a new <code>CollisionMask</code> for the given GameObject.
*
* @param game {Phaser.Game} Current game instance.
* @param parent {Phaser.GameObject} The GameObject this CollisionMask belongs to.
* @param x {number} The initial x position of the CollisionMask.
* @param y {number} The initial y position of the CollisionMask.
* @param width {number} The width of the CollisionMask.
* @param height {number} The height of the CollisionMask.
*/
function CollisionMask(game, parent, x, y, width, height) {
/**
* Geom type of this sprite. (available: QUAD, POINT, CIRCLE, LINE, RECTANGLE, POLYGON)
* @type {number}
*/
this.type = 0;
this._game = game;
this._parent = parent;
// By default the CollisionMask is a quad
this.type = CollisionMask.QUAD;
this.quad = new Phaser.Quad(this._parent.x, this._parent.y, this._parent.width, this._parent.height);
this.offset = new Phaser.MicroPoint(0, 0);
this.last = new Phaser.MicroPoint(0, 0);
this._ref = this.quad;
return this;
}
CollisionMask.QUAD = 0;
CollisionMask.POINT = 1;
CollisionMask.CIRCLE = 2;
CollisionMask.LINE = 3;
CollisionMask.RECTANGLE = 4;
CollisionMask.POLYGON = 5;
CollisionMask.prototype.createCircle = /**
* Create a circle shape with specific diameter.
* @param diameter {number} Diameter of the circle.
* @return {CollisionMask} This
*/
function (diameter) {
this.type = CollisionMask.CIRCLE;
this.circle = new Phaser.Circle(this.last.x, this.last.y, diameter);
this._ref = this.circle;
return this;
};
CollisionMask.prototype.preUpdate = /**
* Pre-update is called right before update() on each object in the game loop.
*/
function () {
this.last.x = this.x;
this.last.y = this.y;
};
CollisionMask.prototype.update = function () {
this._ref.x = this._parent.x + this.offset.x;
this._ref.y = this._parent.y + this.offset.y;
};
CollisionMask.prototype.render = /**
* Renders the bounding box around this Sprite and the contact points. Useful for visually debugging.
* @param camera {Camera} Camera the bound will be rendered to.
* @param cameraOffsetX {number} X offset of bound to the camera.
* @param cameraOffsetY {number} Y offset of bound to the camera.
*/
function (camera, cameraOffsetX, cameraOffsetY) {
var _dx = cameraOffsetX + (this.x - camera.worldView.x);
var _dy = cameraOffsetY + (this.y - camera.worldView.y);
this._parent.context.fillStyle = this._parent.renderDebugColor;
if(this.type == CollisionMask.QUAD) {
this._parent.context.fillRect(_dx, _dy, this.width, this.height);
} else if(this.type == CollisionMask.CIRCLE) {
this._parent.context.beginPath();
this._parent.context.arc(_dx, _dy, this.circle.radius, 0, Math.PI * 2);
this._parent.context.fill();
this._parent.context.closePath();
}
};
CollisionMask.prototype.destroy = /**
* Destroy all objects and references belonging to this CollisionMask
*/
function () {
this._game = null;
this._parent = null;
this._ref = null;
this.quad = null;
this.point = null;
this.circle = null;
this.rect = null;
this.line = null;
this.offset = null;
};
CollisionMask.prototype.intersectsRaw = function (left, right, top, bottom) {
//if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
return true;
};
CollisionMask.prototype.intersectsVector = function (vector) {
if(this.type == CollisionMask.QUAD) {
return this.quad.contains(vector.x, vector.y);
}
};
CollisionMask.prototype.intersects = /**
* Gives a basic boolean response to a geometric collision.
* If you need the details of the collision use the Collision functions instead and inspect the IntersectResult object.
* @param source {GeomSprite} Sprite you want to check.
* @return {boolean} Whether they overlaps or not.
*/
function (source) {
// Quad vs. Quad
if(this.type == CollisionMask.QUAD && source.type == CollisionMask.QUAD) {
return this.quad.intersects(source.quad);
}
// Circle vs. Circle
if(this.type == CollisionMask.CIRCLE && source.type == CollisionMask.CIRCLE) {
return Phaser.Collision.circleToCircle(this.circle, source.circle).result;
}
// Circle vs. Rect
if(this.type == CollisionMask.CIRCLE && source.type == CollisionMask.RECTANGLE) {
return Phaser.Collision.circleToRectangle(this.circle, source.rect).result;
}
// Circle vs. Point
if(this.type == CollisionMask.CIRCLE && source.type == CollisionMask.POINT) {
return Phaser.Collision.circleContainsPoint(this.circle, source.point).result;
}
// Circle vs. Line
if(this.type == CollisionMask.CIRCLE && source.type == CollisionMask.LINE) {
return Phaser.Collision.lineToCircle(source.line, this.circle).result;
}
// Rect vs. Rect
if(this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.RECTANGLE) {
return Phaser.Collision.rectangleToRectangle(this.rect, source.rect).result;
}
// Rect vs. Circle
if(this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.CIRCLE) {
return Phaser.Collision.circleToRectangle(source.circle, this.rect).result;
}
// Rect vs. Point
if(this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.POINT) {
return Phaser.Collision.pointToRectangle(source.point, this.rect).result;
}
// Rect vs. Line
if(this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.LINE) {
return Phaser.Collision.lineToRectangle(source.line, this.rect).result;
}
// Point vs. Point
if(this.type == CollisionMask.POINT && source.type == CollisionMask.POINT) {
return this.point.equals(source.point);
}
// Point vs. Circle
if(this.type == CollisionMask.POINT && source.type == CollisionMask.CIRCLE) {
return Phaser.Collision.circleContainsPoint(source.circle, this.point).result;
}
// Point vs. Rect
if(this.type == CollisionMask.POINT && source.type == CollisionMask.RECTANGLE) {
return Phaser.Collision.pointToRectangle(this.point, source.rect).result;
}
// Point vs. Line
if(this.type == CollisionMask.POINT && source.type == CollisionMask.LINE) {
return source.line.isPointOnLine(this.point.x, this.point.y);
}
// Line vs. Line
if(this.type == CollisionMask.LINE && source.type == CollisionMask.LINE) {
return Phaser.Collision.lineSegmentToLineSegment(this.line, source.line).result;
}
// Line vs. Circle
if(this.type == CollisionMask.LINE && source.type == CollisionMask.CIRCLE) {
return Phaser.Collision.lineToCircle(this.line, source.circle).result;
}
// Line vs. Rect
if(this.type == CollisionMask.LINE && source.type == CollisionMask.RECTANGLE) {
return Phaser.Collision.lineSegmentToRectangle(this.line, source.rect).result;
}
// Line vs. Point
if(this.type == CollisionMask.LINE && source.type == CollisionMask.POINT) {
return this.line.isPointOnLine(source.point.x, source.point.y);
}
return false;
};
CollisionMask.prototype.checkHullIntersection = function (mask) {
if((this.hullX + this.hullWidth > mask.hullX) && (this.hullX < mask.hullX + mask.width) && (this.hullY + this.hullHeight > mask.hullY) && (this.hullY < mask.hullY + mask.hullHeight)) {
return true;
} else {
return false;
}
};
Object.defineProperty(CollisionMask.prototype, "hullWidth", {
get: function () {
if(this.deltaX > 0) {
return this.width + this.deltaX;
} else {
return this.width - this.deltaX;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "hullHeight", {
get: function () {
if(this.deltaY > 0) {
return this.height + this.deltaY;
} else {
return this.height - this.deltaY;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "hullX", {
get: function () {
if(this.x < this.last.x) {
return this.x;
} else {
return this.last.x;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "hullY", {
get: function () {
if(this.y < this.last.y) {
return this.y;
} else {
return this.last.y;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "deltaXAbs", {
get: function () {
return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "deltaYAbs", {
get: function () {
return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "deltaX", {
get: function () {
return this.x - this.last.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "deltaY", {
get: function () {
return this.y - this.last.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "x", {
get: function () {
return this._ref.x;
//return this.quad.x;
},
set: function (value) {
this._ref.x = value;
//this.quad.x = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "y", {
get: function () {
return this._ref.y;
//return this.quad.y;
},
set: function (value) {
this._ref.y = value;
//this.quad.y = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "width", {
get: function () {
//return this.quad.width;
return this._ref.width;
},
set: //public get rotation(): number {
// return this._angle;
//}
//public set rotation(value: number) {
// this._angle = this._game.math.wrap(value, 360, 0);
//}
//public get angle(): number {
// return this._angle;
//}
//public set angle(value: number) {
// this._angle = this._game.math.wrap(value, 360, 0);
//}
function (value) {
//this.quad.width = value;
this._ref.width = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "height", {
get: function () {
//return this.quad.height;
return this._ref.height;
},
set: function (value) {
//this.quad.height = value;
this._ref.height = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "left", {
get: function () {
return this.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "right", {
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "top", {
get: function () {
return this.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "halfWidth", {
get: function () {
return this.width / 2;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CollisionMask.prototype, "halfHeight", {
get: function () {
return this.height / 2;
},
enumerable: true,
configurable: true
});
return CollisionMask;
})();
Phaser.CollisionMask = CollisionMask;
})(Phaser || (Phaser = {}));
+501
View File
@@ -0,0 +1,501 @@
/// <reference path="../Game.ts" />
/**
* Phaser - CollisionMask
*/
module Phaser {
export class CollisionMask {
/**
* CollisionMask constructor. Creates a new <code>CollisionMask</code> for the given GameObject.
*
* @param game {Phaser.Game} Current game instance.
* @param parent {Phaser.GameObject} The GameObject this CollisionMask belongs to.
* @param x {number} The initial x position of the CollisionMask.
* @param y {number} The initial y position of the CollisionMask.
* @param width {number} The width of the CollisionMask.
* @param height {number} The height of the CollisionMask.
*/
constructor(game: Game, parent: GameObject, x: number, y: number, width: number, height: number) {
this._game = game;
this._parent = parent;
// By default the CollisionMask is a quad
this.type = CollisionMask.QUAD;
this.quad = new Phaser.Quad(this._parent.x, this._parent.y, this._parent.width, this._parent.height);
this.offset = new MicroPoint(0, 0);
this.last = new MicroPoint(0, 0);
this._ref = this.quad;
return this;
}
private _game;
private _parent;
// An internal reference to the active collision shape
private _ref;
/**
* Geom type of this sprite. (available: QUAD, POINT, CIRCLE, LINE, RECTANGLE, POLYGON)
* @type {number}
*/
public type: number = 0;
/**
* Quad (a smaller version of Rectangle).
* @type {number}
*/
public static QUAD: number = 0;
/**
* Point.
* @type {number}
*/
public static POINT: number = 1;
/**
* Circle.
* @type {number}
*/
public static CIRCLE: number = 2;
/**
* Line.
* @type {number}
*/
public static LINE: number = 3;
/**
* Rectangle.
* @type {number}
*/
public static RECTANGLE: number = 4;
/**
* Polygon.
* @type {number}
*/
public static POLYGON: number = 5;
/**
* Rectangle shape container. A Rectangle instance.
* @type {Rectangle}
*/
public quad: Quad;
/**
* Point shape container. A Point instance.
* @type {Point}
*/
public point: Point;
/**
* Circle shape container. A Circle instance.
* @type {Circle}
*/
public circle: Circle;
/**
* Line shape container. A Line instance.
* @type {Line}
*/
public line: Line;
/**
* Rectangle shape container. A Rectangle instance.
* @type {Rectangle}
*/
public rect: Rectangle;
/**
* A value from the top-left of the GameObject frame that this collisionMask is offset to.
* If the CollisionMask is a Quad/Rectangle the offset relates to the top-left of that Quad.
* If the CollisionMask is a Circle the offset relates to the center of the circle.
* @type {MicroPoint}
*/
public offset: MicroPoint;
/**
* The previous x/y coordinates of the CollisionMask, used for hull calculations
* @type {MicroPoint}
*/
public last: MicroPoint;
/**
* Create a circle shape with specific diameter.
* @param diameter {number} Diameter of the circle.
* @return {CollisionMask} This
*/
createCircle(diameter: number): CollisionMask {
this.type = CollisionMask.CIRCLE;
this.circle = new Circle(this.last.x, this.last.y, diameter);
this._ref = this.circle;
return this;
}
/**
* Pre-update is called right before update() on each object in the game loop.
*/
public preUpdate() {
this.last.x = this.x;
this.last.y = this.y;
}
public update() {
this._ref.x = this._parent.x + this.offset.x;
this._ref.y = this._parent.y + this.offset.y;
}
/**
* Renders the bounding box around this Sprite and the contact points. Useful for visually debugging.
* @param camera {Camera} Camera the bound will be rendered to.
* @param cameraOffsetX {number} X offset of bound to the camera.
* @param cameraOffsetY {number} Y offset of bound to the camera.
*/
public render(camera:Camera, cameraOffsetX:number, cameraOffsetY:number) {
var _dx = cameraOffsetX + (this.x - camera.worldView.x);
var _dy = cameraOffsetY + (this.y - camera.worldView.y);
this._parent.context.fillStyle = this._parent.renderDebugColor;
if (this.type == CollisionMask.QUAD)
{
this._parent.context.fillRect(_dx, _dy, this.width, this.height);
}
else if (this.type == CollisionMask.CIRCLE)
{
this._parent.context.beginPath();
this._parent.context.arc(_dx, _dy, this.circle.radius, 0, Math.PI * 2);
this._parent.context.fill();
this._parent.context.closePath();
}
}
/**
* Destroy all objects and references belonging to this CollisionMask
*/
public destroy() {
this._game = null;
this._parent = null;
this._ref = null;
this.quad = null;
this.point = null;
this.circle = null;
this.rect = null;
this.line = null;
this.offset = null;
}
public intersectsRaw(left: number, right: number, top: number, bottom: number): bool {
//if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
return true;
}
public intersectsVector(vector: Phaser.Vector2): bool {
if (this.type == CollisionMask.QUAD)
{
return this.quad.contains(vector.x, vector.y);
}
}
/**
* Gives a basic boolean response to a geometric collision.
* If you need the details of the collision use the Collision functions instead and inspect the IntersectResult object.
* @param source {GeomSprite} Sprite you want to check.
* @return {boolean} Whether they overlaps or not.
*/
public intersects(source: CollisionMask): bool {
// Quad vs. Quad
if (this.type == CollisionMask.QUAD && source.type == CollisionMask.QUAD)
{
return this.quad.intersects(source.quad);
}
// Circle vs. Circle
if (this.type == CollisionMask.CIRCLE && source.type == CollisionMask.CIRCLE)
{
return Collision.circleToCircle(this.circle, source.circle).result;
}
// Circle vs. Rect
if (this.type == CollisionMask.CIRCLE && source.type == CollisionMask.RECTANGLE)
{
return Collision.circleToRectangle(this.circle, source.rect).result;
}
// Circle vs. Point
if (this.type == CollisionMask.CIRCLE && source.type == CollisionMask.POINT)
{
return Collision.circleContainsPoint(this.circle, source.point).result;
}
// Circle vs. Line
if (this.type == CollisionMask.CIRCLE && source.type == CollisionMask.LINE)
{
return Collision.lineToCircle(source.line, this.circle).result;
}
// Rect vs. Rect
if (this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.RECTANGLE)
{
return Collision.rectangleToRectangle(this.rect, source.rect).result;
}
// Rect vs. Circle
if (this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.CIRCLE)
{
return Collision.circleToRectangle(source.circle, this.rect).result;
}
// Rect vs. Point
if (this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.POINT)
{
return Collision.pointToRectangle(source.point, this.rect).result;
}
// Rect vs. Line
if (this.type == CollisionMask.RECTANGLE && source.type == CollisionMask.LINE)
{
return Collision.lineToRectangle(source.line, this.rect).result;
}
// Point vs. Point
if (this.type == CollisionMask.POINT && source.type == CollisionMask.POINT)
{
return this.point.equals(source.point);
}
// Point vs. Circle
if (this.type == CollisionMask.POINT && source.type == CollisionMask.CIRCLE)
{
return Collision.circleContainsPoint(source.circle, this.point).result;
}
// Point vs. Rect
if (this.type == CollisionMask.POINT && source.type == CollisionMask.RECTANGLE)
{
return Collision.pointToRectangle(this.point, source.rect).result;
}
// Point vs. Line
if (this.type == CollisionMask.POINT && source.type == CollisionMask.LINE)
{
return source.line.isPointOnLine(this.point.x, this.point.y);
}
// Line vs. Line
if (this.type == CollisionMask.LINE && source.type == CollisionMask.LINE)
{
return Collision.lineSegmentToLineSegment(this.line, source.line).result;
}
// Line vs. Circle
if (this.type == CollisionMask.LINE && source.type == CollisionMask.CIRCLE)
{
return Collision.lineToCircle(this.line, source.circle).result;
}
// Line vs. Rect
if (this.type == CollisionMask.LINE && source.type == CollisionMask.RECTANGLE)
{
return Collision.lineSegmentToRectangle(this.line, source.rect).result;
}
// Line vs. Point
if (this.type == CollisionMask.LINE && source.type == CollisionMask.POINT)
{
return this.line.isPointOnLine(source.point.x, source.point.y);
}
return false;
}
public checkHullIntersection(mask: CollisionMask): bool {
if ((this.hullX + this.hullWidth > mask.hullX) && (this.hullX < mask.hullX + mask.width) && (this.hullY + this.hullHeight > mask.hullY) && (this.hullY < mask.hullY + mask.hullHeight))
{
return true;
}
else
{
return false;
}
}
public get hullWidth(): number {
if (this.deltaX > 0)
{
return this.width + this.deltaX;
}
else
{
return this.width - this.deltaX;
}
}
public get hullHeight(): number {
if (this.deltaY > 0)
{
return this.height + this.deltaY;
}
else
{
return this.height - this.deltaY;
}
}
public get hullX(): number {
if (this.x < this.last.x)
{
return this.x;
}
else
{
return this.last.x;
}
}
public get hullY(): number {
if (this.y < this.last.y)
{
return this.y;
}
else
{
return this.last.y;
}
}
public get deltaXAbs(): number {
return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
}
public get deltaYAbs(): number {
return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
}
public get deltaX(): number {
return this.x - this.last.x;
}
public get deltaY(): number {
return this.y - this.last.y;
}
public get x(): number {
return this._ref.x;
//return this.quad.x;
}
public set x(value: number) {
this._ref.x = value;
//this.quad.x = value;
}
public get y(): number {
return this._ref.y;
//return this.quad.y;
}
public set y(value: number) {
this._ref.y = value;
//this.quad.y = value;
}
//public get rotation(): number {
// return this._angle;
//}
//public set rotation(value: number) {
// this._angle = this._game.math.wrap(value, 360, 0);
//}
//public get angle(): number {
// return this._angle;
//}
//public set angle(value: number) {
// this._angle = this._game.math.wrap(value, 360, 0);
//}
public set width(value:number) {
//this.quad.width = value;
this._ref.width = value;
}
public set height(value:number) {
//this.quad.height = value;
this._ref.height = value;
}
public get width(): number {
//return this.quad.width;
return this._ref.width;
}
public get height(): number {
//return this.quad.height;
return this._ref.height;
}
public get left(): number {
return this.x;
}
public get right(): number {
return this.x + this.width;
}
public get top(): number {
return this.y;
}
public get bottom(): number {
return this.y + this.height;
}
public get halfWidth(): number {
return this.width / 2;
}
public get halfHeight(): number {
return this.height / 2;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+90
View File
@@ -0,0 +1,90 @@
/**
* Phaser - Components - Debug
*
*
*/
module Phaser.Components {
export class Debug {
/**
* Render bound of this sprite for debugging? (default to false)
* @type {boolean}
*/
public renderDebug: bool = false;
/**
* Color of the Sprite when no image is present. Format is a css color string.
* @type {string}
*/
public fillColor: string = 'rgb(255,255,255)';
/**
* Color of bound when render debug. (see renderDebug) Format is a css color string.
* @type {string}
*/
public renderDebugColor: string = 'rgba(0,255,0,0.5)';
/**
* Color of points when render debug. (see renderDebug) Format is a css color string.
* @type {string}
*/
public renderDebugPointColor: string = 'rgba(255,255,255,1)';
/**
* Renders the bounding box around this Sprite and the contact points. Useful for visually debugging.
* @param camera {Camera} Camera the bound will be rendered to.
* @param cameraOffsetX {number} X offset of bound to the camera.
* @param cameraOffsetY {number} Y offset of bound to the camera.
*/
/*
private renderBounds(camera: Camera, cameraOffsetX: number, cameraOffsetY: number) {
this._dx = cameraOffsetX + (this.frameBounds.topLeft.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.frameBounds.topLeft.y - camera.worldView.y);
this.context.fillStyle = this.renderDebugColor;
this.context.fillRect(this._dx, this._dy, this.frameBounds.width, this.frameBounds.height);
//this.context.fillStyle = this.renderDebugPointColor;
//var hw = this.frameBounds.halfWidth * this.scale.x;
//var hh = this.frameBounds.halfHeight * this.scale.y;
//var sw = (this.frameBounds.width * this.scale.x) - 1;
//var sh = (this.frameBounds.height * this.scale.y) - 1;
//this.context.fillRect(this._dx, this._dy, 1, 1); // top left
//this.context.fillRect(this._dx + hw, this._dy, 1, 1); // top center
//this.context.fillRect(this._dx + sw, this._dy, 1, 1); // top right
//this.context.fillRect(this._dx, this._dy + hh, 1, 1); // left center
//this.context.fillRect(this._dx + hw, this._dy + hh, 1, 1); // center
//this.context.fillRect(this._dx + sw, this._dy + hh, 1, 1); // right center
//this.context.fillRect(this._dx, this._dy + sh, 1, 1); // bottom left
//this.context.fillRect(this._dx + hw, this._dy + sh, 1, 1); // bottom center
//this.context.fillRect(this._dx + sw, this._dy + sh, 1, 1); // bottom right
}
*/
/**
* Render debug infos. (including name, bounds info, position and some other properties)
* @param x {number} X position of the debug info to be rendered.
* @param y {number} Y position of the debug info to be rendered.
* @param [color] {number} color of the debug info to be rendered. (format is css color string)
*/
/*
public renderDebugInfo(x: number, y: number, color?: string = 'rgb(255,255,255)') {
this.context.fillStyle = color;
this.context.fillText('Sprite: ' + this.name + ' (' + this.frameBounds.width + ' x ' + this.frameBounds.height + ')', x, y);
this.context.fillText('x: ' + this.frameBounds.x.toFixed(1) + ' y: ' + this.frameBounds.y.toFixed(1) + ' rotation: ' + this.angle.toFixed(1), x, y + 14);
this.context.fillText('dx: ' + this._dx.toFixed(1) + ' dy: ' + this._dy.toFixed(1) + ' dw: ' + this._dw.toFixed(1) + ' dh: ' + this._dh.toFixed(1), x, y + 28);
this.context.fillText('sx: ' + this._sx.toFixed(1) + ' sy: ' + this._sy.toFixed(1) + ' sw: ' + this._sw.toFixed(1) + ' sh: ' + this._sh.toFixed(1), x, y + 42);
}
*/
}
}
+183
View File
@@ -0,0 +1,183 @@
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Phaser;
(function (Phaser) {
var Emitter = (function (_super) {
__extends(Emitter, _super);
function Emitter(game, x, y, size) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof size === "undefined") { size = 0; }
_super.call(this, game, size);
this.x = x;
this.y = y;
this.width = 0;
this.height = 0;
this.minParticleSpeed = new MicroPoint(-100, -100);
this.maxParticleSpeed = new MicroPoint(100, 100);
this.minRotation = -360;
this.maxRotation = 360;
this.gravity = 0;
this.particleClass = null;
this.particleDrag = new MicroPoint();
this.frequency = 0.1;
this.lifespan = 3;
this.bounce = 0;
this._quantity = 0;
this._counter = 0;
this._explode = true;
this.on = false;
this._point = new MicroPoint();
}
Emitter.prototype.destroy = function () {
this.minParticleSpeed = null;
this.maxParticleSpeed = null;
this.particleDrag = null;
this.particleClass = null;
this._point = null;
_super.prototype.destroy.call(this);
};
Emitter.prototype.makeParticles = function (graphics, quantity, multiple, collide) {
if (typeof quantity === "undefined") { quantity = 50; }
if (typeof multiple === "undefined") { multiple = false; }
if (typeof collide === "undefined") { collide = 0; }
this.maxSize = quantity;
var totalFrames = 1;
var randomFrame;
var particle;
var i = 0;
while(i < quantity) {
if(this.particleClass == null) {
particle = new Phaser.Particle(this._game);
} else {
particle = new this.particleClass(this._game);
}
if(multiple) {
} else {
if(graphics) {
particle.loadGraphic(graphics);
}
}
if(collide > 0) {
particle.allowCollisions = Phaser.Collision.ANY;
particle.width *= collide;
particle.height *= collide;
} else {
particle.allowCollisions = Phaser.Collision.NONE;
}
particle.exists = false;
this.add(particle);
i++;
}
return this;
};
Emitter.prototype.update = function () {
if(this.on) {
if(this._explode) {
this.on = false;
var i = 0;
var l = this._quantity;
if((l <= 0) || (l > this.length)) {
l = this.length;
}
while(i < l) {
this.emitParticle();
i++;
}
this._quantity = 0;
} else {
this._timer += this._game.time.elapsed;
while((this.frequency > 0) && (this._timer > this.frequency) && this.on) {
this._timer -= this.frequency;
this.emitParticle();
if((this._quantity > 0) && (++this._counter >= this._quantity)) {
this.on = false;
this._quantity = 0;
}
}
}
}
_super.prototype.update.call(this);
};
Emitter.prototype.kill = function () {
this.on = false;
_super.prototype.kill.call(this);
};
Emitter.prototype.start = function (explode, lifespan, frequency, quantity) {
if (typeof explode === "undefined") { explode = true; }
if (typeof lifespan === "undefined") { lifespan = 0; }
if (typeof frequency === "undefined") { frequency = 0.1; }
if (typeof quantity === "undefined") { quantity = 0; }
this.revive();
this.visible = true;
this.on = true;
this._explode = explode;
this.lifespan = lifespan;
this.frequency = frequency;
this._quantity += quantity;
this._counter = 0;
this._timer = 0;
};
Emitter.prototype.emitParticle = function () {
var particle = this.recycle(Phaser.Particle);
particle.lifespan = this.lifespan;
particle.elasticity = this.bounce;
particle.reset(this.x - (particle.width >> 1) + this._game.math.random() * this.width, this.y - (particle.height >> 1) + this._game.math.random() * this.height);
particle.visible = true;
if(this.minParticleSpeed.x != this.maxParticleSpeed.x) {
particle.velocity.x = this.minParticleSpeed.x + this._game.math.random() * (this.maxParticleSpeed.x - this.minParticleSpeed.x);
} else {
particle.velocity.x = this.minParticleSpeed.x;
}
if(this.minParticleSpeed.y != this.maxParticleSpeed.y) {
particle.velocity.y = this.minParticleSpeed.y + this._game.math.random() * (this.maxParticleSpeed.y - this.minParticleSpeed.y);
} else {
particle.velocity.y = this.minParticleSpeed.y;
}
particle.acceleration.y = this.gravity;
if(this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0) {
particle.angularVelocity = this.minRotation + this._game.math.random() * (this.maxRotation - this.minRotation);
} else {
particle.angularVelocity = this.minRotation;
}
if(particle.angularVelocity != 0) {
particle.angle = this._game.math.random() * 360 - 180;
}
particle.drag.x = this.particleDrag.x;
particle.drag.y = this.particleDrag.y;
particle.onEmit();
};
Emitter.prototype.setSize = function (width, height) {
this.width = width;
this.height = height;
};
Emitter.prototype.setXSpeed = function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minParticleSpeed.x = min;
this.maxParticleSpeed.x = max;
};
Emitter.prototype.setYSpeed = function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minParticleSpeed.y = min;
this.maxParticleSpeed.y = max;
};
Emitter.prototype.setRotation = function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minRotation = min;
this.maxRotation = max;
};
Emitter.prototype.at = function (object) {
object.getMidpoint(this._point);
this.x = this._point.x - (this.width >> 1);
this.y = this._point.y - (this.height >> 1);
};
return Emitter;
})(Phaser.Group);
Phaser.Emitter = Emitter;
})(Phaser || (Phaser = {}));
+454
View File
@@ -0,0 +1,454 @@
/// <reference path="../Game.ts" />
/// <reference path="../Group.ts" />
/**
* Phaser - Emitter
*
* Emitter is a lightweight particle emitter. It can be used for one-time explosions or for
* continuous effects like rain and fire. All it really does is launch Particle objects out
* at set intervals, and fixes their positions and velocities accorindgly.
*/
module Phaser {
export class Emitter extends Group {
/**
* Creates a new <code>Emitter</code> object at a specific position.
* Does NOT automatically generate or attach particles!
*
* @param x {number} The X position of the emitter.
* @param y {number} The Y position of the emitter.
* @param [size] {number} Specifies a maximum capacity for this emitter.
*/
constructor(game: Game, x: number = 0, y: number = 0, size: number = 0) {
super(game, size);
this.x = x;
this.y = y;
this.width = 0;
this.height = 0;
this.minParticleSpeed = new MicroPoint(-100, -100);
this.maxParticleSpeed = new MicroPoint(100, 100);
this.minRotation = -360;
this.maxRotation = 360;
this.gravity = 0;
this.particleClass = null;
this.particleDrag = new MicroPoint();
this.frequency = 0.1;
this.lifespan = 3;
this.bounce = 0;
this._quantity = 0;
this._counter = 0;
this._explode = true;
this.on = false;
this._point = new MicroPoint();
}
/**
* The X position of the top left corner of the emitter in world space.
*/
public x: number;
/**
* The Y position of the top left corner of emitter in world space.
*/
public y: number;
/**
* The width of the emitter. Particles can be randomly generated from anywhere within this box.
*/
public width: number;
/**
* The height of the emitter. Particles can be randomly generated from anywhere within this box.
*/
public height: number;
/**
* The minimum possible velocity of a particle.
* The default value is (-100,-100).
*/
public minParticleSpeed: MicroPoint;
/**
* The maximum possible velocity of a particle.
* The default value is (100,100).
*/
public maxParticleSpeed: MicroPoint;
/**
* The X and Y drag component of particles launched from the emitter.
*/
public particleDrag: MicroPoint;
/**
* The minimum possible angular velocity of a particle. The default value is -360.
* NOTE: rotating particles are more expensive to draw than non-rotating ones!
*/
public minRotation: number;
/**
* The maximum possible angular velocity of a particle. The default value is 360.
* NOTE: rotating particles are more expensive to draw than non-rotating ones!
*/
public maxRotation: number;
/**
* Sets the <code>acceleration.y</code> member of each particle to this value on launch.
*/
public gravity: number;
/**
* Determines whether the emitter is currently emitting particles.
* It is totally safe to directly toggle this.
*/
public on: bool;
/**
* How often a particle is emitted (if emitter is started with Explode == false).
*/
public frequency: number;
/**
* How long each particle lives once it is emitted.
* Set lifespan to 'zero' for particles to live forever.
*/
public lifespan: number;
/**
* How much each particle should bounce. 1 = full bounce, 0 = no bounce.
*/
public bounce: number;
/**
* Set your own particle class type here.
* Default is <code>Particle</code>.
*/
public particleClass;
/**
* Internal helper for deciding how many particles to launch.
*/
private _quantity: number;
/**
* Internal helper for the style of particle emission (all at once, or one at a time).
*/
private _explode: bool;
/**
* Internal helper for deciding when to launch particles or kill them.
*/
private _timer: number;
/**
* Internal counter for figuring out how many particles to launch.
*/
private _counter: number;
/**
* Internal point object, handy for reusing for memory mgmt purposes.
*/
private _point: MicroPoint;
/**
* Clean up memory.
*/
public destroy() {
this.minParticleSpeed = null;
this.maxParticleSpeed = null;
this.particleDrag = null;
this.particleClass = null;
this._point = null;
super.destroy();
}
/**
* This function generates a new array of particle sprites to attach to the emitter.
*
* @param graphics If you opted to not pre-configure an array of Sprite objects, you can simply pass in a particle image or sprite sheet.
* @param quantity {number} The number of particles to generate when using the "create from image" option.
* @param multiple {boolean} Whether the image in the Graphics param is a single particle or a bunch of particles (if it's a bunch, they need to be square!).
* @param collide {number} Whether the particles should be flagged as not 'dead' (non-colliding particles are higher performance). 0 means no collisions, 0-1 controls scale of particle's bounding box.
*
* @return This Emitter instance (nice for chaining stuff together, if you're into that).
*/
public makeParticles(graphics, quantity: number = 50, multiple: bool = false, collide: number = 0): Emitter {
this.maxSize = quantity;
var totalFrames: number = 1;
/*
if(Multiple)
{
var sprite:Sprite = new Sprite(this._game);
sprite.loadGraphic(Graphics,true);
totalFrames = sprite.frames;
sprite.destroy();
}
*/
var randomFrame: number;
var particle: Particle;
var i: number = 0;
while (i < quantity)
{
if (this.particleClass == null)
{
particle = new Particle(this._game);
}
else
{
particle = new this.particleClass(this._game);
}
if (multiple)
{
/*
randomFrame = this._game.math.random()*totalFrames;
if(BakedRotations > 0)
particle.loadRotatedGraphic(Graphics,BakedRotations,randomFrame);
else
{
particle.loadGraphic(Graphics,true);
particle.frame = randomFrame;
}
*/
}
else
{
/*
if (BakedRotations > 0)
particle.loadRotatedGraphic(Graphics,BakedRotations);
else
particle.loadGraphic(Graphics);
*/
if (graphics)
{
particle.loadGraphic(graphics);
}
}
if (collide > 0)
{
particle.allowCollisions = Collision.ANY;
particle.width *= collide;
particle.height *= collide;
//particle.centerOffsets();
}
else
{
particle.allowCollisions = Collision.NONE;
}
particle.exists = false;
this.add(particle);
i++;
}
return this;
}
/**
* Called automatically by the game loop, decides when to launch particles and when to "die".
*/
public update() {
if (this.on)
{
if (this._explode)
{
this.on = false;
var i: number = 0;
var l: number = this._quantity;
if ((l <= 0) || (l > this.length))
{
l = this.length;
}
while (i < l)
{
this.emitParticle();
i++;
}
this._quantity = 0;
}
else
{
this._timer += this._game.time.elapsed;
while ((this.frequency > 0) && (this._timer > this.frequency) && this.on)
{
this._timer -= this.frequency;
this.emitParticle();
if ((this._quantity > 0) && (++this._counter >= this._quantity))
{
this.on = false;
this._quantity = 0;
}
}
}
}
super.update();
}
/**
* Call this function to turn off all the particles and the emitter.
*/
public kill() {
this.on = false;
super.kill();
}
/**
* Call this function to start emitting particles.
*
* @param explode {boolean} Whether the particles should all burst out at once.
* @param lifespan {number} How long each particle lives once emitted. 0 = forever.
* @param frequency {number} Ignored if Explode is set to true. Frequency is how often to emit a particle. 0 = never emit, 0.1 = 1 particle every 0.1 seconds, 5 = 1 particle every 5 seconds.
* @param quantity {number} How many particles to launch. 0 = "all of the particles".
*/
public start(explode: bool = true, lifespan: number = 0, frequency: number = 0.1, quantity: number = 0) {
this.revive();
this.visible = true;
this.on = true;
this._explode = explode;
this.lifespan = lifespan;
this.frequency = frequency;
this._quantity += quantity;
this._counter = 0;
this._timer = 0;
}
/**
* This function can be used both internally and externally to emit the next particle.
*/
public emitParticle() {
var particle: Particle = this.recycle(Particle);
particle.lifespan = this.lifespan;
particle.elasticity = this.bounce;
particle.reset(this.x - (particle.width >> 1) + this._game.math.random() * this.width, this.y - (particle.height >> 1) + this._game.math.random() * this.height);
particle.visible = true;
if (this.minParticleSpeed.x != this.maxParticleSpeed.x)
{
particle.velocity.x = this.minParticleSpeed.x + this._game.math.random() * (this.maxParticleSpeed.x - this.minParticleSpeed.x);
}
else
{
particle.velocity.x = this.minParticleSpeed.x;
}
if (this.minParticleSpeed.y != this.maxParticleSpeed.y)
{
particle.velocity.y = this.minParticleSpeed.y + this._game.math.random() * (this.maxParticleSpeed.y - this.minParticleSpeed.y);
}
else
{
particle.velocity.y = this.minParticleSpeed.y;
}
particle.acceleration.y = this.gravity;
if (this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0)
{
particle.angularVelocity = this.minRotation + this._game.math.random() * (this.maxRotation - this.minRotation);
}
else
{
particle.angularVelocity = this.minRotation;
}
if (particle.angularVelocity != 0)
{
particle.angle = this._game.math.random() * 360 - 180;
}
particle.drag.x = this.particleDrag.x;
particle.drag.y = this.particleDrag.y;
particle.onEmit();
}
/**
* A more compact way of setting the width and height of the emitter.
*
* @param width {number} The desired width of the emitter (particles are spawned randomly within these dimensions).
* @param height {number} The desired height of the emitter.
*/
public setSize(width: number, height: number) {
this.width = width;
this.height = height;
}
/**
* A more compact way of setting the X velocity range of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
public setXSpeed(min: number = 0, max: number = 0) {
this.minParticleSpeed.x = min;
this.maxParticleSpeed.x = max;
}
/**
* A more compact way of setting the Y velocity range of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
public setYSpeed(min: number = 0, max: number = 0) {
this.minParticleSpeed.y = min;
this.maxParticleSpeed.y = max;
}
/**
* A more compact way of setting the angular velocity constraints of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
public setRotation(min: number = 0, max: number = 0) {
this.minRotation = min;
this.maxRotation = max;
}
/**
* Change the emitter's midpoint to match the midpoint of a <code>Object</code>.
*
* @param Object {object} The <code>Object</code> that you want to sync up with.
*/
public at(object) {
object.getMidpoint(this._point);
this.x = this._point.x - (this.width >> 1);
this.y = this._point.y - (this.height >> 1);
}
}
}
+271
View File
@@ -0,0 +1,271 @@
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Phaser;
(function (Phaser) {
var GeomSprite = (function (_super) {
__extends(GeomSprite, _super);
function GeomSprite(game, x, y) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
_super.call(this, game, x, y);
this._dx = 0;
this._dy = 0;
this._dw = 0;
this._dh = 0;
this.type = 0;
this.renderOutline = true;
this.renderFill = true;
this.lineWidth = 1;
this.lineColor = 'rgb(0,255,0)';
this.fillColor = 'rgb(0,100,0)';
this.type = GeomSprite.UNASSIGNED;
return this;
}
GeomSprite.UNASSIGNED = 0;
GeomSprite.CIRCLE = 1;
GeomSprite.LINE = 2;
GeomSprite.POINT = 3;
GeomSprite.RECTANGLE = 4;
GeomSprite.POLYGON = 5;
GeomSprite.prototype.loadCircle = function (circle) {
this.refresh();
this.circle = circle;
this.type = Phaser.GeomSprite.CIRCLE;
return this;
};
GeomSprite.prototype.loadLine = function (line) {
this.refresh();
this.line = line;
this.type = Phaser.GeomSprite.LINE;
return this;
};
GeomSprite.prototype.loadPoint = function (point) {
this.refresh();
this.point = point;
this.type = Phaser.GeomSprite.POINT;
return this;
};
GeomSprite.prototype.loadRectangle = function (rect) {
this.refresh();
this.rect = rect;
this.type = Phaser.GeomSprite.RECTANGLE;
return this;
};
GeomSprite.prototype.createCircle = function (diameter) {
this.refresh();
this.circle = new Phaser.Circle(this.x, this.y, diameter);
this.type = Phaser.GeomSprite.CIRCLE;
this.frameBounds.setTo(this.circle.x - this.circle.radius, this.circle.y - this.circle.radius, this.circle.diameter, this.circle.diameter);
return this;
};
GeomSprite.prototype.createLine = function (x, y) {
this.refresh();
this.line = new Phaser.Line(this.x, this.y, x, y);
this.type = Phaser.GeomSprite.LINE;
this.frameBounds.setTo(this.x, this.y, this.line.width, this.line.height);
return this;
};
GeomSprite.prototype.createPoint = function () {
this.refresh();
this.point = new Phaser.Point(this.x, this.y);
this.type = Phaser.GeomSprite.POINT;
this.frameBounds.width = 1;
this.frameBounds.height = 1;
return this;
};
GeomSprite.prototype.createRectangle = function (width, height) {
this.refresh();
this.rect = new Phaser.Rectangle(this.x, this.y, width, height);
this.type = Phaser.GeomSprite.RECTANGLE;
this.frameBounds.copyFrom(this.rect);
return this;
};
GeomSprite.prototype.createPolygon = function (points) {
if (typeof points === "undefined") { points = []; }
this.refresh();
this.polygon = new Phaser.Polygon(new Vector2(this.x, this.y), points);
this.type = Phaser.GeomSprite.POLYGON;
return this;
};
GeomSprite.prototype.refresh = function () {
this.circle = null;
this.line = null;
this.point = null;
this.rect = null;
};
GeomSprite.prototype.update = function () {
if(this.type == Phaser.GeomSprite.UNASSIGNED) {
return;
} else if(this.type == Phaser.GeomSprite.CIRCLE) {
this.circle.x = this.x;
this.circle.y = this.y;
this.frameBounds.width = this.circle.diameter;
this.frameBounds.height = this.circle.diameter;
} else if(this.type == Phaser.GeomSprite.LINE) {
this.line.x1 = this.x;
this.line.y1 = this.y;
this.frameBounds.setTo(this.x, this.y, this.line.width, this.line.height);
} else if(this.type == Phaser.GeomSprite.POINT) {
this.point.x = this.x;
this.point.y = this.y;
} else if(this.type == Phaser.GeomSprite.RECTANGLE) {
this.rect.x = this.x;
this.rect.y = this.y;
this.frameBounds.copyFrom(this.rect);
}
};
GeomSprite.prototype.inCamera = function (camera) {
if(this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0) {
this._dx = this.frameBounds.x - (camera.x * this.scrollFactor.x);
this._dy = this.frameBounds.y - (camera.y * this.scrollFactor.x);
this._dw = this.frameBounds.width * this.scale.x;
this._dh = this.frameBounds.height * this.scale.y;
return (camera.right > this._dx) && (camera.x < this._dx + this._dw) && (camera.bottom > this._dy) && (camera.y < this._dy + this._dh);
} else {
return camera.intersects(this.frameBounds);
}
};
GeomSprite.prototype.render = function (camera, cameraOffsetX, cameraOffsetY) {
if(this.type == Phaser.GeomSprite.UNASSIGNED || this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.cameraBlacklist.indexOf(camera.ID) !== -1 || this.inCamera(camera.worldView) == false) {
return false;
}
if(this.alpha !== 1) {
var globalAlpha = this.context.globalAlpha;
this.context.globalAlpha = this.alpha;
}
this._dx = cameraOffsetX + (this.frameBounds.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.frameBounds.y - camera.worldView.y);
this._dw = this.frameBounds.width * this.scale.x;
this._dh = this.frameBounds.height * this.scale.y;
if(this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0) {
this._dx -= (camera.worldView.x * this.scrollFactor.x);
this._dy -= (camera.worldView.y * this.scrollFactor.y);
}
this._dx = Math.round(this._dx);
this._dy = Math.round(this._dy);
this._dw = Math.round(this._dw);
this._dh = Math.round(this._dh);
this._game.stage.saveCanvasValues();
this.context.lineWidth = this.lineWidth;
this.context.strokeStyle = this.lineColor;
this.context.fillStyle = this.fillColor;
if(this._game.stage.fillStyle !== this.fillColor) {
}
if(this.type == Phaser.GeomSprite.CIRCLE) {
this.context.beginPath();
this.context.arc(this._dx, this._dy, this.circle.radius, 0, Math.PI * 2);
if(this.renderOutline) {
this.context.stroke();
}
if(this.renderFill) {
this.context.fill();
}
this.context.closePath();
} else if(this.type == Phaser.GeomSprite.LINE) {
this.context.beginPath();
this.context.moveTo(this._dx, this._dy);
this.context.lineTo(this.line.x2, this.line.y2);
this.context.stroke();
this.context.closePath();
} else if(this.type == Phaser.GeomSprite.POINT) {
this.context.fillRect(this._dx, this._dy, 2, 2);
} else if(this.type == Phaser.GeomSprite.RECTANGLE) {
if(this.renderOutline == false) {
this.context.fillRect(this._dx, this._dy, this.rect.width, this.rect.height);
} else {
this.context.beginPath();
this.context.rect(this._dx, this._dy, this.rect.width, this.rect.height);
this.context.stroke();
if(this.renderFill) {
this.context.fill();
}
this.context.closePath();
}
this.context.fillStyle = 'rgb(255,255,255)';
this.renderPoint(this.rect.topLeft, 0, 0, 2);
this.renderPoint(this.rect.topCenter, 0, 0, 2);
this.renderPoint(this.rect.topRight, 0, 0, 2);
this.renderPoint(this.rect.leftCenter, 0, 0, 2);
this.renderPoint(this.rect.center, 0, 0, 2);
this.renderPoint(this.rect.rightCenter, 0, 0, 2);
this.renderPoint(this.rect.bottomLeft, 0, 0, 2);
this.renderPoint(this.rect.bottomCenter, 0, 0, 2);
this.renderPoint(this.rect.bottomRight, 0, 0, 2);
}
this._game.stage.restoreCanvasValues();
if(this.rotation !== 0) {
this.context.translate(0, 0);
this.context.restore();
}
if(globalAlpha > -1) {
this.context.globalAlpha = globalAlpha;
}
return true;
};
GeomSprite.prototype.renderPoint = function (point, offsetX, offsetY, size) {
if (typeof offsetX === "undefined") { offsetX = 0; }
if (typeof offsetY === "undefined") { offsetY = 0; }
if (typeof size === "undefined") { size = 1; }
this.context.fillRect(offsetX + point.x, offsetY + point.y, size, size);
};
GeomSprite.prototype.renderDebugInfo = function (x, y, color) {
if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
};
GeomSprite.prototype.collide = function (source) {
if(this.type == Phaser.GeomSprite.CIRCLE && source.type == Phaser.GeomSprite.CIRCLE) {
return Phaser.Collision.circleToCircle(this.circle, source.circle).result;
}
if(this.type == Phaser.GeomSprite.CIRCLE && source.type == Phaser.GeomSprite.RECTANGLE) {
return Phaser.Collision.circleToRectangle(this.circle, source.rect).result;
}
if(this.type == Phaser.GeomSprite.CIRCLE && source.type == Phaser.GeomSprite.POINT) {
return Phaser.Collision.circleContainsPoint(this.circle, source.point).result;
}
if(this.type == Phaser.GeomSprite.CIRCLE && source.type == Phaser.GeomSprite.LINE) {
return Phaser.Collision.lineToCircle(source.line, this.circle).result;
}
if(this.type == Phaser.GeomSprite.RECTANGLE && source.type == Phaser.GeomSprite.RECTANGLE) {
return Phaser.Collision.rectangleToRectangle(this.rect, source.rect).result;
}
if(this.type == Phaser.GeomSprite.RECTANGLE && source.type == Phaser.GeomSprite.CIRCLE) {
return Phaser.Collision.circleToRectangle(source.circle, this.rect).result;
}
if(this.type == Phaser.GeomSprite.RECTANGLE && source.type == Phaser.GeomSprite.POINT) {
return Phaser.Collision.pointToRectangle(source.point, this.rect).result;
}
if(this.type == Phaser.GeomSprite.RECTANGLE && source.type == Phaser.GeomSprite.LINE) {
return Phaser.Collision.lineToRectangle(source.line, this.rect).result;
}
if(this.type == Phaser.GeomSprite.POINT && source.type == Phaser.GeomSprite.POINT) {
return this.point.equals(source.point);
}
if(this.type == Phaser.GeomSprite.POINT && source.type == Phaser.GeomSprite.CIRCLE) {
return Phaser.Collision.circleContainsPoint(source.circle, this.point).result;
}
if(this.type == Phaser.GeomSprite.POINT && source.type == Phaser.GeomSprite.RECTANGLE) {
return Phaser.Collision.pointToRectangle(this.point, source.rect).result;
}
if(this.type == Phaser.GeomSprite.POINT && source.type == Phaser.GeomSprite.LINE) {
return source.line.isPointOnLine(this.point.x, this.point.y);
}
if(this.type == Phaser.GeomSprite.LINE && source.type == Phaser.GeomSprite.LINE) {
return Phaser.Collision.lineSegmentToLineSegment(this.line, source.line).result;
}
if(this.type == Phaser.GeomSprite.LINE && source.type == Phaser.GeomSprite.CIRCLE) {
return Phaser.Collision.lineToCircle(this.line, source.circle).result;
}
if(this.type == Phaser.GeomSprite.LINE && source.type == Phaser.GeomSprite.RECTANGLE) {
return Phaser.Collision.lineSegmentToRectangle(this.line, source.rect).result;
}
if(this.type == Phaser.GeomSprite.LINE && source.type == Phaser.GeomSprite.POINT) {
return this.line.isPointOnLine(source.point.x, source.point.y);
}
return false;
};
return GeomSprite;
})(Phaser.GameObject);
Phaser.GeomSprite = GeomSprite;
})(Phaser || (Phaser = {}));
+645
View File
@@ -0,0 +1,645 @@
/// <reference path="../Game.ts" />
/// <reference path="../geom/Polygon.ts" />
/// <reference path="../utils/RectangleUtils.ts" />
/**
* Phaser - GeomSprite
*
* A GeomSprite is a special kind of GameObject that contains a base geometry class (Circle, Line, Point, Rectangle).
* They can be rendered in the game and used for collision just like any other game object. Display of them is controlled
* via the lineWidth / lineColor / fillColor and renderOutline / renderFill properties.
*/
module Phaser {
export class GeomSprite extends Sprite {
/**
* GeomSprite constructor
* Create a new <code>GeomSprite</code>.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the sprite.
* @param [y] {number} the initial y position of the sprite.
*/
constructor(game: Game, x?: number = 0, y?: number = 0) {
super(game, x, y);
this.type = GeomSprite.UNASSIGNED;
return this;
}
// local rendering related temp vars to help avoid gc spikes
private _dx: number = 0;
private _dy: number = 0;
private _dw: number = 0;
private _dh: number = 0;
/**
* Geom type of this sprite. (available: UNASSIGNED, CIRCLE, LINE, POINT, RECTANGLE)
* @type {number}
*/
public type: number = 0;
/**
* Not completely set yet. (the default type)
*/
public static UNASSIGNED: number = 0;
/**
* Circle.
* @type {number}
*/
public static CIRCLE: number = 1;
/**
* Line.
* @type {number}
*/
public static LINE: number = 2;
/**
* Point.
* @type {number}
*/
public static POINT: number = 3;
/**
* Rectangle.
* @type {number}
*/
public static RECTANGLE: number = 4;
/**
* Polygon.
* @type {number}
*/
public static POLYGON: number = 5;
/**
* Circle shape container. A Circle instance.
* @type {Circle}
*/
public circle: Circle;
/**
* Line shape container. A Line instance.
* @type {Line}
*/
public line: Line;
/**
* Point shape container. A Point instance.
* @type {Point}
*/
public point: Point;
/**
* Rectangle shape container. A Rectangle instance.
* @type {Rectangle}
*/
public rect: Rectangle;
/**
* Polygon shape container. A Polygon instance.
* @type {Polygon}
*/
public polygon: Polygon;
/**
* Render outline of this sprite or not. (default is true)
* @type {boolean}
*/
public renderOutline: bool = true;
/**
* Fill the shape or not. (default is true)
* @type {boolean}
*/
public renderFill: bool = true;
/**
* Width of outline. (default is 1)
* @type {number}
*/
public lineWidth: number = 1;
/**
* Width of outline. (default is 1)
* @type {number}
*/
public lineColor: string = 'rgb(0,255,0)';
/**
* The color of the filled area in rgb or rgba string format
* @type {string} Defaults to rgb(0,100,0) - a green color
*/
public fillColor: string = 'rgb(0,100,0)';
/**
* Just like Sprite.loadGraphic(), this will load a circle and set its shape to Circle.
* @param circle {Circle} Circle geometry define.
* @return {GeomSprite} GeomSprite instance itself.
*/
loadCircle(circle:Circle): GeomSprite {
this.refresh();
this.circle = circle;
this.type = GeomSprite.CIRCLE;
return this;
}
/**
* Just like Sprite.loadGraphic(), this will load a line and set its shape to Line.
* @param line {Line} Line geometry define.
* @return {GeomSprite} GeomSprite instance itself.
*/
loadLine(line:Line): GeomSprite {
this.refresh();
this.line = line;
this.type = GeomSprite.LINE;
return this;
}
/**
* Just like Sprite.loadGraphic(), this will load a point and set its shape to Point.
* @param point {Point} Point geometry define.
* @return {GeomSprite} GeomSprite instance itself.
*/
loadPoint(point:Point): GeomSprite {
this.refresh();
this.point = point;
this.type = GeomSprite.POINT;
return this;
}
/**
* Just like Sprite.loadGraphic(), this will load a rect and set its shape to Rectangle.
* @param rect {Rectangle} Rectangle geometry define.
* @return {GeomSprite} GeomSprite instance itself.
*/
loadRectangle(rect:Rectangle): GeomSprite {
this.refresh();
this.rect = rect;
this.type = GeomSprite.RECTANGLE;
return this;
}
/**
* Create a circle shape with specific diameter.
* @param diameter {number} Diameter of the circle.
* @return {GeomSprite} GeomSprite instance itself.
*/
createCircle(diameter: number): GeomSprite {
this.refresh();
this.circle = new Circle(this.x, this.y, diameter);
this.type = GeomSprite.CIRCLE;
this.frameBounds.setTo(this.circle.x - this.circle.radius, this.circle.y - this.circle.radius, this.circle.diameter, this.circle.diameter);
return this;
}
/**
* Create a line shape with specific end point.
* @param x {number} X position of the end point.
* @param y {number} Y position of the end point.
* @return {GeomSprite} GeomSprite instance itself.
*/
createLine(x: number, y: number): GeomSprite {
this.refresh();
this.line = new Line(this.x, this.y, x, y);
this.type = GeomSprite.LINE;
this.frameBounds.setTo(this.x, this.y, this.line.width, this.line.height);
return this;
}
/**
* Create a point shape at spriter's position.
* @return {GeomSprite} GeomSprite instance itself.
*/
createPoint(): GeomSprite {
this.refresh();
this.point = new Point(this.x, this.y);
this.type = GeomSprite.POINT;
this.frameBounds.width = 1;
this.frameBounds.height = 1;
return this;
}
/**
* Create a rectangle shape of the given width and height size
* @param width {Number} Width of the rectangle
* @param height {Number} Height of the rectangle
* @return {GeomSprite} GeomSprite instance.
*/
createRectangle(width: number, height: number): GeomSprite {
this.refresh();
this.rect = new Rectangle(this.x, this.y, width, height);
this.type = GeomSprite.RECTANGLE;
this.frameBounds.copyFrom(this.rect);
return this;
}
/**
* Create a polygon object
* @param width {Number} Width of the rectangle
* @param height {Number} Height of the rectangle
* @return {GeomSprite} GeomSprite instance.
*/
createPolygon(points?: Vec2[] = []): GeomSprite {
//this.refresh();
//this.polygon = new Polygon(new Vec2(this.x, this.y), points);
//this.type = GeomSprite.POLYGON;
//this.frameBounds.copyFrom(this.rect);
return this;
}
/**
* Destroy all geom shapes of this sprite.
*/
refresh() {
this.circle = null;
this.line = null;
this.point = null;
this.rect = null;
}
/**
* Update bounds.
*/
update() {
// Update bounds and position?
if (this.type == GeomSprite.UNASSIGNED)
{
return;
}
else if (this.type == GeomSprite.CIRCLE)
{
this.circle.x = this.x;
this.circle.y = this.y;
this.frameBounds.width = this.circle.diameter;
this.frameBounds.height = this.circle.diameter;
}
else if (this.type == GeomSprite.LINE)
{
this.line.x1 = this.x;
this.line.y1 = this.y;
this.frameBounds.setTo(this.x, this.y, this.line.width, this.line.height);
}
else if (this.type == GeomSprite.POINT)
{
this.point.x = this.x;
this.point.y = this.y;
}
else if (this.type == GeomSprite.RECTANGLE)
{
this.rect.x = this.x;
this.rect.y = this.y;
this.frameBounds.copyFrom(this.rect);
}
}
/**
* 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: Rectangle): bool {
if (this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0)
{
this._dx = this.frameBounds.x - (camera.x * this.scrollFactor.x);
this._dy = this.frameBounds.y - (camera.y * this.scrollFactor.x);
this._dw = this.frameBounds.width * this.scale.x;
this._dh = this.frameBounds.height * this.scale.y;
return (camera.right > this._dx) && (camera.x < this._dx + this._dw) && (camera.bottom > this._dy) && (camera.y < this._dy + this._dh);
}
else
{
return camera.intersects(this.frameBounds);
}
}
*/
/**
* Render this sprite to specific camera. Called by game loop after update().
* @param camera {Camera} Camera this sprite will be rendered to.
* @cameraOffsetX {number} X offset to the camera.
* @cameraOffsetY {number} Y offset to the camera.
* @return {boolean} Return false if not rendered, otherwise return true.
*/
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number): bool {
// Render checks
//if (this.type == GeomSprite.UNASSIGNED || this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.cameraBlacklist.indexOf(camera.ID) !== -1 || this.inCamera(camera.worldView) == false)
//{
// return false;
//}
// Alpha
if (this.alpha !== 1)
{
var globalAlpha = this.context.globalAlpha;
this.context.globalAlpha = this.alpha;
}
this._dx = cameraOffsetX + (this.frameBounds.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.frameBounds.y - camera.worldView.y);
this._dw = this.frameBounds.width * this.scale.x;
this._dh = this.frameBounds.height * this.scale.y;
// Apply camera difference
if (this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0)
{
this._dx -= (camera.worldView.x * this.scrollFactor.x);
this._dy -= (camera.worldView.y * this.scrollFactor.y);
}
// Rotation is disabled for now as I don't want it to be misleading re: collision
/*
if (this.angle !== 0)
{
this.context.save();
this.context.translate(this._dx + (this._dw / 2) - this.origin.x, this._dy + (this._dh / 2) - this.origin.y);
this.context.rotate(this.angle * (Math.PI / 180));
this._dx = -(this._dw / 2);
this._dy = -(this._dh / 2);
}
*/
this._dx = Math.round(this._dx);
this._dy = Math.round(this._dy);
this._dw = Math.round(this._dw);
this._dh = Math.round(this._dh);
this._game.stage.saveCanvasValues();
// Debug
//this.context.fillStyle = 'rgba(255,0,0,0.5)';
//this.context.fillRect(this.frameBounds.x, this.frameBounds.y, this.frameBounds.width, this.frameBounds.height);
this.context.lineWidth = this.lineWidth;
this.context.strokeStyle = this.lineColor;
this.context.fillStyle = this.fillColor;
if (this._game.stage.fillStyle !== this.fillColor)
{
}
// Primitive Renderer
if (this.type == GeomSprite.CIRCLE)
{
this.context.beginPath();
this.context.arc(this._dx, this._dy, this.circle.radius, 0, Math.PI * 2);
if (this.renderOutline)
{
this.context.stroke();
}
if (this.renderFill)
{
this.context.fill();
}
this.context.closePath();
}
else if (this.type == GeomSprite.LINE)
{
this.context.beginPath();
this.context.moveTo(this._dx, this._dy);
this.context.lineTo(this.line.x2, this.line.y2);
this.context.stroke();
this.context.closePath();
}
else if (this.type == GeomSprite.POINT)
{
this.context.fillRect(this._dx, this._dy, 2, 2);
}
else if (this.type == GeomSprite.RECTANGLE)
{
// We can use the faster fillRect if we don't need the outline
if (this.renderOutline == false)
{
this.context.fillRect(this._dx, this._dy, this.rect.width, this.rect.height);
}
else
{
this.context.beginPath();
this.context.rect(this._dx, this._dy, this.rect.width, this.rect.height);
this.context.stroke();
if (this.renderFill)
{
this.context.fill();
}
this.context.closePath();
}
// And now the edge points
this.context.fillStyle = 'rgb(255,255,255)';
//this.renderPoint(this.rect.topLeft, this._dx, this._dy, 2);
//this.renderPoint(this.rect.topCenter, this._dx, this._dy, 2);
//this.renderPoint(this.rect.topRight, this._dx, this._dy, 2);
//this.renderPoint(this.rect.leftCenter, this._dx, this._dy, 2);
//this.renderPoint(this.rect.center, this._dx, this._dy, 2);
//this.renderPoint(this.rect.rightCenter, this._dx, this._dy, 2);
//this.renderPoint(this.rect.bottomLeft, this._dx, this._dy, 2);
//this.renderPoint(this.rect.bottomCenter, this._dx, this._dy, 2);
//this.renderPoint(this.rect.bottomRight, this._dx, this._dy, 2);
this.renderPoint(this.rect.topLeft, 0, 0, 2);
this.renderPoint(this.rect.topCenter, 0, 0, 2);
this.renderPoint(this.rect.topRight, 0, 0, 2);
this.renderPoint(this.rect.leftCenter, 0, 0, 2);
this.renderPoint(this.rect.center, 0, 0, 2);
this.renderPoint(this.rect.rightCenter, 0, 0, 2);
this.renderPoint(this.rect.bottomLeft, 0, 0, 2);
this.renderPoint(this.rect.bottomCenter, 0, 0, 2);
this.renderPoint(this.rect.bottomRight, 0, 0, 2);
}
this._game.stage.restoreCanvasValues();
if (this.rotation !== 0)
{
this.context.translate(0, 0);
this.context.restore();
}
if (globalAlpha > -1)
{
this.context.globalAlpha = globalAlpha;
}
return true;
}
/**
* Render a point of geometry.
* @param point {Point} Position of the point.
* @param offsetX {number} X offset to its position.
* @param offsetY {number} Y offset to its position.
* @param [size] {number} point size.
*/
public renderPoint(point, offsetX?: number = 0, offsetY?: number = 0, size?: number = 1) {
this.context.fillRect(offsetX + point.x, offsetY + point.y, size, size);
}
/**
* Render debug infos. (this method does not work now)
* @param x {number} X position of the debug info to be rendered.
* @param y {number} Y position of the debug info to be rendered.
* @param [color] {number} color of the debug info to be rendered. (format is css color string)
*/
public renderDebugInfo(x: number, y: number, color?: string = 'rgb(255,255,255)') {
//this.context.fillStyle = color;
//this.context.fillText('Sprite: ' + this.name + ' (' + this.frameBounds.width + ' x ' + this.frameBounds.height + ')', x, y);
//this.context.fillText('x: ' + this.frameBounds.x.toFixed(1) + ' y: ' + this.frameBounds.y.toFixed(1) + ' rotation: ' + this.angle.toFixed(1), x, y + 14);
//this.context.fillText('dx: ' + this._dx.toFixed(1) + ' dy: ' + this._dy.toFixed(1) + ' dw: ' + this._dw.toFixed(1) + ' dh: ' + this._dh.toFixed(1), x, y + 28);
//this.context.fillText('sx: ' + this._sx.toFixed(1) + ' sy: ' + this._sy.toFixed(1) + ' sw: ' + this._sw.toFixed(1) + ' sh: ' + this._sh.toFixed(1), x, y + 42);
}
/**
* Gives a basic boolean response to a geometric collision.
* If you need the details of the collision use the Collision functions instead and inspect the IntersectResult object.
* @param source {GeomSprite} Sprite you want to check.
* @return {boolean} Whether they overlaps or not.
*/
public collide(source: GeomSprite): bool {
// Circle vs. Circle
if (this.type == GeomSprite.CIRCLE && source.type == GeomSprite.CIRCLE)
{
return Collision.circleToCircle(this.circle, source.circle).result;
}
// Circle vs. Rect
if (this.type == GeomSprite.CIRCLE && source.type == GeomSprite.RECTANGLE)
{
return Collision.circleToRectangle(this.circle, source.rect).result;
}
// Circle vs. Point
if (this.type == GeomSprite.CIRCLE && source.type == GeomSprite.POINT)
{
return Collision.circleContainsPoint(this.circle, source.point).result;
}
// Circle vs. Line
if (this.type == GeomSprite.CIRCLE && source.type == GeomSprite.LINE)
{
return Collision.lineToCircle(source.line, this.circle).result;
}
// Rect vs. Rect
if (this.type == GeomSprite.RECTANGLE && source.type == GeomSprite.RECTANGLE)
{
return Collision.rectangleToRectangle(this.rect, source.rect).result;
}
// Rect vs. Circle
if (this.type == GeomSprite.RECTANGLE && source.type == GeomSprite.CIRCLE)
{
return Collision.circleToRectangle(source.circle, this.rect).result;
}
// Rect vs. Point
if (this.type == GeomSprite.RECTANGLE && source.type == GeomSprite.POINT)
{
return Collision.pointToRectangle(source.point, this.rect).result;
}
// Rect vs. Line
if (this.type == GeomSprite.RECTANGLE && source.type == GeomSprite.LINE)
{
return Collision.lineToRectangle(source.line, this.rect).result;
}
// Point vs. Point
if (this.type == GeomSprite.POINT && source.type == GeomSprite.POINT)
{
return this.point.equals(source.point);
}
// Point vs. Circle
if (this.type == GeomSprite.POINT && source.type == GeomSprite.CIRCLE)
{
return Collision.circleContainsPoint(source.circle, this.point).result;
}
// Point vs. Rect
if (this.type == GeomSprite.POINT && source.type == GeomSprite.RECTANGLE)
{
return Collision.pointToRectangle(this.point, source.rect).result;
}
// Point vs. Line
if (this.type == GeomSprite.POINT && source.type == GeomSprite.LINE)
{
return source.line.isPointOnLine(this.point.x, this.point.y);
}
// Line vs. Line
if (this.type == GeomSprite.LINE && source.type == GeomSprite.LINE)
{
return Collision.lineSegmentToLineSegment(this.line, source.line).result;
}
// Line vs. Circle
if (this.type == GeomSprite.LINE && source.type == GeomSprite.CIRCLE)
{
return Collision.lineToCircle(this.line, source.circle).result;
}
// Line vs. Rect
if (this.type == GeomSprite.LINE && source.type == GeomSprite.RECTANGLE)
{
return Collision.lineSegmentToRectangle(this.line, source.rect).result;
}
// Line vs. Point
if (this.type == GeomSprite.LINE && source.type == GeomSprite.POINT)
{
return this.line.isPointOnLine(source.point.x, source.point.y);
}
return false;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+29
View File
@@ -0,0 +1,29 @@
/**
* Phaser - Components - Input
*
*
*/
module Phaser.Components {
export class Input {
// Input
//public inputEnabled: bool = false;
//private _inputOver: bool = false;
//public onInputOver: Phaser.Signal;
//public onInputOut: Phaser.Signal;
//public onInputDown: Phaser.Signal;
//public onInputUp: Phaser.Signal;
/**
* Update input.
*/
private updateInput() {
}
}
}
+161
View File
@@ -0,0 +1,161 @@
var Phaser;
(function (Phaser) {
var Motion = (function () {
function Motion(game) {
this._game = game;
}
Motion.prototype.computeVelocity = function (Velocity, Acceleration, Drag, Max) {
if (typeof Acceleration === "undefined") { Acceleration = 0; }
if (typeof Drag === "undefined") { Drag = 0; }
if (typeof Max === "undefined") { Max = 10000; }
if(Acceleration !== 0) {
Velocity += Acceleration * this._game.time.elapsed;
} else if(Drag !== 0) {
var drag = Drag * this._game.time.elapsed;
if(Velocity - drag > 0) {
Velocity = Velocity - drag;
} else if(Velocity + drag < 0) {
Velocity += drag;
} else {
Velocity = 0;
}
}
if((Velocity != 0) && (Max != 10000)) {
if(Velocity > Max) {
Velocity = Max;
} else if(Velocity < -Max) {
Velocity = -Max;
}
}
return Velocity;
};
Motion.prototype.velocityFromAngle = function (angle, speed) {
if(isNaN(speed)) {
speed = 0;
}
var a = this._game.math.degreesToRadians(angle);
return new Phaser.Point((Math.cos(a) * speed), (Math.sin(a) * speed));
};
Motion.prototype.moveTowardsObject = function (source, dest, speed, maxTime) {
if (typeof speed === "undefined") { speed = 60; }
if (typeof maxTime === "undefined") { maxTime = 0; }
var a = this.angleBetween(source, dest);
if(maxTime > 0) {
var d = this.distanceBetween(source, dest);
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
};
Motion.prototype.accelerateTowardsObject = function (source, dest, speed, xSpeedMax, ySpeedMax) {
var a = this.angleBetween(source, dest);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
};
Motion.prototype.moveTowardsMouse = function (source, speed, maxTime) {
if (typeof speed === "undefined") { speed = 60; }
if (typeof maxTime === "undefined") { maxTime = 0; }
var a = this.angleBetweenMouse(source);
if(maxTime > 0) {
var d = this.distanceToMouse(source);
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
};
Motion.prototype.accelerateTowardsMouse = function (source, speed, xSpeedMax, ySpeedMax) {
var a = this.angleBetweenMouse(source);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
};
Motion.prototype.moveTowardsPoint = function (source, target, speed, maxTime) {
if (typeof speed === "undefined") { speed = 60; }
if (typeof maxTime === "undefined") { maxTime = 0; }
var a = this.angleBetweenPoint(source, target);
if(maxTime > 0) {
var d = this.distanceToPoint(source, target);
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
};
Motion.prototype.accelerateTowardsPoint = function (source, target, speed, xSpeedMax, ySpeedMax) {
var a = this.angleBetweenPoint(source, target);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
};
Motion.prototype.distanceBetween = function (a, b) {
var dx = (a.x + a.origin.x) - (b.x + b.origin.x);
var dy = (a.y + a.origin.y) - (b.y + b.origin.y);
return this._game.math.vectorLength(dx, dy);
};
Motion.prototype.distanceToPoint = function (a, target) {
var dx = (a.x + a.origin.x) - (target.x);
var dy = (a.y + a.origin.y) - (target.y);
return this._game.math.vectorLength(dx, dy);
};
Motion.prototype.distanceToMouse = function (a) {
var dx = (a.x + a.origin.x) - this._game.input.x;
var dy = (a.y + a.origin.y) - this._game.input.y;
return this._game.math.vectorLength(dx, dy);
};
Motion.prototype.angleBetweenPoint = function (a, target, asDegrees) {
if (typeof asDegrees === "undefined") { asDegrees = false; }
var dx = (target.x) - (a.x + a.origin.x);
var dy = (target.y) - (a.y + a.origin.y);
if(asDegrees) {
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
} else {
return Math.atan2(dy, dx);
}
};
Motion.prototype.angleBetween = function (a, b, asDegrees) {
if (typeof asDegrees === "undefined") { asDegrees = false; }
var dx = (b.x + b.origin.x) - (a.x + a.origin.x);
var dy = (b.y + b.origin.y) - (a.y + a.origin.y);
if(asDegrees) {
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
} else {
return Math.atan2(dy, dx);
}
};
Motion.prototype.velocityFromFacing = function (parent, speed) {
var a;
if(parent.facing == Phaser.Collision.LEFT) {
a = this._game.math.degreesToRadians(180);
} else if(parent.facing == Phaser.Collision.RIGHT) {
a = this._game.math.degreesToRadians(0);
} else if(parent.facing == Phaser.Collision.UP) {
a = this._game.math.degreesToRadians(-90);
} else if(parent.facing == Phaser.Collision.DOWN) {
a = this._game.math.degreesToRadians(90);
}
return new Phaser.Point(Math.cos(a) * speed, Math.sin(a) * speed);
};
Motion.prototype.angleBetweenMouse = function (a, asDegrees) {
if (typeof asDegrees === "undefined") { asDegrees = false; }
var p = a.getScreenXY();
var dx = a._game.input.x - p.x;
var dy = a._game.input.y - p.y;
if(asDegrees) {
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
} else {
return Math.atan2(dy, dx);
}
};
return Motion;
})();
Phaser.Motion = Motion;
})(Phaser || (Phaser = {}));
+409
View File
@@ -0,0 +1,409 @@
/// <reference path="Game.ts" />
/// <reference path="gameobjects/GameObject.ts" />
/**
* Phaser - Motion
*
* The Motion class contains lots of useful functions for moving game objects around in world space.
*/
module Phaser {
export class Motion {
constructor(game: Game) {
this._game = game;
}
private _game: Game;
/**
* A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
*
* @param {number} Velocity Any component of velocity (e.g. 20).
* @param {number} Acceleration Rate at which the velocity is changing.
* @param {number} Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
* @param {number} Max An absolute value cap for the velocity.
*
* @return {number} The altered Velocity value.
*/
public computeVelocity(Velocity: number, Acceleration: number = 0, Drag: number = 0, Max: number = 10000): number {
if (Acceleration !== 0)
{
Velocity += Acceleration * this._game.time.elapsed;
}
else if (Drag !== 0)
{
var drag: number = Drag * this._game.time.elapsed;
if (Velocity - drag > 0)
{
Velocity = Velocity - drag;
}
else if (Velocity + drag < 0)
{
Velocity += drag;
}
else
{
Velocity = 0;
}
}
if ((Velocity != 0) && (Max != 10000))
{
if (Velocity > Max)
{
Velocity = Max;
}
else if (Velocity < -Max)
{
Velocity = -Max;
}
}
return Velocity;
}
/**
* Given the angle and speed calculate the velocity and return it as a Point
*
* @param {number} angle The angle (in degrees) calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
* @param {number} speed The speed it will move, in pixels per second sq
*
* @return {Point} A Point where Point.x contains the velocity x value and Point.y contains the velocity y value
*/
public velocityFromAngle(angle: number, speed: number): Point {
if (isNaN(speed))
{
speed = 0;
}
var a: number = this._game.math.degreesToRadians(angle);
return new Point((Math.cos(a) * speed), (Math.sin(a) * speed));
}
/**
* Sets the source Sprite x/y velocity so it will move directly towards the destination Sprite at the speed given (in pixels per second)<br>
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.<br>
* Timings are approximate due to the way Flash timers work, and irrespective of SWF frame rate. Allow for a variance of +- 50ms.<br>
* The source object doesn't stop moving automatically should it ever reach the destination coordinates.<br>
* If you need the object to accelerate, see accelerateTowardsObject() instead
* Note: Doesn't take into account acceleration, maxVelocity or drag (if you set drag or acceleration too high this object may not move at all)
*
* @param {GameObject} source The Sprite on which the velocity will be set
* @param {GameObject} dest The Sprite where the source object will move to
* @param {number} speed The speed it will move, in pixels per second (default is 60 pixels/sec)
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsObject(source:GameObject, dest:GameObject, speed:number= 60, maxTime:number = 0)
{
var a:number = this.angleBetween(source, dest);
if (maxTime > 0)
{
var d:number = this.distanceBetween(source, dest);
// We know how many pixels we need to move, but how fast?
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
}
/**
* Sets the x/y acceleration on the source Sprite so it will move towards the destination Sprite at the speed given (in pixels per second)<br>
* You must give a maximum speed value, beyond which the Sprite won't go any faster.<br>
* If you don't need acceleration look at moveTowardsObject() instead.
*
* @param {GameObject} source The Sprite on which the acceleration will be set
* @param {GameObject} dest The Sprite where the source object will move towards
* @param {number} speed The speed it will accelerate in pixels per second
* @param {number} xSpeedMax The maximum speed in pixels per second in which the sprite can move horizontally
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsObject(source:GameObject, dest:GameObject, speed:number, xSpeedMax:number, ySpeedMax:number)
{
var a:number = this.angleBetween(source, dest);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
}
/**
* Move the given Sprite towards the mouse pointer coordinates at a steady velocity
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.<br>
* Timings are approximate due to the way Flash timers work, and irrespective of SWF frame rate. Allow for a variance of +- 50ms.<br>
* The source object doesn't stop moving automatically should it ever reach the destination coordinates.<br>
*
* @param {GameObject} source The Sprite to move
* @param {number} speed The speed it will move, in pixels per second (default is 60 pixels/sec)
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsMouse(source:GameObject, speed:number = 60, maxTime:number = 0)
{
var a:number = this.angleBetweenMouse(source);
if (maxTime > 0)
{
var d:number = this.distanceToMouse(source);
// We know how many pixels we need to move, but how fast?
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
}
/**
* Sets the x/y acceleration on the source Sprite so it will move towards the mouse coordinates at the speed given (in pixels per second)<br>
* You must give a maximum speed value, beyond which the Sprite won't go any faster.<br>
* If you don't need acceleration look at moveTowardsMouse() instead.
*
* @param {GameObject} source The Sprite on which the acceleration will be set
* @param {number} speed The speed it will accelerate in pixels per second
* @param {number} xSpeedMax The maximum speed in pixels per second in which the sprite can move horizontally
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsMouse(source:GameObject, speed:number, xSpeedMax:number, ySpeedMax:number)
{
var a:number = this.angleBetweenMouse(source);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
}
/**
* Sets the x/y velocity on the source Sprite so it will move towards the target coordinates at the speed given (in pixels per second)<br>
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.<br>
* Timings are approximate due to the way Flash timers work, and irrespective of SWF frame rate. Allow for a variance of +- 50ms.<br>
* The source object doesn't stop moving automatically should it ever reach the destination coordinates.<br>
*
* @param {GameObject} source The Sprite to move
* @param {Point} target The Point coordinates to move the source Sprite towards
* @param {number} speed The speed it will move, in pixels per second (default is 60 pixels/sec)
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsPoint(source:GameObject, target:Point, speed:number = 60, maxTime:number = 0)
{
var a:number = this.angleBetweenPoint(source, target);
if (maxTime > 0)
{
var d:number = this.distanceToPoint(source, target);
// We know how many pixels we need to move, but how fast?
speed = d / (maxTime / 1000);
}
source.velocity.x = Math.cos(a) * speed;
source.velocity.y = Math.sin(a) * speed;
}
/**
* Sets the x/y acceleration on the source Sprite so it will move towards the target coordinates at the speed given (in pixels per second)<br>
* You must give a maximum speed value, beyond which the Sprite won't go any faster.<br>
* If you don't need acceleration look at moveTowardsPoint() instead.
*
* @param {GameObject} source The Sprite on which the acceleration will be set
* @param {Point} target The Point coordinates to move the source Sprite towards
* @param {number} speed The speed it will accelerate in pixels per second
* @param {number} xSpeedMax The maximum speed in pixels per second in which the sprite can move horizontally
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsPoint(source:GameObject, target:Point, speed:number, xSpeedMax:number, ySpeedMax:number)
{
var a:number = this.angleBetweenPoint(source, target);
source.velocity.x = 0;
source.velocity.y = 0;
source.acceleration.x = Math.cos(a) * speed;
source.acceleration.y = Math.sin(a) * speed;
source.maxVelocity.x = xSpeedMax;
source.maxVelocity.y = ySpeedMax;
}
/**
* Find the distance (in pixels, rounded) between two Sprites, taking their origin into account
*
* @param {GameObject} a The first Sprite
* @param {GameObject} b The second Sprite
* @return {number} int Distance (in pixels)
*/
public distanceBetween(a:GameObject, b:GameObject):number
{
var dx:number = (a.x + a.origin.x) - (b.x + b.origin.x);
var dy:number = (a.y + a.origin.y) - (b.y + b.origin.y);
return this._game.math.vectorLength(dx, dy);
}
/**
* Find the distance (in pixels, rounded) from an Sprite to the given Point, taking the source origin into account
*
* @param {GameObject} a The Sprite
* @param {Point} target The Point
* @return {number} Distance (in pixels)
*/
public distanceToPoint(a:GameObject, target:Point):number
{
var dx:number = (a.x + a.origin.x) - (target.x);
var dy:number = (a.y + a.origin.y) - (target.y);
return this._game.math.vectorLength(dx, dy);
}
/**
* Find the distance (in pixels, rounded) from the object x/y and the mouse x/y
*
* @param {GameObject} a Sprite to test against
* @return {number} The distance between the given sprite and the mouse coordinates
*/
public distanceToMouse(a:GameObject):number
{
var dx: number = (a.x + a.origin.x) - this._game.input.x;
var dy: number = (a.y + a.origin.y) - this._game.input.y;
return this._game.math.vectorLength(dx, dy);
}
/**
* Find the angle (in radians) between an Sprite and an Point. The source sprite takes its x/y and origin into account.
* The angle is calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
*
* @param {GameObject} a The Sprite to test from
* @param {Point} target The Point to angle the Sprite towards
* @param {boolean} asDegrees If you need the value in degrees instead of radians, set to true
*
* @return {number} The angle (in radians unless asDegrees is true)
*/
public angleBetweenPoint(a:GameObject, target:Point, asDegrees:bool = false):number
{
var dx:number = (target.x) - (a.x + a.origin.x);
var dy:number = (target.y) - (a.y + a.origin.y);
if (asDegrees)
{
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
}
else
{
return Math.atan2(dy, dx);
}
}
/**
* Find the angle (in radians) between the two Sprite, taking their x/y and origin into account.
* The angle is calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
*
* @param {GameObject} a The Sprite to test from
* @param {GameObject} b The Sprite to test to
* @param {boolean} asDegrees If you need the value in degrees instead of radians, set to true
*
* @return {number} The angle (in radians unless asDegrees is true)
*/
public angleBetween(a:GameObject, b:GameObject, asDegrees:bool = false):number
{
var dx:number = (b.x + b.origin.x) - (a.x + a.origin.x);
var dy:number = (b.y + b.origin.y) - (a.y + a.origin.y);
if (asDegrees)
{
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
}
else
{
return Math.atan2(dy, dx);
}
}
/**
* Given the GameObject and speed calculate the velocity and return it as an Point based on the direction the sprite is facing
*
* @param {GameObject} parent The Sprite to get the facing value from
* @param {number} speed The speed it will move, in pixels per second sq
*
* @return {Point} An Point where Point.x contains the velocity x value and Point.y contains the velocity y value
*/
public velocityFromFacing(parent:GameObject, speed:number):Point
{
var a:number;
if (parent.facing == Collision.LEFT)
{
a = this._game.math.degreesToRadians(180);
}
else if (parent.facing == Collision.RIGHT)
{
a = this._game.math.degreesToRadians(0);
}
else if (parent.facing == Collision.UP)
{
a = this._game.math.degreesToRadians(-90);
}
else if (parent.facing == Collision.DOWN)
{
a = this._game.math.degreesToRadians(90);
}
return new Point(Math.cos(a) * speed, Math.sin(a) * speed);
}
/**
* Find the angle (in radians) between an Sprite and the mouse, taking their x/y and origin into account.
* The angle is calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
*
* @param {GameObject} a The Object to test from
* @param {boolean} asDegrees If you need the value in degrees instead of radians, set to true
*
* @return {number} The angle (in radians unless asDegrees is true)
*/
public angleBetweenMouse(a:GameObject, asDegrees:bool = false):number
{
// In order to get the angle between the object and mouse, we need the objects screen coordinates (rather than world coordinates)
var p:MicroPoint = a.getScreenXY();
var dx:number = a._game.input.x - p.x;
var dy:number = a._game.input.y - p.y;
if (asDegrees)
{
return this._game.math.radiansToDegrees(Math.atan2(dy, dx));
}
else
{
return Math.atan2(dy, dx);
}
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+355
View File
@@ -0,0 +1,355 @@
/// <reference path="../Game.ts" />
/// <reference path="../AnimationManager.ts" />
/// <reference path="GameObject.ts" />
/// <reference path="../system/Camera.ts" />
/**
* Phaser - Sprite
*
* The Sprite GameObject is an extension of the core GameObject that includes support for animation and dynamic textures.
* It's probably the most used GameObject of all.
*/
module Phaser {
export class OldSprite {
/**
* Sprite constructor
* Create a new <code>Sprite</code>.
*
* @param game {Phaser.Game} Current game instance.
* @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.
* @param [width] {number} The width of the object.
* @param [height] {number} The height of the object.
*/
constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, width?: number = 16, height?: number = 16) {
this.canvas = game.stage.canvas;
this.context = game.stage.context;
this.frameBounds = new Rectangle(x, y, width, height);
this.exists = true;
this.active = true;
this.visible = true;
this.alive = true;
this.isGroup = false;
this.alpha = 1;
this.scale = new MicroPoint(1, 1);
this.last = new MicroPoint(x, y);
this.align = GameObject.ALIGN_TOP_LEFT;
this.mass = 1;
this.elasticity = 0;
this.health = 1;
this.immovable = false;
this.moves = true;
this.worldBounds = null;
this.touching = Collision.NONE;
this.wasTouching = Collision.NONE;
this.allowCollisions = Collision.ANY;
this.velocity = new MicroPoint();
this.acceleration = new MicroPoint();
this.drag = new MicroPoint();
this.maxVelocity = new MicroPoint(10000, 10000);
this.angle = 0;
this.angularVelocity = 0;
this.angularAcceleration = 0;
this.angularDrag = 0;
this.maxAngular = 10000;
this.cameraBlacklist = [];
this.scrollFactor = new MicroPoint(1, 1);
this.collisionMask = new CollisionMask(game, this, x, y, width, height);
this._texture = null;
this.animations = new AnimationManager(this._game, this);
if (key !== null)
{
this.cacheKey = key;
this.loadGraphic(key);
}
else
{
this.frameBounds.width = 16;
this.frameBounds.height = 16;
}
}
/**
* The essential reference to the main game object
*/
public _game: Game;
/**
* Controls whether <code>update()</code> is automatically called by State/Group.
*/
public active: bool;
/**
* Controls whether <code>draw()</code> is automatically called by State/Group.
*/
public visible: bool;
/**
* Setting this to true will prevent the object from being updated during the main game loop (you will have to call update on it yourself)
*/
public ignoreGlobalUpdate: bool;
/**
* Setting this to true will prevent the object from being rendered during the main game loop (you will have to call render on it yourself)
*/
public ignoreGlobalRender: bool;
/**
* An Array of Cameras to which this GameObject won't render
* @type {Array}
*/
public cameraBlacklist: number[];
/**
* Orientation of the object.
* @type {number}
*/
public facing: number;
/**
* Set alpha to a number between 0 and 1 to change the opacity.
* @type {number}
*/
public alpha: number;
/**
* Scale factor of the object.
* @type {MicroPoint}
*/
public scale: MicroPoint;
/**
* Controls if the GameObject is rendered rotated or not.
* If renderRotation is false then the object can still rotate but it will never be rendered rotated.
* @type {boolean}
*/
public renderRotation: bool = true;
/**
* A point that can store numbers from 0 to 1 (for X and Y independently)
* which governs how much this object is affected by the camera .
* @type {MicroPoint}
*/
public scrollFactor: MicroPoint;
/**
* Rectangle container of this object.
* @type {Rectangle}
*/
public frameBounds: Rectangle;
/**
* This objects CollisionMask
* @type {CollisionMask}
*/
public collisionMask: CollisionMask;
/**
* A rectangular area which is object is allowed to exist within. If it travels outside of this area it will perform the outOfBoundsAction.
* @type {Quad}
*/
public worldBounds: Quad;
/**
* A reference to the Canvas this GameObject will render to
* @type {HTMLCanvasElement}
*/
public canvas: HTMLCanvasElement;
/**
* A reference to the Canvas Context2D this GameObject will render to
* @type {CanvasRenderingContext2D}
*/
public context: CanvasRenderingContext2D;
/**
* Texture of this sprite to be rendered.
*/
private _texture;
/**
* Texture of this sprite is DynamicTexture? (default to false)
* @type {boolean}
*/
private _dynamicTexture: bool = false;
/**
* This manages animations of the sprite. You can modify animations though it. (see AnimationManager)
* @type AnimationManager
*/
public animations: AnimationManager;
/**
* The cache key that was used for this texture (if any)
*/
public cacheKey: string;
/**
* Flip the graphic horizontally? (defaults to false)
* @type {boolean}
*/
public flipped: bool = false;
/**
* Pre-update is called right before update() on each object in the game loop.
*/
public preUpdate() {
this.last.x = this.frameBounds.x;
this.last.y = this.frameBounds.y;
this.collisionMask.preUpdate();
}
/**
* 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();
if (this.moves)
{
this.updateMotion();
}
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;
}
}
}
this.collisionMask.update();
if (this.inputEnabled)
{
this.updateInput();
}
this.wasTouching = this.touching;
this.touching = Collision.NONE;
}
/**
* Clean up memory.
*/
public destroy() {
}
public set width(value:number) {
this.frameBounds.width = value;
}
public set height(value:number) {
this.frameBounds.height = value;
}
public get width(): number {
return this.frameBounds.width;
}
public get height(): number {
return this.frameBounds.height;
}
public set frame(value: number) {
this.animations.frame = value;
}
public get frame(): number {
return this.animations.frame;
}
public set frameName(value: string) {
this.animations.frameName = value;
}
public get frameName(): string {
return this.animations.frameName;
}
/**
* 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.
*/
public kill() {
this.alive = false;
this.exists = false;
}
/**
* 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() {
this.alive = true;
this.exists = true;
}
/**
* Convert object to readable string name. Useful for debugging, save games, etc.
*/
public toString(): string {
return "";
}
}
}
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+36
View File
@@ -0,0 +1,36 @@
/**
* Phaser - Components - Properties
*
*
*/
module Phaser.Components {
export class Properties {
/**
* Handy for storing health percentage or armor points or whatever.
* @type {number}
*/
public health: number;
/**
* Reduces the "health" variable of this sprite by the amount specified in Damage.
* Calls kill() if health drops to or below zero.
*
* @param Damage {number} How much health to take away (use a negative number to give a health bonus).
*/
public hurt(damage: number) {
this.health = this.health - damage;
if (this.health <= 0)
{
//this.kill();
}
}
}
}
Binary file not shown.
+187
View File
@@ -0,0 +1,187 @@
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Phaser;
(function (Phaser) {
var Tilemap = (function (_super) {
__extends(Tilemap, _super);
function Tilemap(game, key, mapData, format, resizeWorld, tileWidth, tileHeight) {
if (typeof resizeWorld === "undefined") { resizeWorld = true; }
if (typeof tileWidth === "undefined") { tileWidth = 0; }
if (typeof tileHeight === "undefined") { tileHeight = 0; }
_super.call(this, game);
this.collisionCallback = null;
this.isGroup = false;
this.tiles = [];
this.layers = [];
this.mapFormat = format;
switch(format) {
case Tilemap.FORMAT_CSV:
this.parseCSV(game.cache.getText(mapData), key, tileWidth, tileHeight);
break;
case Tilemap.FORMAT_TILED_JSON:
this.parseTiledJSON(game.cache.getText(mapData), key);
break;
}
if(this.currentLayer && resizeWorld) {
this._game.world.setSize(this.currentLayer.widthInPixels, this.currentLayer.heightInPixels, true);
}
}
Tilemap.FORMAT_CSV = 0;
Tilemap.FORMAT_TILED_JSON = 1;
Tilemap.prototype.update = function () {
};
Tilemap.prototype.render = function (camera, cameraOffsetX, cameraOffsetY) {
if(this.cameraBlacklist.indexOf(camera.ID) == -1) {
for(var i = 0; i < this.layers.length; i++) {
this.layers[i].render(camera, cameraOffsetX, cameraOffsetY);
}
}
};
Tilemap.prototype.parseCSV = function (data, key, tileWidth, tileHeight) {
var layer = new Phaser.TilemapLayer(this._game, this, key, Phaser.Tilemap.FORMAT_CSV, 'TileLayerCSV' + this.layers.length.toString(), tileWidth, tileHeight);
data = data.trim();
var rows = data.split("\n");
for(var i = 0; i < rows.length; i++) {
var column = rows[i].split(",");
if(column.length > 0) {
layer.addColumn(column);
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
this.generateTiles(tileQuantity);
};
Tilemap.prototype.parseTiledJSON = function (data, key) {
data = data.trim();
var json = JSON.parse(data);
for(var i = 0; i < json.layers.length; i++) {
var layer = new Phaser.TilemapLayer(this._game, this, key, Phaser.Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight);
layer.alpha = json.layers[i].opacity;
layer.visible = json.layers[i].visible;
layer.tileMargin = json.tilesets[0].margin;
layer.tileSpacing = json.tilesets[0].spacing;
var c = 0;
var row;
for(var t = 0; t < json.layers[i].data.length; t++) {
if(c == 0) {
row = [];
}
row.push(json.layers[i].data[t]);
c++;
if(c == json.layers[i].width) {
layer.addColumn(row);
c = 0;
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
}
this.generateTiles(tileQuantity);
};
Tilemap.prototype.generateTiles = function (qty) {
for(var i = 0; i < qty; i++) {
this.tiles.push(new Phaser.Tile(this._game, this, i, this.currentLayer.tileWidth, this.currentLayer.tileHeight));
}
};
Object.defineProperty(Tilemap.prototype, "widthInPixels", {
get: function () {
return this.currentLayer.widthInPixels;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Tilemap.prototype, "heightInPixels", {
get: function () {
return this.currentLayer.heightInPixels;
},
enumerable: true,
configurable: true
});
Tilemap.prototype.setCollisionCallback = function (context, callback) {
this.collisionCallbackContext = context;
this.collisionCallback = callback;
};
Tilemap.prototype.setCollisionRange = function (start, end, collision, resetCollisions, separateX, separateY) {
if (typeof collision === "undefined") { collision = Phaser.Collision.ANY; }
if (typeof resetCollisions === "undefined") { resetCollisions = false; }
if (typeof separateX === "undefined") { separateX = true; }
if (typeof separateY === "undefined") { separateY = true; }
for(var i = start; i < end; i++) {
this.tiles[i].setCollision(collision, resetCollisions, separateX, separateY);
}
};
Tilemap.prototype.setCollisionByIndex = function (values, collision, resetCollisions, separateX, separateY) {
if (typeof collision === "undefined") { collision = Phaser.Collision.ANY; }
if (typeof resetCollisions === "undefined") { resetCollisions = false; }
if (typeof separateX === "undefined") { separateX = true; }
if (typeof separateY === "undefined") { separateY = true; }
for(var i = 0; i < values.length; i++) {
this.tiles[values[i]].setCollision(collision, resetCollisions, separateX, separateY);
}
};
Tilemap.prototype.getTileByIndex = function (value) {
if(this.tiles[value]) {
return this.tiles[value];
}
return null;
};
Tilemap.prototype.getTile = function (x, y, layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileIndex(x, y)];
};
Tilemap.prototype.getTileFromWorldXY = function (x, y, layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileFromWorldXY(x, y)];
};
Tilemap.prototype.getTileFromInputXY = function (layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileFromWorldXY(this._game.input.getWorldX(), this._game.input.getWorldY())];
};
Tilemap.prototype.getTileOverlaps = function (object) {
return this.currentLayer.getTileOverlaps(object);
};
Tilemap.prototype.collide = function (objectOrGroup, callback, context) {
if (typeof objectOrGroup === "undefined") { objectOrGroup = null; }
if (typeof callback === "undefined") { callback = null; }
if (typeof context === "undefined") { context = null; }
if(callback !== null && context !== null) {
this.collisionCallback = callback;
this.collisionCallbackContext = context;
}
if(objectOrGroup == null) {
objectOrGroup = this._game.world.group;
}
if(objectOrGroup.isGroup == false) {
this.collideGameObject(objectOrGroup);
} else {
objectOrGroup.forEachAlive(this, this.collideGameObject, true);
}
};
Tilemap.prototype.collideGameObject = function (object) {
if(object !== this && object.immovable == false && object.exists == true && object.allowCollisions != Phaser.Collision.NONE) {
this._tempCollisionData = this.collisionLayer.getTileOverlaps(object);
if(this.collisionCallback !== null && this._tempCollisionData.length > 0) {
this.collisionCallback.call(this.collisionCallbackContext, object, this._tempCollisionData);
}
return true;
} else {
return false;
}
};
Tilemap.prototype.putTile = function (x, y, index, layer) {
if (typeof layer === "undefined") { layer = 0; }
this.layers[layer].putTile(x, y, index);
};
return Tilemap;
})(Phaser.GameObject);
Phaser.Tilemap = Tilemap;
})(Phaser || (Phaser = {}));
+434
View File
@@ -0,0 +1,434 @@
/// <reference path="../Game.ts" />
/// <reference path="../components/TilemapLayer.ts" />
/// <reference path="../components/Tile.ts" />
/**
* Phaser - Tilemap
*
* This GameObject allows for the display of a tilemap within the game world. Tile maps consist of an image, tile data and a size.
* Internally it creates a TilemapLayer for each layer in the tilemap.
*/
module Phaser {
export class Tilemap {
/**
* Tilemap constructor
* Create a new <code>Tilemap</code>.
*
* @param game {Phaser.Game} Current game instance.
* @param key {string} Asset key for this map.
* @param mapData {string} Data of this map. (a big 2d array, normally in csv)
* @param format {number} Format of this map data, available: Tilemap.FORMAT_CSV or Tilemap.FORMAT_TILED_JSON.
* @param resizeWorld {boolean} Resize the world bound automatically based on this tilemap?
* @param tileWidth {number} Width of tiles in this map.
* @param tileHeight {number} Height of tiles in this map.
*/
constructor(game: Game, key: string, mapData: string, format: number, resizeWorld: bool = true, tileWidth?: number = 0, tileHeight?: number = 0) {
//super(game);
this.isGroup = false;
this.tiles = [];
this.layers = [];
this.mapFormat = format;
switch (format)
{
case Tilemap.FORMAT_CSV:
this.parseCSV(game.cache.getText(mapData), key, tileWidth, tileHeight);
break;
case Tilemap.FORMAT_TILED_JSON:
this.parseTiledJSON(game.cache.getText(mapData), key);
break;
}
if (this.currentLayer && resizeWorld)
{
this._game.world.setSize(this.currentLayer.widthInPixels, this.currentLayer.heightInPixels, true);
}
}
private _tempCollisionData;
/**
* Tilemap data format enum: CSV.
* @type {number}
*/
public static FORMAT_CSV: number = 0;
/**
* Tilemap data format enum: Tiled JSON.
* @type {number}
*/
public static FORMAT_TILED_JSON: number = 1;
/**
* Array contains tile objects of this map.
* @type {Tile[]}
*/
public tiles : Tile[];
/**
* Array contains tilemap layer objects of this map.
* @type {TilemapLayer[]}
*/
public layers : TilemapLayer[];
/**
* Current tilemap layer.
* @type {TilemapLayer}
*/
public currentLayer: TilemapLayer;
/**
* The tilemap layer for collision.
* @type {TilemapLayer}
*/
public collisionLayer: TilemapLayer;
/**
* Tilemap collision callback.
* @type {function}
*/
public collisionCallback = null;
/**
* Context for the collision callback called with.
*/
public collisionCallbackContext;
/**
* Format of this tilemap data. Available values: Tilemap.FORMAT_CSV or Tilemap.FORMAT_TILED_JSON.
* @type {number}
*/
public mapFormat: number;
/**
* Inherited update method.
*/
public update() {
}
/**
* Render this tilemap to a specific camera with specific offset.
* @param camera {Camera} The camera this tilemap will be rendered to.
* @param cameraOffsetX {number} X offset of the camera.
* @param cameraOffsetY {number} Y offset of the camera.
*/
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number) {
if (this.cameraBlacklist.indexOf(camera.ID) == -1)
{
// Loop through the layers
for (var i = 0; i < this.layers.length; i++)
{
this.layers[i].render(camera, cameraOffsetX, cameraOffsetY);
}
}
}
/**
* Parset csv map data and generate tiles.
* @param data {string} CSV map data.
* @param key {string} Asset key for tileset image.
* @param tileWidth {number} Width of its tile.
* @param tileHeight {number} Height of its tile.
*/
private parseCSV(data: string, key: string, tileWidth: number, tileHeight: number) {
var layer: TilemapLayer = new TilemapLayer(this._game, this, key, Tilemap.FORMAT_CSV, 'TileLayerCSV' + this.layers.length.toString(), tileWidth, tileHeight);
// Trim any rogue whitespace from the data
data = data.trim();
var rows = data.split("\n");
for (var i = 0; i < rows.length; i++)
{
var column = rows[i].split(",");
if (column.length > 0)
{
layer.addColumn(column);
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
this.generateTiles(tileQuantity);
}
/**
* Parset JSON map data and generate tiles.
* @param data {string} JSON map data.
* @param key {string} Asset key for tileset image.
*/
private parseTiledJSON(data: string, key: string) {
// Trim any rogue whitespace from the data
data = data.trim();
var json = JSON.parse(data);
for (var i = 0; i < json.layers.length; i++)
{
var layer: TilemapLayer = new TilemapLayer(this._game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight);
layer.alpha = json.layers[i].opacity;
layer.visible = json.layers[i].visible;
layer.tileMargin = json.tilesets[0].margin;
layer.tileSpacing = json.tilesets[0].spacing;
var c = 0;
var row;
for (var t = 0; t < json.layers[i].data.length; t++)
{
if (c == 0)
{
row = [];
}
row.push(json.layers[i].data[t]);
c++;
if (c == json.layers[i].width)
{
layer.addColumn(row);
c = 0;
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
}
this.generateTiles(tileQuantity);
}
/**
* Create tiles of given quantity.
* @param qty {number} Quentity of tiles to be generated.
*/
private generateTiles(qty:number) {
for (var i = 0; i < qty; i++)
{
this.tiles.push(new Tile(this._game, this, i, this.currentLayer.tileWidth, this.currentLayer.tileHeight));
}
}
public get widthInPixels(): number {
return this.currentLayer.widthInPixels;
}
public get heightInPixels(): number {
return this.currentLayer.heightInPixels;
}
// Tile Collision
/**
* Set callback to be called when this tilemap collides.
* @param context {object} Callback will be called with this context.
* @param callback {function} Callback function.
*/
public setCollisionCallback(context, callback) {
this.collisionCallbackContext = context;
this.collisionCallback = callback;
}
/**
* Set collision configs of tiles in a range index.
* @param start {number} First index of tiles.
* @param end {number} Last index of tiles.
* @param collision {number} Bit field of flags. (see Tile.allowCollision)
* @param resetCollisions {boolean} Reset collision flags before set.
* @param separateX {boolean} Enable seprate at x-axis.
* @param separateY {boolean} Enable seprate at y-axis.
*/
public setCollisionRange(start: number, end: number, collision?:number = Collision.ANY, resetCollisions?: bool = false, separateX?: bool = true, separateY?: bool = true) {
for (var i = start; i < end; i++)
{
this.tiles[i].setCollision(collision, resetCollisions, separateX, separateY);
}
}
/**
* Set collision configs of tiles with given index.
* @param values {number[]} Index array which contains all tile indexes. The tiles with those indexes will be setup with rest parameters.
* @param collision {number} Bit field of flags. (see Tile.allowCollision)
* @param resetCollisions {boolean} Reset collision flags before set.
* @param separateX {boolean} Enable seprate at x-axis.
* @param separateY {boolean} Enable seprate at y-axis.
*/
public setCollisionByIndex(values:number[], collision?:number = Collision.ANY, resetCollisions?: bool = false, separateX?: bool = true, separateY?: bool = true) {
for (var i = 0; i < values.length; i++)
{
this.tiles[values[i]].setCollision(collision, resetCollisions, separateX, separateY);
}
}
// Tile Management
/**
* Get the tile by its index.
* @param value {number} Index of the tile you want to get.
* @return {Tile} The tile with given index.
*/
public getTileByIndex(value: number):Tile {
if (this.tiles[value])
{
return this.tiles[value];
}
return null;
}
/**
* Get the tile located at specific position and layer.
* @param x {number} X position of this tile located.
* @param y {number} Y position of this tile located.
* @param [layer] {number} layer of this tile located.
* @return {Tile} The tile with specific properties.
*/
public getTile(x: number, y: number, layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileIndex(x, y)];
}
/**
* Get the tile located at specific position (in world coordinate) and layer. (thus you give a position of a point which is within the tile)
* @param x {number} X position of the point in target tile.
* @param x {number} Y position of the point in target tile.
* @param [layer] {number} layer of this tile located.
* @return {Tile} The tile with specific properties.
*/
public getTileFromWorldXY(x: number, y: number, layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileFromWorldXY(x, y)];
}
public getTileFromInputXY(layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileFromWorldXY(this._game.input.getWorldX(), this._game.input.getWorldY())];
}
/**
* Get tiles overlaps the given object.
* @param object {GameObject} Tiles you want to get that overlaps this.
* @return {array} Array with tiles informations. (Each contains x, y and the tile.)
*/
public getTileOverlaps(object: GameObject) {
return this.currentLayer.getTileOverlaps(object);
}
// COLLIDE
/**
* Check whether this tilemap collides with the given game object or group of objects.
* @param objectOrGroup {function} Target object of group you want to check.
* @param callback {function} This is called if objectOrGroup collides the tilemap.
* @param context {object} Callback will be called with this context.
* @return {boolean} Return true if this collides with given object, otherwise return false.
*/
public collide(objectOrGroup = null, callback = null, context = null) {
if (callback !== null && context !== null)
{
this.collisionCallback = callback;
this.collisionCallbackContext = context;
}
if (objectOrGroup == null)
{
objectOrGroup = this._game.world.group;
}
// Group?
if (objectOrGroup.isGroup == false)
{
this.collideGameObject(objectOrGroup);
}
else
{
objectOrGroup.forEachAlive(this, this.collideGameObject, true);
}
}
/**
* Check whether this tilemap collides with the given game object.
* @param object {GameObject} Target object you want to check.
* @return {boolean} Return true if this collides with given object, otherwise return false.
*/
public collideGameObject(object: GameObject): bool {
if (object !== this && object.immovable == false && object.exists == true && object.allowCollisions != Collision.NONE)
{
this._tempCollisionData = this.collisionLayer.getTileOverlaps(object);
if (this.collisionCallback !== null && this._tempCollisionData.length > 0)
{
this.collisionCallback.call(this.collisionCallbackContext, object, this._tempCollisionData);
}
return true;
}
else
{
return false;
}
}
/**
* Set a tile to a specific layer.
* @param x {number} X position of this tile.
* @param y {number} Y position of this tile.
* @param index {number} The index of this tile type in the core map data.
* @param [layer] {number} which layer you want to set the tile to.
*/
public putTile(x: number, y: number, index: number, layer?: number = 0) {
this.layers[layer].putTile(x, y, index);
}
// Set current layer
// Set layer order?
// Delete tiles of certain type
// Erase tiles
}
}
@@ -0,0 +1,715 @@
PART -1: intro/preamble
[3]**
-download the slides at: [++TODO: URL to slides.. metanet/tutorials/fitc05.zip?]
who am i
-one of two people who made N
-we've been using flash since v5 (i.e since actionscript was useful and easy to use)
<short demo of N, just watch a mainmenu replay>**
-promo blurb: "N is a platform/run-and-jump game which combines oldschool gameplay
with modern collision detection + physics simulation"
-we made N with flash prove that flash/actionscript could be used for "real video games"
[4]** -"the curse of sylvaniah" (by Strille/Luxregina) is another great game which also proves our point:
games made in flash can be "real video games"
[5]** -collision detection is a vast feild of research
-impossible to cover properly in an hour.
-i'll present specific methods well-suited for use in flash/actionscript
-some of the ideas we used in N, as well as some of the stuff we've learnt since making N
-there is a LOT of stuff to cover
-i'm going to try to introduce you to the ideas involved without a lot of technical detail
-understand the concepts, independent from the implementation of the concept
-there WILL be some code and formulas and stuff
-it's more important to understand the meaning behind the code and formulas.
-you can check out our online tutorials if you need to look at source.
-warning: i'm a programmer. these slides count as "programmer art".
-ask:
-how many people know what a vector is?
-how many people know what a dotproduct is?
[6]**
-to begin:
-this lecture is about collision detection
-implicitly, it's about game programming in flash
-game programming in flash feels a bit wrong.
-it certainly wasn't made for video games.
-there is a sense of "we're abusing this platform"
-but we're going to write games in flash anyway, so why not try to do it well.
-i'll start by trying to convince you about why collision detection matters
-then i'll discuss some solutions for dealing with collision detection
MOTIVATION:
-why does collision detection matter? is it only useful for ninja platformers?
[7]** -no. a lot of games would benefit from better collision detection/response
-everyone's favorite, the top-view racing game
-pool, pinball,
-basketball/sports (show McShitOut and/or scribball demo)
-platforming games
[8]** -most importantly: _new_ types of genre-defying games which you're going to invent next week
[9]** -having a good collision detection+response system enables a wide range of (otherwise inaccessible) gameplay possibilities.
[10]**
-HitTest:
-why do we need to learn about collision detection?
-doesn't flash already have built-in collision detection?
-yes, but it has two major weaknesses
1: only returns a yes/no answer
2: only works with axis-aligned rectangles
[11]** -what can you do with a yes/no answer?:
[12]** -destroy one/both objects
[13]** -move one/both objects to old position
[14]** -reverse direction of one/both objects
-or any combination of the above
[15]** -what can't you do with a yes/no answer?:
[16]** -friction and bounce
[17]** -sliding along obstacles
[18]** -rotating to orient to the ground
-etc.
[19]** -what can you do with axis-aligned rectangles?:
-anything! ..as long as it involves unrotated rectangles
[20]** -what can't you do with axis-aligned rectangles?:
-circles
-concave surfaces
-curved or angled surfaces
-rotating shapes
-etc.
[21]** -using hittest, if you need more than a yes/no answer about a collision, you can use "tricks":
-sample multiple points on an object
-from the multiple yes/no results, infer information about the collision direction, etc.
-if you work hard enough, you _might_ get it to work..
[22]** -it will be slower than it needs to be (due to the number of calls to hittest)
-it won't work 100% of the time (because you're relying on implied/approximated and not actual information)
-it just doesn't feel as solid as "the real thing"
[23]** -HitTest is awesome -- if you're living in the 80s
-lots of moving rectangles which explode when they touch each other
-if you want to actually respond to collisions in a meaningful way, HitTest isn't enough
-meaningful collision response requires meaningful information about the collision.
-better information, better response, better games, better "feel"
-ultimately, "real" (non-HitTest) collision detection enables "physics"
-physics?!
[24]** -in video games this year, "physics is the new graphics".. everyone wants more physics in their games.
-one common misconception is that "physics" means "slow and complex code". physics doesn't have to be complicated or slow.
<demo ragdoll>**
[25]** -"physics" is a much-abused term.
-most of the time it just means "things moving".
-if you've ever written "position += velocity" or "newpos = oldpos + velocity",
you've already been using "physics".
-what are you afraid of?
[26]** -the only math you need to know is some vector algebra/geometry which we'll cover
-no trig: trig is horrible
-it's very difficult to develop an intuition about it
-it's very hard to visualize when thinking about a problem
-vectors are your friends
-they can be used to replace trig in 99% of situations
-they are easy to visualize and develop intuitions about
[27]** -most importantly: flash vs. SNES
-way less graphical power, way more processing power
-flash can't compete with modern (or even classic) video games when it comes to graphical power
-consoles and PCs have dedicated graphics hardware; flash has only got the CPU
-flash CAN compete in terms of processing power and memory
-the SNES (which came out in 1991) had the same processor as an apple IIgs..
-even with the overhead of the flashplayer VM, flash outperforms the SNES in terms of both speed and complexity
-double-precision floating point, which lets us do a lot of things which simply weren't possible on an SNES
-because of the overhead of the flash VM, "expensive" ops like sqrt() aren't
really much more expensive than any other math op (+, -, etc.)
-this gives us flexibility to pursue different solutions (which might not be tractable on other platforms)
-flashplayer has built-in support for sophisticated structures like hashmaps (i.e "objects")
and dynamic memory management
-this makes it easier for us to explore complex ideas than possible on a SNES
[28]** -so: flash games have the ability to compete with modern (or classic) video games on the battlefield known as "gameplay"
-collision detection and physics are two great tools for developing novel gameplay
[29]** -some examples of games that are using collision detection and physics to create different types of gameplay
[30]**
[31]**
[32]**
-hopefully you're now motivated
[33]**
PART 0: collision response
-collision response is important to mention breifly because it provides the motivation for collision detection
-see our website for tutorials and links to more info
-collision response is _why_ you need a collision detection solution that's more informative than HitTest
-collision detection provides you with information describing a collision;
-if you don't _use_ this information in a meaningful way, CD is moot
[34]** -collision response "in a nutshell":
-there are many different ways to handle collision response
-they all of the need to know the same thing
[35]** -penetration direction, penetration amount
-pdir*pamt = penetration vector, projection vector, etc.
-i may use "penetration vector" and "projection vector" interchangeably
[36]** -one thing we want to do when notified of a collision is prevent the two colliding objects from continuing to collide
-a simple solution to this is "projection"
-given two colliding objects and their penetration vector
-translate (move) one object by the penetration vector
-OR: translate both objects by 1/2 the penetration vector
-etc.. playing with the ratios allows the simulation of objects with different relative mass
-i.e heavy objects aren't moved very much
[37]** -aside from preventing the objects from continuing to overlap, you can modify their properties based on the direction of the collision surface
-penetration vector describes the surface direction of the collision
-you can measure the velocity of objects parallel to and perpendicular to the surface
-we'll cover the math later, it's simple vector projection
[38]** -you break the object's velocity down into those two components
-scale each component seperately/differently, and recombine them to get the post-collision velocity
-this lets you simulate friction/bounce
-you can also let game logic make decisions based collision information
-rotating object graphics so that they align themselves to the ground
-inflicting damage for violent collisions
(the object's velocity perpendicular to the surface tells you how violent the collision was)
<demo: level 0-0, ninja skidding around and rotating to match the surface of things>**
<demo: level 0-0, ninja falling to death>**
[39]**
PART 1: narrow-phase collision detection, aka object-vs-object testing
[40]** -so, what we need to do when performing collision detection on a pair of shapes is:
(a) determine if the two shapes are colliding, and if so
(b) calculate the penetration vector which describes the collision
[41]** -actually.. that's only half of the collision detection problem.
-the other half is knowing which pairs of shapes to test in the first place
[42]** -these two parts of the collision detection process are often called "narrow" and "broad" phase collision detection
-broad = figuring out which pairs of objects we must test
-narrow = testing each pair
-sort of like sifting through something: start with a coarse filter to elliminate most things, then use a fine-grained filter on the remaining stuff
-we'll start with narrow-phase and then discuss broad-phase
-i'll try to answer questions breifly after each section
-i'd prefer to stick to specific questions (i.e if i'm not explaining something in detail)
-leave larger questions for Q&A at the end of the presentation
-there are several different approaches to object-vs-object tests; the one i'm going to describe is based on something called "the method of seperating axes" <todo: refer to ginoVDB and geomtools books>
-it's well-suited for flash
-fast (faster than any other method we've seen)
-simple (easy to understand, easy to code)
-flexible (easy to adapt to many different situations)
[43]**
-the method of seperating axes, in english
-there will be a lot of "axis" talk
-axis really just means "direction". any time you hear "axis", you can mentally substitute "direction".
-1 vector, many vertices
-1 axis, many axes
[44]** -the Method of Seperating Axes is based on the Seperating Axis Theorem:
-a mathmatical theorem about the properties of convex polygons
[45]** -thus, this method only works for convex shapes
-what is a convex shape? probably you've at least got an intuitive understanding of convexity.
there are many "practical" definitions:
-no internal angles <= 180deg
-a line connecting any two points inside the shape is contained within the shape
-only lefthand turns when walking CCW around the surface
-etc.
[46]** -Seperating Axis Theorem, part 1:
-if two convex polygons don't overlap, then there must be a direction along which they are "seperated"
-the converse is also true: if there is no direction which seperates two objects, the objects must be overlapping
-"seperated" means that, if we look at the world along that direction, there is a space between the two shapes
-the direction we look along is called an axis
-if the two objects are seperated, it's a seperating axis
-you could think of it as a line through the objects; it's offset in diagrams to make it less cluttered/confusing
<diagram: show seperated and overlapping cases>
[47]** -Seperating Axis Theorem, part 2:
-we don't have to test _all_ directions; if there is a seperating axis, then it must be perpendicular to an edge of one of the shapes
-so, instead of testing all possible directions to find a seperating axis,
we only test those directions which are perpendicular to the edges of our polygons
<diagram: as before, but point out/focus on normal directions>
-there's a proof for the SAT, but that's (thankfully) outside the scope of this lecture
-we didn't invent this method, we just noticed that other game programmers were using it
[48]** -the Method of Seperating Axes is a method of collision detection which is based on SAT:
-given two shapes, determine all the potentially seperating axes for those shapes
-i.e determine the directions which are perpendicular to each edges of each polygon
-test each potentially seperating axis until we find an axis along which the objects are seperated
-if we've tested all potentially seperating axes and found none that are seperating the objects,
the objects are colliding
-instead of a single, complicated 2D test (based on minimum distance or whatever), we perform a series of simple 1D tests
-each test is along a different direction, or "axis"
-each test boils down to a few lines of very simple (and fast) math
-we'll get to the math shortly
-the strength of this method is the "early out"
-we don't need to test every potentially seperating axis; as soon as we find an axis which seperates the two shapes,
we know (thanks to the SAT) they can't be colliding and we can skip the rest of the axes
-this means when two objects aren't colliding, we do less work than when they are
-in a typical game, any two objects picked at random are likely NOT colliding,
so optimising the not-colliding case makes sense and really speeds things up
[49]** -before we get into actual code, let's review some basic vector algebra/geometry
-basic vector math: nothing to be afraid of
[50]** -vectors (difference of two points)
[51]** -unit vectors/direction
-unit vectors: vectors whose length is 1
-very useful to use these to represent directions, INSTEAD of angles/radians/etc.
-they've got some useful properties which we'll see in a moment
-formula/code:
-basically, you divide x and y components by the length of the vector
-null (0-length) vectors don't work
-when you multiple a unit vector by a scalar X, the result is a vector which points in the same
direction as the unit vector, but which is X units long
-in this presentation, whenever you hear "axis" (and/or "direction"), this means normalized unit vector
-the process of taking a vector and scaling it until it's unit-length is called "normalization"
-the vector has been normalized
-NOT to be confused with the following
[52]** -normal vectors (NOT to be confused with normalized vectors! althouth.. normal vectors are often normalized..)
-perpendicular to a vector
-formula/code: it's so simple it's weird that the results are meaningful/useful
-each vector has two of these, LH and RH
[53]** -by convention, polygon edges are arranged in CCW order
-this means that each edge's RHnorm points "out" of the polygon edge
-these are of special importance to us: the RHnorms of each edge of a polygon _are_ the potentially seperating axes we must test
[54]** -dotproduct
-in highschool you may have learnt a definition of dotprod involving cosine:
-AdotB = |A|*|B|*cos(angle between A and B)
-this is irrelevant
-dotprod is a measure of the relative directions of two vectors
-formula/code: as with normal vectors, it's so simple it's weird that the results are meaningful/useful
-the important thing to note is that:
-when two vectors point in the same direction, their dp is at maximum value
-then they point in opposite directions, their dp is at minimum value
-when they're perpendicular to each other, their dp is 0
[55]** -if vector A is unit length and vector B isn't, the min/max values of their dp are -/+ the length of B
-the value of the dp is no longer just some value, it's now "meaningful":
-it's the _length_ of vector B when "measured along" the direction described by vector A
-"measured along, viewed along, the length of the image of B on A", etc.
-this is important for projection
[56]** -vector projection
-just one multiplication step added onto the end of a dotprod
-as we just learnt, when vector A is unit length, and vector B isn't,
AdotB gives you the length of the "image" of B, when measured along A
-we can make a vector of length AdotB, which is parallel to A
-just multiply A (unit vector) by AdotB
-that vector is called the projection of B onto A
-you can think of it as "B when viewed/measured along the line containing A"
-mapping 2D to 1D
[57]** -this is the core of our method: projecting shapes onto each potentially seperating axis
-if we only care about the length of the projected vector (i.e the dotproduct), we can use the dotproduct itself
-this is also what we use for friction/bounce
-as we saw earlier, you decompose object velocity into two perp. components
by projecting them onto the surface direction
[58]** -the method of seperating axes, revisited
-the if(overlap) step is "where all the action is"
[59]** -example: Box vs. Box
-figure out which axes we have to test
-aside: normally, testing two quadrilaterals would involve testing 8 potentially seperating axes
(4 from each quad)
-boxes are a special case which exploit the SAT's rules
-we need to test all directions which are perpendicular to the surface of each shape
-since, for each box, a single direction is perp. to two surfaces,
we can perform a single axis test for each pair of opposite box edges
-anyway:
-calculate the object-object delta vector (vector from center of one object ot center of the other)
-for each potentially seperating axis (show all 4 axes, then show each step below on a single axis):
-calculate the projected halfsize of each object (projected = when measured along the axis) (BLUE)
-calculate the projected length of the delta vector (projected = when measured along the axis) (GREEN)
-calculate the difference between the sum of the halfsizes, and the delta vector
-if negative, we've found a seperating axis and we can stop: the shapes don't overlap
-if positive, objects overlap along the axis, continue testing (RED)
[60]** -if, after testing each axis, we still haven't found a seperating axis, then the objects must be colliding
[61]** -what??!? i'm confused..
-why are we using this weird concept of "halfsize"?
-don't we still end up with only a yes/no answer? i thought this approach was supposed to give us more info
-..wait a minute.
-this might seem familiar.
[62]** -one very useful insight for understanding this approach is that it's a generalisation of circle-circle collision detection
(which everyone is probably familiar with)
[63]** -circle-circle <diagram each step>
-calculate the object-object delta vector
-for each potentially seperating axis (in this case, there's only one: the axis which passes through both circles' centers)
-calculate distance between circles
-SAT: calculate the projected size of the delta vector (in this case, this is == the length of the delta vector)
-calculate sum of radii
-SAT: calculate the projected halfsize of each object (in this case, this is == their radius)
-calculate the difference between the sum of halfsizes/radii and the delta vector
-if positive, objects overlap along the axis
[64]** -not only does this help us understand what's going on in our SAT test,
it also suggests how to get more than a yes/no answer from the results
-do whatever we do in the circle-circle case
-if the circles ARE overlapping
-the penetration direction is parallel to the axis
-the amount is equal to the difference we calculated (sum-of-radii minus size-of-delta)
[65]** -Box-vs-Box revisited
-it's the same process as with two circles, except that we have to test more than just a single potentially seperating axis
-each axis test is analogous to the circle-circle test, they just involve a bit more math, to project things onto the axis..
-in the circle case, the object halfwidths and delta vectors are parallel to the axis
-as we saw with dotprods, when you project a vector onto an axis that's parallel to the vector, you get the
original vector
-like multiplying any number by 1
-so, for circles, the values are basically "pre-projected" and we skip the projection math
-as soon as we find a seperating axis, we're done -- we know the objects don't overlap
[66]** -as with circles, if the objects ARE overlapping (i.e we tested all axes and none are seperating the two objects),
we can extract collision info "for free" from the per-axis calculations we made
-the axis with the smallest "difference" (sum-of-halfsizes minus size-of-delta) is the projection direction
-the size of the difference is the projection amount
-projection direction + projection amount = projection vector. tada!
[67]** -so, we can use this method to collide any two shapes together, provided that for each shape we can quickly determine:
a) which directions are perpendicular to the shape's surface
(i.e which axes are potentially seperating directions for that shape)
b) how to project the shape onto an axis, i.e
-the shape's center (when projected onto an axis)
-the shape's size/halfsize (when projected onto an axis)
[68]** -example: projecting a box onto an axis
-this is code for an arbitrarily rotated box (in the diagrams, we're just keeping the box still and moving the axis..)
-it's the same thing/relativity
-an important insight for box projection is:
the sum of the projections of the halfwidth vectors = projected halfwidth of box
<point to diagram of this>
[69]** -box representation:
-position (of box center)
-width/height (along object axes)
-unit vector (describing orientation of box; we use the convention that the orientation vector points along local x)
-see our tutorials for examples of how to project different shapes
-linesegs should be obvious
[70]** -step through Box-vs-Box code line-by-line, examining/explaining it
-point out that you COULD make the code more generic/general
-each shape has an array of unit vectors representing potential seperating axes
-each shape has a function "Project" which return the object's halfsize when projected onto a given axis
-however, if you want to it run as fast as possible, writing special code for each possible combination of objects is the best solution
[71]** -what we left out:
[66]** might help when explaining this
-tracking minimum penetration axis
-store all pen amounts and compare them at the end, or keep a "running minimum"
-which direction to project?
-projdir is parallel to the axis of minimum projection, but could point in two possible directions
-use the sign of the delta<dot>axis
[72]**-what about circles?
-we haven't mentioned circles or curved surfaces yet, but they're very useful as collision shapes
-the main difference between circles and polygons is the behaviour around corners (vertices)
-circles "roll" around corners: the collision direction changes smoothly
-polygons slide across them: the collision direction remains the same (surface normal)
<demo: use tutorialA demo: circle falling/sliding off the top of a square>**
<demo: as above, but use an AABB falling/sliding off the top of a square>**
-another way to look at this difference is that, unlike polygons,
there aren't a finite/discrete number of directions perpendicular to a circle's surface
-this is a problem, since our approach relies on knowing which directions might be potentially seperating directions
-but: since this SAT approach is a sort of generalization of circle-circle collision,
surely we can support circles without too much extra work
[73]** -we can
-instead of reiterating what's presented in our online tutorials, i'll just refer you to them
-the basic idea is that for a circle you perform the exact same tests as you would for a box, except you sometimes
perform a single additional test at the end
-to handle the case where the circle is colliding with a "corner" (vertex) of a shape instead of an edge (lineseg)
-you don't always have to perform this test
-there is a fast and simple way to determine if you have to perform this additional test
-you can use information from the axes you've already tested
-if the overlap along the box axes is less than the circle's radius, we know the circle is in a corner region
<demonstrate the above values/etc. with the diagram>
-if the circle's center is in the horiz/vertical regions, we only test the two box axes
-we can tell if the circle is in these regions by looking at the results of these 2 axis tests
-if the circle's NOT in these regions, we have to test it vs. the nearest box corner
-again, which corner to use is easy since part of the 2 axis tests was determining the box->circle delta vector
-this delta vector "points" at the box corner
[74]** -what about non-convex shapes?
-this is important, especially for world/level shapes
-just represent them as a union of convex shapes
-several (possibly overlapping) convex shapes
[75]** -tilebased games use the same idea: decompose the world into small chunks
[76]** -a different decomposition is: linesegs
-this is leading into the next section into broad-phase
[77]** -optimisations:
-the key is to precompute as much information as possible, so that you don't have to calculate it at runtime
-instead you just lookup your precomputed value
-almost every game subscribes to the rule: "the vast majority of things in the world are static"
-i.e the game code makes a distinction between (static) world/level geometry, and (dynamic) objects
-makings things static is a great optimisation because we can precompute almost everything about each static object
-triangles and more complex shapes are harder to project than a box
-more lines of code
-you _can_ still do it on the fly, it's just slower
-calculations for circles and boxes are very fast and simple; they make good candidates for dynamic objects
-more complex shapes can be used for static objects, since most of the calculations
(calculating surface normals aka axis directions, etc.) can be done beforehand instead of at runtime
[78]** QUESTIONS about Seperating Axis Thereom / Method of Seperating Axes
[++TODO: figure out how much time we can spend here, and note it down so that, when presenting, we don't get stuck here for too long]
[79]**
PART 2: broad-phase collision detection, aka spatial database
-switching gears...
[80]** -knowing how to test two objects for collision is only part of the solution to the CD problem
[81]** -if there are 10 objects in the world, we'd have to perform 10*10=100 tests
-it doesn't matter how fast your object-object test is if you're using it 100 times per frame
-for N objects, you have to use N^2 tests
[82]** -we want to be able to very quickly determine which pairs of objects we should test, i.e which pairs MIGHT be colliding
-how to figure out what might be colliding?
-all the methods i know of for broad-phase CD use the assumption:
if two objects are near each other, then they might be colliding
-quickly == approximately; we don't need to know for sure, that's the job of the narrow-phase
-once we know which pairs MIGHT be colliding, we can pass them to our narrow-phase collision system
to figure out if they actually _are_ colliding, and if so, how.
-so, we just need to find a way to quickly determine, given an object or a position in the world,
all of the other objects nearby
-this step is _very_ game specific
-there is no "magic bullet"
[83]** -for small numbers of objects (<=5), using HitTest on each possible pair is often "good enough"
-you're still doing N^2 tests, but you're not doing too many of them, and they're not too expensive
-it's fast, and it tells you what you need to know (that the objects might be colliding)
-if HitTest returns true, you know their bounding boxes are overlapping, and can investigate further using complex tests
-however, for the sake of argument, SAT code for AABBs (i.e rectangles) can be just as fast as Hittest
-the main cost is the overhead of a function call
[84]** -for larger numbers of objects, you need a more sophisticated way to find all the objects near a given point
-this problem has been solved in many different ways:
-grid: divide space into uniform boxes
[85]** -quadtree: recursively subdivide space into 4 equal regions
[86]** -they all amount to the same thing: partitioning space into discrete chunks, and building a database using those chunks
-the data in the database is the location of objects
-hence broad-phase collision systems are often called spatial databases
-the two most important operations on this database are:
a) neighborhood query (quickly determining which objects are near a given position)
b) updating an entry in the database (i.e moving an object)
-optimising (a) is very simple if you don't care about (b)
-games which must support large numbers of moving objects must optimise (b)
-it's hard to do both at once; this is why broad-phase is so game-specific
[87]** -grids are best for flash
-there are many different ways to use grids, but ALL of them are better suited for flash than non-grid-based methods
-why only grids?
-grids allow for constant-time neighborhood queries, and constant-time updating
-the constant cost is extremely low
-for a neighborhood query, you simply find the cell which contains your query point,
then look in the surrounding cells
-to update the position of an object in the grid, you just need to find the cells which the object touches,
which is fast and simple
-more on this later
-all other spatial database approaches are based on search-trees of some sort
-the quadtree i showed you LOOKED sort of like a grid, but the implementation looks
like a normal tree data structure
-each node has 4 children, etc.
-when you look something up from a tree, you have to descend to the leaves, performing tests at each level of the tree
-each test takes time
-grids only require one test, not one test per level of the heirarchy
-likewise, inserting something into a tree is more complex than with a grid
-if grids are so good, why don't other games use them?
-most 2D games _do_ use grids
-obviously, any tile-based game is using some sort of grid
-even doom used grid-based collision
[88]** -the problem with grids is that they take up a LOT of space, since the entire world must be covered in cells
-a 200x100-tile world means a grid with 20000 cells; if each cell needs 256bytes, that's 5MB
-in 3D, this only gets worse: 200x100x100 @ 256bytes = 500MB
-this is why trees are used; they require far less memory. instead of covering the entire world,
you only cover the non-empty parts of the world
-the tradeoff is that trees are slower and more complex to query and update
[89]** -in flash, in 2D, you can afford the extra memory needed by a grid, but you _can't_ afford the extra processing time required by trees
[90]** -all grid operations involve a couple math ops
-you can't get any faster than that
[91]** -using a grid for object-vs-object tests
-i'll just provide an outline of the process
-see our online tutorials for implementation details and source code
[92]** -a grid is just an abstract data structure; there are many differnet ways to actually use the structure.
-two popular ways are "regular" and "loose" grids
<explain the following in english while using diagram to illustrate>
-regular grid:
-every object knows which grid cell(s) it touches
-every grid cell knows which object(s) are touching it
<refer to diagram>
each blue cell must be tested for collision, and each blue cell must be updated when objects move
-loose grid:
-every object knows which grid cell contains it's center
-every cell knows which object(s) it contains
<refer to diagram>
each red cell must be tested for collision, and each blue cell must be updated when objects move
-regular vs. loose:
-less tests vs less time to update moving objects
-can handle any sized shape vs shapes must fit in a cell
[93]** -using a grid for object-vs-world
-as mentioned earlier, most games divide objects into "static" and "dynamic" groups
-you CAN simply use the grid to collide dynamic vs. static objects exactly as you
would for dynamic vs. dynamic objects (as we just saw)
-however, if you know that most of the game world will consist of static shapes,
you might want to create a special system for colliding these static shapes against dynamic objects
[94]** -there isn't time to explore all of the possible ways to use a grid for object-vs-world tests
-i'll breifly cover 2 approaches
-tilebased and geometry-based
-tilebased collision:
-each grid cell stores a tile shape
-each moving object collides against all other moving objects and tiles in it's neighborhood
-again, our online tutorials cover this topic very well (i'd rather not just repeat info that's already available)
-tilebased systems SEEM like a good choice (simple and fast)
-in practise they're quite hard to get good behaviour out of
-tilebased collision is usually rule-based instead of math-based;
rule-based works well for simple dynamic models, but when you start needing smooth
physics-based object movement, rule-based collision simply doesn't perform well
-you end up doing lots of extra work to get things behaving well
-doing lots of extra work defeates the purpose of using a tilebased world in the first place, which was speed and simplicity
-a different grid-based approach is geometry/lineseg based
-the world is made out of polygons
-convex or concave, it doesn't matter
-as a preprocess, before runtime, you decompose your polygons into their component linesegs
-insert each lineseg into a grid
-determining which cells to insert a lineseg into can be done in several ways
-since it's a preprocess it doesn't really matter how slow this code is
-you can simply try lineseg-vs-AABB test for all cells touching the lineseg's bounding box
-or you can use raycast code (which we'll touch on soon)
-at runtime, object-vs-world collision involves one or two object-vs-lineseg tests
-linesegs are the simplest and fastest shapes to collide against
-they have only a single potentially seperating axis
-performing several object-vs-lineseg tests is MUCH faster than performing
several object-vs-tileshape tests
-this system can support the exact same levels and shapes as a tilebased system
-but it's far simpler
-instead of having many different possible tile-shapes to collide against, you have just one shape: lineseg
-it's also a lot faster
-testing vs. linesegs is faster than vs. timeshapes
[95]** -another great advantage that grids have over other spatial databases is: raycasting is very easy
-rays are lines with one endpoint
-they're used to model fast-moving bullets in many games (doom, quake)
-they're also very useful for line-of-sight testing (AI uses these to determine what each enemy can "see")
[96]** -a very efficient and simple to understand raycasting algorithm is presented in this paper
-it's very simple, and very fast
-yet again, please see our online tutorials for implementation details
[97]**
PART 3: misc/conclusion
-summary:
-collision detection is a powerful tool for making fun games
-the MSA is a useful tool for narrow-phase collision detection
-a uniform grid is a useful tool for broad-phase collision detection
-QUESTIONS?
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

+46
View File
@@ -0,0 +1,46 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/large-color-wheel.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var fade;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
fade = myGame.camera.fx.add(Phaser.FX.Camera.Fade);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Fade when the car hits the edges, a different colour per edge
if(car.x < 0) {
fade.start(0x330066, 3);
car.x = 0;
} else if(car.x > myGame.world.width) {
fade.start(0x000066, 3);
car.x = myGame.world.width - car.width;
}
if(car.y < 0) {
fade.start(0xffffff, 4);
car.y = 0;
} else if(car.y > myGame.world.height) {
fade.start(0x000000, 3);
car.y = myGame.world.height - car.height;
}
}
})();
+77
View File
@@ -0,0 +1,77 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/large-color-wheel.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var fade: Phaser.FX.Camera.Fade;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
fade = <Phaser.FX.Camera.Fade> myGame.camera.fx.add(Phaser.FX.Camera.Fade);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Fade when the car hits the edges, a different colour per edge
if (car.x < 0)
{
fade.start(0x330066, 3);
car.x = 0;
}
else if (car.x > myGame.world.width)
{
fade.start(0x000066, 3);
car.x = myGame.world.width - car.width;
}
if (car.y < 0)
{
fade.start(0xffffff, 4);
car.y = 0;
}
else if (car.y > myGame.world.height)
{
fade.start(0x000000, 3);
car.y = myGame.world.height - car.height;
}
}
})();
+46
View File
@@ -0,0 +1,46 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/large-color-wheel.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var flash;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
flash = myGame.camera.fx.add(Phaser.FX.Camera.Flash);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Flash when the car hits the edges, a different colour per edge
if(car.x < 0) {
flash.start(0xffffff, 1);
car.x = 0;
} else if(car.x > myGame.world.width) {
flash.start(0xff0000, 2);
car.x = myGame.world.width - car.width;
}
if(car.y < 0) {
flash.start(0xffff00, 2);
car.y = 0;
} else if(car.y > myGame.world.height) {
flash.start(0xff00ff, 3);
car.y = myGame.world.height - car.height;
}
}
})();
+77
View File
@@ -0,0 +1,77 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/large-color-wheel.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var flash: Phaser.FX.Camera.Flash;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
flash = <Phaser.FX.Camera.Flash> myGame.camera.fx.add(Phaser.FX.Camera.Flash);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Flash when the car hits the edges, a different colour per edge
if (car.x < 0)
{
flash.start(0xffffff, 1);
car.x = 0;
}
else if (car.x > myGame.world.width)
{
flash.start(0xff0000, 2);
car.x = myGame.world.width - car.width;
}
if (car.y < 0)
{
flash.start(0xffff00, 2);
car.y = 0;
}
else if (car.y > myGame.world.height)
{
flash.start(0xff00ff, 3);
car.y = myGame.world.height - car.height;
}
}
})();
+41
View File
@@ -0,0 +1,41 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
// Just set the world to be the size of the image we're loading in
myGame.world.setSize(1216, 896);
myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png');
myGame.loader.load();
}
var mirror;
function create() {
// What we need is a camera 800x400 pixels in size as the mirror effect will be 200px tall and sit below it.
// So we resize our default camera to 400px
myGame.camera.height = 400;
// Because it's our default camera we need to tell it to disable clipping, otherwise we'll never see the mirror effect render.
myGame.camera.disableClipping = true;
// Add our effect to the camera
mirror = myGame.camera.fx.add(Phaser.FX.Camera.Mirror);
// The first 2 parameters are the x and y coordinates of where to display the effect. They are in STAGE coordinates, not World.
// The next is a Quad making up the rectangular region of the Camera that we'll create the effect from (in this case the whole camera).
// Finally we set the fill color that is put over the top of the mirror effect.
mirror.start(0, 400, new Phaser.Quad(0, 0, 800, 400), 'rgba(0, 0, 100, 0.7)');
// Experiment with variations on these to see the different mirror effects that can be achieved.
//mirror.flipX = true;
//mirror.flipY = true;
myGame.add.sprite(0, 0, 'backdrop');
}
function update() {
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.scroll.x -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.scroll.x += 4;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 4;
}
}
})();
+68
View File
@@ -0,0 +1,68 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
// Just set the world to be the size of the image we're loading in
myGame.world.setSize(1216, 896);
myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png');
myGame.loader.load();
}
var mirror: Phaser.FX.Camera.Mirror;
function create() {
// What we need is a camera 800x400 pixels in size as the mirror effect will be 200px tall and sit below it.
// So we resize our default camera to 400px
myGame.camera.height = 400;
// Because it's our default camera we need to tell it to disable clipping, otherwise we'll never see the mirror effect render.
myGame.camera.disableClipping = true;
// Add our effect to the camera
mirror = <Phaser.FX.Camera.Mirror> myGame.camera.fx.add(Phaser.FX.Camera.Mirror);
// The first 2 parameters are the x and y coordinates of where to display the effect. They are in STAGE coordinates, not World.
// The next is a Quad making up the rectangular region of the Camera that we'll create the effect from (in this case the whole camera).
// Finally we set the fill color that is put over the top of the mirror effect.
mirror.start(0, 400, new Phaser.Quad(0, 0, 800, 400), 'rgba(0, 0, 100, 0.7)');
// Experiment with variations on these to see the different mirror effects that can be achieved.
//mirror.flipX = true;
//mirror.flipY = true;
myGame.add.sprite(0, 0, 'backdrop');
}
function update() {
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.scroll.x -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.scroll.x += 4;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 4;
}
}
})();
+32
View File
@@ -0,0 +1,32 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1216, 896);
myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png');
myGame.loader.load();
}
var scanlines;
function create() {
// Add our effect to the camera
scanlines = myGame.camera.fx.add(Phaser.FX.Camera.Scanlines);
// We'll have the scanlines spaced out every 2 pixels
scanlines.spacing = 2;
// This is the color the lines will be drawn in
scanlines.color = 'rgba(0, 0, 0, 0.8)';
myGame.add.sprite(0, 0, 'backdrop');
}
function update() {
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.scroll.x -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.scroll.x += 4;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 4;
}
}
})();
+57
View File
@@ -0,0 +1,57 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1216, 896);
myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png');
myGame.loader.load();
}
var scanlines: Phaser.FX.Camera.Scanlines;
function create() {
// Add our effect to the camera
scanlines = <Phaser.FX.Camera.Scanlines> myGame.camera.fx.add(Phaser.FX.Camera.Scanlines);
// We'll have the scanlines spaced out every 2 pixels
scanlines.spacing = 2;
// This is the color the lines will be drawn in
scanlines.color = 'rgba(0, 0, 0, 0.8)';
myGame.add.sprite(0, 0, 'backdrop');
}
function update() {
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.scroll.x -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.scroll.x += 4;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 4;
}
}
})();
+50
View File
@@ -0,0 +1,50 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var shake;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
shake = myGame.camera.fx.add(Phaser.FX.Camera.Shake);
myGame.onRenderCallback = render;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Shake the camera when the car hits the edges, a different intensity per edge
if(car.x < 0) {
shake.start();
car.x = 0;
} else if(car.x > myGame.world.width) {
shake.start(0.02);
car.x = myGame.world.width - car.width;
}
if(car.y < 0) {
shake.start(0.07, 1);
car.y = 0;
} else if(car.y > myGame.world.height) {
shake.start(0.1);
car.y = myGame.world.height - car.height;
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
}
})();
+85
View File
@@ -0,0 +1,85 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../build/phaser-fx.d.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('background', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var shake: Phaser.FX.Camera.Shake;
function create() {
myGame.add.sprite(0, 0, 'background');
car = myGame.add.sprite(400, 300, 'car');
// Add our effect to the camera
shake = <Phaser.FX.Camera.Shake> myGame.camera.fx.add(Phaser.FX.Camera.Shake);
myGame.onRenderCallback = render;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
// Shake the camera when the car hits the edges, a different intensity per edge
if (car.x < 0)
{
shake.start();
car.x = 0;
}
else if (car.x > myGame.world.width)
{
shake.start(0.02);
car.x = myGame.world.width - car.width;
}
if (car.y < 0)
{
shake.start(0.07, 1);
car.y = 0;
}
else if (car.y > myGame.world.height)
{
shake.start(0.1);
car.y = myGame.world.height - car.height;
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
}
})();
+38
View File
@@ -0,0 +1,38 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var miniCam;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car, Phaser.Camera.STYLE_TOPDOWN);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(0, 0, 300, 300);
miniCam.follow(car, Phaser.Camera.STYLE_TOPDOWN_TIGHT);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.alpha = 0.7;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
+63
View File
@@ -0,0 +1,63 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var miniCam: Phaser.Camera;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car, Phaser.Camera.STYLE_TOPDOWN);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(0, 0, 300, 300);
miniCam.follow(car, Phaser.Camera.STYLE_TOPDOWN_TIGHT);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.alpha = 0.7;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,33 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1200);
myGame.camera.setBounds(0, 0, 1920, 1200);
myGame.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
function create() {
myGame.add.sprite(0, 0, 'backdrop');
for(var i = 0; i < 100; i++) {
myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'melon');
}
myGame.onRenderCallback = render;
}
function update() {
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.scroll.x -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.scroll.x += 4;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 4;
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
}
})();
@@ -0,0 +1,60 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1200);
myGame.camera.setBounds(0, 0, 1920, 1200);
myGame.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
function create() {
myGame.add.sprite(0, 0, 'backdrop');
for (var i = 0; i < 100; i++)
{
myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'melon');
}
myGame.onRenderCallback = render;
}
function update() {
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.scroll.x -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.scroll.x += 4;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 4;
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
}
})();
@@ -0,0 +1,40 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var cam2;
function create() {
for(var i = 0; i < 1000; i++) {
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
myGame.camera.setPosition(16, 80);
myGame.camera.setSize(320, 320);
myGame.camera.showBorder = true;
myGame.camera.borderColor = 'rgb(255,0,0)';
cam2 = myGame.add.camera(380, 100, 400, 400);
cam2.showBorder = true;
cam2.borderColor = 'rgb(255,255,0)';
}
function update() {
myGame.camera.renderDebugInfo(16, 16);
cam2.renderDebugInfo(200, 16);
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.x -= 4;
cam2.x -= 2;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.x += 4;
cam2.x += 2;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.y -= 4;
cam2.y -= 2;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.y += 4;
cam2.y += 2;
}
}
})();
@@ -0,0 +1,66 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var cam2: Phaser.Camera;
function create() {
for (var i = 0; i < 1000; i++)
{
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
myGame.camera.setPosition(16, 80);
myGame.camera.setSize(320, 320);
myGame.camera.showBorder = true;
myGame.camera.borderColor = 'rgb(255,0,0)';
cam2 = myGame.add.camera(380, 100, 400, 400);
cam2.showBorder = true;
cam2.borderColor = 'rgb(255,255,0)';
}
function update() {
myGame.camera.renderDebugInfo(16, 16);
cam2.renderDebugInfo(200, 16);
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.x -= 4;
cam2.x -= 2;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.x += 4;
cam2.x += 2;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.y -= 4;
cam2.y -= 2;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.y += 4;
cam2.y += 2;
}
}
})();
@@ -0,0 +1,34 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('car', 'assets/sprites/car.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
function create() {
for(var i = 0; i < 1000; i++) {
if(Math.random() > 0.5) {
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'car');
} else {
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
}
myGame.camera.setPosition(100, 100);
myGame.camera.setSize(320, 320);
}
function update() {
myGame.camera.renderDebugInfo(600, 32);
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.rotation -= 2;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.rotation += 2;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 4;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 4;
}
}
})();
@@ -0,0 +1,61 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('car', 'assets/sprites/car.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
function create() {
for (var i = 0; i < 1000; i++)
{
if (Math.random() > 0.5)
{
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'car');
}
else
{
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
}
myGame.camera.setPosition(100, 100);
myGame.camera.setSize(320, 320);
}
function update() {
myGame.camera.renderDebugInfo(600, 32);
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.rotation -= 2;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.rotation += 2;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 4;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 4;
}
}
})();
+45
View File
@@ -0,0 +1,45 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var miniCam;
var bigCam;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(600, 32, 200, 200);
miniCam.follow(car, Phaser.Camera.STYLE_LOCKON);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.scale.setTo(0.5, 0.5);
bigCam = myGame.add.camera(32, 32, 200, 200);
bigCam.follow(car, Phaser.Camera.STYLE_LOCKON);
bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
bigCam.showBorder = true;
bigCam.scale.setTo(2, 2);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
+71
View File
@@ -0,0 +1,71 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var miniCam: Phaser.Camera;
var bigCam: Phaser.Camera;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(600, 32, 200, 200);
miniCam.follow(car, Phaser.Camera.STYLE_LOCKON);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.scale.setTo(0.5, 0.5);
bigCam = myGame.add.camera(32, 32, 200, 200);
bigCam.follow(car, Phaser.Camera.STYLE_LOCKON);
bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
bigCam.showBorder = true;
bigCam.scale.setTo(2, 2);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,47 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var miniCam;
var bigCam;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(600, 32, 200, 200);
miniCam.follow(car, Phaser.Camera.STYLE_LOCKON);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.scale.setTo(0.5, 0.5);
miniCam.showShadow = true;
bigCam = myGame.add.camera(32, 32, 200, 200);
bigCam.follow(car, Phaser.Camera.STYLE_LOCKON);
bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
bigCam.showBorder = true;
bigCam.scale.setTo(2, 2);
bigCam.showShadow = true;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,73 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var miniCam: Phaser.Camera;
var bigCam: Phaser.Camera;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam = myGame.add.camera(600, 32, 200, 200);
miniCam.follow(car, Phaser.Camera.STYLE_LOCKON);
miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
miniCam.showBorder = true;
miniCam.scale.setTo(0.5, 0.5);
miniCam.showShadow = true;
bigCam = myGame.add.camera(32, 32, 200, 200);
bigCam.follow(car, Phaser.Camera.STYLE_LOCKON);
bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
bigCam.showBorder = true;
bigCam.scale.setTo(2, 2);
bigCam.showShadow = true;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,46 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('balls', 'assets/sprites/balls.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
var miniCam;
var bigCam;
function create() {
//myGame.add.sprite('grid', 0, 0);
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.setTexture('balls');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
//miniCam = myGame.add.camera(600, 32, 200, 200);
//miniCam.follow(car, Camera.STYLE_LOCKON);
//miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
//miniCam.showBorder = true;
//miniCam.scale.setTo(0.5, 0.5);
//bigCam = myGame.add.camera(32, 32, 200, 200);
//bigCam.follow(car, Camera.STYLE_LOCKON);
//bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
//bigCam.showBorder = true;
//bigCam.scale.setTo(2, 2);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,72 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('balls', 'assets/sprites/balls.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var miniCam: Phaser.Camera;
var bigCam: Phaser.Camera;
function create() {
//myGame.add.sprite('grid', 0, 0);
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.setTexture('balls');
myGame.camera.follow(car);
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
//miniCam = myGame.add.camera(600, 32, 200, 200);
//miniCam.follow(car, Camera.STYLE_LOCKON);
//miniCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
//miniCam.showBorder = true;
//miniCam.scale.setTo(0.5, 0.5);
//bigCam = myGame.add.camera(32, 32, 200, 200);
//bigCam.follow(car, Camera.STYLE_LOCKON);
//bigCam.setBounds(0, 0, myGame.world.width, myGame.world.height);
//bigCam.showBorder = true;
//bigCam.scale.setTo(2, 2);
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
+36
View File
@@ -0,0 +1,36 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1920);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.addImageFile('carrot', 'assets/sprites/carrot.png');
myGame.loader.load();
}
var melon;
function create() {
// locked to the camera
myGame.add.sprite(0, 0, 'grid');
melon = myGame.add.sprite(600, 650, 'melon');
melon.scrollFactor.setTo(1.5, 1.5);
// scrolls x2 camera speed
for(var i = 0; i < 100; i++) {
var tempSprite = myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'carrot');
tempSprite.scrollFactor.setTo(2, 2);
}
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
melon.renderDebugInfo(200, 32);
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.focusOnXY(640, 640);
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.focusOnXY(1234, 800);
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.focusOnXY(50, 200);
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.focusOnXY(1700, 1700);
}
}
})();
+62
View File
@@ -0,0 +1,62 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1920);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.addImageFile('carrot', 'assets/sprites/carrot.png');
myGame.loader.load();
}
var melon: Phaser.Sprite;
function create() {
// locked to the camera
myGame.add.sprite(0, 0, 'grid');
melon = myGame.add.sprite(600, 650, 'melon');
melon.scrollFactor.setTo(1.5, 1.5);
// scrolls x2 camera speed
for (var i = 0; i < 100; i++)
{
var tempSprite = myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'carrot');
tempSprite.scrollFactor.setTo(2, 2);
}
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
melon.renderDebugInfo(200, 32);
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.focusOnXY(640, 640);
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.focusOnXY(1234, 800);
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.focusOnXY(50, 200);
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.focusOnXY(1700, 1700);
}
}
})();
@@ -0,0 +1,36 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
// Here we'll set our own custom deadzone which is 64px smaller than the stage size on all sides
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,61 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
// Here we'll set our own custom deadzone which is 64px smaller than the stage size on all sides
myGame.camera.deadzone = new Phaser.Rectangle(64, 64, myGame.stage.width - 128, myGame.stage.height - 128);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,34 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1920);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.onRenderCallback = render;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
}
})();
@@ -0,0 +1,62 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1920);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car);
myGame.onRenderCallback = render;
}
function update() {
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 300));
}
}
function render() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
}
})();
@@ -0,0 +1,34 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car, Phaser.Camera.STYLE_TOPDOWN);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
var motion = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
@@ -0,0 +1,59 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(2240, 2240);
myGame.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png');
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
function create() {
myGame.add.sprite(0, 0, 'grid');
car = myGame.add.sprite(400, 300, 'car');
myGame.camera.follow(car, Phaser.Camera.STYLE_TOPDOWN);
myGame.camera.setBounds(0, 0, myGame.world.width, myGame.world.height);
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
car.renderDebugInfo(200, 32);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
car.angularAcceleration = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
var motion:Phaser.Point = myGame.motion.velocityFromAngle(car.angle, 300);
car.velocity.copyFrom(motion);
}
}
})();
+44
View File
@@ -0,0 +1,44 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('car', 'assets/sprites/car.png');
myGame.loader.addImageFile('coin', 'assets/sprites/coin.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var cam2;
function create() {
for(var i = 0; i < 1000; i++) {
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
myGame.camera.setPosition(16, 80);
myGame.camera.setSize(320, 320);
myGame.camera.showBorder = true;
myGame.camera.borderColor = 'rgb(255,0,0)';
cam2 = myGame.add.camera(380, 100, 400, 400);
//cam2.transparent = false;
//cam2.backgroundColor = 'rgb(20,20,20)';
cam2.showBorder = true;
cam2.borderColor = 'rgb(255,255,0)';
}
function update() {
myGame.camera.renderDebugInfo(16, 16);
cam2.renderDebugInfo(200, 16);
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.scroll.x -= 4;
cam2.scroll.x -= 2;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.scroll.x += 4;
cam2.scroll.x += 2;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 4;
cam2.scroll.y -= 2;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 4;
cam2.scroll.y += 2;
}
}
})();
+70
View File
@@ -0,0 +1,70 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(3000, 3000);
myGame.loader.addImageFile('car', 'assets/sprites/car.png');
myGame.loader.addImageFile('coin', 'assets/sprites/coin.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var cam2: Phaser.Camera;
function create() {
for (var i = 0; i < 1000; i++)
{
myGame.add.sprite(Math.random() * 3000, Math.random() * 3000, 'melon');
}
myGame.camera.setPosition(16, 80);
myGame.camera.setSize(320, 320);
myGame.camera.showBorder = true;
myGame.camera.borderColor = 'rgb(255,0,0)';
cam2 = myGame.add.camera(380, 100, 400, 400);
//cam2.transparent = false;
//cam2.backgroundColor = 'rgb(20,20,20)';
cam2.showBorder = true;
cam2.borderColor = 'rgb(255,255,0)';
}
function update() {
myGame.camera.renderDebugInfo(16, 16);
cam2.renderDebugInfo(200, 16);
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.scroll.x -= 4;
cam2.scroll.x -= 2;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.scroll.x += 4;
cam2.scroll.x += 2;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 4;
cam2.scroll.y -= 2;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 4;
cam2.scroll.y += 2;
}
}
})();
@@ -0,0 +1,37 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1200);
myGame.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.addImageFile('carrot', 'assets/sprites/carrot.png');
myGame.loader.load();
}
var melon;
function create() {
// scrolls in time with the camera
myGame.add.sprite(0, 0, 'backdrop');
melon = myGame.add.sprite(600, 650, 'melon');
melon.scrollFactor.setTo(1.5, 1.5);
// scrolls x2 camera speed
for(var i = 0; i < 100; i++) {
var tempSprite = myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'carrot');
tempSprite.scrollFactor.setTo(2, 2);
}
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
melon.renderDebugInfo(200, 32);
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
myGame.camera.scroll.x -= 1;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
myGame.camera.scroll.x += 1;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
myGame.camera.scroll.y -= 1;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
myGame.camera.scroll.y += 1;
}
}
})();
@@ -0,0 +1,63 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.world.setSize(1920, 1200);
myGame.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.addImageFile('carrot', 'assets/sprites/carrot.png');
myGame.loader.load();
}
var melon: Phaser.Sprite;
function create() {
// scrolls in time with the camera
myGame.add.sprite(0, 0, 'backdrop');
melon = myGame.add.sprite(600, 650, 'melon');
melon.scrollFactor.setTo(1.5, 1.5);
// scrolls x2 camera speed
for (var i = 0; i < 100; i++)
{
var tempSprite = myGame.add.sprite(Math.random() * myGame.world.width, Math.random() * myGame.world.height, 'carrot');
tempSprite.scrollFactor.setTo(2, 2);
}
}
function update() {
myGame.camera.renderDebugInfo(32, 32);
melon.renderDebugInfo(200, 32);
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
myGame.camera.scroll.x -= 1;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
myGame.camera.scroll.x += 1;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
myGame.camera.scroll.y -= 1;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
myGame.camera.scroll.y += 1;
}
}
})();
@@ -0,0 +1,35 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var car;
var melon;
function create() {
car = myGame.add.sprite(100, 300, 'car');
melon = myGame.add.sprite(200, 310, 'melon');
car.name = 'car';
melon.name = 'melon';
}
function update() {
car.renderDebugInfo(16, 16);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
car.angularVelocity = -200;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
car.angularVelocity = 200;
}
if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) {
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 200));
}
myGame.collide(car, melon, collides);
}
function collides(a, b) {
console.log('Collision!!!!!');
}
})();
@@ -0,0 +1,61 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('car', 'assets/sprites/car90.png');
myGame.loader.addImageFile('melon', 'assets/sprites/melon.png');
myGame.loader.load();
}
var car: Phaser.Sprite;
var melon: Phaser.Sprite;
function create() {
car = myGame.add.sprite(100, 300, 'car');
melon = myGame.add.sprite(200, 310, 'melon');
car.name = 'car';
melon.name = 'melon';
}
function update() {
car.renderDebugInfo(16, 16);
car.velocity.x = 0;
car.velocity.y = 0;
car.angularVelocity = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.angularVelocity = -200;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.angularVelocity = 200;
}
if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP))
{
car.velocity.copyFrom(myGame.motion.velocityFromAngle(car.angle, 200));
}
myGame.collide(car, melon, collides);
}
function collides(a, b) {
console.log('Collision!!!!!');
}
})();
@@ -0,0 +1,45 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('ball0', 'assets/sprites/yellow_ball.png');
myGame.loader.addImageFile('ball1', 'assets/sprites/aqua_ball.png');
myGame.loader.addImageFile('ball2', 'assets/sprites/blue_ball.png');
myGame.loader.addImageFile('ball3', 'assets/sprites/green_ball.png');
myGame.loader.addImageFile('ball4', 'assets/sprites/red_ball.png');
myGame.loader.addImageFile('ball5', 'assets/sprites/purple_ball.png');
myGame.loader.addImageFile('atari', 'assets/sprites/atari130xe.png');
myGame.loader.load();
}
var atari;
var balls;
function create() {
atari = myGame.add.sprite(300, 450, 'atari');
atari.immovable = true;
balls = myGame.add.group();
for(var i = 0; i < 100; i++) {
var tempBall = new Phaser.Sprite(myGame, Math.random() * myGame.stage.width, -32, 'ball' + Math.round(Math.random() * 5));
tempBall.velocity.y = 100 + Math.random() * 150;
tempBall.elasticity = 0.9;
balls.add(tempBall);
}
}
function update() {
atari.velocity.x = 0;
if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
atari.velocity.x = -400;
} else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
atari.velocity.x = 400;
}
balls.forEach(checkOffScreen, false);
myGame.collide(atari, balls);
}
function checkOffScreen(ball) {
if(ball.y < -32 || ball.y > myGame.stage.height || ball.x < 0 || ball.x > myGame.stage.width) {
ball.x = Math.random() * myGame.stage.width;
ball.y = -32;
ball.velocity.x = 0;
ball.velocity.y = 100 + Math.random() * 150;
}
}
})();
@@ -0,0 +1,72 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('ball0', 'assets/sprites/yellow_ball.png');
myGame.loader.addImageFile('ball1', 'assets/sprites/aqua_ball.png');
myGame.loader.addImageFile('ball2', 'assets/sprites/blue_ball.png');
myGame.loader.addImageFile('ball3', 'assets/sprites/green_ball.png');
myGame.loader.addImageFile('ball4', 'assets/sprites/red_ball.png');
myGame.loader.addImageFile('ball5', 'assets/sprites/purple_ball.png');
myGame.loader.addImageFile('atari', 'assets/sprites/atari130xe.png');
myGame.loader.load();
}
var atari: Phaser.Sprite;
var balls: Phaser.Group;
function create() {
atari = myGame.add.sprite(300, 450, 'atari');
atari.immovable = true;
balls = myGame.add.group();
for (var i = 0; i < 100; i++)
{
var tempBall: Phaser.Sprite = new Phaser.Sprite(myGame, Math.random() * myGame.stage.width, -32, 'ball' + Math.round(Math.random() * 5));
tempBall.velocity.y = 100 + Math.random() * 150;
tempBall.elasticity = 0.9;
balls.add(tempBall);
}
}
function update() {
atari.velocity.x = 0;
if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
atari.velocity.x = -400;
}
else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
atari.velocity.x = 400;
}
balls.forEach(checkOffScreen, false);
myGame.collide(atari, balls);
}
function checkOffScreen(ball:Phaser.Sprite) {
if (ball.y < -32 || ball.y > myGame.stage.height || ball.x < 0 || ball.x > myGame.stage.width)
{
ball.x = Math.random() * myGame.stage.width;
ball.y = -32;
ball.velocity.x = 0;
ball.velocity.y = 100 + Math.random() * 150;
}
}
})();
@@ -0,0 +1,31 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('card', 'assets/sprites/mana_card.png');
myGame.loader.addTextureAtlas('bot', 'assets/sprites/running_bot.png', 'assets/sprites/running_bot.json');
myGame.loader.load();
}
var card;
var bot;
function create() {
card = myGame.add.sprite(200, 220, 'card');
bot = myGame.add.sprite(myGame.stage.width - 100, 300, 'bot');
// The collision mask is much thinner than the animated sprite
bot.collisionMask.offset.x = 16;
bot.collisionMask.width = 32;
bot.renderDebug = true;
bot.animations.add('run');
bot.animations.play('run', 10, true);
bot.velocity.x = -150;
}
function update() {
if(bot.x < -bot.width) {
bot.x = myGame.stage.width;
bot.velocity.x = -150;
card.x = 200;
card.velocity.x = 0;
}
myGame.collide(card, bot);
}
})();
@@ -0,0 +1,50 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update);
function init() {
myGame.loader.addImageFile('card', 'assets/sprites/mana_card.png');
myGame.loader.addTextureAtlas('bot', 'assets/sprites/running_bot.png', 'assets/sprites/running_bot.json');
myGame.loader.load();
}
var card: Phaser.Sprite;
var bot: Phaser.Sprite;
function create() {
card = myGame.add.sprite(200, 220, 'card');
bot = myGame.add.sprite(myGame.stage.width - 100, 300, 'bot');
// The collision mask is much thinner than the animated sprite
bot.collisionMask.offset.x = 16;
bot.collisionMask.width = 32;
bot.renderDebug = true;
bot.animations.add('run');
bot.animations.play('run', 10, true);
bot.velocity.x = -150;
}
function update() {
if (bot.x < -bot.width)
{
bot.x = myGame.stage.width;
bot.velocity.x = -150;
card.x = 200;
card.velocity.x = 0;
}
myGame.collide(card, bot);
}
})();

Some files were not shown because too many files have changed in this diff Show More