【Cocos游戏实战】功夫小子第四课之设置功能和图籍场景的实现

原创 2015年06月18日 22:34:57

转载请注明出处:http://blog.csdn.net/suool/article/details/46553463
本节课的视频教程地址是:
第四课在此

如果本教程有帮助到您,希望您能点击进去观看一下,而且现在注册成为极客学院的会员,验证手机号码和邮箱号码会赠送三天的会员时间,手机端首次也可以领取五天的会员时间哦(即使是购买年会员目前也仅仅是年费260),成为极客学院学习会员可以无限制的下载和观看所有的学院网站的视频,谢谢您的支持!

第三课我们学习了过渡场景和主开始菜单的分析和实现。这节课我们讲学习下如何实现主开始菜单场景的附属场景设置功能场景和图籍场景。

设置功能场景

首先是设置功能场景的分析和实现。
整个设置功能场景要实现的就是设置游戏的音乐和音效的设置并将设置保存下来。
所以这里我们首先需要知道是如何保存用户的数据,在我们的Cocos2d-x引擎中提供了一个类似数据存储的功能API

Userdefault类

这个类的作用和一些重要的API我们可以通过其源码很容易看出来:

/**
 *首先说明的是这个类的作用类似于一个小型数据库,其实是以键值对的形式存储数据的
 * UserDefault acts as a tiny database. You can save and get base type values by it.
 * For example, setBoolForKey("played", true) will add a bool value true into the database.
 * Its key is "played". You can get the value of the key by getBoolForKey("played").
 * 
 * It supports the following base types:支持以下几种特殊的数据类型的存储
 * bool, int, float, double, string
 */
class CC_DLL UserDefault
{
public:
    // 获取数据的方法,提供键取值
    // get value methods

    /**
    @brief Get bool value by key, if the key doesn't exist, a default value will return.
     You can set the default value, or it is false.
    * @js NA
    */
    bool    getBoolForKey(const char* pKey);
    /**
     * @js NA 如果取不到该键对应的值,则返回指定的默认值,一下的方法都是一样的
     */
    bool    getBoolForKey(const char* pKey, bool defaultValue)
    int     getIntegerForKey(const char* pKey);
    int     getIntegerForKey(const char* pKey, int defaultValue);
    float    getFloatForKey(const char* pKey);
    float    getFloatForKey(const char* pKey, float defaultValue);
    double  getDoubleForKey(const char* pKey);
    double  getDoubleForKey(const char* pKey, double defaultValue);
    std::string getStringForKey(const char* pKey);
    std::string getStringForKey(const char* pKey, const std::string & defaultValue);
    Data getDataForKey(const char* pKey);
    Data getDataForKey(const char* pKey, const Data& defaultValue);

    // 存储数据的方法,指定键和值存储数据,方法和上述取值一样
    // set value methods


    void    setBoolForKey(const char* pKey, bool value);
    void    setIntegerForKey(const char* pKey, int value);
    void    setFloatForKey(const char* pKey, float value);
    void    setDoubleForKey(const char* pKey, double value);
    void    setStringForKey(const char* pKey, const std::string & value);
    void    setDataForKey(const char* pKey, const Data& value);
    void    flush();
    /** returns the singleton 获取user default的一个实例(此处是单例模式)
     * @js NA
     * @lua NA
     */
    static UserDefault* getInstance();
    /**
     * @js NA
     */
    static void destroyInstance();
    // 已经弃用的方法
    /** deprecated. Use getInstace() instead 
     * @js NA
     * @lua NA
     */
    CC_DEPRECATED_ATTRIBUTE static UserDefault* sharedUserDefault();
    /**
     * @js NA
     */
    CC_DEPRECATED_ATTRIBUTE static void purgeSharedUserDefault();
    /** 这个方法就说明userdefault存储的数据其实在xml文件中,这个是获取xml文件路径
     * @js NA
     */
    const static std::string& getXMLFilePath();
    /** 判断存储数据的xml文件是否存在,可以根据这个来判断是否是首次运行这个程序
     * @js NA
     */
    static bool isXMLFileExist();
    // 更多源码和实现请自行参考源码的cpp文件和文档
};

