A Flash Developer Resource Site

Results 1 to 8 of 8

Thread: [AS3] RPG Collision Detection

  1. #1
    Junior Member
    Join Date
    Jun 2010
    Posts
    7

    Unhappy [AS3] RPG Collision Detection

    Hey guys - I'm trying to make a top down RPG game - similar to what you'd find in the Zelda or Pokemon games on portable consoles.

    I was wondering if anybody could enlighten me with a simple collision detection - perhaps something similar to pixel collision? I'm probably making this confusing so feel free to post a question if you don't get what I'm after and I'll try and explain it better.

    Thanks,

    Sammy

  2. #2
    Junior Member
    Join Date
    Jun 2010
    Posts
    7
    Actionscript Code:
    import flash.events.KeyboardEvent;
    import flash.events.Event;

    ///////////////////////////////////////////////////////////////////////////////
    // Position Character /////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////

    char.x = 100;
    char.y = 100;

    ///////////////////////////////////////////////////////////////////////////////
    // Character Movement /////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////

    var speed:Number = 5;
    var leftButton:Boolean = false;
    var rightButton:Boolean = false;
    var upButton:Boolean = false;
    var downButton:Boolean = false;

     stop();
     char.gotoAndStop(4);

    stage.addEventListener(KeyboardEvent.KEY_DOWN, kDown);
    stage.addEventListener(KeyboardEvent.KEY_UP, kUp);
    stage.addEventListener(Event.ENTER_FRAME, moveChar);

    function kDown(event:KeyboardEvent)
    {
        if (event.keyCode == 37 || event.keyCode == 65)
        {
            leftButton = true;
        }
        if (event.keyCode == 38 || event.keyCode == 87)
        {
            upButton = true;
        }
        if (event.keyCode == 39 || event.keyCode == 68)
        {
            rightButton = true;
        }
        if (event.keyCode == 40 || event.keyCode == 83)
        {
            downButton = true;
        }
    }

    function kUp(event:KeyboardEvent)
    {
        if (event.keyCode == 37 || event.keyCode == 65)
        {
            leftButton = false;
        }
        if (event.keyCode == 38 || event.keyCode == 87)
        {
            upButton = false;
        }
        if (event.keyCode == 39 || event.keyCode == 68)
        {
            rightButton = false;
        }
        if (event.keyCode == 40 || event.keyCode == 83)
        {
            downButton = false;
        }
    }

    function moveChar(event:Event)
    {
        if (leftButton == true)
        {
            char.gotoAndStop(1);
            char.x -=  speed;
        }
        else if (rightButton == true)
        {
            char.gotoAndStop(3);
            char.x +=  speed;
        }
        else if (upButton == true)
        {
            char.gotoAndStop(2);
            char.y -=  speed;
        }
        else if (downButton == true)
        {
            char.gotoAndStop(4);
            char.y +=  speed;
        }
    }

    This is the code I have so far - anybody got any ideas how I could successfully and effectivly add collision detection into this code?

    Thanks,

    Sammy

  3. #3
    Senior Member
    Join Date
    Jul 2008
    Posts
    391
    I'm not sure how to add 100% pixel by pixel collision detection but I use a sort-of pixel collision detection instead. But I'll start with hitTestObject.
    PHP Code:
    if (circle.hitTestObject (triangle)) {
        
    //They collided

    hitTestObject checks if the bounding boxes of both objects intersect, a bounding box is the blue box that surrounds your movieclip when you select it. This is a truly awful way to detect collisions unless all your movieclips are squares or rectangles.

    PHP Code:
    if (veryelaborateshape.hitTestPoint (mouseXmouseYtrue)) {
        
    //They collided

    hitTestPoint takes 3 parameters, the x point, the y point, and whether to check using the bounding box or check every pixel. This is perfect for testing a shape with a point, such as if your mouse cursor is over a very elaborately drawn movieclip.

    Now I don't know pixel by pixel testing but this is what I do to try to achieve that. Let's say I want to test collision between a treble clef (complex shape) and a triangle (less complex shape). In addition to the 2 movieclips, I would create a new one called mc_hitpoint and I would go into the triangle movieclip and place an instance of mc_hitpoint on each corner of the triangle. Then this is the code I would use
    PHP Code:
    for (var 0triangle.numChildreni++) {
        if (
    triangle.getChildAt (iis mc_hitpoint) {//The current child is a hit point
            
    var hitpoint:MovieClip MovieClip (triangle.getChildAt (i));
            var 
    globalpoint:Point hitpoint.localToGlobal (new Point (00));//Get the hit point's coordinates in the stage's coordinate space        

            
    if (treble.hitTestPoint (globalpoint.xglobalpoint.ytrue)) {
                
    //Triangle and treble collided
            
    }
        }

    This method is better than using hitTestObject or hitTestPoint alone because you're not checking with a box or a single point on a triangle. And the great thing about this method is if you want to be more precise, all you do is add more instances of mc_hitpoint in the triangle movieclip.

    For your purposes just choose whichever method you think will be best suited for you. If you need anymore detail I have no problem explaining them further.

  4. #4
    Junior Member
    Join Date
    Jun 2010
    Posts
    7
    So... using the code I provided - could you possibly explain a way in which I could implement it? Considering there is going to be a number of Movie Clips that would be used as blocks.

  5. #5
    Junior Member
    Join Date
    Jun 2010
    Posts
    7
    Actionscript Code:
    import flash.events.Event;
    import flash.events.KeyboardEvent;

    ///////////////////////////////////////////////////////////////////////////////
    // Position Character /////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////

    char.x = 100;
    char.y = 100;

    ///////////////////////////////////////////////////////////////////////////////
    // Character Movement ////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////

    var speed:Number = 5;
    var leftButton:Boolean = false;
    var rightButton:Boolean = false;
    var upButton:Boolean = false;
    var downButton:Boolean = false;

     stop();
     char.gotoAndStop(4);

    stage.addEventListener(KeyboardEvent.KEY_DOWN, kDown);
    stage.addEventListener(KeyboardEvent.KEY_UP, kUp);
    stage.addEventListener(Event.ENTER_FRAME, moveChar);

    function kDown(event:KeyboardEvent)
    {
        if (event.keyCode == 37 || event.keyCode == 65)
        {
            leftButton = true;
        }
        if (event.keyCode == 38 || event.keyCode == 87)
        {
            upButton = true;
        }
        if (event.keyCode == 39 || event.keyCode == 68)
        {
            rightButton = true;
        }
        if (event.keyCode == 40 || event.keyCode == 83)
        {
            downButton = true;
        }
        if (event.keyCode == 69)
        {
            gotoAndStop(2);
        }
        if (char.hitTestObject(tree)) {
           
                    leftButton = false;
                    upButton = false;
                    rightButton = false;
                    downButton = false;
                }
    }


    function kUp(event:KeyboardEvent)
    {
        if (event.keyCode == 37 || event.keyCode == 65)
        {
            leftButton = false;
        }
        if (event.keyCode == 38 || event.keyCode == 87)
        {
            upButton = false;
        }
        if (event.keyCode == 39 || event.keyCode == 68)
        {
            rightButton = false;
        }
        if (event.keyCode == 40 || event.keyCode == 83)
        {
            downButton = false;
        }
    }

    function moveChar(event:Event)
    {
        if (leftButton == true)
        {
            char.gotoAndStop(1);
            char.x -=  speed;
        }
        else if (rightButton == true)
        {
            char.gotoAndStop(3);
            char.x +=  speed;
        }
        else if (upButton == true)
        {
            char.gotoAndStop(2);
            char.y -=  speed;
        }
        else if (downButton == true)
        {
            char.gotoAndStop(4);
            char.y +=  speed;
           
        }
    }

    This is what I have so far - colliding with a single object - but if I write it this way this means im going to have to write MILLIONS of "if" statements.

    I'm also having the problem where this doesn't work until I hit the center of the object and then I can't move away - the character freezes - please help?

  6. #6
    Senior Member
    Join Date
    Jul 2008
    Posts
    391
    PHP Code:
    function kDown(event:KeyboardEvent)
    {
        if (
    event.keyCode == 37 || event.keyCode == 65)
        {
            
    leftButton true;
        }
        if (
    event.keyCode == 38 || event.keyCode == 87)
        {
            
    upButton true;
        }
        if (
    event.keyCode == 39 || event.keyCode == 68)
        {
            
    rightButton true;
        }
        if (
    event.keyCode == 40 || event.keyCode == 83)
        {
            
    downButton true;
        }
        if (
    event.keyCode == 69)
        {
            
    gotoAndStop(2);
        }
        if (
    char.hitTestObject(tree)) {
            
                    
    leftButton false;
                    
    upButton false;
                    
    rightButton false;
                    
    downButton false;
                }

    The reason your attempt didn't work is because the the hit test is taking place in the wrong function. It should take place in the enter frame function. In your example, let's say char has already collided with the tree. So when you press the left button you set leftButton to true. But immediately you check if char is hitting the tree and it is, so you set all the button states to false. So you're not giving the enter frame function a chance to update char's position before checking for a collision.

    This is an example of using my third method of collision. I chose the tree to be the complex shape and the character the simple shape for obvious reasons. In the character movieclip is a layer that contains hit points on 4 corners. The trees are added to their own container called trees because this is more organized and easier to access.

    So in the enter frame function it enters a for loop that goes through every tree in trees, and on every iteration it enters another for loop that goes through every hit point in the character. So it checks each hit point to see if it collides with the current tree.

    As for what happens once you collide, that's up to you because different game mechanics call for different responses.
    Attached Files Attached Files

  7. #7
    Junior Member
    Join Date
    Jun 2010
    Posts
    7
    if (tree.hitTestPoint (global.x, global.y, true)) {
    //One of the hit points collided with the tree
    trace ("A");
    break;
    }


    Sorry to be a pain in the ass - but what would I have to enter in here to successfully stop all character movement. Previous tests I've done stop the character but if I try to move the character after collision - it doesn't move.

    Any ideas?

    Again - sorry for this - i'm new to as3 coding and im in real need of this

    Thanks.

  8. #8
    Senior Member
    Join Date
    Jul 2008
    Posts
    391
    You can still set the 4 arrows to false. The only reason it didn't work for you was because of what I said before.

Posting Permissions

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




Click Here to Expand Forum to Full Width

HTML5 Development Center