AS3 - Столкновение hitTestObject не регистрируется правильно - PullRequest
1 голос
/ 08 августа 2011

У меня была проблема с обнаружением столкновений hitTestObject пару дней назад, которая с тех пор была исправлена ​​( Как я могу решить мою ошибку исправления нулевого объекта hitTestObject Collision ) с помощью вас, ребята (спасибо) ,

Моя проблема теперь такова:

Когда мой "врага.хит" вступает в контакт с "игрока.хит", он регистрируется как попадание - это хорошо.

Когда мой "building.collide" вступает в контакт с "player.hit", он регистрируется как попадание - это хорошо.

Однако, когда мой "building.collide" вступает в контакт с моим "врага.хит", он не регистрируется, но иногда он регистрируется, даже если единственный враг на экране находится на расстоянии многих пикселей от него - как если бы либо строение или вражеский «хитбокс» находится где-то, кроме непосредственно на графике (в данном случае MovieClip).

Я не понимаю, как это могло быть. У моего вражеского класса есть hit.hitTestObject (player.hit), который отлично работает. В моем классе сборки есть collide.hitTestObject (player.hit), который также отлично работает. Таким образом, это должно привести к тому, что мой класс сборки collide.hitTestObject (врага.hit) также должен работать нормально - но это не так. Есть идеи?

Мой код состоит из примерно 10 файлов .as, и я не совсем уверен, какой из них вызывает проблему. Я не хочу быть грубым и выложу 1000 строк своего любительского кода, чтобы вы могли с ним разобраться - хотя, если понадобится, я сделаю это.

Зеленые части - это хитбоксы (которые являются слоем внутри этого мувиклипа)

gunslingersnapshot

Я надеюсь, что это запутанное описание достаточно просто для подражания. Спасибо за поиск.

Я думаю, что знаю, что происходит, но я не знаю, как это исправить. Я использую класс ObjectPlacer для размещения зданий, флоры, фауны и т. Д., И я считаю, что когда я звоню - var targetCowboy:Cowboy = new Cowboy(stageRef); var enemyJoe:EnemyJoe = new EnemyJoe(stageRef, targetCowboy); var Buildings03Left:BuildingsLeft03 = new BuildingsLeft03(stage, 0, -720, targetCowboy, enemyJoe);<br> stageRef.addChildAt((Buildings03Left), 2); build01Place = false;

То, что это на самом деле создает несколько экземпляров и Cowboy, и EnemyJoe, и это то, что сбивает с толку flash. Как я могу ссылаться на Cowboy и EnemyJoe без использования «new»? (Например, var targetCowboy: Cowboy = new Cowboy (stageRef);)

