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

上次我们解决了moveDown的边界处理。这次我们可以依样画葫芦,把moveLeft,moveRight的边界处理都完成。

每次边界处理也同样是3步:1)确定新的位置。2)查看新位置是否可行。3)如果可行,把新的位置替代旧的位置。

void Element::moveLeft()
{
	Box newBody[4];
	for (int i=0; i<4; i++)
	{
		newBody[i].setX(body[i].getX()-1);
		newBody[i].setY(body[i].getY());
	}
	if (!ifOccupied(newBody))
		copyBody(newBody);
}

void Element::moveRight()
{
	Box newBody[4];
	for (int i=0; i<4; i++)
	{
		newBody[i].setX(body[i].getX()+1);
		newBody[i].setY(body[i].getY());
	}
	if (!ifOccupied(newBody))
		copyBody(newBody);
}

 

最后,还要进行边界判断的还有旋转。如果旋转出了边界,或者遇到了障碍块,那得阻止旋转。

和其他不同的是,左移右移,下落是每种方块行为都一致,所以在父类Element中实现。而旋转时不同形状的方块行为不同,所以旋转是在子类中实现的。现在为了加上边界处理,我们不得不在每个子类的旋转实现中都进行修改。比如在Bar的旋转我们修改如下:

void Bar::rotate()
{
	//确定新的位置
	Box newBody[4];
	if(body[0].getX() == body[1].getX())
	{
		newBody[0].setX(body[0].getX() + 2);
		newBody[0].setY(body[0].getY() + 2);
		newBody[1].setX(body[1].getX() + 1);
		newBody[1].setY(body[1].getY() + 1);
		newBody[3].setX(body[3].getX() - 1);
		newBody[3].setY(body[3].getY() - 1);
		newBody[2]=body[2];
	}
	else
	{		
		newBody[0].setX(body[0].getX() - 2);
		newBody[0].setY(body[0].getY() - 2);
		newBody[1].setX(body[1].getX() - 1);
		newBody[1].setY(body[1].getY() - 1);
		newBody[3].setX(body[3].getX() + 1);
		newBody[3].setY(body[3].getY() + 1);
		newBody[2]=body[2];
	}
	//如果新的位置可行
	if (!ifOccupied(newBody))
		//用新的位置代替旧的位置
		copyBody(newBody);
} 

鉴于篇幅,其他几种形状的旋转代码就省略了。

 

到现在为止,我们已经写了很多遍相同代码

	if (!ifOccupied(newBody))
		//用新的位置代替旧的位置
		copyBody(newBody); 

 

虽然只有两行代码,但是出现了那么多次,我们还是可以把他重构成一个单独的函数

bool Element::move(Box * newBody)
{
	bool flag = ifOccupied(newBody);

	if (!flag)
		//用新的位置代替旧的位置
		copyBody(newBody);
	return !flag;
}
 

这样无论在父类的移动或下降函数,或者子类的旋转中,我们只需要关心移动或旋转的规则,然后调用move函数就可以了。

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);
	}
	move(newBody);

}
void Element::moveLeft()
{
	Box newBody[4];
	for (int i=0; i<4; i++)
	{
		newBody[i].setX(body[i].getX()-1);
		newBody[i].setY(body[i].getY());
	}
	move(newBody);

}


void Element::moveRight()
{
	Box newBody[4];
	for (int i=0; i<4; i++)
	{
		newBody[i].setX(body[i].getX()+1);
		newBody[i].setY(body[i].getY());
	}
	move(newBody);

}

 

void Bar::rotate()
{
	Box newBody[4];
	if(body[0].getX() == body[1].getX())
	{
		newBody[0].setX(body[0].getX() + 2);
		newBody[0].setY(body[0].getY() + 2);
		newBody[1].setX(body[1].getX() + 1);
		newBody[1].setY(body[1].getY() + 1);
		newBody[3].setX(body[3].getX() - 1);
		newBody[3].setY(body[3].getY() - 1);
		newBody[2]=body[2];
	}
	else
	{		
		newBody[0].setX(body[0].getX() - 2);
		newBody[0].setY(body[0].getY() - 2);
		newBody[1].setX(body[1].getX() - 1);
		newBody[1].setY(body[1].getY() - 1);
		newBody[3].setX(body[3].getX() + 1);
		newBody[3].setY(body[3].getY() + 1);
		newBody[2]=body[2];
	}
	move(newBody);

}
 

这样我们的边界处理算是圆满完成了。最后还要提醒一句,为了让move函数可以被子类调用,而不被其他类使用,move函数必须声明成protected

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值