cocos2d 简单消除游戏算法 (一)

1. 游戏视频演示

2.三消游戏我的理解

上面视频中的游戏,我做了2个星期时间,只能算个简单Demo,还有bug,特效也几乎没有。感觉三消游戏主要靠磨,越磨越精品。市场上三消游戏已经超级多了。主流的是地图型的,几乎是无尽模式,各种消除特效,各种各样的过关方式,玩起来还是不错的,就是遇到比较难的关卡,要多试几次,运气非常好的时候就过了,不然卡死。

这个游戏真正扩展的地方就是过关模式,还需要整个特殊的地图编辑器,配合策划,不断升级游戏。

3.消除涉及到的简单算法

3.1 生成随机地图算法

有各种各样的地图,这里拿最简单的矩形来说。需求:

1.这个算法要生成一个随机的地图,不能有3个横着相同或者3个竖着相同。

2.这个地图用户移动一步能进行消除(不能是个死地图)

初看到这个需求感觉还是蛮难的,后来想了下第2个需求应该先别管,如果是死地图,再重新生成一张地图就可以了。测试了下,生成死地图的概率非常低。

算法实现的描述:

假设地图的(0,0)在左上角。

非常简单x从上面的最左边开始往右生成,y从最上面直到底部。每次先判断下它的左边两个是否已经同色,还有上面两个是否已经同色,如果同色了,要去掉这个颜色。

假设已经生成的地图是:

2, 3, 3, 4, 1, 3, 2

1, 2, 3, 4, 4, 3, 3

1, 2, 4, 2, 2, X

因为X的左边两个都是2,所以X不能再是2了,它的上面两个都是3,所以X不能再是3了。所以X的结果只能是0,1,4中随机取一个了。

下面是伪代码(是不能运行的真代码):

enum MatchItemType{
   kRedItem = 0,         //0
   kGreenItem,           //1
   kBlueItem,            //2
   kWhiteItem,           //3
   kOrangeItem           //4
};

MatchItemType getOneRandomTypeExceptParameter(const MatchItemType& type){
    MatchItemType allType[5] = {kRedItem, kGreenItem, kBlueItem, kWhiteItem, kOrangeItem};
    std::vector restType;
    for(int i = 0; i < 5; ++i){
        if(allType[i] != type){
            restType.push_back(allType[i]);
        }
    }
    int restSize = restType.size();
    int randomIndex = rand() % restSize;

    return restType[randomIndex];
}

Array2D<MatchItemType> getOneRandomMapArray(){
    Array2D<MatchItemType> map = Array2D<MatchItemType>(7, 7);
    bool findThreeSameInX = false;
    bool findThreeSameInY = false;

    for(int y = 0; y < 7; ++y){
        for(int x = 0; x < 7; ++x){
             MatchItemType randomType = (MatchItemType)(rand() % 5);

            if(x >= 2){
                //左边两个是同色
	        if( map.Get(x - 1, y) == map.Get(x - 2, y)){
                    //need find a new type
                    findThreeSameInX = true;
                }else{
                    findThreeSameInX = false;
                }
            }else{
                findThreeSameInX = false;
            }
            if(y >= 2){
                //上面两个是同色
                if(map.Get(x, y - 1) == map.Get(x, y -2)){
                    //need find a new type;
                    findThreeSameInY = true;
                }else{
                    findThreeSameInY = false;
                }
            }else{
                findThreeSameInY = false;
            }
            if(findThreeSameInX == false && findThreeSameInY == false){
               //do nothing
            }else if(findThreeSameInX == true && findThreeSameInY == false){
                randomType = getOneRandomTypeExceptParameter(map.Get(x - 1, y));
            }else if(findThreeSameInX == false && findThreeSameInY == true){
                randomType = getOneRandomTypeExceptParameter(map.Get(x, y - 1));
            }else{
                randomType = getOneRandomTypeExceptParameter(map.Get(x - 1, y),
                                                             map.Get(x, y - 1));
            }

            map.Set(x, y, randomType);
        }
    }

    return map;
}

3.2 判断地图是否是死地图

如果整个地图,用户移动任何一步也不能有消除,就是死地图了,要重新生成地图了。

