/**//*************************************************** Filename:ELSFK.h Anthor:shly E-mail:xlq1989@vip.qq.com LastUpdate:2009.8.7 ***************************************************/
#pragma once
#include "stdafx.h" #include <cassert> //----------------------Data--------------------------- struct SquareData{ static const int S_KIND = 7; static const int S_MAX = 16; static const int S_START= 6; static int sE[S_KIND]; static int sData[S_KIND][S_MAX]; }; int SquareData::sE[SquareData::S_KIND] = {4, 3, 3, 3, 3, 3, 2}; int SquareData::sData[SquareData::S_KIND][SquareData::S_MAX] = {//0为格子不显示 非0则显示 {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, {2, 0, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 3, 0, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, {4, 4, 0, 0, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 5, 5, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 6, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; //----------------------Matrix-------------------------- //游戏区域 class Matrix{ protected: int x,y; int* pM; public: Matrix(int _x, int _y) :x(_x),y(_y) { pM = new int[x*y]; assert(pM); for(int i = 0; i<x*y; ++i) pM[i] = 0; } Matrix(int* _t, int _x, int _y) :x(_x),y(_y) { pM = new int[x*y]; assert(pM); for(int i = 0; i<x*y; ++i) pM[i] = _t[i]; } virtual ~Matrix(){ delete [] pM;} public: //common functions int GetX() const {return x;} int GetY() const {return y;} int*GetM() const {return pM;} void MatrixCombin(Matrix& _m,int _x, int _y, bool zero = false); bool MatrixIntersect(Matrix& _m, int _x, int _y); bool MatrixYAll(int _y, bool zero = false); public: //use in the game void MatrixDeleteAndMove(int _y); }; void Matrix::MatrixCombin(Matrix& _m, int _x, int _y, bool zero) { int Ex = _m.GetX(), Ey = _m.GetY(); for(int i = 0; i<Ey; ++i) for(int j =0; j<Ex; ++j) { if(_m.GetM()[i*Ex+j]){ if(_x+j<0 || _x+j>=x || _y+i<0 || _y+i>=y ) continue; zero?pM[(_y+i)*x+_x+j] = 0:pM[(_y+i)*x+_x+j] = (pM[(_y+i)*x+_x+j]>_m.GetM()[i*Ex+j]?pM[(_y+i)*x+_x+j]:_m.GetM()[i*Ex+j]); } } } bool Matrix::MatrixIntersect(Matrix& _m, int _x, int _y) { int Ex = _m.GetX(), Ey = _m.GetY(); for(int i = 0; i<Ey; ++i) for(int j =0; j<Ex; ++j) { if(_m.GetM()[i*Ex+j]){ if(_x+j<0 || _x+j>=x || _y+i<0 || _y+i>=y || pM[(_y+i)*x+_x+j] ) return true; } } return false; } bool Matrix::MatrixYAll(int _y, bool zero) { if(_y<0 || _y>=y) return false; for(int i = 0; i<x; ++i) if( zero?pM[_y*x+i]:!pM[_y*x+i]) return false; return true; } void Matrix::MatrixDeleteAndMove(int _y) { if(_y<0 || _y>=y) return; for(int i = _y; i>0; --i){ for(int j = 0; j<x; ++j) pM[i*x+j] = pM[(i-1)*x+j]; //use in the game if(MatrixYAll(i,true)) break; } }
//------------------------FKMatrix------------------------- //方块 class FKMatrix:public Matrix{ protected: int sx, sy; public: FKMatrix(int index):Matrix(SquareData::sData[index], SquareData::sE[index], SquareData::sE[index]), sx(SquareData::S_START),sy(0) {} int GetSX() const {return sx;} int GetSY() const {return sy;} void SetSX(int _x) {sx = _x;} void SetSY(int _y) {sy = _y;} void FKMatrixTransform(Matrix& _m); };
void FKMatrix::FKMatrixTransform(Matrix& _m) { int i = 0,E = x; int* tM = new int[E*E]; assert(pM); int* t = pM; for(int j = 0; j<E; ++j) for(int l = E - 1; l>=0; --l, ++i) tM[i] = pM[l*E+j]; //use in the game pM = tM; if(_m.MatrixIntersect(*this,sx,sy)){ pM = t; delete [] tM; }else delete [] t; }
// ELSFK.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "ELSFK.h" #include "resource.h" #include <ctime>
// 全局变量: Matrix matGame(10,18); FKMatrix* matFK = NULL;
bool bAgain = true; int score = 0; int level = 1; const int DES = 20; const int SCREEN_WIDTH = 308; const int SCREEN_HEIGHT = 408;
#define FKBeginUpdate(__g,__f) __g.MatrixCombin(*__f,__f->GetSX(),__f->GetSY(),true); #define FKEndUpdate(__g,__f) __g.MatrixCombin(*__f,__f->GetSX(),__f->GetSY(),false);\ InvalidateRect(hWnd,NULL,false);
//{{{--------------------------编译器生成代码-------------------------- #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); MSG msg; HACCEL hAccelTable; LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_ELSFK, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)){return FALSE;} hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_ELSFK)); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ELSFK)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_ELSFK); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX, 400,100,SCREEN_WIDTH,SCREEN_HEIGHT, NULL, NULL, hInstance, NULL); if (!hWnd){ return FALSE;} ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //--------------------------编译器生成代码------------------------}}}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc;
switch (message) { //{{{---------------------菜单---------------------- case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; //---------------------菜单----------------------}}} case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); HBITMAP tmpBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT); HDC tmpDC = CreateCompatibleDC(hdc); SelectObject(tmpDC,tmpBmp); //---------------------背景------------------------- { RECT r1 = {0,0,(matGame.GetX())*DES,(matGame.GetY())*DES}; RECT r2 = {(matGame.GetX())*DES,0,SCREEN_WIDTH,(matGame.GetY())*DES}; FillRect(tmpDC,&r1,(HBRUSH)GetStockObject(BLACK_BRUSH)); FillRect(tmpDC,&r2,(HBRUSH)GetStockObject(DKGRAY_BRUSH)); } //--------------------游戏区------------------------ for(int i = 0; i<matGame.GetY(); ++i) for(int j = 0; j<matGame.GetX(); ++j) { int id = matGame.GetM()[i*matGame.GetX()+j]; if(!id) continue; HBRUSH hBrush = CreateSolidBrush(RGB(id*35,255-id*35,id*20+150)); HBRUSH hOld =(HBRUSH) SelectObject(hdc,hBrush); RECT r = {j*DES,i*DES,j*DES+DES-1,i*DES+DES-1}; FillRect(tmpDC,&r,hBrush); SelectObject(hdc,hOld); DeleteObject(hBrush); } //---------------------边栏------------------------- SetBkMode(tmpDC,TRANSPARENT); SetTextColor(tmpDC,RGB(200,50,75)); char cScr[20]; int l = wsprintfA(cScr,"得分: %d",score); TextOutA(tmpDC,matGame.GetX()*DES+2,SCREEN_HEIGHT/2-60,cScr,l);
SetTextColor(tmpDC,RGB(200,200,0)); l = wsprintfA(cScr,"等级: %d",level); TextOutA(tmpDC,matGame.GetX()*DES+2,SCREEN_HEIGHT/2,cScr,l);
BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,tmpDC,0,0,SRCCOPY); DeleteDC(tmpDC); DeleteObject(tmpBmp); EndPaint(hWnd, &ps); break; } case WM_TIMER: SendMessage(hWnd,WM_KEYDOWN,VK_DOWN,0); break; case WM_KEYDOWN: { FKBeginUpdate(matGame,matFK);//开始更新 int sx = matFK->GetSX(), sy = matFK->GetSY(); int x = matGame.GetX(), y = matGame.GetY(); switch(wParam) { case VK_SPACE: case VK_UP: matFK->FKMatrixTransform(matGame); break; case VK_DOWN: if(matGame.MatrixIntersect(*matFK,sx,sy+1)) bAgain = true; else matFK->SetSY(sy+1); break; case VK_LEFT: if(matGame.MatrixIntersect(*matFK,sx-1,sy)) break; matFK->SetSX(sx-1); break; case VK_RIGHT: if(matGame.MatrixIntersect(*matFK,sx+1,sy)) break; matFK->SetSX(sx+1); break; default:break; } FKEndUpdate(matGame,matFK);//结束更新 if(bAgain) { int count = 0; for(int i = 0; i<matFK->GetY(); ++i) if(matGame.MatrixYAll(sy+i,false)){ matGame.MatrixDeleteAndMove(sy+i); ++count; } score += count*count*2; level = score/200+1; if(matFK->GetSY()-count<=0){ KillTimer(hWnd,1); MessageBox(NULL,L"Game Over!",L"Sys",MB_OK); SendMessage(hWnd,WM_DESTROY,0,0); return 0; } delete matFK; bAgain = false; matFK = new FKMatrix(rand()%7); FKEndUpdate(matGame,matFK); } break; } //----------------------初始和结束处理------------------------ case WM_CREATE: srand(time(NULL)); matFK = new FKMatrix(rand()%7); bAgain = false; FKEndUpdate(matGame,matFK); SetTimer(hWnd,1,500,NULL); break; case WM_DESTROY: PostQuitMessage(0); delete matFK; break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
// “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE;
case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
|