Lucky_tree

黄昏开始书写,黎明是无数扉页

我罗斯方块3

这个作业属于哪个课程 2020面向对象程序设计
这个作业要求在哪里 我罗斯方块最终篇
这个作业的目标 汇报自己这个阶段的开发进度。
作业正文 我罗斯方块3
项目地址 github
小组成员 031902344赵睿言
031902334董晓鸥
031902341邵明杰

碎碎念

代码质量真的是差差差!!!还在完善,运行还有问题 从一开始准备做这个的时候就很分不清楚每个类的分工,虽然后面大致做出来了,但是代码问题很大,玩家类和方块类都是不清不楚的,也没能分离出源文件,整个代码特别是玩家类就显得比较混乱。 除此之外,真的是思索半天方块的设计这里,也没能按照最初设计明确分工渲染类、地图类、方块类、玩家类,如果使用继承派生的方式定义每个方块,我就弄不好了(好像就有些违背了用c++做它的意义)

代码就没有上传到github(太惨不忍睹了T^T),后面我还会尽量继续完善。

界面效果

虽然展示出来了,但是有点问题……


视频在这里

给对方增行有问题)视频链接

收获与心得

能完成这个作业因为是站在巨人的肩膀上,网上有很多的单人版教程,以及easyx的渲染方法。 刚开始的时候手足无措,做的时候思路一点点清晰,首先要有界面(与数组x/y轴方向相反),没界面怎么做,然后要有方块,有了方块还要可以运动,自己可以下落,上下左右,运动时候还要检测,运动完了界面要更新,更新时候怎么传数据,这样一步步就做成了单人的。
双人版开始以为是两个单人版凑到一起,定义两个玩家对象,可是这么写完以后问题出来了,首先我要如何把玩家的两个对象写进去。。。虽然基本可以双人玩了但是我们的游戏还是残缺的(在消行那里,功能不完整)。做法依然是两个人的拼到一起,然后规定两人交替,中间有时间差但是程序运行较快看不太出来。 学习了一下定时器,真是做的时候被定时器弄得没脾气,操作的时候体验感也比较差劲。。。。。。。
简单的easyx功能,渲染的时候基础界面可以,还学会渲染自己设置rgb渐变色哈哈哈哈,但是后面继续研究的时候发现界面更新的时候好多问题,而且用floodfill函数一个格子一个格子渲染时,原理没弄明白经常渲染的整个界面一个色。。。。最后还是网上教程解救了我们,借鉴大佬的方法\^o^/,还插入了背景音乐哈哈哈哈!

代码要点

方块的设计,这个被我们掐死了好几种方案,比如四方格记录左上角位置,每个类型存到一个思维数组里,全部存全部编号方便后面旋转 后来我们终于找到了一个很好地方法,每个方块占四个格子,格子坐标假设如图,每次记录原点(0,0)位置(左下角),记录四个格子的坐标 七种方块,每个方块最对四个方向四个坐标,每个坐标两个数字,建立一个三维数组。

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 }, //  | 型
{ 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 } ,      //  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 型(反)
{ 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 型
{ 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 型(反)
{ 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 },        // 田 型
{ 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 }    // 山 型
	
	};

键盘事件

bool Block::getCmd()
{

		// 接受指令
		
		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;
}

碰撞检测

bool Block::checkPut(int mp_x, int mp_y, int dir_idx)//如果移动左下角位置,与形状
{
	int xad[4];//记录对应x/y格子位置
	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];
	}

	// 左右越界、下方越界、重复占格、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;
}

消行增行

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;
		//检查多少行满
		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];
		}
}

每次下落界面更新

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];
		}
}

开始初始化

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);
}

依然存在的问题

  • 最重要的一点就是代码类的定义真的很糟糕,玩家类对象的使用也不好,所以解决所有问题的第一步估计应该是把代码做的条理清晰。

  • 双人同时按键是另一方不能动,渲染类还在修改。还有一个给对方增行时,如果对方还没触底,会有一点延迟。


posted @ 2020-06-10 18:07  Luckyy_tree  阅读(315)  评论(4编辑  收藏  举报