C++win32实现俄罗斯方块(类实现)

Vesta ·
更新时间:2024-09-21
· 709 次阅读

C++win32实现俄罗斯方块 头文件

在这里插入图片描述

源文件:

在这里插入图片描述

背景类的源码

.h文件

#pragma once class bg { public: bg(void); int getmark(); int addmark(int num); public: int background[20][10]; private: int mark ; };

.cpp文件

#include "StdAfx.h" #include "bg.h" bg::bg() { for(int i =0;i<20;i++) { for(int j = 0;jmark = this->mark + num; } int bg::getmark() { return this->mark; }

父类Block.h

#pragma once #include #include "bg.h" class Block { public: void Init(); int createBlock(Block *p); void Fix(); virtual void printblock(HDC &Hdc)=0 ; void printFix(HDC &Hdc); void fall(); void MoveLeft(); void MoveRight(); void del(); void Zchange(); void change_background(); virtual void Zchangesquare(const bg *ground) = 0; void Zchangesquare1(); void Zchangesquare2(); void Zchangesquare3(); void Zchangesquare4(); int Zchangesquarecan(); void Zchangesquare6(); int Zchangesquare6can(); bool isDown(); bool isDown_collide(); bool isGameOver(HWND hWnd); bool isLeft(); bool isRight(); bool isLeft_collide(); bool isRright_collide(); bool isFull(int a); int getSquarenum(); int getmark(); void showScore(HDC & Hdc); void wirteDcu(HWND hwnd,int mark); int ReadDcu(); void releaseDB(); protected: int squarenum; int squareline; int squarelist; protected: POINT point[8];//记录方块坐标 用于画图 int block[2][4]; //记录方块状态 int num ; };

父类的实现block.cpp

