Board logo

标题: [游戏娱乐] 2016版纯批处理俄罗斯方块 [打印本页]

作者: happy886rr    时间: 2016-10-3 11:59     标题: 2016版纯批处理俄罗斯方块

本帖最后由 happy886rr 于 2018-11-11 13:16 编辑

经典俄罗斯方块游戏,再次用批处理和C重写。动态显示,迅捷如闪电。预留Settings设置,参数可自行调整。

操控说明
  1. A左D右;W旋转;S加速下落;
  2. Q退出;P暂停;方向键继续;
复制代码
效果图

[2016/10/6] C语言版 C-Version 1.0
  1. @echo off
  2. ::**************Happy's Tetris C语言版******
  3. REM 使用说明:
  4. REM A左D右;W旋转;S加速下落;
  5. REM Q退出;P暂停;任意键继续;
  6. ::**************Settings高级设置************
  7. REM 设置窗体
  8.   title &mode con cols=35 lines=25&color F0
  9. REM 设置时钟T(毫秒)
  10.   set T=300
  11. REM 按键黏度N(微秒)
  12.   set N=5
  13. REM 设置旋转体系:填TGM 或 SRS
  14.   set MODE=TGM
  15. ::**************Base64转码******************
  16. :START
  17. cls&Tetris.exe %N% %T% %MODE%&&exit /b||certutil -decode "%~f0" "%~dp0Tetris.exe"
  18. goto START
  19. -----BEGIN CERTIFICATE-----
  20. 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
  21. -----END CERTIFICATE-----
复制代码
源码Tetris.c

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <Windows.h>

/**********初始化参数************/

int i,j,N,T,F,J,X,Y,dx,dy,  KEY_V,  Cache1,Cache2,NU,NI,RU,RI,  P_X,P_Y,POS_Y_MAX,  LEVEL=1,SCORE=0,  P[4],  POINT_V[12][22],  MARK[21],  FLAG[5]={0,0,0,1,0};

int TGM[7][4]={{0x159D,0x89AB,0x159D,0x89AB},{0x126A,0x4856,0x159A,0x4526},{0x926A,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x5926,0x0156,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x156A,0x4152,0x156A,0x4152}};

int SRS[7][4]={{0x159D,0x89AB,0x26AE,0x4567},{0x0159,0x4856,0x159A,0x4526},{0x8159,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x4815,0x459A,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x0459,0x8596,0x156A,0x4152}};

/**********光标位置函数**********/

void Pos(int x,int y)

{

        COORD pos;

        HANDLE hOutput;

        pos.X=2*x;

        pos.Y=y;

        hOutput=GetStdHandle(STD_OUTPUT_HANDLE);

        SetConsoleCursorPosition(hOutput,pos);

}

void HideCursor()

{

        CONSOLE_CURSOR_INFO cursor_info={1,0};

        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

}

/**********初始化界面************/

void CreatUI()

{

        int i,j,BOUNDARY;

        printf("┏━━━━━━━━━━┓\n");

        for(j=1;j<=20;j++) {

                if     (j==3){printf("┃          ┃LEVEL:1\n");}

                else if(j==5){printf("┃          ┃SCORE:0\n");}

                else if(j==7){printf("┃          ┃NEXT   \n");}

                else         {printf("┃          ┃\n");}

        }

        printf("┗━━━━━━━━━━┛\n");

        printf(" CopyRight@2016~2018 BY HAPPY\n");

        for(j=1;j<=21;j++){

                for(i=0;i<=11;i++){

                        BOUNDARY=i*(i-11)*(j-21);

                        if(BOUNDARY==0){

                                POINT_V[i][j]=1;

                        }else{

                                POINT_V[i][j]=0;

                        }               

                }

        }

}

/**********按键获取**************/

int Getkey(int N,int T)

{

        if(KEY_V==115){return 115;}

        int start=clock();

         do{

                 if(kbhit()){

                         KEY_V=(int)(getch());

                         if(KEY_V<97){KEY_V+=32;}

                         return KEY_V;

                 }

                for(i=0;i<=N;i++);

        }while((clock()-start)<T);

        dy=1;

        return -1;

}

/***********块体转置*************/

int Rote(int S, int I)

{

        return (F==0)?TGM[S][(I+4)%4]:SRS[S][(I+4)%4];

}

/***********擦除显示*************/

int Display(int x, int y, int CAC, int Mode)

{

        for(j=0;j<=3;j++){

                P[j]=CAC&0xF, CAC>>=4;

                if     (Mode==1){Pos((P[j]>>2)+x,(P[j]&0x3)+y);printf("■");}

                else if(Mode==0){Pos((P[j]>>2)+x,(P[j]&0x3)+y);printf(" ");}

        }

        return 0;

}

/***********固化块体*************/

int DoBlocks()

{

        //~~~游戏结束

        if(Y<2){

                Pos(1,22);printf("GAME OVER!");

                exit(0);

        }

        //~~~固化块体

        POS_Y_MAX=0, FLAG[3]=1;

        for(j=0;j<=3;j++){

                P_X=(P[j]>>2)+X,P_Y=(P[j]&0x3)+Y;

                if(POS_Y_MAX<P_Y){POS_Y_MAX=P_Y;}

                POINT_V[P_X][P_Y]=1;

        }

        //~~~关卡得分

        for(j=Y;j<=POS_Y_MAX;j++){

                FLAG[2]=1;

                for(i=1;i<=10;i++){

                        if(POINT_V[i][j]==0){FLAG[2]=0;}

                }

                if(FLAG[2]){

                        SCORE+=10,MARK[j]=1;

                        if(SCORE==400){

                                SCORE=0,LEVEL+=1,T-=100;

                                FLAG[4]=1;      

                        }

                }

        }

        //~~~极品消行

        for(j=20;j>=5;j--){

                if(FLAG[4]){

                        for(i=1;i<=10;i++){

                                POINT_V[i][j]=0;

                                Pos(i,j);printf(" ");

                        }

                }

                else if(MARK[j])

                {

                        MARK[j]=0,J=j-1;

                        for(N=1;N<=3;N++){

                                if(MARK[J]){J--;}

                        }

                        MARK[J]=1;

                        for(i=1;i<=10;i++){

                                Pos(i,j);

                                if(POINT_V[i][j]=POINT_V[i][J]){

                                        printf("■");

                                }else{

                                        printf(" ");

                                }

                        }

                }

        }

        FLAG[4]=0;

        return 0;

}

/***********碰撞检测*************/

int CheckCollision()

{                              

        for(j=0;j<=3;j++){

                P_X=(P[j]>>2)+X+dx,P_Y=(P[j]&0x3)+Y+dy;

                if(POINT_V[P_X][P_Y]){

                        if(dx!=0){return 1;}

                        if(dy){

                                DoBlocks();

                                Pos(12,3);printf("LEVEL:%-3d",LEVEL);

                                Pos(12,5);printf("SCORE:%-3d",SCORE);

                                return 2;

                        }

                        if(KEY_V==119){FLAG[0]=1;}

                }

        }

        return 0;

}

/***********循环核心*************/

int GameCycle(int N, int T, int F)

{

        srand((unsigned)time(NULL));RU=rand()%7,RI=(rand()%4);

        while(1){

                if(FLAG[3]){

                        Display(12,8,Rote(RU,RI),0);

                        X=4,Y=1, NU=RU,NI=RI, RU=rand()%7,RI=(rand()%4), FLAG[3]=0,KEY_V=0;

                        Display(12,8,Rote(RU,RI),1);

                        Display(X, Y,Rote(NU,NI),1);

                }

                dx=0,dy=0;      

                KEY_V=Getkey(N,T);

                  if(KEY_V==119){

                          NI++;

                         Display(X,Y,Rote(NU,NI),2);

                }//旋W

                else if(KEY_V==115){dy= 1;}//下S

                else if(KEY_V==97 ){dx=-1;}//左A

                else if(KEY_V==100){dx= 1;}//右D

                else if(KEY_V==112){getch(); }//暂停P

                else if(KEY_V==113){return 0;}//退出Q

                if(dx!=0 || dy!=0 || KEY_V==119){

                        if(!CheckCollision()){

                                if(FLAG[0]){

                                        NI--,FLAG[0]=0;

                                        Display(X,Y,Rote(NU,NI),0);

                                }

                                else if(KEY_V==119){

                                        Display(X,Y,Rote(NU,NI-1),0);

                                }else{

                                        Display(X,Y,Rote(NU,NI),0);

                                }

                                Display(X+dx,Y+dy,Rote(NU,NI),1);

                                X+=dx,Y+=dy;

                        }

                }

        }

        return 0;

}

/**********Main主函数***********/

int main(char argc, char* argv[])

{

        if(argc!=4){

                printf("参数错误。\n");

                return 1;

        }else{

                if     (!strcasecmp(argv[3],"TGM")){F=0;}

                else if(!strcasecmp(argv[3],"SRS")){F=1;}

                else{return 2;}

                N=atoi(argv[1]);

                T=atoi(argv[2]);

        }

        HideCursor();

        CreatUI();

        GameCycle(N,T,F);

        return 0;

}


