Автосохранение в пакетной текстовой приключенческой игре?

Я создаю игру Text Adventure, используя пакетный скрипт, и хотел бы знать, есть ли способ запрограммировать ее на автоматическое сохранение в определенный момент.
Я спрашиваю об этом, так как недавно прочитал, что < em>youtuber однажды запрограммировал автосохранение одной из своих ролевых игр, но никогда не раскрывал этого публично.

Итак, есть ли способ заставить пакетную ролевую/текстовую адвенчуру публиковать автосохранения? Если так, то как ты это делаешь?


person Jackson Fydor    schedule 04.08.2013    source источник
comment
Начните с перехода на реальный язык программирования.   -  person Blender    schedule 04.08.2013
comment
Подождите, вы имеете в виду, что я должен изучать другой язык программирования, чтобы знать пакет?   -  person Jackson Fydor    schedule 04.08.2013
comment
@JacksonFydor - Нет, он говорит создать эту приключенческую ролевую игру на таком языке, как Python, Java и т. д. Кстати, тег RPG предназначен для генератора программ отчетов, а не для ролевых игр. Игра.   -  person s0d4pop    schedule 04.08.2013
comment
О, простите меня, я здесь новенький. Но разве не грубо просто сказать кому-то перейти на другой язык программирования? Он мог бы использовать более приятные слова, чтобы описать то, что он говорил. Все, что я хочу, это просто ответ да или нет.   -  person Jackson Fydor    schedule 04.08.2013
comment
@JacksonFydor: не будет грубым сказать вам, что вы делаете что-то с неправильными инструментами.   -  person Blender    schedule 04.08.2013
comment
Что ж, лично мне нравится использовать пакетную программу для запуска моей игры, и если вы скажете, что это неправильный инструмент, что вы предложите?   -  person Jackson Fydor    schedule 04.08.2013
comment
@JacksonFydor: что-нибудь еще. Я бы использовал Python.   -  person Blender    schedule 04.08.2013


Ответы (3)


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

С процедурными языками я придерживался аналогичной структуры на протяжении десятилетий. Суть в том, чтобы иметь только ОДНУ процедуру, взаимодействующую с пользователем. Остальная часть программы затем становится конечным автоматом, направляемым из одного состояния в другое в ответ на ввод пользователя. Это может занять некоторое время, но я успешно (и быстро) разрабатывал программы, использующие этот принцип в пакетном режиме, коболе, паскале, базовом, прогрессе, богомоле и других.

@ECHO OFF
SETLOCAL
SET state=0
SET "savefile="
:mainloop
CALL :state%state%
IF %state% neq 999999 GOTO mainloop
GOTO :EOF

::
:: USER I/O
::

:userio
IF NOT DEFINED savefile GOTO useriolp
set>%savefile%
:useriolp
SET "response="
SET /p response="%message% ? "
IF NOT DEFINED response GOTO useriolp
SET response=%response: =_%
FOR %%r IN (EXIT quit) DO IF /i %response%==%%r SET state=999999&GOTO :EOF
SET "state="
FOR %%r IN (%vr%) DO IF DEFINED state (
 IF /i %%r==%response% GOTO :EOF
 SET "state="
) ELSE (SET state=%%r)
IF DEFINED state GOTO :eof
ECHO Invalid response
GOTO useriolp

::State 0 - get username

:state0
SET "vr=100"
SET message=Your name
GOTO userio

:: State 100 - have username.
:: Load user's savefile if it exists

:state100
SET savefile=%response%
IF exist %savefile% GOTO S100.1

:: New game - initialise data
:: set start-state in STATE

SET example=exampledata

SET state=1000
GOTO :eof

:: Load game - including STATE

:S100.1
SET "state="
FOR /f "tokens=1*delims==" %%i IN (%savefile%) DO IF NOT defined %%i SET %%i=%%j

GOTO :eof

:: State 1000 - start game

:state1000

::  ** Just for a demo, show example as loaded from savefile

ECHO example=%example%

ECHO You see a shimmering blue-hued house with four doors numbered 1,2,3 and 4
SET "vr=1001 1 1002 2 1003 3 1004 4 1001 one 1002 two 1003 three 1004 four"
SET message=Which door do you choose
GOTO userio

:: State 1001 - door 1

:state1001
ECHO You see John Lodge
SET example=John Lodge
:: OK, from here, you're on your own. I'll force a state and loop
SET state=1000
GOTO :eof


:: State 1002 - door 2

:state1002
ECHO You see Graeme Edge
SET example=Graeme Edge
:: OK, from here, you're on your own. I'll force a state and loop
SET state=1000
GOTO :eof


