Windows批处理文件街机游戏的优化

 书友37715123 发布于 2023-02-13 16:48

我制作了一个批处理文件游戏,它可以工作,但它是不稳定和丑陋的.我已经了解了线程,但我不想在我的第一个版本中实现它.在我开始用这个游戏做更高级的事情之前,我希望能够优化.我的问题是:我可以对这个游戏进行哪些优化,以便它不会变得不稳定,而且在显示屏上不会那么烦人.欢迎任何有关如何使其更快更清晰或占用更少内存的想法或意见,但是,请不要发布如下答案:"不要使用批处理""重写它(在这里插入语言)""用vb做这个部分-script"等...因为他们没有帮助,他们也没有回答这个问题.任何和所有非批评的仇恨批评都受到欢迎.

这是代码:

@setlocal enableextensions enabledelayedexpansion
@echo off
color 0a
mode con lines=35 cols=50
cls
set instructions=use a and d to move left and right, w to fire. use q to quit and p to pause.
set height=30
set length=         
set screen=50
set swidth=20
set amo=8
set lives=3
set 1=0
set 2=1
set 3=2
set 4=3
set 5=4
set 6=0
set 7=1
set 8=2
set 9=3
set 10=4

echo. What quality would you like?
echo.   1. fast, but the graphics suck!
echo.   2. medium both ways.
echo.   3. slow, but the graphics are better!
choice /n /c:123
set firequal=%errorlevel%00
cls
echo %instructions%
echo.
pause
cls

