C语言实现俄罗斯方块课程设计

本文实例为大家分享了C语言实现俄罗斯方块的具体代码,供大家参考,具体内容如下

该课程设计用VC++6.0操作如下:

1、文件->新建->文件->左边选C/C++ Header File->右边文件名命名为“tetris.h”->路径假定为桌面文件夹:tetris->确定。然后将下面红色字体标记的“头文件”代码粘贴至其中,保存并退出(或者关闭工作空间)。

2、文件->新建->文件->左边选C/C++ Header File->右边文件名命名为“tetris.h”->路径假定为桌面文件夹:tetris->确定。新建“tetris.c”源文件,将下面“源代码”代码粘贴到其中,保存并退出(或者关闭工作空间)。

3、文件->新建->工程->左边选Win32 Application ->右边工程名称命名为:tetris->路径假定为桌面文件夹:tetris->确定->一个空工程->完成。接下来:工程->增加到工程->文件。这时候,将头文件和源代码添加进去,调试使用。

1.头文件

//1.自定义枚举类型,定义7种形态的游戏方块typedef enum tetris_shape{ ZShape=0,  SShape,  LineShape,  TShape,  SquareShape,  LShape,  MirroredLShape}shape;//2.函数声明//(1)操作方块函数int maxX();//取得当前方块的最大x坐标int minX();//取得当前方块的最小x坐标void turn_left();//当前方块逆时针旋转90度void turn_right();int out_of_table();void transform();int leftable();int rightable();int downable();void move_left();void move_right();//(2)操作游戏桌面的函数int add_to_table();void remove_full();//(3)控制游戏函数void new_game();void run_game();void next_shape();int random(int seed);//(4)绘图函数void paint();void draw_table();//(5)其他功能函数void key_down(WPARAM wParam);void resize();void initialize();void finalize();//(6)回调函数,用来处理Windows消息LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);

2.源代码

//1.文件包含#include<windows.h>#include<time.h>#include<stdio.h>#include"tetris.h"//2.常量定义#define APP_NAME "TETRIS"#define APP_TITLE "Tetris Game"#define GAMEOVER "GAME OVER"#define SHAPE_COUNT 7#define BLOCK_COUNT 4#define MAX_SPEED 5#define COLUMS 10#define ROWS 20#define RED RGB(255,0,0)#define YELLOW RGB(255,255,0)#define GRAY RGB(128,128,128)#define BLACK RGB(0,0,0)#define WHITE RGB(255,255,255)#define STONE RGB(192,192,192)#define CHARS_IN_LINE 14#define SCORE "SCORE %4d"

3.全局变量定义

