欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用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