Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a somewhat simple side-scroller in Flash. The way I'm currently doing the really basic physics(you don't fall through floors/can't walk through walls) is that I have a big symbol of all the walls/floor/ceiling and use some complex hit testing against that.

Basically, if you are moving down when you hit, move you up til you're out, moving left move right, etc. If you're moving diagonally you'll move diagonally out and then move over the direction that didn't get you out until you hit something or get lined up. Then I move you down one so you're touching the floor since I have you fall down 20 pixels if you're in the air, and that make it slow since it has to do 20 hit tests every frame. Here's the code I use:

    public function onEnterFrame(e:Event){
            hitTests = 0;
            trace("x:"+x+", y: "+y);
            if(!game.main.Paused) {
                if(!HitTest.complexHitTestObject(this, room.main.currentRoom.edge, 1)) {
                    hitTests++;
                    movementY += 10;
//                    trace("movY: "+(movementY-20)+" > "+movementY);
                }
                if(game.main.Ahit) {
                    movementX -= 5;
                }
                if(game.main.Dhit) {
                    movementX += 5;
                }
                x += movementX;
                y += movementY;
//                trace((y-movementY)+" + "+movementY+" = "+y);
                if(HitTest.complexHitTestObject(this, room.main.currentRoom.edge, 1)) {
                    hitTests++;
                    dynamicXnum = 0;
                    dynamicYnum = 0;
                    free4floor = true;
                    while(HitTest.complexHitTestObject(this, room.main.currentRoom.edge, 1)) {
                        hitTests++;
                        if(movementX == 0 && movementY == 0) {
                            break;
                            xlast = undefined;
                        }
                        if(movementX > 0) {
                            x--;
                            dynamicXnum--;
                        }
                        if(movementX  0 || free4floor) {
                            y--;
                            dynamicYnum--;
                            free4floor = false;
                        }
                        if(movementY  0) {
                                y--;
                                dynamicYnum--;
                            }
                            else {
                                break;
                            }
                        }
                    }
                    if(xlast == false) {
                        while(!HitTest.complexHitTestObject(this, room.main.currentRoom.edge, 1) && dynamicXnum != 0) {
                            hitTests++;
                            if(dynamicXnum  0) {
                                x--;
                                dynamicXnum--;
                            }
                            else {
                                break;
                            }
                        }
                        if(movementX > 0)
                            x--;
                        if(movementX  0 || movementX != 0)
                            y++;
                        movementY = 0;
                    }
                }
                if(movementX >= 5) {
                    movementX -= 5;
                }
                else if(movementX  maxHitTests)
                maxHitTests = hitTests;
            trace("end: x:"+x+", y: "+y);
            trace("hts: "+hitTests)
            trace("mhts: "+maxHitTests);
            }
        }

This is working okay for now, and you can see a demo of it here, but there are a couple of problems.

For one, it can get a little slow, but this isn't that big of a problem, since it's pretty rare, and it's not that slow. Mainly, it's that when I get around to animating the little dude, and even now sometimes when it messes up a bit, it will get more than five pixels in the wall. Then when I try to move out, it won't make it out in one frame, and it will force him through the wall the wrong way, making him fall into infinity...does anyone know how to fix this? Should I totally redo how I do it? Should I have some kind of variable for which way he came from? If so, how should I do it?

share|improve this question

4 Answers 4

up vote 1 down vote accepted

Have you thought about using a good API to help you with your flash development?

Take a look at Flixel and Box2D.

share|improve this answer
    
Doesn't really answer the question. It is not really possible to port an existing game to Flixel without rewriting the whole thing. –  Iain Aug 4 '10 at 22:29
1  
Of course. But what it does do is solves the problem of performance and lack of physics knowledge. Create games, not wheels. –  David McGraw Aug 4 '10 at 23:02
    
I've decided to go with Box2D. I've kinda cancelled work on my game until I figure out how it works, and I found a great set of tutorials here: kerp.net/box2d/index.php Since you mentioned Box2D first, I'll accept yours even if it is really late. :p –  Ullallulloo Aug 20 '10 at 16:50

Also, if you really want to understand... I highly recommend MetaNet's tutorial series:

http://www.metanetsoftware.com/technique/tutorialA.html

(This tutorial includes an example -- with source from N! N had excellent and speedy physics.)

They go over way MORE than what you need, but DO go over what you need rather well.

share|improve this answer
    
the metanet tutorials are truely excellent –  tenpn Aug 4 '10 at 17:44

Honestly Box2D is a great physics library for flash and is very incorporable into existing projects.

share|improve this answer

It's hard to comment on speed since we don't know what's happening in HitTest.complexHitTestObject. I would say though that if you have a point that represent the player's feet, you can just move that point straight up in a while loop until you hit the air. I would have 2 "detector" points, one on the bottom left corner of the character, one on the bottom right, and test the leading point against terrain and move the character back until they are out of terrain (as you are doing). If you are using the built-in hitTest methods be aware that they are not that fast, but may well be the only way to get the effect you want.

share|improve this answer
    
Here's the hit testing I'm using: foxarc.com/blog/article/106.htm I can't use the built in hit testing very well since it's just block hit-testing. –  Ullallulloo Aug 5 '10 at 2:49
    
Ok that is using loads of bitmap methods so no wonder it is slow. You need to look at how to do basic rectangle and circle collisions - which are fine for most purposes. –  Iain Aug 5 '10 at 15:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.