问题
I've been learning some batch programming, and decided to make a roguelike, as it's one of my favorite types of games. I have researched any information on making a roguelike in batch, but haven't found much. From the little bit I've gathered, this is the code I have so far:
@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%
This works so far, and draws the simple 4x4 room.I made the room only 4x4 for testing purposes, so it would be simple.
Now I'm at a point where I'm not sure how to write the rest. I know I'll need to call subroutines, and get the input (WASD), but I don't know how to structure those subroutines in the file. I'd appreciate anyone's help on how to structure a batch roguelike, get input to move the player, or even just ideas about what could work.
Thanks.
回答1:
I give you here a technic without CHOICE
and without an External command.
It use Xcopy
to get the INPUT (W,A,S,D). IN this Exemple i don't make any test of position (where is your object on the screen), So to test it go first right (D).
It's just an exemple to help you.
@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%
回答2:
@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
This code may be useful.
The main loop simply repeats showmap, getmove, makemove.
makemove
is the critical routine that needs to be expanded to build your game. The principle is to see which moves are valid for the next input, place those in moveoptions
and generate an appropriate userprompt
Otherwise, your mapcells are in c_x_y
and objects in obj_level_x_y
I simply chose the object-description to be displaysymbolDESCRIPTION
in objdescX
where the X
is stored in obj_level_x_y
. In this way, you can set up extra object characteristics simply by setting variables like objhitbonusX
or objdosesX
.
You could extend the scheme to opponenthealthX
opponentweaponX
etc.
You'd not that GOTOs are minimised to avoid spaghetti-code.
来源:https://stackoverflow.com/questions/20589066/batch-roguelike-game