Каков наилучший способ запрограммировать путь пули? - PullRequest
1 голос
/ 08 ноября 2010

Я играю с ActionScript 3 и пытаюсь создать очень простой прототип для видеоигры (экшен / шутер сверху вниз) и понял, что обработка пуль немного сложнее, чем я себе представлял.

Чтобы получить довольно приличный «полет» пули между персонажем и целью, я использовал сильно модифицированную версию Алгоритма линии Брезенхема для определения траектории полета пули, а затемпросто нарисуйте крошечный объект flash.geom.Rectangle в соответствующем месте на этой «траектории полета» во время этапа рисования моего приложения.

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

Чего мне здесь не хватает?Я на самом деле не разработчик игр, и поэтому большинство вещей, которые я делаю, я просто «придумал» на месте, но я не могу понять, как эффективно обращаться с пулями во Flash.

РЕДАКТИРОВАТЬ : В соответствии с просьбой, вот "мой" код Брезенхэма.Я говорю «мой» в кавычках, потому что я в основном разорвал это где-то в Интернете.Мои изменения в алгоритме в основном затрагивают строки внизу.Первоначальная реализация нашла бы путь от персонажа игрока к цели, за исключением того, что время от времени (и я потратил немного времени, пытаясь выяснить это, но никогда никуда не попал), он будет генерировать путь от цели кигрок.Чтобы «исправить» это, я закончил тем, что просто проверял первые значения X / Y из массива path и обращал массив, если эти значения не соответствовали значениям X / Y моего игрового персонажа.

public function bresenham(fromX:int, fromY:int, toX:int, toY:int, value:int):Array
{
    // store the character's location
    var orig_x:int = fromX;
    var orig_y:int = fromY;

    var error:int;
    var bullet_path:Array = new Array;

    var dx:int = toX - fromX;
    var dy:int = toY - fromY;
    var yi:int = 1;
    if ( dx < dy ) {
        // swap end points
        fromX ^= toX; toX ^= fromX; fromX ^= toX;
        fromY ^= toY; toY ^= fromY; fromY ^= toY;
    }

    if ( dx < 0 ) {
        dx = -dx;
        yi = -yi;
    }
    if ( dy < 0 ) {
        dy = -dy;
        yi = -yi;
    }
    if ( dy > dx ) {
        error = -( dy >> 1 );
        for ( ; toY < fromY; toY++ ) {
            bullet_path.push( { 'x' : toX, 'y': toY } );
            error += dx;
            if ( error > 0 ) {
                toX   += yi;
                error -= dy;
            }
        }
    } else {
        error = -(dx >> 1);
        for ( ; fromX < toX; fromX++ ) {
            bullet_path.push( { 'x' : fromX, 'y': fromY } );
            error += dy;
            if ( error > 0 ) {
                fromY += yi;
                error -= dx;
            }
        }
    }
    // reverse the bullet path if it was generated from target to player.
    if ( bullet_path[0].x != orig_x && bullet_path[0].y != orig_y ) {
        return bullet_path.reverse();
    }
    return bullet_path;
}

Ответы [ 4 ]

1 голос
/ 09 ноября 2010

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

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

Вы также должны проверить GameDev.Stackexchange.com, так как многие люди более квалифицированы, чтобы отвечать на вопросы Game Dev.

1 голос
/ 08 ноября 2010

Можете ли вы опубликовать свой код реализации (Брезенхэма) здесь? Я хотел бы сделать тест производительности, если моя реализация будет быстрее: D ...

Странная вещь - я ДЕЙСТВИТЕЛЬНО проводил сравнение, сравнивая мою реализацию с нативной Graphics.drawLine () AS3.0. Это было буквально в 5-10 раз быстрее. Это даже сглаживание, но я думаю, что здесь делает дело Рождество.

Но в любом случае - до тех пор, пока пули ... Скажем, MISSILES (пули, ракеты, лазеры ...), здесь нет ничего медленно движущегося, большого, который должен выглядеть тоже хорошо (не только линии), используйте MovieClip или даже лучше Sprite , когда анимация не требуется. В другом месте используйте Graphics.drawLine () .

Кроме того, для проверки попадания с помощью линий и поиска точек, на которых можно нарисовать линии (не Спрайты ), у вас будет диапазон этой пули (если он бесконечный, используйте что-то вроде Stage.width , или Stage.height , если он больше), где он все еще может попасть. Тогда у тебя тоже будет свой угол. Если это вдоль осей X или Y, довольно легко получить точки линии. Для различных используйте Point.polar (диапазон, угол) [liveDocs] , к которому вы добавляете исходную позицию этой пули.

Тестирование попаданий будет выполнено с помощью Point.interpolate () [liveDocs] . Точка 1 будет исходной позицией / начальной точкой, вторая - точкой, полученной из Point.polar () . Наконец, последним параметром должно быть расстояние от начала (здесь не нужно Math.atan2 () - просто увеличьте это значение каждый кадр на скорость пули), деленное на расстояние между начальной и конечной точками (снова , нет Math.atan2 () - только «диапазон». Этот Point.interpolate () даст вам точку, которую вы, наконец, будете использовать с каждой возможной целью для пули (либо переберите все, либо, для производительности, проверьте, меньше ли расстояния X и Y или равны их ширине и высоте) - target.hitTestPoint (interX, interY, true) [liveDocs ] .

0 голосов
/ 08 ноября 2010

Определите расстояние, которое пуля должна пройти в каждом кадре, и отпустите. Если каждая пуля знает, как далеко она должна продвинуться по своим свойствам x и y на кадр, вам не нужно вычислять ее снова, и пуля будет лететь прямо. Если вы используете линейный алгоритм Брезенхэма каждый раз, когда пуля движется, вы выполняете много работы. Просто убедитесь, что движение по x и y сохранено как число, иначе пуля не окажется там, где должна.

0 голосов
/ 08 ноября 2010

Независимо от того, что вы делаете, слишком много актеров на сцене будут ухудшать производительность.Я лично попытался бы создать экземпляры символов в виде movieClips и перемещать их по пути, удаляя их, когда они вступают в контакт с целью.(Делая это таким образом, вы также обнаруживаете столкновения, что будет важно, если цели могут сойти с дороги. При обнаружении столкновения пуля может воспроизвести сцену «взрыва» и т.

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