少年啊,來一發昆特嗎(二)——昆特牌的基礎定義

既然是昆特牌遊戲那麼毫無疑問,昆特牌無疑就是重點需要關注的地方,本節主要講解怎樣實現昆特牌
對於昆特牌來說,總共有四種類型的卡,單位卡(包括普通單位卡和英雄單位卡),天氣卡,特殊卡,領導卡,並且單位卡還具有力量值,能力,所屬勢力,卡牌的名稱等屬性,所以單純的sprite是無法實現這些的,需要自定義類來實現,既然是自定義類,那麼就需要有自己的構造方法和create方法,cocos2dx當然也提供了創建create方法的靜態宏,但CREATE_FUNC宏爲無參宏,只能處理不放置參數的宏,所以既然是自定義昆特牌的類,肯定需要傳入參數來初始化卡牌,所以這裏並不能使用宏,而需要自己寫一個create函數,這個create函數可以參照宏的寫法來寫,create_func宏的寫法如下:

#define CREATE_FUNC(__TYPE__) \
//type即爲類名
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else \
    { \
        delete pRet; \
        pRet = NULL; \
        return NULL; \
    } \
}

所以自己的create函數可以這麼寫,就是將上面的type全部替換爲自己所創建的類名,並填上參數

GWentCard* GWentCard::create(Dictionary *dictionary){
    GWentCard* card = new GWentCard(dictionary);
    if (card&& card->init())
    {
        card->autorelease();

        return card;
    }
    CC_SAFE_DELETE(card);
    return card;
}

接一下是類的構造,這個類的目的是爲了創建一張昆特牌,那麼昆特牌的屬性一共有基礎力量,能力,卡牌名稱,卡牌的種類,存儲改變後的力量值,攻擊的範圍,大致需要用到如上所述的幾種屬性,對於這個類來說就必須具備上述參數,並提供外部訪問函數,而cocos恰好提供了一個非常方便的宏CC_SYNTHESIZE,此宏可以同時定義一個變量,並提供對該變量進行set和get的函數,定義方法如下:

CC_SYNTHESIZE(bool,m_isSelect,Select);//是否已選    
//bool爲變量的類型,m_isSelect爲變量名稱,Select爲函數名稱,使用時的函數爲setSelect和getSelect

基礎部分完畢後,就是需要用到的函數了,完整的類定義如下:

#pragma once
#include "cocos2d.h"
class Gamescene;
USING_NS_CC;
class GWentCard : public Layer
{
public:
    GWentCard();//無參構造函數
    GWentCard(Dictionary *dictionary);//帶參構造函數
    ~GWentCard();//析構函數
    static GWentCard* create(Dictionary *dictionary);
    static GWentCard * createcard(Dictionary *dictionary);
    virtual void onEnter();//入口函數,在最終將卡牌創建前調用
    virtual void onExit();//退出函數,在其中釋放所有數據
    virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent);//觸摸開始函數
    virtual void onTouchMoved(CCTouch *pTouch, CCEvent *pEvent);//觸摸移動函數
    virtual void onTouchEnded(CCTouch *pTouch, CCEvent *pEvent);//觸摸結束函數
    virtual void onTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
    virtual bool onTouchBeganSelect(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchMovedSelect(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchEndedSelect(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchCancelledSelect(CCTouch *pTouch, CCEvent *pEvent);
    virtual bool onTouchBeganSelectGrave(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchMovedSelectGrave(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchEndedSelectGrave(CCTouch *pTouch, CCEvent *pEvent);
    virtual void onTouchCancelledSelectGrave(CCTouch *pTouch, CCEvent *pEvent);
    void setPowerLabel(int pow);//改變力量值
    bool init();//初始化
    void setTouchPriority(int num);
    void SelectPkLuTou();//如果選擇了牌就露出頭
    void SelectPkSuoTou();//如果選擇了牌就縮頭
    void setothernotlutou();//如果有一張被選擇,就讓其他的都不露頭
    void setNewPow(float scale);//設置新的力量值
    void updatePowerLabel();
private:
    CC_SYNTHESIZE(bool,m_isSelect,Select);//是否已選    
    CC_SYNTHESIZE(Gamescene*,m_gameMain,GameMain);
    CC_SYNTHESIZE(int,newPow,NewPower);
    CC_SYNTHESIZE(bool,m_isDianJi,DianJi);//是否能被點擊
    CC_SYNTHESIZE(std::string,m_Ability,Ability);//能力
    CC_SYNTHESIZE(std::string,m_Type,Type);//卡片的種類
    CC_SYNTHESIZE(int,m_pow,Pow);//卡片力量值
    CC_SYNTHESIZE(std::string,m_CardName,CardName);//卡片名稱
    CC_SYNTHESIZE(std::string,m_imgpath,imgPath);//卡片的圖片
    CC_SYNTHESIZE(std::string,cardrange,CardRange);
    CC_SYNTHESIZE(bool,onlayer,islayer);//是否已放入遊戲中
    CC_SYNTHESIZE(int,Spritetype,BType);//設置精靈種類,0爲進行遊玩時的種類,1是發牌階段換牌,2爲墓地時的調用
    CC_SYNTHESIZE(Dictionary *,dictionary,Dic);//獲取dictionary
    Point firstPoint; //點擊的第一個位置
    EventListenerTouchOneByOne* touchListener;

};

首先是init函數,該函數在create中調用,目的是初始化卡片的圖像要素,以layer爲基礎,創建一個sprite並將其添加到layer上,具體過程如下:

auto layer=Layer::create();//創建一個layer
    auto sprite=Sprite::create(this->m_imgpath);創建一個sprite,參數爲圖像路徑
    String *pow=String::createWithFormat("%d",newPow);
    sprite->setAnchorPoint(Point::ZERO);//設置描點
    layer->addChild(sprite);
    this->addChild(layer);
    this->setContentSize(sprite->getContentSize());
    return true;

其次就是觸摸函數,因爲在昆特牌中需要用到多種觸摸形式,如果單純只用一個觸摸函數來處理會變得很麻煩,所以在這裏用了多種觸摸函數來處理,並提供一個參數BType來進行控制,具體使用哪種觸摸函數,下面是cocos2dx的觸摸機制定義,因爲要通過參數來控制,而在調用create的過程中init函數和構造函數都已經調用過了,所以這裏放在onEnter中進行定義。

void GWentCard::onEnter(){
    CCLayer::onEnter();
    //觸摸響應註冊
    touchListener = EventListenerTouchOneByOne::create();//創建單點觸摸事件監聽器
    this->setTouchEnabled(true);
    //當爲0時就使用如下觸摸
    if(Spritetype==0){
      touchListener->onTouchBegan = CC_CALLBACK_2(GWentCard::onTouchBegan, this);//觸摸開始
      touchListener->onTouchMoved = CC_CALLBACK_2(GWentCard::onTouchMoved, this);//觸摸移動
      touchListener->onTouchEnded = CC_CALLBACK_2(GWentCard::onTouchEnded, this);//觸摸結束
      touchListener->setSwallowTouches(false);//不向下吞併觸摸
      _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);//註冊分發器
    }else if(Spritetype==1){
       touchListener->onTouchBegan = CC_CALLBACK_2(GWentCard::onTouchBeganSelect, this);//觸摸開始
       touchListener->onTouchMoved = CC_CALLBACK_2(GWentCard::onTouchMovedSelect, this);//觸摸移動
       touchListener->onTouchEnded = CC_CALLBACK_2(GWentCard::onTouchEndedSelect, this);//觸摸結束
       touchListener->setSwallowTouches(false);//不向下吞併觸摸
       _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);//註冊分發器

    }else if(Spritetype==2){
         touchListener->onTouchBegan = CC_CALLBACK_2(GWentCard::onTouchBeganSelectGrave, this);//觸摸開始
         touchListener->onTouchMoved = CC_CALLBACK_2(GWentCard::onTouchMovedSelectGrave, this);//觸摸移動
         touchListener->onTouchEnded = CC_CALLBACK_2(GWentCard::onTouchEndedSelectGrave, this);//觸摸結束
         touchListener->setSwallowTouches(false);//不向下吞併觸摸
         _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);//註冊分發器

    }else if(Spritetype==3){

    }
}

今天就到這裏了,具體的觸摸函數將會在下一篇一起進行講解

昆特牌1.0版源代碼
http://pan.baidu.com/s/1kTozWTT

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章