刚写的一个俄罗斯方块程序

前些日子因为在CSDN上发 “程序开发的壳与核”一文结识了网友C,在QQ聊天的时候他说他在写一个俄罗斯方块的程序,我说好啊,我也写一个,到时一起讨论,然后就开始写了,断断续续写了好几天昨天他已经把写好的发给我看了,我的还只写到50%,所以今天写了一个下午把它写了出来,不过还是有些地方没实现,比如NEXT指示的显示,事件发生的音效也没加,(只有背景音乐,但背景MCI播放的MID循环也没做出来),还有有时会有个消行时的BUG,不过我没办法重现,又不大会测试,所以就这样子算了吧,下面是截图,最后是程序,C不介意把他的代码也贴上来,一比较,就会觉得我的代码不太规范,有些地方也不具备扩展性,不便修改,他比我还低一级,还不是计算机专业的,编程能力真是让我汗颜啊。唉。。。。。。

这是我做的:

 

///

#define WIN32_LEAN_AND_MEAN


#include<windows.h>
#include<stdlib.h>
#include<time.h>

#define  ID_TIMER 1

#define  WHITE    0
#define  BLACK    1
int level=1;
int score=0;
int global[18][16];
int diamond[4][2];
int current_max=18;
int current_type=0;
int xBase,yBase;
int game_over;

#include "mmsystem.h"

HWND  hwnd=NULL;
HINSTANCE hInstance;
TCHAR szAppName[]=TEXT("俄罗斯方块");

int i;

bool Init(char * title,int xStart,int yStart,int width,int height);   //Window Initialization
void DrawUnit(HWND hwnd,int m,int n,int color);
void DrawDiamond(int color);
void InitDiamond(HWND hwnd,int a,int b,int current_type);
void DownLine(HWND hwnd,int baseline); //all rows above the success row down one stair
bool CheckLeft();
void MoveLeft();
bool CheckRight();
void MoveRight();
void DownQuickly();
void Rotate();

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE prevInstance,PSTR szCmdLine,int iCmdShow)
{
 MSG  msg;

 if(!Init(szAppName,150,100,800,610))
 {
  return 0;         
 }
    while (GetMessage (&msg, NULL, 0, 0))
    {
         TranslateMessage (&msg) ;
         DispatchMessage (&msg) ;
    }
 return (msg.wParam);
}

