问题
I have an area where the enemy needs to be spawned to look good (they are behind a fence) and I don't want the enemies to spawn over each other so I was wondering if there is any good way to do this?
http://sv.tinypic.com/r/2zowwu1/8
I created a function that check if the next box (the next enemy) fits in all possible positions (pixel by pixel) but this is to slow as it is a mobile application and the enemies can be spawned rather fast sometimes. Sure there must be a nice formula that can calculate the different boundaries where the next enemy can fit?
回答1:
There are several good solutions.
Fast and easy. You can check only boundaries. You have a 2 points for each square enemy. You can easily test, if two rectangles are intersecting, and, if you sort your x coordinates, you can check gap's between them. If gap is more, than next enemy width - check y gaps, and then spawn it there.
Here you have x1_1 == 25, x1_2 == 29, and x2_1 = 10, x2_2 = 15 x1_1 is left x coord of enemy 1, x2_2 - rightmost x coord of enemy 2 after some sorting you will have a gap between x2_1 and x1_2 equal to 25-15==10 so, you can fit someone here =)
Divide your spawn location to regular grid, mark as occupied, all cells within enemy bounds. Check not pixels, but cells to find a place to spawn.
|-----|-----|-----| | 1 +-|-2-+ | 3 | // 1,2,4,5 was ocupied. Very simple check. | | | | | | // You will have to update that info sometimes. |---|-|---+-|-----| | 4 +---5-+ | 6 | | | | | |-----|-----|-----|
If spawn point is big, consider quadtree, to divide it into segments abd then check 'em to find place that fits.
回答2:
If each enemy occupies a surface E, and your area has surface S, then E/S is the fraction of your area occupied by one enemy. Presumably you have E/S very small, otherwise you'll have a hard time putting in many enemies without overlapping. So if E/S is small, and you have N enemies, and n*E/S is still somewhat small (like 1/10th), then you have good chances of being able to randomly select a position, then go over your list of enemies and check whether your new enemy x is within radius R of any other enemy. If not, try new random position. If your list of enemies is ordered according to their x coordinate, then that part will be fast, you'll save half the list on average. Use a second table for sorting along y. As is usually the case, performance comes at the cost of memory (when it is based on amount of information available, as is case here). So:
- keep track of enemies you create, by putting them in two tables: one table sorted according to x, another table sorted according to y
- select where to spawn next enemy: x, y
- find in table 1 the two enemies that bound x: is new enemy closer than R (enemy size) to either of them (sqrt((x-xi)^2+(y-yi)^2) where xi,yi is enemy from table)? Check any other conditions required.
- if fail test, select new x, y and repeat from step 4
- if pass, save index where new enemy will be inserted, and repeat above test for y, using y table:
- find in table 2 the two enemies that bound y: is new enemy closer than R (enemy size) to either of them (sqrt((x-xi)^2+(y-yi)^2) where xi,yi is enemy from table)?
- if fail test, select new y and repeat from step 6 if only select new y
- if pass, save index where new enemy will be inserted
- insert new enemy at saved index 1 in table 1 and saved index 2 in table 2
来源:https://stackoverflow.com/questions/21857322/finding-free-space-in-square-to-spawn-enemy