12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Cocos2dxでダイアログ的な何かを作ってみた

Last updated at Posted at 2014-09-27

何を目的に作ったか。

ダイアログ的な表示を簡単に呼べる汎用ライブラリを作成したい。
休みの日についカッとなって作った、今は反省している

何処迄作ったか

  • ガワを除く、構造を作成
  • モーダルレイヤ機能
  • タイトル、詳細が空の場合は間を詰める
  • ボタンの増減が可能な可変機能

実装イメージ

背景はサンプルで実装とは異なります。
Qiitaにアップした動画GIFが不安定なのは何やろ。。
DialogSample.gif

呼び出し方

cocos2d::ccMenuCallback action = CC_CALLBACK_1(GameScene::menuStartCallback,this);
std::vector<UIDialogButton*> buttons = {
    new UIDialogButton("ルームを作成する",action,1),
    new UIDialogButton("ルームを探す",action,2),
};
auto* dialog = UIDialog::create("ダイアログタイトル","このゲームは適当に選択したらはじまります\n※たぶん※", buttons);
addChild(dialog,Z_Dialog,T_Dialog);

結果の受取

void GameScene::menuStartCallback(Ref* Sender)
{
    MenuItem* menuItem = (MenuItem*)Sender;
    log("%d",menuItem->getTag());
    switch(menuItem->getTag()){
        case 1:
            break;
        case 2:
            break;
    }
    dialogClose();
}
void GameScene::dialogClose()
{
    UIDialog* dialog = static_cast<UIDialog*>(getChildByTag(T_Dialog));
    dialog->close();
}

ライブラリ

UIDialog.h
#include "cocos2d.h"
USING_NS_CC;

struct UIDialogButton {
private:
    std::string _name;
    cocos2d::ccMenuCallback &_action;
    int _tag;

public:
    
    UIDialogButton(std::string name, cocos2d::ccMenuCallback &action,int tag=1)
        : _name(name), _action(action), _tag(tag) {}
    
    std::string name() const { return _name; }
    cocos2d::ccMenuCallback action() const { return _action; }
    int tag() const { return _tag; }
};

class UIDialog : public Layer
{
protected:
    Layer* _uiLayer;
    
public:
    static UIDialog* create(std::string title,
                            std::string content,
                            std::vector<UIDialogButton*> buttons);
    virtual bool init();
    virtual void view(std::string title,
                     std::string content,
                     std::vector<UIDialogButton*> buttons);
    void close();
};
UIDialog.cpp
#include "UIDialog.h"
USING_NS_CC;

UIDialog* UIDialog::create(std::string title,
                           std::string content,
                           std::vector<UIDialogButton*> buttons)
{
    auto dialog = new UIDialog();
    
    dialog->init();
    dialog->view(title,content,buttons);
    dialog->autorelease();
    return dialog;
    
}

#define kModalLayerPriority -1

bool UIDialog::init()
{
    if (!Layer::init())
        return false;
    
    _uiLayer = Layer::create();
    addChild(_uiLayer);
    
    return true;
}

void UIDialog::view(std::string title,
          std::string content,
          std::vector<UIDialogButton*> buttons){
    
    Size winSize = Director::getInstance()->getWinSize();
    
    // 背景作成
    auto s = Sprite::create();
    s->setTextureRect(Rect(0,0,winSize.width*2,winSize.height*2));
    s->setColor(Color3B::BLACK);
    s->setOpacity(128); // 透明度
    _uiLayer->addChild(s);
    
    // モーダルレイヤ化
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = [](Touch *touch,Event*event)->bool{
        return true;
    };
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    this->getEventDispatcher()->setPriority(listener, kModalLayerPriority);
    
    int size = buttons.size() - 1;
    if (title != "") size++;
    if (content != "") size++;
    
    float mergin = 150.0f;
    float height = mergin * size / 2;
    
    Vector<MenuItem*> item;
    if (title != ""){
        auto* titleLabel = Label::createWithSystemFont(title, "Arial", 28,Size::ZERO,TextHAlignment::CENTER,TextVAlignment::CENTER);
        titleLabel->setPosition(Point(winSize.width/2,winSize.height/2+height));
        _uiLayer->addChild(titleLabel);
        height -= mergin;
    }
    
    if (content != ""){
        auto* contentLabel = Label::createWithSystemFont(content, "Arial", 28,Size::ZERO,TextHAlignment::CENTER,TextVAlignment::CENTER);
        contentLabel->setPosition(Point(winSize.width/2,winSize.height/2+height));
        _uiLayer->addChild(contentLabel);
        height -= mergin;
    }
    
    int tag = 1;
    for (auto b : buttons){
        auto* labelBtnLabel = Label::createWithSystemFont(b->name(), "Arial", 48);
        auto* itemLabel = MenuItemLabel::create(labelBtnLabel, b->action());
        
        // ボタンのサイズ
        //log("%f %f",itemLabel->getPosition().x, itemLabel->getPosition().y);
        itemLabel->setPosition(Vec2(0.0f, height));
        if (b->tag() != 1) tag = b->tag(); // 指定があれば指定タグ
        itemLabel->setTag(tag);
        item.pushBack(itemLabel);
        height -= mergin;
        tag++; // 普段は加算
    }
     //メニューを作成
    auto* menu = Menu::createWithArray(item);
    _uiLayer->addChild(menu);
}

void UIDialog::close()
{
    Action* action = RemoveSelf::create();
    runAction(action);
}
12
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?