bool Init(char * title,int xStart,int yStart,int width,int height)
{
 RECT WindowRect;
 WindowRect.left=(long)xStart;  
 WindowRect.right=(long)(xStart+width);  
 WindowRect.top=(long)yStart; 
 WindowRect.bottom=(long)(yStart+height);

 hInstance   = GetModuleHandle(NULL);

 WNDCLASS wc;    
 wc.style   = CS_HREDRAW | CS_VREDRAW ; 
 wc.lpfnWndProc  = (WNDPROC) WndProc;     
 wc.cbClsExtra  = 0;         
 wc.cbWndExtra  = 0;        
 wc.hInstance  = hInstance;       
 wc.hIcon   = LoadIcon(NULL, IDI_WINLOGO);   
 wc.hCursor   = LoadCursor(NULL, IDC_ARROW);   
 wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(208,221,238));        
 wc.lpszMenuName  = NULL;         
 wc.lpszClassName = title;

 if(!RegisterClass(&wc))         
 {
  MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return FALSE;           // Return FALSE
 }

 if (!(hwnd=CreateWindow(title,       
       title,        
       WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,     
       xStart, yStart,        
       WindowRect.right-WindowRect.left, 
       WindowRect.bottom-WindowRect.top, 
       NULL,        
       NULL,        
       hInstance,       
       NULL)))
 {
  MessageBox(NULL,"Failed to create window !","ERROR",MB_OK | MB_ICONEXCLAMATION);
  return FALSE;
 }

 ShowWindow(hwnd,SW_SHOW);
 UpdateWindow(hwnd);

 return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;

 RECT rectLeft;     //left blank
 rectLeft.left=0;
 rectLeft.top=0;
 rectLeft.right=150;
 rectLeft.bottom=610;

 RECT rectRight;     //right blank
 rectRight.left=665;
 rectRight.top=0;
 rectRight.right=800;
 rectRight.bottom=610;

 UINT wMIDIDeviceID;    //for playing background music .mid
 MCI_OPEN_PARMS mciOpenParams;
 MCI_PLAY_PARMS mciPlayParams;
 DWORD dwError;

 static bool done=true;
 static bool down=false;

 switch(message)
 {
 case WM_CREATE:
  SetTimer (hwnd, ID_TIMER,500, NULL);    //start the timer

  mciOpenParams.lpstrDeviceType ="sequencer";   //play music
  mciOpenParams.lpstrElementName="Loop.mid";
  if(dwError=mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT|MCI_OPEN_TYPE,(DWORD)(LPVOID)&mciOpenParams))
  {
  }
  else
  {
      wMIDIDeviceID=mciOpenParams.wDeviceID;
  }
 
  if(dwError=mciSendCommand(wMIDIDeviceID,MCI_PLAY,MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParams))
  {
      mciSendCommand(wMIDIDeviceID,MCI_CLOSE,0,NULL);
  }

  return 0;
  case WM_KEYDOWN:
   switch(wParam)
   {
   case VK_LEFT:
    if(CheckLeft())
    {
     MoveLeft();
    }
    break;
   case VK_RIGHT:
    if(CheckRight())
    {
     MoveRight();
    }
    break;
   case VK_UP:      //rotate
    Rotate();
    break;
   case VK_DOWN:
    DownQuickly();
    break;
   }
   return 0;
 case WM_TIMER:
  if(done)
  {
   if(current_max<=0)
   {
    KillTimer(hwnd,ID_TIMER);
    MessageBox(NULL,"     You do well this time!      ","Game Over !",MB_OK);    
    SendMessage(hwnd,WM_DESTROY,0,0);
    break;
   }
   srand((unsigned)time(NULL));
   current_type=rand()%19;
   xBase=0;
   yBase=7;
   InitDiamond(hwnd,xBase,yBase,current_type);
   DrawDiamond(BLACK);
   down=true;
   done=false;
  }
  else
  {
   for(i=0;i<4;i++)   //check for down
   {
    if(global[diamond[i][0]+1][diamond[i][1]]==1 || diamond[i][0]+1>17)
    {
     down=false;
    }
   }
   if(down==true)    //then refresh
   {
    DrawDiamond(WHITE);
    for(i=0;i<4;i++)
    {
     diamond[i][0]=diamond[i][0]+1;
    }
    DrawDiamond(BLACK);
   }
   else
   {
    current_max=current_max<diamond[0][0]?current_max:diamond[0][0];   
    for(i=0;i<4;i++)    //and check for is there any row can be clear?
    {
     global[diamond[i][0]][diamond[i][1]]=1;
    }
    
    for(i=0;i<4;i++)
    {
     bool clear=true;
     for(int m=0;m<16;m++)
     {
      if(global[diamond[i][0]][m]==0)
      {
       clear=false;
      }
     }
     if(clear==true)
     {
      score+=10;
      DownLine(hwnd,diamond[i][0]);
     }
    }
    done=true;
   }
  }    
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hwnd,&ps);
  FillRect(hdc,&rectLeft,WHITE_BRUSH);
  FillRect(hdc,&rectRight,WHITE_BRUSH);
  TextOut(hdc,50,30,"Next",strlen("Next"));
  TextOut(hdc,700,30,"Level :",strlen("Level :"));
  char  p_int[4];
  wsprintf(p_int,"%d",level);
  TextOut(hdc,715,50,p_int,strlen(p_int));
  TextOut(hdc,700,200,"Score :",strlen("Score :"));
  wsprintf(p_int,"%d",score);
  TextOut(hdc,715,220,p_int,strlen(p_int));
  EndPaint(hwnd,&ps);

  for(i=18;i>=current_max;i--)
  {
   for(int n=0;n<16;n++)
   {
    if(global[i][n]==1)
    {
     DrawUnit(hwnd,i,n,BLACK);
    }
    else
    {
     DrawUnit(hwnd,i,n,WHITE);
    }
   }
  }
  if(diamond[0][0]!=0 && diamond[0][1]!=0)
  {
   for(int m=0;m<4;m++)
   {
    DrawUnit(hwnd,diamond[m][0],diamond[m][1],BLACK);
   }
  }
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return DefWindowProc(hwnd,message,wParam,lParam);
}