一一一
一一一
一一一
一一一一一一一一一一一一一一一以下是批处理版本一一一一一一一一一一一一一一一一
[2016/10/4] Version 2.1新修版,修正NEXT下一个图块显示异常。采用16位数据处理,达到或接近C语言的运行速度。打造最快bat俄罗斯方块。
  1. @echo off
  2. ::**************Happy's俄罗斯方块***********
  3. REM 使用说明:
  4. REM A左D右;W旋转;S加速下落;
  5. REM Q退出;P暂停;方向键继续;
  6. ::**************Settings高级设置************
  7. REM 设置窗体
  8.   title &setlocal enabledelayedexpansion
  9.   mode con cols=35 lines=25&color F0
  10. REM 开启防闪烁,用于画质增强
  11.   set F1=1
  12. REM 设置时钟T, 越小下落越快
  13.   set T=190
  14. REM 默认皮肤
  15.   set "SKIN= ■"
  16. REM 设置旋转体系:依次为TGM、SRS(第二代超级形码)
  17. ::set "SHAPE=0x159D0x89AB0x159D0x89AB0x126A0x48560x159A0x45260x926A0x456A0x15920x04560x48590x48590x48590x48590x59260x01560x59260x01560x41590x45960x15960x41560x156A0x41520x156A0x4152"
  18.   set "SHAPE=0x159D0x89AB0x26AE0x45670x01590x48560x159A0x45260x81590x456A0x15920x04560x48590x48590x48590x48590x48150x459A0x59260x01560x41590x45960x15960x41560x04590x85960x156A0x4152"
  19. ::**************方向控制台******************
  20. if "%1"=="CONTROLP" (
  21. title &MODE CON cols=15 lines=1
  22. for /l %%i in (1,1,100000) do (
  23. set "KEY="
  24. for /f "delims=" %%a in ('xcopy /W . 2^>NUL') do (
  25. if not defined KEY (
  26. set "KEY=%%a"&set "KEY=!KEY:~-1!"
  27. echo %%i!KEY!>key.ini&if /i "!KEY!"=="Q" (exit)
  28. )
  29. )
  30. )
  31. )
  32. start "" "%~f0" CONTROLP
  33. ::**************先导程序********************
  34. REM 准备元素
  35. set/a "LEVEL=1,SCORE=0, RU=!random!%%7,RI=(!random!%%4)*6"
  36. for /l %%N in (0,24,144) do (set/a "N=%%N/24"&set "SHAPE!N!=!SHAPE:~%%N,24!")
  37. for /l %%N in (0,1,1   ) do (set "E%%N=!SKIN:~%%N,1!")
  38. for /l %%N in (1,1,10  ) do (set "LINES=!LINES!━"   )
  39. for /l %%N in (1,1,300 ) do (set "SPACE=!SPACE!"    )
  40. REM 构建显存
  41. :DISPLAY_RAM
  42. for /l %%j in (0,1,21) do (
  43. set "#[%%j]=1"
  44. for /l %%i in (0,1,11) do (
  45. set/a "BOUNDARY=(%%i)*(%%i-11)*(%%j-21)"
  46. if !BOUNDARY! equ 0 (set "P[%%i][%%j]=1") else (set "P[%%i][%%j]=0")
  47. )
  48. )
  49. ::**************主体程序********************
  50. REM ~~~随机块体
  51. :RANDOM_SHAPE
  52. set/a "NU=RU,NI=RI, RU=!random!%%7,RI=(!random!%%4)*6, X=4,Y=1"
  53. echo RW>key.ini
  54. REM ~~~计数面板
  55. set "V1=!LEVEL!    "
  56. set "V2=!SCORE!    "
  57. set "READM[3]=LEVEL:!V1:~0,3!"
  58. set "READM[5]=SCORE:!V2:~0,3!"
  59. set "READM[7]=NEXT"
  60. REM ~~~读取按键
  61. :READKEY
  62. set/a "Dx=0,Dy=0"
  63. set/p KEY=<key.ini
  64. if /i "!KEY:~-1!"=="P" (goto :READKEY)
  65. if not "!PRE_KEY!"=="!KEY!" (
  66. set PRE_KEY=!KEY!
  67. if /i "!KEY:~-1!"=="A" (set "Dx=-1")
  68. if /i "!KEY:~-1!"=="D" (set "Dx=1" )
  69. if /i "!KEY:~-1!"=="W" (
  70. set "Cache=!SHAPE%NU%:~%NI%,6!"
  71. set/a "Xf=X,NI+=6,NI%%=24"
  72. REM ~~~16进制超级转码
  73. for /l %%j in (0,1,3) do (
  74. set/a "POS[%%j]=Cache&0xF, Cache=Cache>>4" 2>NUL
  75. )
  76. if "!KEY!"=="RW" (
  77. set "Cache2=!SHAPE%RU%:~%RI%,6!"
  78. for /l %%J in (0,1,3) do (
  79. set/a "RPOS[%%J]=Cache2&0xF, Cache2=Cache2>>4" 2>NUL
  80. for /l %%I in (0,1,3) do (
  81. set "R[%%I][%%J]=0"
  82. )
  83. )
  84. for %%p in (!RPOS[0]!,!RPOS[1]!,!RPOS[2]!,!RPOS[3]!) do (
  85. set/a "RPOS_X=%%p>>2,RPOS_Y=%%p&0x3"
  86. set "R[!RPOS_X!][!RPOS_Y!]=1"
  87. )
  88. for /l %%J in (0,1,3) do (
  89. set "TP="
  90. for /l %%I in (0,1,3) do (
  91. set "TP=!TP!!R[%%I][%%J]!"
  92. )
  93. set "TP=!TP:0=%E0%!"
  94. set "TP=!TP:1=%E1%!"
  95. set/a "SN=%%J+8"
  96. set "READM[!SN!]=!TP!"
  97. )
  98. echo WO>key.ini
  99. for /l %%j in (8,1,11) do (set/a "#[%%j]=1")
  100. )
  101. goto :DATA_PROCESSING
  102. )
  103. if /i "!KEY:~-1!"=="Q" (exit)
  104. )
  105. if /i "!KEY:~-1!"=="S" (set "Dy=1"&goto :DATA_PROCESSING)
  106. REM ~~~下落体系
  107. if !Mark! equ 0 (
  108. set "Mark=1"
  109. set "T1=!time:~9,2!"
  110. ) else (
  111. set/a "TS=2!time:~9,2!-1!T1!"
  112. set/a "TS=1!TS:~-2!"
  113. if !TS! lss !T! (set "Dy=0") else (set/a "Dy=1,Mark=0")
  114. )
  115. if !Dx! equ 0 if !Dy! equ 0 (goto :READKEY)
  116. REM ~~~数据处理
  117. :DATA_PROCESSING
  118. SETLOCAL
  119. for %%p in (!POS[0]!,!POS[1]!,!POS[2]!,!POS[3]!) do (
  120. set/a "POS_X=(%%p>>2)+X+Dx,POS_Y=(%%p&0x3)+Y+Dy"
  121. set/a "CHE=P[!POS_X!][!POS_Y!]"
  122. if !CHE! equ 0 (
  123. set "P[!POS_X!][!POS_Y!]=1"
  124. ) else (
  125. if !Dx! neq 0 (
  126. ENDLOCAL
  127. goto :READKEY
  128. )
  129. if !Dy! equ 1 (
  130. ENDLOCAL
  131. if !Y! lss 2 (
  132. echo GAME OVER!
  133. ping -n 2 127.1>NUL
  134. goto :DISPLAY_RAM
  135. )
  136. REM ~~~固化块体
  137. set "POS_Y_MAX=0"
  138. for %%P in (!POS[0]!,!POS[1]!,!POS[2]!,!POS[3]!) do (
  139. set/a "POS_X=(%%P>>2)+X,POS_Y=(%%P&0x3)+Y"
  140. if !POS_Y_MAX! lss !POS_Y! (set "POS_Y_MAX=!POS_Y!")
  141. set "P[!POS_X!][!POS_Y!]=1"
  142. )
  143. REM ~~~关卡得分
  144. for /l %%J in (!Y!,1,!POS_Y_MAX!) do (
  145. set "TP="
  146. for /l %%I in (1,1,10) do (
  147. set "TP=!TP!!P[%%I][%%J]!"
  148. )
  149. if "!TP!"=="1111111111" (
  150. set/a "SCORE+=10"
  151. set "#%%J=1"
  152. if !SCORE! equ 400 (
  153. for /l %%N in (!Y!,1,!POS_Y_MAX!) do (set "#%%N=")
  154. set/a "SCORE=0,LEVEL+=1,T-=10"
  155. goto :DISPLAY_RAM
  156. )
  157. )
  158. )
  159. REM ~~~极品消行
  160. for /l %%J in (20,-1,5) do (
  161. if defined #%%J (
  162. set "#%%J="
  163. set/a "MarkJ=%%J-1, GK=1"
  164. for /l %%N in (1,1,3) do (
  165. if defined #!MarkJ! (set/a "MarkJ-=1")
  166. )
  167. set "#!MarkJ!=1"
  168. for /l %%I in (1,1,10) do (
  169. set/a "P[%%I][%%J]=P[%%I][!MarkJ!]"
  170. )
  171. )
  172. )
  173. if defined GK (for /l %%J in (20,-1,5) do (set "#[%%J]=1")&set "GK=")
  174. goto :RANDOM_SHAPE
  175. )
  176. if /i "!KEY:~-1!"=="W" (
  177. ENDLOCAL
  178. echo OW>key.ini
  179. set/a "NI=(NI+12)%%24"
  180. goto :READKEY
  181. )
  182. )
  183. )
  184. REM ~~~绘图引擎
  185. if !F1! equ 1 (2>NUL echo !SPACE!&set/p=<NUL) else (cls)
  186. echo ┏%LINES%┓
  187. for /l %%j in (0,1,5) do (set/a "MARK_Y=Y+%%j,#[!MARK_Y!]=1")
  188. for /l %%j in (1,1,20) do (
  189. if not defined #[%%j] (
  190. echo;
  191. ) else (
  192. set "TP="
  193. for /l %%i in (1,1,10) do (set "TP=!TP!!P[%%i][%%j]!")
  194. set "TP=!TP:1=%E1%!"
  195. set "TP=!TP:0=%E0%!"
  196. echo ┃!TP!┃!READM[%%j]!
  197. )
  198. )
  199. echo ┗%LINES%┛
  200. echo  CopyRight@2016~2018 BY HAPPY
  201. ENDLOCAL&for /l %%j in (1,1,20) do (set "#[%%j]=")
  202. set/a "X+=Dx,Y+=Dy"
  203. goto :READKEY
