回 帖 发 新 帖 刷新版面

主题:俄罗斯方快

有谁给说说原理。。
谢谢了。。

回复列表 (共21个回复)

沙发

(*转载,,有更好的欢迎*)
俄罗斯方块详细说明
关于本站(www.delfan.com)的TETRIS(俄罗斯方块)很多网友发来电子邮件询问设计思路, 一直想写, 总是没有时间, 趁着今天休息, 就写一点东西吧.
1. 首先这个程序是个多线程, 就是处理下落的情况我们用一个单独的线程来处理. 关于线程编程方面的知识, 我就不罗索了, 可以参考本站收集的一篇文章<Java多线程编程详解>. 这个处理下落的线程同时也担负着处理开始的时候闪烁字体的任务.
2. 很多网友不理解造型数组的定义. 这里其实我是偷懒了, 本来应该只定义出来基本的形状, 就是7个基本的形状, 不用定义出来旋转后的情况, 旋转后的情况可以通过计算得到的. 我这里这样定义为了简化程序. 我们来看一下其定义及其含义:
byte SHAPE[][][][] = // [造型索引][旋转索引][4][坐标]
关于这个数组, 我们这么来想: 每个造型都是一个二维数组, 为了包含所有的情况, 就使用可能出现的最大的情况, 就是那个"■■■■"造型, 就必须用4x4的二维数组来处理. 这样, 我们就可以用"1"来表示造型中有方块的情况, "0"来表示没有方块的情况, 例如:
[][][][]   0,0,0,0
[]■[][] ==> 0,1,0,0
■■■[]1,1,1,0
[][][][]0,0,0,0
OK, 我们接着往下推导. 为了下落的时候处理方便, 我们用坐标来表示有方块的相对位置,注意, 只保留有方块的位置, 就是上面数组中为"1"的情况, 就可以把上述数组转化为这样的情况:
-----,-----,-----,-----
-----,(1,1),-----,-----
(3,1),(3,2),(3,3),-----
-----,-----,-----,-----
再来接着想, 为了简化处理旋转的情况, 我们把旋转的那个方块作为零坐标(0,0), 其他都是相对这个方块的相对坐标, 上面的这个"数组"就可以推出下面的情况:
------,------,-----,-----
------,(0,-1),-----,-----
(-1,0),(0, 0),(1,0),-----
------,------,-----,-----
现在, 每一个造型就可以变成一个元素为4的数组, 而每一个元素是一个坐标, 一个最标也是一个二维数组"{x,y}", 因此, 一个造型就可以表示为{{x1,y1},{x2,y2},{x3,y3},{x4,y4}}, 这时候数组的定义就是"造型[4][2]".
好, 我们现在把旋转后的情况加上, 也就是一个造型有4种旋转的情况, 此时, 数组就是"造型[4][4][2]".由此类推, 因为有7种不同的造型, 我们把他们整合到一个数组中, 就是"造型[7种造型][4种旋转情况][每个造型有4个方块][每个方块的坐标]". 这样, 我们就完成了整个数组的定义.
3. 下落过程的处理, 其实就是提前模拟出已经下落或旋转的情况, 然后去判断下落或旋转后, 是否和已经堆放的方块有重叠的情况, 是否有下落或旋转后超出边界的情况. 没有则下落或旋转, 有则判断是否需要停止下落或旋转, 是否要堆放等.
4. 双缓冲处理, 这个问题在本站的其他Applet中都有很详细的解释, 这里就不罗索了.

好了, 主要就是这些东西了, 如果您还有其他什么不懂的地方, 可以给我们发邮件或着留言. 最后祝大家早日成为编程高手~ :)

板凳

刚找到的源程序:
USES Crt;
CONST
Change:Array [0..6,0..3,0..7] Of Byte =(((0,1,1,1,2,1,3,1),(1,0,1,1,1,2,1,3),(0,1,1,1,2,1,3,1),(1,0,1,1,1,2,1,3)),
                                        ((1,0,0,1,1,1,2,1),(1,0,1,1,1,2,2,1),(0,1,1,1,2,1,1,2),(1,0,0,1,1,1,1,2)),
                                        ((1,0,2,0,1,1,2,1),(1,0,2,0,1,1,2,1),(1,0,2,0,1,1,2,1),(1,0,2,0,1,1,2,1)),
                                        ((1,0,2,0,0,1,1,1),(0,0,0,1,1,1,1,2),(1,0,2,0,0,1,1,1),(0,0,0,1,1,1,1,2)),
                                        ((0,0,1,0,1,1,2,1),(1,0,0,1,1,1,0,2),(0,0,1,0,1,1,2,1),(1,0,0,1,1,1,0,2)),
                                        ((1,0,2,0,1,1,1,2),(0,0,0,1,1,1,2,1),(1,0,0,2,1,1,1,2),(2,2,0,1,1,1,2,1)),
                                        ((0,0,1,0,1,1,1,2),(2,0,0,1,1,1,2,1),(2,2,1,0,1,1,1,2),(0,2,0,1,1,1,2,1)));
VAR
  Board:Array [0..3,0..11,1..25] Of Byte;
  Players,N,Nowx,Nowy,Kind,Trans,Speed:Byte;
  Time,Score:Word;
  Now:Array [0..7] Of Byte;