void DrawUnit(HWND hwnd,int m,int n,int color)
{
 HDC hdcNow=GetDC(hwnd);
 if(color==WHITE)
 {
  SelectObject(hdcNow,CreatePen(NULL,NULL,RGB(208,221,238)));
  SelectObject(hdcNow,(HBRUSH)CreateSolidBrush(RGB(208,221,238)));
 }
 Rectangle(hdcNow,32*n+150,32*m,32*n+150+32,32*m+32);
 ReleaseDC(hwnd,hdcNow);
}

void DrawDiamond(int color)
{
 DrawUnit(hwnd,diamond[0][0],diamond[0][1],color);
 DrawUnit(hwnd,diamond[1][0],diamond[1][1],color);
 DrawUnit(hwnd,diamond[2][0],diamond[2][1],color);
 DrawUnit(hwnd,diamond[3][0],diamond[3][1],color);
}

void InitDiamond(HWND hwnd,int a,int b,int current_type)
{
 int c=0,d=0,e=0,f=0,g=0,h=0;
 switch(current_type)
 {
 case 0:
  c=a+1;
  d=b-1;
  e=a+1;
  f=b;
  g=a+1;
  h=b+1;
  break;
 case 1:
  c=a+1;
  d=b;
  e=a+1;
  f=b+1;
  g=a+2;
  h=b;
  break;
 case 2:
  c=a;
  d=b+1;
  e=a;
  f=b+2;
  g=a+1;
  h=b+1;
  break;
 case 3:
  c=a+1;
  d=b-1;
  e=a+1;
  f=b;
  g=a+2;
  h=b;

  break;
 case 4:
  c=a;
  d=b+1;
  e=a+1;
  f=b-1;
  g=a+1;
  h=b;

  break;
 case 5:
  c=a+1;
  d=b;
  e=a+1;
  f=b+1;
  g=a+2;
  h=b+1;

  break;
 case 6:
  c=a;
  d=b+1;
  e=a+1;
  f=b+1;
  g=a+1;
  h=b+2;

  break;
 case 7:
  c=a+1;
  d=b-1;
  e=a+1;
  f=b;
  g=a+2;
  h=b-1;

  break;
 case 8:
  c=a;
  d=b+1;
  e=a+1;
  f=b;
  g=a+1;
  h=b+1;

  break;
 case 9:
  c=a+1;
  d=b-2;
  e=a+1;
  f=b-1;
  g=a+1;
  h=b;

  break;
 case 10:
  c=a+1;
  d=b;
  e=a+2;
  f=b;
  g=a+2;
  h=b+1;

  break;
 case 11:
  c=a;
  d=b+1;
  e=a;
  f=b+2;
  g=a+1;
  h=b;

  break;
 case 12:
  c=a;
  d=b+1;
  e=a+1;
  f=b+1;
  g=a+2;
  h=b+1;

  break;
 case 13:
  c=a+1;
  d=b;
  e=a+1;
  f=b+1;
  g=a+1;
  h=b+2;

  break;
 case 14:
  c=a;
  d=b+1;
  e=a+1;
  f=b;
  g=a+2;
  h=b;

  break;
 case 15:
  c=a;
  d=b+1;
  e=a;
  f=b+2;
  g=a+1;
  h=b+2;

  break;
 case 16:
  c=a+1;
  d=b;
  e=a+2;
  f=b-1;
  g=a+2;
  h=b;

  break;
 case 17:
  c=a+1;
  d=b;
  e=a+2;
  f=b;
  g=a+3;
  h=b;

  break;
 case 18:
  c=a;
  d=b+1;
  e=a;
  f=b+2;
  g=a;
  h=b+3;
  break;
 } 
 diamond[0][0]=a;
 diamond[0][1]=b;
 diamond[1][0]=c; 
 diamond[1][1]=d;
 diamond[2][0]=e;
 diamond[2][1]=f;
 diamond[3][0]=g;
 diamond[3][1]=h;
}