:: State 1003 - door 3

:state1003
ECHO You see Justin Hayward
SET example=Justin Hayward
:: OK, from here, you're on your own. I'll force a state and loop
SET state=1000
GOTO :eof


:: State 1004 - door 4

:state1004
ECHO You see Ray Thomas
SET example=Ray Thomas
:: OK, from here, you're on your own. I'll force a state and loop
SET state=1000
GOTO :eof

С приведенным выше кодом вы можете увидеть скелет. :mainloop просто устанавливает «повторять до тех пор, пока exitstructure, whereEXIT» не станет состоянием = 999999. Я использовал числа для штатов, но это просто вопрос выбора.

Для любого конкретного состояния вы (необязательно) что-то делаете, затем настраиваете подсказку (не называйте ее prompt — это пакетное ключевое слово) и набор допустимых ответов (vr легче ввести, чем valid_responses), затем переходите к :userio процедура (которая возвращается к :mainloop после принятия ответа.

:userio сохраняет всю текущую среду (поэтому имеет функцию «автосохранения»), затем запрашивает сообщение и принимает ответ. Set /p оставит response без изменений, если нажать enter, поэтому установка response на [ничего] сначала гарантирует, что enter не будет повторять предыдущий ответ.

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

Затем, если пользователь вводит ВЫХОД или ВЫХОД, назначается состояние выхода.

В противном случае строка действительных ответов сопоставляется с полученным ответом. Строка vr просто

nextstate ifthisresponse nextstate ifthisresponse nextstate ifthisresponse nextstateotherwise

nextstate в противном случае не должен появляться, и если это не так, генерируется сообщение invalid response и повторно запрашивается ввод.

Итак, из состояния 0 вам будет предложено ввести ваше имя, а следующее состояние будет равно 100 независимо от этого.

State100 устанавливает savefile в ответ пользователя (имя), и если этот файл существует, любая переменная, записанная в файле сохранения, перезагружается в среду, восстанавливая игру до ее точного состояния, когда в последний раз программа была EXITed. Если файл не существует, то у вас есть возможность установить любые необходимые игровые данные - я только что установил переменную example в качестве примера.

State1000 запускает игру. Я только что показал значение example в демонстрационных целях. Он должен начинаться как exampledata, как установлено в state100-no-savefile. Итак, вы получаете описание сценария, устанавливаете подсказку и vr определяет следующее состояние как 1001, если ваш ответ (1 или один); 1002 за (2 или два)...

Выбор 1,2,3 или 4 переключает вас в следующее состояние; строка example изменена, и - ну, я заставил state1000 быть пунктом назначения. Что бы вы сделали, так это просто следили бы за прыгающим мячом в состоянии 1000.

Теперь - если вы наберете exit, программа завершится. Повторно запустите и введите то же имя пользователя, и значение example будет отображаться как последнее установленное значение, восстановленное из файла сохранения.

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

IF /i %response%==help call :help&goto useriolp

после строки FOR %%r IN (EXIT quit) .... Обратите внимание, что вы можете сделать подпрограмму :help контекстно-зависимой, потому что у вас есть значение state, чтобы сообщить вам, где вы находитесь.

Точно так же вы можете реализовать систему look, если хотите, по тому же принципу.

Все в пакете. Другие языки вообще не нужны... :)