复制代码
一一一
一一一
一一一
一一一
一一一一一一一一一一一一一一一以下是过去的旧版本一一一一一一一一一一一一一一一一
[2016/10/3] Version 1.0初版
  1. @echo off
  2. ::**************Happy's俄罗斯方块***********
  3. REM 使用说明:
  4. REM A左D右;W旋转;S加速下落;
  5. REM Q退出;P暂停;方向键继续;
  6. ::**************Settings高级设置************
  7. REM 设置窗体
  8.   title &setlocal enabledelayedexpansion
  9.   mode con cols=35 lines=25&color F0
  10. REM 开启防闪烁,用于画质增强
  11.   set F1=1
  12. REM 设置时钟T, 越小下落越快
  13.   set T=130
  14. REM 默认皮肤
  15.   set "SKIN= ■"
  16. REM 设置旋转体系:依次为TGM、SRS
  17. ::set "SHAPE=0x0F000x22220x0F000x22220x08E00x64400x0E200x44C00x02E00x44600x0E800xC4400x66000x66000x66000x66000x06C00x8C400x06C00x8C400x4E000x46400x0E400x4C400x0C600x4C800x0C600x4C80"
  18.   set "SHAPE=0x0F000x22220x00F00x44440x8E000x64400x0E200x44C00x2E000x44600x0E800xC4400x66000x66000x66000x66000x6C000x46200x06C00x8C400x4E000x46400x0E400x4C400xC6000x26400x0C600x4C80"
  19. ::**************方向控制台******************
  20. if "%1"=="CONTROLP" (
  21. title &MODE CON cols=15 lines=1
  22. for /l %%i in (1,1,100000) do (
  23. set "key="
  24. for /f "delims=" %%a in ('xcopy /W . 2^>NUL') do (
  25. if not defined key (
  26. set "key=%%a"&set "key=!key:~-1!"
  27. echo %%i!key!>key.ini&if /i "!key!"=="Q" (exit)
  28. )
  29. )
  30. )
  31. )
  32. start "" "%~f0" CONTROLP
  33. ::**************先导程序********************
  34. REM 准备元素
  35. set/a "LEVEL=1,SCORE=0, RU=!random!%%7,RI=(!random!%%4)*6"
  36. for /l %%N in (0,24,144) do (set/a "N=%%N/24"&set "SHAPE!N!=!SHAPE:~%%N,24!")
  37. for /l %%N in (0,1,1   ) do (set "P%%N=!SKIN:~%%N,1!")
  38. for /l %%N in (1,1,10  ) do (set "LINES=!LINES!━"   )
  39. for /l %%N in (1,1,300 ) do (set "SPACE=!SPACE!"    )
  40. REM 构建显存
  41. :DISPLAY_RAM
  42. for /l %%j in (0,1,21) do (
  43. set "#[%%j]=1"
  44. for /l %%i in (0,1,11) do (
  45. set/a "BOUNDARY=(%%i)*(%%i-11)*(%%j-21)"
  46. if !BOUNDARY! equ 0 (set "POINT[%%i][%%j]=1") else (set "POINT[%%i][%%j]=0")
  47. )
  48. )
  49. ::**************主体程序********************
  50. REM ~~~随机块体
  51. :RANDOM_SHAPE
  52. set/a "NU=RU,NI=RI, RU=!random!%%7,RI=(!random!%%4)*6, X=4,Y=1"
  53. echo RW>key.ini
  54. REM ~~~计数面板
  55. set "READM[3]=LEVEL:!LEVEL!"
  56. set "READM[5]=SCORE:!SCORE!"
  57. set "READM[7]=NEXT :"
  58. REM ~~~读取按键
  59. :READKEY
  60. set/a "dx=0,dy=0"&set/p key=<key.ini
  61. if /i "!key:~-1!"=="P" (goto :READKEY)
  62. if not "!PRE_KEY!"=="!key!" (
  63. set PRE_KEY=!key!
  64. if /i "!key:~-1!"=="A" (set "dx=-1")
  65. if /i "!key:~-1!"=="D" (set "dx=1" )
  66. if /i "!key:~-1!"=="W" (
  67. set "Cache=!SHAPE%NU%:~%NI%,6!"
  68. set/a "Xf=X,NI+=6,NI%%=24"
  69. if "!key!"=="RW" (set "Cache2=!SHAPE%RU%:~%RI%,6!")
  70. REM ~~~16进制旋转
  71. for /l %%j in (3,-1,0) do (
  72. set/a "DIV[3][%%j]=(Cache&0x1), DIV[2][%%j]=(Cache&0x2)>>0x1, DIV[1][%%j]=(Cache&0x4)>>0x2, DIV[0][%%j]=(Cache&0x8)>>0x3, Cache=Cache>>0x4"
  73. if "!key!"=="RW" (
  74. set/a "RDIV[3][%%j]=(Cache2&0x1), RDIV[2][%%j]=(Cache2&0x2)>>0x1, RDIV[1][%%j]=(Cache2&0x4)>>0x2, RDIV[0][%%j]=(Cache2&0x8)>>0x3, Cache2=Cache2>>0x4, RDI=%%j+8"
  75. set "RDISPLAY[%%j]=!RDIV[0][%%j]!!RDIV[1][%%j]!!RDIV[2][%%j]!!RDIV[3][%%j]!"
  76. set "RDISPLAY[%%j]=!RDISPLAY[%%j]:1=%P1%!"&set "READM[!RDI!]=!RDISPLAY[%%j]:0=%P0%!"
  77. )
  78. )
  79. if "!key!"=="RW" (echo WO>key.ini)
  80. goto :DATA_PROCESSING
  81. )
  82. if /i "!key:~-1!"=="Q" (exit)
  83. )
  84. if /i "!key:~-1!"=="S" (set "dy=1"&goto :DATA_PROCESSING)
  85. REM ~~~下落体系
  86. if !Mark! equ 0 (
  87. set "Mark=1"
  88. set "T1=!time:~9,2!"
  89. ) else (
  90. set/a "TS=2!time:~9,2!-1!T1!"
  91. set/a "TS=1!TS:~-2!"
  92. if !TS! lss !T! (set "dy=0") else (set/a "dy=1,Mark=0")
  93. )
  94. if !dx! equ 0 if !dy! equ 0 (goto :READKEY)
  95. REM ~~~数据处理
  96. :DATA_PROCESSING
  97. set/a "CYC=Y+4"
  98. SETLOCAL
  99. for /l %%j in (!Y!,1,!CYC!) do (
  100. set "#[%%j]=1"
  101. set "DISPLAY[%%j]="
  102. for /l %%i in (0,1,11) do (
  103. set/a "XV=%%i-X-dx,YV=%%j-Y-dy"
  104. if defined  DIV[!XV!][!YV!] (
  105. set/a "CHE1=DIV[!XV!][!YV!]&POINT[%%i][%%j],CHE2=DIV[!XV!][!YV!]|POINT[%%i][%%j]"
  106. if !CHE1! equ 0 (
  107. set "POINT[%%i][%%j]=!CHE2!"
  108. ) else (
  109. if !dx! neq 0 (
  110. ENDLOCAL
  111. goto :READKEY
  112. )
  113. if !dy! equ 1 (
  114. ENDLOCAL
  115. if !Y! lss 4 (goto GAME_OVER)
  116. REM ~~~固化块体
  117. for /l %%J in (!CYC!,-1,!Y!) do (
  118. set "DISPLAY[%%J]="
  119. for /l %%I in (1,1,10) do (
  120. set/a "XV=%%I-X,YV=%%J-Y"
  121. if defined  DIV[!XV!][!YV!] (
  122. set/a "POINT[%%I][%%J]=DIV[!XV!][!YV!]|POINT[%%I][%%J]"
  123. )
  124. set "DISPLAY[%%J]=!DISPLAY[%%J]!!POINT[%%I][%%J]!"
  125. )
  126. REM ~~~关卡得分
  127. if %%J leq 20 if "!DISPLAY[%%J]!"=="1111111111" (
  128. set/a "SCORE+=10"&set "#%%J=1"
  129. if !SCORE! equ 400 (
  130. for /l %%n in (!CYC!,-1,!Y!) do (set "#%%n=")
  131. set/a "SCORE=0,LEVEL+=1,T-=10"
  132. goto :DISPLAY_RAM
  133. )
  134. )
  135. )
  136. REM ~~~极品消行
  137. for /l %%J in (20,-1,5) do (
  138. if defined #%%J (
  139. set "#%%J="
  140. set/a "PJ=%%J-1"
  141. for /l %%n in (1,1,3) do (
  142. if defined #!PJ! (set/a "PJ-=1")
  143. )
  144. set "#!PJ!=1"
  145. for /l %%I in (1,1,10) do (
  146. set/a "POINT[%%I][%%J]=POINT[%%I][!PJ!]"
  147. )
  148. )
  149. set "#[%%J]=1"
  150. )
  151. goto :RANDOM_SHAPE
  152. )
  153. if /i "!key:~-1!"=="W" (
  154. ENDLOCAL
  155. echo OW>key.ini
  156. set/a "NI=(NI+12)%%24"
  157. goto :READKEY
  158. )
  159. )
  160. )
  161. )
  162. )
  163. REM ~~~绘图引擎
  164. if !F1! equ 1 (2>NUL echo !SPACE!&set/p=<NUL) else (cls)
  165. echo ┏%LINES%┓
  166. for /l %%j in (1,1,20) do (
  167. if defined #[%%j] (
  168. set "#[%%j]="
  169. set "DISPLAY[%%j]="
  170. for /l %%i in (1,1,10) do (set "DISPLAY[%%j]=!DISPLAY[%%j]!!POINT[%%i][%%j]:1=%P1%!")
  171. echo ┃!DISPLAY[%%j]:0=%P0%!┃!READM[%%j]!
  172. ) else (echo;)
  173. )
  174. echo ┗%LINES%┛
  175. echo  CopyRight@2016~2018 BY HAPPY&ENDLOCAL&set/a "X+=dx,Y+=dy"
  176. goto :READKEY
  177. REM ~~~游戏结束
  178. :GAME_OVER
  179. echo GAME OVER!&ping -n 2 127.1>NUL&goto :DISPLAY_RAM
