Как я могу заставить хвост змеи следовать за головой?


10

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

В настоящее время у меня есть голова змеи (простой прямоугольник на данном этапе), которая движется по холсту игры. Самый простой способ построения остальной части змеи - это иметь в голове собственный Java-коллекционный LinkedList SnakeElements, размер которого будет увеличиваться / уменьшаться в зависимости от того, что делает игрок.

Наличие этого списка SnakeElements следует за головой, однако оказалось не тривиальным.

Текущая функция, выполняющая это, выглядит следующим образом и вызывается каждый раз, когда голова обновляет свою позицию:

private void moveTail (float x, float y, int direction) {
    float tmpx, tmpy;
    int tmpdirection;
    int offset_x, offset_y;

    for (SnakeSegment snse : tail) {
        offset_x = 0;
        offset_y = 0;

        tmpx = snse.getX();
        tmpy = snse.getY();
        tmpdirection = snse.getDirection();

        switch(direction) {
            case 0:
                offset_x = 0;
                offset_y = -(2 + snse.width);
                break;
            case 1:
                offset_x = -(2 + snse.width);
                offset_y = 0;
                break;
            case 2:
                offset_x = 0;
                offset_y = (2 + snse.width);
                break;
            case 3:
                offset_x = (2 + snse.width);
                offset_y = 0;
                break;
            default:
                System.out.println("wrong direction");
        }

        snse.setX(x + offset_x);
        snse.setY(y + offset_y);
        snse.setDirection(direction);

        x = tmpx;
        y = tmpy;
        direction = tmpdirection;
    }
}

что, к сожалению, приводит к такому поведению:

GIF

Любые советы о том, как сделать правильно работающий змеиный хвост, будут очень благодарны :)

Ответы:


18

Подумайте о проблеме так:
как змея движется в оригинальной игре?
Змея движется в своем текущем направлении. Поведение выглядит так, будто голова появляется из ничего, а последняя часть хвоста исчезает.

Вы можете иметь список частей змеи. То, что вы хотите сделать, это удалить последний элемент в списке, который представляет последнюю часть хвоста.
Затем вы хотите создать новый заголовок, где он должен быть расположен, и поместить его в первую позицию списка.
Это означает, что оставшаяся часть змеи не перемещается, поскольку вы меняете только первую и последнюю позицию.
Это создает змееподобное поведение.


Оу, спасибо! Это имеет большой смысл и должно было быть идеей с самого начала, похоже, что я немного повеселился бы в рефакторинге :) Мне просто жаль, что моя грустная карма мешает мне отговорить вас. Я обещаю, что вернусь в будущем!
Килиан,

1
Альтернативный способ думать об этом состоит в том, что каждый элемент змеи следует только за элементом непосредственно перед ним, а не за головой. Это будет полезно, если позже змеи будут текстурированы или что-то в этом роде.
Натан Рид

2
Вот текущая версия, кстати, еще раз спасибо :) i.imgur.com/IaT5PNH.gif
Килиан,

1

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

Другими словами, каждая часть змеи была бы Объектом с Позицией (x, y) , ссылкой на часть впереди нее, которую она будет использовать для перемещения, и функцией для обработки позиции части впереди нее и двигаться соответственно. Главная змея (Голова) должна иметь ссылки для каждой части змеи и должна вызывать функцию, ответственную за то, чтобы деталь следовала за своим предшественником, будучи Главой, предшественником первой части.
Надеюсь, поможет!


Это была идея, но обработка углов оказалась довольно сложной. И что произойдет, если игрок повернет на 180 градусов? Мы не были уверены, как правильно с этим справиться, и использование метода, описанного Pontus Magnusson, хорошо решает все эти проблемы.
Килиан

Понимаю. Единственный раз, когда я реализовал систему гусеницы, у меня была сетка с ячейками по размеру частей, поэтому каждая деталь всегда находилась внутри одной конкретной ячейки, таким образом, проблема не возникала. Извините за мой плохой английский.
Линс Ассассино

Ах, да, это имеет смысл и должно также работать, но мы отказались от идеи иметь сетку по причине, которую я сейчас не могу вспомнить;) Спасибо, хотя :)
Kilian
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.