HTML5 canvas: mouse and polygon collision detection

So, I am making a tower defense game with HTML5 and Javascript. My only problem is detecting when the mouse makes contact with a hacker Trojan, which is necessary in order to stop the player from creating towers on the way. The path of the attackers is defined in the MAP.js file (see the link below) by a two-dimensional array (an array containing pairs of x and y), so I need to work with a number of points that make up the path when connecting. I just want to prevent the player from placing towers inside, say, 50 pixels of the path. Honestly, I'm just terrible at collision detection, so help will be greatly appreciated.

Here is the link to the whole code: http://shapeshifting.comuv.com/Tower_Defense/td/

As you can imagine, only .js files are applicable, but most of the corresponding code is inside the objects.js file. (PLease justifies the mess)

+7
javascript html5 canvas collision-detection
source share
3 answers

Collision detection is one of those old, hidden game coding issues. Usually, people take the dark penguin approach to preliminary costing in some way, where it is and is not available on your static map. The next step is to create a way to determine the most effective collision map.

You don’t want your game to do a ton of math in response to the user moving their mouse β€” it should be short and fast β€” so pre-computing to something fast is crucial.

If your map is a grid, then you have your answer right there - the collision map is a precalculated 2D array - basically a very small black and white image with a pixel for each place in the grid. White pixels (1) are places, and black pixels (0) are not. You just use this true / false 2D array to search. If you want to save memory, you can link each strip of 32 spaces in the grid into one bit.

If your map is not a grid, you still want to calculate things in advance, but the strategy is a bit more complicated. The first possibility is to do the math, such as Hitesh, to create a higher resolution collision map, and then the rest will be exactly the same as the grid strategy - for example, if each 4x4 pixel block was one collision , then can a tower be placed a test on whether its coordinates will be checked for a sufficient number of 1 - you may need 100% of the tests - 1, or you can let them get a little closer, and let them say that 75% of the tests are 1.

If this is not enough, you can perform these more complex polygon tests, but you want them to be as simple as possible. If you don’t use a pre-calculated grid, the simplest 2D collision analysis - 2 circles - you simply calculate the distance between their centers and check if it is greater or less than the sum of their radii. If you pre-calculate your monster path in a circle of circles, the next step is to split these circles into ... guess what ... the grid. This does not allow each check to check every circle on the map. This allows you to have a large number of these circles on the collision map, since the collision test is to first search for what elements of the grid are currently in the tower, and then check if it collides with the nearest surroundings, and not the entire map. It is important to note that this pre-calculated grid of circle lists will often have the same circle in a set of neighboring grid entries, because each grid entry containing any part of a given circle must have this circle in the master checklist.

One of the nice things about the first two approaches to the grid is that it is very simple for QA - it literally saves the collision map as an image and visually check it to make sure that it looks right for the map on which it is based. You can also do this manually if you do not want to write code to create them.

The circular approach gives you legitimate curves and can lead to the smallest details of a collision, but it is obviously harder to check and ensure there are no cards with bad cards. It is also more work to write a map generation tool.

Good luck

+3
source share

I would do it step by step. Let's see where you start. You have a path defined by points β€” pairs of points define a line segment. So you really have a path out of line segments. When the user moves the mouse, you will get the x, y coordinates of the current position. What you want to do is find the distance from the mouse point to all segments of the line. If it is less than 50 pixels from any segment of the line, then you do not want to allow them to be built there.

To find the distance between a point and a line segment, the pseudo-code is as follows. Suppose that points A and B represent both ends of a line segment, and point C represents a mouse point.

float distancePoint2LineSegment(Point a, Point b, Point c) { Vector ab = b - a Vector ac = c - a Vector bc = c - b float e = dotProduct(ac, ab) if (e <= 0.0) return sqrt(dotProduct(ac, ac)) float f = dotProduct(ab, ab) if (e >= f) return sqrt(dotProduct(bc, bc)) return sqrt(dotProduct(ac, ac) - e * e / f) } 

This will answer your question about collision detection, but I think you would like to look at performance. How many line segments will be on your way and you want to calculate the distance to each line segment every time the user moves his mouse? You can place line segments in quadrants so that you have to test mouse point collisions with fewer line segments.

+2
source share

It’s probably easier and faster to identify areas in which the user can place towers in a design in a map file ... Define each area as a convex polygon (possibly including edges of the map, broken concave polygons that prefer horizontal or vertical lines, then the mouse test is in one of the polygons, see this answer for implementation

How to check if a point is inside a convex polygon in two-dimensional integer coordinates?

Triangulation makes testing even easier

+2
source share

All Articles