复制代码

作者: aa77dd@163.com    时间: 2016-10-3 12:10

楼主再有时间时, 可以考虑下, 消层时, 被消层替换成别的字符比如阴影方块闪动短暂瞬间, 被消层上面的方块逐层下落过渡一下

另外 %windir%\media\ 目录中有很多 Windows 自带的音效文件 WAV/MID ,  可以用 wmplayer 播放合适的作为游戏音效
作者: happy886rr    时间: 2016-10-3 12:19

本帖最后由 happy886rr 于 2016-10-3 16:53 编辑

回复 2# aa77dd@163.com
感谢建议。用批处理实现俄罗斯方非常繁琐,毕竟效率不是很高,连choice也被xcopy替换了,要是借助点第三方,体验可以有很大改善。不过这个雏形的好处就是,好多都能自定义,什么形状,随意自定义,不过得用16进制表示。

这只是初版,意在尝试用批处理模拟一个div在另一个图层上的移动。移动一个层,因此效率不是很快,代码也过于繁杂。其实对于俄罗斯方块,就那5种形状,且每种形状均由4个黑格组成,因此,我们只需记住这四个点的移动,就可以省掉40多次循环,再采用矩阵的旋转处理算法。俄罗斯方块2.0版将提供这种精简处理方案,预计游戏速度可以提高近15倍。
作者: happy886rr    时间: 2016-10-4 21:44