//case 1
/////[x]//////[x]////////
//[x][o][x][x][o][x]/////
/////[x]//////[x]////////
/////////////////////////

//case 2
////////[x]//////////////
/////[x][o][x]///////////
////////[x]//////////////
////////[x]//////////////
/////[x][o][x]///////////
////////[x]//////////////

这里用注释画了简单的两种情况,注意x的位置。case1 是横着有两个同色的情况,移动一步能消除只有6种可能,左边3种,右边3种。下面是竖着有两个同色的情况,移动一步能消除也是6种情况。上面3种,下面3种。知道了这个,代码就容易了。记得找到一个就直接return。

vector<MatchItem*> getThreeMatchItemCanRemoveByOneStep(const Array2D<MatchItem*> & map){
    vector<MatchItem*> result;

    int maxX = 7;
    int maxY = 7;

    for(int y = 0; y < maxY; ++y){
        for(int x = 0; x < maxX; ++x){
            if(x + 1 < maxX){
                //case 1
                if(map.Get(x, y)->getType() == map.Get(x + 1, y)->getType()){
                    MatchItemType currentType = map.Get(x, y)->getType();
                    //check 6 item, one move one step can combine three same item
                    if(x - 2 >= 0){
                        if(map.Get(x - 2, y)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x - 2, y));
                            return result;
                        }
                    }
                    if(x - 1 >= 0 && y - 1 >= 0){
                        if(map.Get(x - 1, y - 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x - 1, y - 1));
                            return result;
                        }
                    }
                    if(x + 2 < maxX && y - 1 >= 0){
                        if(map.Get(x + 2, y - 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x + 2, y - 1));
                            return result;
                        }
                    }
                    if(x + 3 < maxX){
                        if(map.Get(x + 3, y)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x + 3, y));
                            return result;
                        }
                    }
                    if(x + 2 < maxX && y + 1 < maxY){
                        if(map.Get(x + 2, y + 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x + 2, y + 1));
                            return result;
                        }
                    }
                    if(x - 1 >= 0 && y + 1 < maxY){
                        if(map.Get(x - 1, y + 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x + 1, y));
                            result.push_back(map.Get(x - 1, y + 1));
                            return result;
                        }
                    }
                }

            }
            if(y + 1 < maxY){
                MatchItemType currentType = map.Get(x, y)->getType();
                //case 2
                if(map.Get(x, y)->getType() == map.Get(x, y + 1)->getType()){
                    if(y - 2 >= 0){
                        if(map.Get(x, y - 2)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x, y - 2));
                            return result;
                        }
                    }
                    if(x + 1 < maxX && y - 1 >= 0){
                        if(map.Get(x + 1, y - 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x + 1, y - 1));
                            return result;
                        }
                    }
                    if(x + 1 < maxX && y + 2 < maxY){
                        if(map.Get(x + 1, y + 2)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x + 1, y + 2));
                            return result;
                        }
                    }
                    if(y + 3 < GameGlobal::xMapCount){
                        if(map.Get(x, y + 3)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x, y + 3));
                            return result;
                        }
                    }
                    if(x - 1 >= 0 && y + 2 < maxY){
                        if(map.Get(x - 1, y + 2)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x - 1, y + 2));
                            return result;
                        }
                    }
                    if(x - 1 >= 0 && y - 1 >= 0){
                        if(map.Get(x - 1, y + 1)->getType() == currentType){
                            //find one
                            result.push_back(map.Get(x, y));
                            result.push_back(map.Get(x, y + 1));
                            result.push_back(map.Get(x - 1, y - 1));
                            return result;
                        }
                    }

                }

            }

        }
    }

    return result;
}

看起来是有点复杂,穷举了12种情况,这个算法应该速度很快的。还有个地方要用到这个算法,就是在消除游戏中,用户很久时间没有进行消除了,要给提示。就用这个算法找到哪3个可以移动一步进行消除。

算法先到这里... 后续有时间再更新...

http://www.waitingfy.com/archives/1335

时间: 2024-11-02 10:55:49

cocos2d 简单消除游戏算法 (一)的相关文章

一款简单射击游戏IOS源码

