Jake123
Well me and my friend are going to program a batch Pokémon game! Exciting right? One problem though. I am trying to figure out how to make the XY Coordinate thingy for the entire area where the character moves in. And also trying to figure out the all important question: how to make the character move on this XY coordinate and when they reach a certain part of it something happens (like a wild pokemon appears). IT would be helpful if someone showed me an example code of this and EXPLAINED each part of it so I understand better. I am still a noob so cut me some slack. Thank you for your help.
----------------------------
#2 18 Apr 2013 16:51
jeb
Simple answer: Batch can't do this.
But you can add this functionality by a small program (google: dostips batch gotoxy).
Or you build the complete screen in variables, clear the screen and print the new screen
----------------------------
#3 18 Apr 2013 23:41
Jake123
Hmmm actually it can do this... almost at least.
Code: Select all
@echo off
setlocal enabledelayedexpansion
:variables
set player=@
set space=
set bound=Û
set /a A=3
set /a B=8
set X!A!Y!B!=!player!
set X1Y9=!bound!
set X1Y8=!bound!
set X1Y7=!bound!
set X1Y6=!bound!
set X1Y5=!bound!
set X1Y4=!bound!
set X1Y3=!bound!
set X1Y2=!bound!
set X1Y1=!bound!
set X2Y1=!bound!
set X3Y1=!bound!
set X4Y1=!bound!
set X5Y1=!bound!
set X5Y2=!bound!
set X5Y3=!bound!
set X5Y4=!bound!
set X5Y5=!bound!
set X5Y6=!bound!
set X5Y7=!bound!
set X5Y8=!bound!
set X5Y9=!bound!
set X4Y9=!bound!
set X3Y9=!bound!
set X2Y9=!bound!
set X1Y9=!bound!
set X2Y8=!space!
set X4Y8=!space!
set X2Y7=!space!
set X3Y7=!space!
set X4Y7=!space!
set X2Y6=!space!
set X3Y6=!space!
set X4Y6=!space!
set X2Y5=!space!
set X3Y5=!space!
set X4Y5=!space!
set X2Y4=!space!
set X3Y4=!space!
set X4Y4=!space!
set X2Y3=!space!
set X3Y3=!space!
set X4Y3=!space!
set X2Y2=!space!
set X3Y2=!space!
set X4Y2=!space!
:game
cls
echo.
echo !X1Y9!!X2Y9!!X3Y9!!X4Y9!!X5Y9!
echo !X1Y8!!X2Y8!!X3Y8!!X4Y8! !X5Y8!
echo !X1Y7!!X2Y7!!X3Y7!!X4Y7! !X5Y7!
echo !X1Y6!!X2Y6!!X3Y6!!X4Y6!!X5Y6!
echo !X1Y5!!X2Y5!!X3Y5!!X4Y5!!X5Y5!
echo !X1Y4!!X2Y4!!X3Y4!!X4Y4!!X5Y4!
echo !X1Y3!!X2Y3!!X3Y3!!X4Y3! !X5Y3!
echo !X1Y2!!X2Y2!!X3Y2!!X4Y2! !X5Y2!
echo !X1Y1!!X2Y1!!X3Y1!!X4Y1!!X5Y1!
echo.
call :movement
:movement
choice /c:wasdl /n
if %errorlevel% equ 1 goto :Y+
if %errorlevel% equ 2 goto :X-
if %errorlevel% equ 3 goto :Y-
if %errorlevel% equ 4 goto :X+
if %errorlevel% equ 5 exit
goto :eof
:Y+
set /a B=!B! + 1
set X!A!Y!B!=!player!
goto game
:X-
set /a A=!A! - 1
set X!A!Y!B!=!player!
goto game
:Y-
set /a B=!B! - 1
set X!A!Y!B!=!player!
goto game
:X+
set /a A=!A! + 1
set X!A!Y!B!=!player!
goto game
----------------------------
#4 19 Apr 2013 07:11
foxidrive
You will run into performance issues, even if you manage to get a block of characters to move on a screen refresh.
A compiled language is probably a better choice, rather than interpreted.
----------------------------
#5 19 Apr 2013 11:18
Jake123
Yeah man but I really want to do this thing with one batch file. It would be a challenge for me. All I need is for someone to fix the code so that the player icon moves without leaving a trail of itself as it moves.
----------------------------
#6 23 Apr 2013 09:05
bluesxman
You aren't blanking the previous location when you move.
For example:
Code: Select all
:Y+
set X!A!Y!B!=!space!
set /a B=!B! + 1
set X!A!Y!B!=!player!
goto game
----------------------------
#7 23 Apr 2013 12:35
Jake123
ok I tried running that through the file and it creates even more problems. It moves the boundary (bound) closer and closer to the player icon until everything is gone and it just reads ECHO IS OFF. Any ideas how to combat this issue?
----------------------------
#8 23 Apr 2013 13:19
bluesxman
At a guess, try changing this line:
set space=
To this:
set "space= "
In fact, I'd recommend using quotes on all "set" commands, thus:
set "variable=sometext"
set /a "expression=x + y"
Last edited by bluesxman (23 Apr 2013 13:21)
cmd | *sh | ruby | chef
----------------------------
#9 23 Apr 2013 13:47
bluesxman
OK I've actually run the code and found a couple of issues.
Below I've addressed (in a slightly dirty fashion) the problem of exceeding the bounds of the play field. I don't actually have "choice" on this PC so I've frigged a way round that with "set /p".
Code: Select all
@echo off
setlocal enabledelayedexpansion
:variables
set player=@
set "space= "
set bound=Û
set /a A=3
set /a B=8
set X!A!Y!B!=!player!
set X1Y9=!bound!
set X1Y8=!bound!
set X1Y7=!bound!
set X1Y6=!bound!
set X1Y5=!bound!
set X1Y4=!bound!
set X1Y3=!bound!
set X1Y2=!bound!
set X1Y1=!bound!
set X2Y1=!bound!
set X3Y1=!bound!
set X4Y1=!bound!
set X5Y1=!bound!
set X5Y2=!bound!
set X5Y3=!bound!
set X5Y4=!bound!
set X5Y5=!bound!
set X5Y6=!bound!
set X5Y7=!bound!
set X5Y8=!bound!
set X5Y9=!bound!
set X4Y9=!bound!
set X3Y9=!bound!
set X2Y9=!bound!
set X1Y9=!bound!
set X2Y8=!space!
set X4Y8=!space!
set X2Y7=!space!
set X3Y7=!space!
set X4Y7=!space!
set X2Y6=!space!
set X3Y6=!space!
set X4Y6=!space!
set X2Y5=!space!
set X3Y5=!space!
set X4Y5=!space!
set X2Y4=!space!
set X3Y4=!space!
set X4Y4=!space!
set X2Y3=!space!
set X3Y3=!space!
set X4Y3=!space!
set X2Y2=!space!
set X3Y2=!space!
set X4Y2=!space!
:game
cls
echo.
echo:!X1Y9!!X2Y9!!X3Y9!!X4Y9!!X5Y9!
echo:!X1Y8!!X2Y8!!X3Y8!!X4Y8!!X5Y8!
echo:!X1Y7!!X2Y7!!X3Y7!!X4Y7!!X5Y7!
echo:!X1Y6!!X2Y6!!X3Y6!!X4Y6!!X5Y6!
echo:!X1Y5!!X2Y5!!X3Y5!!X4Y5!!X5Y5!
echo:!X1Y4!!X2Y4!!X3Y4!!X4Y4!!X5Y4!
echo:!X1Y3!!X2Y3!!X3Y3!!X4Y3!!X5Y3!
echo:!X1Y2!!X2Y2!!X3Y2!!X4Y2!!X5Y2!
echo:!X1Y1!!X2Y1!!X3Y1!!X4Y1!!X5Y1!
echo.
call :movement
goto game
:movement
choice /c:wasdl /n 2>nul
if errorlevel 9009 call :choice w a s d l
if %errorlevel% equ 1 goto :Y+
if %errorlevel% equ 2 goto :X-
if %errorlevel% equ 3 goto :Y-
if %errorlevel% equ 4 goto :X+
if %errorlevel% equ 5 exit
goto :eof
:Y+
set X!A!Y!B!=!space!
set /a B=!B! + 1
if "!X%A%Y%B%!" equ "%bound%" set /a "B-=1" goto game
set X!A!Y!B!=!player!
goto game
:X-
set X!A!Y!B!=!space!
set /a A=!A! - 1
if "!X%A%Y%B%!" equ "%bound%" set /a "A+=1" goto game
set X!A!Y!B!=!player!
goto game
:Y-
set X!A!Y!B!=!space!
set /a B=!B! - 1
if "!X%A%Y%B%!" equ "%bound%" set /a "B+=1" goto game
set X!A!Y!B!=!player!
goto game
:X+
set X!A!Y!B!=!space!
set /a A=!A! + 1
if "!X%A%Y%B%!" equ "%bound%" set /a "A-=1" goto game
set X!A!Y!B!=!player!
goto game
:choice
set "choice="
set /p "choice=>: "
if "%choice%" EQU "%~1" exit /b 1
if "%choice%" EQU "%~2" exit /b 2
if "%choice%" EQU "%~3" exit /b 3
if "%choice%" EQU "%~4" exit /b 4
if "%choice%" EQU "%~5" exit /b 5
exit /b 0
Last edited by bluesxman (23 Apr 2013 13:57)
cmd | *sh | ruby | chef
----------------------------
#10 23 Apr 2013 21:49
Jake123
That is awesome man thanks!
----------------------------
#11 25 Apr 2013 09:35
bluesxman
Made some more modifications.
* The play field can be of arbitrary size (though larger sizes will be quite slow to draw)
* Obstacles appear in random locations (frequency is configurable, higher = fewer; frequency value over 32767 disables them)
* Screen flashes if the player attempts to breach the boundary or step on an obstacle
To be done: drop a bomb to clear obstacles from surrounding cells
I'm getting quite interested in this from a "to see if I can" type perspective
EDIT: Fixed key stroke bug noted by AiroNG -- thanks. I have in mind a better way to configure the key strokes which I'll look at later.
EDIT: Starting location randomised (2013/04/26 bug fixed whereby you could spawn in top or left boundary)
Code: Select all
::
:: http://ss64.org/oldforum/viewtopic.php?id=1688
::
@echo off
title %~nx0
setlocal enabledelayedexpansion
:variables
set "player=@"
set "space= "
set "bound=#"
set "obstacle=+"
set "obstacle.freq=10"
set "width=40"
set "height=20"
REM key stroke set up (for future use)
set "key.w=move up"
set "key.s=move down"
set "key.a=move left"
set "key.d=move right"
set "key.b=bomb" & REM destroy all surrounding obstacles at cost of 4 gold or specific at cost of 1
set "key.l=quit"
set "key.p=panic" & REM warp to a random grid location (not current, not obstacle, not boundary)
set "key.j=jump" & REM jump a number of cells (at cost of gold)
REM == IDEAS ==
REM destroyed obstacles randomly spawns nothing or gold (for buying bombs/jumps)
REM collect randomly spawned dots -- every X collected increments gold
REM health - gold can be booby trapped, maybe?
REM what increases health? dots?
REM hang on, what's the aim of the game?!
REM random starting location
set /a "A=(%random% %% (%width% - 2)) + 2"
set /a "B=(%random% %% (%height% - 2)) + 2"
REM set /a A=3
REM set /a B=8
call :init
:game
cls
set location=x!A!y!B!
call :draw
REM set X!A!Y!B!=!player!
call :movement
goto :game
:init
REM sets up the playing field
for /l %%Y in (1,1,%height%) do (
REM set "line="
for /l %%X in (1,1,%width%) do (
set "cell=%space%"
if %%Y EQU 1 set "cell=%bound%"
if %%Y EQU %height% set "cell=%bound%"
if %%X EQU 1 set "cell=%bound%"
if %%X EQU %width% set "cell=%bound%"
if "!cell!" EQU "!space!" (
set /a "obstacle.mod=!random! %% obstacle.freq"
REM set obstacle.mod
if !obstacle.mod! EQU 0 set "cell=%obstacle%"
)
if "x%%Xy%%Y" EQU "%location%" set "cell=%player%"
set "x%%Xy%%Y=!cell!"
)
REM echo:!line!
)
goto :EOF
:draw
set "%location%=%player%"
REM draw the playing field
for /l %%Y in (1,1,%height%) do (
set "line="
for /l %%X in (1,1,%width%) do (
set "line=!line!!x%%Xy%%Y!"
)
echo:!line!
)
goto :EOF
:movement
set location
set "commands=w a s d b l"
choice /c:%commands: =% /n 2>nul
if errorlevel 9009 call :choice %commands%
if %errorlevel% equ 1 call :move up & goto :EOF
if %errorlevel% equ 2 call :move left & goto :EOF
if %errorlevel% equ 3 call :move down & goto :EOF
if %errorlevel% equ 4 call :move right & goto :EOF
if %errorlevel% equ 5 call :bomb & goto :EOF
if %errorlevel% equ 6 exit
goto :EOF
:bomb
REM remove obstacles from the 8 surrounding cells
REM -- calulate surrounding 8 cells, turn to space if "+"
REM -- %1 = direction key to bomb 2 cells in that direction only
REM -- bombing has a cost
call :color.cycle 2 "c7 07"
:: TBC
goto :EOF
:move
::echo %0 %*
if "%1" EQU "up" (
set op=-
set var=B
)
if "%1" EQU "down" (
set op=+
set var=B
)
if "%1" EQU "left" (
set op=-
set var=A
)
if "%1" EQU "right" (
set op=+
set var=A
)
set A.new=%A%
set B.new=%B%
::set "%var%.new=%var%"
set /a "%var%.new%op%=1"
::set var
::echo %var%=!%var%!
::set %var%.new
::echo:new cell x%A.new%y%B.new% contains [!x%A.new%y%B.new%!]
if "!x%A.new%y%B.new%!" EQU "%space%" (
set "%var%=!%var%.new!"
set "x%A%y%B%=%space%"
set "x!A!y!B!=%player%"
) else (
call :color.cycle 2 "70 07"
)
set "location=x%A%y%B%"
goto :EOF
:color.cycle
for /l %%i in (1,1,%1) do (
for %%C in (%~2) do (
color %%C
ping 127.1 -n 1 >nul
)
)
goto :EOF
:choice
REM last movement latches if you don't blank choice
REM set "choice="
set /p "choice=>: "
set count=0
for %%C in (%*) do (
set /a "count+=1"
if "%choice%" EQU "%%C" exit /b !count!
)
exit /b 0
cmd | *sh | ruby | chef
----------------------------
#12 25 Apr 2013 10:05
foxidrive
Nice work.
----------------------------
#13 25 Apr 2013 10:58
AiroNG
You can include Choice on WinXP-Machines, it only works on 32bit Systems however.
I found it here: http://winworldpc.com/library_m2.shtml and it works on my WindowsXP 32bit.
Search for "Microsoft DOS 6.22 (Upgrade) (3.5).7z" in "/Abandonware Operating Systems/PC/DOS/Microsoft/",
unzipp it and get the choice.com from disk1.img. Once that is done simply put it in your windows\ folder
I discovered a small mistake in your code bluesxman
You forgot the "b" in:
Code: Select all
choice /c:wasdl /n 2>nul
I don't suffer from insanity, I enjoy every minute of it.
----------------------------
#14 25 Apr 2013 11:13
bluesxman
Thanks, fixed above.
cmd | *sh | ruby | chef
----------------------------
#15 25 Apr 2013 12:08
bluesxman
Starting location is now randomised (update above).
Last edited by bluesxman (26 Apr 2013 09:58)
cmd | *sh | ruby | chef
----------------------------
#16 29 Apr 2013 06:20
dbenham
bluesxman - I like your :choice solution
I've got some significant techniques to dramatically improve performance. My script below can easily handle a 60x40 screen.
1) No need to build each line character by character on every refresh when most of the "pixels" remain constant. Instead, build an array of lines once. Then use SET substring operations to move a character. Only 2 assignments are required to change the value of a pixel. Once a turn is over, simply ECHO the array of modified lines. This change makes a HUGE difference.
2) Much of the logic can be replaced by creative use of variable names and SET /A
3) CALLs are quite slow. Place blocks of logic directly in the main loop instead of using CALL whenever possible.
4) Blocks of code that perform a useful action can be stored in variables as "macros" instead of in CALLed subroutines. There is even a nifty trick to create "macros" that accept arguments. Macros with arguments actually take a bit more code than traditional CALLed routines. But the macros are MUCH faster. See the following DosTips threads for more info about batch macros:
https://www.dostips.com/forum/viewtopic ... lit=macros
https://www.dostips.com/forum/viewtopic ... lit=macros
Here is a complete, functioning game: HUNTER.BAT
There are a number of configurable options near the top of the script. One obvious improvement would be prompts to allow the user to configure the game, without having to edit the file.
There are lots of directions the game could be taken. It has a solid foundation for expansion. A lot more logic could be added and still the game would have decent performance.
Code: Select all
::
:: https://ss64.org/oldforum/viewtopic.php?id=1688
::
@echo off
if "%~1" neq "StartTheGame" (
cmd /c "%~f0" StartTheGame
exit /b
)
title %~nx0
setlocal disableDelayedExpansion
cls
::::::::::::::::::::::::::::::::::::::::::::::::
:: User configurable options
set "keyUp=W"
set "keyDown=S"
set "keyLeft=A"
set "keyRight=D"
set "keyBomb=B"
set "keyFire=F"
set "keyHelp=H"
set "keyExit=L"
set "keyPanic=P"
set "keyWait=N"
set "keyWhereAmI=M"
set "width=40"
set "height=20"
set "monsterCount=10"
set "monsterStrength=3" Value from 1 to 3
set "monsterVision=8" Value >= 1
set "obstacleFreq=15" Roughly 1 out of N will be obstacle
set "bombTicks=6" Value from 2 to 9
set "bombSpread=2" Reasonable values are 1, 2 or 3
set "boardColor=07" white on black
set "bombColor=C7" white on bright red
set "collideColor=0E" bright yellow on black
set "fireColor=70" black on white
set "monsterDeathPoints=25"
set "hitMonsterPoints=10"
set "dotPoints=1"
set "penaltyPoints=-1"
set "penaltyTicks=2" subract penaltyPoints every PenaltyTicks
::::::::::::::::::::::::::::::::::::::::::::::::
:: Define variables
set /a "time=score=0"
set "up=1"
set "left=2"
set "down=3"
set "right=4"
set "bomb=5"
set "fire=6"
set "help=7"
set "exit=8"
set "whereAmI=9"
set "panic=10"
set "wait=11"
set "commands=%keyUp% %keyLeft% %keyDown% %keyRight% %keyBomb% %keyFire% %keyHelp% %keyExit% %keyWhereAmI% %keyPanic% %keyWait%"
set "spinner1=-"
set "spinner2=\"
set "spinner3=|"
set "spinner4=/"
set "spinner= spinner1 spinner2 spinner3 spinner4 "
set "playerDir=%up%"
set "space= "
set "bound=#"
set "obstacle=+"
set "dot=."
set "monster3=M"
set "monster2=N"
set "monster1=O"
set "death=X"
set "empty=%space%"
set "xDiff%up%=+0"
set "xDiff%left%=-1"
set "xDiff%down%=+0"
set "xDiff%right%=+1"
set "yDiff%up%=-1"
set "yDiff%left%=+0"
set "yDiff%down%=+1"
set "yDiff%right%=+0"
set "player%up%=^"
set "player%left%=<"
set "player%down%=v"
set "player%right%=>"
set "bombList="
set "nextBomb=0"
set /a "monsterVision*=monsterVision"
::::::::::::::::::::::::::::::::::::::::::::::::
:: Define macros
::define a Line Feed (newline) string (normally only used as !LF!)
set LF=^
::Above 2 blank lines are required - do not remove
::define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:: setErr
::: Sets the ERRORLEVEL to 1
set "setErr=(call)"
:: clrErr
::: Sets the ERRORLEVEL to 0
set "clrErr=(call )"
:: choice
::: Gets command input, returns result in errorlevel
2>nul >nul choice /? && (
set "choice=choice /c:%commands: =% /n >nul"
) || (
set "choice=call :choice %commands%"
)
:: draw
::: draws the board
set draw=%\n%
cls%\n%
for /l %%Y in (1,1,%height%) do echo(!line%%Y!%\n%
echo score=!score! time=!time!
:: test X Y ValueListVar
::: tests if value at coordinates X,Y is within contents of ValueListVar
set test=%\n%
for %%# in (1 2) do if %%#==2 (for /f "tokens=1-3" %%1 in ("!args!") do (%\n%
for %%A in ("!x%%1y%%2!") do if "!%%3:%%~A=!" neq "!%%3!" %clrErr% else %setErr%%\n%
)) else set args=
:: plot X Y ValueVar
::: places contents of ValueVar at coordinates X,Y
set plot=%\n%
for %%# in (1 2) do if %%#==2 (for /f "tokens=1-3" %%1 in ("!args!") do (%\n%
set "x%%1y%%2=!%%3!"%\n%
set "part1=!line%%2:~0,%%1!"%\n%
set "line%%2=!part1:~0,-1!!%%3!!line%%2:~%%1!"%\n%
)) else set args=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Define additional variables that require delayed expansion
setlocal enableDelayedExpansion
set "playerClass=!player%up%!!player%down%!!player%left%!!player%right%!"
set "monsterClass=%monster1%%monster2%%monster3%"
set "playerSpace=%space%%dot%"
set "fireSpace=%space%%dot%%playerClass%"
set "bombSpace=%space%%dot%"
set "monsterSpace=%space%%dot%%playerClass%"
set "bombEffect=%dot%%obstacle%%playerClass%%monsterClass%0"
set "nextMonster%monster3%=%monster2%"
set "nextMonster%monster2%=%monster1%"
set "nextMonster%monster1%=%space%"
for /f "tokens=* delims=:." %%L in ('findstr /bl :::. "%~f0"') do @echo(%%L
::::::::::::::::::::::::::::::::::::::::::::::::
:: Initialize the board
<nul set /p "=Initializing."
call :place P player%playerDir%
set "monsterList="
for /l %%N in (1 1 %monsterCount%) do (
set "monsterList=!monsterList!M%%N "
call :place M%%N monster%monsterStrength%
set "M%%NDir="
)
for /l %%Y in (1 1 %height%) do (
<nul set /p "=."
set "line%%Y="
for /l %%X in (1,1,%width%) do (
if %%Y EQU 1 set "x%%Xy%%Y=%bound%"
if %%Y EQU %height% set "x%%Xy%%Y=%bound%"
if %%X EQU 1 set "x%%Xy%%Y=%bound%"
if %%X EQU %width% set "x%%Xy%%Y=%bound%"
if not defined x%%Xy%%Y 2>nul set /a "1/(!random!%%obstacleFreq)" && (
set "x%%Xy%%Y=%empty%"
) || (
set "x%%Xy%%Y=%obstacle%"
)
set "line%%Y=!line%%Y!!x%%Xy%%Y!"
)
)
echo(
echo(
pause
call :spinner !PX! !PY! player!playerDir!
::::::::::::::::::::::::::::::::::::::::::::::::
:: Main Loop (infinite loop)
for /l %%. in (0 0 2) do (
%draw%
%========== player actions =======%
set "hold="
%choice%
for %%C in (!errorlevel!) do (
if %%C leq %right% (
if %%C equ !playerDir! (
%== attempt to move forward in same direction ==%
set /a "X=PX+xDiff%%C, Y=PY+yDiff%%C"
(%test% !X! !Y! playerSpace) && (
%== successfull move ==%
(%test% !X! !Y! dot) && set /a score+=dotPoints
%plot% !PX! !PY! space
set /a "PX=X, PY=Y"
%plot% !PX! !PY! player%%C
) || (
%== failed move ==%
call :flash %collideColor%
)
) else (
%== change direction with no movement ==%
set "playerDir=%%C"
set "player=!player%%C!"
%plot% !PX! !PY! player%%C
)
)
if %%C equ %fire% (
%== fire a "gun" forward until it hits something ==%
call :flash %fireColor%
set /a "X=xDiff!playerDir!, xDiff=X+^!X, xMax=^!^!X*(1+X)/2*width+^!X*PX, Y=yDiff!playerDir!, yDiff=Y+^!Y, yMax=^!^!Y*(1+Y)/2*height+^!Y*PY"
set "hit="
for /l %%X in (!PX! !xDiff! !xMax!) do for /l %%Y in (!PY! !yDiff! !yMax!) do (
if not defined hit (%test% %%X %%Y fireSpace) || (
%== Hit detected ==%
set "hit=1"
(%test% %%X %%Y monsterClass) && (
%== Hit a monster ==%
for %%M in (!x%%Xy%%Y!) do set "M=!nextMonster%%M!"
call :spinner %%X %%Y M
set /a score+=hitMonsterPoints
)
)
)
)
if %%C equ %bomb% (
%== attempt to place bomb behind player ==%
set /a "X=PX-xDiff!playerDir!, Y=PY-yDiff!playerDir!"
(%test% !X! !Y! bombSpace) && (
%== successful bomb ==%
set "bombList=!bombList!B!nextBomb! "
set /a "B!nextBomb!X=X, B!nextBomb!Y=Y, B!nextBomb!Ticks=bombTicks, nextBomb+=1"
) || (
%== failed bomb ==%
call :flash %collideColor%
)
)
if %%C equ %panic% (
%== attempt random jump ==%
set /a "X=(!random!%%(width-2))+2, Y=(!random!%%(height-2))+2"
(%test% !X! !Y! playerSpace) && (
%== successfull move ==%
(%test% !X! !Y! dot) && set /a score+=dotPoints
%plot% !PX! !PY! space
set /a "PX=X, PY=Y"
call :spinner !PX! !PY! player!playerDir!
) || (
%== failed move ==%
call :flash %collideColor%
)
)
if %%C equ %whereAmI% (
call :spinner !PX! !PY! player!playerDir!
set "hold=1"
)
if %%C equ %help% (
cls
for /f "tokens=* delims=:." %%L in ('findstr /bl :::. "%~f0"') do @echo(%%L
pause
set "hold=1"
)
if %%C equ %exit% call :exit "You quit :|"
)
if not defined hold (
%========== bomb countdown ========%
set "boomList="
for %%B in (!bombList!) do (
2>nul set /a "%%BTicks-=1, 1/%%BTicks" || (
set "boomList=!boomList!%%B "
set "bombList=!bombList:%%B =!"
)
%plot% !%%BX! !%%BY! %%BTicks
)
%========== bomb explosion ========%
if defined boomList (
%draw%
call :flash %bombColor%
for %%B in (!boomList!) do (
set /a "x1=%%BX-%bombSpread%, x2=%%BX+%bombSpread%, y1=%%BY-%bombSpread%, y2=%%BY+%bombSpread%"
if !x1! lss 1 set "x1=1"
if !x2! gtr %width% set "x2=%width%
if !y1! lss 1 set "y1=1"
if !y2! gtr %height% set "y2=%height%
for /l %%X in (!x1! 1 !x2!) do for /l %%Y in (!y1! 1 !y2!) do (
(%test% %%X %%Y bombEffect) && (%plot% %%X %%Y space)
)
set "%%BTicks="
set "%%BX="
set "%%BY="
)
)
%========== monster actions ========%
for %%M in (!monsterList!) do (
(%test% !%%MX! !%%MY! monsterClass) && (
%== monster is alive ==%
%== First establish movement direction ==%
set /a "DX=PX-%%MX, DY=PY-%%MY, DX2=DX*DX, DY2=DY*DY, D=DX2+DY2"
if !D! leq !monsterVision! (
%== monster sees player - the chase is on ==%
if !DX2! equ !DY2! set /a "T=!random!%%2, DX2+=T, DY2+=^!T"
if !DX2! gtr !DY2! (
if !DX! lss 0 (set %%MDir=%left%) else (set %%MDir=%right%)
) else (
if !DY! lss 0 (set %%MDir=%up%) else (set %%MDir=%down%)
)
) else (
%== continue current direction, set random direction if stationary ==%
if not defined %%MDir set /a "%%MDir=!random! %% 4 + 1"
)
%== attempt movement ==%
set /a "X=%%MX+xDiff!%%MDir!, Y=%%MY+yDiff!%%MDir!"
(%test% !X! !Y! monsterSpace) && (
%== successfull move ==%
for %%A in (x!%%MX!y!%%MY!) do set "M=!%%A!"
%plot% !%%MX! !%%MY! space
set /a "%%MX=X, %%MY=Y"
%plot% !%%MX! !%%MY! M
) || (
%== failed move, clear direction and wait turn ==%
set "%%MDir="
)
) || (
%== monster died, place bomb at death site ==%
set "bombList=!bombList!B!nextBomb! "
set /a "B!nextBomb!X=%%MX, B!nextBomb!Y=%%MY, B=B!nextBomb!Ticks=bombTicks-1, nextBomb+=1"
%plot% !%%MX! !%%MY! B
set "monsterList=!monsterList:%%M =!"
set /a "score+=monsterDeathPoints"
)
)
%========== player death ========%
(%test% !PX! !PY! playerClass) || (
call :spinner !PX! !PY! death
%draw%
call :exit "You died :("
)
%========== monsters cleared ========%
if not defined bombList if not defined monsterList (
call :exit "You slayed the monsters :)"
)
set /a "time+=1, score-=^!(time%%%penaltyTicks%)"
)
)
:choice
set /p "key=>Enter Command (%key%): "
if defined key set "key=!key:~0,1!"
set count=0
for %%C in (%*) do (
set /a "count+=1"
if /i "%key%" equ "%%C" exit /b !count!
)
set "key="
%draw%
goto :choice
:place CoordinatePrefix ObjectName ValueVar
set /a "%1X=(!random!%%(width-2))+2, %1Y=(!random!%%(height-2))+2"
(%test% !%1X! !%1Y! space) || goto :place
set "x!%1X!y!%1Y!=!%2!"
exit /b
:spinner X Y ValueVar
for /l %%N in (1 1 5) do for %%C in (%spinner%) do (
%plot% %1 %2 %%C
%draw%
ping 127.1 -n 1 >nul
)
(%plot% %1 %2 %3)
exit /b
:flash color
for /l %%i in (1,1,2) do (
for %%C in (%1 %boardColor%) do (
color %%C
ping 127.1 -n 1 >nul
)
)
exit /b
:exit Message
set "message=%~1"
echo GAME OVER: !message!
pause
cls
echo score=!score! time=!time!
echo GAME OVER: !message!
exit
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Help text
:::. Characters Control Keys
:::.------------------------------ --------------------------------------------
:::. Monster = !monster3! (3 hits left) Movement: !keyUp! = up
:::. !monster2! (2 hits left) !keyDown! = down
:::. !monster1! (1 hit left) !keyLeft! = left
:::. !keyRight! = right
:::. Player = !player1! (facing up) !keyPanic! = panic (random jump, may fail)
:::. !player3! (facing down) !keyWait! = nothing (sit still)
:::. !player2! (facing left)
:::. !player4! (facing right) Weaponry: !keyBomb! = release bomb to rear
:::. !keyFire! = fire gun forward
:::. Border = !bound! (permanent)
:::.Obstacle = !obstacle! (can be blown up) Other: !keyWhereAmI! = where am I
:::. !keyHelp! = help
:::. !keyExit! = quit (leave)
:::. Scoring
:::.------------------------------
:::. Hit monster = !hitMonsterPoints!
:::. Kill monster = !monsterDeathPoints!
:::. !penaltyTicks! time units = !penaltyPoints!
:::.
Dave Benham
Last edited by dbenham (29 Apr 2013 14:32)
----------------------------
#17 01 May 2013 09:11
npocmaka
very inspirational thread...
----------------------------
#18 14 Jul 2013 19:02
Simon Sheppard
I've edited the title of this thread slightly to make it a bit more descriptive.
Also I have added a new page to SS64.com describing the Batch Macro technique
https://ss64.com/nt/syntax-macros.html