Cocos2dx-學習筆記

1)2d笛卡爾座標

//創建一個正方形
    auto rect = DrawNode::create();
    rect->drawRect(Vec2(0,0), Vec2(50,50), Color4F(1.0,0,0,1.0));
    //添加正方形到場景中
    addChild(rect);

    //創建一個點
    auto dot = DrawNode::create();
    dot->drawDot(Vec2(0,0), 5, Color4F(1.0,1.0,1.0,1.0));
    //將點加入到正方形中
    rect->addChild(dot);

    //圍繞中心點旋轉
    rect->setContentSize(Size(50,50));
    rect->setAnchorPoint(Vec2(0.5,0.5f));//錨點

    //居中
    rect->setPosition(visibleSize/2);
    //調節點的位置
    dot->setPosition(Vec2(10,10));

    //旋轉
    schedule([dot,rect](float f){
        //旋轉
        rect->setRotation(rect->getRotation()+1);
        //獲取世界座標
        auto p = dot->convertToWorldSpace(Vec2(0,0));
        //輸出世界座標
        CCLOG("%f,%f",p.y,p.x);
    },"Test");

2)三角函數例子

//通過三角函數使物體運動
    _angle=0;
    auto dot2 = DrawNode::create();
    dot2->drawDot(Vec2(0,0), 10, Color4F(1.0,1.0,1.0,1.0));
    addChild(dot2);
    dot2->setPosition(visibleSize/2);
    schedule([dot2,this,visibleSize](float f){
        //通過修改y軸座標使得小球運動
        dot2->setPositionY(visibleSize.height/2 + sin(_angle)*100.0);
        //通過修改X軸座標使得小球運動發生變化
        dot2->setPositionX(visibleSize.height/2 + cos(_angle)*100.0);
        //角度自增0.1
        _angle+=0.1;
    },"Test");

3)小球向指定方向持續移動

 _direction.set(random(-1.0f, 1.0f), random(-1.0f,1.0f));
    _direction.normalize();//方向上的大小等於1,標準化
        auto dot3 = DrawNode::create();
        dot3->drawDot(Vec2(0,0), 10, Color4F(1.0,1.0,1.0,1.0));
        addChild(dot3);
    dot3->setPosition(visibleSize/2);
    schedule([dot3,this,visibleSize](float f){
        auto p = dot3->getPosition();

        if (p.x<0||p.x>visibleSize.width) {
            _direction.x*=-1;
        }else if(p.y<0||p.y>visibleSize.height){
            _direction.y*=-1;
        }

        dot3->setPosition(p+_direction*10);

    },"Test");

4)遊戲設置
1->設計分辨率
//設計分辨率

AppDelegate::glview->setDesignResolutionSize(1280, 720, ResolutionPolicy::FIXED_HEIGHT);

2->橫屏豎屏修改

3->顯示對象的使用

//    auto logo = Sprite::create("logo.png");
//    addChild(logo);
//    logo->setPosition(visibleSize/2);

    //將圖片提前加載成2d紋理Texture2d
    auto img = Director::getInstance()->getTextureCache()->addImage("logo.png");//可以提前異步加載圖片
    //獲取圖片的大小
    auto logoSize = img->getContentSize();
    CCLOG("logo size : %f , %f",logoSize.width,logoSize.height);
    //將2d紋理放入sprite對象中
    auto logo = Sprite::createWithTexture(img);
    addChild(logo);
    logo->setPosition(visibleSize/2);

4->圖層的先後與場景的切換

 auto layer1=Layer::create();
    auto layer2=Layer::create();
    auto layer3=Layer::create();

    auto img1 = Sprite::create("layer1.png");
    auto img2 = Sprite::create("layer2.png");
    auto img3 = Sprite::create("layer3.png");
    img1->setAnchorPoint(Vec2(0,0));
    img2->setAnchorPoint(Vec2(0,0));
    img3->setAnchorPoint(Vec2(0,0));

    layer1->addChild(img1);
    layer2->addChild(img2);
    layer3->addChild(img3);

    addChild(layer2);
    addChild(layer1);
    addChild(layer3);

    layer1->setPosition(Vec2(100,-100));
    layer1->setPosition(Vec2(500,-500));
    layer1->setPosition(Vec2(900,-900));

    scheduleOnce([visibleSize,this](float f){
        //建立一個新的場景和圖層
        auto scene2 = Scene::create();
        auto scene2Layer = Layer::create();
        //將圖層加入場景中
        scene2->addChild(scene2Layer);
        //定義一個新的logo,設置logo居中顯示
        auto logo2 = Sprite::create("logo2.png");
        logo2->setPosition(visibleSize/2);
        scene2Layer->addChild(logo2);
        //調用導演類替換圖層
        Director::getInstance()->replaceScene(scene2);
    }, 3,"delay");

5->自定義現實對象
LogoNode.hpp->

#ifndef LogoNode_hpp
#define LogoNode_hpp
#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
class LogoNode:public Node{
protected:
    Sprite* _logo;
    Sprite* _cocosLogo;
public:
    LogoNode();
    virtual ~LogoNode();
    virtual bool init();
    CREATE_FUNC(LogoNode);
};
#endif /* LogoNode_hpp */

LogoNode.cpp->

#include "LogoNode.hpp"
LogoNode::LogoNode():_logo(nullptr),_cocosLogo(nullptr){}
LogoNode::~LogoNode(){}
bool LogoNode::init(){
    //調用父類的init函數,如果調用失敗,則返回false;
    if(!Node::init()){
        return false;
    }
    _logo =Sprite::create("logo2.png");
    _cocosLogo = Sprite::create("logo.png");
    addChild(_logo);
    addChild(_cocosLogo);
    _cocosLogo->setVisible(false);
    schedule([this](float f){
        _logo->setVisible(!_logo->isVisible());
        _cocosLogo->setVisible(!_cocosLogo->isVisible());
    },1,"test");
    return true;
}

GameScene.hpp->

#ifndef GameScene_hpp
#define GameScene_hpp
#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
class GameScene:public Layer{
public:
    GameScene();
    virtual ~GameScene();
    virtual bool init();
    CREATE_FUNC(GameScene);
    static Scene* createScene();
};
#endif /* GameScene_hpp */

GameScene.cpp->

#include "GameScene.hpp"
#include "LogoNode.hpp"
GameScene::GameScene(){}
GameScene::~GameScene(){}
bool GameScene::init(){
    if (!Layer::init()) {
        return false;
    }
    auto logo = LogoNode::create();
    addChild(logo);
    logo->setPosition(Director::getInstance()->getVisibleSize()/2);
    return true;
}
Scene* GameScene::createScene(){
    auto scene=Scene::create();
    auto layer=GameScene::create();
    scene->addChild(layer);
    return scene;
}

     AppDelegate.cpp->
     auto scene = GameScene::createScene();

三 Action動畫與實現
1)基本動畫的實現

//創建一個Sprite
    auto role = Sprite::create("role.png");
    addChild(role);
    role->setPosition(visibleSize/2);
    role->setScale(1);

    //開啓Action,1爲運行時間,Vec2爲移動到的座標
    //role->runAction(MoveTo::create(1, Vec2(100,visibleSize.height-100)));

    //連續執行Action
    auto action1 = MoveBy::create(1, Vec2(100,100));
    auto action2 = action1->reverse();//反轉函數,支持MoveBy函數。
    //使用Sequence可以順序執行動畫
    role->runAction(Sequence::create(action1,action2, NULL));

    //並列執行動畫
    auto action3 = ScaleTo::create(2, 0.2);
    auto action4 = MoveBy::create(2, Vec2(200,0));
    //使用Spawn函數並列執行動畫
    role->runAction(Spawn::create(action3,action4, NULL));

    //動畫執行完成回調,通過順序/並列執行動畫達到監聽Action動畫的效果,使用CallFunc函數回調
    role->runAction(Sequence::create(Spawn::create(action3,action4, NULL),CallFunc::create([](){
        CCLOG("Play Completed");
    }) , NULL));

2) Action內置特效(NodeGrid)

實例代碼:

//建立NodeGrid對象,加入Sprite
    auto role = NodeGrid::create();
    role->addChild(Sprite::create("role.png"));
    role->setPosition(visibleSize/2);
    addChild(role);

    //Shaky3D,ShakyTiles3D,ShuffleTiles,TurnOffTiles

    /**ShakyTiles3D->10爲震動時間,Size爲網格大小,數值越大,網格越細,1爲震動幅度,false爲Z軸的深度
    role->runAction(ShakyTiles3D::create(10, Size(10,10), 1, false));*/

    /*爆炸效果->1爲爆炸時間,Size爲碎片大小,25爲爆炸的速度
    role->runAction(ShuffleTiles::create(1, Size(50,50), 25));*/


    /*先抖動後爆炸
    auto shaky = ShakyTiles3D::create(1, Size(50,50), 5, false);
    auto shuffle = ShuffleTiles::create(0.5, Size(50,50), 25);
    role->runAction(Sequence::create(shaky,shuffle, NULL));*/

    /*碎片消失
    role->runAction(TurnOffTiles::create(1, Size(50,50)));*/

    /*波浪效果->3爲持續時間,Size爲網格大小,5爲波紋幅度,40爲扭曲度
    role->runAction(Waves3D::create(3, Size(50,50), 5, 40));*/

    /*波浪震動後還原
    auto wave1 = Waves3D::create(3, Size(15,10), 5, 40);
    auto wave2 = Waves3D::create(3, Size(15,10), 5, 0);
    role->runAction(Sequence::create(wave1,wave2, NULL));*/