Код ObjectPlacer:

    package com.gamecherry.gunslinger
    {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class  ObjectPlacer extends MovieClip
{

    private var Build01Timer:Timer;
    private var Build02Timer:Timer;
    private var CactiSet01Timer:Timer;

    private var build01Place:Boolean = false;// if true - addChild starts at first frame
    private var build02Place:Boolean = false;
    private var cactiSet01Place:Boolean = false;
    private var stageRef:Stage;


    public function ObjectPlacer(stageRef:Stage)
    {
        this.stageRef = stageRef;


    var Build01Timer = new Timer(1000, 1);
    var Build02Timer = new Timer(25000, 1);
    var CactiSet01Timer = new Timer(0, 1);


    Build01Timer.addEventListener(TimerEvent.TIMER, build01TimerHandler, false, 0, true);
    Build02Timer.addEventListener(TimerEvent.TIMER, build02TimerHandler, false, 0, true);
    CactiSet01Timer.addEventListener(TimerEvent.TIMER, cactiSet01TimerHandler, false, 0, true);

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

        Build01Timer.start();
        Build02Timer.start();
        CactiSet01Timer.start();
    }


    public function loop(e:Event): void
    {
        BuildSet01();
        BuildSet02();
        CactiSet01();

    }   

    private function BuildSet01(): void
    {

        if (build01Place)
        {
        var Buildings01Right:BuildingsLeft = new BuildingsLeft(stage, 720, -624);   
        Buildings01Right.scaleX = -1;
        stageRef.addChildAt((Buildings01Right), 2);

        var targetCowboy:Cowboy = new Cowboy(stageRef);
        var enemyJoe:EnemyJoe = new EnemyJoe(stageRef, targetCowboy);
        var Buildings03Left:BuildingsLeft03 = new BuildingsLeft03(stage, 0, -720, targetCowboy, enemyJoe);              
        stageRef.addChildAt((Buildings03Left), 2);
        build01Place = false;


        }

    }

    private function BuildSet02(): void
    {

        if (build02Place)
        {

        var Buildings04Left:BuildingsLeft04 = new BuildingsLeft04(stage, 0, -800);
        stageRef.addChildAt((Buildings04Left), 2);
        build02Place = false;
        }
    }

    private function CactiSet01(): void
    {
        if (cactiSet01Place)
        {
            var cactus01:GScactus01 = new GScactus01(stage, 0, 300);
            stageRef.addChildAt((cactus01), 2);
            var cactus01b:GScactus01 = new GScactus01(stage, 190, 50);
            stageRef.addChildAt((cactus01b), 2);
            var cactus01c:GScactus01 = new GScactus01(stage, 660, -40);
            stageRef.addChildAt((cactus01c), 2);
            cactus01c.scaleX = -1;
            var cactus01d:GScactus01 = new GScactus01(stage, 710, 340);
            stageRef.addChildAt((cactus01d), 2);
            cactus01d.scaleX = -1;
            var cactus02:GScactus02 = new GScactus02(stage, 420, -50);
            stageRef.addChildAt((cactus02), 2);
            var cactus02b:GScactus02 = new GScactus02(stage, 600, 180);
            stageRef.addChildAt((cactus02b), 2);
            var cactus02c:GScactus02 = new GScactus02(stage, 300, 240);
            stageRef.addChildAt((cactus02c), 2);
            var cactus03:GScactus03 = new GScactus03(stage, 540, 100);
            stageRef.addChildAt((cactus03), 2);
            var cactus03b:GScactus03 = new GScactus03(stage, 30, 5);
            stageRef.addChildAt((cactus03b), 2);
            cactus03b.scaleX = -1;
            var cactus03c:GScactus03 = new GScactus03(stage, 520, 420);
            stageRef.addChildAt((cactus03c), 2);

            cactiSet01Place = false;
        }
    }



    private function build01TimerHandler(e: TimerEvent) : void
    {
        build01Place = true;
    }
    private function build02TimerHandler(e: TimerEvent) : void
    {
        build02Place = true;
    }


    private function cactiSet01TimerHandler(e: TimerEvent) : void
    {
        cactiSet01Place = true;
    }











    private function removeSelf() : void
    {
        removeEventListener(Event.ENTER_FRAME, loop);

        if (stageRef.contains(this))
        stageRef.removeChild(this); 
    }   

}

}

Ответы [ 2 ]

1 голос
/ 08 августа 2011

Следует опасаться, что hitTestObject вызывает AABB (ограничивающий ось ограничивающий прямоугольник) столкновение , что означает, что оно соответствует прямоугольнику вокруг вашего объекта и использует его для проверки на столкновения.Ваши здания, кажется, имеют сложные, вогнутые формы - hitTestObject не будет принимать их во внимание, он просто наматывает гигантский прямоугольник на здание и использует его для проверки.Также обратите внимание, что если collide - это один MovieClip со всеми областями застройки внутри него, то прямоугольник будет намотан на всю эту область, а не на отдельные области для отдельных зданий.Вам придется разделить области столкновения на отдельные прямоугольники и проверить их по отдельности.Вероятно, именно поэтому вы видите некоторые ложные срабатывания и плохое поведение.

hitTestPoint будет учитывать форму объекта и выполнять идеальное столкновение пикселей, если для параметра shapeFlag установлено значениеправда, но это будет проверять только одну точку.Чтобы проверить большую форму, вы можете попробовать сделать несколько вызовов hitTestPoint итеративно.Если этого недостаточно, изучите более сложные методы столкновения.Проверьте этот набор учебных пособий от создателей N.

0 голосов
/ 08 августа 2011

Я давно отказался от встроенных функций вспышки для обнаружения столкновений в пользу моей собственной системы, которая использует теорему о разделении осей для AABB или использует что-то вроде Box2D для управления физикой для меня.

У меня никогда не было успеха ни с hitTestPoint, ни с hitTestObject, но вы можете обнаружить, что bitmapData.hitTest будет работать для вас (никогда не использовал его), или вы можете использовать систему сетки на основе прямоугольников для всего, что является что я делаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...