搜索
查看: 2946|回复: 4
打印 上一主题 下一主题

【cocos2d-x】拼图游戏

[复制链接]
跳转到指定楼层
楼主
发表于 2016-6-7 04:45:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 李掌柜 于 2016-6-7 05:09 编辑

这个帖子是笔记,有想用C或C++语言开发游戏的可以加这个
掌柜的创的Cocos2d-x 学习群:153412944

游戏版本:0.0.1. 20160601 base
图片资源:

图片有点污, 本来想在网上找张六一节的图片,度娘太不给力了,就用了《军火女王》的很牛A它弟牛C它哥的一张图片
C++ 代码:
  //Photo.h
#ifndef __PHOTO_H__
#define __PHOTO_H__
#include <vector>
#include "cocos2d.h"
USING_NS_CC;
class Photo: public Layer
{
    Photo();                //构造宫格函数
    ~Photo();               //析构宫格函数
public:
    static Photo * create (const char * photo, unsigned int rows = 3, unsigned int cols = 3);   //同上
protected:
    unsigned int _rows;     //行数
    unsigned int _cols;     //列数
    unsigned int _rcWidth;  //格子宽度
    unsigned int _rcHeight; //格子高度
    std::vector<std::vector<Sprite * >> _slices;        //存储我们的切片
    virtual bool initWithPhoto ( const char * photo, unsigned int rows, unsigned int cols);     //初始化图片
    bool initSlice(const char * photo);     //初始化切片数组
    void initTouchEventlistener ();         //初始化触摸事件
    void move (int x, int y);               //移动指定位置的卡片
public:
    void restart ();                        //重新开始 (随机布置卡片)
};
#endif
//Photo.cpp
#include "hoto.h"
Photo:hoto () : _rows ( 3 ), _cols ( 3 )
{
}
Photo::~Photo ()
{
    this->removeAllChildren ();         //从容器中删除所有的孩子,并清除所有动作和回调。
}
Photo * Photo::create ( const char * photo, unsigned int rows, unsigned int cols )
{
    Photo * cp = new Photo ();
    if ( cp && cp->initWithPhoto ( photo, rows, cols ))
    {
        cp->autorelease ();         //在下一帧自动释放 Ref 对象的所有权。
        return cp;
    }
    CC_SAFE_DELETE (cp);            //使用delete操作符删除一个C++对象cp,如果p为NULL,则不进行操作
    return nullptr;
}
bool Photo::initWithPhoto ( const char * photo, unsigned int rows, unsigned int cols)
{
    bool result;        //初始化是否成功
    if ( Layer::init ())
    {
        _rows = rows;
        _cols = cols;
        if ( initSlice ( photo ))
        {
            initTouchEventlistener ();
            restart ();
            result = true;
        }
        else
        {
            result = false;
        }
    }
    else
    {
        result = false;
    }
    return result;
}
bool Photo::initSlice ( const char * photo )
{
    Texture2D * texture = Director::getInstance ()->getTextureCache ()->addImage ( photo );
    if ( texture == nullptr )
    {
        return false;
    }
    //初始化存储行列的列表
    for ( int w = 0; w < _rows; ++w )
    {
        std::vector<Sprite*> row;
        for ( int h = 0; h < _cols; ++h )
        {
            row.push_back ( nullptr );      //将渲染命令插入到当前渲染队列末尾。
        }
        _slices.push_back ( row);
    }
    //计算图片每列的宽度
    auto size = texture->getContentSize ();
    _rcWidth = size.width / _rows;
    _rcHeight = size.height / _cols;
    this->setContentSize ( size );      //设置Layer大小
    //最后一块
    auto endSlice = Sprite::createWithTexture ( texture, Rect ( _rcWidth * ( _rows - 1), _rcHeight * ( _cols - 1 ), _rcWidth, _rcHeight ));
    endSlice->setAnchorPoint ( Vec2 ( 0, 0 ));
    endSlice->setPosition ( ( _rows - 1 ) * _rcWidth, 0);
    endSlice->setOpacity ( 100 );       //降低透明度
    this->addChild ( endSlice );
    _slices[_rows - 1][_cols - 1] = nullptr;        //设为空,表示这格可以移入
    //创建切片
    for ( int w = 0; w < _rows; ++w)
    {
        for ( int h = 0; h < _cols; ++h)
        {
            if ( w == _rows - 1 && h == _cols - 1 )
            {
                //最后一块不需要
                break;
            }
            Sprite * slice = Sprite::createWithTexture ( texture, Rect ( _rcWidth * w, _rcHeight * h, _rcWidth, _rcHeight ));
            slice->setAnchorPoint ( Vec2 ( 0, 0 ));
            slice->setPosition ( w * _rcWidth, size.height - ( h + 1 ) * _rcHeight );
            this->addChild ( slice );
            _slices[w][h] = slice;
        }
    }
    return true;
}
void Photo::initTouchEventlistener ()
{
    auto listener = EventListenerTouchOneByOne::create ();
    listener->onTouchBegan = [ & ] ( Touch * touch, Event * event)
    {
        Point locationInNode = this->convertToNodeSpace ( touch->getLocation ());
        Size s = this->getContentSize ();
        Rect rect = Rect ( 0, 0, s.width, s.height );
        if ( rect.containsPoint ( locationInNode ))
        {
            return true;
        }
        else
        {
            return false;
        }
    };
    listener->onTouchEnded = [ & ] ( Touch * touch, Event * event )
    {
        Point locationInNode = this->convertToNodeSpace ( touch->getLocation ());
        int x = static_cast<int>( floor ( locationInNode.x / this->_rcWidth ));
        int y = static_cast<int>( floor ( locationInNode.y / this->_rcHeight ));
        this->move( x, y );
    };
    _eventDispatcher->addEventListenerWithSceneGraphPriority ( listener, this );
}
void Photo::move ( int x, int y)
{
    y = _cols - y - 1;
    auto slice = _slices [x][y];
    if ( slice == nullptr )
    {
        return;
    }
    //查找周围是否有空白的区域
    bool isFind = false;
    Point targetPos;

    if ( y < _cols - 1 && _slices[x][y + 1] == nullptr )
    {
        targetPos.x = x;
        targetPos.y = y + 1;
        isFind = true;
    }
    else if ( y > 0 && _slices[x][y - 1] == nullptr )
    {
        targetPos.x = x;
        targetPos.y = y - 1;
        isFind = true;
    }
    else if ( x < _rows - 1 && _slices[x + 1][y] == nullptr )
    {
        targetPos.x = x + 1;
        targetPos.y = y;
        isFind = true;
    }
    else if ( x > 0 && _slices[x - 1][y] == nullptr )
    {
        targetPos.x = x - 1;
        targetPos.y = y;
        isFind = true;
    }
    if ( isFind == false )
    {
        return;
    }
    slice->runAction ( MoveTo::create ( 0.25, Vec2 ( targetPos.x * _rcWidth, _rcHeight * _cols - ( targetPos.y + 1 ) * _rcHeight)));
    _slices[targetPos.x][targetPos.y] = slice;
    _slices[x][y] = nullptr;
}
void Photo::restart ()
{
    //取出所有切片
    cocos2d::Vector<Sprite*> list;
    for ( int w = 0; w < _rows; ++w )
    {
        for ( int h = 0; h < _cols; ++h )
        {
            auto slice = _slices[w][h];
            if ( slice != nullptr )
            {
                list.pushBack ( slice );
            }
        }
    }
    //随机布置到一个位置
    for ( int w = 0; w < _rows; ++w )
    {
        for ( int h = 0; h < _cols; ++h )
        {
            if ( w == _rows -1 && h == _cols -1 )
            {
                //最后一块不需要
                _slices[w][h] = nullptr;
                break;
            }
            auto length = list.size ();
            auto value = static_cast<int>( CCRANDOM_0_1 () * length );
            auto slice = list.at ( value );
            list.eraseObject ( slice );
            _slices[w][h] = slice;
            slice->setPosition ( w * _rcWidth, _rcHeight * _cols - ( h + 1 ) * _rcHeight );
        }
    }
}
//HelloWorldScene.cpp