::main
:controls
cls
if %height% EQU 2 goto gameover
if %lives% LSS 1 goto gameover
cls
set /a shouldbomb+=1
set /a whenbomb=shouldbomb%%15
if %whenbomb% == 9 call :bomb
if '%ret%'=='1' exit /b
set ret=
cls
set alive=
for /l %%i in (1,1,10) do if defined %%i set alive=true
if not defined alive goto win
cls
for /l %%i in (1,1,5) do (
      if defined %%i (
     set /p a=[_]  nul 2>&1
)
call :checkshot
set /a shouldbomb+=1
set /a whenbomb=shouldbomb%%2
if %whenbomb% == 0 call :bomb
goto controls

:inactive
if %amo% LSS 10 set /a amo+=1
if !height! NEQ 2 set /a height-=1
call :bomb
goto controls

:bomb
:btop
set bombx=
for /l %%a in (1,1,10) do (
   if defined %%a (
     set /a randomnum=%random%%%5
     if '!%%a!'=='%randomnum%' (
        set /a "bombx=5*(!%%a!)"
     )
      )
   )
)
if not defined bombx goto btop
cls
set bomb= 
for /l %%b in (1,1,!bombx!) do (
      set bomb=!bomb! 
)
set /a bombh=height-1
for /l %%c in (1,1,!bombh!) do (
   cls
   for /l %%i in (1,1,5) do (
     if defined %%i (
        set /p a=[_]  nul 2>&1
)
if "%bomb%"   == "%length%"   call :looselife
if "%bomb% "  == "%length%"   call :looselife
if "%bomb%"   == "%length% "  call :looselife
if "%bomb%  " == "%length%"   call :looselife
if "%bomb%"   == "%length%  " call :looselife
exit /b

:strlen  
(   
    setlocal EnableDelayedExpansion
    set "s=!%~2!#"
    set "len=0"
    for %%P in (1024 512 256 128 64 32 16 8 4 2 1) do (
    if "!s:~%%P,1!" NEQ "" ( 
        set /a "len+=%%P"
        set "s=!s:~%%P!"
    )
    )
)
( 
    endlocal
    set "%~1=%len%"
    exit /b
)

:checkshot
call :strlen slen length
for /l %%i in (0,5,20) do (
   if '!slen!' == '%%i' (
      set /a hit=%%i
      set /a hit=hit/5+1
      set /a hit2=hit+5
      if not defined !hit2! set !hit!=
      if defined !hit2! set !hit2!=
   )
)
exit /b

:looselife
set /a lives-=1
set length=         
set 1=0
set 2=1
set 3=2
set 4=3
set 5=4
if %lives% GTR 1 timeout /nobreak 1 >nul 2>&1
exit /b

:win
cls
echo YOU WIN^!^!^!^!
echo.
echo GOOD JOB^!^!^!
echo.
pause
cls
exit /b

:gameover
cls
echo YOU LOOSE.
echo.
echo PLEASE TRY AGAIN.
echo.
pause
cls
set ret=1

预先感谢您的任何帮助.

PS我正在写这个游戏来说服朋友除了html之外还要学习一些东西,虽然批次不是最好的,但他使用的是Windows,他现在只会做一些简单的事情.他十二岁,所以我觉得批次是最好的选择.

2 个回答
  • 一些优化

    1)最好使用好的变量名.

    名称,如1,2...... 10是非常糟糕的,没有人知道他们是什么好,连你自己也不会在一个月内记住.
    然后它也是一个坏主意,因为它可能有许多副作用,使用以数字开头的变量,批处理中有许多这些只会失败.

    2)您应该在输出之前将输出组合成完整的行.
    那你就不需要set/pecho,而且速度更快.

    3)对:strlen应该避免的函数调用,调用都很昂贵,在你的情况下,应该可以在没有strlen的情况下解决相同的问题.

    4)该功能:checkshot不需要for循环.
    我不明白你在那里尝试做什么,但你测试slen它是否是5的多重.
    这可以解决

    set /a remainder=slen %% 5
    if !remainder! EQU 0 (
      ...
    

    5)按照dbenham的提示:-)

    2023-02-13 16:50 回答
  • 你绝对可以大大改善.我知道,因为我已经使用纯Windows批量生成了一个非常流畅且可玩的SNAKE版本!尝试一下 - 我想你会对那些发霉的老批可以做的事感到惊讶和印象:-)

    当然链接有代码,但它也有一些指针,我曾经用过一些技术来表现得很好.仔细阅读整个第一篇文章,并阅读其余的重点发展.

    优化是一个很大的主题.我将简单地总结一下,而不是重复这里的所有信息.请点击链接了解更多详情.

    1)最小化GOTO和CALL语句.

    对于传统批处理函数调用的主要速度改进,我们在DosTips 开发了带有参数的批处理宏.第一个宏观链接产生了许多重要概念.但是,我在游戏中实际使用的宏形式使用了附加参数的更优雅的解决方案.

    GOTO循环可以由在新进程中运行的无限FOR循环替换.您可以通过退出子进程来摆脱循环.

    2)以非阻塞方式大大改善按键检测.

    批量的一个主要限制是无法在不阻碍游戏进程的情况下轻松检测按键.可以通过使用两个进程来解决问题,这两个进程都在同一个控制台窗口中运行.控制器进程读取按键并通过文本文件将它们发送到主游戏进程.控制器具有多种操作模式.游戏过程通过另一个文本文件向控制器发送命令.该技术需要仔细协调输入和输出重定向.

    XP上没有CHOICE命令.DosTips的一些人发现了如何使用XCOPY来模拟CHOICE的大部分功能,它适用于所有版本的Windows.很酷!

    3)屏幕画

    逐个字符构建屏幕非常慢.使用具有固定长度的字符串"数组"构建初始屏幕要快得多.字符串中的每个字符代表一个"像素".字符串中的位置表示X坐标,字符串行号表示Y坐标.通常,对于任何给定的屏幕刷新,只有少数像素发生变化.可以通过使用具有简单子串操作的SET来"绘制"像素.然后可以使用CLS快速刷新整个屏幕,然后使用屏幕阵列中每行的ECHO.

    4)流畅的动画

    执行游戏逻辑和屏幕绘图所需的工作量可能会根据当前游戏背景而有很大差异.但是你希望动画流畅.您可以改为测量自上次更新屏幕以来的时间,而不是在每轮运动之间有固定的延迟.只有在预定的时间过去后才会继续.只要所有游戏逻辑和绘图都可以在延迟时间段内发生,那么动画将始终是平滑的.

    这是描述时序逻辑的伪代码:

    initialize delayTime
    initialize previousTime
    loop (
      get currentTime
      set diffTime = currentTime - previousTime
      if diffTime >= delayTime (
        set previousTime = currentTime
        perform user input, game logic, and screen refresh
      )
    )
    

    这是实际的代码,用于计算自上次移动以来经过的时间.currentTime(t2)从午夜开始测量为厘秒(1/100秒).它使用FOR/F和基本数学进行解析和计算.tDiff如果previousTime(t1)在午夜之前并且currentTime(t2)在午夜之后,则diffTime()将为负.如果为负数,则将1天添加到diffTime以获得正确的时间间隔.

    %=== 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
    

    还有更多可以讨论的内容.尝试SNAKE.BAT游戏,研究帖子和代码,看看你的想象力可以带你去哪里.

    2023-02-13 16:51 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有