void DownLine(HWND hwnd,int baseline)
{
 for(int i=baseline;i>=current_max;i--)
 {
  for(int n=0;n<16;n++)
  {
   global[i][n]=global[i-1][n];
/*   if(global[i][n]==0)
   {
    DrawUnit(hwnd,i,n,WHITE);
   }
   else
   {
    DrawUnit(hwnd,i,n,BLACK);
   }*/
  }
 }
 InvalidateRect(hwnd,NULL,FALSE);
}

bool CheckLeft()
{
 bool canleft=true;
 for(i=0;i<4;i++)
 {
  if(global[diamond[i][0]][diamond[i][1]-1]==1 || diamond[i][1]-1<0)
  {
   canleft=false;
  }
 }
 return canleft;
}

void MoveLeft()
{
 DrawDiamond(WHITE);
 for(i=0;i<4;i++)
 {
  diamond[i][1]=diamond[i][1]-1;
 }
 DrawDiamond(BLACK);
}

bool CheckRight()
{
 bool canright=true;
 for(i=0;i<4;i++)
 {
  if(global[diamond[i][0]][diamond[i][1]+1]==1 || diamond[i][1]+1>15)
  {
   canright=false;
  }
 }
 return canright;
}

void MoveRight()
{
 DrawDiamond(WHITE);
 for(i=0;i<4;i++)
 {
  diamond[i][1]=diamond[i][1]+1;
 }
 DrawDiamond(BLACK);
}

void DownQuickly()
{
 bool down=true;
 for(i=0;i<4;i++)   //check for down
 {
  if(global[diamond[i][0]+2][diamond[i][1]]==1 || diamond[i][0]+2>=18)
  {
   down=false;
  }
 }
 if(down==true)
 {
  DrawDiamond(WHITE);
  for(i=0;i<4;i++)
  {
   diamond[i][0]=diamond[i][0]+2;
  }
  DrawDiamond(BLACK);
 }
}

void Rotate()
{
 int diamond_backup[4][2];

 int new_type=0;
 for(int m=0;m<4;m++)
 {
  for(int n=0;n<2;n++)
  {
   diamond_backup[m][n]=diamond[m][n];
  }
 }

 bool can_rotate=true;
 xBase=diamond[0][0];
 yBase=diamond[0][1];
 switch(current_type)
 {
 case 0:
  new_type=1;
  break;
 case 1:
  new_type=2;
  yBase=diamond[0][1]-1;
  break;
 case 2:
  new_type=3;
  yBase=diamond[0][1]+1;
  break;
 case 3:
  current_type=0;
  break;
 case 4:
  new_type=5;
  yBase=diamond[0][1]-1;
  break;
 case 5:
  new_type=4;
  yBase=diamond[0][1]+1;
  break;
 case 6:
  new_type=7;
  yBase=diamond[0][1]+1;
  break;
 case 7:
  new_type=6;
  yBase=diamond[0][1]-1;
  break;
 case 8:
        new_type=8;
  break;
 case 9:
  new_type=10;
  yBase=diamond[0][1]-1;
  break;
 case 10:
  new_type=11;
  break;
 case 11:
  new_type=12;
  break;
 case 12:
  new_type=9;
  break;
 case 13:
  new_type=14;
  break;
 case 14:
  new_type=15;
  break;
 case 15:
  new_type=16;
  break;
 case 16:
  new_type=13;
  break;
 case 17:
  new_type=18;
  break;
 case 18:
  new_type=17;
  break;
 }
 InitDiamond(hwnd,xBase,yBase,new_type);
 for(m=0;m<4;m++)
 {
  if(global[diamond[m][0]][diamond[m][1]]==1 || diamond[m][0]>18 || diamond[m][1]<0 || diamond[m][1]>15)
  {
   can_rotate=false;
  }
 }
 if(current_type!=8 && can_rotate==true)
 {
  for(int m=0;m<4;m++)
  {
   for(int n=0;n<2;n++)
   {
    diamond[m][n]=diamond_backup[m][n];
   }
  }
  DrawDiamond(WHITE);
  current_type=new_type;
  InitDiamond(hwnd,xBase,yBase,current_type);
  DrawDiamond(BLACK);
 }
 if(can_rotate==false)     //restore the diamond
 {
  for(int m=0;m<4;m++)
  {
   for(int n=0;n<2;n++)
   {
    diamond[m][n]=diamond_backup[m][n];
   }
  }
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值