Actionscript 3.0使用数组创建边界

时间:2013-07-23 15:22:20

标签: actionscript

目前我正在开发一个重建马里奥级别的项目,我的问题是,当我没有硬编码bottomLimit(地板,目前设置为400)时,马里奥最终会落空。

另一件我无法弄清楚的事情是我如何移动我的隐形块来创建地板边界以容纳地板。选择的级别是超级马里奥兄弟3的堡垒级别,如果这有助于描绘我正在尝试用它做什么。

我的代码中有几个.as文件,我会把我麻烦的文件和我的碰撞代码放在一起。

package {

import flash.display.MovieClip;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.media.Sound;


public class FortressMap extends MovieClip
{
    private var _mario:SmallMario;
    private var vx:Number = 0;
    private var vy:Number = 0;
    private var _ceiling:Array = new Array();
    private var _floor:Array = new Array();
    public const accy:Number = 0.20;
    public const termv:Number = 15;
    public var onGround:Boolean;
    public var bottomLimit:Number;

    public function FortressMap()
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

        _mario = new SmallMario();
        addChild(_mario);
        _mario.x = 50;
        _mario.y = 400;

        //Creating the blocks for the floor
        createFloor(16, 416);

        //Creating the blocks for the ceiling
        createCeiling(16, 352);
}

    private function createFloor(xPos:Number, yPos:Number):void
    {
        var floor:Floor = new Floor();
        addChild(floor);
        floor.x = xPos;
        floor.y = yPos;
        floor.height = 16;
        _floor.push(floor);
        floor.visible = false;
    }

    private function createCeiling(xPos:Number, yPos:Number):void
    {
        var ceiling:Ceiling = new Ceiling();
        addChild(ceiling);
        ceiling.x = xPos;
        ceiling.y = yPos;
        ceiling.height = 16;
        _ceiling.push(ceiling);
        ceiling.visible = false;
    }

    private function addedToStageHandler(event:Event):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        addEventListener(Event.ENTER_FRAME, frameHandler);
        addEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
    }

    private function frameHandler(event:Event):void
    {

        _mario.x +=  vx;
        _mario.y +=  vy;


        if (_mario.x < 16)
        {
            _mario.x = 16;
        }

        vy +=  accy;

        for (var i:int = 0; i < _ceiling.length; ++i)
        {
            Collision.block(_mario, _ceiling[i]);
        }
        for (var j:int = 0; j < _floor.length; ++j)
        {
            Collision.block(_mario, _floor[j]);
        }

        bottomLimit = 400;

        if(_mario.y >= bottomLimit)
        {
            _mario.y = bottomLimit;
            vy = 0;
            onGround = true;

        }
        else
        {
            onGround = false;
        }           
    }

    private function keyDownHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT)
        {
            vx = -5;
            return;
        }
        if (event.keyCode == Keyboard.RIGHT)
        {
            vx = 5;
            return;
        }
        if (event.keyCode == Keyboard.UP)
        {
            if(onGround == true)
            {
                vy = -5;
                trace("My people need me!");
            }
            return;
        }
        if (event.keyCode == Keyboard.DOWN)
        {
            //vy = 5;
            return;
        }
    }

    private function keyUpHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
        {
            vx = 0;
            return;
        }
        if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN)
        {
            //vy = 0;
            return;
        }
    }

    private function removeStageHandler(event:Event):void
    {
        removeEventListener(Event.ENTER_FRAME, frameHandler);
        removeEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
        stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
    }
}

包 {     import flash.display.Sprite;

public class Collision
{
    static public var collisionSide:String = ""; 

    public function Collision()
    {
    }
    static public function block(r1:Sprite, r2:Sprite):Boolean
    {
        var isBlocked:Boolean;
        //Calculate the distance vector
        var vx:Number 
            = (r1.x + (r1.width / 2)) 
            - (r2.x + (r2.width / 2));

        var vy:Number 
            = (r1.y + (r1.height / 2)) 
            - (r2.y + (r2.height / 2));

        //Check whether vx 
        //is less than the combined half widths
        if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
        {
            //A collision might be occurring! Check 
            //whether vy is less than the combined half heights
            if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
            {
                //A collision has ocurred! This is good!

                //Find out the size of the overlap on both the X and Y axes
                var overlap_X:Number 
                = r1.width / 2 
                    + r2.width / 2 
                    - Math.abs(vx);

                var overlap_Y:Number 
                = r1.height / 2 
                    + r2.height / 2 
                    - Math.abs(vy);

                //The collision has occurred on the axis with the
                //*smallest* amount of overlap. Let's figure out which
                //axis that is

                if(overlap_X >=  overlap_Y)
                {
                    //The collision is happening on the X axis
                    //But on which side? _v0's vy can tell us 
                    if(vy > 0)
                    {
                        collisionSide = "Top";

                        //Move the rectangle out of the collision
                        r1.y = r1.y + overlap_Y;
                        //r1 is being blocked
                        isBlocked = true;
                    }
                    else
                    {
                        collisionSide = "Bottom";

                        //Move the rectangle out of the collision
                        r1.y = r1.y - overlap_Y;
                        //r1 is being blocked
                        isBlocked = true;
                    }
                }
                else
                {
                    //The collision is happening on the Y axis
                    //But on which side? _v0's vx can tell us 
                    if(vx > 0)
                    {
                        collisionSide = "Left";

                        //Move the rectangle out of the collision
                        r1.x = r1.x + overlap_X;
                        //r1 is being blocked
                        isBlocked = true;
                    }
                    else
                    {
                        collisionSide = "Right"; 

                        //Move the rectangle out of the collision
                        r1.x = r1.x - overlap_X;
                        //r1 is being blocked
                        isBlocked = true;
                    }
                }
            }
            else
            {
                //No collision
                collisionSide = "No collision";
                //r1 is not being blocked
                isBlocked = false;
            }
        }
        else
        {
            //No collision
            collisionSide = "No collision";
            //r1 is not being blocked
            isBlocked = false;
        }
        return isBlocked;
    }
}

}

1 个答案:

答案 0 :(得分:0)

我认为你想要做的是设置底部限制,但不是硬编码400,对吗?

我会改变你的createFloor方法:

private function createFloor(xPos:Number, yPos:Number):void
{
    var floor:Floor = new Floor();
    addChild(floor);
    floor.x = xPos;
    floor.y = yPos;
    floor.height = 16;
    _floor.push(floor);
    floor.visible = false;

    // set bottom limit here
    bottomLimit = yPos;
}

...那么你不需要将它设置为400。

但是,另一个选择是更改你的if语句:

    if(_mario.y >= Floor(_floor[0]).y)
    {
        _mario.y = Floor(_floor[0]).y;
        vy = 0;
        onGround = true;

    }
    else
    {
        onGround = false;
    }    

...然后你可以完全摆脱bottomLimit变量 (假设我理解你的代码,并且地砖始终位于底部限制)