? ? ? ? 最近在b站上看一个Unity教学视频,制作开心消消乐。个人感觉视频中的消除方法写得很随意,有点不爽,于是自己新写了个方法。
基本规则:三个或三个以上元素,横着连一起算消除,竖着连一起算消除。
L形和T形也算。
函数返回匹配成功的待消除对象。
????????视频中的消除方法大概意思是:
返回列表 匹配(待匹配元素){
横向检测
如果横向检测成功,加入结果列表
如果横向检测成功,纵向检测
如果纵向成功,加入结果列表
如果结果成立,返回结果列表
//同上
纵向检测
如果纵向检测成功,加入结果列表
如果纵向检测成功,横向检测
如果横向成功,加入结果列表
如果结果成立,返回结果列表
返回空
}
????????但是这样一来,弓字形是探测不到的。感觉跟我想的不太一样,于是我写了包括弓形的方法:
void 匹配 (待匹配元素){
横匹配
对于横匹配的每一个结果{
标记为横匹配过
如果没有纵匹配过{
纵匹配
对于纵匹配的每一个结果{
标记为纵匹配过
如果没有横匹配过{
匹配;
}
}
}
}
}
匹配结果就是横匹配标记列表或者纵匹配标记列表
虽然是递归,但是最后,所有结果元素也只会被匹配两次,所以算法复杂度并不高
具体代码如下(color组件的color相等即为元素相等):
? ? ? ? 原函数:
public List<GamePiece> GetMatch(GamePiece piece, int newX, int newY)
{
if (piece.IsColored())
{
ColorPiece.ColorType color = piece.ColorComponent.Color;
List<GamePiece> horizontalPieces = new List<GamePiece>();
List<GamePiece> verticalPieces = new List<GamePiece>();
List<GamePiece> matchingPieces = new List<GamePiece>();
horizontalPieces.Add(piece);
//First check horizontal
//direction: dir = 0 is left,dir = 1 is right
for(int dir = 0;dir <= 1; dir++)
{
for(int xOffset = 1;xOffset < xDim; xOffset++)
{
int x;
if(dir == 0)
{
x = newX - xOffset;
}
else
{
x = newX + xOffset;
}
if (x < 0 || x >= xDim)
{
break;
}
if(pieces[x,newY].IsColored() && pieces[x,newY].ColorComponent.Color == color)
{
horizontalPieces.Add(pieces[x, newY]);
}
else
{
break;
}
}
}
if(horizontalPieces.Count >= 3)
{
for(int i = 0; i < horizontalPieces.Count; i++)
{
matchingPieces.Add(horizontalPieces[i]);
}
}
if(horizontalPieces.Count >= 3)
{
for(int i = 0; i < horizontalPieces.Count; i++)
{
for(int dir = 0; dir <= 1; dir++)
{
for(int yOffset = 1; yOffset < yDim; yOffset++)
{
int y;
if(dir == 0)
{
y = newY - yOffset;
}
else
{
y = newY + yOffset;
}
if (y < 0 || y >= yDim)
{
break;
}
if(pieces[horizontalPieces[i].X,y].IsColored() && pieces[horizontalPieces[i].X, y].ColorComponent.Color == color)
{
verticalPieces.Add(pieces[horizontalPieces[i].X, y]);
}
else
{
break;
}
}
}
if(verticalPieces.Count < 2)
{
verticalPieces.Clear();
}
else
{
for(int j = 0;j < verticalPieces.Count; j++)
{
matchingPieces.Add(verticalPieces[j]);
}
break;
}
}
}
if(matchingPieces.Count >= 3)
{
return matchingPieces;
}
horizontalPieces.Clear();
verticalPieces.Clear();
verticalPieces.Add(piece);
//then check vertically
for (int dir = 0; dir <= 1; dir++)
{
for (int yOffset = 1; yOffset < yDim; yOffset++)
{
int y;
if (dir == 0)
{
y = newY - yOffset;
}
else
{
y = newY + yOffset;
}
if (y < 0 || y >= yDim)
{
break;
}
if (pieces[newX, y].IsColored() && pieces[newX, y].ColorComponent.Color == color)
{
verticalPieces.Add(pieces[newX, y]);
}
else
{
break;
}
}
}
if (verticalPieces.Count >= 3)
{
for (int i = 0; i < verticalPieces.Count; i++)
{
matchingPieces.Add(verticalPieces[i]);
}
}
if (verticalPieces.Count >= 3)
{
for (int i = 0; i < verticalPieces.Count; i++)
{
for (int dir = 0; dir <= 1; dir++)
{
for (int xOffset = 1; xOffset < xDim; xOffset++)
{
int x;
if (dir == 0)
{
x = newX - xOffset;
}
else
{
x = newX + xOffset;
}
if (x < 0 || x >= xDim)
{
break;
}
if (pieces[x,verticalPieces[i].Y].IsColored() && pieces[x, verticalPieces[i].Y].ColorComponent.Color == color)
{
verticalPieces.Add(pieces[x,verticalPieces[i].Y]);
}
else
{
break;
}
}
}
if (horizontalPieces.Count < 2)
{
horizontalPieces.Clear();
}
else
{
for (int j = 0; j < horizontalPieces.Count; j++)
{
matchingPieces.Add(horizontalPieces[j]);
}
break;
}
}
}
if (matchingPieces.Count >= 3)
{
return matchingPieces;
}
}
return null;
}
????????新函数:
private List<GamePiece> horizonMatched = new List<GamePiece>();
private List<GamePiece> verticalMatched = new List<GamePiece>();
public List<GamePiece> GetMatch2(GamePiece piece,int newX,int newY)
{
if (!piece.IsColored())
{
return null;
}
horizonMatched.Clear();
verticalMatched.Clear();
Matching(piece,newX,newY);
if (horizonMatched.Count < 3)
{
return null;
}
return horizonMatched;
}
private void Matching(GamePiece piece, int newX, int newY)
{
List<GamePiece> hMatching = HorizontalMatching(piece,newX,newY);
foreach(var hM in hMatching)
{
horizonMatched.Add(hM);
if (!verticalMatched.Contains(hM))
{
List<GamePiece> vMatching = VerticalMatching(hM, hM.X, hM.Y);
foreach(var vM in vMatching)
{
verticalMatched.Add(vM);
if (!horizonMatched.Contains(vM))
{
Matching(vM, vM.X, vM.Y);
}
}
}
}
}
private List<GamePiece> HorizontalMatching(GamePiece piece, int newX, int newY)
{
List<GamePiece> horizontalMatching = new List<GamePiece>();
horizontalMatching.Add(piece);
for (int x = newX - 1; x >= 0; x--)
{
if (pieces[x, newY].IsColored() && pieces[x, newY].ColorComponent.Color == piece.ColorComponent.Color)
{
horizontalMatching.Add(pieces[x,newY]);
}
else
{
break;
}
}
for (int x = newX + 1; x < xDim; x++)
{
if (pieces[x, newY].IsColored() && pieces[x, newY].ColorComponent.Color == piece.ColorComponent.Color)
{
horizontalMatching.Add(pieces[x,newY]);
}
else
{
break;
}
}
if (horizontalMatching.Count < 3)
{
horizontalMatching.Clear();
horizontalMatching.Add(piece);
}
return horizontalMatching;
}
private List<GamePiece> VerticalMatching(GamePiece piece, int newX, int newY)
{
List<GamePiece> verticalMatching = new List<GamePiece>();
verticalMatching.Add(piece);
for (int y = newY - 1; y >= 0; y--)
{
if (pieces[newX, y].IsColored() && pieces[newX, y].ColorComponent.Color == piece.ColorComponent.Color)
{
verticalMatching.Add(pieces[newX,y]);
}
else
{
break;
}
}
for (int y = newY + 1; y < yDim; y++)
{
if (pieces[newX, y].IsColored() && pieces[newX, y].ColorComponent.Color == piece.ColorComponent.Color)
{
verticalMatching.Add(pieces[newX,y]);
}
else
{
break;
}
}
if (verticalMatching.Count < 3)
{
verticalMatching.Clear();
verticalMatching.Add(piece);
}
return verticalMatching;
}
完
|