Isometric Bullet Dodging Game

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Lowsun
Posts: 29
Joined: 14 Apr 2019 17:22

Isometric Bullet Dodging Game

#1 Post by Lowsun » 06 Nov 2019 10:10

I've always been fascinated by isometric designs, and so I decided one day to make an isometric grid generator. Naturally, I thought that it would be a really unique perspective to try to make a game in. It is just showcase of an isometric movement system using purely ASCII characters. I really tried to go for style+efficiency in this script. Here's a screenshot Image and here's the code:

Code: Select all

    @ECHO OFF
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    IF not "%~1" == "" (
        GOTO :%~1
    )
    
    FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
    SET mv[W]="y[#]-=1","x[#]+=1"
    SET mv[A]="x[#]-=3"
    SET mv[S]="y[#]+=1","x[#]-=1"
    SET mv[D]="x[#]+=3"
    SET up=%ESC%[nA
    SET dn=%ESC%[nB
    SET bk=%ESC%[nD
    SET nx=%ESC%[nC
    SET col=%ESC%[38;2;cm
    SET bcl=%ESC%[48;2;cm
    SET framerate=FOR /L %%J in (1,40,1000000) DO REM
    SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
    SET /A "grid[x]=13","grid[y]=6","grid[bk]=(grid[x]*3)+1","x[u]=grid[x]+grid[y]","y[u]=6","score=0"
    FOR /L %%X in (1, 1, %grid[x]%) DO (
        SET "grid[xlen]=!grid[xlen]!/_/"
        SET "grid[tlen]=!grid[tlen]!__ "
    )
    SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
    FOR /L %%Y in (1, 1, %grid[y]%) DO (
        SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
    )
    ECHO %ESC%[?25l
    
    IF exist "%temp%\%~n0_signal.txt" (
        DEL "%temp%\%~n0_signal.txt"
    )
    "%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt"
    EXIT /B
    
    :GAME
    FOR /L %%# in () DO (
        SET /P "rec="
        TITLE Score : !score!
        ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
        SET /A "count+=1"
        FOR %%G in (!rec!) DO (
            (SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+10)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+10)+(3*grid[x])))>>31)&1))" 2>NUL) && (
                SET /A !mv[%%G]:#=u!
            )
        )
        2>NUL SET /A !every:#=15! && (
            SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+11+(3*grid[x])"
            SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
            SET "p[li]=!p[li]! [!p[ct]!]"
        )
        2>NUL SET /A !every:#=2! && (
            SET "p[dp]="
            FOR %%Q in (!p[li]!) DO (
                SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
                IF !d[x]! EQU !d[max]! (
                    SET /A "score+=1"
                    SET "p[li]=!p[li]:%%Q=!"
                ) else (
                    SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
                )
                IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
                    TITLE You died...
                    ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
                    EXIT /B
                )
            )
        )
        SET "rec="
        %framerate%
    )
    
    :CONTROL
    FOR /L %%C in () do (
        FOR /F "tokens=*" %%A in ('CHOICE /C:WASD /N') DO (
            <NUL SET /P ".=%%A"
        )
    )
    GOTO :EOF

The game is pretty simple, just use WASD to move.

Lowsun

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Isometric Bullet Dodging Game

#2 Post by dbenham » 06 Nov 2019 13:24

Nicely done. I assume you've seen SNAKE.BAT.

It didn't take much to enhance your code to allow cleanly exiting the game. My added/modified code is in lower case. Press Q to exit the game. This could be before or after you die. Either way, your final score is printed.

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

IF not "%~1" == "" (
    GOTO :%~1
)

FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
SET /A "grid[x]=13","grid[y]=6","grid[bk]=(grid[x]*3)+1","x[u]=grid[x]+grid[y]","y[u]=6","score=0"
FOR /L %%X in (1, 1, %grid[x]%) DO (
    SET "grid[xlen]=!grid[xlen]!/_/"
    SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
    SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)
ECHO %ESC%[?25l

IF exist "%temp%\%~n0_signal.txt" (
    DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & set /a score=!errorlevel!
echo(
echo(
echo(
echo(
echo(
echo(
if %score% lss 0 (
    echo You died!
    set /a score=score*-1-1
)
echo Score: %score%
echo(
EXIT /B

:GAME
FOR /L %%# in () DO (
    SET /P "rec="
    TITLE Score : !score!
    ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
    SET /A "count+=1"
    if !rec! == Q exit !score!
    FOR %%G in (!rec!) DO (
        (SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+10)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+10)+(3*grid[x])))>>31)&1))" 2>NUL) && (
            SET /A !mv[%%G]:#=u!
        )
    )
    2>NUL SET /A !every:#=15! && (
        SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+11+(3*grid[x])"
        SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
        SET "p[li]=!p[li]! [!p[ct]!]"
    )
    2>NUL SET /A !every:#=2! && (
        SET "p[dp]="
        FOR %%Q in (!p[li]!) DO (
            SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
            IF !d[x]! EQU !d[max]! (
                SET /A "score+=1"
                SET "p[li]=!p[li]:%%Q=!"
            ) else (
                SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
            )
            IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
                title You died... Press Q to continue
                ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
                set /a score+=1
                exit -!score!
            )
        )
    )
    SET "rec="
    %framerate%
)

