/
*
detect and store the gems that are alike the selected gem
*/
bool GameController::matchDetector(Gem* pSelected)
{
// get the gem that are near the selected gem based on the selected gem movement type
// for example if moved right the movement type is (RightMovment) so the next gem is row,col+1
Gem* pNextSprite = getNextGem(pSelected,pSelected->getGemState());
// array that will store the Gems that are found for each direction array of its own
CCArray * rightGemsToRemove = CCArray::create();
CCArray * leftGemsToRemove = CCArray::create();
CCArray * upperGemsToRemove = CCArray::create();
CCArray * downGemsToRemove = CCArray::create();
if(pNextSprite == NULL)
{
return false;
}
//copy the selected NEXT gem to the selected gem
//so the calculation to find the next gems will be right
pSelected->swap(pNextSprite);
int col = pSelected->getColNum();
int row = pSelected->getRowNum();
/*
its long switch case that on its option doing the same so only the first one commented
*/
switch(pSelected->getGemState())
{
case kMoveRight:
{
// if its right direction i need to run on all the right gems until its NOT the same and stor it
for(int i=pSelected->getColNum()+1;i < maxGemsInCol;i++)
{
std::string nextInnerSpriteId = pUT->setGemId(i,row);
// get the next gem from the container
Gem* pNextInnerSprite = (Gem*)GameSingleTone::getInstance()->getGemsDictionary()->objectForKey(nextInnerSpriteId);
if(pNextInnerSprite == NULL)
{
return false;
}
else
{
// add it to the container
rightGemsToRemove->addObject(pNextInnerSprite);
}
}
break;
}
case kMoveLeft:
{
for(int i=pSelected->getColNum()-1;i < maxGemsInCol;i++)
{
std::string nextInnerSpriteId = pUT->setGemId(i,row);
Gem* pNextInnerSprite = (Gem*)GameSingleTone::getInstance()->getGemsDictionary()->objectForKey(nextInnerSpriteId);
if(pNextInnerSprite == NULL)
{
return false;
}
else
{
leftGemsToRemove->addObject(pNextInnerSprite);
}
}
break;
}
case kMoveUp:
{
for(int i=pSelected->getRowNum()+1;i < maxGemsInRow ;i++)
{
std::string nextInnerSpriteId = pUT->setGemId(col,i);
Gem* pNextInnerSprite = (Gem*)GameSingleTone::getInstance()->getGemsDictionary()->objectForKey(nextInnerSpriteId);
if(pNextInnerSprite == NULL)
{
return false;
}
else
{
upperGemsToRemove->addObject(pNextInnerSprite);
}
}
break;
}
case kMoveDown:
{
for(int i=pSelected->getRowNum()-1;i < maxGemsInRow ;i++)
{
std::string nextInnerSpriteId = pUT->setGemId(col,i);
Gem* pNextInnerSprite = (Gem*)GameSingleTone::getInstance()->getGemsDictionary()->objectForKey(nextInnerSpriteId);
if(pNextInnerSprite == NULL)
{
return false;
}
else
{
downGemsToRemove->addObject(pNextInnerSprite);
}
}
break;
}
}
/*
this function will run on all the arrays and will check which gems needs to be removed from the GRID and all the rest ( fill the grid with new gems and so on .. )
*/
handleGems(downGemsToRemove,upperGemsToRemove,leftGemsToRemove,rightGemsToRemove)
}
答案 0 :(得分:1)
我认为你正在使用的算法绝对没有问题(“在给定的方向上循环宝石,直到你找到一个不同的算法”)。除非游戏板有数百万行或列,否则最多只需几微秒,这是迄今为止最简单的算法。
我不明白的一件事是你积累了四个单独的列表rightGemsToRemove
,leftGemsToRemove
等等。handleGems()
会对每种列表做些不同的事情吗?如果没有,只需使用一个gemsToRemove
列表。
另一个建议:你有四个案例,每个案例包含基本相同的代码。这种重复是产生错误的肥沃土壤:如果你需要对逻辑进行一些改变,很容易忘记在所有四个副本中进行相同的更改,或者意外地做出错误的更改(使用例如复制和粘贴) )。我建议将switch
声明缩减为:
int dx, dy;
switch (switch(pSelected->getGemState())) {
case kMoveRight: dx = 1; dy = 0; break;
case kMoveLeft: dx = -1; dy = 0; break;
case kMoveUp: dx = 0; dy = -1; break;
case kMoveDown: dx = 0; dy = 1; break;
}
之后,您只需编写一个循环,将dx
添加到x
,将dy
添加到y
:
int x = pSelected->getColNum() + dx;
int y = pSelected->getRowNum() + dy;
while (x >= 0 && x < maxGemsInRow && y >= 0 && x < maxGemsInCol) {
std::string nextInnerSpriteId = pUT->setGemId(x, y);
Gem* pNextInnerSprite = (Gem*)GameSingleTone::getInstance()->getGemsDictionary()->objectForKey(nextInnerSpriteId);
if(pNextInnerSprite == NULL) {
return false;
} else {
gemsToRemove->addObject(pNextInnerSprite);
}
x += dx;
y += dy;
}
可以说更好:如果kMoveRight
等都是小整数值,你可以直接从静态数组中查找它们:
static int dxFromMovement[] = { 1, -1, 0, 0 };
static int dyFromMovement[] = { 0, 0, -1, 1 };
dx = dxFromMovement[pSelected->getGemState()];
dy = dyFromMovement[pSelected->getGemState()];
这可能会稍微快一些,但在我看来,它稍微不那么明确,而且速度差异远远低于我的意见,这是不值得的。