3)場景切換特效:

實例代碼:

auto background= Sprite::create("a.png");
    background->setPosition(visibleSize/2);
    addChild(background);

    //建立schedule替換場景
    scheduleOnce([visibleSize](float f){
        //創建新的場景
        auto newScene = Scene::create();
        auto newBackground = Sprite::create("b.png");
        newBackground->setPosition(visibleSize/2);
        newScene->addChild(newBackground);
        /*創建場景替換動畫,TransitionCrossFade是淡入淡出
        auto transition = TransitionCrossFade::create(1, newScene);*/
        /*反轉動畫效果
        auto transition = TransitionZoomFlipAngular::create(1, newScene);*/
        /*翻頁效果
        auto transition = TransitionPageTurn::create(1, newScene, true);*/
        /*順時針切換
        auto transition = TransitionProgressRadialCW::create(1, newScene);*/
        /*左右切換
        auto transition = TransitionSplitRows::create(1, newScene);*/
        //替換場景
        Director::getInstance()->replaceScene(newScene);
    }, 2,"Test");

四,內存管理和數據結構

1)所有的現實對象,如果當前正在顯示,則不會被釋放內存。如果沒有在顯示,也沒有調用Ref::retain()函數,則會因爲索引爲0而倍自動釋放。 Ref::autoRelease() ->每一幀都會遍歷一次所有的對象,進行自動釋放。
obj->getReferenceCount() 可以查看引用的計數

記得使用對象時需要retain()和release(),或者直接autorelease();

2)Vector和Map ->自動管理對象,不能保存沒有繼承Ref的對象

//Vector 的正確用法
    Vector<Label*> vec;
    auto label1 = Label::create();
    auto label2 = Label::create();
    label1->setString("Label 1");
    label2->setString("Label 2");
    label1->setSystemFontSize(50);
    label2->setSystemFontSize(50);
    vec.pushBack(label1);
    vec.pushBack(label2);
    int i = 0;
    for (auto label:vec) {
        i++;
        label->setPosition(Vec2(visibleSize.width/2,i*150));
        addChild(label);
    }
    //Map的正確用法
    Map<std::string,Label*> map;
    auto label1 = Label::create();
    auto label2 = Label::create();
    label1->setString("Label 1");
    label2->setString("Label 2");
    label1->setSystemFontSize(50);
    label2->setSystemFontSize(50);
    label1->setPosition(Vec2(visibleSize.width/2,200));
    label2->setPosition(Vec2(visibleSize.width/2,300));
    map.insert("label1",label1);
    map.insert("label2",label2);
    addChild(map.at("label1"));

3)value
實例代碼:

 //Value的使用
    Value value1 = Value("abc");
    Value value2 = Value(123);
    Value value3 = Value(true);
    //一般情況下通過以下代碼輸出
    CCLOG("%s %d %s ",value1.asString().c_str(),value2.asInt(),value3.asBool()==true?"True":"False");
    //萬能value輸出方式更自由
    CCLOG("%s %s %s",value1.asString().c_str(),value2.asString().c_str(),value3.asString().c_str());

    Value value4 = Value::Null;//將Value設置爲null
    value4=value1;
    value4=value2;
    value4=value3;
    //Value可以被重複賦值
    CCLOG("%s %s",value4.getType()==Value::Type::BOOLEAN?"True":"False",value4.asString().c_str());

    //ValueVector的使用,和打印
    ValueVector vector;
    vector.push_back(Value("Hello"));
    vector.push_back(value1);
    vector.push_back(value2);
    for (auto v:vector) {
        CCLOG("Vector %s",v.asString().c_str());
    }

    //ValueMap,先遍歷最後面的值?
    ValueMap map;
    map["a"]=value2;
    map["b"]=value1;
    for (auto m:map) {
        CCLOG("%s = %s",m.first.c_str(),m.second.asString().c_str());
    }

五,基本控件介紹
Director->Scene->Layer->Sprite
#錨點?->定位點,默認情況0.5,0.5
#Director::runWithScene();
#靜態方法: Sprite::create() ->Cocos2d-x的約定,這是一個靜態的方法,
#auto 是什麼意思?

消息框MessageBox()用法->

 //消息框提示
    MessageBox("hello world", "title");

文本標籤LabelTTF

 //標籤
    LabelTTF *label =LabelTTF::create();
    label->setString("Hello World");
    label->setFontSize(50);
    label->setPosition(visibleSize.width/2,visibleSize.height/2);
    addChild(label);

輸入文本框TextFieldTTF->

