仿《雷霆戰機》飛行射擊手遊開發--GameObject

在上一篇中,咱們介紹了各類遊戲對象的功能及類的集成關係,如今咱們來看看GameObject的源代碼ide

碰撞體

GameObject.h函數

class GameObject : public Sprite
{
public:
    GameObject();

    virtual void setBodySize(const Size& s);
    virtual void setBodySize(float w, float h);
    virtual const Size& getBodySize();
    virtual const Size& getOrignBodySize() const;

    virtual void setBodyCenter(const Vec2& v);
    virtual void setBodyCenter(float x, float y);
    virtual const Vec2& getBodyCenter() const;

    //獲取世界座標下的body的位置和大小
    virtual Rect getBodyBox() const;


protected:
    //用於碰撞檢測的剛體大小和位置
    Vec2 m_bodyCenter; //剛體的中心點座標(相對於精靈錨點的座標)
    Size m_bodySize;   //剛體的寬高
};

GameObject.cpp優化

void GameObject::setBodySize(const Size& s)
{
    m_bodySize = s;
}

void GameObject::setBodySize(float w, float h)
{
    setBodySize(Size(w, h));
}

const Size& GameObject::getBodySize()
{
    return m_bodySize;
}

void GameObject::setBodyCenter(const Vec2& v)
{
    m_bodyCenter = v;
}

void GameObject::setBodyCenter(float x, float y)
{
    m_bodyCenter = Vec2(x, y);
}

const Vec2& GameObject::getBodyCenter() const
{
    return m_bodyCenter;
}

//獲取世界座標下的body的位置和大小
Rect GameObject::getBodyBox() const
{
    Vec2 pos = getPosition();

    return Rect(pos.x + m_bodyCenter.x - m_bodySize.width * getAnchorPoint().x,
        pos.y + m_bodyCenter.y - m_bodySize.height * getAnchorPoint().y,
        m_bodySize.width,
        m_bodySize.height);
}

碰撞體的定義很簡單,中心座標+寬高,而後加上常見的get/set方法。其中比較有用的是getBodyBox()方法。因爲碰撞體的中心座標是相對於Sprite錨點的座標,因此若是要用來判斷兩個碰撞體是否發生碰撞(是否有重疊區域),必需要獲取兩個碰撞體在世界座標下的位置和大小,這時就要調用getBodyBox()方法來獲得Rect對象,而後再調用Rect的bool intersectsRect(const Rect& rect)方法來判斷兩個碰撞體是否發生了碰撞。動畫

 暫停/恢復

GameObject.hthis

virtual void pause() override;
    virtual void resume() override;
    void pause(Node *pNode);
    void resume(Node *pNode);

GameObject.cppspa

void GameObject::pause()
{
    this->pause(this);
}

void GameObject::resume()
{
    this->resume(this);
}

void GameObject::pause(Node *pNode)
{
    Node::pause();

    for (auto p : pNode->getChildren())
    {
        p->pause();
    }
}

void GameObject::resume(Node *pNode)
{
    Node::resume();

    for (auto p : pNode->getChildren())
    {
        p->resume();
    }
}

調用pause和resume的同時,會調用全部子節點的pause和resume。這樣,當玩家飛機暫停時,僚機做爲它的子節點,也會跟着暫停。.net

初始化 

先看代碼code

bool GameObject::initSpriteWithFileList(const std::vector<std::string>& fileList, float dura)
{
    SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(fileList.at(0));
    if (NULL == frame)
    {
        DEBUG_LOG("Error get frame of '%s'", fileList.at(0).c_str());
        CCASSERT(frame, "Error get frame");
    }
    Sprite::initWithSpriteFrame(frame);

    //動畫
    if (fileList.size() > 1)
    {
        Animation* animation = Animation::create();
        animation->setDelayPerUnit(dura);
        for (unsigned i = 0; i < fileList.size(); i++)
        {
            SpriteFrame* pFrame = CCSpriteFrameCache::getInstance()->getSpriteFrameByName(fileList[i]);
            if (NULL == pFrame)
            {
                continue;
            }
            animation->addSpriteFrame(pFrame);
        }

        //設置重複
        Animate* animate = Animate::create(animation);
        Repeat* repeat = Repeat::create(animate, CC_REPEAT_FOREVER);
        m_pAnimateSequence = Sequence::create(repeat, NULL);
        m_pAnimateSequence->retain();
        runAction(m_pAnimateSequence);
    }

    return true;
}

這個函數是經過幀序列來初始化。這裏有兩個輸入參數:fileList是圖片列表,dura是每張圖片之間個時間間隔。如何是骨骼動畫呢?看下面這個代碼:對象

bool GameObject::initArmature(const std::string& armatureName, float scale)
{
    if (armatureName.length() <= 0)
    {
        return true;
    }

    m_pArmature = cocostudio::Armature::create(armatureName);
    m_pArmature->setPosition(getContentSize() / 2);
    m_pArmature->getAnimation()->play(GlobalData::getInstance()->getArmatureData(armatureName)->defaultAction);
    m_pArmature->setScale(scale);

    addChild(m_pArmature);

    return true;
}

首先經過骨骼動畫的名稱armatureName建立骨骼動畫,而後執行默認動做defaultAction(defaultAction是從配置文件中獲取的,配置文件的讀寫將在之後詳述)。最後把骨骼動畫添加到Sprite上。blog

    這裏就有一個疑問了,爲何既要支持幀序列動畫,又要支持骨骼動畫呢?咱們知道骨骼動畫的表現形式比幀序列動畫更豐富,可是隨之而來的問題就是骨骼動畫更佔資源。若是隻有一個簡單的動畫,或者像子彈那樣速度比較快而且數量比較多的遊戲對象,應該儘可能使用幀序列動畫,甚至對於子彈來講,只用單張圖片來表現就能夠了,根本用不着動畫。而對於玩家飛機、boss來講,由於涉及到變形,那就不得不用骨骼動畫了。

    另外,這裏也有一個能夠優化的地方。咱們能夠把GameObject繼承自Node,當遊戲對象是序列幀動畫時,就添加一個Sprite子節點,若是是骨骼動畫,就添加一個Armature子節點。

 

轉載請註明:http://www.javashuo.com/article/p-spqylilq-dt.html

項目首頁:https://www.oschina.net/p/raiden

相關文章
相關標籤/搜索