• 我罗斯方块最终篇


    作业描述 详情
    这个作业属于哪个课程 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.游戏体验
    卡顿卡顿卡顿卡顿卡顿卡顿卡顿

  • 相关阅读:
    windows下搭建hadoopproject(一)
    inspect模块---检查活动对象
    Python的datetime模块分析
    深入理解python之self
    request payload
    计算机基础知识
    pycharm常用快捷键
    英语学习五大法则
    基础语法
    英语基本语法
  • 原文地址:https://www.cnblogs.com/ponynice/p/13118783.html
Copyright © 2020-2023  润新知