//(1)char score_char[CHARS_IN_LINE]={0};//(2)char* press_enter="Press Enter key...";//(3)帮助提示信息char *help[]={ "press space or up key to transform shape.",  "Press left or right key to mover shape.",  "Press down key to speed up.",  "Press enter key to pause game.",  "Enjoy it.:-)",  0};//(4)枚举游戏的状态enum game_state{ game_start,  game_run,  game_pause,  game_over,}state=game_start;//(5)定义方块的颜色COLORREF shape_color[]={ RGB(255,0,0),  RGB(0,255,0),  RGB(0,0,255),  RGB(255,255,0),  RGB(0,255,255),  RGB(255,0,255),  RGB(255,255,255)};//(6)方块的7中类型int shape_coordinate[SHAPE_COUNT][BLOCK_COUNT][2]={ {{0,1},{0,0},{-1,0},{-1,1}}, {{0,-1},{0,0},{1,0},{1,1}}, {{0,-1},{0,0},{0,1},{0,2}}, {{-1,0},{0,0},{1,0},{0,1}}, {{0,0},{1,0},{0,1},{1,1}}, {{-1,-1},{0,-1},{0,0},{0,1}}, {{1,-1},{0,-1},{0,0},{0,1}}};//(7)得分int score=0;//(8)下一个方块shape next=0;//(9)当前方块shape current=0;//(10)当前方块的每一部分坐标int current_coordinate[4][2]={0};//(11)游戏桌面int table[ROWS][COLUMS]={0};//(12)当前方块的x坐标int shapex=0;//(13)当前方块的\y坐标int shapey=0;//(14)方块下移速度int speed=0;//(15)每一帧开始时间clock_t start=0;//(16)每一帧结束时间clock_t finish=0;//(17)windows绘图用变量HWND gameWND;HBITMAP memBM;HBITMAP memBMOld;HDC memDC;RECT clientRC;HBRUSH blackBrush;HBRUSH stoneBrush;HBRUSH shapeBrush[SHAPE_COUNT];HPEN grayPen;HFONT bigFont;HFONT smallFont;//4.主要处理函数//(1)取最大坐标int maxX(){ int i=0; int x=current_coordinate[i][0]; int m=x; for(i=1;i<BLOCK_COUNT;i++) {  x=current_coordinate[i][0];   if(m<x)   {    m=x;   } } return m;}//(2)取最小坐标int minX(){ int i=0; int x=current_coordinate[i][0]; int m=x; for(i=1;i<BLOCK_COUNT;i++) {  x=current_coordinate[i][0];   if(m>x)   {    m=x;   } } return m;}//(3)逆时针转动方块void turn_left(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=current_coordinate[i][0];  y=current_coordinate[i][1];  current_coordinate[i][0]=y;  current_coordinate[i][1]=-x; }}//(4)顺时针旋转方块void turn_right(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=current_coordinate[i][0];  y=current_coordinate[i][1];  current_coordinate[i][0]=-y;  current_coordinate[i][1]=x; }}//(5)检查方块是否越界int out_of_table(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=shapex+current_coordinate[i][0];  y=shapey+current_coordinate[i][1];  if(x<0||x>(COLUMS-1)||y>(ROWS-1))  {   return 1;  }  if(table[y][x])  {   return 1;  } } return 0;}//(6)旋转方块void transform(){ if(current==SquareShape) {  return ; } turn_right(); if(out_of_table()) {  turn_left(); }}//(7)判断方块是否向左移动int leftable(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=shapex+current_coordinate[i][0];  y=shapey+current_coordinate[i][1];  if(x<=0||table[y][x-1]==1)  {   return 0;  } } return 1;}//(8)判断方块是否向右移动int rightable(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=shapex+current_coordinate[i][0];  y=shapey+current_coordinate[i][1];  if(x>=(COLUMS-1)||table[y][x+1]==1)  {   return 0;  } } return 1;}//(9)判断方块是否向下移动int downable(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=shapex+current_coordinate[i][0];  y=shapey+current_coordinate[i][1];  if(y>=(ROWS-1)||table[y+1][x]==1)  {   return 0;  } } return 1;}//(10)向左移动当前方块void move_left(){ if(leftable()) {  shapex--; }}//(11)向右移动当前方块void move_right(){ if(rightable()) {  shapex++; }}//(12)向下移动当前方块void move_down(){ if(downable()) {  shapey++; } else {  if(add_to_table())  {   remove_full();   next_shape();  }  else  {   state=game_over;  } }}//(13)将当前方块固定到桌面上int add_to_table(){ int i=0; int x,y; for(i=0;i<4;i++) {  x=shapex+current_coordinate[i][0];  y=shapey+current_coordinate[i][1];  if(y<0||table[y][x]==1)  {   return 0;  }  table[y][x]=1; } return 1;}//(14)删除填满的行void remove_full(){ int c=0; int i,j; for(i=ROWS-1;i>0;i--) {  c=0;  for(j=0;j<COLUMS;j++)  {   c+=table[i][j];  }  if(c==COLUMS)  {   memmove(table[1],table[0],sizeof(int)*COLUMS*i);   memset(table[0],0,sizeof(int)*COLUMS);   score++;   speed=(score/100)%MAX_SPEED;   i++;  }  else if(c==0)  {   break;  } }}//(15)创建新游戏void new_game(){ memset(table,0,sizeof(int)*COLUMS*ROWS); start=clock(); next=random(SHAPE_COUNT); score=0; speed=0;}//(16)运行游戏void run_game(){ finish=clock(); if((finish-start)>(MAX_SPEED-speed)*100) {  move_down();  start=clock();  InvalidateRect(gameWND,NULL,TRUE); }}//(17)操作当前方块void next_shape(){ current=next; memcpy(current_coordinate,shape_coordinate[next],sizeof(int)*BLOCK_COUNT*2); shapex=(COLUMS-((maxX(current)-minX(current))))/2; shapey=0; next=random(SHAPE_COUNT);}//(18)取随机数 int random(int seed) {  if(seed==0)  {   return 0;  }  srand((unsigned)time(NULL));  return (rand()%seed); } //(19)绘图 void paint() {  PAINTSTRUCT ps;  HDC hdc;  draw_table();  hdc=BeginPaint(gameWND,&ps);  BitBlt(hdc,clientRC.left,clientRC.top,clientRC.right,clientRC.bottom,memDC,0,0,SRCCOPY);  EndPaint(gameWND,&ps); } //(20)绘制游戏桌面 void draw_table() {  HBRUSH hBrushOld;  HPEN hPenOld;  HFONT hFontOld;  RECT rc;  int x0,y0,w;  int x,y,i,j;  char* str;  w=clientRC.bottom/(ROWS+2);  x0=y0=w;  FillRect(memDC,&clientRC,blackBrush);  // 如果游戏是开始或结束状态  if(state==game_start||state==game_over)  {   memcpy(&rc,&clientRC,sizeof(RECT));   rc.bottom=rc.bottom/2;   hFontOld=SelectObject(memDC,bigFont);   SetBkColor(memDC,BLACK);   //如果游戏是开始状态,用黄色字显示游戏开始画面   if(state==game_start)   {    str=APP_TITLE;    SetTextColor(memDC,YELLOW);    }  //如果游戏是结束状态,用红色字显示GAME OVER     else    {     str=GAMEOVER;     SetTextColor(memDC,RED);    }    DrawText(memDC,str,strlen(str),&rc,DT_SINGLELINE|DT_CENTER|DT_BOTTOM);    SelectObject(memDC,hFontOld);    hFontOld=SelectObject(memDC,smallFont);    rc.top=rc.bottom;    rc.bottom=rc.bottom*2;    if(state==game_over)    {     SetTextColor(memDC,YELLOW);     sprintf(score_char,SCORE,score);     DrawText(memDC,score_char,strlen(score_char),&rc,DT_SINGLELINE|DT_CENTER|DT_TOP);    }    SetTextColor(memDC,STONE);    DrawText(memDC,press_enter,strlen(press_enter),&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);    SelectObject(memDC,hFontOld);    return;   }  //桌面上残留的方块   hBrushOld=SelectObject(memDC,stoneBrush);   for(i=0;i<ROWS;i++)   {    for(j=0;j<COLUMS;j++)    {     if(table[i][j]==1)     {      x=x0+j*w;      y=y0+i*w;      Rectangle(memDC,x,y,x+w+1,y+w+1);     }    }   }   SelectObject(memDC,hBrushOld);   //画当前的方块   hBrushOld=SelectObject(memDC,shapeBrush[current]);   for(i=0;i<4;i++)   {    x=x0+(current_coordinate[i][0]+shapex)*w;    y=y0+(current_coordinate[i][1]+shapey)*w;    if(x<x0||y<y0)    {     continue;    }    Rectangle(memDC,x,y,x+w+1,y+w+1);   }   SelectObject(memDC,hBrushOld);   //画桌面上的表格线   hPenOld=SelectObject(memDC,grayPen);   for(i=0;i<=ROWS;i++)   {    MoveToEx(memDC,x0,y0+i*w,NULL);    LineTo(memDC,x0+COLUMS*w,y0+i*w);   }   for(i=0;i<=COLUMS;i++)   {    MoveToEx(memDC,x0+i*w,y0,NULL);    LineTo(memDC,x0+i*w,y0+ROWS*w);   }   SelectObject(memDC,hPenOld);   //画玩家得分   x0=x0+COLUMS*w+3*w;   y0=y0+w;   hFontOld=SelectObject(memDC,smallFont);   SetTextColor(memDC,YELLOW);   sprintf(score_char,SCORE,score);   TextOut(memDC,x0,y0,score_char,strlen(score_char));   //画下一个方块   y0+=w;   SetTextColor(memDC,STONE);   TextOut(memDC,x0,y0,"NEXT",4);   x0+=w;   y0+=2*w;   hBrushOld=SelectObject(memDC,shapeBrush[next]);   for(i=0;i<4;i++)   {    x=x0+shape_coordinate[next][i][0]*w;    y=y0+shape_coordinate[next][i][1]*w;    Rectangle(memDC,x,y,x+w+1,y+w+1);   }   SelectObject(memDC,hBrushOld);   //打印帮助信息   x0=(COLUMS+2)*w;   y0+=4*w;   SetTextColor(memDC,GRAY);   i=0;   while(help[i])   {    TextOut(memDC,x0,y0,help[i],strlen(help[i]));    y0+=w;    i++;   }  SelectObject(memDC,hFontOld); } //(21)处理按键 void key_down(WPARAM wParam) {  //如果游戏不是运行状态,按下回车键  if(state!=game_run)  {   if(wParam==VK_RETURN)   {   switch(state)    {     case game_start:      next_shape();      state=game_run;      break;     case game_pause:      state=game_run;      break;     case game_over:      new_game();      next_shape();      state=game_run;      break;    }   }  }  //如果游戏状态是运行  else   {   switch(wParam)   {   case VK_SPACE:   case VK_UP:    transform();    break;   case VK_LEFT:    move_left();    break;   case VK_RIGHT:    move_right();    break;   case VK_DOWN:    move_down();    break;   case VK_RETURN:    state=game_pause;    break;   }  }  InvalidateRect(gameWND,NULL,TRUE); } //(22)改变窗口大小 void resize() {  HDC hdc;  LOGFONT lf;  hdc=GetDC(gameWND);  GetClientRect(gameWND,&clientRC);  SelectObject(memDC,memBMOld);  DeleteObject(memBM);  memBM=CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);  memBMOld=SelectObject(memDC,memBM);  DeleteObject(bigFont);  memset(&lf,0,sizeof(LOGFONT));  lf.lfWidth=(clientRC.right-clientRC.left)/CHARS_IN_LINE;  lf.lfHeight=(clientRC.bottom-clientRC.top)/4;  lf.lfItalic=1;  lf.lfWeight=FW_BOLD;  bigFont=CreateFontIndirect(&lf);  DeleteObject(smallFont);  lf.lfHeight=clientRC.bottom/(ROWS+2);  lf.lfWidth=lf.lfHeight/2;  lf.lfItalic=0;  lf.lfWeight=FW_NORMAL;  smallFont=CreateFontIndirect(&lf);  ReleaseDC(gameWND,hdc); } //(23)处理消息 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {  switch(message)  {  case WM_SIZE:   resize();   return 0;  case WM_ERASEBKGND:   return 0;  case WM_PAINT:   paint();   return 0;  case WM_KEYDOWN:   key_down(wParam);   return 0;  case WM_DESTROY:   PostQuitMessage(0);   return 0;  }  //其他消息用Windows默认的消息处理函数处理 return DefWindowProc(hwnd,message,wParam,lParam); } //(24)初始化 void initialize() {  LOGFONT lf;  HDC hdc;  int i;  hdc=GetDC(gameWND);  GetClientRect(gameWND,&clientRC);  memDC=CreateCompatibleDC(hdc);  memBM=CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);  memBMOld=SelectObject(memDC,memBM);  blackBrush=CreateSolidBrush(BLACK);  stoneBrush=CreateSolidBrush(STONE);  //创建每个方块对应颜色的画笔  for(i=0;i<SHAPE_COUNT;i++)  {   shapeBrush[i]=CreateSolidBrush(shape_color[i]);  }  grayPen=CreatePen(PS_SOLID,1,GRAY);  memset(&lf,0,sizeof(LOGFONT));  //创建一个大字体  lf.lfWidth=(clientRC.right-clientRC.left)/CHARS_IN_LINE;  lf.lfHeight=(clientRC.bottom-clientRC.top)/4;  lf.lfItalic=0;  lf.lfWeight=FW_NORMAL;  smallFont=CreateFontIndirect(&lf);  ReleaseDC(gameWND,hdc); } //(25)释放资源 void finalize() {  int i=0;  DeleteObject(blackBrush);  DeleteObject(stoneBrush);  for(i=0;i<SHAPE_COUNT;i++)  {   DeleteObject(shapeBrush[i]);  }  DeleteObject(grayPen);  DeleteObject(bigFont);  DeleteObject(smallFont);  SelectObject(memDC,memBMOld);  DeleteObject(memBM);  DeleteObject(memDC); } //(26) 入口函数 int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) {  MSG msg;  WNDCLASS wndclass;  //设置窗口样式  wndclass.style=CS_HREDRAW|CS_VREDRAW;  wndclass.lpfnWndProc=WndProc;  wndclass.cbClsExtra=0;  wndclass.cbWndExtra=0;  wndclass.hInstance=hInstance;  wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);  wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);  wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);  wndclass.lpszMenuName=NULL;  wndclass.lpszClassName=APP_NAME;  RegisterClass(&wndclass);  //创建Windows窗口  gameWND=CreateWindow(APP_NAME,   APP_TITLE,   WS_OVERLAPPEDWINDOW,   CW_USEDEFAULT,   CW_USEDEFAULT,   CW_USEDEFAULT,   CW_USEDEFAULT,   NULL,NULL,   hInstance,NULL);  initialize();  ShowWindow(gameWND,iCmdShow);  UpdateWindow(gameWND);  new_game();  for(;;)  {   if(state==game_run)   {    run_game();   }   //判断是否有Windows消息   if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))   {    if(GetMessage(&msg,NULL,0,0))    {     TranslateMessage(&msg);     DispatchMessage(&msg);    }    else    {     break;    }   }  }  finalize();  return msg.wParam;}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

开始的时侯,我们就知道,总会有终结。

C语言实现俄罗斯方块课程设计

相关文章:

你感兴趣的文章:

标签云: