as3 hitTestObject(), чтобы поразить все

В моей игре есть человек, который стреляет, и мне нужно, чтобы пуля попала во что-нибудь, чтобы удалить спрайт.

var i = 1;
var f:Function;
addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, f = function(){ 
    bullet.x += movex*i;
    bullet.y += movey*i;
    i++;
});

Как сделать hitTestObject() со всем?


person Andrey    schedule 30.12.2012    source источник


Ответы (3)


Существует множество методов обнаружения столкновений, однако используемый метод зависит от формы целевого объекта. Pixel perfect hittesting — самый точный метод обнаружения столкновений, хотя и очень медленный. Геометрическое тестирование, вероятно, является самым быстрым и может быть очень точным, если все сделано правильно. Одним из недостатков использования hitTestObject является то, что он довольно медленный. Поэтому мое мнение, если вам нужно обрабатывать большой пул объектов, заключается в использовании альтернативных методов обнаружения столкновений.

Определенно, для обнаружения столкновений объекта с объектом вам необходимо перебрать каждый целевой объект, помещенный в массив (но для повышения производительности в <Vector>), и проверить, попадает ли пуля в целевой объект.

bullet.addEventListener(Event.ENTER_FRAME, testCollision);

private function testCollision(e: Event) {        
    bullet.x += moveX*i;
    bullet.y += moveY*i;

    for (var j = 0; j < objects.length; j++) {     
        if (bullet.hitTestObject(objects[j])) {
            // Do something
        }
    }

    i++;
};

Стоит прочитать эти статьи для дальнейших объяснений:

http://plasticsturgeon.com/2011/03/actionscript-collision-detection-u-circle-circle-collision-detection/

http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/

http://www.mikechambers.com/blog/2009/06/25/strategies-for-optimizing-collision-detection-with-bitmapdata-hittest/

А вот библиотека, которая выполняет тяжелую работу: http://code.google.com/p/collisiondetectionkit/

person Endre Simo    schedule 30.12.2012
comment
как я могу использовать эту библиотеку (ничего в вики) - person Andrey; 30.12.2012
comment
Вот очень краткое описание того, как вы можете его использовать: stanford.edu/~ алипер/EPGY/сэмплы/ - person Endre Simo; 30.12.2012

Я бы решил это так (я предполагаю, что пули - это мувиклипы, которые вы добавляете из библиотеки).

Я использую зомби и растения в качестве примеров мувиклипов, уже находящихся на сцене, которые вы вручную передаете в массив liveObjects.

Для более масштабных игр, очевидно, вы не будете жестко кодировать, но я пытаюсь убрать лишнее, чтобы сделать пример более понятным)

import flash.events.Event;
import flash.display.MovieClip;

var liveObjects:Array = [
  zombie1, // A MovieClip on the stage
  zombie2, // ditto
  zombie3, // ditto
  plant1,  // ditto
  plant2   // ditto
];

// Create bullet
var bullet:Bullet = new Bullet();
bullet.x = 200;
bullet.y = 200;
addChild( bullet );
bullet.addEventListener( Event.ENTER_FRAME, f );

var i:int = 1;
var moveX:int = 1;
var moveY:int = 1;
function f( e:Event ){ 
  var thisBullet:MovieClip = ( e.currentTarget as MovieClip );
  thisBullet.x += moveX * i;
  thisBullet.y += moveY * i;
  i++;

  for( var j:int; j < liveObjects.length; j++ ) {
    if( thisBullet.hitTestObject( liveObjects[ j ] ) ) {
        trace( "Hit " + liveObjects[ j ] );
    }
  }
};
person Chris    schedule 30.12.2012
comment
Было бы полезно, если бы я действительно добавил их с помощью MovieClip (я делаю это со спрайтом). В любом случае, спасибо за помощь, я думаю, что воспользуюсь ею позже в игре. - person Andrey; 30.12.2012
comment
Я могу неправильно истолковать ваше намерение, но ваш код, похоже, рекомендует добавлять отдельный прослушиватель ENTER_FRAME для каждой пули в игре, а не одиночный игровой цикл? Могу я спросить, почему? - person Jimbo Jonny; 30.12.2012
comment
Я далек от того, чтобы рекомендовать это, но я расширяю код, указанный в вопросе. Возможно, в его случае у него есть только 1 пуля (я не знаю, потому что он не обрисовал это в общих чертах) - поэтому мне нужно исходить из предположения, что он знает свой проект и решил добавить прослушиватель событий к пуле, после который я расширил код, чтобы ответить на вопрос о тестах попаданий (а не об прослушивателях событий). Но я полностью согласен с игровыми циклами - person Chris; 31.12.2012

Надеюсь, у вас есть массив, содержащий ссылки на все вражеские спрайты. Просто прокрутите этот вызов hitTestObject() с помощью пули.

person mitim    schedule 30.12.2012