Пропустить конкретную итерацию в цикле FOR - PullRequest
0 голосов
/ 16 сентября 2018

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

Я пытаюсь вставить иконку для игрока. Вместо того, чтобы изменять данные карты, я хотел бы реализовать их полностью в графической подпрограмме.

Прямо сейчас отображается значок, но он отодвигает всю графическую строку на один пробел. Я бы хотел, чтобы он пропускал плитку, над которой находится игрок, но единственный способ сделать это, похоже, сделать что-то похожее на команду «СЛЕДУЮЩИЙ» в «Бейсике». Я не знаю о Пакетном эквиваленте, поэтому я пришел сюда за помощью. Мне нужно пропустить определенную итерацию цикла FOR после отрисовки тайла игрока.

Это не будет иметь большого смысла без значительного количества контекста, но вот подпрограмма в ее нынешнем виде:

:D
REM Draw tiles
IF /I %OSV% LSS 3 (
FOR /L %%G IN (0,1,31) DO (
    REM Old tileset
    IF "%2" == "1" IF "%%G" == "%X%" CALL :C 0C "i" & REM skip the rest
    IF "!M%MAP%%1:~%%G,1!" == "0" CALL :C 00 " "
    IF "!M%MAP%%1:~%%G,1!" == "1" CALL :C 2A "w"
    IF "!M%MAP%%1:~%%G,1!" == "2" CALL :C 87 "S"
    IF "!M%MAP%%1:~%%G,1!" == "3" CALL :C 6E "W"
    IF "!M%MAP%%1:~%%G,1!" == "4" CALL :C 0A "T"
    IF "!M%MAP%%1:~%%G,1!" == "5" CALL :C 0A "n"
    IF "!M%MAP%%1:~%%G,1!" == "6" CALL :C 6E "H"
    IF "!M%MAP%%1:~%%G,1!" == "7" CALL :C 91 "m"
    IF "!M%MAP%%1:~%%G,1!" == "8" CALL :C 19 "m"
    IF "!M%MAP%%1:~%%G,1!" == "9" CALL :C B3 "M"
    IF "!M%MAP%%1:~%%G,1!" == "A" CALL :C 4C "m"
    IF "!M%MAP%%1:~%%G,1!" == "B" CALL :C C4 "M"
    IF "!M%MAP%%1:~%%G,1!" == "C" CALL :C 6E "O"
    IF "!M%MAP%%1:~%%G,1!" == "D" CALL :C 6E "W"
    IF "!M%MAP%%1:~%%G,1!" == "E" CALL :C 78 "W"
    IF "!M%MAP%%1:~%%G,1!" == "F" CALL :C 0D "X"
    IF "!M%MAP%%1:~%%G,1!" == "G" CALL :C 6E "E"
    IF "!M%MAP%%1:~%%G,1!" == "H" CALL :C 48 "E"
    IF "!M%MAP%%1:~%%G,1!" == "I" CALL :C 68 "n"
    IF "!M%MAP%%1:~%%G,1!" == "J" CALL :C 6E "m"
    IF "!M%MAP%%1:~%%G,1!" == "K" CALL :C E6 "W"
    IF "!M%MAP%%1:~%%G,1!" == "L" CALL :C 6A "T"
    IF "!M%MAP%%1:~%%G,1!" == "M" CALL :C 2A "w"
    IF "!M%MAP%%1:~%%G,1!" == "N" CALL :C 87 "S"
    IF "!M%MAP%%1:~%%G,1!" == "O" CALL :C 0D "i"
    IF "!M%MAP%%1:~%%G,1!" == "P" CALL :C 6A "Y"
    IF "!M%MAP%%1:~%%G,1!" == "Q" CALL :C BF "C"
)
)
GOTO :EOF

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

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

Переменные, переданные функции:

  • % 1 - значение Y для рисования
  • % 2 - игрок с этим значением Y

Нет выходов, кроме терминала, через функцию C, которая просто рисует цветной символ.

Любые идеи были бы великолепны.

РЕДАКТИРОВАТЬ: Вот некоторые примеры вывода без значка игрока. Красные буквы обозначают положение игрока. Я хотел бы заменить плитку в этой позиции на иконку игрока.

Скриншот Overworld

Overworld screenshot

Скриншот пустыни

Desert screenshot

1 Ответ

0 голосов
/ 16 сентября 2018

Вы не создали MCVE, и ваш код не имеет смысла, поскольку, если он останавливается после строки 6 th , остальное просто бесполезно, и нет необходимости выполнять цикл 32 раза. Таким образом, это всего лишь пример

Чтобы предотвратить запуск блока при выполнении условия, просто инвертируйте условие

FOR /L %%G IN (0,1,31) DO (
    rem Things that will done every time
    IF NOT "%%G" == "6" (do something) else (
        rem Things that will be done when %%G != 6
        rem i.e. if %%G != 6 next
    )
)

В этом случае, если вы хотите пропустить оставшиеся команды, когда условия в первой строке выполняются, то

FOR /L %%G IN (0,1,31) DO (
    IF "%2" == "1" IF "%%G" == "%X%" (CALL :C 0C "i") ELSE (
        IF "!M%MAP%%1:~%%G,1!" == "0" CALL :C 00 " "
        IF "!M%MAP%%1:~%%G,1!" == "1" CALL :C 2A "w"
        IF "!M%MAP%%1:~%%G,1!" == "2" CALL :C 87 "S"
        IF ...
    )
)

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

IF /I %OSV% LSS 3 (
    IF "!M%MAP%%1:~0,1!" == "0" (call :checkplayer %2 %%G %X% || CALL :C 00 " ")
    IF "!M%MAP%%1:~1,1!" == "1" (call :checkplayer %2 %%G %X% || CALL :C 2A "w")
    IF "!M%MAP%%1:~2,1!" == "2" (call :checkplayer %2 %%G %X% || CALL :C 87 "S")
    ...
)

:checkplayer
IF "%1" == "1" IF "%2" == "%3" (
    CALL :C 0C "i"
    exit /b 0
) ELSE (
    exit /b 1
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...