Patched the QuadTree, now working a whole lot better but am worried it's still working out too many collisions.

This commit is contained in:
Richard Davey
2013-09-04 04:54:43 +01:00
parent 3f3b6bfd35
commit b2263c16c6
3 changed files with 84 additions and 26 deletions
+27 -2
View File
@@ -20,15 +20,20 @@
}
var ship;
var total;
var aliens;
function create() {
for (var i = 0; i < 50; i++)
aliens = [];
for (var i = 0; i < 100; i++)
{
var s = game.add.sprite(game.world.randomX, game.world.randomY, 'baddie');
s.body.collideWorldBounds = true;
s.body.bounce.setTo(1, 1);
s.body.velocity.setTo(50 + Math.random() * 50, 50 + Math.random() * 50);
s.body.velocity.setTo(10 + Math.random() * 10, 10 + Math.random() * 10);
aliens.push(s);
}
ship = game.add.sprite(400, 400, 'ship');
@@ -39,6 +44,18 @@
function update() {
for (var i = 0; i < aliens.length; i++)
{
aliens[i].alpha = 0.3;
}
total = game.physics.quadTree.retrieve(ship);
for (var i = 0; i < total.length; i++)
{
total[i].sprite.alpha = 1;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
ship.body.velocity.x -= 2;
@@ -61,6 +78,14 @@
function render() {
for (var i = 0; i < aliens.length; i++)
{
game.debug.renderRectangle(aliens[i].bounds);
}
game.debug.renderText(total.length, 32, 32);
game.debug.renderQuadTree(game.physics.quadTree);
game.debug.renderRectangle(ship);
}
+32 -24
View File
@@ -44,14 +44,14 @@ Phaser.QuadTree = function (x, y, width, height, maxObjects, maxLevels, level) {
this.level = level || 0;
this.bounds = {
x: x,
y: y,
x: Math.round(x),
y: Math.round(y),
width: width,
height: height,
subWidth: Math.floor(width / 2 ),
subHeight: Math.floor(height / 2 ),
right: x + Math.floor(width / 2 ),
bottom: y + Math.floor(height / 2 )
subWidth: Math.floor(width / 2),
subHeight: Math.floor(height / 2),
right: Math.round(x) + Math.floor(width / 2),
bottom: Math.round(y) + Math.floor(height / 2)
};
this.objects = [];
@@ -65,18 +65,20 @@ Phaser.QuadTree.prototype = {
* Split the node into 4 subnodes
*/
split: function() {
this.level + 1;
// top right node
this.nodes[0] = new Phaser.QuadTree(this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level + 1);
this.nodes[0] = new Phaser.QuadTree(this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
// top left node
this.nodes[1] = new Phaser.QuadTree(this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level + 1);
this.nodes[1] = new Phaser.QuadTree(this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
// bottom left node
this.nodes[2] = new Phaser.QuadTree(this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level + 1);
this.nodes[2] = new Phaser.QuadTree(this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
// bottom right node
this.nodes[3] = new Phaser.QuadTree(this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level + 1);
this.nodes[3] = new Phaser.QuadTree(this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
},
@@ -89,30 +91,36 @@ Phaser.QuadTree.prototype = {
var index = -1;
// Duplicated comparisons, but they only get checked once in the flow so it saves creating temp. vars
// var verticalMidpoint = this.bounds.x + (this.bounds.width / 2);
var verticalMidpoint = this.bounds.right;
// var horizontalMidpoint = this.bounds.y + (this.bounds.height / 2);
var horizontalMidpoint = this.bounds.bottom;
var topQuadrant = (rect.y < this.bounds.bottom && rect.bottom < this.bounds.bottom);
var bottomQuadrant = (rect.y > this.bounds.bottom);
// rect can completely fit within the left quadrants
if (rect.x < this.bounds.bottom && rect.right < this.bounds.bottom)
if (rect.x < verticalMidpoint && rect.right < verticalMidpoint)
{
if ((rect.y < this.bounds.right && rect.bottom < this.bounds.right))
if (topQuadrant)
{
// rect can completely fit within the top quadrants
index = 1;
}
else if ((rect.y > this.bounds.right))
else if (bottomQuadrant)
{
// rect can completely fit within the bottom quadrants
index = 2;
}
}
else if (rect.x > this.bounds.bottom)
else if (rect.x > verticalMidpoint)
{
// rect can completely fit within the right quadrants
if ((rect.y < this.bounds.right && rect.bottom < this.bounds.right))
if (topQuadrant)
{
index = 0;
}
else if ((rect.y > this.bounds.right))
else if (bottomQuadrant)
{
index = 3;
}
@@ -135,7 +143,7 @@ Phaser.QuadTree.prototype = {
// if we have subnodes ...
// if (typeof this.nodes[0] !== 'undefined')
if (this.nodes[0])
if (this.nodes[0] != null)
{
index = this.getIndex(body.bounds);
@@ -152,7 +160,7 @@ Phaser.QuadTree.prototype = {
{
// Split if we don't already have subnodes
// if (typeof this.nodes[0] === 'undefined')
if (!this.nodes[0])
if (this.nodes[0] == null)
{
this.split();
}
@@ -180,9 +188,9 @@ Phaser.QuadTree.prototype = {
* @param Object pRect bounds of the object to be checked, with x, y, width, height
* @Return Array array with all detected objects
*/
retrieve: function (rect) {
retrieve: function (sprite) {
var index = this.getIndex(rect);
var index = this.getIndex(sprite.body.bounds);
var returnObjects = this.objects;
// if we have subnodes ...
@@ -192,14 +200,14 @@ Phaser.QuadTree.prototype = {
// if rect fits into a subnode ..
if (index !== -1)
{
returnObjects = returnObjects.concat(this.nodes[index].retrieve(rect));
returnObjects = returnObjects.concat(this.nodes[index].retrieve(sprite));
}
else
{
// if rect does not fit into a subnode, check it against all subnodes
for (var i = 0, len = this.nodes.length; i < len; i++)
{
returnObjects = returnObjects.concat(this.nodes[i].retrieve(rect));
returnObjects = returnObjects.concat(this.nodes[i].retrieve(sprite));
}
}
}
+25
View File
@@ -105,6 +105,31 @@ Phaser.Utils.Debug.prototype = {
},
renderQuadTree: function (quadtree, color) {
color = color || 'rgba(255,0,0,0.3)';
this.start();
var bounds = quadtree.bounds;
if (quadtree.nodes.length === 0)
{
this.context.strokeStyle = color;
this.context.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
else
{
for (var i = 0; i < quadtree.nodes.length; i++)
{
this.renderQuadTree(quadtree.nodes[i]);
}
}
this.stop();
},
renderSpriteCorners: function (sprite, showText, showBounds, color) {
if (this.context == null)