T3RRYT3RR0R

Sprite System for Batch Arcade games w/Demo

Dec 16th, 2020 (edited)
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 29.02 KB | None | 0 0
  1. @Echo off & CD "%~dp0"
  2. CHCP 65001 > nul
  3. cls
  4. :::::::::: Version 1.5 19/12/2020
  5. ::: Games_by_T3RRY: https://drive.google.com/file/d/1cAQLd-f9HN6SuWowBUETccKCZd2dVbWj/view?usp=sharing
  6. ::: Header: Game building tool + tutorial for Batch Arcade Games
  7. ::: Dev Notes:
  8. ::: Purpose: Create a system to convert ASCII Art into sprites that can be moved and interacted with.
  9. ::: Move.Sprite macro Performance Decreases as Sprite size increases.
  10. ::: Creation Date 16/12/2020
  11. ::: [ * Author: T3RRY * ]
  12. ::::::::::::::::::::::::::::
  13. ::: Additional Accreditation
  14. ::: Getkey.Exe by Antonio {https://stackoverflow.com/users/778560/aacini} for Extended key controls.
  15. ::::::::::::::::::::::::::::
  16. ::: Recommended Resources:
  17. ::: Batch Macro's with Arguments Appended:
  18. ::: https://www.dostips.com/forum/viewtopic.php?f=3&t=2518
  19. ::: VT sequence Information:
  20. ::: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
  21. ::: 255 bit color chart [ for VT color sequences ]
  22. ::: https://www.rapidtables.com/web/color/RGB_Color.html
  23. ::::::::::::::::::::::::::::
  24. ::: Version Changes 19/12/2020:
  25. ::: Added Usage tests and output to Background.Border Def.Sprite Show.Sprite and Move.Sprite Macro's
  26. ::: Version Changes 19/12/2020:
  27. ::: Removed Response handling of collision from Move.Sprite macro
  28. ::: Upgraded move.sprite macro to accept arguments for Collision or Capture Characters
  29. ::: - return Vars [Collision is True: Valid=0] [Capture is True: Captured=1]
  30. ::: - Implemented Title based level load indicator during sprite definition
  31. ::: - Improved modelling of handling game exit / End of level cleanup.
  32. ::: - Added 7th arg to Background.Border macro for flagging Border collision as Fatal T[0]/F[-1]
  33. :::::::::::::::
  34. rem /* Establish and verify required resources. Clearly separate script elements */
  35. rem /* Test Environment is suitable for definition of Macro's */
  36.  If "!![" == "[" (Echo/Delayed expansion Must not be enabled prior to starting %~n0.bat & Pause & Exit /B 0)
  37. =============================================================================
  38. ::: CRITICAL RESOURCE DEFINITION AND VALIDATION
  39. =============================================================================
  40.  Set "MSG=Title ?"
  41.  %MSG:?= Verifying Resources ...%
  42. rem /* use wmic output with find to test if system is windows 10. Exit with notice if not */
  43.  wmic OS get OSArchitecture,caption | FIND "10" > nul || (ECHO/Windows 10 required for ascii escape codes & Exit /B)
  44. rem /* Define Escape character used for console virtual terminal sequences */
  45. rem - https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
  46.  for /F "delims=#" %%a in ('"prompt #$E# & for %%a in (1) do rem"') do set "\E=%%a"
  47. rem /* Define Getkey path wit /n no wait parameter */
  48.  For /F "Delims=" %%C in ('dir "%~dp0*GetKey.exe" /B /S') Do If not defined GetKey Set "GetKey="%%C" /n"
  49. rem /* Test getkey var is defined with valid exe path. Exit with notice if not. */
  50.  Echo/%GetKey%|findstr.exe /LIC:"GetKey.exe" > nul || (Echo/GetKey.Exe not found in Directory. Game cannot be played without GetKey.exe &Pause &Exit /B 0)
  51. rem /* Ensure prefix used for Collision detection array unnassigned */
  52.  (For /F "Tokens=1,2 Delims==" %%G in ('Set "}" 2^> Nul ')Do Set "%%~G=") 2> nul
  53. rem /* If TEMP path not found; Assign Current Directory as ~tmp file output folder */
  54.  If not exist "%TEMP%" (Set "Save.Dir=%~dp0")Else Set "Save.Dir=%TEMP%\"
  55. rem /* Test write permission in the assigned directory. Exit with notice if no write permission */
  56.  break >"%Save.Dir%%~n0_testpermission.com" || (
  57.   Echo/Write permission required in %Save.Dir% to continue
  58.   Pause
  59.   Exit /B
  60.  )
  61.  Set Background="%Save.Dir%%~n0_background.~tmp"
  62.  Set Foreground="%Save.Dir%%~n0_foreground.~tmp"
  63.  DEL %Foreground% 2> Nul
  64.  %= --------------------------------------------------------- =%
  65. ::: MACRO DEFINITIONS
  66. ::: \n and COMMENT vars can't have trailing spaces or strings when expanded.
  67. (Set LF=^
  68.  
  69.  
  70. %= Linefeed var. DO NOT MODIFY =%)
  71. (Set \n=^^^
  72.  
  73. %= Macro newline var. DO NOT MODIFY =%)
  74. (Set COMMENT=rem {i} ^^^
  75.  
  76. %= Macro Comment var. DO NOT MODIFY =%)
  77. rem /* On win loss action */
  78.  Set "G.O=Call :End & Endlocal & Goto :start"
  79. rem /* Inverse Player movements for AI control */
  80.  Set ".Left=Right"&Set ".Right=Left"&Set ".Up=Down"&Set ".Down=Up"
  81. rem /* Default Width for game control info panel */
  82.  Set "CNTRL.Width=20"
  83. ========================================================================================================
  84. ::: BACKGROUND.BORDER macro. Define border dimension;color and character.
  85. ::: Resizes console; padding right of the border for Control display
  86. ::: Defines Critical Variables needed for .sprite + other macro's; using the arguments supplied
  87.  Set "Border.Usage=%%Background.Border:CNTRL.Width=INTEGER%%{VTcolorcode}{.Xmin}{.Xmax}{.Ymin}{.Ymax}{BorderCharacter}{0|-1}"
  88. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  89.  Set Background.Border=Set "Border=" ^& For %%n in (1 2)Do If %%n==2 ( %\n%
  90.   %COMMENT:{i}= Ensure Args 1-7 captured \n%
  91.   For /F "Tokens=1,2,3,4,5,6,7 Delims={}" %%G in ("!Border!")Do If not "%%~M" == "" ( %\n%
  92.   %!! use within other macros {Args 2 -5} \n%
  93.    Set /A ".Xmin=%%~H,.Xmax=%%~I,.Ymin=%%~J,.Ymax=%%~K"%\n%
  94.   %!!%
  95.    Set ".Char=%%~L"%\n%
  96.    Set "?Border.Fatal=%%~M"%\n%
  97.    If !?Border.Fatal! GTR 0 ( Echo/Invalid Arg 7 for %%Background.Border%%. Accepted - "0" or "-1" ^& Pause ^> nul ^& Exit /B ) %\n%
  98.   %COMMENT:{i}= {SIDES} For each in xmin AND xmax do for each in Ymin TO Ymax Do \n%
  99.    For %%w in (%%~H %%~I)Do for /L %%h in (%%~J,1,%%~K)Do ( %\n%
  100.   %COMMENT:{i}= Define Cell of Border for Collision testing and display \n%
  101.     Set "}%%h;%%w=%\E%[%%h;%%wH%\E%[%%~Gm%%~L" %\n%
  102.   %COMMENT:{i}= {TOP + BASE} For each in Ymin AND Ymax do for each in Xmin TO Xmax Do \n%
  103.     For %%i in (%%~J %%~K)Do If %%h Equ %%i ( %\n%
  104.      For /L %%W in (%%~H 1 %%~I)Do ( %\n%
  105.   %COMMENT:{i}= Define Cell of Border for Collision testing and display {with VT Color Arg 1} \n%
  106.       Set "}%%h;%%W=%\E%[%%h;%%WH%\E%[%%~Gm%%~L" %\n%
  107.   ))))Else ( %\n%
  108.    Mode 1000 %\n%
  109.    Echo/Error in Level !lvl!!LF!Missing Args for -!LF!%%Background.Border%%=!Border!!LF! Background.Border USAGE: %\n%
  110.    Echo/!Border.Usage!%\n%
  111.    Pause ^& Endlocal ^& Exit /B 0%\n%
  112.   ) %\n%
  113.   %COMMENT:{i}= Define Console Size Lines Cols and Control Panel X Position based on Y X max values \n%
  114.   Set /A "CNTRL=!.Xmax!+5,cols=!.Xmax!+CNTRL.Width+5,lines=!.Ymax!+2" %\n%
  115.   mode !Cols!,!lines! %\n%
  116.  )Else Set Border=
  117. ========================================================================================================
  118.  Set "UPDATE.Background=Set /A ".End=!.Ymax! + 1" & ((For /F "Tokens=2* Delims==" %%G in ('Set "}"')Do (< nul Set /P "=%%~G") & < nul Set /P "=%\E%[!.END!;1H%\E%[0m%\E%[?25l")) >%Background% & Type %Background%"
  119. ========================================================================================================
  120.  Set "Def.Key=Set "input="&For %%n in (1 2)Do if %%n==2 (For %%I in (!input!)Do Set "k%%~I")Else Set input="
  121.  Set "?Key#=For %%E in (!Errorlevel!) Do If not "!k%%E!" == "" (Set "Key=!k%%E!" & (If /I "!Key!" == "space" ( Pause > nul )) & (For %%d in (left right up down)Do If /I "!Key!" == "%%d" (Set "Dir=%%d")))Else If not "%%E" == "0" (If "mode" == "dev" TITLE Key Errorcode - %%E)"
  122. ::: Hash vars used to test / confirm Substring modification is used where needed.
  123.  Set "HASH=#"
  124.  Set "oHASH=Obj"
  125. ========================================================================================================
  126. ::: DEF.SPRITE : Converts Ascii art to objects [ as a list ] with Defined Cordinates }Y;H=}Y;XHcharacter
  127.  Set "Def.Sprite.Usage=%Def.Sprite:#=lineYpos%{SPRITEVARNAME}{VTCOLORCODE}{string defining characters for x positions of substituted Y line}"
  128. :::::::::::::::::::::::::::::::::::::::::::::::::::
  129.  Set Def.Sprite=For %%n in (1 2)Do if %%n==2 ( %\n%
  130.   Set "tMsg=Title Loading Level !lvl!" %\n%
  131.   !tMsg! %\n%
  132.   %COMMENT:{i}= get Y coordinate value of current line from value supplied during macro expansion \n%
  133.   If Not "#" == "!HASH!" ( Set "{y}=#" ) %\n%
  134.   Set /A "{y}+=1 + 0" %\n%
  135.   If !{y}! GEQ !.Ymax! (Echo/Error in Level !lvl!!LF!Y Value - [!{y}!] Exceeds Border Boundary - [!.Ymax!]!LF!!Cells!!LF!!Border! ^& Pause ^& Endlocal ^& Exit /B 0) %\n%
  136.   For /F "Tokens=1,2,3 Delims={}" %%G in ("!Cells!")Do If not "%%~I" == "" ( %\n%
  137.    %COMMENT:{i}= Split Arg 2 cell data from Arg 1 Sprite name \n%
  138.    Set "cell=%%I" %\n%
  139.    %COMMENT:{i}= Color arg can be any valid VT color sequence. \n%
  140.    Set "%%G.Color=%%~H" %\n%
  141.    %COMMENT:{i}= Constrain sprite definition to Playfield X dimensions \n%
  142.    For /L %%i in (2 1 !.Xmin!)Do Set "cell= !cell!" %\n%
  143.    %COMMENT:{i}= Get x coordinate of non whitespace elements in Cell string \n%
  144.    For /L %%x in (0 1 !.Xmax!)Do If not "!cell:~%%x,1!" == "" ( %\n%
  145.     If not "!cell:~%%x,1!" == " " ( %\n%
  146.     Set "tMsg=!tMsg!." %\n%
  147.     !tMsg! %\n%
  148.     %COMMENT:{i}= Shift {x} value from 0 index used by substring modification to 1 index of Virtual Terminal Sequences \n%
  149.      FOR /F "Delims=" %%X in ('Set /A "{x}=%%x+!.Xmin!+1"')Do ( %\n%
  150.       %COMMENT:{i}= Define Cell cordinate for collision testing \n%
  151.       For %%C in ("H" ";" "[")Do If /I "!cell:~%%x,1!" == "%%~C" ( %\n%
  152.        Echo/ Delim character %%C cannot be defined to a sprite. ^& Endlocal %\n%
  153.        Pause  %\n%
  154.        Exit /B 0 %\n%
  155.       ) %\n%
  156.       Set "}!{y}!;%%X=!{y}!;%%XH!cell:~%%x,1!" %\n%
  157.       %COMMENT:{i}= Define Sprite variable Arg 1 with converted Coordinates for non whitespace cells from Arg 2 \n%
  158.       Set "%%G=!%%G!"!{y}!;%%XH!cell:~%%x,1!"," %\n%
  159.   ))))Else ( %\n%
  160.    Mode 1000 %\n%
  161.    Echo/Error in Level !lvl!!LF!Missing Args for -!LF!%%Def.Sprite%%=!Cells!!LF! Def.Sprite USAGE: %\n%
  162.    Echo/%%Def.Sprite:#=lineYpos%%{SPRITEVARNAME}{VTCOLORCODE}{string defining characters for x positions of Y line}%\n%
  163.    Pause ^& Endlocal ^& Exit /B 0%\n%
  164.   ) %\n%
  165.  )Else Set Cells=
  166. ========================================================================================================
  167. ::: SHOW : Iterates over the list value of a substituted sprite variable and outputs value.
  168. ========================================================================================================
  169. rem /* USAGE: %Show:obj=SpriteVARNAME% */ [ Displays spritenames cells ]
  170.  Set "Show=For %%n in (1 2)Do If %%n==2 (If /I "!oHASH!" == "Obj" (<nul Set /P "=%\E%[!.End!;1HError in level !lvl!. Unknown Sprite not displayed^^^!.!LF! Usage: %%Show:!oHASH!=SpriteVARNAME%%")Else For %%g in (!obj!)Do ((Set "oStr=%%~g") & < nul Set /P "=%\E%[!Obj.Color!m%\E%[!oStr!%\E%[0m"))"
  171. rem /* Variables used to convert Direction to Vector in Move.Sprite Macro*/
  172. ========================================================================================================
  173.  Set "Left={x}{-}"& Set "Right={x}{+}"& Set "Up={y}{-}"& Set "Down={y}{+}"
  174. ========================================================================================================
  175. ::: rem /* Move.Sprite macro. Usage:
  176.  Set "Move.Sprite.Usage=%%Move.Sprite:Obj=SPRITEVARNAME%%{y|x}{-|+}{Optional-Collision Chars}{Optional-Capture Characters}"
  177. ::: Args 3 and 4 are optional; Allowing sprites that don't need collision or capture testing to be moved
  178. ::: Due to these optional args; Usage testing is not perfomed beyond the
  179. ::: To ensure correct results; Characters for testing should  be unique to a
  180. ::: single test; Characters MUST NOT match the current object or characters in the other test.
  181. :::::::::::::::::::::::::::::::::::::::::::::::::::::
  182.  Set Move.Sprite=For %%n in (1 2) Do if %%n==2 ( %\n%
  183.    If /I "!oHASH!" == "Obj" ( %\n%
  184.     Mode 1000 %\n%
  185.     Echo/Error in Level !lvl!!LF!Missing Substituion for -!LF! %%move.Sprite:!oHASH!=obj%%!Move.Dir! !LF! Move.Sprite USAGE: %\n%
  186.     Echo/!Move.Sprite.Usage! %\n%
  187.     Pause ^& Endlocal ^& Exit /B 0 %\n%
  188.    ) %\n%
  189.   %COMMENT:{i}= reset sprite clone SUB and VALID move flag variable \n%
  190.   Set "Sub=" %\n%
  191.   Set /A "valid=1,captured=0" %\n%
  192.   %COMMENT:{i}= Catch Move Vector and Collision objects \n%
  193.   For /F "Tokens=1,2,3,4 Delims={}" %%G in ("!Move.Dir!")Do ( %\n%
  194.    Set "axis=%%G" %\n%
  195.    If "%%~H" == "" ( %\n%
  196.     Mode 1000 %\n%
  197.     Echo/Error in Level !lvl!!LF!Missing Args for - !LF! %%move.Sprite:!oHASH!%%obj!Move.Dir! !LF! Move.Sprite USAGE: %\n%
  198.     Echo/!Move.Sprite.Usage!%\n%
  199.     Pause ^& Endlocal ^& Exit /B 0 %\n%
  200.    ) %\n%
  201.    Set "vector=%%~H" %\n%
  202.    If not "%%~I" == "" (Set "Collide=%%I")Else (Set "Collide=") %\n%
  203.    If not "%%~J" == "" (Set "Flag=%%J")Else ( %\n%
  204.     Set "Flag=" %\n%
  205.   )) %\n%
  206.   %COMMENT:{i}= For X or Y axis \n%
  207.   If /I "!axis!" == "X" ( %\n%
  208.    %COMMENT:{i}= iterate over sprite cells \n%
  209.    For %%g in (!obj!) Do ( %\n%
  210.     %!!%
  211.     For /F "Tokens=1,2,3 Delims=;H" %%t in ("%%~g")Do ( %\n%
  212.      %COMMENT:{i}= Adjust cells vector \n%
  213.      Set /A "cx=%%u!vector!1" %\n%
  214.      Set "cTkn=%%v" %\n%
  215.      %COMMENT:{i}= get value of new y/x coord for substring modification \n%
  216.      For /F "Delims=" %%c in ("!cx!")Do ( %\n%
  217.       %COMMENT:{i}= Test cell against each collision character. Flag move invalid on collision \n%
  218.       For %%K in (!Collide!)Do If Not "!}%%t;%%c!" == "" ( %\n%
  219.        Set "KO=!}%%t;%%c:%%~K=!" %\n%
  220.        If Not "!}%%t;%%c!" == "!KO!" ( Set "valid=0" ) %\n%
  221.        For %%0 in ("!.Char!")Do Set "KO=!}%%t;%%c:%%~0=!" %\n%
  222.      %COMMENT:{i}= Return value of ?Border.fatal on border collision \n%
  223.        If Not "!}%%t;%%c!" == "!KO!" ( Set "valid=!?border.fatal!" ) %\n%
  224.       ) %\n%
  225.       %COMMENT:{i}= Test cell against each capture character. Captured var Returns 1 if true \n%
  226.       For %%Q in (!Flag!)Do If Not "!}%%t;%%c!" == "" ( %\n%
  227.        Set "flag.C=!}%%t;%%c:%%~Q=!" %\n%
  228.        Set "flag.Cell=!}%%t;%%c!" %\n%
  229.        If not "!flag.Cell!" == "!flag.C!" ( Set "Captured=1" ) %\n%
  230.       ) %\n%
  231.       %COMMENT:{i}= On valid move for cell build sprite clone string \n%
  232.       If "!Valid!" == "1" (Set "Sub=!Sub!"%%t;%%cH!cTKN!",") %\n%
  233.    )))) ELSE ( %\n%
  234.    For %%g in (!obj!) Do ( %\n%
  235.     For /F "Tokens=1,2,3 Delims=;H" %%i in ("%%~g") Do ( %\n%
  236.      Set /A "cy=%%i!vector!1" %\n%
  237.      Set "cTkn=%%k" %\n%
  238.      For /F "Delims=" %%o in ("!cy!") Do ( %\n%
  239.       For %%K in (!Collide!)Do If not "!}%%o;%%j!" == "" ( %\n%
  240.        Set "KO=!}%%o;%%j:%%~K=!" %\n%
  241.        If Not "!}%%o;%%j!" == "!KO!" ( Set "valid=0" ) %\n%
  242.        For %%0 in ("!.Char!")Do Set "KO=!}%%o;%%j:%%~0=!" %\n%
  243.        If Not "!}%%o;%%j!" == "!KO!" ( Set "valid=!?border.fatal!" ) %\n%
  244.       ) %\n%
  245.       For %%P in (!Flag!)Do If Not "!}%%o;%%j!" == "" ( %\n%
  246.        Set "flag.C=!}%%o;%%j:%%~P=!" %\n%
  247.        Set "flag.Cell=!}%%o;%%j!" %\n%
  248.        If Not "!flag.Cell!" == "!flag.C!" ( Set "Captured=1" ) %\n%
  249.       ) %\n%
  250.       If "!valid!" == "1" (Set "Sub=!Sub!"%%o;%%jH!cTKN!",") %\n%
  251.   ))))%\n%
  252.   %Comment:{i}= If "valid" EQU "0" (Goto End) \n%
  253.   %COMMENT:{i}= On all moves being valid \n%
  254.   If "!valid!" == "1" (%\n%
  255.    %!!%
  256.    (For %%Q in (!obj!)Do ( %\n%
  257.     %COMMENT:{i}= Seperate Y/X values \n%
  258.     For /F "tokens=1,2 Delims=;H" %%1 in ("%%~Q") Do (%\n%
  259.      %COMMENT:{i}= undefine Cell from collision detection array and clear from display \n%
  260.      Set "}%%~1;%%~2=" %\n%
  261.      Echo/%\E%[%%1;%%2H %\n%
  262.      %COMMENT:{i}= [overwrite foreground file] and redirect output of whitespace for last sprite cell positions \n%
  263.    )))^>%Foreground% %\n%
  264.    %COMMENT:{i}= Define new Cell Location with new value and output \n%
  265.    (For %%S in (!Sub!)Do ( %\n%
  266.     For /F "tokens=1,2,3 Delims=;H" %%3 in ("%%~S") Do (%\n%
  267.      Set "cTKN=%%5" %\n%
  268.      Set "}%%~3;%%~4=%%~3%!!%~4H!cTKN!" %\n%
  269.      Echo/%\E%[%%~3;%%~4H%\E%[!Obj.Color!m!cTKN!%\n%
  270.       %COMMENT:{i}= append output of new sprite cell positions to foreground file to type to console \n%
  271.    ))) ^>^>%Foreground% %\n%
  272.    TYPE %Foreground% %\n%
  273.    %COMMENT:{i}= replace sprite with moved clone \n%
  274.    Set "obj=!Sub!" %\n%
  275.   ) %\n%
  276.  )Else Set Move.Dir=
  277. ========================================================================================================
  278.  Set "}2;!CNTRL!=%\E%[2;!CNTRL!H%\E%[33mControls:"
  279.  Set "}3;!CNTRL!=%\E%[3;!CNTRL!H  ▲    - Up"
  280.  Set "}4;!CNTRL!=%\E%[4;!CNTRL!H  ◄    - Left"
  281.  Set "}5;!CNTRL!=%\E%[5;!CNTRL!H  ▼    - Down"
  282.  Set "}6;!CNTRL!=%\E%[6;!CNTRL!H  ►    - Right"
  283.  Set "}7;!CNTRL!=%\E%[7;!CNTRL!HSpace  - Pause"
  284.  Set "}8;!CNTRL!=%\E%[8;!CNTRL!HEscape - Quit"
  285. ========================================================================================================
  286. ::: Commence Game. Define BORDER and SPRITE properties
  287. ========================================================================================================
  288. :start
  289. CLS
  290.  Set "lvl=1"
  291.  Setlocal EnableDelayedExpansion
  292.  %MSG:?= Generating Border ...%
  293. :::::: USAGE:
  294. ::: %Background.Border%{VTcolor}{.Xmin}{.Xmax}{.Ymin}{.Ymax}{.Char}{0|-1}
  295. ::: %Background.Border:CNTRL.Width=INTEGER%{VTcolor}{.Xmin}{.Xmax}{.Ymin}{.Ymax}{.Char}{0|-1}
  296. ::: Arg 7 {0|-1} 0=Border Collision Fatal; -1=Non Fatal
  297.  %Background.Border%{33}{1}{50}{1}{25}{#}{0}
  298. ::: CNTRL.Width Default = 20. Info Panel position at col .Xmax + 5
  299. :::   Console Lines .Ymax + 2
  300. ::: Console Columns .Xmax + 5 + CNTRL.Width
  301. ::: Console resizes during execution of Background.Border Macro using the above offsets.
  302. ::: Game Control / Info Panel. Default width should be modified as shown in above Usage if
  303. ::: strings in panel info exceed 19 characters length
  304.  %Update.BackGround%
  305.  Set "lvl=1"
  306. rem /* custom {Y} coordinate for each line of a sprite to be supplied during Def.Sprite Expansion */
  307. rem /* using substring modification to replace # with Integer Y value GTR .Ymin LSS .Ymax */
  308. ========================================================================================================
  309.  %Def.Sprite:#=1%{player}{32}{ O  }
  310.      %Def.Sprite%{player}{32}{MWM }
  311.      %Def.Sprite%{player}{32}{ ^^ }
  312. ========================================================================================================
  313.   %Def.Sprite:#=3%{rocks}{90}{            @                             }
  314.       %Def.Sprite%{rocks}{90}{            @                             }
  315.       %Def.Sprite%{rocks}{90}{             #                         #@ }
  316.       %Def.Sprite%{rocks}{90}{                                      @@  }
  317.  %Def.Sprite:#=17%{rocks}{90}{                 @       @                }
  318.       %Def.Sprite%{rocks}{90}{                @         @               }
  319.       %Def.Sprite%{rocks}{90}{                #                         }
  320.       %Def.Sprite%{rocks}{90}{                 @                        }
  321. ========================================================================================================
  322.   %Def.Sprite:#=1%{river}{36}{                        .ll           }
  323.   %Def.Sprite:#=2%{river}{36}{                          ^l.         }
  324.       %Def.Sprite%{river}{36}{                           .l         }
  325.       %Def.Sprite%{river}{36}{                             .l_      }
  326.       %Def.Sprite%{river}{36}{                            .r^)._    }
  327.       %Def.Sprite%{river}{36}{                        _^)` .l`  ^). }
  328.       %Def.Sprite%{river}{36}{                             l`     . }
  329.       %Def.Sprite%{river}{36}{                           _l.        }
  330.       %Def.Sprite%{river}{36}{                          .           }
  331. ========================================================================================================
  332.   %Def.Sprite:#=9%{mount}{37}{        x X   xXx }
  333.       %Def.Sprite%{mount}{37}{       XxXx  Xx X }
  334.       %Def.Sprite%{mount}{37}{      Xx  xXxxX  x}
  335. ========================================================================================================
  336.   %Def.Sprite:#=8%{money}{33}{                                       $}
  337.  %Def.Sprite:#=12%{money}{33}{                          $}
  338. ========================================================================================================
  339. rem /* varname[index#] naming convention can be used to define multiple sprites of a given type - allowing for random selection from an array of sprites */
  340.  %Def.Sprite:#=21%{AI[1]}{31}{                                           /+\}
  341.       %Def.Sprite%{AI[1]}{31}{                                            + }
  342.       %Def.Sprite%{AI[1]}{31}{                                           \+/}
  343. ========================================================================================================
  344. rem /* Show initial sprite positions */
  345. rem /* Display order: Collectable; Background; Player; Collideable */
  346. :::    Display order priority allows quick confirmation of sprite placement during development
  347.  (
  348.   %Show:obj=money%
  349.   %Show:obj=mount%
  350.   %Show:obj=river%
  351.   %Show:obj=rocks%
  352.   %Show:obj=player%
  353.   %Show:obj=AI[1]%
  354.  )>%Foreground%
  355.  TYPE %Foreground%
  356. rem /* Define valid keys */
  357.  %Def.Key%"-72=up" "-80=down" "-75=left" "-77=right" "27=escape" "32=space" "13=enter"
  358.  %Def.Key%"48=0" "49=1" "50=2" "51=3" "52=4" "53=5" "54=6" "55=7" "56=8" "57=9"
  359.  %MSG:?= Sprite Demo by T3RRY. Collect Both $ Coins%
  360.  For %%G in (start)Do < Nul Set /P "=%\E%[10;!CNTRL!H%\E%[32mPlayer: %%G%\E%[0m   %\E%!!!!!!H    %\E%[31mAI: waiting%\E%[0m   "
  361. ========================================================================================================
  362. ::: GAME LOGIC           /* DEMO of Sprite movement and Display only. Not intended as an Actual Game. */
  363. :level[1] :# Objectives ::::::::::::::::::::::::::::::::::::
  364. ::: Player Win  - capture both $ coins                   :::
  365. ::: Player Loss - player or AI experiences any collision :::
  366. ::: AI     Win  - AI Captures any $ coin                 :::
  367. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  368. rem /* input is taken and assessed within the loop ; all game actions repeat with each loop until a specified end condition is met */
  369. rem /* clear previous key; catch new input */
  370.   Set "Key="& %GetKey%
  371. rem /* ::: ?Key# insert/remove substring modification ':mode=dev' for/after debugging. Dev mode allows testing of key inputs to identify errorcode values returned */
  372. rem /* Expand ?Key# macro; test if captured errorlevel corresponds to a valid key */
  373.  %?Key#%
  374. rem /* Static Sprite Objects NOT collision tested should be refreshed each cycle PRIOR to movement */
  375.  %Show:obj=river%
  376. rem /* Test move in the current Direction for declared SPRITE OBJect valid against list of collision characters; Call :End on Collision */
  377. rem /* Previous sprite position overwritten with whitespace during Move.Sprite macro execution */
  378.  For %%G in (!Dir!)Do < Nul Set /P "=%\E%[10;!CNTRL!H%\E%[32mPlayer: %%G%\E%[0m   %\E%!!!!!!H    %\E%[31mAI: !.%%G!%\E%[0m     "
  379.  For %%M in (!Dir!)Do %Move.Sprite:obj=player%!%%M!{"@" "x" "+" "/" "\"}{"$"}
  380.  If "!captured!" == "1" Set /A "Playercoin+=1 + 0"
  381.  If "!valid!" == "0" ( Set "Win=Lost" & set ".Win=Won" & %G.O% 1)
  382. ::: GAME LOGIC OPTION :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  383. ::: Implement levels by using conditional tests that flag winning the current level jump to
  384. ::: a new label to define new sprites.
  385. ::: Before implementing a new level loop:
  386. :::   - endlocal environment to remove previous sprites and renew Setlocal EnableDelayedExpansion
  387. :::      [ Tunneling any variables For scoring etc ]
  388. :::     prior to defining the next batch of sprites - MUST be done to remove }Y;X definitions used
  389. :::     for collision testing.
  390.  If "!Playercoin!" == "2" (Set "Win=Won" & set ".Win=Lost" & %G.O:start=lvl[2]% 1)
  391. ::: %G.O:start=lvl[2]% Substution changes label to target from start to lvl[2] definition stage
  392. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  393. rem /* Simple AI sprite motion. AI moves in opposite direction to player */
  394.  For %%. in (!Dir!)Do For %%M in (!.%%.!)Do %Move.Sprite:obj=AI[1]%!%%M!{"@" "x" "O" "M" "^^"}{"$"}
  395.  If "!captured!" == "1" (Set "Win=Lost" & set ".Win=Won" & %G.O%)
  396.  If "!valid!" == "0" (Set "Win=Lost" & set ".Win=Lost" & %G.O%)
  397.  If /I "!Key!" == "escape" Goto :Quit
  398. Goto :level[1]
  399. =======================================================================================================
  400. ::: Demonstration of level implementation
  401. :lvl[2] :# Level specific definitions
  402. CLS
  403.  Set /A "lvl+=1+0"
  404.  Setlocal EnableDelayedExpansion
  405.  %MSG:?= Generating Border ...%
  406.  %Background.Border%{38;2;240;128;128}{1}{50}{1}{25}{#}{0}
  407.  %Update.BackGround%
  408. ========================================================================================================
  409.  %Def.Sprite:#=1%{player}{36}{ O  }
  410.      %Def.Sprite%{player}{36}{MWM }
  411.      %Def.Sprite%{player}{36}{ ^^ }
  412. ========================================================================================================
  413.   %Def.Sprite:#=5%{rocks}{38;2;160;82;45}{                  #@                    }
  414.       %Def.Sprite%{rocks}{38;2;160;82;45}{                 @#                   # }
  415.       %Def.Sprite%{rocks}{38;2;160;82;45}{                #                   @#@ }
  416.       %Def.Sprite%{rocks}{38;2;160;82;45}{                                      @@}
  417.  %Def.Sprite:#=17%{rocks}{38;2;160;82;45}{               @#@                      }
  418.       %Def.Sprite%{rocks}{38;2;160;82;45}{                @         @#            }
  419.       %Def.Sprite%{rocks}{38;2;160;82;45}{                           #@           }
  420. ========================================================================================================
  421.  %Def.Sprite:#=12%{river}{34}{      .ll     }
  422.       %Def.Sprite%{river}{34}{       ^l.    }
  423.       %Def.Sprite%{river}{34}{      .l      }
  424.       %Def.Sprite%{river}{34}{     .l_      }
  425.       %Def.Sprite%{river}{34}{   r^) ._     }
  426.       %Def.Sprite%{river}{34}{ .l`    ^).   }
  427.       %Def.Sprite%{river}{34}{        l` `. }
  428.       %Def.Sprite%{river}{34}{      _l   .^)}
  429.       %Def.Sprite%{river}{34}{          .r  }
  430. ========================================================================================================
  431.   %Def.Sprite:#=9%{mount}{37}{        x X   xXx }
  432.       %Def.Sprite%{mount}{37}{       XxXx  Xx X }
  433.       %Def.Sprite%{mount}{37}{      Xx  xXxxX  x}
  434. ========================================================================================================
  435.   %Def.Sprite:#=4%{money}{33}{                $}
  436.   %Def.Sprite:#=7%{money}{33}{                                        $}
  437. ========================================================================================================
  438.  %Def.Sprite:#=20%{AI[1]}{35}{                                           /+\}
  439.       %Def.Sprite%{AI[1]}{35}{                                           +++}
  440.       %Def.Sprite%{AI[1]}{35}{                                           \+/}
  441.       %Def.Sprite%{AI[1]}{35}{                                           \+/}
  442. ========================================================================================================
  443.  (
  444.   %Show:obj=money%
  445.   %Show:obj=mount%
  446.   %Show:obj=river%
  447.   %Show:obj=rocks%
  448.   %Show:obj=player%
  449.   %Show:obj=AI[1]%
  450.  ) >%Foreground%
  451.  TYPE %Foreground%
  452.  %Def.Key%"-72=up" "-80=down" "-75=left" "-77=right" "27=escape" "32=space" "13=enter"
  453.  %Def.Key%"48=0" "49=1" "50=2" "51=3" "52=4" "53=5" "54=6" "55=7" "56=8" "57=9"
  454.  %MSG:?= Sprite Demo by T3RRY. Collect Both $ Coins%
  455.  For %%G in (start)Do < Nul Set /P "=%\E%[10;!CNTRL!H%\E%[32mPlayer: %%G%\E%[0m   %\E%!!!!!!H    %\E%[31mAI: waiting%\E%[0m   "
  456. :level[2] :# Gameplay Loop
  457.   Set "Key="& %GetKey%
  458.  %?Key#%
  459.  %Show:obj=river%
  460.  For %%G in (!Dir!)Do < Nul Set /P "=%\E%[10;!CNTRL!H%\E%[!Player.Color!mPlayer: %%G%\E%[0m   %\E%!!!!!!H    %\E%[!AI[1].Color!mAI: !.%%G!%\E%[0m     "
  461.  For %%M in (!Dir!)Do %Move.Sprite:obj=player%!%%M!{"@" "x" "+" "/" "\"}{"$"}
  462.  If "!captured!" == "1" Set /A "Playercoin+=1 + 0"
  463.  If "!valid!" == "0" ( Set "Win=Lost" & set ".Win=Won" & %G.O%)
  464.  If "!Playercoin!" == "2" (Set "Win=Won" & set ".Win=Lost" & %G.O:start=Eof%)
  465.  For %%. in (!Dir!)Do For %%M in (!.%%.!)Do %Move.Sprite:obj=AI[1]%!%%M!{"@" "x" "O" "M" "^^"}{"$"}
  466.  If "!captured!" == "1" (Set "Win=Lost" & set ".Win=Won" & %G.O%)
  467.  If "!valid!" == "0" (Set "Win=Lost" & set ".Win=Lost" & %G.O%)
  468.  If /I "!Key!" == "escape" Goto :Quit
  469. Goto :level[2]
  470. =======================================================================================================
  471. ::: SCRIPT BREAK :# Functions below.
  472. =======================================================================================================
  473. :End
  474.  (
  475.   %Show:obj=player%
  476.   %Show:obj=AI[1]%
  477.  )>%Foreground%
  478.  TYPE %Foreground%
  479. rem /* Sound alert level over */
  480.  Echo/n|Choice /N /C:y 2> nul
  481.  %MSG:?= Level !lvl! !Win! %
  482.  For %%G in ("Win")Do < Nul Set /P "=%\E%[10;!CNTRL!H%\E%[32mPlayer: !%%~G!%\E%[0m   %\E%[11;!CNTRL!H    %\E%[31mAI: !.%%~G!%\E%[0m   "
  483.  Timeout /T 2 /Nobreak > Nul
  484.  <nul Set /P "=%\E%[!.End!;1H%\E%[?25h%\E%[31m{escape} %\E%[0m:%\E%[31m Quit%\E%[37m or %\E%[32mPress any Key to continue... "
  485. rem /* use substitution to remove /n no-wait switch from getkey macro execution; wait for input */
  486.  Set "Key="& %Getkey: /n=%
  487.  %?Key#%
  488.  If /I "!Key!" == "escape" (Call :Quit & Exit)
  489. :Quit
  490.  <nul Set /P "=%\E%[!.End!;1H%\E%[?25h%\E%[31m"
  491.  DEL "%Save.Dir%%~n0*.~tmp" 2> Nul
  492.  <nul Set /P "=%\E%[0m"
  493. Exit /B 0
Add Comment
Please, Sign In to add comment