Обнаружение столкновений во Flash или лучший способ сделать это

Я пытаюсь создать аэрохоккей во флэш-памяти с использованием AS3.

На данный момент я использую функцию ввода кадра, чтобы проверить расположение 3 объектов, 2 лопастей и мяча, затем он проверяет, находятся ли они в контакте, и если они есть, то инициирует функцию обнаружения столкновения.

Однако он проверяет каждый раз, когда загружается кадр, и при 25 кадрах в секунду это довольно много, и приложение лагает.

Любые идеи или лучшие способы сделать это?

Заранее спасибо.


person S1syphus    schedule 04.01.2011    source источник
comment
Как устроена остальная часть вашей игры? У вас есть один цикл рендеринга? Сложные ли игровые спрайты или они представляют собой простой прямоугольник/круг? Как вы рассчитываете обнаружение столкновений? Используете ли вы встроенные функции или выполняете свои собственные расчеты?   -  person weltraumpirat    schedule 04.01.2011
comment
На данный момент спрайты очень простые, три круга. Обнаружение столкновений, сделал я сам, проверяет расстояние между двумя кругами, смотрите, равно ли оно радиусу двух кругов.   -  person S1syphus    schedule 04.01.2011
comment
Я бы не подумал, что запуск этого в каждом кадре будет очень дорогим, поскольку это всего несколько объектов. Я бы придерживался использования вычислений радиуса, но что касается оптимизации, вы можете убедиться, что вы выходите из своей сравнительной логики там, где это имеет смысл. IE) если скорость всех предметов равна 0. если шайба находится на левой половине, то не нужно проверять правую ракетку (если вы придерживаетесь правил аэрохоккея!), и т.д..   -  person gthmb    schedule 04.01.2011


Ответы (3)


Два утверждения Пифагора замедляют вашу игру? При 25 кадрах в секунду? Что-то не так. Это не должно быть так.

Полностью удалите обнаружение столкновений и убедитесь, что вы вернули свои 25 кадров в секунду, затем добавляйте операторы по строке за раз, пока замедление не появится снова.

Убедитесь, что вы не вызываете свой код столкновения более одного раза (ну, два раза) за кадр.

Помните, что вы можете проверить конфликты без использования Math.sqrt:

function circlesTouching(circle1:Point, circle1Radius:Number, circle2:Point, circle2Radius:Number):Boolean {
    var dx:Number = circle1.x - circle2.x;
    var dy:Number = circle1.y - circle2.y;
    var minDist:Number = circle1Radius + circle2Radius;
    return (dx*dx) + (dy*dy) < (minDist * minDist);
}

(Вам все равно понадобится sqrt для разрешения коллизии, но это должно быть довольно редко.)

Однако, по моему опыту, даже несмотря на то, что Math.sqrt является самой медленной частью Pythagoras, ее все же достаточно для обработки двух вызовов на кадр со скоростью 25 кадров в секунду. Похоже, что-то еще не так.

person Chris Burt-Brown    schedule 04.01.2011

Если вам нужно периодически что-то проверять, я думаю, что событие enterFrame является подходящим механизмом для этого.

Вы не упомянули, используете ли вы встроенные функции проверки попадания или нет, поэтому я решил упомянуть их: hitTestObject и hitTestPoint.

person Lars Blåsjö    schedule 04.01.2011
comment
Не использовал hitTestObject, так как он включает ограничивающую рамку... потому что это были круги, думал, что будет легче проверить, является ли расстояние суммой радиусов двух окружностей. - person S1syphus; 04.01.2011

Вы пробовали таймер?

var timer:Timer = new Timer(250); // 4 times a second

timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();


private function onTimer(ev:TimerEvent):void
{
  checkCollision();
}
person Roy    schedule 04.01.2011