Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by monkeyArms

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);
}

1 decade ago by alexandre

Couldn't you just use Entity's .distanceTo function, e.g.,

var d = this.distanceTo(other);

1 decade ago by monkeyArms

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.

1 decade ago by alexandre

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

1 decade ago by monkeyArms

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 »