仿《雷霆战机》飞行射击手游开发--GameObject

在上一篇中,我们介绍了各种游戏对象的功能及类的集成关系,现在我们来看看GameObject的源代码

碰撞体

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.h

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

GameObject.cpp

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。这样,当玩家飞机暂停时,僚机作为它的子节点,也会跟着暂停。

初始化 

先看代码

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上。

    这里就有一个疑问了,为什么既要支持帧序列动画,又要支持骨骼动画呢?我们知道骨骼动画的表现形式比帧序列动画更丰富,但是随之而来的问题就是骨骼动画更占资源。如果只有一个简单的动画,或者像子弹那样速度比较快并且数量比较多的游戏对象,应该尽量使用帧序列动画,甚至对于子弹来说,只用单张图片来表现就可以了,根本用不着动画。而对于玩家飞机、boss来说,因为涉及到变形,那就不得不用骨骼动画了。

    另外,这里也有一个可以优化的地方。我们可以把GameObject继承自Node,当游戏对象是序列帧动画时,就添加一个Sprite子节点,如果是骨骼动画,就添加一个Armature子节点。

 

转载请注明:https://my.oschina.net/u/1986600/blog/828371

项目首页:https://www.oschina.net/p/raiden

转载于:https://my.oschina.net/u/1986600/blog/828371

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值