person Magoo    schedule 04.08.2013
comment
У меня есть проблема с примером выше, он все время хочет показать строку example=. Кроме того, у меня есть главное меню для моей игры, и я хотел бы знать, могу ли я иметь его там, где я могу ввести букву или цифру, чтобы загрузить последнюю сохраненную точку. - person Jackson Fydor; 04.08.2013
comment
Я действительно не понимаю вашей проблемы. Я продемонстрировал, как принять и обработать пользовательский ввод (состояние0, состояние100) и как создать меню и обработать сделанный выбор (состояние1000, состояние1001..1004). Состояние100 показывает, как перезагрузить игру. Я понятия не имею, что такое механика вашей игры. Я просто использую example как пример переменной, которая может быть изменена и перезагружается при повторном запуске игры. Вы не хотите показывать значение example? Отлично. удалите все ссылки на example и обработайте gold или credits или buckets_of_fish или что-то еще. - person Magoo; 06.08.2013
comment
Я пытаюсь сказать, что команда, известная как example=, не прячется, когда я запускаю программу. Я просто хочу знать, это ошибка или это естественно. Извините, проблема не была решена четко. - person Jackson Fydor; 06.08.2013
comment
Это просто для того, чтобы показать вам, что переменная была повторно загружена из сохраненного файла. Если вы запустите игру и ответите, например, jf на приглашение Your Name, игра будет сохранена как jf. Если ваш следующий ответ будет quit или exit, программа закроется. Запустите его снова, укажите jf и будет показано значение example. Ответьте 2 на вопрос which door, будет установлено и показано новое значение example, ответьте quit и перезапустите, и игра jf будет восстановлена ​​точно до того места, где вы вышли, а значение example показывает, что она была восстановлена ​​с файл jf. - person Magoo; 07.08.2013
comment
Так же, как и в строке FOR %%r IN (EXIT quit) DO ..., у вас может быть FOR %%r IN (gold) DO IF /i %response%==%%r echo you have %gold% Gold coins&goto userio, чтобы показывать свое богатство каждый раз, когда вы отвечаете gold на подсказку, или FOR %%r IN (wand wands) DO IF /i %response%==%%r call :showwands&goto userio, чтобы перечислять свои жезлы всякий раз, когда вы отвечаете wand или wands. Подпрограмма :userio сохраняет среду каждый раз, когда вам предлагается ответить. Подпрограмма state100 запускает игру с новым именем или перезагружает старую игру из указанного файла. - person Magoo; 07.08.2013

Есть множество, возможно, сотни языков, которые лучше подходят для приключенческих игр, чем пакетные сценарии MS-DOS. Попробуйте Python, TCL, Lua, Java, C# или любой другой язык, кроме пакетного. Объектно-ориентированный язык часто используется для фэнтезийных приключенческих игр из-за его способности хорошо моделировать. Язык с инфраструктурой сохраняемости (например, Hibernate) может быть удобен для автоматического сохранения. Но это, как правило, связано с хранением данных в реляционной базе данных, которая также хороша для моделирования. Но не пытайтесь откусить слишком много за один раз.

Поскольку вы находитесь в настроении, чтобы попробовать текстовую игру с очень простым языком. Вы могли бы преуспеть с TCL. Но, как я уже сказал, есть множество хороших вариантов. Пакет не считается одним из них.

person WarrenT    schedule 04.08.2013
comment
Благодарю вас! Я мог бы просто использовать эфирный C++ или C#, так как я немного знаю ++ и у меня есть программа, которая может кодировать на этих языках. - person Jackson Fydor; 04.08.2013

На самом деле это довольно просто, хотя и занимает много места, в зависимости от того, сколько переменных вы хотите сохранить. Вы хотите иметь другой пакетный файл в том же каталоге, что и пакетный файл, который вы запускаете. Этот пакетный файл может называться save.bat, variable.bat или как-то еще. Для каждого выполненного действия вы хотите, чтобы оно сохраняло переменные в этот пакетный файл. Например:

@echo off
call save.bat
:direction
cls
echo.
echo Would you like to
echo 1) go north
echo 2) go south
set /p answer=:
if %answer% equ 1 goto north
if %answer% equ 2 goto south
cls
echo.
echo That command isn't recognized.
echo.
pause
goto direction
:north
echo set /a money=%money%>>save.bat
echo set /a health=%health%>>save.bat
echo set /a mana=%mana%>>save.bat
cls
echo.
echo You head North.
echo.
pause
exit
:south
echo set /a money=%money%>>save.bat
echo set /a health=%health%>>save.bat
echo set /a mana=%mana%>>save.bat
cls
echo.
echo You head South.
echo.
pause
exit

Вы заметите, как он сохраняет переменные в файле save.bat, который затем вызывается в начале игры. >> указывает, что он добавляет новую строку в файл. Если вы просто используете один >, он удалит все, что было раньше, и добавит переменную в файл. Хотя вам придется сохранять переменные после каждого действия, оно того стоит. Если вы хотите сэкономить место, вы можете сделать это:

@echo off
call save.bat
:direction
cls
echo.
echo Would you like to
echo 1) go north
echo 2) go south
set /p answer=:
if %answer% equ 1 goto north
if %answer% equ 2 goto south
cls
echo.
echo That command isn't recognized.
echo.
pause
goto direction
:north
call autosave.bat
cls
echo.
echo You head North.
echo.
pause
exit
:south
call autosave.bat
cls
echo.
echo You head South.
echo.
pause
exit

И внутри autosave.bat:

echo set /a money=%money%>>save.bat
echo set /a health=%health%>>save.bat
echo set /a mana=%mana%>>save.bat

Так что да, именно так вы можете автоматически сохранять игру.

person Gnarslogge    schedule 07.01.2014