我罗斯方块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);
}
依然存在的问题
-
最重要的一点就是代码类的定义真的很糟糕,玩家类对象的使用也不好,所以解决所有问题的第一步估计应该是把代码做的条理清晰。
-
双人同时按键是另一方不能动,渲染类还在修改。还有一个给对方增行时,如果对方还没触底,会有一点延迟。