The forums have permanently moved to forum.kirupa.com. This forum will be kept around in read-only mode for archival purposes. To learn how to continue using your existing account on the new forums, check out this thread.


Page 1 of 2 12 LastLast
Results 1 to 15 of 18

Thread: Checking object type before collision detection

  1. #1

    Checking object type before collision detection

    In my current game there are several game object types. Some objects only interact with certain other objects, for example, enemies only react with other enemies, the player and player bullets, while player bullets only react with enemies (not other bullets or items)... and so on.

    My question is, how do you check for the type of the objects before doing any collision detection? This way I can have Flash only do as much work as is necessary, eg if playerBullets don't care about enemyBullets, then there's no reason to check collision between the them.

    Do you do something like:

    Code:
    if (sprite1:Enemy && sprite2:PlayerBullet) checkCollision(sprite1, sprite2);
    Or is there a better way to do this? (Note: I can't actually get the above code to work but I swear I saw someone else do it--it is possible, right?) Do you use separate arrays for each type currently on the stage and check them against other arrays (eg the particle pool, actor pool, etc)? Or maybe sprite "layers" that only collide with objects in other specific layers? How do you do it?

  2. #2
    I can't really answer your question, but as for the code above, I don't think you understand the use of : delimiters on variables. Its known as strict data typing, and is used to enforce a specific type upon a variable. In your case, I'm almost certain the sprites are MovieClips. Unless your actually using classes called Enemy and/or PlayerBullet.

  3. #3
    I am quite familiar with typing. I actually did write classes called Enemy and PlayerBullet, as this provides me with a rough (but fast) implementation of the Interface design pattern (actually using "public class Blah implements IBlah" is slower, so I avoid it when writing games).

    And yes, the sprites are actually based off the Sprite class, not MoveClip, again for performance reasons.

    In case anyone was wondering, I learned that you can check for types using the is operator, like so:
    Code:
    if (sprite1 is Enemy && sprite2 is PlayerBullet) checkCollision(sprite1, sprite2);
    As for the other problem though, the only way is to check types (as above) and if the condition returns true, then do the collision reaction. I was hoping it would be a bit more elegant, but so far no one knows of any other solution (I asked 3 forums so far). I have a lot of boring code to write
    Last edited by vonWolfehaus; May 4th, 2008 at 03:14 PM.

  4. I don't really know what else you would expect? :S And coding isn't boring :S

  5. #5
    I don't understand what the problem is. What you will want to do is put like-minded objects into arrays. Have an array with all your enemies, an array for all your bullets, an array for your players, etc. You see where this is going, right?

    onEnterFrame > 1. check collisions between enemies and bullets. 2. check collisions between enemies and players. 3. etc.

    make sense?

    Maybe have a function that receives the two arrays you will be comparing.

    function checkCollisions( type1:Array, type2:Array )

    or maybe a unique function for each collision type. whichever you prefer.

    checkCollisionsBetweenEnemiesAndBullets();
    checkCollisionsBetweenEnemiesAndPlayers();
    etc();

    Does this make sense? It's not hard at all.
    Last edited by therobot; May 4th, 2008 at 11:02 PM.
    you = function(){
    setEnabled( true );
    live();
    setEnabled( false );
    }

  6. #6
    Quote Originally Posted by ArmoredSandwich View Post
    I don't really know what else you would expect? :S And coding isn't boring :S
    Then you clearly haven't been coding long enough There are definitely some boring parts for me, after I've written them so many times.

    Quote Originally Posted by therobot View Post
    I don't understand what the problem is. What you will want to do is put like-minded objects into arrays. Have an array with all your enemies, an array for all your bullets, an array for your players, etc. You see where this is going, right?

    onEnterFrame > 1. check collisions between enemies and bullets. 2. check collisions between enemies and players. 3. etc.

    make sense?
    That's what I thought of first, but that actually requires more loops and conditionals than is really necessary because you have to loop through each array, resulting in a lot of wasted processing (and redundant code). This costs some performance, and since my game is going to be crowded, I have to be a bit more efficient than that--I can only loop through one array, so all objects must be in only one array, savvy?

    Quote Originally Posted by therobot View Post
    Maybe have a function that receives the two arrays you will be comparing.

    function checkCollisions( type1:Array, type2:Array )
    That's a better idea, but suffers the same problem as the first since you'd have to run that method for each type of collision.

    Quote Originally Posted by therobot View Post
    or maybe a unique function for each collision type. whichever you prefer.

    checkCollisionsBetweenEnemiesAndBullets();
    checkCollisionsBetweenEnemiesAndPlayers();
    etc();
    I came across this as well, but again, this suffers the same inefficiency as the first two.

    Quote Originally Posted by therobot View Post
    Does this make sense? It's not hard at all.
    It is more difficult when you're trying not to be wasteful. Thanks for the reply though, I appreciate it.

    The system I mentioned earlier is what I'm sticking to. It's efficient enough and after I wrote it, turned out to be simpler than I previously thought and there's no redundant code.

    For the curious: I simply put all game objects (there are no static ones) in a single array and loop through that. This is obvious, the trouble I was having was getting certain objects to only react to certain other objects (as I tried to explain before), so to do that I designed an object hierarchy that allowed me to check types with some conditionals, which turned out to only amount to four. So it actually wasn't all that bad, I was just missing a well-designed hierarchy and the is operator. Ah well, it's done.
    Last edited by vonWolfehaus; May 5th, 2008 at 03:02 AM.

  7. Sorry to go offtopic here, but if a part is boring you simply aren't coding it correctly. Maybe if you already coded it before, then it could be boring but besides a lone exception I always enjoy coding.

  8. #8
    1,627
    posts
    hugeExplosions = true;
    This is definitely possible, I've done it with my flash game in AS2, it can't be much diff in AS3 - let me dig up the code
    MS Paint FTW!


  9. #9
    1,627
    posts
    hugeExplosions = true;
    Well I can't find the code but I'm sure it's something like

    if(object1 is SomeType)

    or something along those lines

    - ah just did a google and look at flash.utils.describeType

    It allows run time type checking - not sure on exact use but it's probably along the lines of

    if(describeType(TypeName) == "SomeType") {
    }
    MS Paint FTW!


  10. #10
    Quote Originally Posted by vonWolfehaus View Post
    That's what I thought of first, but that actually requires more loops and conditionals than is really necessary because you have to loop through each array, resulting in a lot of wasted processing (and redundant code). This costs some performance, and since my game is going to be crowded, I have to be a bit more efficient than that--I can only loop through one array, so all objects must be in only one array, savvy?

    I'm sorry, I don't exactly see how my way is redundant. I'm seeing the same amount of calculations and less confusion using my method. Sorry, but if you'll explain, i'd love to listen.
    you = function(){
    setEnabled( true );
    live();
    setEnabled( false );
    }

  11. #11
    Quote Originally Posted by Charleh View Post
    - ah just did a google and look at flash.utils.describeType

    It allows run time type checking - not sure on exact use but it's probably along the lines of

    if(describeType(TypeName) == "SomeType") {
    }
    Oh cool, I didn't know that. Thanks! Turns out it returns an XML object you have to parse, which probably isn't the best thing for my situation, but I can definitely see that method coming in handy later on.

    Quote Originally Posted by therobot View Post
    I'm sorry, I don't exactly see how my way is redundant. I'm seeing the same amount of calculations and less confusion using my method. Sorry, but if you'll explain, i'd love to listen.
    I hope you're not taking any personal offense--I mean none. Like you said, the solutions you provided were not that hard and, as I mentioned before, I had indeed come up with them myself as well. So I'm not dissing you or anything, just letting you know that those aren't good solutions for my particular situation.

    I say those methods use redundant code because, if you write them out, you will notice that you will end up with some blocks of code you just copy and paste to the different functions, or writing one function that you run more than once. I'll explain.

    The method you suggested (the same one that has crossed my mind as well) was to make several arrays and loop through them, two at a time, for every possible collision situation. So here's our example arrays:
    Code:
    public var enemyArray:Array = new Array();
    public var enemyBulletArray:Array = new Array();
    public var playerArray:Array = new Array(); // could include player's allies
    public var playerBulletArray:Array = new Array();
    public var items:Array = new Array();
    So we'll want to loop through those arrays to check for collisions between them. Let's write a single checkCollisions() method to minimize redundant code (writing separate checkCollisionsBetweenXandY() would have been even more wasteful):
    Code:
    public function checkCollisions(array1:Array, array2:Array):void
    {
    // loop through each array
    for (var i:int = 0; i < array1.length; i++)
    {
    	var object1 = array1[i];
    	for (var j:int = i + 1; j < array2.length; j++)
    	{
    		var object2 = array2[j];
    		var dx:int = object2.x - object1.x;
    		var dy:int = object2.y - object1.y;
    		var dist:Number = Math.sqrt(dx * dx + dy * dy);
    		if (dist < object1.radius + object2.radius)
    		{ if (array1[object1] is Enemy && array2[object2] is PlayerBullet)
    			{ // react appropriately
    			}
    			// &c... all the other conditionals for each situation...
    		}
    	}
    }
    So that's two loops within a function, which is fine, but in our game loop we'd have to run this method a few times in order to go through all of the arrays, probably like this:
    Code:
    checkCollisions(enemyArray, playerBulletsArray);
    checkCollisions(enemyBulletsArray, playerArray);
    checkCollisions(itemsArray, playerArray);
    That's minimal, and we're already at 6 loops. In addition, passing arrays into the function does us no good since we'll have to check for their type anyway. And if we wrote separate functions for each collision type, there would still be as many loops, but that would also bring us a lot of redundant code since we'd have to write the loops and some of the calculations again, for each of those functions.

    So I hope that clears some things up for you. Let me know if any of that was confusing and I'll do my best to explain it better. Cheers

  12. #12
    Oh, I wasn't taking offense in anything

    Still, I think lumping like-minded objects into arrays will be more efficient (in actual cpu cycles) than looping (twice) through every single object and then running a slew of if..then statements (in EACH iteration of the loop) to determine which object types you are dealing with.

    You know what I mean? Plus, there are all sorts of other advantages to sorting your objects into arrays.

    I guess we were misunderstanding each other. You were thinking redundant in terms of lines of code, and I was thinking waste of cpu cycles...


    EDIT: (further explanation)
    running 6 loops @ 20 iterations each without if then statements will be much faster than running 1 loop @ 120 iterations each with an if..then statement to determine what types you are dealing with.

    I wouldn't be so concerned with having an extra 10 lines that are nearly identical to another 10 lines if it will make your game run faster
    Last edited by therobot; May 5th, 2008 at 05:29 PM.
    you = function(){
    setEnabled( true );
    live();
    setEnabled( false );
    }

  13. #13
    Ack, there was some misunderstanding. Also, I'm kinda slow I see what you mean now. Going through it again, I can see that looping through objects in one array and only testing them against objects in another array could be faster, since the first array completely ignores all the other arrays, saving some checking. I'm definitely going to test this out, thanks.
    Last edited by vonWolfehaus; May 6th, 2008 at 01:33 AM.

  14. #14
    1,627
    posts
    hugeExplosions = true;
    Saying all this though you CAN type check, I just can't remember how, it's in the flash docs somewhere!!
    MS Paint FTW!


  15. #15
    Quote Originally Posted by Charleh View Post
    Saying all this though you CAN type check, I just can't remember how, it's in the flash docs somewhere!!

    If you can find it, I'd like to know how. Just in case. It could be useful.
    you = function(){
    setEnabled( true );
    live();
    setEnabled( false );
    }

Page 1 of 2 12 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Home About kirupa.com Meet the Moderators Advertise

 Link to Us

 Credits

Copyright 1999 - 2012