PROCEDURE Furbish;
  VAR B,C:Byte;
  Begin
    For C:=24 Downto 2 Do Begin
      Gotoxy(1,C);
        For B:=1 To 10 Do
         If Board[0,B,C]=0 Then Write('  ')
          Else Write('圹');
        End;
  End;
PROCEDURE Clear;
Var A,B,C:Byte;D:Boolean;
Begin
  For A:=24 Downto 1 Do
   Begin
    D:=True;
    For B:=1 To 10 Do
     If Board[0,B,A]=0 Then D:=False;
    If D=True Then
     Begin
      Score:=Score+10;Gotoxy(1,1);Write(Score:5,'0');
      For C:=A Downto 2 Do
       For B:=1 To 10 Do
        Board[0,B,C]:=Board[0,B,C-1];
      A:=A+1;
       End;
     End;
   Furbish;
  End;
FUNCTION Canmove(X,Y:Byte):Boolean;
BEGIN
Canmove:=True;
If Board[0,X+Now[0],Y+Now[1]]>0 Then Canmove:=False;
If Board[0,X+Now[2],Y+Now[3]]>0 Then Canmove:=False;
If Board[0,X+Now[4],Y+Now[5]]>0 Then Canmove:=False;
If Board[0,X+Now[6],Y+Now[7]]>0 Then Canmove:=False;
End;
PROCEDURE Clean;
Begin
   Gotoxy((Nowx+Now[0])*2-1,Nowy+Now[1]);Write('  ');
   Gotoxy((Nowx+Now[2])*2-1,Nowy+Now[3]);Write('  ');
   Gotoxy((Nowx+Now[4])*2-1,Nowy+Now[5]);Write('  ');
   Gotoxy((Nowx+Now[6])*2-1,Nowy+Now[7]);Write('  ');
  End;
PROCEDURE Show;
Begin
   Gotoxy((Nowx+Now[0])*2-1,Nowy+Now[1]);Write('圹');
   Gotoxy((Nowx+Now[2])*2-1,Nowy+Now[3]);Write('圹');
   Gotoxy((Nowx+Now[4])*2-1,Nowy+Now[5]);Write('圹');
   Gotoxy((Nowx+Now[6])*2-1,Nowy+Now[7]);Write('圹');
  End;
BEGIN
Fillchar(Board,Sizeof(Board),0);
Randomize;Score:=0;
For N:=1 To 24 Do
  Board[0,0,N]:=1;
For N:=1 To 24 Do
  Board[0,11,N]:=1;
For N:=1 To 10 Do
  Board[0,N,25]:=1;
Window(31,2,50,25);Textcolor(White);Textbackground(Blue);
Clrscr;Window(31,2,51,25);
Speed:=1;
Kind:=Random(7);Trans:=Random(4);Nowx:=4;Nowy:=1;
For N:=0 To 7 Do
  Now[N]:=Change[Kind,Trans,N];
While Canmove(Nowx,Nowy) Do
  Begin
  Repeat
   Clean;Nowy:=Nowy+1;Show;
   Repeat
   If Keypressed Then
     Case Upcase(Readkey) Of
       #0:Case Readkey Of
           #75:If Canmove(Nowx-1,Nowy) Then Begin Clean;Nowx:=Nowx-1;Show;End;
           #77:If Canmove(Nowx+1,Nowy) Then Begin Clean;Nowx:=Nowx+1;Show;End;
           #80:Begin Clean;Repeat
                If Canmove(Nowx,Nowy+1) Then Nowy:=Nowy+1;
               Until Not(Canmove(Nowx,Nowy+1));Show;End;
           #61:Begin Gotoxy(9,12);Write('Pause');Repeat Delay(1000);Until Keypressed;Furbish;End;
           End;
       #27:Exit;
       ' ',#13:Begin
            Clean;Trans:=Trans+1;
            If Trans=4 Then Trans:=0;
            For N:=0 To 7 Do
             Now[N]:=Change[Kind,Trans,N];
            If Not(Canmove(Nowx,Nowy)) Then Begin Trans:=Trans-1;For N:=0 To 7 Do
             Now[N]:=Change[Kind,Trans,N];Show;End
             Else Show;
             End;
     End;
  Until Not(Keypressed);
   Delay((10-Speed)*50);
   Until Not(Canmove(Nowx,Nowy+1));
Score:=Score+1;Gotoxy(1,1);Write(Score:5,'0');Speed:=(Score Div 300)+1;
Board[0,Nowx+Now[0],Nowy+Now[1]]:=1;
Board[0,Nowx+Now[2],Nowy+Now[3]]:=1;
Board[0,Nowx+Now[4],Nowy+Now[5]]:=1;
Board[0,Nowx+Now[6],Nowy+Now[7]]:=1;
Clear;
   Kind:=Random(7);Trans:=Random(4);Nowx:=4;Nowy:=1;
   For N:=0 To 7 Do
    Now[N]:=Change[Kind,Trans,N];
  End;
   Gotoxy(7,12);Write('GAME OVER');Readln;
END.

3 楼

不是人编的

4 楼

谁能用c编一个出来?~

5 楼

看不懂。。。

6 楼

我也是

7 楼

gotoxy是什么意思

8 楼

把光标移到某个位置的函数。

9 楼

用c++简单10倍

10 楼

1楼、2楼的,在下佩服!

我来回复

您尚未登录,请登录后再回复。点此登录或注册