I rose cube 3

Keywords: github Programming

Which course does this assignment belong to 2020 object oriented programming
Where are the requirements for this assignment My Rose Square final
The goal of this job Report the development progress of this stage.
Job body I rose cube 3
Project address github
Team members 031902344 Zhao Ruiyan
031902334 Dong Xiaoou
031902341 Shao Mingjie

Fragmentary thoughts

Code quality is really poor!!! From the beginning, when preparing to do this, it was very unclear about the division of labor of each class. Although it was roughly done later, the code problem was very large. The player class and the block class were not clear, and the source file could not be separated. The whole code, especially the player class, was quite confused. In addition, I really think about the design of half a day's Square. Here, I didn't make clear the division of rendering class, map class, square class and player class according to the original design. If I use inheritance and derivation to define each square, I can't make it (it seems that it violates the meaning of using c + + to do it). The definition of player class is really endless......

The code hasn't been uploaded to github (too bad to see T^T). I will try my best to improve it later.

Interface effect

Although it is shown, there are some problems

The video links show the beautiful side. The problems mentioned later are not shown (especially the problem of adding new lines to each other). The blog Park cannot be uploaded and published in Youku directly Video link

Harvest and experience

I can finish this job because I stand on the shoulders of giants. There are many single version tutorials on the Internet, and easyx rendering method. At the beginning, I was at a loss. When I was doing this, I had to have an interface (opposite to the x/y axis of the array). I didn't have an interface to do it. Then I had to have a box. When I had a box, I had to be able to move. I could fall down, up, down, left and right. When I was moving, I had to detect it. When I finished moving, I had to update the interface and how to transmit data when I was updating, so I could do it step by step It's single.
At first, the double version thought that it was two single versions coming together to define two players' objects. But after that, the problem came out. First, how do I write in the two players' objects? Then when I press the key, I can't move the two together.... I haven't solved the problem completely yet.. Although it can be played by two people basically, there is still some delay when pressing the key (because it is changed to one person pressing the key and another person is not allowed to move, hee hee hee hee hee). At last, we have to solve the problem of eliminating one line by oneself and adding another line by the other. This has a big problem that we haven't completely solved yet.... After learning about timer, I really lost my temper when I was doing it, and I had a poor sense of experience when I was operating it.......
Simple easyx function, the basic interface can be used when rendering, and you can also learn to render your own rgb gradient ha ha ha ha, but when you continue to study later, you will find many problems when the interface is updated. Moreover, when you use the floodfill function to render from one grid to another, you don't understand the principle of one color of the whole interface that is often rendered.... In the end, we were saved by online tutorials. We borrowed from the big guy's method \ ^ o ^ /, and inserted background music!

Code points

For the design of blocks, we have strangled several schemes. For example, the square lattice records the position of the upper left corner, and each type is stored in a thinking array, all of which are stored with all numbers for later rotation Later, we finally found a good method. Each square occupies four grids. The grid coordinate assumption is as shown in the figure. Each time, record the origin (0, 0) position (lower left corner), record the coordinates of four grids and seven kinds of squares. Each square has four coordinates in the most four directions, two numbers in each coordinate, and establish a three-dimensional array.

struct blockdata
{
	int dir[4][4][2];
};

blockdata blocks[7] ={
{ 0, -3, 0, -2, 0, -1, 0, 0, 0, -3, 1, -3, 2, -3, 3, -3, 0, -3, 0, -2, 0, -1, 0, 0, 0, -3, 1, -3, 2, -3, 3, -3 }, //  |Type
{ 0, 0, 1, -1, 1, 0, 2, -1, 1, -2, 1, -1, 2, -1, 2, 0, 0, 0, 1, -1, 1, 0, 2, -1, 1, -2, 1, -1, 2, -1, 2, 0 } ,      //  Type Z
{ 0, -1, 1, -1, 1, 0, 2, 0, 0, -1, 0, 0, 1, -2, 1, -1, 0, -1, 1, -1, 1, 0, 2, 0, 0, -1, 0, 0, 1, -2, 1, -1 } ,   //  Z type (reverse)
{ 0, -2, 0, -1, 0, 0, 1, 0, 0, -1, 1, -1, 2, -1, 0, 0, 0, -2, 1, -2, 1, -1, 1, 0, 0, 0, 1, 0, 2, 0, 2, -1 },       //  L type
{ 0, 0, 1, 0, 1, -1, 1, -2, 0, -1, 0, 0, 1, 0, 2, 0, 0, -2, 0, -1, 0, 0, 1, -2, 0, -1, 1, -1, 2, -1, 2, 0 },       //  L type (reverse)
{ 0, -1, 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 1, -1, 1, 0, 0, -1, 0, 0, 1, -1, 1, 0 },        // Field type
{ 0, 0, 1, -1, 1, 0, 2, 0, 1, -2, 1, -1, 1, 0, 2, -1, 0, -1, 1, -1, 1, 0, 2, -1, 0, -1, 1, -2, 1, -1, 1, 0 }    // Mountain type
	
	};

Keyboard events

bool Block::getCmd()
{

		// Accept instructions
		
		if (isKeyDown(VK_LEFT))
		{
			moveLeft();
			return true;
		}
		else if (isKeyDown(VK_RIGHT))
		{
			moveRight();
			return true;
		}  
		else if (isKeyDown(VK_DOWN))
		{
			Sleep(100);
			moveDown();
			return true;
		}
		else if (isKeyDown(VK_UP))
		{
			moveRotate();
			Sleep(300);
			return true;
		}
		Sleep(20);
		return false;
}

collision detection

