AS3 Персонаж останавливается только у стен в одном направлении - PullRequest
2 голосов
/ 20 октября 2011

Я перепробовал почти все, чтобы мой персонаж остановился, когда обнаружил стену. Это работает только для ВВЕРХ и ВПРАВО или ВНИЗ и ВЛЕВО, но не для всех четырех направлений, поэтому только одно движение y и одно движение x. Поэтому я решил сделать 4 функции, по одной для каждого направления. Но тогда это работает только тогда, когда левая клавиша нажата и ударяется о стену.

Мой вопрос к вам; Что мне нужно сделать, чтобы обнаружение столкновений остановило движение персонажа во всех 4 направлениях? Заранее спасибо

var leftArrow:Boolean;
var upArrow:Boolean;
var rightArrow:Boolean;
var downArrow:Boolean;
var speed:int = 10;
var hitting:Boolean;
var ismoving:Boolean;
var wallsRect:Rectangle = bounds.getBounds(this);
var charRect:Rectangle = char.getBounds(this);

var boundsBmpData = new BitmapData(wallsRect.width, wallsRect.height, true, 0);
var charBmpData = new BitmapData(charRect.width, charRect.height, true, 0);

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.ENTER_FRAME, detectHit2);
stage.addEventListener(Event.ENTER_FRAME, walkingLEFT);
stage.addEventListener(Event.ENTER_FRAME, walkingUP);
stage.addEventListener(Event.ENTER_FRAME, walkingDOWN);
stage.addEventListener(Event.ENTER_FRAME, walkingRIGHT);

boundsBmpData.draw(bounds);
charBmpData.draw(char);

function keyPressed(event:KeyboardEvent):void 
    {
        if (event.keyCode == Keyboard.LEFT) 
            {
                leftArrow = true;

            }
        if (event.keyCode == Keyboard.UP) 
            {
                upArrow = true;
            }
        if (event.keyCode == Keyboard.RIGHT) 
            {
                rightArrow = true;
            }
        if (event.keyCode == Keyboard.DOWN) 
            {
                downArrow = true;
            }


    }





function keyReleased(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT) 
            {
                leftArrow = false;

            }
        if (event.keyCode == Keyboard.UP) 
            {
                upArrow = false;
            }
        if (event.keyCode == Keyboard.RIGHT) 
            {
                rightArrow = false;

            }
        if (event.keyCode == Keyboard.DOWN) 
            {
                downArrow = false;
            }
    }


function walkingLEFT(event:Event):void 
{
    if (leftArrow && ! hitting) 
        {
            char.x -= speed;

        }else
                                {
                                    hitting = false;
                                    ismoving = false;

                                }
}

function walkingRIGHT(event:Event):void 
{
    if (rightArrow && ! hitting) 
        {
            char.x += speed;

        }else
                                {
                                    hitting = false;
                                    ismoving = false;

                                }
}


function walkingUP(event:Event):void
{

                    if (upArrow && ! hitting)
                        {
                            char.y -= speed;

                        }
                            else
                                {
                                    hitting = false;
                                    ismoving = false;

                                }
                }

function walkingDOWN(event:Event):void
{

                    if (downArrow && ! hitting)
                        {
                            char.y += speed;

                        }
                            else
                                {
                                    hitting = false;
                                    ismoving = false;

                                }
                }




function detectHit2(e:Event):void
{
    if(boundsBmpData.hitTest(new Point(bounds.x, bounds.y),
                                255,
                                charBmpData,
                                new Point(char.x, char.y),
                                255))
        {

            hitting = true;
            ismoving = false;

        }
            else 
                { 

                      hitting = false;

                      bounds.filters = [];
                }
        }

Ответы [ 2 ]

2 голосов
/ 23 октября 2011

Вышеприведенный код действительно не будет работать для всех остальных направлений, затем оставленных.

Порядок вызовов слушателя такой же, как вы их добавили.

Итак, сначала DetectHit2 ()выполняется, в результате чего будет установлено значение «истина» в случае наложения.

Следующий левый проверяется с помощью walkLEFT ();если пользователь не нажимает влево, переменная ударная установка снова устанавливается в ложное значение.

При использовании дополнительных методов walkXXXX () ударная установка будет ложной, и координата всегда будет корректироваться при нажатии конкретной клавиши.

Как и в предыдущем ответе, попробуйте использовать 1 прослушиватель одного события.

Примерно так:

this.addEventListener(Event.ENTER_FRAME, handleEnterFrame);

function handleEnterFrame(anEvent: Event): void
{
  var newx: Number = char.x - (leftArrow ? speed : 0) + (rightArrow ? speed : 0);
  var newy: Number = char.y - (upArrow ? speed : 0) + (downArrow ? speed : 0);
  if(!boundsBmpData.hitTest(new Point(bounds.x, bounds.y),
                            255,
                            charBmpData,
                            new Point(newx, newy),
                            255))
  {
     char.x = newx;
     char.y = newy;
  }
}

Если вы разрешите своему игроку нажимать несколько клавиш направления, вывозможно, потребуется уточнить приведенный выше код, скорректировав сначала X, а затем Y-координату (поэтому требуется два раза вызвать hitTest).Таким образом, символ скользит по стенам, когда пользователь нажимает две клавиши со стрелками, и одна из этих клавиш продолжает врезаться в стену.

1 голос
/ 20 октября 2011

Ваш код немного spagetti-y и поэтому трудно следовать, но я бы попытался переместить весь код ENTER_FRAME в одну функцию вместо 5. Это исключило бы любую возможность вызова функций в порядке, который вы не делаете ожидать.

...