Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can definitely improve things considerably. I know, because I have already produced a very smooth and playable version of <a href="http://www.dostips.com/forum/viewtopic.php?f=3&amp;t=4741">SNAKE using pure Windows batch</a>! Give it a try - I think you will be surprised and impressed with what musty old batch can do :-)</p> <p>Of course the link has the code, but it also has pointers on some of the techniques I used to make the came perform so well. Read the entire first post carefully, and read the remainder of the thread for some additional important developments.</p> <p>Optimization is a large topic. Rather than repeat all the information here, I will simply summarize. Follow the link for more details.</p> <p>1) Minimize GOTO and CALL statements.</p> <ul> <li><p>For major speed improvements over traditional batch function calls, we developed <a href="http://www.dostips.com/forum/viewtopic.php?f=3&amp;t=1827">batch macros with arguments</a> at DosTips. That first macro link develops a number of important concepts. However, the macro form I actually used in the game uses a more <a href="http://www.dostips.com/forum/viewtopic.php?f=3&amp;t=2518">elegant solution with arguments appended</a>.</p></li> <li><p>A GOTO loop can be replaced by an infinite FOR loop that runs in a new process. You break out of the loop by EXITing the child process.</p></li> </ul> <p>2) Greatly improve key press detection in a non-blocking way.</p> <ul> <li><p>A major limitation of batch is the inability to easily detect a keypress without blocking progress of the game. The problem can be solved by using two processes, both running in the same console window. The controller process reads keypresses and sends them to the main game process via a text file. The controller has multiple modes of operation. The game process sends commands to the controller via another text file. This technique requires careful coordination of input and output redirection.</p></li> <li><p>The CHOICE command is not available on XP. Some folks at DosTips discovered how to use XCOPY to simulate most of the features of CHOICE, and it works on all versions of Windows. Very cool!</p></li> </ul> <p>3) Screen painting</p> <ul> <li>Building the screen character by character is extremely slow. It is much faster to build the initial screen once, using an "array" of strings with fixed length. Each character within a string represents one "pixel". The position within a string represents the X coordinate, and the string row number represents the Y coordinate. Generally, only a few pixels change for any given screen refresh. Pixels can be "plotted" by using SET with simple substring operations. The entire screen can then be quickly refreshed using CLS followed by ECHO of each line in the screen array.</li> </ul> <p>4) Smooth animation</p> <ul> <li>The amount of work required to perform game logic and screen plotting can vary significantly depending on the current game context. But you want the animation to be smooth. Rather than have a fixed delay between each round of movement, you can instead measure the time since the screen was last updated. Only continue when a pre-determined amount of time has elapsed. As long as all game logic and plotting can occur within the delay time period, then the animation will always be smooth.</li> </ul> <p>Here is pseudo code that describes the timing logic:<br/></p> <pre><code>initialize delayTime initialize previousTime loop ( get currentTime set diffTime = currentTime - previousTime if diffTime &gt;= delayTime ( set previousTime = currentTime perform user input, game logic, and screen refresh ) ) </code></pre> <p>And here is actual code that computes the elapsed time since last movement. The currentTime (<code>t2</code>) is measured as centiseconds (1/100 second) since midnight. It is parsed and computed using FOR /F and basic math. The diffTime (<code>tDiff</code>) will be negative if the previousTime (<code>t1</code>) is before midnight and the currentTime (<code>t2</code>) is after midnight. If negative, then 1 day is added to diffTime to get the correct time interval.</p> <pre><code>%=== compute time since last move ===% for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do set /a "t2=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100, tDiff=t2-t1" if !tDiff! lss 0 set /a tDiff+=24*60*60*100 </code></pre> <p>There is so much more that can be discussed. Try the SNAKE.BAT game, study the post and the code, and see where your imagination can take you.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload