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.

  • 相关阅读:
    [na][dhcp]华为DHCP-重要
    [na]win PPTP场景与搭建
    [na]锐起无盘机并发部署多台windows
    [na]wireshark抓包排错-tcp.flags.reset
    [svc]mousedos网络批量部署xp
    [na]诺顿ghost磁盘对刻(备份系统分区或数据分区)
    [na]代理arp导致的问题(路由卷)
    [na]pc加入域认证细节
    【VS开发】【智能语音处理】VS中声音的采集实现
    【VS开发】【智能语音处理】MATLAB 与 音频处理 相关内容摘记
  • 原文地址:https://www.cnblogs.com/Chaobs/p/3837542.html
Copyright © 2011-2022 走看看