zoukankan      html  css  js  c++  java
  • Pascal小游戏 俄罗斯方块怀旧版

    俄罗斯方块怀旧版(注释版)

    {$APPTYPE GUI}
    {$MODE DELPHI}
    program WinPiece;


    uses
    Windows;

    const
    AppName = 'WinPiece';
    pm = 25;

    var
    dc : hdc;
    AMessage : Msg;
    hWindow: HWnd;
    hPen ,hBrush : longword;
    intNextPiece, intCurPiece,intTempPiece : longint;
    BigMap : array [0..11,-4..20] of boolean;
    NextPiece,CurPiece,TempPiece : array [0..3,0..3] of boolean;
    isGameing : boolean;
    Piece : array [0..18] of longint;
    scoreString, levelString: string;
    xPos, yPos : integer;
    score,level : longint; //分数,关卡
    speed : integer;

    procedure TimerProc(Window:HWND;uMsg:UINT;idEvent:UINT;Time:DWORD);stdcall;
    FORWARD;


    Procedure IntToNextPiece ( );
    var
    i,j : integer;
    t: longint;
    begin

    t:=intNextPiece;
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    begin
    If (t mod 2=1) Then
    NextPiece[j][i] := true
    else
    NextPiece[j][i] := false ;

    t := t div 2;
    end;

    end;

    Procedure IntToCurPiece ( );
    var
    i,j : integer;
    t : longint;
    begin
    t:=intCurPiece;
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    begin
    If (t mod 2=1) Then
    CurPiece[j][i] := true
    else
    CurPiece[j][i] := false ;
    t := t div 2;
    end;
    end;

    Procedure IntToTempPiece ( );
    var
    i,j : integer;
    t : longint;
    begin
    t:=intTempPiece;
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    begin
    If (t mod 2=1) Then
    TempPiece[j][i] := true
    else
    TempPiece[j][i] := false ;
    t := t div 2;
    end;
    end;

    Procedure DrawPiece(x,y:integer);
    begin
    SelectObject (dc,GetStockObject (NULL_PEN)) ; //选择空画笔 
    hBrush := CreateSolidBrush (RGB(255,0,128)); //创建粉色笔刷 
    SelectObject (dc,hBrush) ; //选择我们创建的粉色笔刷 
    Rectangle(dc,x,y,x+pm,y+pm); //画粉色矩形 
    DeleteObject(hBrush); //删除刚创建的粉色笔刷

    SelectObject (dc,GetStockObject (WHITE_PEN)) ; //选择白色画笔 
    MoveToEx (dc, x+24,y, nil);
    LineTo(dc,x,y);
    LineTo(dc,x,y+24);
    hPen:=CreatePen(PS_SOLID,1, RGB(100,100,100)); //创建灰色画笔 
    SelectObject (dc,hPen) ; //选择我们刚创建的灰色画笔 
    LineTo(dc,x+24,y+24);
    LineTo(dc,x+24,y);
    DeleteObject(hPen); //删除我们刚创建的灰色画笔 
    end;

    //未完,待回贴,传送
    Procedure DrawNextMap( );
    var
    i, j : integer;
    begin
    SelectObject (dc,GetStockObject (BLACK_PEN)); //选择黑色画笔 
    SelectObject (dc,GetStockObject (BLACK_BRUSH)); //选择黑色画笔 
    Rectangle(dc,277,66,277+pm*4,66+pm*4); //先画BigMap黑色矩形背景
    IntToNextPiece();
    SelectObject (dc,GetStockObject (WHITE_PEN)) ;
    For i:= 0 to 3 DO
    begin
    For j:=0 TO 3 DO
    begin
    If NextPiece[i][j] Then
    begin
    DrawPiece(277+pm*i,66+pm*j);
    end;
    end;
    end; 
    end;

    Procedure DrawBigMap( );
    var
    i, j:integer;
    begin
    For i:= 1 TO 10 DO
    begin
    For j:= 0 TO 19 DO
    begin
    If BigMap[i][j] Then
    DrawPiece(12+(i-1)*pm,66+j*pm)
    else
    begin
    SelectObject (dc, GetStockObject (BLACK_PEN)) ;
    SelectObject (dc, GetStockObject (BLACK_BRUSH)) ;
    Rectangle(dc,12+(i-1)*pm,66+j*pm,12+(i-1)*pm+pm,66+j*pm+pm);
    end;
    end;
    end;
    end;

    Procedure DrawCurMap();
    var
    i, j : integer;
    begin
    IntToCurPiece();
    For i:=0 TO 3 DO
    For j:= 0 TO 3 DO
    If (CurPiece[i][j]) and (yPos+j>=0) Then DrawPiece(12+(xPos+i-1)*pm,66+(yPos+j)*pm);
    end;

    Procedure DrawScore ( );
    begin
    SetBkColor(dc,RGB(200,200,200)); //设置字体的背景色为灰色,以与窗口背景保持一致 
    TextOut(dc,300,220,PChar(scoreString),length(scoreString)); //输出分数 
    TextOut(dc, 300, 270, PChar(levelString),length(levelString)); //输出过关数 
    //MessageBox(0,'','',MB_OK);
    end;

    function NewPiece ( ):longint;
    begin
    NewPiece:=Piece[trunc(random*19)];
    end;

    Procedure init ( );
    var
    i, j : integer;
    begin
    For i:=0 TO 11 DO
    For j:=-4 TO 20 DO
    If (i=0) or (i=11) or (j=20) Then
    BigMap[i][j] := true
    else
    BigMap[i][j] := false ;

    score:=0;
    str(score,scoreString);
    scoreString:='分数:'+ scoreString + ' ';
    level:=0; 
    str(level,levelString);
    levelString:='级别:'+ levelString +' ';
    xPos:=4;
    yPos:=-4;
    end;

    function CanTurn(): boolean;
    var
    i,j: integer;
    r: boolean;
    begin
    r:=true ;
    For i:=0 TO 18 DO
    If intCurPiece=Piece[i] Then
    begin
    break ;
    end;
    case i of
    0: intTempPiece := Piece[0]; //方块
    1: intTempPiece := Piece[2]; //i
    2: intTempPiece := Piece[1]; //i
    3: intTempPiece := Piece[4]; //z
    4: intTempPiece := Piece[3]; //z
    5: intTempPiece := Piece[6]; //反z
    6: intTempPiece := Piece[5]; //反z
    7: intTempPiece := Piece[10]; //T
    8, 9, 10: intTempPiece := Piece[i - 1]; //T
    11: intTempPiece := Piece[14]; //L
    12, 13, 14: intTempPiece := Piece[i - 1]; //L
    15: intTempPiece := Piece[18]; //反L
    16, 17, 18: intTempPiece := Piece[i - 1]; //反L
    end;

    IntToTempPiece ( );
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    If (((xPos+i)>=0) and ((xPos+i)<12) and (BigMap[xPos+i][yPos+j]) and (TempPiece[i][j])) Then //当有重合的格子都为1时,表示表不能变形
    begin
    CanTurn:=false ;
    r:=false;
    exit ;
    end;
    intCurPiece:=intTempPiece;
    intToCurPiece();
    CanTurn:=r;
    end;

    //未完,待回贴,传送
    Function CanRight ( ) : boolean;
    var
    i,j: integer;
    begin
    inc(xPos); //假设方块继续右
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    If (((xPos+i)>=0) and ((xPos+i)<12) and (BigMap[xPos+i][yPos+j]) and (CurPiece[i][j])) Then //当有重合的格子都为1时,表示不能右移
    begin
    dec(xPos);
    CanRight:=false ;
    exit ;
    end;
    dec(xPos);
    CanRight := true ;
    end;

    Function CanLeft ( ) : boolean;
    var
    i,j: integer;
    begin
    dec(xPos); //假设方块继续左
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    If (((xPos+i)>=0) and ((xPos+i)<12) and (BigMap[xPos+i][yPos+j]) and (CurPiece[i][j])) Then //当有重合的格子都为1时,表示不能左移
    begin
    inc(xPos);
    CanLeft:=false ;
    exit ;
    end;
    inc(xPos);
    CanLeft := true ;
    end;

    Function CanDown ( ) : boolean; //判断CurPiece能否继续下落 
    var
    i,j: integer;
    begin
    inc(yPos); //假设方块继续下落
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    If (((xPos+i)>=0) and ((xPos+i)<12) and (yPos+j>=0) and (BigMap[xPos+i][yPos+j]) and (CurPiece[i][j])) Then //当有重合的格子都为1时,不能表示表能下落了 
    begin
    dec(yPos);
    CanDown:=false ;
    exit ;
    end;
    dec(yPos);
    CanDown := true ;
    end;

    Procedure FillBigMap ( ); //记录大图
    var
    i, j : integer;
    begin
    For i:=0 TO 3 DO
    For j:=0 TO 3 DO
    If CurPiece[i][j] Then
    BigMap[xPos+i][yPos+j]:=true;

    end;

    Function IsGameOver ( ) : boolean; //游戏是过否结束
    var
    i:integer;
    r:boolean;
    begin
    r:=false ;
    For i:=1 TO 10 DO 
    If BigMap[i][0] Then //当 最上一行有小格为1,返回真
    begin
    r:=true ;
    break 
    end;
    IsGameOver := r ;
    end;

    Procedure ClearLine ( ); //消行 
    var
    linesCount, count, i, j, k, m: integer;
    begin
    linesCount := 0; //一次消行的行数 
    For j:=19 downTO 0 DO
    begin
    count:=0;
    For i:=1 TO 10 DO
    If BigMap[i][j] Then
    inc(count);
    If count=10 Then //count=10,表明该行已满 
    begin
    inc(linesCount);
    For k:= j downTO 1 DO
    For m:= 1 TO 10 DO
    BigMap[m][k]:=BigMap[m][k-1];
    //inc(j); //这个怎么办????
    if(linesCount>0) then
    begin
    score:=score+linesCount*10;
    str(score,scoreString);
    scoreString:='分数:'+ scoreString + ' ';

    if( level<>(score div 1000) ) then
    begin
    level := score div 1000;
    str(level,levelString);
    levelString:='级别:'+ levelString + ' ';
    KillTimer(hwindow,11);
    speed:=speed div 2;
    SetTimer(hWindow,11,speed,@TimerProc);
    end;

    end;
    end;
    end;
    end;

    procedure TimerProc(Window:HWND;uMsg:UINT;idEvent:UINT;Time:DWORD);stdcall;
    begin
    If (CanDown()) then //如果能继续下落 
    yPos := yPos + 1 //则CurPiece下落(纵坐标加1 ) 
    else //如果不能下落
    begin
    FillBigMap(); //将CurPiece填入BigMap
    intCurPiece:=intNextPiece;
    IntToCurPiece();

    intNextPiece:=NewPiece(); //随机产生新方块,并复制给NextPiece
    IntToNextPiece();
    xPos:=4; //横坐标初始化为4 
    yPos:=-4; //纵坐标初始化为-1 
    ClearLine(); //消行 
    if(IsGameOver()) then
    begin
    KillTimer(window,11);
    isGameing:=false ;
    MessageBox(window,'游戏结束!"','提示',MB_OK); 
    end;

    end;
    PostMessage(window, WM_PAINT, 0, 0);
    end;

    Procedure BeginGame ( );
    begin
    init();
    randomize;
    intCurPiece:=NewPiece(); //随机产生新方块,并复制给NextPiece
    IntToCurPiece(); //
    intNextPiece:=NewPiece(); //随机产生新方块,并复制给NextPiece
    IntToNextPiece();
    isGameing:=true;
    speed:=1000;
    SetTimer(hWindow,11,speed,@TimerProc); //定时器id为11,时间间隔为1000ms,时间回调函数是TimerProc()
    end;
    //未完,待回贴,传送
    function WindowProc(Window: HWnd; AMessage: UINT; WParam : WPARAM;
    LParam: LPARAM): LRESULT; stdcall; export;

    var
    nrmenu : longint;
    aboutString : String;

    begin
    WindowProc := 0;

    case AMessage of

    wm_paint:
    begin
    DefWindowProc(Window, AMessage, WParam, LParam);
    dc:= GetDC(window);

    DrawBigMap();
    DrawNextMap();
    DrawCurMap();
    DrawScore(); 
    ReleaseDC(window, dc) ;
    end;

    wm_Destroy:
    begin
    PostQuitMessage(0);
    Exit;
    end;

    wm_Create:
    begin
    CreateWindowEx(0,'button','开始',
    ws_child or ws_visible or bs_pushbutton,
    20,10,75,40,
    Window,
    0,system.MainInstance,nil);

    CreateWindowEx(0,'button','暂停',
    ws_child or ws_visible or bs_pushbutton,
    100,10,75,40,
    Window,
    1,system.MainInstance,nil);

    CreateWindowEx(0,'button','继续',
    ws_child or ws_visible or bs_pushbutton,
    180,10,75,40,
    Window,
    2,system.MainInstance,nil);

    CreateWindowEx(0,'button','关于',
    ws_child or ws_visible or bs_pushbutton,
    260,10,75,40,
    Window,
    3,system.MainInstance,nil);
    end;
    wm_command:
    begin
    NrMenu := WParam And $FFFF;
    case NrMenu of
    0: 
    begin
    BeginGame();
    end;
    1:
    If (not isGameOver()) and (isGameing) Then
    begin
    isGameing:=false ;
    killTimer(window,11);
    end;
    2:
    begin
    If (not isGameOver()) and (not isGameing) Then
    begin
    isGameing:=true ;
    SetTimer(hWindow,11,speed,@TimerProc);
    end;
    end;
    3:
    begin
    PostMessage(window,wm_command,1,0);
    aboutString := '嘲哥出品 必属精品'+ chr(13) + chr(10);
    aboutString :=aboutString + 'chaobs荣誉出品' + chr(13) + chr(10);
    aboutString :=aboutString + '网页:hi.baidu.com/chaobs';
    messagebox(window,pchar(aboutString),'俄罗斯方块怀旧版 Chaobs荣誉出品',mb_ok);
    PostMessage(window,wm_command,2,0);
    end;
    end;
    SetFocus(window); //把焦点归还给主窗口 
    end;

    WM_KEYDOWN:
    begin
    if(isGameing) then
    begin
    NrMenu := WParam And $FFFF;
    case NrMenu of
    VK_UP:
    If CanTurn() Then
    begin
    PostMessage(window,WM_PAINT,0,0);
    end;
    VK_LEFT:
    If CanLeft() Then
    begin
    dec(xpos);
    PostMessage(window,WM_PAINT,0,0);
    end;
    VK_RIGHT:
    If CanRight() Then
    begin
    inc(xpos);
    PostMessage(window,WM_PAINT,0,0);
    end;
    VK_DOWN:
    If CanDown() Then
    begin
    TimerProc(window,11,0,0);
    end;
    end;
    end;
    end;
    end;

    WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
    end;

    { Register the Window Class }
    function WinRegister: Boolean;
    var
    WindowClass: WndClass;
    begin
    WindowClass.Style := cs_hRedraw or cs_vRedraw;
    WindowClass.lpfnWndProc := WndProc(@WindowProc);
    WindowClass.cbClsExtra := 0;
    WindowClass.cbWndExtra := 0;
    WindowClass.hInstance := system.MainInstance;
    WindowClass.hIcon := LoadIcon(0, idi_Application);
    WindowClass.hCursor := LoadCursor(0, idc_Arrow);
    WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
    WindowClass.lpszMenuName := nil;
    WindowClass.lpszClassName := AppName;

    WinRegister := RegisterClass(WindowClass) <> 0;
    end;

    { Create the Window Class }
    function WinCreate: HWnd;

    begin
    hWindow := CreateWindow(AppName, '俄罗斯方块怀旧版 Chaobs荣誉出品',
    ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
    400, 615, 0, 0, system.MainInstance, nil);

    if hWindow <> 0 then
    begin
    ShowWindow(hWindow, CmdShow);
    ShowWindow(hWindow, SW_SHOW);
    UpdateWindow(hWindow);
    end;

    WinCreate := hWindow;
    end;

    Procedure VarInit( );
    begin
    Piece[0]:=13056;
    Piece[1]:=8738;
    Piece[2]:=3840;
    Piece[3]:=25344;
    Piece[4]:=4896;
    Piece[5]:=13824;
    Piece[6]:=8976;
    Piece[7]:=29184;
    Piece[8]:=17984;
    Piece[9]:=9984;
    Piece[10]:=4880;
    Piece[11]:=25120;
    Piece[12]:=29696;
    Piece[13]:=17504;
    Piece[14]:=5888;
    Piece[15]:=12832;
    Piece[16]:=18176;
    Piece[17]:=8800;
    Piece[18]:=28928;
    end;

    begin
    VarInit();
    if not WinRegister then
    begin
    MessageBox(0, 'Register failed', nil, mb_Ok);
    Exit;
    end;
    hWindow := WinCreate;
    if longint(hWindow) = 0 then
    begin
    MessageBox(0, 'WinCreate failed', nil, mb_Ok);
    Exit;
    end;

    while GetMessage(@AMessage, 0, 0, 0) do
    begin
    TranslateMessage(AMessage);
    DispatchMessage(AMessage);
    end;
    Halt(AMessage.wParam);
    end.

  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/Chaobs/p/3837542.html
Copyright © 2011-2022 走看看