#include "stdafx.h" #include "Block.h" #include #include "Z.h" bg *ground = new bg; //随机产生方块 int Block::createBlock(Block *p) { for (int i = 0; i < 2; i++) { for (int j = 0; j background[i][j + 3] = p->block[i][j]; } } return 0; } //画固定方块 void Block::printFix(HDC & Hdc) { HGDIOBJ oldBrush; HGDIOBJ newBrush = CreateSolidBrush(RGB(0, 255, 127)); oldBrush = SelectObject(Hdc, newBrush); for (int i = 0; i < 20; i++) { for (int j = 0; j background[i][j]) { Rectangle(Hdc, j * 20, i * 20, j * 20 + 19, i * 20 + 19); } } } newBrush = SelectObject(Hdc, oldBrush); DeleteObject(newBrush); } //固定 void Block::Fix() { for (int i = 0; i < 20; i++) { for (int j = 0; j background[i][j]) { ground->background[i][j] = 2; num = 0; } } } } //是否能下落 bool Block::isDown() { for (int i = 0; i background[19][i]) { return false; } } return true; } //下落障碍碰撞 bool Block::isDown_collide() { for (int i = 19; i >= 0; i--) { for (int j = 0; j background[i][j]) { if (2 == ground->background[i + 1][j]) { return false; } } } } return true; } bool Block::isLeft() { for (int i = 0; i background[i][0]) { return false; } } return true; } //左移障碍碰撞 bool Block::isLeft_collide() { for (int i = 0; i < 20; i++) { for (int j = 0; j background[i][j]) { if (2 == ground->background[i][j - 1]) { return false; } } } } return true; } bool Block::isRight() { for (int i = 0; i background[i][9]) { return false; } } return true; } //右移障碍碰撞 bool Block::isRright_collide() { for (int i = 0; i = 0; j--) { if (1 == ground->background[i][j]) { if (2 == ground->background[i][j + 1]) { return false; } } } } return true; } //下落 void Block::fall() { for(int i =0;i = 0; i--) { for (int j = 0; j background[i][j]) { ground->background[i + 1][j] = ground->background[i][j]; ground->background[i][j] = 0; } } } squareline++; } //左移 void Block::MoveLeft() { for(int i =0;i<sizeof(point)/sizeof(POINT);i++) { point[i].x-=20; } for (int i = 0; i < 20; i++) { for (int j = 0; j background[i][j]) { ground->background[i][j - 1] = ground->background[i][j]; ground->background[i][j] = 0; } } } squarelist--; } //右移 void Block::MoveRight() { for(int i =0;i<sizeof(point)/sizeof(POINT);i++) { point[i].x+=20; } for (int i = 0; i = 0; j--) { if (1 == ground->background[i][j]) { ground->background[i][j + 1] = ground->background[i][j]; ground->background[i][j] = 0; } } } squarelist++; } //判断是否满行 bool Block::isFull(int a) { int n = 0; for(int j = 0;jbackground[a][j] == 2 ) { n++; } } if(n == 10) { ground->addmark(10); return true; } return false; } void Block::del()//消行 { for(int i = 0;i=0;n--) { for(int j = 0;jbackground[n][j] = ground->background[n-1][j]; } } for(int i2 = 0;i2background[0][i2] = 0; } } } } int Block::getSquarenum() { return this->squarenum; } int Block::getmark() { return ground->getmark(); } //该方法计划用于数据存储,基本内容已经实现,有些小细节没有完成 void Block::wirteDcu(HWND hwnd,int mark) { TCHAR writeFile[] = _T("d://a.txt"); HANDLE wFile = CreateFile(writeFile, //创建文件的名称。 GENERIC_WRITE, // GENERIC_WRITE | GENERIC_READ, 写和读文件。 0, // 不共享。 NULL, // 缺省安全属性 OPEN_ALWAYS, // CREATE_ALWAYS 覆盖文件(不存在则创建) OPEN_EXISTING 打开文件(不存在则报错) FILE_ATTRIBUTE_NORMAL, // 一般的文件。 NULL); // 模板文件为空。 GetLastError(); DWORD dwreturnsize; wchar_t p[5]; memset(p,0,sizeof(p)); _itoa(mark,(char*) p, 10); p[4]='\0'; WriteFile(wFile, p, sizeof(p), &dwreturnsize, NULL); //WriteFile(wFile, &s, 1, &dwreturnsize, NULL); CloseHandle(wFile);//关闭文件 } int Block::ReadDcu() { TCHAR szFile[] = _T("d://a.txt"); HANDLE hFile = CreateFile(szFile, //创建文件的名称。 GENERIC_READ, // GENERIC_WRITE | GENERIC_READ, 写和读文件。 FILE_SHARE_READ, // 共享读。 NULL, // 缺省安全属性 OPEN_EXISTING, // CREATE_ALWAYS 覆盖文件(不存在则创建) OPEN_EXISTING 打开文件(不存在则报错) FILE_ATTRIBUTE_NORMAL, // 一般的文件。 NULL); // 模板文件为空。 if (hFile == INVALID_HANDLE_VALUE) //无效值 { OutputDebugString(TEXT("CreateFile fail!\r\n")); return 0; } DWORD dwSize = GetFileSize(hFile, NULL); //读取文件大小 //cout << "dwSize=" << dwSize << endl; char cBuf[5]; //在堆上开辟缓冲区,等待读入文件数据 memset(cBuf,0,sizeof(cBuf)); //SetFilePointer(hFile, 10, NULL, FILE_BEGIN); DWORD haveReadByte; ReadFile(hFile, cBuf, 4, &haveReadByte, 0); int num = MultiByteToWideChar(0,0,cBuf,-1,NULL,0); MessageBox(NULL,cBuf, TEXT("最佳纪录"), MB_OK); CloseHandle(hFile); return 0; } void Block::releaseDB() { if(ground != NULL) { delete ground; ground = NULL; } }

功能以及分数展示

void Block::showScore(HDC & Hdc) { Rectangle(Hdc, 200, 0, 350, 400); char strScore[10]; memset(strScore,0,sizeof(strScore)); _itoa(ground->getmark(),(char*)strScore, 10); TextOut(Hdc, 250, 80, TEXT("分数"), strlen("分数")); TextOut(Hdc, 270, 100, strScore, strlen(strScore)); TextOut(Hdc,210, 195, TEXT("俄罗斯方块游戏介绍"), strlen(TEXT("俄罗斯方块游戏介绍"))); TextOut(Hdc,235, 240, TEXT("按上变形"), strlen("按上变形")); TextOut(Hdc, 235, 260, TEXT("按下加速"), strlen("按下加速")); TextOut(Hdc, 235, 280, TEXT("按左向左移"), strlen("按左向左移")); TextOut(Hdc, 235, 300, TEXT("按右向右移"), strlen("按右向右移")); }

游戏结束的判断

bool Block::isGameOver(HWND hWnd) { for (int i = 0; i background[1][i] || 1 == ground->background[1][i]|| 2 == ground->background[0][i]||1 == ground->background[0][i] ) { TCHAR szBuffer[1024]; LPCTSTR str = TEXT("恭喜你获得: %d分"); wsprintf(szBuffer, str,ground->getmark() ); wirteDcu(hWnd,ground->getmark()); MessageBox(NULL, szBuffer , TEXT("gameover"), MB_RETRYCANCEL); releaseDB(); return false; } } return true; }

旋转的实现