回复 3# plp626
2.0版本更加迅捷,至于A按钮迟钝,那是因为没有使用第三方,用xcopy当按键有很多弊端,批处理的横向移动,要不断set/p读取按键,故比不上直接上第三方的手感。
作者: 523066680    时间: 2016-10-5 16:57

本帖最后由 523066680 于 2016-10-5 17:03 编辑

最讨厌这种形状了

  ■■
    ■■


对了有时候 NEXT 下方显示的方块形状好像不对
┏━━━━━━━━━━┓
┃          ┃
┃          ┃
┃          ┃LEVEL:1
┃          ┃
┃          ┃SCORE:10
┃       ■  ┃
┃      ■■  ┃NEXT
┃       ■  ┃ ■■ 
┃          ┃ ■■ 
┃          ┃ ■  
┃          ┃    
┃          ┃
┃          ┃
┃          ┃
┃          ┃
┃          ┃
┃          ┃
┃   ■■  ■  ┃
┃  ■■■■■■  ┃
┃   ■■■■■  ┃
┗━━━━━━━━━━┛
CopyRight@2016~2018 BY HAPPY


作者: Bella    时间: 2016-10-5 17:07

论坛里的几个游戏, 我按键盘都没反应
作者: aa77dd@163.com    时间: 2016-10-5 17:51

