对对碰游戏,相信大家也并陌生了.游戏规则也很简单,就是随意转换地图中的相邻的两个图案,只要转换后,能够使得某一种图形在横排或竖排相邻并且个数超过三个,即可消除这几个图形.不过今天研究的不是怎样玩游戏,而是如何来写游戏.先试玩一下就游戏先吧 点击试玩 源码下载
根据流程,我们就可以一步一步的来完成游戏的编写了.在连连看设计思路与源码那里我已经介绍了一些基本的前期工作,例如,生成地图,显示,还有地图的一些操作如洗牌等的一些讲解,所以这里就略过了介绍,主要讲一下几个主要算法.
第一个,就是遍历整个地图,寻找符合消除条件的所有方块.
由于消除条件是有横排跟竖排之分,所以我们也必须对这两种情形,进行检测.
首先判断相连的三个图形(例如第1,2,3个)是否相同,不是则右移一位再判断另三个图形(此时应是第2,.3,4个)是否相同,如果第1,2,3 个图形相同,则继续尝试判断第4个,第5个....是否也相同,直到找到不相同的为止.然后下次另找一对进行比较时就不用再从2,3,4开始了,而是从可消除的方块之后开始判断了,如前次1,2,3,4,5图形相同,则本次判断就从,6,7,8三个开始判断,再判断成功后,我们用一个数组cancelArray来存放这些可消除的方块的位置,..然后一直遍历整个地图..以下是该算法的代码:
//检测地图中的可消除元素并存于数组cancelArray里面.
public function findCancel():Boolean{
var i:uint;
var j:uint;
var result:Boolean = false;
cancelArray = new Array();
//先测试横行是否可以消除
for(i=0;i<Map.ROWS;i++){
for(j=0;j<Map.COLS-2;j++){
if(mapArray[i][j]==mapArray[i][j+1] && mapArray[i][j] == mapArray[i][j+2]){
result = true;
cancelArray.push(i + "_" + j,i + "_" + (j+1),i + "_" + (j+2));
if(j+3<Map.COLS){
var k:uint=j+3;
while(mapArray[i][j]==mapArray[i][k]){
cancelArray.push(i + "_" + k);
if(k+1<Map.COLS){
k++;
}
else{
j=k;
break;
}
}
}
}
}
}
//再测试竖行是否可以削除
for(i=0;i<Map.COLS;i++){
for(j=0;j<Map.ROWS-2;j++){
if(mapArray[j][i] == mapArray[j+1][i] && mapArray[j][i] == mapArray[j+2][i]){
result=true;
cancelArray.push(j + "_" + i,(j+1) + "_" + i,(j+2) + "_" + i);
if(j+3<Map.ROWS){
var k:uint = j+3;
while(mapArray[j][i] == mapArray[k][i]){
cancelArray.push(k + "_" + i);
if(k+1 < Map.ROWS){
k++;
}else{
j=k;
break;
}
}
}
}
}
}
distinctArray(cancelArray);
return result;
}
另外一个算法就是,检查整个地图是否有解,如无解,则必须重新洗牌,如有解则游戏继续.
那么地图要怎样才能有解呢?
|
1 |
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
|
|
1 |
|
|
2 |
|
|
|
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
|
|
|
5 |
|
|
6 |
|
|
|
4 |
|
6 |
|
|
|
|
|
|
|
|
|
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
2 |
|
3 |
|
|
2 |
|
|
|
3 |
|
|
|
|
|
|
|
|
|
4 |
|
|
|
|
|
4 |
|
|
|
|
|
|
|
|
|
|
由图可以知道,只要地图中标数字的地方所在的图形只要有一个为,地图就有解.以下是本算法的代码,有点长,但都有注释.
public function findRoad():Boolean{
//有解的情况 只要任何一个数字为A便有解
// 一 二
// X 1 X 或者 X 1 X X 2 X
// 2 X 3 3 X A A X 4
// X A X X 5 X X 6 X
// X A X
// 4 X 5
// X 6 X
//
// 三 四
// X 3 X
// X A X X X 1 X X
// 1 X 2 或者 3 A X A 4
// X A X X X 2 X X
// X 4 X
var i:uint,j:uint;
//横向测试
for(i=0;i<Map.ROWS;i++){
for(j=0;j<Map.COLS-1;j++){
//其中有两个相连 图二
if(mapArray[i][j] == mapArray[i][j+1]){
//检测 1
if(i-1>=0 && j-1>=0){
if(mapArray[i][j] == mapArray[i-1][j-1]){
addHintArray(j-1,i-1,j-1,i);
return true;
}
}
//检测 2
if(i-1 >= 0 && j+2<Map.COLS){
if(mapArray[i][j] == mapArray[i-1][j+2]){
addHintArray(j+2,i-1,j+2,i);
return true;
}
}
//检测 3
if(j-2>=0){
if(mapArray[i][j] == mapArray[i][j-2]){
addHintArray(j-2,i,j-1,i);
return true;
}
}
//检测 4
if(j+3<Map.COLS){
if(mapArray[i][j] == mapArray[i][j+3]){
addHintArray(j+3,i,j+2,i);
return true;
}
}
//检测 5
if(i+1<Map.ROWS && j-1>=0){
if(mapArray[i][j] == mapArray[i+1][j-1]){
addHintArray(j-1,i+1,j-1,i);
return true;
}
}
//检测 6
if(i+1<Map.ROWS && j+2 < Map.COLS){
if(mapArray[i][j] == mapArray[i+1][j+2]){
addHintArray(j+2,i+1,j+2,i);
return true;
}
}
}
else{
//两个相隔一格 图四
if(j+2<Map.COLS){
if(mapArray[i][j] == mapArray[i][j+2]){
//检测1
if(i-1>=0){
if(mapArray[i][j] == mapArray[i-1][j+1]){
addHintArray(j+1,i-1,j+1,i);
return true;
}
}
//检测2
if(i+1<Map.ROWS){
if(mapArray[i][j] == mapArray[i+1][j+1]){
addHintArray(j+1,i+1,j+1,i);
return true;
}
}
//检测3
if(j-1>=0){
if(mapArray[i][j] == mapArray[i][j-1]){
addHintArray(j+2,i,j+1,i);
return true;
}
}
//检测4
if(j+3<Map.COLS){
if(mapArray[i][j] == mapArray[i][j+3]){
addHintArray(j,i,j+1,i);
return true;
}
}
}
}
}
}
}
for(i=0;i<Map.COLS;i++){
for(j=0;j<Map.ROWS-1;j++){
//如果有两个相连 图一
if(mapArray[j][i] == mapArray[j+1][i]){
//检测1
if(j-2>=0){
if(mapArray[j][i] == mapArray[j-2][i]){
addHintArray(i,j-2,i,j-1);
return true;
}
}
//检测2
if(j-1>=0 && i-1>=0){
if(mapArray[j][i] == mapArray[j-1][i-1]){
addHintArray(i-1,j-1,i,j-1);
return true;
}
}
//检测3
if(j-1>=0 && i+1<Map.COLS){
if(mapArray[j][i] == mapArray[j-1][i+1]){
addHintArray(i+1,j-1,i,j-1);
return true;
}
}
//检测4
if(j+2<Map.ROWS && i-1>=0){
if(mapArray[j][i] == mapArray[j+2][i-1]){
addHintArray(i-1,j+2,i,j+2);
return true;
}
}
//检测5
if(j+2<Map.ROWS && i+1 <Map.COLS){
if(mapArray[j][i] == mapArray[j+2][i+1]){
addHintArray(i+1,j+2,i,j+2);
return true;
}
}
//检测6
if(j+3<Map.ROWS){
if(mapArray[j][i] == mapArray[j+3][i]){
addHintArray(i,j+3,i,j+2);
return true;
}
}
}
else{
//间隔相同 图三
if(j+2<Map.ROWS){
if(mapArray[j][i] == mapArray[j+2][i]){
//检测1
if(i-1>=0){
if(mapArray[j][i] == mapArray[j+1][i-1]){
addHintArray(i-1,j+1,i,j+1);
return true;
}
}
//检测2
if(i+1<Map.COLS){
if(mapArray[j][i] == mapArray[j+1][i+1]){
addHintArray(i+1,j+1,i,j+1);
return true;
}
}
//检测3
if(j-1>=0){
if(mapArray[j][i] == mapArray[j-1][i]){
addHintArray(i,j+2,i,j+1);
return true;
}
}
//检测4
if(j+3<Map.ROWS){
if(mapArray[j][i] == mapArray[j+3][i]){
addHintArray(i,j,i,j+1);
return true;
}
}
}
}
}
}
}
return false;
}
private function addHintArray(c1:uint,r1:uint,c2:uint,r2:uint):void{
hintArray = [r1 + "_" + c1,r2 + "_" + c2];
}
在算法完成之后,最后就是游戏的实现,但在实现的过程中,我遇到了很多的困难,因为在很多地方,代码的实现都可以说是异步的.例如两个图形的转换, 我们不能在点击第一个图形,再点击另外一个图形后就马上判断是否可以消除,而必须得等到两个图形移动完位移以后,才进行判断.我们也不能在刚消完图形,还没等上面的图形掉落下来填满整个地图就进行下一次的地图检测,所以很多事情都得"等".例如我们不能让用户在图形移动的过程中,例如AB做上下的转换的过程中,用户快速的将B跟左右做位移.也就是很多的事情都必须等动画结束以后才能继续进行.所以在代码中,我做完一次动画就得向系统广播一次事件,然后只要系统检测到该事件,就可以知道我做完某事情了.然后再继续往后的事情.
在本次程序中,我引用了网上别人写的一个代理类.该类的功能就是可以让你在监听的事件中传递事件进去 .
//代理类.可为监听的函数加上参数
//如
//timer.addEventListener(TimerEvent.TIMER,proxyClass.create(onMove,c1,r1,c2,r2));
//function onMove(e:Event,c1:uint,r1:uint,c2:uint,r2:uint):void{}
package net.conanlwl
{
public dynamic class proxyClass
{
public function proxyClass(){
}
public static function create(fun:Function,...arg):Function{
var flag:Boolean = false;
var _fun:Function = function(e:*,..._arg):void{
_arg= arg;
if(!flag){
flag = true;
_arg.unshift(e);
}
fun.apply(null,_arg);
}
return _fun;
}
}
}
晚了,睡了~...虽然没人顶过文章 但最后还是想说,如果有什么问题或者好的建议,欢迎发表评论
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |