Working on a top view RPG game, and I needed to find the closest entity the player was interacting with, taking the entity size into account. I'm sure there is an easier and simpler formula for this, but this works well for calculating the (shortest) distance from an entity's bounding box to another entity's midpoint (in this case, my player). I added this to my entities' base class:
distanceFromBoundingBoxToPoint: function( other )
{
var p = {
x: (other.pos.x + other.size.x/2),
y: (other.pos.y + other.size.y/2)
},
minX = this.pos.x,
maxX = (this.pos.x + this.size.x),
minY = this.pos.y,
maxY = (this.pos.y + this.size.y),
distSquared = 0;
if (p.x > maxX) {
distSquared += (p.x - maxX) * (p.x - maxX);
} else if (p.x < minX) {
distSquared += (minX - p.x) * (minX - p.x);
}
if (p.y > maxY) {
distSquared += (p.y - maxY) * (p.y - maxY);
} else if (p.y < minY) {
distSquared += (minY - p.y) * (minY - p.y);
}
return Math.sqrt(distSquared);
}
Couldn't you just use Entity's .distanceTo function, e.g.,
var d = this.distanceTo(other);
No, because distanceTo() calculates the distance between the midpoints of each entity - for example if an entity is 600px wide and a player is touching the left edge of the entity, distanceTo() would return about 300, instead of (approximately) zero which is what I'm after.
Oh yes I see.
Have you considered injecting this into the Game class instead of Entity class? That way you could have a Game.entityClosestTo(anEntity) function that could be of use in other games too (including one I am doing right now :)
PS: the game has a lion scanning for nearest prey in fleeing herd
Quote from alexandre
Have you considered injecting this into the Game class instead of Entity class? That way you could have a Game.entityClosestTo(anEntity) function that could be of use in other games too (including one I am doing right now :)
PS: the game has a lion scanning for nearest prey in fleeing herd
You could tweak it to accept the two entities as arguments and inject it into the Game class, but to me it's simpler and cleaner to have it as part of an extended entity class - you're going to need to access to both entities anyway, and I prefer:
distance = entity1.distanceFromBoundingBoxToPoint( entity2 )
to
distance = this.distanceFromBoundingBoxToPoint(entity1, entity2)
but feel free to modify to suit your preferences.
This is how I'm implementing this in my game's update method:
// if interacting, find closest engagable entity to player
// note that i have a boolean flag in my entities called 'engagable'...
// In my case I'm only interested in finding the closest "engagable" entity
this.engagingEntity = false;
if( ig.input.state( 'interact' ) ) {
var closestEngagable = false,
closestDist = 0,
dist,
player = this.player;
$.each(this.entities, function( key, entity ) {
if (entity.engagable) {
dist = entity.distanceFromBoundingBoxToPoint( player );
if (!closestEngagable || dist < closestDist) {
closestDist = dist;
closestEngagable = entity;
}
}
});
if (closestDist < this.engagableMaxDist) {
this.engagingEntity = closestEngagable;
}
}
if (this.engagingEntity) {
// do stuff here
}
Page 1 of 1
« first
« previous
next ›
last »