3
\$\begingroup\$

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?

\$\endgroup\$

4 Answers 4

1
\$\begingroup\$

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

Take a look at Flixel and Box2D.

\$\endgroup\$
3
  • \$\begingroup\$ Doesn't really answer the question. It is not really possible to port an existing game to Flixel without rewriting the whole thing. \$\endgroup\$
    – Iain
    Commented Aug 4, 2010 at 22:29
  • 1
    \$\begingroup\$ Of course. But what it does do is solves the problem of performance and lack of physics knowledge. Create games, not wheels. \$\endgroup\$ Commented Aug 4, 2010 at 23:02
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Aug 20, 2010 at 16:50
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ the metanet tutorials are truely excellent \$\endgroup\$
    – tenpn
    Commented Aug 4, 2010 at 17:44
2
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Aug 5, 2010 at 2:49
  • \$\begingroup\$ 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. \$\endgroup\$
    – Iain
    Commented Aug 5, 2010 at 15:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .