Collision problem

Blitz3D Forums/Blitz3D Programming/Collision problem

HappyCat(Posted 2005) [#1]
I'm having a wee problem with Blitz collisions. I sometimes get bullets passing right through enemies - it seems to only happen when 2 bullets hit the enemy in the same frame - one of them gets a collision, the other doesn't and keeps going.

My collisions are set up as:

Collisions PlayerShotType, EnemyType, 1, 1

and checked as:

EntityCollided(Shot, EnemyType)

and each shot and enemy has their EntityType and EntityRadius set.

Anyone got any ideas?


lo-tekk(Posted 2005) [#2]
You might use EntityDistance instead of the collisions. Or you might give Nuclear Glory Collision Plugin a try. Have bought it recently because of the lack of No-Respond-Collisions in Blitz.

http://www.blitzbasic.com/toolbox/toolbox.php?tool=49

-------------------------
www.moonworx.de


HappyCat(Posted 2005) [#3]
I'm using EntityDistance for all other collisions in the game but I went with Collisions for players bullets because they move so fast and, ironically, at lower frame rates occasionally bullets were passing right over enemies in a single frame.

I have verified the problem described above several times using Fraps to record the session and playing it back slowly and I can quite clearly see the missiles going right through the enemy. Having done a bit more searching around here I'm suspecting it's related to the reported problems with detecting collisions between two moving entities.

In light of this problem I'm seriously considering going back to just using EntityDistance, especially as I'm also on the verge of going with a fixed rate logic system, which would mean that I could guarantee collisions not being missed.


Sledge(Posted 2005) [#4]
You could use multiple updateworld's to move the enemy separately to the bullets. That would negate the problem because only one collision type would be in motion at any one time.


Hujiklo(Posted 2005) [#5]
You're best off looking at the linepick commands for these sort of collisions... If a bullet is going too fast then it may already be through the target before Blitz gets a look in.
Set up a line pick from your gun and if it hits an enemy then you've registered a hit. I've never had this method fail.


HappyCat(Posted 2005) [#6]
Sledge: that didn't help I'm afraid. Same thing is happening :-(

Hujiklo: I'll have a look, thanks.


Nicstt(Posted 2005) [#7]
seems to me that the first one to register the collision will always get acted on.

how about using EntityCollided and then changing the position of the bullet that didnt so it hits just after instead? If it doesnt matter if the target has alrdy been hit, just do something instead with the projectiles


jfk EO-11110(Posted 2005) [#8]
Maybe you did call ResetEntityon the enemy after the first detection? Or you did hide him, or even free him or something? You could use CountCollisions to check if the enemy was hit one or two times. Additionaly I'd suggest to use polygonal collision.

BTW instead of EntityCollided you may use somethin like
For i=1 to countcollisions(shot)
 impact=collisionentity(shot,i)
 if impact=enemy then do something
next



Sledge(Posted 2005) [#9]

and checked as:

EntityCollided(Shot, EnemyType)



Leaving the whole two-object-types-moving-at-once problem to one side for the moment, if that's all you're doing when looking for collisions then it's not enough. In fact it's the wrong command entirely - see my example below (EntityCollided not used once).



As you can see, you have to iterate through all the collisions for each object (of the entitytype that leads in the collisions command), then you can decide what to do based on the entitytype of the collided entity for each one of those collisions.

Edit: Whoops, just noticed jfk EO-11110 totally beat me to most of that and that I'd misread him with my first edit. But you have a working example now.


Sledge(Posted 2005) [#10]

Sledge: that [multiple updateworld's] didn't help I'm afraid. Same thing is happening :-(


Sorry - it's a bit more complex and, thinking a on it a little more, not really suited to multiple targets (because it involves translating the colliding objects along with the collided one then subtracting the translated figures from the colliding objects regular movement. I can post if you like though.)

Everyone is going to yell "IT'S SLOW! IT'S SLOW!" but my gut reaction to solving the two-object-types-moving-at-once problem would, in this case, be to check the distance of the bullets to each enemy and if they're very close then go on to see if their meshes intersect.


HappyCat(Posted 2005) [#11]
Hujiklo - I can't get LinePick to do anything. Are there any tricks to it (I'm doing EntityRadius and EntityPickMode and making sure I'm using the delta). But nothing.

Sledge - CountCollisions always returns 1 so I think the problem is more fundamental than that. I'm also intrigued as to why EntityCollided is "the wrong command entirely" as apart from this one problem (which also happens with CollisionEntity) it's been working fine.

And the last thing you suggest is basically what I was doing before - but at low frame rates the missiles would occasionally skip over an enemy in a single frame - which is why I thought Blitz collisions would help.

jfk EO-11110 - I don't call ResetEntity (at all) or hide the entity (until it's been destroyed at least, which takes > 1 missile).


Hujiklo(Posted 2005) [#12]
So you've set your enemy's pickmode to 'pickable' right?
look at this code example below....

Linepick should be set by your gun. The 'gunhit' variable will return the ' pickable' entity it has picked.

You then cycle through your enemies to check if their handle corresponds to the 'gunhit' handle...if it does, either do damage or kill it.

If MouseHit (1) 
	TFormVector 0,0,10000,GUN,0 ; vector does not have to be so large!!!
	If weapontype=1 ; Check which type of gun if necessary
    gunhit=LinePick (EntityX(GUN,True),EntityY(GUN,True),EntityZ(GUN,True),TFormedX(),TFormedY(),TFormedZ(),0.2)
	recoilgun#=0.01
	EndIf 
endif



Sledge(Posted 2005) [#13]

CountCollisions always returns 1



Yup, it should - for each bullet that hits the enemy in question. Are you checking each bullet, because it sounds like you're only checking one? The code I posted shows you how to check though lots of bullets (balls in this case) hitting a mesh (a scaled cube, but any mesh would do fine) simultaneously using CollisionEntity - if you can't work out where you're going wrong then post more of your code and we'll mull it over. HOWEVER, for fast moving objects you should take Hujiklo's advice and consider a linepick - it's a much more straightforward solution.


HappyCat(Posted 2005) [#14]
I was checking each bullet - only ever 1 collision each (which is how it should be).

If I swapped it round and checked the enemies then I could get multiple collisions ... some of the time ... at other times it would return 1 (or even 0) when there quite blatantly should have been 2 collisions.

As I say, I think it's something going wrong in the Blitz collisions (rather than my code) as CountCollisions just doesn't always return the correct value (but at other times it does). As such, I've abandoned that approach and instead have been trying LinePick ...

... and it's getting there - having some fun with the scaling (Sprite Control does a lot of internal scaling to get pixel perfect sprites) - a little more time should get it working ...


HappyCat(Posted 2005) [#15]
Hey hey! Got it - with LinePick. Rock solid - thanks guys!