:CONTROL
FOR /L %%C in () do (
    FOR /F "tokens=*" %%A in ('CHOICE /C:WASDQ /N') DO (
        <NUL SET /P ".=%%A"
        if %%A == Q exit
    )
)
GOTO :EOF

Dave Benham

Lowsun
Posts: 29
Joined: 14 Apr 2019 17:22

Re: Isometric Bullet Dodging Game

#3 Post by Lowsun » 06 Nov 2019 18:04

Ya, SNAKE.bat is pretty inspirational. I like your modifications, but could I ask why you set errorlevel in the EXIT to a negative number? Does it have something to do with having a score of 1 or 0?

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Isometric Bullet Dodging Game

#4 Post by dbenham » 06 Nov 2019 22:39

So I could differentiate between quit while alive and death. That allows me to ECHO out "You died" when appropriate. The window title is reset once the child processes are terminated.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Isometric Bullet Dodging Game

#5 Post by dbenham » 07 Nov 2019 07:35

But your mention of 0 vs 1 reminded me that I forgot to subtract one from the score upon returning from the pipe when you die. I fixed the code a few posts back.

Lowsun
Posts: 29
Joined: 14 Apr 2019 17:22

Re: Isometric Bullet Dodging Game

#6 Post by Lowsun » 07 Nov 2019 18:36

Ahhhh yes that makes a lot more sense. Thanks for the suggestions! I ended up not using that bit and instead just made Q for when you die. I guess if you press Q when playing you can't move, but I don't really see a way around that. Here's a final version with a proper menu and different map sizes.

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
MODE 60, 25

IF not "%~1" == "" (
    GOTO :%~1
)

FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET "score=0"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
ECHO %ESC%[?25l

:MENU
TITLE Dodge Dungeon
ECHO %ESC%[2J%ESC%[0m%ESC%[2;2HLowsun 2019%ESC%[7;10H__   __   __   __   ___%dn:n=1%%bk:n=24%^|  \ /  \ ^|  \ / _` ^|__%dn:n=1%%bk:n=23%^|__/ \__/ ^|__/ \__^> ^|___%dn:n=1%%bk:n=23%%col:c=135;245;233%^<Í D U N G E O N Í^>%ESC%[0m%ESC%[15;9H1) Large%dn:n=2%%ESC%[9G2) Medium%dn:n=2%%ESC%[9G3) Small%ESC%[11;10HSCORE : !score!
CHOICE /C 123 /N>NUL
SET /A "grid[x]=16-(3*%errorlevel%)","grid[y]=13-(3*%errorlevel%)","grid[bk]=(grid[x]*3)+1","score=0","p[rt]=15","margin=20-grid[x]","x[u]=16","y[u]=7"
FOR /L %%X in (1, 1, %grid[x]%) DO (
    SET "grid[xlen]=!grid[xlen]!/_/"
    SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
    SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)


IF exist "%temp%\%~n0_signal.txt" (
    DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & SET /A "score=!errorlevel!" & SET "grid[xlen]=" & SET "grid[tlen]="
GOTO :MENU

:GAME
FOR /L %%# in () DO (
    SET /P "rec="
    TITLE Score : !score!
    ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GUse WASD to move%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
    SET /A "count+=1"
    FOR %%G in (!rec!) DO (
        (SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+%margin%)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+%margin%)+(3*grid[x])))>>31)&1))" 2>NUL) && (
            SET /A !mv[%%G]:#=u!
        )
    )
    FOR %%Q in (!p[rt]!) DO (
        2>NUL SET /A !every:#=%%Q! && (
            SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+(%margin%+1)+(3*grid[x])"
            SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
            SET "p[li]=!p[li]! [!p[ct]!]"
        )
    )
    2>NUL SET /A !every:#=50! && (
        IF !p[rt]! GTR 2 (
            SET /A "p[rt]-=1"
        )
    )
    2>NUL SET /A !every:#=2! && (
        SET "p[dp]="
        FOR %%Q in (!p[li]!) DO (
            SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
            IF !d[x]! EQU !d[max]! (
                SET /A "score+=1"
                SET "p[li]=!p[li]:%%Q=!"
            ) else (
                SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
            )
            IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
                ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GOuch^^! Press Q to continue%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
                EXIT !score!
            )
        )
    )
    SET "rec="
    %framerate%
)

:CONTROL
FOR /L %%C in () do (
    FOR /F "tokens=*" %%A in ('CHOICE /C:WASQD /N') DO (
        <NUL SET /P ".=%%A"
        IF "%%A" == "Q" (
            EXIT
        )
    )
)
GOTO :EOF

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Isometric Bullet Dodging Game

#7 Post by dbenham » 08 Nov 2019 18:18

An alternative to adding the Q key that can freeze the game is to use the presence of a file as a signal that the player has died. I used that technique for multiple purposes in SNAKE.BAT.

and, Doh! you forgot to add a Quit option to the Menu :!:

Here is the modified code

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
MODE 60, 25

IF not "%~1" == "" (
    GOTO :%~1
)

FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET "score=0"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
ECHO %ESC%[?25l
del "%~dpn0.quit" 2>nul

:MENU
TITLE Dodge Dungeon
ECHO %ESC%[2J%ESC%[0m%ESC%[2;2HLowsun 2019%ESC%[7;10H__   __   __   __   ___%dn:n=1%%bk:n=24%^|  \ /  \ ^|  \ / _` ^|__%dn:n=1%%bk:n=23%^|__/ \__/ ^|__/ \__^> ^|___%dn:n=1%%bk:n=23%%col:c=135;245;233%^<Í D U N G E O N Í^>%ESC%[0m%ESC%[15;9H1) Large%dn:n=2%%ESC%[9G2) Medium%dn:n=2%%ESC%[9G3) Small%dn:n=2%%ESC%[9GQ) Quit%ESC%[11;10HSCORE : !score!
CHOICE /C 123Q /N>NUL
if %errorlevel% == 4 cls & exit /b
SET /A "grid[x]=16-(3*%errorlevel%)","grid[y]=13-(3*%errorlevel%)","grid[bk]=(grid[x]*3)+1","score=0","p[rt]=15","margin=20-grid[x]","x[u]=16","y[u]=7"
FOR /L %%X in (1, 1, %grid[x]%) DO (
    SET "grid[xlen]=!grid[xlen]!/_/"
    SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
    SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)


IF exist "%temp%\%~n0_signal.txt" (
    DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & SET /A "score=!errorlevel!" & SET "grid[xlen]=" & SET "grid[tlen]="
GOTO :MENU

:GAME
FOR /L %%# in () DO (
    SET /P "rec="
    TITLE Score : !score!
    ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GUse WASD to move%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
    SET /A "count+=1"
    FOR %%G in (!rec!) DO (
        (SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+%margin%)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+%margin%)+(3*grid[x])))>>31)&1))" 2>NUL) && (
            SET /A !mv[%%G]:#=u!
        )
    )
    FOR %%Q in (!p[rt]!) DO (
        2>NUL SET /A !every:#=%%Q! && (
            SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+(%margin%+1)+(3*grid[x])"
            SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
            SET "p[li]=!p[li]! [!p[ct]!]"
        )
    )
    2>NUL SET /A !every:#=50! && (
        IF !p[rt]! GTR 2 (
            SET /A "p[rt]-=1"
        )
    )
    2>NUL SET /A !every:#=2! && (
        SET "p[dp]="
        FOR %%Q in (!p[li]!) DO (
            SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
            IF !d[x]! EQU !d[max]! (
                SET /A "score+=1"
                SET "p[li]=!p[li]:%%Q=!"
            ) else (
                SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
            )
            IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
                ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GOuch^^! Press any of WASD to continue%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
                copy nul "%~dpn0.quit" >nul
                EXIT !score!
            )
        )
    )
    SET "rec="
    %framerate%
)

:CONTROL
FOR /L %%C in () do (
    FOR /F "tokens=*" %%A in ('CHOICE /C:WASD /N') DO (
        if exist "%~dpn0.quit" del "%~dpn0.quit" & exit
        <NUL SET /P ".=%%A"
    )
)
GOTO :EOF

Dave Benham

Lowsun
Posts: 29
Joined: 14 Apr 2019 17:22

Re: Isometric Bullet Dodging Game

#8 Post by Lowsun » 08 Nov 2019 20:54

Oh right! Thanks man, I really appreciate your help! "Dodge Dungeon" is now a finished script :)

Post Reply