Measuring Distance Between Objects: Lessons From a Tower Defence Game

Measuring the distance between two points sounds simple enough, doesn’t it? But how do you make it work in a browser? In this article, I dive into the details of my journey measuring a distance using JavaScript for a tower defence game and all I learnt…


This content originally appeared on Level Up Coding - Medium and was authored by Vlad Ogir

Measuring the distance between two points sounds simple enough, doesn’t it? But how do you make it work in a browser? In this article, I dive into the details of my journey measuring a distance using JavaScript for a tower defence game and all I learnt along the way.

I will cover:
- Measuring the distance between two points
- Retrieving the position of objects in the DOM
- Impact of object sizes in the DOM on distance
- Implementing a function to measure the distance between an enemy and a tower
- Share codepen with the whole code!

This is part of a larger series of articles where I create a tower defence game using JavaScript/TypeScript.

Learn Software Engineering by Building a Tower Defence Game

Problem

As part of the game, we need to know if an enemy is within the tower’s shooting range. But which enemy is within tower’s distance?

Which enemy is within tower’s range?

Measuring the distance between two points

This is where distance measurement comes in. To measure distance, we will use the Euclidean distance formula:

function computeDistanceBetweenPoints(point1: IPoint, point2: IPoint): number {
const row1 = point1["row"]
const col1 = point1["col"]

const row2 = point2["row"]
const col2 = point2["col"]
return Math.sqrt((row2 - row1) ** 2 + (col2 - col1) ** 2)
}
In mathematics, the Euclidean distance between two points in Euclidean space is the length of the line segment between them.

You can learn more about Euclidean distance on the wiki or play with it using this superb distance calculator.

How to get the position of an object in the DOM

In JavaScript, you can get the current position of any element in DOM using getBoundingClientRect. This method returns “the size of an element and its position relative to the viewport.”. The output of this function will be used to get the size and position of an element.

Those are the attributes that the method returns. (Taken from https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect.)

You can learn more about this method at the link below:

Element: getBoundingClientRect() method - Web APIs | MDN

Map Grid needs to be pixel-perfect

In my case, a grid is a table that is a reflection of a multi-dimensional array. You can learn more about this at the link below:

Demystifying Tower Defence Game Architecture: A Practical Guide

It may sound obvious, but it’s easy to get caught out: any borderlines, padding, etc., impact the dimension of cells. This has a knock-on effect on the tower ranges, which need to be adjusted. Otherwise, enemies will be out of the tower’s range.

It’s best to avoid any padding or consider it as the size of a cell.

Border and padding resulted in enemies being out of range

The Centre of a tower is of the most importance

When it comes to the tower we will be computing range starting from the centre point. The tower range is a circle around the centre point. This way tower can be of any shape.

An enemy is more than just a point

Unlike a tower, an enemy is more than just a point. It’s a shape. Any of the corners or sides might be within the tower’s range. For that reason, I opted to think of an enemy as a square or a rectangle.

We have four possible points in a square

Distance needs to be measured between the source and each point in a square since any of the corners might be within range.

Using getBoundingClientRect, we can find the top left and bottom right corners. The other two can be worked out manually.

Below is an example code for how all corners can be computed:

function computeCorners(points: IPoint[]): IPoint[] {
const top_left = points[0]
const bottom_right = points[1]

return [
{ // existing top left
row: top_left["row"],
col: top_left["col"]
},
{ // existing bottom right
row: bottom_right["row"],
col: bottom_right["col"]
},
{ // computed bottom left
row: bottom_right["row"],
col: top_left["col"]
},
{ // computed top right
row: top_left["row"],
col: bottom_right["col"]
},
]
}

Find the closest point

For the formula, we only need one point in a square. Therefore, I opted to use the closest point to the tower.

The code below implements that:

function findClosestDistance(circle: IPoint, rectangle: IPoint[]): number {
const points = computeCorners(rectangle)
let result = Infinity

for (const point of points) {
result = Math.min(result, computeDistanceBetweenPoints(circle, point))
}
return result
}

In the example above, we compute all the corners and select the closest point.

Compare with the distance

Now that we have everything in place, it’s a matter of checking if the closest distance is within our range

function isEnemyWithinRange(tower: ITower, enemy: IEnemy): bool {
const client_react = enemy.dom.getBoundingClientRect()
const enemy_coords = [
{
"row": client_react.top,
"col": client_react.left
},
{
"row": client_react.bottom,
"col": client_react.right
}
]

const closest_distance = findClosestDistance(tower.position, enemy_coords)

return closest_distance <= tower.range
}

Measuring distance is easier said than done

That is it! We now have a function to tell a distance between a tower and an enemy. Using this function we can tell if an enemy is within tower’s reach!

You can see distance measuring in action below:

In the next article I will cover how to turn an Event Model a Tower into an implementation. This will pave the way to improving performance of the battle function.

Until then, give distance measurement a go and share your thoughts!


Measuring Distance Between Objects: Lessons From a Tower Defence Game was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Vlad Ogir


Print Share Comment Cite Upload Translate Updates
APA

Vlad Ogir | Sciencx (2025-01-15T16:50:03+00:00) Measuring Distance Between Objects: Lessons From a Tower Defence Game. Retrieved from https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/

MLA
" » Measuring Distance Between Objects: Lessons From a Tower Defence Game." Vlad Ogir | Sciencx - Wednesday January 15, 2025, https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/
HARVARD
Vlad Ogir | Sciencx Wednesday January 15, 2025 » Measuring Distance Between Objects: Lessons From a Tower Defence Game., viewed ,<https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/>
VANCOUVER
Vlad Ogir | Sciencx - » Measuring Distance Between Objects: Lessons From a Tower Defence Game. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/
CHICAGO
" » Measuring Distance Between Objects: Lessons From a Tower Defence Game." Vlad Ogir | Sciencx - Accessed . https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/
IEEE
" » Measuring Distance Between Objects: Lessons From a Tower Defence Game." Vlad Ogir | Sciencx [Online]. Available: https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/. [Accessed: ]
rf:citation
» Measuring Distance Between Objects: Lessons From a Tower Defence Game | Vlad Ogir | Sciencx | https://www.scien.cx/2025/01/15/measuring-distance-between-objects-lessons-from-a-tower-defence-game/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.