回复 6# Bella

一些老帖 可能不能在 Win7 以上运行, 原作者没更新, 也没人发兼容版, 较新的帖, 可能在 Win7 测试过, 但 Win8 以上大概都没测试过了
作者: happy886rr    时间: 2016-10-5 20:18

回复 6# Bella
那些游戏都是两个窗口,你得把鼠标焦点聚集到小窗口上,按键才有反应。还有论坛的其他游戏貌似是2009年那会的,他们的换行符什么的复制下来都丢了,其实那些游戏都能运行,你把多余的空格和换行符补全基本都能运行。
作者: happy886rr    时间: 2016-10-5 20:23

回复 5# 523066680
主要是考虑不闪屏幕,所以全部用的动态显示,也就是不cls,只更新变化的那个点,因此就会出现老点残留的情况。你的块走到哪,才更新周围的字符,优点是显示速度极快,缺点是残留老点。1.0版应该还好,一会公布C语言版,还在测试中。
作者: aa77dd@163.com    时间: 2016-10-5 20:25

本帖最后由 aa77dd@163.com 于 2016-10-5 20:42 编辑

回复 8# happy886rr

我每次打开, 那控制窗口都遮着主窗口, 我会用键盘移动窗口(Alt + 空格, M, 方向键... 回车),  但有人不会这个的,  

