Пакетная игра-рогалик

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

@echo off

rem init starting position
set pos=6

:level
set c1=#
set c2=#
set c3=#
set c4=#

set c5=#
set c6=.
set c7=.
set c8=#

set c9=#
set c10=.
set c11=.
set c12=#

set c13=#
set c14=#
set c15=#
set c16=#

echo %c1%%c2%%c3%%c4%
echo %c5%%c6%%c7%%c8%
echo %c9%%c10%%c11%%c12%
echo %c13%%c14%%c15%%c16%

Это работает до сих пор и рисует простую комнату 4x4. Я сделал комнату только 4x4 для целей тестирования, так что это будет просто.

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

Спасибо.


person Jeremy Darrach    schedule 14.12.2013    source источник
comment
МОЙ БОГ. Вы сняли это?   -  person Brian MacKay    schedule 14.07.2014
comment
До сих пор интересно узнать, чем это закончилось!   -  person Alexander van Oostenrijk    schedule 16.08.2018


Ответы (2)


Я даю вам здесь технику без CHOICE и без внешней команды. Он использует Xcopy для получения ВВОДА (W, A, S, D). В этом примере я не проверяю положение (где находится ваш объект на экране), поэтому, чтобы проверить его, идите сначала вправо (D). Это просто пример, чтобы помочь вам.

@echo off

:level
set c1=#
set c2=#
set c3=#
set c4=#

set c5=#
set c6=.
set c7=.
set c8=#

set c9=#
set c10=.
set c11=.
set c12=#

set c13=#
set c14=#
set c15=#
set c16=#


@echo off
setlocal enableextensions enabledelayedexpansion

set haut=        
set larg=

:boucle
cls
echo WASD TO MOVE THE CURSOR Q TO QUIT&echo.
for %%a in ( !haut! ) do echo.
call:aff
Set "Key="
For /F "delims=" %%# In ('Xcopy /W "%~f0" "%~f0" 2^>Nul') Do If Not Defined Key Set "Key=%%#"
Set "Key=%Key:~-1%"
if /i %key%==q (exit /b)
if /i %key%==w goto:UP
if /i %key%==s goto:DOWN
if /i %key%==a goto:LEFT
if /i %key%==d goto:RIGHT

:LEFT
set larg=!larg:~0,-1!
goto boucle

:RIGHT
set larg= !larg!
goto boucle

:UP
set haut=!haut:~0,-2!
goto boucle

:DOWN
set haut=!haut! a
goto boucle


:aff
echo !larg!%c1%%c2%%c3%%c4%
echo !larg!%c5%%c6%%c7%%c8%
echo !larg!%c9%%c10%%c11%%c12%
echo !larg!%c13%%c14%%c15%%c16%
person SachaDee    schedule 14.12.2013
comment
Спасибо за ответ! Я написал все это и запустил, но я не совсем уверен, что он делает. Когда я нажимаю WASD, слева от комнаты появляется текст, показывающий ~0,-2 или ~0,-2a. Главное, чего я не понимаю, это цикл for. Если бы вы могли уточнить, что именно делают эти функции, я был бы очень признателен. Спасибо - person Jeremy Darrach; 15.12.2013
comment
Как я уже говорил вам в своем посте, вы должны начать движение прямо с клавиши D. Это всего лишь пример перемещения по объектам в окнах CMD с помощью клавиш (W, A, S, D). FOR предназначен для восстановления нажатой клавиши, поэтому вам не нужна команда Choice. Я напишу направление на английском языке, чтобы вы могли его понять. - person SachaDee; 15.12.2013
comment
Спасибо большое за помощь. Теперь, как я могу добавить обратно в позицию и физически переместить символ «@»? - person Jeremy Darrach; 15.12.2013
comment
о ничего себе, я только что скопировал весь ваш файл в новый файл .bat и запустил его, а мой этого не делает! Я наверное что-то не так написал. я вернусь и проверю - person Jeremy Darrach; 15.12.2013
comment
Если вы хотите переместить символ @, поместите echo !larg!@ вместо call:aff. - person SachaDee; 15.12.2013

@ECHO OFF
setlocal enableextensions enabledelayedexpansion

SET /a maxx=13
SET /a maxy=7
SET /a level=1
:: current x,y position in cx, cy - set start position
SET /a cx=3
SET /a cy=2

SET objdesc16=*Book of something
CALL :putobjects 1 6 3 16

SET userprompt=Q always Quits - MOVE WASD
SET moveoptions=wasd

:newlevel
:: Set physical map
CALL :map%level%
:loop
CALL :showmap
CALL :getmove
IF /i "%key%"=="Q" GOTO :eof
CALL :makemove
GOTO loop

