/* * 作者:did0602 * 出自:http://www.oschina.net/code/snippet_188854_13088 */ #include #include #include #define CELL 20 #define ROWS 25 #define COLS 15 //升级所需分数值 #define SCORE_LEVEL_INC 80 #define ID_TIMER 1 /////////////////全局变量///////////////////////////// HWND hwnd; //保存窗口句柄 int score=0; //分数 int level=0; //级数 int interval_unit=25; //随级数递增的时间间隔增量 int interval_base=300; //时间间隔基量 int old_interval; //保存当前的时间间隔,用于加速操作 int cur_left,cur_top; //记录方块当前的位置 int width_block,height_block; //方块的宽带和高度 bool isPause=false; //暂停标识 UINT timer_id=0; //保存计时器ID static byte *block=NULL; //方块,方块为随机大小,采用动态分配内存方式,所以这里是指针变量 byte g_panel[ROWS][COLS]={0}; //////////////////////////////////////////////////// LRESULT CALLBACK WndProc ( HWND,UINT,WPARAM,LPARAM ); void DrawPanel ( HDC hdc ); //绘制表格 void RefreshPanel ( HDC hdc ); //刷新面板 void DoDownShift ( HDC hdc ); //下移 void DoLeftShift ( HDC hdc ); //左移 void DoRightShift ( HDC hdc ); //右移 void DoAccelerate ( HDC hdc ); //加速 void DoRedirection ( HDC hdc ); //改变方向 void ClearRow ( HDC hdc ); //消行 bool ExportBlock(); //输出方块, //该函数会直接修改全局变量block,width_block,height_block, //cur_left和cur_top bool IsTouchBottom ( HDC hdc ); //判断是否到达底部 int main() { HINSTANCE hInstance=GetModuleHandle ( NULL ); TCHAR szAppName[]=TEXT ( "teris" ); MSG msg; WNDCLASS wc; wc.style=CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc=WndProc; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hInstance=hInstance; wc.hIcon=LoadIcon ( NULL,IDI_APPLICATION ); wc.hCursor=LoadCursor ( NULL,IDC_ARROW ); wc.hbrBackground= ( HBRUSH ) GetStockObject ( WHITE_BRUSH ); wc.lpszMenuName=NULL; wc.lpszClassName=szAppName; if ( !RegisterClass ( &wc ) ) { printf ( "RegisterClass occur errors!" ); return 0; } hwnd=CreateWindow ( szAppName,TEXT ( "Teris Demo" ), WS_OVERLAPPEDWINDOW, 0,0,0,0, NULL, NULL, hInstance, NULL ); ShowWindow ( hwnd,SW_SHOW ); UpdateWindow ( hwnd ); while ( GetMessage ( &msg,NULL,0,0 ) ) { TranslateMessage ( &msg ); DispatchMessage ( &msg ); } return msg.wParam; } void DrawPanel ( HDC hdc ) //绘制游戏面板 { int x,y; RECT rect; for ( y=0; y=0; x-- ) //从右边开始扫描,获取该行最右边的实心方格块 { if ( * ( block+y*width_block+x ) ) { //判断当前方格在面板上右边一个方格是否为实心,是就代表不能再右移 if ( g_panel[cur_top+y][cur_left+x+1] ) return; break; //只判断最右边的一个实心方格 } } } cur_left++; RefreshPanel ( hdc ); } void DoRedirection ( HDC hdc ) //改变方向 { int i,j; byte * temp=NULL; if ( NULL==block ) return; if ( cur_top<0 ) return; //方块完整显示前不能转向 temp= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block ); for ( i=0; i=ROWS||temp_cur_left<0||temp_cur_left+max_len-1>=COLS ) { free ( temp ); //退出前必须先释放内存 return; } for ( i=0; i=0; y-- ) //从底行开始扫描 { //判断第一个实心方块在面板上邻接的下方方格是否为实心,是就代表已经到达底部 for ( x=0; x=0; i-- ) { isFilled=true; for ( j=0; j=0; k-- ) { for ( j=0; j=10*SCORE_LEVEL_INC-1 ) return; //加分规则:消除行数,1行加10分,2行加15分,3行加20分,4行加30分 switch ( count ) { case 1: score+=10; break; case 2: score+=15; break; case 3: score+=20; break; case 4: score+=30; break; } int temp_level=score/SCORE_LEVEL_INC; if ( temp_level>level ) { level=temp_level; //撤销当前计时器,然后重设 if ( timer_id ) KillTimer ( hwnd,ID_TIMER ); timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,NULL ); } system ( "cls" ); printf ( "score: %d, level: %d ",score,level ); } void RefreshPanel ( HDC hdc ) //刷新面板 { int x,y; RECT rect; HBRUSH h_bSolid= ( HBRUSH ) GetStockObject ( GRAY_BRUSH ), h_bEmpty= ( HBRUSH ) GetStockObject ( WHITE_BRUSH ); if ( NULL==block ) return; //先刷屏 for ( y=0; y