然后看下设置功能场景的ui效果图:
设置场景的UI效果图
可以看出这个功能场景的控件就三种类型,一个是菜单按钮——关闭按钮和保存按钮以及音乐和音效的开关按钮。而是精灵图片——背景图片等,三是滑动条的控件。因此此处我们需要学习的两个全新的控件就是滑动条的控件和开关按钮的控件,他们对应的Cocos2d-x的控件是:滑动条:ControlSlider,开关按钮MenuItemToggle。

ControlSlider的用法

滑动条控件的组成分为三部分——互动的背景图,滑块,划过区域的图。看下他的关键源码:

ControlSlider.cpp
 /* 
 继承自Control控件类,这个类有三个子类——ControlSlider(滑动条),ControlButton(按钮类,这个在后面会用到),ControlSwitch(开关类)。Control类为它的子类提供了一系列的触摸响应绑定的函数。具体参考Control的源码。
 */
class ControlSlider: public Control
{
public:
    /** 通过一个背景图片,划过区域,滑块图片名称创建一个滑动条。
     * Creates slider with a background filename, a progress filename and a
     * thumb image filename.
     */
    static ControlSlider* create(const char* bgFile, const char* progressFile, const char* thumbFile);

    /** 通过一个背景图片精灵,划过区域精灵,滑块图片精灵创建一个滑动条
     * Creates a slider with a given background sprite and a progress bar and a
     * thumb item.
     *
     * @see initWithSprites
     */
    static ControlSlider* create(Sprite * backgroundSprite, Sprite* pogressSprite, Sprite* thumbSprite);
    // 以上两个方法仅仅是参数不同,但是第一个其实在方法内部也是使用的精灵实现的

    /**
     * Creates slider with a background filename, a progress filename, a thumb
     * and a selected thumb image filename.
     */
    static ControlSlider* create(const char* bgFile, const char* progressFile, const char* thumbFile,
            const char* selectedThumbSpriteFile);

    /** 多了一个选中的滑块的图片,下面方法一样
     * Creates a slider with a given background sprite and a progress bar, a thumb
     * and a selected thumb .
     *
     * @see initWithSprites
     */
    static ControlSlider* create(Sprite * backgroundSprite, Sprite* pogressSprite, Sprite* thumbSprite,
            Sprite* selectedThumbSprite);
    /**
     * @js ctor
     */
    ControlSlider();
    /**
     * @js NA
     * @lua NA
     */
    virtual ~ControlSlider();

    /** 初始化一个Slider使用参数中的精灵,各个参数的意义见下面的注释
    * Initializes a slider with a background sprite, a progress bar and a thumb
    * item.
    *
    * @param backgroundSprite          Sprite, that is used as a background.
    * @param progressSprite            Sprite, that is used as a progress bar.
    * @param thumbSprite               Sprite, that is used as a thumb.
    */
    virtual bool initWithSprites(Sprite * backgroundSprite, Sprite* progressSprite, Sprite* thumbSprite);

    /** 
    * Initializes a slider with a background sprite, a progress bar and a thumb
    * item.
    *
    * @param backgroundSprite          Sprite, that is used as a background.
    * @param progressSprite            Sprite, that is used as a progress bar.
    * @param thumbSprite               Sprite, that is used as a thumb.
    * @param selectedThumbSprite       Sprite, that is used as a selected thumb.
    */
    virtual bool initWithSprites(Sprite * backgroundSprite, Sprite* progressSprite, Sprite* thumbSprite,
            Sprite* selectedThumbSprite);

    virtual void needsLayout();
    // 常用的API
    virtual void setMaximumValue(float val); // 设置滑动的最大值
    virtual void setEnabled(bool enabled);   // 设置能否响应
    virtual bool isTouchInside(Touch * touch); 
    Point locationFromTouch(Touch* touch);
    virtual void setValue(float val);     // 手动设置滑动条的值
    virtual void setMinimumValue(float val); // 设置最小值
    ``````
    // 更多方法请自查文档和源码 
};

他的父类Control提供了一个绑定事件的函数如下:

/**
     * Adds a target and action for a particular event to an internal dispatch 
     * table.
     * The action message may optionnaly include the sender and the event as 
     * parameters, in that order.
     * When you call this method, target is not retained.
     *
     * @param target The target object¡ªthat is, the object to which the action 
     * message is sent. It cannot be nil. The target is not retained.
     * @param action A selector identifying an action message. It cannot be NULL.
     * @param controlEvent A control event for which the action message is sent.
     * See "CCControlEvent" for constants.
     */
    void addTargetWithActionForControlEvent(Ref* target, Handler action, EventType controlEvent);
// 其中Eventype是Control的强枚举类型:这里需要使用的是VALUE_CHANGE数据变化
/** Kinds of possible events for the control objects. */
    enum class EventType
    {
        TOUCH_DOWN           = 1 << 0,    // A touch-down event in the control.
        DRAG_INSIDE          = 1 << 1,    // An event where a finger is dragged inside the bounds of the control.
        DRAG_OUTSIDE         = 1 << 2,    // An event where a finger is dragged just outside the bounds of the control.
        DRAG_ENTER           = 1 << 3,    // An event where a finger is dragged into the bounds of the control.
        DRAG_EXIT            = 1 << 4,    // An event where a finger is dragged from within a control to outside its bounds.
        TOUCH_UP_INSIDE      = 1 << 5,    // A touch-up event in the control where the finger is inside the bounds of the control.
        TOUCH_UP_OUTSIDE     = 1 << 6,    // A touch-up event in the control where the finger is outside the bounds of the control.
        TOUCH_CANCEL         = 1 << 7,    // A system event canceling the current touches for the control.
        VALUE_CHANGED        = 1 << 8      // A touch dragging or otherwise manipulating a control, causing it to emit a series of different values.
    };

然后是MenuItemToggle的用法,这个控件的学习方法和上面一样,查看其源码就可以知道他的构造性方法和重要的API函数,我这里就不再带着大家走一遍了。
下面是该界面的主要实现代码:

// 头文件
/*!
 * \file SetLayer.h
 * \date 2015/05/23 8:21
 *
 * \author SuooL
 * Contact: hu1020935219@gmail.com
 *
 * \brief 设置场景,用来设置音效,音乐,音量等
 *
 * TODO: long description
 *
 * \note 
*/


#ifndef __SetLayer__H__
#define __SetLayer__H__
#include "cocos2d.h"
#include "extensions/cocos-ext.h"

USING_NS_CC;
using namespace cocos2d::extension;

class SetLayer : public Layer {
public:
    static Scene* createScene();
    virtual bool init();
    CREATE_FUNC(SetLayer);

    void changeMusicVol(Ref* pSender, Control::EventType type);
    void changeEffectVol(Ref* pSender, Control::EventType type);
    void saveSet(Ref* pSender);
    void closeBtn(Ref* pSender);
    void musicSet(Ref* pSender);
    void effectSet(Ref* pSender);
};
#endif

实现代码

Scene* SetLayer::createScene()
{
    Scene* setScene = Scene::create();
    SetLayer* layer = SetLayer::create();
    setScene->addChild(layer);
    return setScene;
}

bool SetLayer::init()
{
    if (!Layer::init())
    {
        return false;
    }

    float music = getFloatFromXML(MUSICVOL)*100.0f;
    float effect = getFloatFromXML(SOUNDVOL)*100.0f;
    // 背景精灵和关闭,保存按钮初始化
    auto BG = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("image-0.png"));
    BG->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
    //BG->setColor(cocos2d::ccGRAY);

    auto bgInterface = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("BGPicSet.png"));
    bgInterface->setPosition(WINSIZE.width / 2 + 50, WINSIZE.height / 2);

    auto closeBtn = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("closeSetNormal.png")), 
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("closeSetSelected.png")), CC_CALLBACK_1(SetLayer::closeBtn, this));
    closeBtn->setPosition(WINSIZE.width - 150, WINSIZE.height - 100);


    auto saveBtn = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("SaveSettings.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("SaveSettings.png")), CC_CALLBACK_1(SetLayer::saveSet, this));
    saveBtn->setPosition(WINSIZE.width/2+40, WINSIZE.height / 2 - 190);
    // 音乐开关按钮
    auto musicOn = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("unchecked.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("unchecked.png")));
    auto musicOff = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("Hook.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("Hook.png")));
    // 音效开关按钮
    auto effectOn = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("unchecked.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("unchecked.png")));
    auto effectOff = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("Hook.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("Hook.png")));

    auto musicToggle = MenuItemToggle::createWithTarget(this, menu_selector(SetLayer::musicSet), musicOn, musicOff, NULL);
    musicToggle->setPosition(369.5, 457);
    auto effectToggle = MenuItemToggle::createWithTarget(this, menu_selector(SetLayer::effectSet), effectOn, effectOff, NULL);
    effectToggle->setPosition(369.5, 357);
    // 根据当前的音乐和音效状态设置开关按钮的初始化状态
    if (getBoolFromXML(MUSIC_KEY))
    {
        musicToggle->setSelectedIndex(1);
    }
    else
    {
        musicToggle->setSelectedIndex(0);
    }
    if (getBoolFromXML(SOUND_KEY))
    {
        effectToggle->setSelectedIndex(1);
    }
    else
    {
        effectToggle->setSelectedIndex(0);
    }
    // 封装MenuItem到Menu并添加到场景中来
    auto menu = Menu::create(closeBtn, saveBtn, musicToggle, effectToggle, NULL);
    menu->setPosition(Point::ZERO);
    // 初始化创建滑动条控件
    auto musicSlider = ControlSlider::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("bgBar.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("progressBar.png")), Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ThumbBtn.png")));
    // 绑定回调函数
    musicSlider->addTargetWithActionForControlEvents(this, cccontrol_selector(SetLayer::changeMusicVol), Control::EventType::VALUE_CHANGED);
    auto effectSlider = ControlSlider::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("bgBar.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("progressBar.png")), Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ThumbBtn.png")));
    // 绑定回调函数
    effectSlider->addTargetWithActionForControlEvents(this, cccontrol_selector(SetLayer::changeEffectVol), Control::EventType::VALUE_CHANGED);
    // 设置滑动条控件的基本属性
    musicSlider->setPosition(800, 457);
    musicSlider->setMinimumValue(0.0f);
    musicSlider->setMaximumValue(100.0f);
    musicSlider->setMinimumAllowedValue(0.0f);
    musicSlider->setMaximumAllowedValue(100.0f);

    musicSlider->setValue(music);
    effectSlider->setPosition(800, 357);
    effectSlider->setMinimumValue(0.0f);
    effectSlider->setMaximumValue(100.0f);
    effectSlider->setMinimumAllowedValue(0.0f);
    effectSlider->setMaximumAllowedValue(100.0f);
    effectSlider->setValue(effect);
    // 将控件添加到场景中
    this->addChild(BG);
    this->addChild(bgInterface);
    this->addChild(musicSlider);
    this->addChild(effectSlider);
    this->addChild(menu);

    return true;

}

// 滑动条控件的回调函数
void SetLayer::changeMusicVol(Ref* pSender, Control::EventType type)
{
    auto temp = (ControlSlider*)pSender;
    setFloatToXML(MUSICVOL, temp->getValue()/100.0f);
    UserDefault::getInstance()->flush();
    aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
}

void SetLayer::changeEffectVol(Ref* pSender, Control::EventType type)
{
    auto temp = (ControlSlider*)pSender;
    setFloatToXML(SOUNDVOL, temp->getValue()/100.0f);
    UserDefault::getInstance()->flush();
    aduioEngine->setEffectsVolume(getFloatFromXML(SOUNDVOL));
}

// 菜单按钮的回调函数
void SetLayer::closeBtn(Ref* pSender)
{
    PLAYEFFECT;
    Director::getInstance()->replaceScene(StartLayer::createScene());
}


void SetLayer::saveSet(Ref* pSender)
{
    PLAYEFFECT;
    Director::getInstance()->replaceScene(StartLayer::createScene());
}
// 开关按钮的回调函数
void SetLayer::musicSet(Ref* pSender)
{
    auto musicTemp = (MenuItemToggle*)pSender;
    PLAYEFFECT;
    if (musicTemp->getSelectedIndex() == 0)
    {
        setBoolToXML(MUSIC_KEY, false);
        UserDefault::getInstance()->flush();
        SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    }
    else
    {
        setBoolToXML(MUSIC_KEY, true);
        UserDefault::getInstance()->flush();
        aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
        SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    }
}

void SetLayer::effectSet(Ref* pSender)
{
    auto effectTemp = (MenuItemToggle*)pSender;
    if (effectTemp->getSelectedIndex() == 0)
    {
        setBoolToXML(SOUND_KEY, false);
        UserDefault::getInstance()->flush();
    }
    else
    {
        setBoolToXML(SOUND_KEY, true);
        UserDefault::getInstance()->flush();
    }
}

以上就是设置功能场景的基本实现,其所使用的新的内容首先是UserDefault类保存和读取用户的数据,然后是ControlSlider类和MenuItemToggle类。

图籍场景的实现

图籍场景的UI效果如所示:
图籍场景的UI效果图
从上面的UI效果图可以看出.这个场景中主要要实现的效果是左边的一个列表选择,中间的列表项展示区域以及一个标签提示。
关于能够实现列表显示的控件Cocos2d-x提供的相关的类有:ListView,TableView,以及一个相关的PageView。
这三个类都有些复杂,限于时间和篇幅,这里难以展开细说提供给大家几个学习的博文和demo:
TableVIew
http://blog.csdn.net/hitwhylz/article/details/22522841

ScrollView
http://shahdza.blog.51cto.com/2410787/1544983

ListVIew:
这个可以直接看我们项目中的对listview的使用。最好还是看一下源码,分析下他的实现方式,这样如果以后需要自己定制类似的控件也会方便许多。
这个场景的实现代码如下:

Scene* TujiLayer::createScene()
{
    Scene* scene = Scene::create();
    TujiLayer* tjLayer = TujiLayer::create();
    scene->addChild(tjLayer);

    return scene;
}

bool TujiLayer::init()
{
    if (!Layer::init())
    {
        return false;
    }

    m_iBeforeSel = 0;

    // 背景
    auto bgSprite = Sprite::create("PhotoGalleryBackground.png");
    bgSprite->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
    this->addChild(bgSprite);

    auto closeItem = MenuItemSprite::create(
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("GalleryOffNormal.png")),
        Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("GalleryOffSelected.png")),
        [&](Ref * ref){
        PLAYEFFECT;
        //弹出场景
        Director::getInstance()->replaceScene(StartLayer::createScene()); });
    // 关闭按钮
    closeItem->setPosition(WINSIZE.width/2+580, WINSIZE.height/2+320);
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    bgSprite->addChild(menu);

    // 怪物图鉴
    m_pMZ_Pic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ManWood.png"));
    m_pMZ_Txt = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("Text.png"));
    m_pMZLabel = LabelTTF::create("木\n桩\n怪", "", 30);
    m_pMZLabel->setColor(ccc3(0, 255, 255));
    m_pLion_Pic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ManLion.png"));
    m_pLionLabel = LabelTTF::create("狮\n子\n怪", "", 30);
    m_pLionLabel->setColor(ccc3(0, 255, 255));
    m_pStone_Pic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ManStone.png"));
    m_pStoneLabel = LabelTTF::create("石\n头\n怪", "", 30);
    m_pStoneLabel->setColor(ccc3(0, 255, 255));

    m_pMZ_Pic->setPosition(WINSIZE.width / 2 + 50, WINSIZE.height / 2);
    m_pMZ_Pic->setVisible(true);
    m_pMZ_Txt->setPosition(WINSIZE.width / 2 + 460, WINSIZE.height / 2 );
    m_pMZ_Txt->setVisible(true);
    m_pMZLabel->setPosition(WINSIZE.width / 2 + 265, WINSIZE.height / 2 - 120);
    m_pMZLabel->setVisible(true);

    m_pLion_Pic->setPosition(WINSIZE.width / 2+50, WINSIZE.height / 2);
    m_pLion_Pic->setVisible(false);
    m_pLionLabel->setPosition(WINSIZE.width / 2 + 265, WINSIZE.height / 2 - 120);
    m_pLionLabel->setVisible(false);

    m_pStone_Pic->setPosition(WINSIZE.width / 2 , WINSIZE.height / 2 );
    m_pStone_Pic->setVisible(false);
    m_pStoneLabel->setPosition(WINSIZE.width / 2 + 265, WINSIZE.height / 2 - 120);
    m_pStoneLabel->setVisible(false);

    bgSprite->addChild(m_pMZ_Pic);
    bgSprite->addChild(m_pMZ_Txt);
    bgSprite->addChild(m_pMZLabel);
    bgSprite->addChild(m_pLion_Pic);
    bgSprite->addChild(m_pLionLabel);
    bgSprite->addChild(m_pStone_Pic);
    bgSprite->addChild(m_pStoneLabel);

    listView = ListView::create();
    listView->setDirection(SCROLLVIEW_DIR_VERTICAL);
    listView->setTouchEnabled(true);
    listView->setBounceEnabled(true);  // 反弹
    listView->setSize(Size(445, 500));
    listView->ignoreContentAdaptWithSize(false);
    listView->setAnchorPoint(Point(0.0, 0.0));
    listView->setPosition(Point(0, WINSIZE.height / 4));
    listView->addEventListenerListView(this, SEL_ListViewEvent(&TujiLayer::selectedItemEvent));

    bgSprite->addChild(listView);

    Button* default_button = Button::create("Cell_0.png", "CellSel_0.png", "", UI_TEX_TYPE_PLIST);

    default_button->setName("Title Button");

    Layout* default_item = Layout::create();
    default_item->setTouchEnabled(true);
    default_item->setSize(default_button->getSize());
    default_button->setPosition(Point(default_item->getSize().width / 2.0f,
    default_item->getSize().height / 2.0f));
    default_item->addChild(default_button);

    // set model 将创建的模板设置为项目模板  
    listView->setItemModel(default_item);


    // 1
    Button* custom_buttonMZ = Button::create("CellSel_0.png", "Cell_0.png", "", UI_TEX_TYPE_PLIST);
    custom_buttonMZ->setName("one Button");
    custom_buttonMZ->setScale9Enabled(true);
    custom_buttonMZ->setSize(default_button->getSize());
    Layout *custom_itemMZ = Layout::create();
    custom_itemMZ->setSize(custom_buttonMZ->getSize());
    custom_buttonMZ->setPosition(Point(custom_itemMZ->getSize().width / 2.0f, custom_itemMZ->getSize().height / 2.0f));
    custom_itemMZ->addChild(custom_buttonMZ);

    // 2
    Button* custom_buttonLion = Button::create("CellSel_1.png", "Cell_1.png", "", UI_TEX_TYPE_PLIST);
    custom_buttonLion->setName("two Button");
    custom_buttonLion->setScale9Enabled(true);
    custom_buttonLion->setSize(default_button->getSize());
    Layout *custom_itemLion = Layout::create();
    custom_itemLion->setSize(custom_buttonLion->getSize());
    custom_buttonLion->setPosition(Point(custom_itemLion->getSize().width / 2.0f, custom_itemLion->getSize().height / 2.0f));
    custom_itemLion->addChild(custom_buttonLion);

    // 3
    Button* custom_buttonStone = Button::create("CellSel_2.png", "Cell_2.png", "", UI_TEX_TYPE_PLIST);
    custom_buttonStone->setName("three Button");
    custom_buttonStone->setScale9Enabled(true);
    custom_buttonStone->setSize(default_button->getSize());
    Layout *custom_itemStone = Layout::create();
    custom_itemStone->setSize(custom_buttonStone->getSize());
    custom_buttonStone->setPosition(Point(custom_itemStone->getSize().width / 2.0f, custom_itemStone->getSize().height / 2.0f));
    custom_itemStone->addChild(custom_buttonStone);

    // 4
    Button* custom_buttonWood = Button::create("CellSel_3.png", "Cell_3.png", "", UI_TEX_TYPE_PLIST);
    custom_buttonWood->setName("four Button");
    custom_buttonWood->setScale9Enabled(true);
    custom_buttonWood->setSize(default_button->getSize());
    Layout *custom_itemWood = Layout::create();
    custom_itemWood->setSize(custom_buttonWood->getSize());
    custom_buttonWood->setPosition(Point(custom_itemWood->getSize().width / 2.0f, custom_itemWood->getSize().height / 2.0f));
    custom_itemWood->addChild(custom_buttonWood);

    listView->pushBackCustomItem(custom_itemMZ);
    listView->pushBackCustomItem(custom_itemLion);
    listView->pushBackCustomItem(custom_itemStone);
    listView->pushBackCustomItem(custom_itemWood);


    return true;
}

