我罗斯方块最终篇

作业描述 详情
这个作业属于哪个课程 2020面向对象程序设计
这个作业要求在哪里 我罗斯方块最终篇
这个作业的目标 1.代码的 git 仓库链接。
2.运行截图/运行视频。
3.代码要点。
4.收获与心得.
5.依然存在的问题。
作业正文 如下
小组成员 031902535陈玉娜
031902537江舒颖
031902538李晓芳
项目GitHub地址 https://github.com/dump16/Tetris

运行截图/运行视频

1.启动界面

2.结束界面

3.基础操作.gif

show

4.结束.gif

show

代码要点

Block类:

方块类主要负责设置、操作、判定、绘制方块

1.MoveDown 下落

方块的下落本质上是不断擦除、重绘的过程。
用一个 44 矩阵表示动态方块,左上角的点为基础点,用基础点的行、列坐标确定动态方块在地图上移动的位置。当方块触底后,就将动态方块固定在地图上,产生新的动态方块。
游戏池的设计是 10
22 方格,实际的游戏池地图是 10*26 方格,顶部的四行是隐藏的,只有当方块下落到第五行时,才开始绘制方块。

	setfillcolor(dynamic_color);
	setlinecolor(WHITE);
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (dynamic_shape[i][j] == 1 && row + i >= 4) {
				fillrectangle(map_x + UNIT * (column + j) + 1, map_y + UNIT * (row + i) + 1,
					map_x + UNIT * (column + j + 1) - 1, map_y + UNIT * (row + i + 1) - 1);
			}
		}
	}

2.MoveLeft 左移、MoveRight 右移

改变基础点的行列坐标,擦除、重绘方块,在下落的基础上实现。

3.Rotate 旋转

旋转一次,矩阵顺时针旋转 90°。

	int temp[4][4] = { 0 };
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			temp[i][j] = dynamic_shape[3 - j][i];
		}
	}
	memcpy(dynamic_shape, temp, sizeof(temp));

存在的缺陷是,违背了物理逻辑:旋转路径中不能有障碍物存在,否则,方块是转不动的。

4.DeleteLine 消行、AddLine 增行

将地图矩阵循环赋值,实现整行的消除(增添),然后刷新游戏池。

	for (int i = r; i > 3; i--) {
		for (int j = 0; j < 10; j++) {
			map[i][j] = map[i - 1][j];
		}
	}

5.DrawBlock 绘制

利用 easyx 的 fillrectangle( ) 函数绘制方块。
擦除本质上是背景色方块的重绘,用以覆盖已绘制的方块。

6.View预测

实际上,先有预测方块,后有动态方块。

	srand((unsigned)time(NULL));
	view_type = rand() % 7;

随机产生方块的类型,设置方块的颜色、形状。

	switch (view_type) {
	case 0://	O型
		view_shape[1][1] = view_shape[1][2] = view_shape[2][1] = view_shape[2][2] = 1;
		view_color = BLUE;
		break;
	case 1://	I型
		view_shape[0][1] = view_shape[1][1] = view_shape[2][1] = view_shape[3][1] = 1;
		view_color = RED;
		break;
	case 2://	S型
		view_shape[1][1] = view_shape[1][2] = view_shape[2][0] = view_shape[2][1] = 1;
		view_color = GREEN;
		break;
	case 3://	Z型
		view_shape[1][0] = view_shape[1][1] = view_shape[2][1] = view_shape[2][2] = 1;
		view_color = CYAN;
		break;
	case 4://	L型
		view_shape[0][1] = view_shape[1][1] = view_shape[2][1] = view_shape[2][2] = 1;
		view_color = MAGENTA;
		break;
	case 5://	J型
		view_shape[0][2] = view_shape[1][2] = view_shape[2][1] = view_shape[2][2] = 1;
		view_color = YELLOW;
		break;
	case 6://	T型
		view_shape[1][0] = view_shape[1][1] = view_shape[1][2] = view_shape[2][1] = 1;
		view_color = BROWN;
		break;
	}

当新方块在游戏池中绘制时,在预测框中绘制下一个方块。新方块是将预测方块赋值给动态方块。

Game类:

