用c++写的俄罗斯方块
程序员文章站
2022-03-14 08:33:12
由于刚学完c++,就选了俄罗斯方块当练手项目,完善还算可以,因此特写博客一篇,记录开发过程遇到的问题以及心得,特此分享
虽然感觉实现的不是很完美,但会继续完善,望大佬多多指教...
由于刚学完c++,就选了俄罗斯方块当练手项目,完善还算可以,因此特写博客一篇,记录开发过程遇到的问题以及心得,特此分享
虽然感觉实现的不是很完美,但会继续完善,望大佬多多指教
开发工具:vs2012(旗舰版)
绘图库函数:EasyX_20151015(beta)
缺点: (1)运行效率低 (2)感觉比较繁琐
(3)代码量太大 (4)可以尝试用多线程 (5)j界面比较繁琐,可以试着写用MFC 写(VC++ ) (6)针对于每一种方块的变换问题,我此处的方法比较繁琐,可以搜索资料进行坐标转化进行翻转
声明:写此游戏全部是靠自己思索解决每一个问题,比如,坐标转换,洁面控制,流程控制 ,以及 对于类的继承和多态的使用,虽然比较繁琐,但是这是我思思维的结晶,后会再查些资料看看
别人是如何实现的,应该肯定有更简单的实现方式
(1)头文件
#ifndef _TETRIS_H_ #define _TETRIS_H_ #define ROW 24//行数 #define CLO 14//列数 typedef struct pos//记录点的坐标的数据结构 { int x; int y; }POSITION; class Tetris10//第一种方块的类 { protected : POSITION pos[4]; int flag ; public: virtual void InitTetris();//初始化图形坐标 并且声明为虚函数 virtual void changePos();//当接到转换图形时,使图形旋转九度 并且声明为虚函数 void move();//控制移动 void change();//改变左右和变换图形的形状 bool isGetBottom();//判断是否到达底部 void show();//显示图形 bool IsStop();//是否要停止 void changeArr();//改变整个坐标 bool IsRight();//是否能上右移动 bool IsLeft();//是否能上左移动 void showBlack();//覆盖原来的图形 POSITION getmaxPos();//得到每种图形的y坐标的最大值 }; class Tetris20:public Tetris10//第二种图形 继承第一种 下同 { public: virtual void InitTetris(); virtual void changePos(); }; class Tetris30:public Tetris10 { public: virtual void InitTetris(); virtual void changePos(); }; class Tetris40:public Tetris10 { public: virtual void InitTetris(); virtual void changePos(); }; class Tetris50:public Tetris10 { public: virtual void InitTetris(); virtual void changePos(); }; bool gameover();//判断是否游戏结束 void IsDelete();//当每一行满时,进行删除 #endif
主函数:
/* 作者:品大人 时间:2017 8 10 21:20 项目名称:俄罗斯方块
*/ #include #include #include #include #include #include "tetris.h" using namespace std; int a[ROW][CLO];//数组记录每个位置是否被标记有方块 int main() { int flag = 1; int r; initgraph(280,480); Tetris10* pTetris; int i = 0; while( 1 ) { srand( (unsigned)time( NULL ) ); i = rand() % 5 ;//随机生成不同的方块 switch( i ) { case 0: pTetris = new Tetris10; break; case 1: pTetris = new Tetris20; break; case 2: pTetris = new Tetris30; break; case 3: pTetris = new Tetris40; break; case 4: pTetris = new Tetris50; break; } pTetris->InitTetris();//用虚函数形式基类指针,类型兼容性原则 while( !pTetris->IsStop() )//判断方块是否停止 { pTetris->move(); if( kbhit() )//判断是否用键盘按下密 { pTetris->change();//进行相应的操作 } } pTetris->changeArr();//改变数组的数。目的是记录方块的位置 IsDelete();//进行当每一行满是进行删除 delete pTetris;//删除对象 } getch(); closegraph(); return 0; }(3)对类中成员函数的实现(tetris10.cpp)
#include #include "tetris.h" #include #include using namespace std; #define SPARD 100 extern int a[ROW][CLO]; void Tetris10::InitTetris() { pos[0].x = 140; pos[0].y = -20; pos[1].x = 140; pos[1].y = 0; pos[2].x = 160; pos[2].y = 0; pos[3].x = 160; pos[3].y = 20; flag = 0; } void Tetris10::showBlack() { IMAGE img; for(int i=0; i<4; i++) { loadimage(&img, _T("res//black.JPG")); putimage(pos[i].x,pos[i].y, &img); } } void Tetris10::move() { showBlack(); for(int i=0; i<4; i++) { pos[i].y += 20; } show(); } void Tetris10::show() { IMAGE img; for(int i=0; i<4; i++) { loadimage(&img, _T("res//img.JPG")); putimage(pos[i].x,pos[i].y, &img); } Sleep(SPARD); } bool Tetris10::IsLeft() { int x = 0; for( int i=0; i<4; i++) { if( pos[i].x>=20 && a[(pos[i].y)/20][(pos[i].x-20)/20] != 1 ) { x++; } else { break; } } if( x == 4 ) { return false; } return true ; } bool Tetris10::IsRight() { int x = 0; for( int i=0; i<4; i++) { if( pos[i].x<260 && a[(pos[i].y)/20][(pos[i].x+20)/20] != 1 ) { x++; } else { break; } } if( x == 4 ) { return false; } return true ; } void Tetris10::change() { char c = getch(); showBlack(); switch( c ) { case 'a': if( !IsLeft() ) { for( int i=0; i<4; i++) { pos[i].x -= 20; } } show(); break; case 'd': if( !IsRight() ) { for( int i=0; i<4; i++) { pos[i].x += 20; } } show(); break; case 'w': { changePos(); } break; case ' ': getch(); show(); break; } } void Tetris10::changePos() { flag = (flag)%2; switch( flag ) { case 0: { pos[0].x += 0; pos[0].y += 40; pos[1].x += 20; pos[1].y += 20; pos[2].x += 0; pos[2].y += 0; pos[3].x += 20; pos[3].y -= 20; } break; case 1: { pos[0].x += 0; pos[0].y -= 40; pos[1].x -= 20; pos[1].y -= 20; pos[2].x -= 0; pos[2].y -= 0; pos[3].x -= 20; pos[3].y += 20; } break; } flag++; } bool Tetris10::IsStop() { int x = 0; for( int i=0; i<4; i++) { if( pos[i].y<460 && a[(pos[i].y+ 20)/20][(pos[i].x)/20] != 1 ) { x++; } else { break; } } if( x == 4 ) { return false; } return true ; } void Tetris10::changeArr() { for(int i=0;i<4; i++) { a[(pos[i].y)/20][(pos[i].x)/20] = 1; } } POSITION Tetris10 ::getmaxPos() { POSITION max = pos[0]; for(int i=1; i<4; i++) { if( pos[i].y > max.y ) { max = pos[i]; } } return max;; }
(4)其他类的实现
#include #include "tetris.h" using namespace std; void Tetris20::InitTetris() { pos[0].x = 140; pos[0].y = -20; pos[1].x = 140; pos[1].y = 0; pos[2].x = 160; pos[2].y = 0; pos[3].x = 180; pos[3].y = 0; flag = 0; } void Tetris20::changePos() { flag = (flag)%4; POSITION p = getmaxPos(); switch( flag ) { case 0: { pos[0].x = p.x ; pos[0].y = p.y ; pos[1].x = p.x + 20; pos[1].y = p.y; pos[2].x = p.x + 20; pos[2].y = p.y - 20; pos[3].x = p.x + 20; pos[3].y = p.y - 40; } break; case 1: { pos[0].x = p.x + 20 ; pos[0].y = p.y ; pos[1].x = p.x + 20; pos[1].y = p.y - 20; pos[2].x = p.x ; pos[2].y = p.y - 20; pos[3].x = p.x - 20; pos[3].y = p.y - 20; } break; case 2: { pos[0].x = p.x - 20 ; pos[0].y = p.y + 40; pos[1].x =p.x - 20; pos[1].y =p.y + 20; pos[2].x = p.x - 20; pos[2].y = p.y ; pos[3].x = p.x ; pos[3].y = p.y ; } break; case 3: { pos[0].x = p.x; pos[0].y = p.y ; pos[1].x =p.x + 20; pos[1].y =p.y; pos[2].x = p.x + 40; pos[2].y = p.y ; pos[3].x = p.x ; pos[3].y = p.y-20 ; } break; } flag++; } void Tetris30::InitTetris() { pos[0].x = 120; pos[0].y = 0; pos[1].x = 140; pos[1].y = -20; pos[2].x = 160; pos[2].y = 0; pos[3].x = 140; pos[3].y = 0; flag = 0; } void Tetris30::changePos() { flag = (flag)%4; POSITION p = getmaxPos(); switch( flag ) { case 0: { pos[0].x = p.x +20 ; pos[0].y = p.y; pos[1].x = p.x ; pos[1].y = p.y-20; pos[2].x = p.x +20 ; pos[2].y = p.y -20; pos[3].x = p.x+20 ; pos[3].y = p.y-40; } break; case 1: { pos[0].x = p.x ; pos[0].y = p.y ; pos[1].x = p.x; pos[1].y = p.y-20; pos[2].x = p.x-20 ; pos[2].y = p.y - 20; pos[3].x = p.x + 20; pos[3].y = p.y - 20; } break; case 2: { pos[0].x = p.x - 20 ; pos[0].y = p.y; pos[1].x =p.x - 20; pos[1].y =p.y - 20; pos[2].x = p.x; pos[2].y = p.y -20; pos[3].x = p.x-20 ; pos[3].y = p.y-40 ; } break; case 3: { pos[0].x = p.x-20; pos[0].y = p.y -20; pos[1].x =p.x ; pos[1].y =p.y - 20; pos[2].x = p.x ; pos[2].y = p.y -40; pos[3].x = p.x+20 ; pos[3].y = p.y-20 ; } break; } flag++; } void Tetris40::InitTetris() { pos[0].x = 140; pos[0].y =-20; pos[1].x = 160; pos[1].y =-20 ; pos[2].x = 140; pos[2].y = 0; pos[3].x = 160; pos[3].y =0; flag = 0; } void Tetris40::changePos() { } void Tetris50::InitTetris() { pos[0].x = 120; pos[0].y = 0; pos[1].x = 140; pos[1].y = 0; pos[2].x = 160; pos[2].y = 0; pos[3].x = 180; pos[3].y = 0; flag = 0; } void Tetris50::changePos() { flag = (flag)%2; POSITION p = getmaxPos(); switch( flag ) { case 0: { pos[0].x = p.x+20 ; pos[0].y = p.y ; pos[1].x = p.x+20 ; pos[1].y = p.y -20; pos[2].x = p.x+20 ; pos[2].y = p.y -40; pos[3].x = p.x+20 ; pos[3].y = p.y -60; } break; case 1: { pos[0].x = p.x-20 ; pos[0].y = p.y ; pos[1].x = p.x ; pos[1].y = p.y ; pos[2].x = p.x+20 ; pos[2].y = p.y ; pos[3].x = p.x+40 ; pos[3].y = p.y; } break; } flag++; }
(5)其他普通函数实现(myFunction.cpp)
#include #include #include "tetris.h" using namespace std; extern int a[ROW][CLO]; bool isAllRow(int row) { for(int i=0; i0; i--) { for(int j=0; j