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

转载请注明出处:http://www.jb51.cc/article/p-ulyytgcj-cc.html
本节课的视频教程地址是:
第四课在此

如果本教程有帮助到您,希望您能点击进去观看一下,而且现在注册成为极客学院的会员,验证手机号码和邮箱号码会赠送三天的会员时间,手机端首次也可以领取五天的会员时间哦(即使是购买年会员目前也仅仅是年费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效果图:

可以看出这个功能场景的控件就三种类型,一个是菜单按钮——关闭按钮和保存按钮以及音乐和音效的开关按钮。而是精灵图片——背景图片等,三是滑动条的控件。因此此处我们需要学习的两个全新的控件就是滑动条的控件和开关按钮的控件,他们对应的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* 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* 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,that is used as a thumb. * @param selectedThumbSprite Sprite,that is used as a selected thumb. */
    virtual bool initWithSprites(Sprite * backgroundSprite,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("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效果图可以看出.这个场景中主要要实现的效果是左边的一个列表选择,中间的列表项展示区域以及一个标签提示。
关于能够实现列表显示的控件Cocos2d-x提供的相关的类有:ListView,TableView,以及一个相关的PageView。
这三个类都有些复杂,限于时间和篇幅,这里难以展开细说提供给大家几个学习的博文和demo:
TableVIew
http://www.jb51.cc/article/p-wdfoghun-hy.html

ScrollView
http://www.jb51.cc/article/p-uwhqrcdx-wx.html

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));
    m_pStone_Pic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("ManStone.png"));
    m_pStoneLabel = LabelTTF::create("石\n头\n怪",30);
    m_pStoneLabel->setColor(ccc3(0,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://www.jb51.cc/article/p-ulyytgcj-cc.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是