// ListView触摸监听
void TujiLayer::selectedItemEvent(Ref* pSender, ListViewEventType  type)//ListView触摸事件
{
    ListView* listView = static_cast<ListView*>(pSender);
    CC_UNUSED_PARAM(listView);

//  if (m_iBeforeSel == listView->getCurSelectedIndex())
//  {
//      return;
//  }
//  String *normalBtn = String::createWithFormat("Cell_%d.png", m_iBeforeSel);
//  String *SelctBtn = String::createWithFormat("CellSel_%d.png", listView->getCurSelectedIndex());

    m_iBeforeSel = listView->getCurSelectedIndex();

    switch (m_iBeforeSel)
    {
    case 0:
        m_pMZ_Pic->setVisible(true);
        m_pMZ_Txt->setVisible(true);
        m_pMZLabel->setVisible(true);
        m_pLion_Pic->setVisible(false);
        m_pLionLabel->setVisible(false);
        m_pStone_Pic->setVisible(false);
        m_pStoneLabel->setVisible(false);
        break;
    case 1:
        m_pMZ_Pic->setVisible(false);
        m_pMZLabel->setVisible(false);
        m_pMZ_Txt->setVisible(false);
        m_pLionLabel->setVisible(true);
        m_pLion_Pic->setVisible(true);
        m_pStoneLabel->setVisible(false);
        m_pStone_Pic->setVisible(false);
        break;
    case 2:
        m_pMZ_Pic->setVisible(false);
        m_pMZ_Txt->setVisible(false);
        m_pMZLabel->setVisible(false);
        m_pLion_Pic->setVisible(false);
        m_pLionLabel->setVisible(false);
        m_pStone_Pic->setVisible(true);
        m_pStoneLabel->setVisible(true);
        break;
    case 3:
        m_pMZ_Pic->setVisible(false);
        m_pMZ_Txt->setVisible(false);
        m_pLion_Pic->setVisible(false);
        m_pStone_Pic->setVisible(false);
        m_pLionLabel->setVisible(false);
        m_pStoneLabel->setVisible(false);
        m_pMZLabel->setVisible(false);
        break;
    default:
        break;
    }
}

这就是我们的图籍场景的实现,所使用的是ListView,这个控件的使用方法是非常简单的,但是需要我们了解下其背后的实现原理。
这里有两个问题先提出来,一个是ListView 3.0版本的在Android平台下可能会出现白屏绿底的现象。二是我们的这个场景的标签在Windows平台下面是乱码。具体的解决办法我们会在后面的给出答案,当然您也可以提前找下解决的方法。

本节课的视频教程地址是:第四课在此

如果本教程有帮助到您,希望您能点击进去观看一下,而且现在注册成为极客学院的会员,验证手机号码和邮箱号码会赠送三天的会员时间,手机端首次也可以领取五天的会员时间哦(即使是购买年会员目前也仅仅是年费260),成为极客学院学习会员可以无限制的下载和观看所有的学院网站的视频,谢谢您的支持!

转载请注明出处:http://blog.csdn.net/suool/article/details/46553463