控制窗口弄大点呢, 那么小, 标题栏都没地方可以用鼠标点着拖动, 弄大点, 在里面显示着这是控制窗口, 需要焦点...

老地方没有用空格覆盖, 就会残留
作者: happy886rr    时间: 2016-10-5 20:47

本帖最后由 happy886rr 于 2018-11-11 13:40 编辑

回复 10# aa77dd@163.com
呵呵,就是要小,要遮住,这样人们才会很费劲的去移动那个小家伙,焦点就被聚焦在小窗口上了。另外五子棋和象棋的游戏还在测试中,棋类游戏我借助了第三方,用鼠标点击去落子,还得完善下bug。
作者: 523066680    时间: 2016-10-5 21:33

回复 11# happy886rr


    精力爆表!(C语言版出来的时候去我那里发个副本吧~)
作者: happy886rr    时间: 2016-10-5 21:45

回复 12# 523066680
好的,修bug花去很多时间。好在C语言有断点调试。
作者: CrLf    时间: 2016-10-5 23:36

本帖最后由 CrLf 于 2016-10-5 23:37 编辑

回复 13# happy886rr


    楼主最近的骗到的赚来的技术分快够换书了
作者: happy886rr    时间: 2016-10-6 04:13

回复 14# CrLf
哈哈,大师都养了800多鸡,我才96鸡,我只是鸡肋呀。
作者: 523066680    时间: 2016-10-6 17:31

本帖最后由 523066680 于 2016-10-6 20:24 编辑

呜,C代码还是用自带的code标签好了,对了,需要输入啥参数?
推荐 sublime text/其他编辑器 以及 左花括号换行(强迫症路过)

因为源代码是要求gbk格式保存,建议发附件

建议补充:
1. 建议执行前清理一下屏幕,执行后清理一下屏幕,执行前后是这样的:
┃          ┃
┃          ┃
C:\Users   \Desktop>a 20 200 SRS
┏━━━   ━━━━┓
┃          ┃SCORE:30
┃          ┃
┃          ┃LEVEL:1
┃    ■     ┃  ■
C:\Users\UserN\Desktop> ■■  0
┃          ┃ ■■


2. 应该设置参数缺省(默认)值,使得双击也能运行
作者: happy886rr    时间: 2016-10-6 20:31

回复 5# 523066680
在批处理版Version2.0中添加
  1. REM ~~~开启此项可以解决NEXT显示异常,但加速下落速度会减慢
  2. ::for /l %%j in (8,1,11) do (set/a "#[%%j]=1")
复制代码
动态显示是按行来的,标记哪行显示哪行。只需标记NEXT那几行,就可以每次都更新,下一个图标就不会再异常了,或者直接复制version2.1新修版。
作者: happy886rr    时间: 2016-10-6 20:44

回复 16# 523066680
直接将C中main函数换为如下,即点即玩。
  1. /**********Main主函数***********/
  2. int main()
  3. {
  4. system("color F0&mode con cols=35 lines=25");
  5.         HideCursor();
  6.         CreatUI();
  7.         GameCycle(10,800,1);
  8.         return 0;
  9. }
复制代码
Tetris.c的无参数直接启动文件地址




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2