我用Flash CS3,actionscript 3.0,在别人的基础上,用代码实现了自己的连连看游戏,比较简单,适合初学者学习,源码下载地址:http://download.csdn.net/detail/dxzysk/9577256。(Flash CS3及以上版本均可打开)
二:部分代码说明
1.初始化界面
通过读取初始化配置xml文件的相关参数,比如行数和列数,向舞台添加水果(影片剪辑)
private function loadXML(e:Event):void
{
allowTypeCount = 98;//总共有98张图片,就是有98个水果可供选择排列到画布
//arrayN = map.getMap(int(Math.random()*3));//记录位置是否为空的矩阵0或1
//arrayN = map.getMap(3);
arrayN = map.getMap(int(Math.random()*4)+10*int(Math.random()*2));
var X:int;
var Y:int;
var N:int;
var sup:Supporter = new Supporter();
var getLoader:URLLoader=e.target as URLLoader;
blockAll = 0;
var i:int;
var j:int;
for(i = 0; i < arrayN.length; i++)
{
for(j = 0; j < arrayN[i].length; j++)
{
if(arrayN[i][j])
blockAll++;
}
}
trace("blockAll",blockAll);//显示排列水果个数
i = 0;
j = 0;
if(getLoader!=null)
{
var myXML:XML;
myXML=new XML(getLoader.data);
X = sup.fStringToInt(myXML.bx);
Y = sup.fStringToInt(myXML.by);
NumX = sup.fStringToInt(myXML.numx);
NumY = sup.fStringToInt(myXML.numy);
N = sup.fStringToInt(myXML.N);
}
//blockArray = new Array(NumX);
blockArray = new Array(NumY); // 记录水果位置横纵坐标(有遮挡单元格)
var t:int = 0;
var p:int = 0;
var s:int = blockAll;
checkQueue = new Array(NumX * NumY);
for(; t < NumX * NumY; t++)
{
checkQueue[t] = new Array(3);
checkQueue[t][0] = 0;
checkQueue[t][1] = 0;
checkQueue[t][2] = 0;
}
t = 0;
p = 0;
var numArray:Array = new Array(allowTypeCount);//水果种类序号集合
var numN:int = allowTypeCount;
for(t = 0; t < allowTypeCount; t++)
{
numArray[t] = t + 1;
}
//var typeNum:int = 20 + int(Math.random()*21);//水果种类个数
var typeNum:int = 10 + int(Math.random()*11);//水果种类个数
if (blockAll < typeNum*2)//二者数目有冲突,应该取最小值
{
//typeNum = blockAll/2 -3;
typeNum = int(blockAll/3);
}
var typeArray:Array = new Array(typeNum);//存放水果种类序号及个数
p = int(Math.random()*allowTypeCount);//数组的序号,随机从中间开始往后再回头遍历,循环遍历
for(t = 0; t < typeNum; t++)
{
typeArray[t] = new Array(2);
typeArray[t][0] = numArray[p];//该种类对应的水果种类序号
typeArray[t][1] = 2;//该种类的个数
numArray[p] = -1;
p++;
p = p%typeNum;//更简单容易,重复的多
//p = p%allowTypeCount;//游戏更难,重复的少
}
s = blockAll - typeNum*2;//剩余需要的排列的block位置数目
p = 0;
while(s)//数组的序号,随机从中间开始往后再回头遍历,循环遍历,直到block枚举完
{
typeArray[p][1] += 2;//与其相同的再加两个,变成4个或6个
p++;
p = p%typeNum;
s -= 2;
}
var bN:int = 0;
for(p = 0; p < NumY; p++)
{
blockArray[p] = new Array(NumX);
for(t = NumX - 1; t > -1; t--)
{
if(arrayN[p][t] != 0)//该位置不空(p,t)
{
bN = int(Math.random()*typeNum);
while(!typeArray[bN][1])//找到一个记录种类数组个数typeArray[bN][1]不为0的
{
bN = int(Math.random()*typeNum);
}
typeArray[bN][1] --;//添加了一个就少一个
blockArray[p][t] = new lianGameBlock(t,p,typeArray[bN][0]);//
arrayN[p][t] = typeArray[bN][0];//arrayN原来是记录0或1,及是否空白,现在记录为自然数,0:空白,非0:水果序号
addChild(blockArray[p][t]);
}
else
{
blockArray[p][t] = new lianGameBlock(t,p,0);//添加空的MovieClip,且设置不可见
blockArray[p][t].Block.visible = false;
addChild(blockArray[p][t]);
}
}
}
sup = null;
init();
}
private function init()
{
socer = 0;
choiceAX = -1;
choiceAY = -1;
choiceBX = -1;
choiceBY = -1;
checkCase = true;
checkOn = false;
blocks = blockAll;
if(NumX > NumY)
{
fLine = new Array(NumX*2 + NumY);
fLink1 = new Array(NumX*2 + NumY);
fLink2 = new Array(NumX*2 + NumY);
for(var p:int = 0; p < (NumX*2 + NumY); p++)
{
fLine[p] = new lianxian();
fLine[p].shu.visible = false;
fLine[p].heng.visible = false;
addChild(fLine[p]);
//fLink1[p] = new Tween(fLine[p],"alpha",null,0,1,8,false);
fLink1[p] = new Tween(fLine[p],"alpha",null,0,1,12,false);//画线,利用Tween播放实现淡入淡出效果
//fLink2[p] = new Tween(fLine[p],"alpha",null,1,0,8,false);
fLink2[p] = new Tween(fLine[p],"alpha",null,1,0,12,false);
}
}
else
{
fLine = new Array(NumY*2 + NumX);
fLink1 = new Array(NumY*2 + NumX);
fLink2 = new Array(NumY*2 + NumX);
for(var q:int = 0; q < (NumY*2 + NumX); q++)
{
fLine[q] = new lianxian();
fLine[q].shu.visible = false;
fLine[q].heng.visible = false;
addChild(fLine[q]);
//fLink1[q] = new Tween(fLine[q],"alpha",null,0,1,8,false);
//fLink2[q] = new Tween(fLine[q],"alpha",null,1,0,8,false);
fLink1[q] = new Tween(fLine[q],"alpha",null,0,1,12,false);
fLink2[q] = new Tween(fLine[q],"alpha",null,1,0,12,false);
}
}
}
2.点击两个同样的水果,消去
消去的连线不能超过两个拐点,相关算法看看其他文章的说明,类似迷宫寻路
//两者之间检查连线是否有遮挡,以便消去,如果成功Road=true表示通的,迷宫寻路
private function Check(nowX:int,nowY:int,pNum:int,lastD:int,nextD:int):int
{
if(Road)
return 0;
if(pNum == -1)
{
bx = choiceAX;
by = choiceAY;
ex = choiceBX;
ey = choiceBY;
nowX = bx;
nowY = by;
pNum = 0;
}
else if(pNum == -2)
{
nowX = bx;
nowY = by;
pNum = 0;
}
else
{
if((lastD + nextD) == 0)
return 0;
switch(nextD)
{
case 1:
{
nowY++;
break;
}
case -1:
{
nowY--;
break;
}
case 2:
{
nowX++;
break;
}
case -2:
{
nowX--;
break;
}
}
if(nowX > (NumX - 1) || nowX < 0 || nowY > (NumY - 1) || nowY < 0) //出界
{
return 0;
}
if(lastD != nextD && lastD) //遇折点
{
pNum++;
if(pNum > 2)
return 0;
}
if(nowX == ex && nowY == ey)
{
Road = true;
RoadX = ex;
RoadY = ey;
RoadN = 0;
return nextD;//找到了退出上一级回调结束会画线
}
if(nowX > -1 && nowX < NumX && nowY > -1 && nowY < NumY ) //遇障碍
{
if(arrayN[nowY][nowX] != 0)
{
return 0;
}
}
}
if(!Road)
Check(nowX,nowY,pNum,nextD,1);//向下寻找通路
if(!Road)
Check(nowX,nowY,pNum,nextD,-1);//向上寻找通路
if(!Road)
Check(nowX,nowY,pNum,nextD,2);//向右寻找通路
if(!Road)
Check(nowX,nowY,pNum,nextD,-2);//向左寻找通路
if(Road)//表示通的
{
if(checkOn == false)
{
if(nowX == RoadX)//画竖线
{
fLine[RoadN].heng.visible = false;
fLine[RoadN].shu.visible = true;
fLine[RoadN].x = nowX*37 + 37/2 + 2;
if(RoadY > nowY)
{
fLine[RoadN].y = nowY*42 + 42/2;//计算竖线线段坐标,在该格子的中心,42表示格子的高度(nowY表示纵向的格子数)
}
else
{
fLine[RoadN].y = RoadY*42 + 42/2;
}
}
else
{
fLine[RoadN].shu.visible = false;
fLine[RoadN].heng.visible = true;
fLine[RoadN].y = RoadY*42 + 42/2;
if(RoadX > nowX)//计算横线线段坐标,在该格子的中心,42表示格子的高度
{
fLine[RoadN].x = nowX*37 + 37/2 + 2;//计算横线线段坐标,在该格子的中心,42表示格子的高度
}
else
{
fLine[RoadN].x = RoadX*37 + 37/2 + 2;
}
}
//fLink1[RoadN].start();
fLink2[RoadN].start();
}
RoadN ++;
RoadX = nowX; //RoadX是上一个点,nowX是当前点,水平或垂直相邻的点
RoadY = nowY;
}
return 1000;
}