#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
#include "hoto.h"
USING_NS_CC;
using namespace cocostudio::timeline;
Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();
    // add layer as a child to scene
    scene->addChild(layer);
    // return the scene
    return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{

    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    Size visibleSize = Director::getInstance ()->getVisibleSize ();
    Vec2 origin = Director::getInstance ()->getVisibleOrigin ();
    auto photo = Photo::create ( "gril.jpg");
    auto photoSize = photo->getContentSize ();
    photo->setPosition ( origin.x + visibleSize.width / 2 - photoSize.width /2,
        origin.y + visibleSize.height / 2 - photoSize.height / 2);
    addChild ( photo );
    return true;
}

效果图:


QQ截图20160607044419.png (281.25 KB, 下载次数: 22)

QQ截图20160607044419.png
沙发
发表于 2016-6-8 20:26:19 | 只看该作者
找张粽子的图片,毕竟端午节了。。
板凳
 楼主| 发表于 2016-6-8 23:34:00 | 只看该作者
端午节版本的拼图小游戏
链接: http://pan.baidu.com/s/1nuHr8cp 密码: 6svc
地板
发表于 2016-6-9 00:13:09 | 只看该作者
这张图其实蛮温馨的,孩子想念母亲的怀抱什么的..嗯,一点都不污!

点评

只要大拇指在那个一下就温馨了。。  发表于 2016-6-9 22:51
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表