源码描述: 一款基于cocos2d的简单设计游戏,并且也是一款基于cocos2d的简单射击游戏(含苹果IAD广告), 游戏操作很简单,哪个数字大就点击射击哪个.里面有苹果iad广告,功能简单完整,适合学习一下cocos2d整套游戏的开发. 使用方法:   截图: <ignore_js_op> <ignore_js_op> 详细说明:http://ios.662p.com/thread-1445-1-1.html

四色三消游戏算法

四色三消游戏算法 下面是用python写的四色三消游戏算法,很容易改成更多颜色和行列的.基本思路就是3个一样的diamonds连在一起就可以消除.废话不说,上代码: #!/usr/bin/python #-*- coding: UTF-8 -*- #====================================================================== import os import sys import getopt import time import

[华为机试练习题]44.24点游戏算法

题目 注意: 6 + 2 * 4 + 10 = 24 不是一个数字一个数字的计算 代码 /*--------------------------------------- * 日期:2015-07-03 * 作者:SJF0115 * 题目:24点游戏算法 * 来源:华为机试练习题 -----------------------------------------*/ #include <iostream> #include <string> #include <vector&

简单的PHP算法题(带扩充)

简单的PHP算法题(待完善…) 只打印0 具体个数由输入的参数n决定 如n=5就打印00000 根据n值打印n个0 打印一行 0101010101010101010101 具体个数由输入的参数n决定 如test.php?n=3打印010 根据n值打印010101… 实现1 00 111 0000 11111 for if 实现 <?php for ($i = 0; $i < 10; $i++) { for ($j = 0; $j <= $i; $j++) { if ($i % 2 ==

Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6

Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:[email protected] E-mail: 313134555 @qq.com 这个游戏,效果看着还是不错的. 推荐. This game, the effect looks good.Recommend it. 可以生成四个平台的,html5的,窗口手机的,安卓的,苹果的. You can

怎样用HTML5 Canvas制作一个简单的游戏

为了让大家清楚HTML5制作游戏的简单流程,所以先了制作一个非常简单的游戏,来看一看这个过程.   游戏非常简单,无非就是英雄抓住怪物就得分,然后游戏重新开始,怪物出现在地图的随机位置,英雄初始化在地图的中间.点击[这里](../simple_canvas_game-master/index.html "simple_canvas_game"),我们可以直接先玩玩这个游戏 ![simple_game](Figure/1_simple_game.png) ## 1. 创建一个Canvas

【教程】原创:历上最简单的游戏编程入门教程(基于cocos2d-js)

前言: 大家好.我是一个游戏开发者.曾就职于cocos2d-x这个手机游戏引擎的开发的公司. 在这边我准备了一个最简单的教程,想告诉大家制作一个游戏有多简单. 回忆起当年刚刚步入游戏这个行业,我也抱着非常多的疑问. 所以如果大家对游戏有兴趣的朋友,可以在下面留言. 这个教程我会讲的非常通俗易懂.争取几句话之内就让你看到一个效果. 另外教程里面有丰富的图文讲解.我保证你学完之后掌握了做游戏的真髓. 你完全可以马上开始做自己的游戏.并且能够让你的游戏在网页上,ios,android 还有pc平台上跑

【Cocos2D研究院之游戏开发】

http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发] 201211-19 Cocos2D研究院之打开全新ViewController与返回(八) 雨松MOMO [Cocos2D研究院之游戏开发] 围观5745次 17条评论          之前cocos2d的文章都是由魏凯同学维护,从今天开始我也会抽时间写点cocos2d的文章.最近在研究如何将IOS游戏与软件结合起来.通常游

三种简单的排序算法

排序算法总是分不清,借了本数据结构来专门看了一下 说一下分类,主要有五类,插入排序,交换排序,选择排序,基数排序和归并排序 今天中午看了一下插入排序中的直接插入排序,交换排序的冒泡排序,选择排序中的冒泡排序 1.插入排序 将数组分成两个部分,一个是有序,一个是无序.将无序的每个元素插入到有序中,一共需要n - 1趟,最后一个元素不用计算 每一趟将第1个元素即array[i]元前面的i个元素比较,如果比array[i]大则后移一个位置.这样找到第i个元素的位置,插入 2.冒泡排序 将相邻两个元素比