Cohesion
Blitz3D Forums/Blitz3D Beginners Area/Cohesion
| ||
Hi! New to programming so if this is really obvious I appologise. Does anyone have a good routine for checking if characters on a board game are all within a certain distance of each other, say 40 pixels max? I might have upto 20 characters and they all need to be within 40 pixels of each other, but in any random location. Or maybe another way to think of it is a flock of pigeons on the ground, all randomly spaced but needing to be within 2 feet of each other, how would you go about checking if they are? Thanks |
| ||
If your working in 3d you could use EntityDistance# ( src_entity,dest_entity) If your working in 2d you could use mathamatics and if then statments to check number of pixels between characters. And check the code archives under algorithms, ther is one that checks the distance between 2 rectangles and another one with homing missles that could just as well be little sheep folowing a sheep herder.Have a looksee. |
| ||
Maybe something like this?:Const MaxDistance = 40 Type Character Field PosX, PosY End Type For Ch.Character = Each Character InRange = False For Ch2.Character = Each Character DistX# = Ch2\PosX - Ch\PosX DistY# = Ch2\PosY - Ch\PosY If Sqr((DistX#^2)+(DistY#^2)) <= MaxDistance InRange = True EndIf Next If Not InRange ;Character Too Far Away Else ;Character Within MaxDistance Range EndIf Next |
| ||
Yeah I would definitely suggest using 'Types' as Todd suggested because it is a quick way to check through each 'instance'. |
| ||
Thanks for the reply(s). I have been working with something very similar to Todd's suggestion but the problem that I'm having is that the algorithm would allow a situation where the flock of pigeons break into 2 seperate groups on other sides of the field. This is not allowed, but as long as the pigeons in each group are close enough to each other, the algoritm above wouldn't catch this situation. Somebody mentioned a "Binary Heap" might work, but I don't even know what a "Binary Heap" is, let alone whether it would work? |
| ||
'Binary heap' means nothing to me either ;) If you need the 'pigeons' to split up into separate groups, are these groups different for a reson? different 'teams'??? If so, then repeat the above, but have a different Type for each group maybe? |
| ||
No, the 'pigeons' are all part of the same team. It's the splitting up that I'm trying to stop them doing, but I have no way of detecting when it happens. |
| ||
Could you post some of your existing code? |
| ||
Perhaps simply looking for two or more 'pigeons' in close proximity is what you are after... |
| ||
The method I wrote just checks if each "pigeon" is within 40 pixels of at least one other pigeon. If you wanted to check that each pigeon should be within 40 pixels of each other pigeon, than just change the "<=" to ">", and change "If Not InRange" to "If InRange". That way, the code after "If InRange" would only be run if a pigeon was more than 40 pixels away from any other pigeon. For example, using the code I wrote in my first post, both A and B would work. If you made those two changes I described though, only B would work, because in A it's possible for pigeons to be more than 40 pixels away: ![]() |
| ||
Wow! great graphics Todd, I think I might use them in my game ;). I've attached a screenshot from the game that might help. In this shot, all the units (members of 'red' team) are within 2 cells of each other and there are no gaps of more than 2 cells between 'clusters', i.e. 14,1,7,4 are not more than two cells away from 10,12,8. So this is perfectly OK, but..... In the shot below, 14,2,4 meet the criteria, but they are more than two cells away from the rest, which is not allowed, but the algorithm can't catch this because when 14 is tested, it finds that it's next to 2, so it thinks it's OK. |
| ||
if the pieces start out next to eachother, you could check for adjaceceny when one is moved, if it is no longer adjacent, then move back to original position. but if the pieces become scattered or dont start next to eachother, you would have to do a union tree or a flood fill, to check them all. make a fill Type, each only has a position on the grid start on any piece, by placeing a fill spot there check all tiles within adjacency radius of the fill spot, if there is a piece on any of those tiles, with a piece \checked=false then set that piece's\checked=true and place a fill spot on that piece. delete the origional fill spot when you check all its adjacent tiles for each fill spot do that same thing until theres no more fill spots youre done. you can go through each piece and if it's \checked is false then it is unconnected |
| ||
Thanks Coorrae, it worked like a charm! |