俄罗斯方块(十)处理边界

当俄罗斯方块移动的时候,需要判断边界,来确定是不是可以移动。

判断边界有两个因素要考虑:1)是不是超过Panel边线,包括最大值和最小值。2)是不是有障碍块。

因为Panel边线和障碍块都是Panel的属性,也就是Panel的成员变量,所以,我们可以把确定边界的函数写成Panel的成员函数。

 

bool Panel::isUnavailable(int w, int h)
{
	if (w<0 || h<0) return true;
	if (w>=getWidth() || h >= getHeight()) return true;
	return body[h][w]; 
}

在每次俄罗斯方块移动的时候我们需要做这几件事:1)确立要移动到的位置。2)判断新的位置是否可用。3)如果可用则用新的位置替代旧的位置。

比如在moveDown的时候我们可以这样写

void Element::moveDown()
{
	//确立新的位置
	Box newBody[4];
	for (int i=0; i<4; i++)
	{
		newBody[i].setX(body[i].getX());
		newBody[i].setY(body[i].getY()+1);
	}
	//如果新的位置可用
	if (!ifOccupied(newBody))
	{
		//用新的位置替代旧的位置
		for(int i = 0; i < 4; i++)
			body[i] = newBody[i];
	}
}

 而其中判断位置是否可用,则是把body的几个点都用Panel的isUnavailable进行判断

bool Element::ifOccupied(Box * newBody)
{
	for(int i = 0; i < 4; i++)
	{
		if (myPanel->isUnavailable(newBody[i].getX(), newBody[i].getY()))
			return true;
	}
	return false;
}

 

当然啦,为了使Element类可以调用到Panel的成员函数,Element需要持有Panel的一个指针或引用。

class Element
{
private:
	Panel * myPanel;

 

 那什么时候对这个myPanel赋值呢?既然是Panel构造了Element,那可以在Element的构造函数中获取Panel的指针。

Element(Panel * panel):myPanel(panel){}

 

我们在修改代码的时候,最麻烦的就是修改基类,或者是修改接口。因为基于基类的实现类或者基于接口的实现类都可能需要改变。这里也是一样,一旦Element的构造函数改掉了,那么基于Element的四种形状的构造函数都需要修改。

Bar::Bar(int a,int b, Panel * panel):Element(panel)
{
	...

ShapeL::ShapeL(int a,int b, Panel * panel):Element(panel)
{
	...

ShapeT::ShapeT(int a,int b, Panel * panel):Element(panel)
{
	...

Square::Square(int a,int b, Panel * panel):Element(panel)
{
	...

 好。现在只要在构造这些ELement的时候,把Panel传递进去就可以了

void Panel::randomCreate()
{
	srand(time(NULL));
	int i = rand() % 4;
	if(i == 0)
		element = new Bar(getWidth()/2,0, this);
	if(i == 1)
		element = new Square(getWidth()/2,0, this);
	if(i == 2)
		element = new ShapeL(getWidth()/2,0, this);
	if(i == 3)
		element = new ShapeT(getWidth()/2,0, this);
}

 现在,我们类之间的关系是这样的。(红色是这一章节我们增加的关系)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值