EntityCollided
Blitz3D Forums/Blitz3D Beginners Area/EntityCollided
| ||
How do you properly use EntityCollided? I am confused as to what the paramaters are supposed to be. |
| ||
I don't use the command much but I'm pretty sure this is the correct usage ... If you set up a scene like so .. const C_Player = 1 const C_Plane = 2 Player = createsphere() entitytype Player, C_Player Plane = createplane() entitytype Plane , C_Plane collisions C_Player , C_Plane , 2, 3 Then you would use ... if entitycollided( Player , C_Plane ) = Plane [do stuff] endif |
| ||
ususally you want to loop through all of the collisions of an entity, so if it runs into two things the code won't mess up. for k = 1 to countcollisions(enitity) if CollisionEntity(entity,k) = otherentity then ;do whatever you need to do here endif if CollisionEntity(entity,k) = anotherentity then ;do whatever here endif next I use this to determmine collisions in all of my games, because it lets me do different things for different entities, and dosen't give weird results with multiple collisions. |
| ||
I have tried all of these to no avail. Why is it that in Paul Gerfen's tutorial, when he demonstrates EntityCollided, he never says EntityCollided(sphere, CUBE_COL) = blahblahblah He just says EntityCollided(sphere, CUBE_COL) and it works perfectly! 1. I have been told that EntityCollided returns a number and therefore must equal something. 2. I have tried using EntityCollided in every way I can think of (everyone tells me to use it a different way, i.e. "EntityCollided(Goodguy, Goodguy's collision)," "EntityCollided(Goodguy, badguy's collision)," "EntityCollided(Goodguy, badguy) = blahblahblah")) and nothing works - my good guys still run right through their powerups, and bullets still go right through their targets. PLEASE, SOMEONE, TELL ME ONCE AND FOR ALL THE CORRECT WAY TO USE THIS FUNCTION! |
| ||
Umm, like this: entity_that_collided=EntityCollided(entity,type) where "entity" is what you want to know is being collided with (ie your camera or pivot, or other player character representation) and "type" is what is doing the colliding with you. The "type" here is best illustrated by the following command from the Blitz Help: EntityType entity,collision_type[,recursive] Parameters entity - entity handle collision_type - collision type of entity. Must be in the range 0-999. recursive (optional) - true to apply collision type to entity's children. Defaults to false. Description Sets the collision type for an entity. A collision_type value of 0 indicates that no collision checking will occur with that entity. A collision value of 1-999 will mean collision checking will occur. You have the choice of 1 to 999 for setting types. So, if you decide that bullets are going to be type 1, and doors type 2, walls type 3, enemies type 4, etc, then you can check to see if a collision occurred with any of these, on a per-type basis (ie did a collision occur with a bullet, instead of a wall?). The reason for this variety is that collision checking will have different possibilities via the Collisions command: Collisions src_type,dest_type,method,response Parameters src_type - entity type to be checked for collisions. dest_type - entity type to be collided with. method - collision detection method. 1: ellipsoid-to-ellipsoid collisions 2: ellipsoid-to-polygon collisions 3: ellipsoid-to-box collisions response - what the source entity does when a collision occurs. 1: stop 2: slide1 - full sliding collision 3: slide2 - prevent entities from sliding down slopes Bullets you may want to come to a full stop when they colide, but if you collide with a wall, you may want to slide. Finally, the handle that is returned ("entity_that_collided" in my example above) is useful because you won't usually want to know merely that *A* bullet collided, but *WHICH* bullet collided (ie so you can delete it, if nothing else). And, of course, if it's doors you are testing for collision with, then you will want to know *WHICH* door, based on what might lie behind it. Hope this helps. |
| ||
Question: Can I use Collisions for an entity that doesn't exist yet - like a bullet? What's wrong with my code then? For bullet.bullet = Each bullet entitycollision = EntityCollided(player2\sphere, 3) If entitycollision > 0 FreeEntity bullet\entity Delete bullet Return EndIf Next By the way, 3 is the bullet's type for collisions. Also, about mindstorm's method... I don't see how that prevents weird things from happening when 2 things collide at once because Blitz will check one thing at a time, even if you do it the old-fashioned way. Also, since you use n = 1 to CountCollisions(entity), wouldn't that mean that if the player collided with only the wall, CountCollisions would return 1 because the player only hit the wall, but then if a bullet's type is 1 and the wall's type is 3, the player would run into the wall and act like he hit a bullet? I don't see how that method works at all, because it cycles through numbers, but the numbers don't necessarily stand for what the player hit. |
| ||
Collisions will set the general parameters of what kind of collision checking are we doing (ie 1: ellipsoid-to-ellipsoid collisions; 2: ellipsoid-to-polygon collisions; 3: ellipsoid-to-box collisions ), and how to handle such collisions when they occur: (ie 1: stop ; 2: slide1 - full sliding collision ; 3: slide2 - prevent entities from sliding down slopes ). So, yes, you can set Collisions for an entity that does not yet exist. When you create the entity, you will need to assign to it what type of entity it is (ie bullet=3). As far as 2 (or more) things colliding at once, collisions are put into a queue (a list). Blitz will automatically set into motion the response that you already assigned via Collisions (ie, stop, slide, etc). Your interest, then, is not how to handle the collision as such, since the Collisions command does that for you, but to determine what else you want to happen as a result of the collision (ie a bullet damages/kills the target entity, etc). mindstorm's method is good. It allows for the possibility of sorting out what types of collisions occurred (ie collision with an entity of type 1, type 2, type 3, etc.), and allows you to set up what you want to happen on the basis of what KIND of entity you collided with (ie bullet, wall, etc). Say your player character collides with a wall just as he gets shot with a bullet. The Collisions settings will tell Blitz that, for instance, colliding with the wall will allow you to slide, whereas the bullet hitting will just stop dead in its tracks (heh heh, play on words, dude). Now, regarding the colliding with the wall, say for instance, you don't really want anything special to happen to the player character, but are content to allow him to "slide". However, since a bullet also hit him, now, you have to work on what damage was done. mindstorm's method allows you tp sort through the list of collisions so that you can focus in on the bullet hitting, and have your code do appropriate damage to the player. The code for sorting it all out should look something like this: For loop=1 to CountCollisions(player_entity) which_entity=CollisionEntity (player_entity,loop) my_type=GetEntityType (which_entity) ;put in code for handling what you want to happen ;with entity named which_entity based on which ;entity type it is, according to the my_entity that ;was returned from GetEntityType. Next So, the logic is as follows: Step 1: CountCollisions tells how many collisions there were (Blitz keeps track of this). Step 2: CollisionEntity tells which entity collided. Step 3: GetEntityType tells what type entity it was. Now, you have an identification, not merely that a collision occurred, but which entity did the colliding, and what type entity it is. Cheers :) |
| ||
Yeah, here's an example of that. It just iterates through the collision list for the blue target and looks at what kind of entity was involved in each collision. If it was the room then the target changes direction; if it was a bullet mesh then the owning instance is indentified (there are undocumented commands that can speed this process up) and it is set to decay while sticking to the target. It's probably not what you'd do with "bullets" and "targets" in-game (because you'd almost certainly want bullets to interact with the room too) but it does show you how to do different things with the items on a collision list based upon what they are. |
| ||
Here's something I did a good while back ... http://www.blitzbasic.com/codearcs/codearcs.php?code=1095 If you take a look at the bullet update function in this ... it'll give you an idea of how it could be done. One tip would be to always use constants for your collision types ... much more readable .. Hope this helps. Stevie |
| ||
Thanks guys. I'm still not sure about EntityCollided, but now I understand mindstorm's method. I had just missed the CollisionEntity line. Thanks again. Edit: Whoa. I don't know if this is the reason why it wasn't working... well, actually, I know it was the reason why it wasn't working, but I just don't know if it was the only one - I was using player\sphere, when I had actually set player\pivot to do the collisions. And to think, this morning I would have throttled someone if they didn't provide me with a fool-proof solution to my problem! Well, I guess that wraps it up. God, I'm dumb. |
| ||
Sir Gak, your method is great, but how can I specify which bullet I want deleted after it hits the player? It says, "Variable must be a type" as an error message. Here's my code: For collisionnumber = 1 To CountCollisions(player\pivot) entity = CollisionEntity(player\pivot, collisionnumber) otherentity = GetEntityType(entity) Select otherentity Case 3 FreeEntity bullet\entity Delete bullet Default End Select Next |
| ||
When you create the bullet store the handle of the type instance in the entityname ...b.bullet = new bullet b\Entity = copyentity( bulletmesh?? ) nameentity b\Entity , handle( b ) Then to retreive ... case 3 b.bullet = object.bullet( entityname( entity ) ) freeentity b\entity delete b Stevie |
| ||
Stevie - thanks, but it didn't work because I don't know what "entity" is supposed to represent, and I've never used any of these commands before. |
| ||
Well, according to YOUR code above ..entity = CollisionEntity(player\pivot, collisionnumber) As I mentioned in a post above .. the Tanx game I wrote will give you a good idea of how to handle this. Stevie |
| ||
Sir Gak, your method is great, but how can I specify which bullet I want deleted after it hits the player? Stevie - thanks, but it didn't work because I don't know what "entity" is supposed to represent, and I've never used any of these commands before. My example shows you the longhand ("safe") method, wherein you have to iterate through every bullet instance to find out which one the bullet mesh of the currently considered collision belongs to; Stevie's method cuts that step out by creating a direct link back from each bullet mesh to its owner instance. They are two different ways of getting an answer to the question "which exact instance does this mesh belong to?" |
| ||
Just wondering... could this be not working because my bullet is a sprite? |
| ||
Whew! The code works without using sprites, so I can only assume that sprites cannot collide with anything. Thanks for putting up with me all this time and for the awesome help. Edit: Actually, the powerups - which were sprites but now are images on scaled-very-thin cubes - work great, but the bullets - using the same method and same code - don't. |
| ||
My bullet/player collisions still don't work! The bullets go right through the player, even though I used the same code that I used for the powerups! Could it be that the bullets are colliding with the player, and not the other way around, or does it not matter? Please help! |
| ||
It appears that the only time the bullet collisions work is when by a mysterious bug, the player outruns the bullet and hits it. This leads me to believe, as I said above, that there is a difference between the bullets colliding with the player, and the player colliding with the bullets, though it seems stupid to me. |
| ||
Collisions between two moving objects is not really supported that well - ellipsoid-to-ellipsoid can be made to work (see my posted example, above) but notice how the collisions line for the bullets is bullets-to-target not target-to-bullets, even though I only iterate through the target's collision list. If you swap that around (to target-to-bullets) in my example then you will get the same bug, with bullets slipping through the target. You have a couple of options: a) Use ellipsoid collision zones to get good collisions between moving objects. b) Move objecs of each mobile type separately, relative to one another, between multiple updateworlds, and deal with them in isolation. Erm, should work :/ c) Go custom with meshesintersect(). (Potentially slow) d) Consider if you really need to model the projectyle nature of bullets when a pick might do instead. |
| ||
Sledge, thanks for answering. 1. I've tried ellipsoid collision zones and it still doesn't work because it's target-to-bullets. 2. I'm not quite sure what you're suggesting here. 3. I don't want a major slowdown. 4. I do need to model the projectile nature of bullets because - unlike an FPS - the bullets aren't lightning-quick. They're slow, like bullets in old platformers, and thus allow opponents to dodge. I think I might try using a For...Each...Next loop to cycle through each bullet and see if it's hit a player, but that's still rather inefficient. |
| ||
I've tried ellipsoid collision zones and it still doesn't work because it's target-to-bullets. If you can possibly to it the other way around then that looks like the best option. I'm not quite sure what you're suggesting here. The problem comes from both parties moving at once, so you could move one party, updateworld and process; then move the other party, updateworld and process... all in one gameloop. That way the in-built collisions system does not have to deal with collisions between two moving objects because one type is always static while the other is moving. There are, however, complexities in managing such a system (bullets would have to be offset while you moved the player, to keep them relatively static, for example) and I would personally do everything to avoid it. But it's an option so I mentioned it for the sake of being complete. |
| ||
Sledge, guess what?! I'm still having friggin' problems with this friggin' code! I tried: For bullet.bullet = Each bullet MoveEntity bullet\entity, 0, 0, -bullet\speed# For x = 1 To CountCollisions(bullet\entity) entity = CollisionEntity(bullet\entity, x) player.player = Object.player(EntityName(entity)) player\health = player\health - 1 Next And I'm so very close, but it highlights the player\health = player\health - 1 line, and says "Object does not exist!" The object does exist, by golly, because I said so! For all of Mark Sibly's godliness, this whole collisions issue really sucks. Edit: Sledge, what did you use for Ice-Teroids bullets? |
| ||
I never use Object and Handle because they are still undocumented, but maybe Stevie will pop by and give you a definitive verdict on your usage of the commands. I notice in the code posted that you have no Updateworld between moving your bullets and processing collisions - best to move all your bullets, then deal with any collisions afterwards (ie in a separate loop) I think. But yeah, you need Updateworld in there because that is the command that processes all the collisions stuff. Edit: Sledge, what did you use for Ice-Teroids bullets? Ice-Teroids uses MeshesIntersect(), slinkily sidestepping any and all collisions issues. For all of Mark Sibly's godliness, this whole collisions issue really sucks. It's not so much that it sucks, rather it's geared towards particular things - I mean if you want sliding collision between the player and a static level (and somewhere along the line you generally do) then it's life-savingly brilliant. Given that Blitz3D is a language rather than an engine, the amount of automated collisions stuff you get is really rather sweet; but no, it's not comprehensive and you have to give yourself time to get used to its limitations/foibles. I can only really refer you back to the example I posted, which shows you working collisions between bullets and a moving target - I know having to use spheres is a limitation, but you could use several to construct a more complex collision body if required. Keep us posted! |
| ||
I would put in a check before you remove health from the collided entities type instance. e.g. If Player <> Null player\health = player\health - 1 endif Are all your collidable entities of type player? If they are not then you will need to handle each type serarately. Are you definately storing the handle in the entityname? We WILL get this working for you ;) Stevie |
| ||
Stevie, you are a godsend! I can't believe I'm that STUPID! I stored the handle in the entityname originally, but then I changed methods so I deleted that line. Then, when I switched back, I forgot all about that vital piece of code. It works great now! Thanks so much for all of the help, everyone! |
| ||
Whoops. There's a new bug. When someone gets hit with a bullet, it says that "otherentity = GetEntityType(entity)" in the powerup code doesn't work, but getting powerups works fine. |
| ||
For powerups why not use a simple ... If entitydistance( Player , powerup ) < 10 [do stuff ] endif No need for collisions. Stevie |