mirror of
https://github.com/wassname/phaser.git
synced 2026-07-17 11:31:30 +08:00
Camera culling
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>phaser.js - a new beginning</title>
|
||||
<?php
|
||||
require('js.php');
|
||||
?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
(function () {
|
||||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
game.load.image('mushroom', 'assets/sprites/mushroom2.png');
|
||||
}
|
||||
|
||||
var s;
|
||||
|
||||
function create() {
|
||||
|
||||
// Make our game world 2000x2000 pixels in size (the default is to match the game size)
|
||||
game.world.setSize(2000, 2000);
|
||||
|
||||
s = game.add.sprite(800, 400, 'mushroom');
|
||||
// s.scrollFactor.setTo(0.5, 0.5);
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
// s.rotation += 0.01;
|
||||
|
||||
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
|
||||
{
|
||||
game.camera.x -= 4;
|
||||
}
|
||||
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
|
||||
{
|
||||
game.camera.x += 4;
|
||||
}
|
||||
|
||||
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
|
||||
{
|
||||
game.camera.y -= 4;
|
||||
}
|
||||
else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
|
||||
{
|
||||
game.camera.y += 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderRectangle(game.world.camera.view, 'rgba(200,0,0,0.2)');
|
||||
game.debug.renderRectangle(s.bounds);
|
||||
|
||||
game.debug.renderSpriteInfo(s, 32, 32);
|
||||
game.debug.renderCameraInfo(game.world.camera, 32, 200);
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,7 +15,6 @@
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
var s;
|
||||
var r;
|
||||
|
||||
function preload() {
|
||||
game.load.image('test', 'assets/sprites/mana_card.png');
|
||||
@@ -26,20 +25,17 @@
|
||||
s = game.add.sprite(game.world.centerX, game.world.centerY, 'test');
|
||||
s.anchor.setTo(0.5, 0.5);
|
||||
|
||||
r = s.getBounds(r);
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
s.angle += 1;
|
||||
s.getBounds(r);
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderRectangle(r);
|
||||
game.debug.renderRectangle(s.bounds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -14,7 +14,9 @@ Phaser.Camera = function (game, id, x, y, width, height) {
|
||||
// The view into the world we wish to render (by default the game dimensions)
|
||||
// The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render
|
||||
// Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?)
|
||||
this.view = new Phaser.Rectangle(x, y, width, height);
|
||||
this.view = new Phaser.Rectangle(x, y, width, height);
|
||||
this.screenView = new Phaser.Rectangle(x, y, width, height);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -116,6 +118,8 @@ Phaser.Camera.prototype = {
|
||||
|
||||
// this.plugins.preUpdate();
|
||||
|
||||
// Add dirty flag
|
||||
|
||||
if (this.target !== null)
|
||||
{
|
||||
if (this.deadzone == null)
|
||||
|
||||
+5
-5
@@ -59,11 +59,11 @@ Phaser.World.prototype = {
|
||||
|
||||
do
|
||||
{
|
||||
if (!displayObject.visible)
|
||||
{
|
||||
displayObject = displayObject.last._iNext;
|
||||
continue;
|
||||
}
|
||||
// if (!displayObject.active)
|
||||
// {
|
||||
// displayObject = displayObject.last._iNext;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (displayObject['update'])
|
||||
{
|
||||
|
||||
+58
-43
@@ -104,18 +104,15 @@ Phaser.Sprite = function (game, x, y, key, frame) {
|
||||
|
||||
this.scrollFactor = new Phaser.Point(1, 1);
|
||||
|
||||
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
|
||||
// this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
|
||||
|
||||
// Edge points
|
||||
this.offset = new Phaser.Point();
|
||||
this.center = new Phaser.Point();
|
||||
this.topLeft = new Phaser.Point();
|
||||
this.topRight = new Phaser.Point();
|
||||
this.bottomRight = new Phaser.Point();
|
||||
this.bottomLeft = new Phaser.Point();
|
||||
|
||||
// Do we need all 4 edge points? It might be better to just calculate the center and apply the circle for a bounds check
|
||||
this.getLocalPosition(this.center, this.offset.x + this.width / 2, this.offset.y + this.height / 2);
|
||||
this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y);
|
||||
this.getLocalPosition(this.topRight, this.offset.x + this.width, this.offset.y);
|
||||
this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this.height);
|
||||
@@ -133,6 +130,10 @@ Phaser.Sprite = function (game, x, y, key, frame) {
|
||||
this._a11 = 0;
|
||||
this._a12 = 0;
|
||||
this._id = 0;
|
||||
this._left = null;
|
||||
this._right = null;
|
||||
this._top = null;
|
||||
this._bottom = null;
|
||||
|
||||
// The actual scale X value based on the worldTransform
|
||||
this._sx = 0;
|
||||
@@ -157,74 +158,90 @@ Phaser.Sprite.prototype.update = function() {
|
||||
|
||||
this.animations.update();
|
||||
|
||||
this.worldView.setTo(this._x, this._y, this.width, this.height);
|
||||
|
||||
this.position.x = this._x - (this.game.world.camera.x * this.scrollFactor.x);
|
||||
this.position.y = this._y - (this.game.world.camera.y * this.scrollFactor.y);
|
||||
|
||||
// |a c tx|
|
||||
// |b d ty|
|
||||
// |0 0 1|
|
||||
|
||||
this.position.x = this._x - (this.game.world.camera.x * this.scrollFactor.x);
|
||||
this.position.y = this._y - (this.game.world.camera.y * this.scrollFactor.y);
|
||||
|
||||
|
||||
// Cache our transform values
|
||||
if (this.worldTransform[0] != this._a00 || this.worldTransform[1] != this._a01)
|
||||
{
|
||||
// if (this.worldTransform[0] != this._a00 || this.worldTransform[1] != this._a01)
|
||||
// {
|
||||
this._a00 = this.worldTransform[0]; // scaleX a
|
||||
this._a01 = this.worldTransform[1]; // skewY c
|
||||
this._sx = Math.sqrt((this._a00 * this._a00) + (this._a01 * this._a01));
|
||||
this._a01 *= -1;
|
||||
this._dirty = true;
|
||||
}
|
||||
// }
|
||||
|
||||
if (this.worldTransform[3] != this._a10 || this.worldTransform[4] != this._a11)
|
||||
{
|
||||
// if (this.worldTransform[3] != this._a10 || this.worldTransform[4] != this._a11)
|
||||
// {
|
||||
this._a10 = this.worldTransform[3]; // skewX b
|
||||
this._a11 = this.worldTransform[4]; // scaleY d
|
||||
this._sy = Math.sqrt((this._a10 * this._a10) + (this._a11 * this._a11));
|
||||
this._a10 *= -1;
|
||||
this._dirty = true;
|
||||
}
|
||||
// }
|
||||
|
||||
if (this.worldTransform[2] != this._a02 || this.worldTransform[5] != this._a12)
|
||||
{
|
||||
// if (this.worldTransform[2] != this._a02 || this.worldTransform[5] != this._a12)
|
||||
// {
|
||||
this._a02 = this.worldTransform[2]; // translateX tx
|
||||
this._a12 = this.worldTransform[5]; // translateY ty
|
||||
this._dirty = true;
|
||||
}
|
||||
// this._a02 -= (this.game.world.camera.x * this.scrollFactor.x);
|
||||
// this._a12 -= (this.game.world.camera.y * this.scrollFactor.y);
|
||||
// this._dirty = true;
|
||||
// }
|
||||
|
||||
// If the frame has changed we ought to set _dirty
|
||||
this._sw = this.texture.frame.width * this._sx;
|
||||
this._sh = this.texture.frame.height * this._sy;
|
||||
|
||||
if (this._dirty)
|
||||
{
|
||||
//if (this._dirty)
|
||||
//{
|
||||
this._id = 1 / (this._a00 * this._a11 + this._a01 * -this._a10);
|
||||
|
||||
// Update the edge points
|
||||
this.offset.setTo(this._a02 - (this.anchor.x * this._sw), this._a12 - (this.anchor.y * this._sh));
|
||||
|
||||
// Do we need all 4 edge points? It might be better to just calculate the center and apply the circle for a bounds check
|
||||
this.getLocalPosition(this.center, this.offset.x + this.width / 2, this.offset.y + this.height / 2);
|
||||
this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y);
|
||||
this.getLocalPosition(this.topRight, this.offset.x + this._sw, this.offset.y);
|
||||
this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this._sh);
|
||||
this.getLocalPosition(this.bottomRight, this.offset.x + this._sw, this.offset.y + this._sh);
|
||||
|
||||
// Update our bounds
|
||||
this.getBounds(this.bounds);
|
||||
}
|
||||
this.updateBounds();
|
||||
|
||||
this.visible = this.inCamera(this.game.world.camera.screenView);
|
||||
//}
|
||||
|
||||
// Check our bounds
|
||||
|
||||
}
|
||||
|
||||
Phaser.Sprite.prototype.updateBounds = function() {
|
||||
|
||||
// Update the edge points
|
||||
this.offset.setTo(this._a02 - (this.anchor.x * this._sw), this._a12 - (this.anchor.y * this._sh));
|
||||
|
||||
this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y);
|
||||
this.getLocalPosition(this.topRight, this.offset.x + this._sw, this.offset.y);
|
||||
this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this._sh);
|
||||
this.getLocalPosition(this.bottomRight, this.offset.x + this._sw, this.offset.y + this._sh);
|
||||
|
||||
this._left = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
this._right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
this._top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
this._bottom = Phaser.Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
|
||||
this.bounds.setTo(this._left, this._top, this._right - this._left, this._bottom - this._top);
|
||||
|
||||
}
|
||||
|
||||
Phaser.Sprite.prototype.inCamera = function(cameraRect) {
|
||||
|
||||
return Phaser.Rectangle.intersects(cameraRect, this.bounds, 0);
|
||||
|
||||
}
|
||||
|
||||
Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
|
||||
|
||||
p.x = ((this._a11 * this._id * x + -this._a01 * this._id * y + (this._a12 * this._a01 - this._a02 * this._a11) * this._id) * this._sx) + this._a02;
|
||||
p.y = ((this._a00 * this._id * y + -this._a10 * this._id * x + (-this._a12 * this._a00 + this._a02 * this._a10) * this._id) * this._sy) + this._a12;
|
||||
|
||||
// At this point could be working out the smallest / largest value for the bounds check
|
||||
|
||||
return p;
|
||||
|
||||
}
|
||||
@@ -233,17 +250,15 @@ Phaser.Sprite.prototype.getBounds = function(rect) {
|
||||
|
||||
rect = rect || new Phaser.Rectangle;
|
||||
|
||||
var left = Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
var right = Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
var top = Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
var bottom = Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
var left = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
var right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
|
||||
var top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
var bottom = Phaser.Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
|
||||
|
||||
rect.x = left;
|
||||
rect.y = top;
|
||||
rect.width = right - left;
|
||||
rect.height = bottom - top;
|
||||
|
||||
// This could work to include the children by running through the linked list and storing only the highest min.max values
|
||||
|
||||
return rect;
|
||||
|
||||
@@ -268,7 +283,7 @@ Object.defineProperty(Phaser.Sprite.prototype, 'x', {
|
||||
},
|
||||
|
||||
set: function(value) {
|
||||
this.worldView.x = value;
|
||||
// this.worldView.x = value;
|
||||
this._x = value;
|
||||
}
|
||||
|
||||
@@ -281,7 +296,7 @@ Object.defineProperty(Phaser.Sprite.prototype, 'y', {
|
||||
},
|
||||
|
||||
set: function(value) {
|
||||
this.worldView.y = value;
|
||||
// this.worldView.y = value;
|
||||
this._y = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -663,7 +663,7 @@ Phaser.Rectangle.intersection = function (a, b, out) {
|
||||
*/
|
||||
Phaser.Rectangle.intersects = function (a, b, tolerance) {
|
||||
|
||||
if (typeof tolerance === "undefined") { tolerance = 0; }
|
||||
tolerance = tolerance || 0;
|
||||
|
||||
return !(a.left > b.right + tolerance || a.right < b.left - tolerance || a.top > b.bottom + tolerance || a.bottom < b.top - tolerance);
|
||||
|
||||
|
||||
@@ -428,6 +428,44 @@ Phaser.Math = {
|
||||
return true;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Significantly faster version of Math.max
|
||||
* See http://jsperf.com/math-s-min-max-vs-homemade/5
|
||||
*
|
||||
* @return The highest value from those given.
|
||||
*/
|
||||
max: function () {
|
||||
|
||||
for (var i = 1, max = 0, len = arguments.length; i < len; i++)
|
||||
{
|
||||
if (arguments[max] < arguments[i]) {
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
|
||||
return arguments[max];
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Significantly faster version of Math.min
|
||||
* See http://jsperf.com/math-s-min-max-vs-homemade/5
|
||||
*
|
||||
* @return The lowest value from those given.
|
||||
*/
|
||||
min: function () {
|
||||
|
||||
for (var i =1 , min = 0, len = arguments.length; i < len; i++)
|
||||
{
|
||||
if (arguments[i] < arguments[min]){
|
||||
min = i;
|
||||
}
|
||||
}
|
||||
|
||||
return arguments[min];
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
+8
-10
@@ -273,6 +273,7 @@ Phaser.Utils.Debug.prototype = {
|
||||
|
||||
this.line('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') anchor: ' + sprite.anchor.x + ' x ' + sprite.anchor.y);
|
||||
this.line('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1));
|
||||
this.line('rendering: ' + sprite.visible);
|
||||
// this.line('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right);
|
||||
// this.line('sx: ' + sprite.scale.x.toFixed(1) + ' sy: ' + sprite.scale.y.toFixed(1));
|
||||
|
||||
@@ -284,17 +285,14 @@ Phaser.Utils.Debug.prototype = {
|
||||
// 5 = translateY
|
||||
|
||||
|
||||
this.line('id: ' + sprite._id);
|
||||
this.line('scale x: ' + sprite.worldTransform[0]);
|
||||
this.line('scale y: ' + sprite.worldTransform[4]);
|
||||
this.line('tx: ' + sprite.worldTransform[2]);
|
||||
this.line('ty: ' + sprite.worldTransform[5]);
|
||||
this.line('skew x: ' + sprite.worldTransform[3]);
|
||||
this.line('skew y: ' + sprite.worldTransform[1]);
|
||||
// this.line('id: ' + sprite._id);
|
||||
// this.line('scale x: ' + sprite.worldTransform[0]);
|
||||
// this.line('scale y: ' + sprite.worldTransform[4]);
|
||||
// this.line('tx: ' + sprite.worldTransform[2]);
|
||||
// this.line('ty: ' + sprite.worldTransform[5]);
|
||||
// this.line('skew x: ' + sprite.worldTransform[3]);
|
||||
// this.line('skew y: ' + sprite.worldTransform[1]);
|
||||
|
||||
// this.line('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1));
|
||||
// this.line('center x: ' + sprite.transform.center.x + ' y: ' + sprite.transform.center.y);
|
||||
// this.line('cameraView x: ' + sprite.cameraView.x + ' y: ' + sprite.cameraView.y + ' width: ' + sprite.cameraView.width + ' height: ' + sprite.cameraView.height);
|
||||
// this.line('inCamera: ' + this.game.renderer.spriteRenderer.inCamera(this.game.camera, sprite));
|
||||
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user