//新增輸入文本
    TextFieldTTF *textfield = TextFieldTTF::textFieldWithPlaceHolder("在這裏輸入", "宋體", 20);
    textfield->setPosition(visibleSize.width/2,visibleSize.height/2);
    addChild(textfield);
    //建立一個文本框的listener
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan=[textfield ](Touch *t,Event *event){
        if (textfield->getBoundingBox().containsPoint(t->getLocation())) {
            //彈出輸入鍵盤
            textfield->attachWithIME();
        }else{
            //當點擊到別的地方時,隱藏輸入鍵盤
            textfield->detachWithIME();
        }
        return false;
    };
    //註冊TextField的listener
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, textfield);

自定義類(與常用的C++類使用有差別)
Ball.cpp->

#include "Ball.hpp"
bool Ball::init(){
    //調用Sprite類的initWithFile代碼
    initWithFile("ball.png");
    return true;
}

Ball.hpp->

#ifndef Ball_hpp
#define Ball_hpz
#include <stdio.h>
#include "cocos2d.h"
using namespace cocos2d;
class Ball:public Sprite{
public:
    //在這裏做初始化的操作,比如加載圖片
    virtual bool init();
//    static Ball* create(){
//        Ball * b = new Ball();
//        b->init();
//        b->autorelease();
//        return b;
//    }
    //使用宏快速創建Ball,代碼與上面註釋的類似
    CREATE_FUNC(Ball);
};
#endif /* Ball_hpp */

HelloWorldScene.cpp->

#include "Ball.hpp"
auto b = Ball::create();
b->setPosition(200,200);
addChild(b);

菜單Menu
實例代碼->可以添加多個菜單

//Menu菜單的使用
//創建一個菜單,通過 lambda表達式註冊回調函數
auto menu = Menu::create(MenuItemImage::create("unselect.png", "selected.png", [](Object* obj){
//函數回調
log("menu item touched");
}), NULL);
addChild(menu);

列表的使用:
HelloWorldScene.h->

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
//要使用列表必須引入以下頭文件
#include <cocos-ext.h>
USING_NS_CC;
//要使用列表必須使用以下命名空間
USING_NS_CC_EXT;
class HelloWorld : public cocos2d::Layer,TableViewDataSource,TableViewDelegate
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
public:
    /**
     * cell height for a given table.
     *
     * @param table table to hold the instances of Class
     * @return cell size
     */
    virtual Size cellSizeForTable(TableView *table);
    /**
     * a cell instance at a given index
     *
     * @param idx index to search for a cell
     * @return cell found at idx
     */
    virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx);
    /**
     * Returns number of cells in a given table view.
     *
     * @return number of cells
     */
    virtual ssize_t numberOfCellsInTableView(TableView *table);
public:
    /**
     * @js NA
     * @lua NA
     */
    virtual void scrollViewDidScroll(ScrollView* view) {};
    /**
     * @js NA
     * @lua NA
     */
    virtual void scrollViewDidZoom(ScrollView* view) {};
    /**
     * Delegate to respond touch event
     *
     * @param table table contains the given cell
     * @param cell  cell that is touched
     * @js NA
     * @lua NA
     */
    virtual void tableCellTouched(TableView* table, TableViewCell* cell);
};
#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp->

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
//使用列表必須要引入以下頭文件
#include <cocos-ext.h>
//比如要使用以下命名空間
USING_NS_CC_EXT;
USING_NS_CC;
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;
    }
    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    //建立一個TableView,需要繼承兩個類:TableViewDataSource,TableViewDelegate
    TableView * tv = TableView::create(this, Size(300,300));
    tv->setAnchorPoint(Point(0,0));
    tv->setPosition(50,50);
    //註冊點擊監聽函數
    tv->setDelegate(this);
    addChild(tv);
    return true;
}
//返回每一個列表項的大小
Size HelloWorld::cellSizeForTable(cocos2d::extension::TableView *table){
    return Size(300,50);
}
//創建列表項,類似於android的getView()
TableViewCell* HelloWorld::tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx){
    TableViewCell *cell = table->dequeueCell();
    LabelTTF *label;
    if (cell==NULL) {
        cell = TableViewCell::create();
        label = LabelTTF::create();
        label->setTag(2);
        label->setFontSize(20);
        label->setAnchorPoint(Point(0,0));
        cell->addChild(label);
    }else{
        label = (LabelTTF*)cell->getChildByTag(2);
    }
    label->setString(StringUtils::format("Label: %ld",idx));
    return cell;
}
//返回列表的數量
ssize_t HelloWorld::numberOfCellsInTableView(cocos2d::extension::TableView *table){
    return 100;
}
//當label被點擊時的回調方法
void HelloWorld::tableCellTouched(cocos2d::extension::TableView *table, cocos2d::extension::TableViewCell *cell){
    LabelTTF *label =(LabelTTF*) cell->getChildByTag(2);
    log("%s",label->getString().c_str());
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
    Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章