【Cocos游戏实战】功夫小子第二课之基础类分析和实现

本节课的视频教程地址是:第二课在此 在开始第二节课之前,这里需要声明的是, 首先:本系列课程是为了结合Cocos2d-x 3.x 的基本组件和核心模块的学习而制作的,开发所使用的版本是3.0,但是...
  • hu1020935219
  • hu1020935219
  • 2015年05月29日 22:58
  • 3628

【Cocos游戏实战】功夫小子第六课之游戏主功能场景的分析和实现

经过前面五节课的学习我们目前还剩的未完成的工作就是游戏的核心场景——游戏场景。这节课我们就来学习如何实现游戏的核心场景。(核心场景的逻辑功能完成放在下一课。) 根据我们在第一课中对整个核心游戏场景的...
  • hu1020935219
  • hu1020935219
  • 2015年07月12日 16:47
  • 3163

【Cocos游戏实战】功夫小子第八课之游戏打包和相关问题说明

至此,功夫小子系列的Cocos2d-x的实战文章就结束了。 再次贴个目录以便检索: 功夫小子专栏地址:http://blog.csdn.net/column/details/suoolcocosh...
  • hu1020935219
  • hu1020935219
  • 2015年07月29日 16:12
  • 2087

功夫小子实践开发-游戏设置功能的实现

设置功能场景的ui效果图:  可以看出这个功能场景的控件就三种类型,一个是菜单按钮——关闭按钮和保存按钮以及音乐和音效的开关按钮。而是精灵图片——背景图片等,三是滑动条的控件。因此此处我们需...
  • hushhw
  • hushhw
  • 2017年08月12日 22:46
  • 85

【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现

CSDN的markdown编辑器是吃屎了么!!!什么玩意!!写了一半写不了东西,搞个毛线! 1.人物的运动状态控制——跳起,受伤,死亡判断,和怪物的打斗逻辑 2.碰撞检测(我们这个游戏由于是横版且...
  • hu1020935219
  • hu1020935219
  • 2015年07月29日 15:50
  • 1432

【Cocos游戏实战】功夫小子第五课之帮助场景和选关功能的实现

功夫小子之帮助场景和选关功能的实现转载请注明出处:http://blog.csdn.net/suool/article/details/46661231 本节课的视频教程地址是: 第五课在此 ...
  • hu1020935219
  • hu1020935219
  • 2015年06月27日 16:25
  • 2189

git深入了解

刚开始学习git时 只是记载下git常用指令,但是却不是很理解其中的含义下面,我就来说说我的理解 当然在了解之前我们说一下 工作区:就是你在电脑里能看到的目录。 stage区:一般存放在 “.g...
  • drdongshiye
  • drdongshiye
  • 2017年12月20日 17:47
  • 64

SQL优化总结---百万数据

网上关于SQL优化的教程很多,但是比较杂乱。近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充。 这篇文章我花费了大量的时间查找资料、修改、排版,希望大家阅读之后,感...
  • drdongshiye
  • drdongshiye
  • 2017年11月22日 16:11
  • 84

【Cocos2dx】利用导演类、场景类完成重新开始游戏、暂停游戏、关闭游戏功能

重新开始游戏、暂停游戏、关闭游戏是绝对是游戏的基础,虽然代码不多,不过这要利用到Cocos2dx导演类、场景类完成,事先如果不对其进行了解,绝对是很难做出来。 下面用一个小例子说明如何利用导演类、场...
  • yongh701
  • yongh701
  • 2015年10月31日 11:12
  • 4243

功夫小子实践开发-菜单场景之游戏秘籍场景的分析和实现

秘籍场景相对来说就比较简单,没有新的知识点。 有一点不好理解的就是代码里面有用到 lambda表达式的使用,如果有什么问题可以参考上一篇。 MijiLayer.h #ifndef __M...
  • hushhw
  • hushhw
  • 2017年08月08日 21:25
  • 63
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Cocos游戏实战】功夫小子第四课之设置功能和图籍场景的实现
举报原因:
原因补充:

(最多只允许输入30个字)