bool Block::checkPut(int mp_x, int mp_y, int dir_idx)//If you move the lower left corner position, and the shape
{
	int xad[4];//Record the corresponding x/y grid position
	int yad[4];
	for (int i = 0; i < 4; ++i)
	{
		xad[i] = mp_x + squares[nowtype].dir[dir_idx][i][0];
		yad[i] = mp_y + squares[nowtype].dir[dir_idx][i][1];
	}

	// No problem when left and right cross boundary, lower cross boundary, repeated space occupying, y < 0
	for (int i = 0; i < 4; ++i)
	{
		if (xad[i] < morew + 0 || xad[i] > morew + 9 || yad[i] >= 15)
			return false;
		if (yad[i] < 0) 
			continue;
		if (mp[xad[i]][yad[i]])
			return false;
	}
	return true;
}

Cancel and add lines

void Block::addclear()
{
	int a =clear;
	while (a > 0)
	{
		for (int i = obj2.morew + 0; i < obj2.morew + 10; ++i)
		{
			for (int j = 0; j < 14; ++j)
			{
				if (obj2.mp[i][j + 1] && !obj2.mp[i][j])
				{
					obj2.mp[i][j] = 1;
					obj2.mp_c[i][j] = BLACK;
					break;
				}
			}
		}
		a--;
	}
	clear = 0;
}
void Block::exeClear()
{
	memset(mp_tmp, 0, sizeof(mp_tmp));
	memset(mp_c_tmp, 0, sizeof(mp_c_tmp));
	clear = 0;
	int cnt_j = 14;
	for (int j = 14; j >= 0; --j)
	{
		int cnt = 0;
		for (int i = morew + 0; i < morew + 10; ++i)
			if (mp[i][j])
				++cnt;
		//Check how many lines are full
		if (cnt != 10)
		{
			for (int i = morew + 0; i < morew + 10; ++i)
			{
				mp_tmp[i][cnt_j] = mp[i][j];
				mp_c_tmp[i][cnt_j] = mp_c[i][j];
			}
			--cnt_j;
		}
		else
		{
			++score;
			clear++;
		}
			
	}

	for (int j = 0; j < 15; ++j)
		for (int i = morew + 0; i < morew + 10; ++i)
		{
			mp[i][j] = mp_tmp[i][j];
			mp_c[i][j] = mp_c_tmp[i][j];
		}
}

Every drop interface update

void Block::recordSquareNow()
{
	int xad[4];
	int yad[4];
	for (int i = 0; i < 4; ++i)
	{
		xad[i] = now_mp_x + blocks[nowtype].dir[nowshape][i][0];
		yad[i] = now_mp_y + blocks[nowtype].dir[nowshape][i][1];
	}
	for (int i = 0; i < 4; ++i)
		if (yad[i] >= 0)
		{
			mp[xad[i]][yad[i]] = 1;
			mp_c[xad[i]][yad[i]] = colors[nowcolor];
		}
}

Start initialization

void Block::initDatasPerSquare()
{
	now_mp_x = morew+5;
	now_mp_y = -1;
	flag_next = 0;

	nowcolor = nextcolor;
	nowtype = nexttype;
	nowshape = nextshape;

	nextcolor = rand() % 7;
	nexttype = rand() % 7;
	nextshape = rand() % 4;
}

void Block::drawBG()
{
	COLORREF tmp = getlinecolor();
	for (int i = 0; i < 541; ++i)
	{
		setlinecolor(RGB(135, 140, 210 - i / 10));
		line(612+0, i, 612 + 360, i);

		setlinecolor(RGB(135, 140, 210 - i / 10));
		line(253 + 0, 540-i, 253 + 360, 540-i);
	}
	setlinecolor(tmp);
}

Main function

int main()
{
	
	obj2.morew =7;
	obj1.morew = 17;
	obj1.initboard();
	
	// Start the game
	mciSendString(TEXT("open bgm.mp3 alias music"), 0, 0, 0);
	//open operation mode, alias -- defines the alias of the music file as music
	mciSendString(TEXT("play music repeat"), 0, 0, 0);

		while (!obj1.flag_over&& !obj2.flag_over)
		{
			obj1.initDatasPerSquare();
			obj2.initDatasPerSquare();
			while (!obj1.flag_next|| !obj2.flag_next)
			{
				BeginBatchDraw();
				obj1.drawGameBG();
				obj1.drawSide();
				obj1.drawMap();
				obj1.drawSquareNow();
				EndBatchDraw();

				BeginBatchDraw();
				obj2.drawSide();
				obj2.drawMap();
				obj2.drawSquareNow();
				EndBatchDraw();
				
				if (obj1.getCmd())
				{
				}
				else if (obj2.getCmd())
				{
				}
				else
				{
					obj1.timers();
					obj2.timers();
				}
				
				
				if (obj1.flag_next)
				{
					
					obj2.addclear();
				
				}
				if (obj2.flag_next)
				{

					obj1.addclear();
				}
					
			}
			
		
		}
		
	return 0;
}

Problems still exist

  • The most important point is that the definition of my code class is really poor, and the use of player class objects is not good, so the first step to solve all problems should be to make the code clear.

  • I think all of these problems may be because we all complete everything in one cpp. Cause two people at the same time is the other side can't move, some online say two threads.. But I haven't read it for a long time.... When adding lines to the other party, we must first touch the bottom of the other party, and then we can cancel adding lines to the other party. If the appearance order is wrong, it will not work. The same problem as the key still needs to be solved. In addition, when each square falls, when one person touches the bottom, he can not create a new square until another person also touches the bottom...

Posted by powergen on Wed, 10 Jun 2020 19:17:36 -0700