Page 1 of 1

Isometric Bullet Dodging Game

Posted: 06 Nov 2019 10:10
by Lowsun
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

Re: Isometric Bullet Dodging Game

Posted: 06 Nov 2019 13:24
by dbenham
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

Re: Isometric Bullet Dodging Game

Posted: 06 Nov 2019 18:04
by Lowsun
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?

Re: Isometric Bullet Dodging Game

Posted: 06 Nov 2019 22:39
by dbenham
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.

Re: Isometric Bullet Dodging Game

Posted: 07 Nov 2019 07:35
by dbenham
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.

Re: Isometric Bullet Dodging Game

Posted: 07 Nov 2019 18:36
by Lowsun
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

Re: Isometric Bullet Dodging Game

Posted: 08 Nov 2019 18:18
by dbenham
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

Re: Isometric Bullet Dodging Game

Posted: 08 Nov 2019 20:54
by Lowsun
Oh right! Thanks man, I really appreciate your help! "Dodge Dungeon" is now a finished script :)