:getmove
ECHO(%userprompt%
SET "userprompt="
:getmovel
Set "key="
For /F "delims=" %%Z In ('Xcopy /W "%~f0" "%~f0" 2^>Nul') Do If Not Defined Key Set "key=%%Z"
IF NOT DEFINED key GOTO getmovel
Set "key=%key:~-1%"
IF /i "%key%"=="Q" GOTO :eof
IF /i "%moveoptions%"=="!moveoptions:%key%=!" GOTO getmovel
GOTO :eof

:: make a move given KEY

:makemove
if /i %key%==w CALL :movedir 0 -1
if /i %key%==a CALL :movedir -1 0
if /i %key%==s CALL :movedir 0 1
if /i %key%==d CALL :movedir 1 0
GOTO :eof

:movedir
SET /a $m=%1+%cx%
SET /a $n=%2+%cy%
CALL :mapsquare %$m% %$n%
IF "%$s%"=="." SET cy=%$n%&SET cx=%$m%&CALL :setprompt wasd&GOTO :EOF
IF "%$s%"=="#" CALL :setprompt ouch&GOTO :EOF
GOTO :eof

:: standard userprompts

:setprompt
IF /i "%1"=="wasd" SET userprompt=MOVE WASD&GOTO :EOF 
IF /i "%1"=="ouch" SET userprompt=OUCH!&GOTO :EOF 
GOTO :EOF


:map1
CALL :initmap
:: Special map symbols for level 1 (stairs, etc)
CALL :mapsymbol 4 2 ?

GOTO :eof

:mapsymbol
SET "c_%1_%2=%3"
GOTO :eof

:: set border to '#', internal to '.'
:initmap
FOR /l %%y IN (0,1,%maxy%) DO ( 
 FOR /l %%x IN (0,1,%maxx%) DO ( 
  SET c_%%x_%%y=.
  IF %%x==0 SET c_%%x_%%y=#
  IF %%y==0 SET c_%%x_%%y=#
  IF %%x==%maxx% SET c_%%x_%%y=#
  IF %%y==%maxy% SET c_%%x_%%y=#
 )
)
GOTO :eof

:: map on new screen

:showmap
CLS
FOR /l %%y IN (0,1,%maxy%) DO (
 SET "mapline="
 FOR /l %%x IN (0,1,%maxx%) DO ( 
  CALL :mapsquare %%x %%y
  SET mapline=!mapline!!$s!
 )
 ECHO(!mapline!
)
GOTO :eof

:: get the symbol to show in x,y

:mapsquare
:: From map
SET $s=!c_%1_%2!
:: Object
IF DEFINED obj%level%_%1_%2 CALL :getobj %level%_%1_%2
:: Character
IF %cx%==%1 IF %cy%==%2 SET $s=@
SET $s=%$s:~0,1%
GOTO :eof

:: Get object description for object (%1) to $s

:getobj
SET $s=!obj%1!
SET $s=!objdesc%$s%!
GOTO :eof

:: PUTOBJECTS onlevel at-x at-y object#

:putobjects 1 1 3 16
SET "obj%1_%2_%3=%4"
GOTO :eof

Этот код может быть полезен.

Основной цикл просто повторяет showmap, getmove, makemove.

makemove — это критически важная процедура, которую необходимо расширить для создания вашей игры. Принцип заключается в том, чтобы увидеть, какие ходы допустимы для следующего ввода, поместить тех в moveoptions и сгенерировать соответствующий userprompt

В противном случае ваши ячейки карты находятся в c_x_y, а объекты в obj_level_x_y. Я просто выбрал описание объекта как displaysymbolDESCRIPTION в objdescX, где X хранится в obj_level_x_y. Таким образом, вы можете настроить дополнительные характеристики объекта, просто установив такие переменные, как objhitbonusX или objdosesX.

Вы можете расширить схему до opponenthealthX opponentweaponX и т. д.

Вы не заметили, что GOTO сведены к минимуму, чтобы избежать спагетти-кода.

person Magoo    schedule 15.12.2013
comment
Спасибо за ответ! Я протестировал его, и он отлично работает. Мне было интересно, есть ли способ уменьшить эффект перерисовки. Ничего страшного, просто интересно, возможно ли это. В любом случае, я буду продолжать читать код, чтобы понять, что все делает. :) Еще раз спасибо - person Jeremy Darrach; 15.12.2013
comment
Вам понадобится способ управления курсором, который, к сожалению, остался в прошлом AFAIAA. Раньше вы могли загружать ANSI.SYS и отправлять escape-последовательность, но, похоже, это больше невозможно, потому что система была улучшена. Я очень рад, что кто-то продемонстрирует, как это можно сделать! - person Magoo; 15.12.2013