游戏类控制游戏的开始、暂停、继续、结束、退出

1.HandleInput 处理键盘输入

监听键盘输入

	switch (_getch()) {	//	获取键码

	//	Player A 操作响应
	case 'W':
	case 'w':	block_a.Rotate();		break;
	case 'A':
	case 'a':	block_a.MoveLeft();		break;
	case 'S':
	case 's':	block_a.Sink();			break;
	case 'D':
	case 'd':	block_a.MoveRight();	break;

		//	Player B 操作响应
	case 0:
	case 0xE0:
		switch (_getch()) {
		case 72:	block_b.Rotate();		break;	//	↑
		case 75:	block_b.MoveLeft();		break;	//	←
		case 80:	block_b.Sink();			break;	//	↓
		case 77:	block_b.MoveRight();	break;	//	→
		}
		break;

		//	控制游戏
	case 27:	Quit();					break;	//	Esc 键 退出
	case 32:	system("pause");		break;	//	空格键 暂停
	case 13:	NewGame();				break;	//	回车键 新游戏
	}

2.NewGame 新游戏

串联方块类的逻辑

	while (GameOver() == 0) {	//游戏未结束
		while (1) {//	不触底
			if (_kbhit()) {	//	有按键
				HandleInput();
			}
			else if (block_a.IsBottom()) {
				for (int i = 0; i < block_a.FixBlock(); i++) {
					block_b.AddLine();
				}	//	方块触底,固定方块;若满行,实现己方消行,对方增行
				block_a.NewBlock();
				break;
			}
			else if (block_b.IsBottom()) {
				for (int i = 0; i < block_b.FixBlock(); i++) {
					block_a.AddLine();
				}
				block_b.NewBlock();
				break;
			}
			else {
				block_a.MoveDown();	//	下落
				block_b.MoveDown();
			}
		}
	}

Render类:

渲染类绘制启动、运行、结束界面

收获与心得

在将单人俄罗斯方块转变为双人俄罗斯方块的时候,尝试使用多线程,但遇到诸多问题,例如:颜色冲突,玩家间地图干扰等等。遂放弃多线程的方法,利用游戏类把方块类的逻辑串联起来。许多课本上没接触到的新东西也通过这个的小组合作开始慢慢尝试,体会到了自学能力真的对于个人今后的发展非常重要,还需要时刻保持对于学习的兴趣,比如做一些可以运用所学知识并且自己感兴趣的东西。大家都通过这个合作不断磨合并且发现了自己的优点和缺点。
并且在这次的作业中,让我对“兴趣是最好的老师”这句话感触颇深。在刚开始的时候,对于制作游戏这一事情感到新奇,虽然之前没有做过,感觉可能会很难,但是还是报以极大热情。然而随着时间渐逝,繁重的课业,作业进程推进的缓慢,一次次失败的尝试,都让人觉得沮丧、有很大压力,甚至一度想要放弃。在这种时候,只能靠“完成作业”来作为驱动力,让人觉得很难受。然而,在大家的合作下,看着一点点完成的作业,感觉又有了动力。在其他人持之以恒完成作业、不断学习,想到自己也要努力、不能拖其他人后腿,这时候感觉又有了很大动力,又重新燃起了兴趣。“兴趣是最好的老师”,没有兴趣,只剩下“完成作业"的心态是很难真正做好一件事。

依然存在的问题

1.未实现精确延时
方块落定后,就不能微小移动,无法实现将方块放置到更优位置的功能。
2.方块下落的预测
下落预测能够防止方块沉底出现错格误差,实现这个功能的方法有两个:一是在游戏池中绘制方格线,二是绘制预测下落位置的方块框。
出于美观性的考虑,第一种方法暂未采用,第二种暂未实现。
3.按键冲突
长按任一按键,会导致其他按键的输入出错。
4.玩家交互设计
设想实现玩家输入名称,未实现。
5.界面美观性问题
似乎启动界面比运行界面美观许多(?)
6.游戏体验
卡顿卡顿卡顿卡顿卡顿卡顿卡顿

posted @ 2020-06-13 20:27  尼古拉斯宝莉  阅读(313)  评论(1编辑  收藏  举报