void Block::Zchange() { switch(squarenum) { case 0: if(1==Zchangesquarecan()) { Zchangesquare(ground); } else { return ; } break; case 1: if(1==Zchangesquarecan()) { Zchangesquare(ground); } else { return ; } break; case 2: if(1==Zchangesquarecan()) { Zchangesquare(ground); } else { return ; } break; case 3: if(1==Zchangesquarecan()) { Zchangesquare(ground); } else { return ; } break; case 4: if(1==Zchangesquarecan()) { Zchangesquare(ground); } else { return ; } break; case 5: return; case 6: if(1==Zchangesquare6can()) { Zchangesquare6(); } else { return; } break; } } void Block::change_background() { int x = 0; int y = 0; int twoline = 2; int Zremblock[3][3]={0}; for(x = 0 ;x < 3;x++) { for(y = 0;y background[squareline+x][squarelist+y]; } } for( x = 0;x < 3;x++) { for(y = 0;y background[squareline+x][squarelist+y] = Zremblock[twoline][x]; twoline--; } twoline=2; } } int Block::Zchangesquarecan() { int x = 0; int y = 0; for(x=0;x<3;x++) { for(y=0;ybackground[squareline+x][squarelist+y]) { return 0; } } } if( squareline >= 17) { return 0; } if( squarelist=8) { return 0; } return 1; } void Block::Zchangesquare6() { if(1 == ground->background[squareline][squarelist-1]) { if(2 == ground->background[squareline+1][squarelist]||2==ground->background[squareline+2][squarelist]) { return; } else { ground->background[squareline][squarelist-1]=0; ground->background[squareline][squarelist+1]=0; ground->background[squareline][squarelist+2]=0; ground->background[squareline-1][squarelist]=1; ground->background[squareline+1][squarelist]=1; ground->background[squareline+2][squarelist]=1; point[0].y = 20*(squareline-1);point[0].x = 20*(squarelist); point[1].y = 20*(squareline-1)+20-1;point[1].x = 20*(squarelist)+20-1; point[4].y = 20*(squareline+1);point[4].x = 20*(squarelist); point[5].y = 20*(squareline+1)+20-1;point[5].x = 20*(squarelist)+20-1; point[6].y = 20*(squareline+2);point[6].x = 20*(squarelist); point[7].y = 20*(squareline+2)+20-1;point[7].x = 20*squarelist+20-1; } } else { if(2 == ground->background[squareline][squarelist+1] || 2 == ground->background[squareline][squarelist+2] || 2 == ground->background[squareline][squarelist-1]) { return; } else { point[0].y = 20*squareline; point[0].x = 20*(squarelist-1); point[1].y = (20*squareline)+20-1; point[1].x = 20*(squarelist-1)+20-1; point[4].y = 20*squareline; point[4].x = 20*(squarelist+1); point[5].y = (20*squareline)+20-1; point[5].x = 20*(squarelist+1)+20-1; point[6].y = 20*squareline; point[6].x = 20*(squarelist+2); point[7].y = (20*squareline)+20-1; point[7].x = 20*(squarelist+2)+20-1; ground->background[squareline][squarelist-1]=1; ground->background[squareline][squarelist+1]=1; ground->background[squareline][squarelist+2]=1; ground->background[squareline-1][squarelist]=0; ground->background[squareline+1][squarelist]=0; ground->background[squareline+2][squarelist]=0; } } } int Block::Zchangesquare6can() { if(squareline0 && squarelist>0 && squarelist<8)//边界不可变 { return 1; } return 0; } 子类的实现 #include "StdAfx.h" #include "L.h" L::L() { // ■ // ■■■ point[0].x = 60;point[0].y = 0; point[1].x = 79;point[1].y = 19; point[2].x = 60;point[2].y = 20; point[3].x = 79;point[3].y = 39; point[6].x = 80;point[6].y = 20; point[7].x = 99;point[7].y = 39; point[4].x = 100;point[4].y = 20; point[5].x = 119;point[5].y = 39; block[0][0] = 1,block[0][1] = 0,block[0][2] = 0,block[0][3] = 0; block[1][0] = 1,block[1][1] = 1,block[1][2] = 1,block[1][3] = 0; squareline = 0; squarelist = 3; squarenum = 3; } void L::printblock(HDC &Hdc) { Rectangle(Hdc, 0, 0, 200, 400); HBRUSH oldBrush; HBRUSH newBrush = CreateSolidBrush(RGB(141, 238, 238));//将画笔改成红色 oldBrush = (HBRUSH)SelectObject(Hdc, newBrush);//保存之前的画笔颜色 for(int i = 0;i background[squareline][squarelist])//0 { change_background(); point[0].x = 20*(squarelist+2);point[0].y = 20*(squareline); point[1].x = 20*(squarelist+2+1)-1;point[1].y = 20*(squareline+1)-1; point[2].x = 20*(squarelist+1);point[2].y = 20*(squareline); point[3].x = 20*(squarelist+1+1)-1;point[3].y = 20*(squareline+1)-1; point[4].x = 20*(squarelist+1);point[4].y = 20*(squareline+1); point[5].x = 20*(squarelist+1+1)-1;point[5].y = 20*(squareline+1+1)-1; point[6].x = 20*(squarelist+1);point[6].y = 20*(squareline+2); point[7].x = 20*(squarelist+1+1)-1;point[7].y = 20*(squareline+2+1)-1; } else if(1 == ground->background[squareline][squarelist+2])//1 { change_background(); point[0].x = 20*(squarelist+2);point[0].y = 20*(squareline+2); point[1].x = 20*(squarelist+2+1)-1;point[1].y = 20*(squareline+2+1)-1; point[2].x = 20*(squarelist+2);point[2].y = 20*(squareline+1); point[3].x = 20*(squarelist+2+1)-1;point[3].y = 20*(squareline+1+1)-1; point[4].x = 20*(squarelist+1);point[4].y = 20*(squareline+1); point[5].x = 20*(squarelist+1+1)-1;point[5].y = 20*(squareline+1+1)-1; point[6].x = 20*(squarelist);point[6].y = 20*(squareline+1); point[7].x = 20*(squarelist+1)-1;point[7].y = 20*(squareline+1+1)-1; } else if(1 == ground->background[squareline+2][squarelist+2])//2 { change_background(); point[0].x = 20*(squarelist);point[0].y = 20*(squareline+2); point[1].x = 20*(squarelist+1)-1;point[1].y = 20*(squareline+2+1)-1; point[2].x = 20*(squarelist+1);point[2].y = 20*(squareline+2); point[3].x = 20*(squarelist+1+1)-1;point[3].y = 20*(squareline+2+1)-1; point[4].x = 20*(squarelist+1);point[4].y = 20*(squareline+1); point[5].x = 20*(squarelist+1+1)-1;point[5].y = 20*(squareline+1+1)-1; point[6].x = 20*(squarelist+1);point[6].y = 20*(squareline); point[7].x = 20*(squarelist+1+1)-1;point[7].y = 20*(squareline+1)-1; } else if(1 == ground->background[squareline+2][squarelist])//3 { change_background(); point[0].x = 20*(squarelist);point[0].y = 20*(squareline); point[1].x = 20*(squarelist+1)-1;point[1].y = 20*(squareline+1)-1; point[2].x = 20*(squarelist);point[2].y = 20*(squareline+1); point[3].x = 20*(squarelist+1)-1;point[3].y = 20*(squareline+1+1)-1; point[4].x = 20*(squarelist+1);point[4].y = 20*(squareline+1); point[5].x = 20*(squarelist+1+1)-1;point[5].y = 20*(squareline+1+1)-1; point[6].x = 20*(squarelist+2);point[6].y = 20*(squareline+1); point[7].x = 20*(squarelist+2+1)-1;point[7].y = 20*(squareline+1+1)-1; } }

其他的类似实现方法

为窗口实现事件监听 switch (message) { case WM_CREATE: timer.Init(); timer.onReturn(hWnd,500); break; case WM_TIMER: timer.onTimer(hWnd); break; case WM_PAINT: { PAINTSTRUCT pt; HDC hdc = BeginPaint(hWnd, &pt); timer.onPrint(hdc); EndPaint(hWnd, &pt); break; } case WM_KEYDOWN: switch(wParam) { case VK_SPACE: case VK_RETURN: timer.onReturn(hWnd,500); break; case VK_LEFT: timer.onLeft(hWnd); break; case VK_RIGHT: timer.onRight (hWnd); break; case VK_DOWN: //timer.onReturn(hWnd); timer.onDown(hWnd); break; case VK_UP: timer.onUp(hWnd); break; } case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_easy: timer.onReturn(hWnd,500); break; case IDR_common: timer.onReturn(hWnd,300); break; case IDC_diff: timer.onReturn(hWnd,200); break; case IDC_VIP: timer.getMax(); break; } } break; case WM_CLOSE: case WM_DESTROY: timer.onClose(hWnd); PostQuitMessage(0); break; }

实现的效果图:
在这里插入图片描述部分最佳记录功能有瑕疵,望包涵!
源码
持续更新C++、数据结构的源码,java SSM项目可关注我的博文,git同步更新源码!


作者:atcain



c+ win32 俄罗斯方块 win

需要 登录 后方可回复, 如果你还没有账号请 注册新账号