我罗斯方块2

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

设计方向改变

  • 经过第一步学习后发现,qt渲染已经超出我们现有的学习能力,小组成员经商讨决定选择EasyX函数实现页面的绘制。T^T。
  • 进度较慢,第一步完成基础方块类。在编写的过程中发现第一次初步设计的初稿有很多地方不合理,这一次在慢慢实现函数的功能时,我们也做了很大的修改。
  • 后续进行其他类的完成。

我们的方块类

class blockData
{
    int data[4][4];//代表每种方块的每个方向的四宫格地图,block类的分支
};

class Block
{
private:
    int num;  // 每个方块可以有几个方向会使地图不同
    blockData blockdata[4]; // 4个方向地图
public:
	int posX,posY;//方块左上角位置
	int boardGround[][];//这里未设计好如何与初步设计的Board类衔接
	void InitBlocks();//初始化方块地图
	void DrawBlock(Block &block, int posX, int posY);//渲染
	void CheckKeyboard(Block &block);//监听键盘事件并控制移动
	void CreateNewBlock();//随机创建方块
	bool detectNewTurn(Block &block);//碰撞检测是否显示新方块
};

坐标位置方便我们思考与数学平面直角坐标系一致,只不过y轴方向向下。

具体函数设计

成员1号

负责各类方块的地图设计、成员一起查阅资料完成渲染

1.构建方块:每个方块都可以由一个二维数组来存储,根据构建的五种方块可知,用4*4的数组即可存放每个方块所有方向的数据。方块占用的位置用1表示,未占用的位置则用0表示。以下为所有方块类型的不同方向的方块地图,全部列出。

void InitBlocks()
{
    
    block[0].blockdata[0] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        1, 1, 0, 0,
        0, 1, 1, 0,
    };
    block[0].blockdata[1] =
    {
        0, 0, 0, 0,
        0, 1, 0, 0,
        1, 1, 0, 0,
        1, 0, 0, 0,
    };
    block[0].num = 2;

    block[1].blockdata[0] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0,
        1, 1, 1, 1,

    };
    block[1].blockdata[1] =
    {
        0, 1, 0, 0,
        0, 1, 0, 0,
        0, 1, 0, 0,
        0, 1, 0, 0,
    };
    block[1].num = 2;

    block[2].blockdata[0] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 1, 1, 0,
        1, 1, 0, 0,
    };

    block[2].blockdata[1] =
    {
        0, 0, 0, 0,
        1, 0, 0, 0,
        1, 1, 0, 0,
        0, 1, 0, 0,
    };
    block[2].num = 2;

    block[3].blockdata[0] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 1, 1, 0,
        0, 1, 1, 0,
    };
    block[3].num = 1;

    block[4].blockdata[0] =
    {
        0, 0, 0, 0,
        1, 1, 0, 0,
        0, 1, 0, 0,
        0, 1, 0, 0,
    };
    block[4].blockdata[1] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 1, 0,
        1, 1, 1, 0,
    };
    block[4].blockdata[2] =
    {
        0, 0, 0, 0,
        1, 0, 0, 0,
        1, 0, 0, 0,
        1, 1, 0, 0,
    };
    block[4].blockdata[3] =
    {
        0, 0, 0, 0,
        0, 0, 0, 0,
        1, 1, 1, 0,
        1, 0, 0, 0,
    };
    block[4].num = 4;
} 

经过上网查阅资料。进行渲染,一个格子一个格子,每个宽度设为30,使用setfillcolor函数和fillrectangle填充。

void DrawBlock(Block &block, int posX, int posY)
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j <4; j++)
        {
            blockData &typeData = block.blockdata[typed];
            if (typeData.data[j][i] == 0)
            {
                continue;  // 方块4*4数组中数据为0的位置忽略
            }
            setfillcolor(BLUE);
            int x = (i + posX) *30;
            int y = (j + posY) *30;
            fillrectangle(x, y, x+30, y+30);
        }
    }
}

成员2号

负责方块的移动与键盘监听事件
每当键盘按下一个按键,就进行判断方块是否可以移动,这里的按键监听为参考网上教程为初步为上下左右,wasd并未设置,
这一步比较糊里糊涂,还是有些不明白判断按键是否按下函数

// 判断按键是否按下
bool isKeyDown(int key)
{
    return (GetAsyncKeyState(key) && 0x8000 );
}

// 控制方块移动
void CheckKeyboard(Block &block)
{
        if (isKeyDown(VK_LEFT))
        {
            if (canMove( block, posX - 1, posY,typed))
            {
                posX -= 1;
            }
        }
        else if (isKeyDown(VK_RIGHT))
        {
            if (canMove(block, posX + 1, posY,typed))
            {
                posX += 1;
            }

        }
        else if (isKeyDown(VK_DOWN))
        {
            if (canMove(block, posX, posY + 1,typed))
            {
                posY += 1;
            }

        }
        else if (isKeyDown(VK_UP))
        {
            typed++;
            typed %= block.dirctionCount;//具体是哪一个方向
        }
}

每一次移动都要进行判断方块是否可以移动,是否碰壁,地图位置是否已有方块。

bool canMove(Block &block, int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            blockData &typeData = block.blockdata[typed];
            if (typeData.data[j][i] == 0)
            {
                continue;
            }
            if (i + x < 0)
            {
                 return false;
            }
            if (i + x >= 10)
            {
                return false;
            }
            if (j + y >= 20)
            {
                return false;
            }
            if (backGround[j + y][i + x] == 1)
            {
                return false;
            }
        }
    }
    return true;
}

成员3号

随机创建方块: 借助rand()函数随机取数,来达到抽取所有方块中随机一个的目的。同时自定义方块的初始坐标;
void CreateNewBlock()
{
    index = rand() % _countof(block);    // 随机抽取方块
    posX = 4;   // 定义方块初始值坐标
    posY = 0;
}

判断是否进入新一轮:
首先定义下一行,且设置进入下一轮参数为假。用循环得到16格大方块需要判断临界值时的坐标,忽略16格方块中为0的部分(即非显示方块部分),判断格子界面下一行如果不是空的或者方块降到底部(方块高度与下一行的和超过页面总高),就进入下一轮

bool detectNewTurn(Block &block)
{
    int tmpY = posY + 1;
    //tmpy表示下一行,方块不能移动到下一行则进入下一轮
    bool restart = false;
    //初始状态进入下一行为假
    for (int p = 0; p < 4; p++)
    {
        for (int q = 0; q < 4; q++)
        {
            if (q + tmpY < 0)
            {
                continue;
            }
blockData &typeData = block.blockData[typed];
//得到4*4方块即将触底时的坐标
            if (typeData.data[j][i] == 0)
            {
                continue; // 方块4*4数组中数据为0的位置忽略
            }
            if (backGround[j + tmpY][i + posX] == 1)
            {
                restart = true;
                //游戏地图界面下一行如果不是空的,就进入下一轮
            }
            if (j + tmpY >= 20)
             {
                restart = true;// 方块降到底部进入下一轮
            }
        }
    }
    return restart;
}

回顾

目前我们还是有些困顿于每个类的具体分工,以及后续类完成后如何使得各个类相互连贯,感觉很头痛。

渲染后的方块

猜你喜欢

转载自www.cnblogs.com/qiaozhi8/p/12939886.html
今日推荐