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

转载请注明:http://www.cnblogs.com/thorqq/p/5646509.html

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

碰撞体

GameObject.h

 1 class GameObject : public Sprite
 2 {
 3 public:
 4     GameObject();
 5
 6     virtual void setBodySize(const Size& s);
 7     virtual void setBodySize(float w, float h);
 8     virtual const Size& getBodySize();
 9     virtual const Size& getOrignBodySize() const;
10
11     virtual void setBodyCenter(const Vec2& v);
12     virtual void setBodyCenter(float x, float y);
13     virtual const Vec2& getBodyCenter() const;
14
15     //获取世界坐标下的body的位置和大小
16     virtual Rect getBodyBox() const;
17
18
19 protected:
20     //用于碰撞检测的刚体大小和位置
21     Vec2 m_bodyCenter; //刚体的中心点坐标(相对于精灵锚点的坐标)
22     Size m_bodySize;   //刚体的宽高
23 };

GameObject.cpp

 1 void GameObject::setBodySize(const Size& s)
 2 {
 3     m_bodySize = s;
 4 }
 5
 6 void GameObject::setBodySize(float w, float h)
 7 {
 8     setBodySize(Size(w, h));
 9 }
10
11 const Size& GameObject::getBodySize()
12 {
13     return m_bodySize;
14 }
15
16 void GameObject::setBodyCenter(const Vec2& v)
17 {
18     m_bodyCenter = v;
19 }
20
21 void GameObject::setBodyCenter(float x, float y)
22 {
23     m_bodyCenter = Vec2(x, y);
24 }
25
26 const Vec2& GameObject::getBodyCenter() const
27 {
28     return m_bodyCenter;
29 }
30
31 //获取世界坐标下的body的位置和大小
32 Rect GameObject::getBodyBox() const
33 {
34     Vec2 pos = getPosition();
35
36     return Rect(pos.x + m_bodyCenter.x - m_bodySize.width * getAnchorPoint().x,
37         pos.y + m_bodyCenter.y - m_bodySize.height * getAnchorPoint().y,
38         m_bodySize.width,
39         m_bodySize.height);
40 }

碰撞体的定义很简单,中心坐标+宽高,然后加上常见的get/set方法。其中比较有用的是getBodyBox()方法。由于碰撞体的中心坐标是相对于Sprite锚点的坐标,所以如果要用来判断两个碰撞体是否发生碰撞(是否有重叠区域),必须要获取两个碰撞体在世界坐标下的位置和大小,这时就要调用getBodyBox()方法来得到Rect对象,然后再调用Rect的bool intersectsRect(const Rect& rect)方法来判断两个碰撞体是否发生了碰撞。

暂停/恢复

GameObject.h

1     virtual void pause() override;
2     virtual void resume() override;
3     void pause(Node *pNode);
4     void resume(Node *pNode);

GameObject.cpp

 1 void GameObject::pause()
 2 {
 3     this->pause(this);
 4 }
 5
 6 void GameObject::resume()
 7 {
 8     this->resume(this);
 9 }
10
11 void GameObject::pause(Node *pNode)
12 {
13     Node::pause();
14
15     for (auto p : pNode->getChildren())
16     {
17         p->pause();
18     }
19 }
20
21 void GameObject::resume(Node *pNode)
22 {
23     Node::resume();
24
25     for (auto p : pNode->getChildren())
26     {
27         p->resume();
28     }
29 }

调用pause和resume的同时,会调用所有子节点的pause和resume。这样,当玩家飞机暂停时,僚机作为它的子节点,也会跟着暂停。

初始化

先看代码

 1 bool GameObject::initSpriteWithFileList(const std::vector<std::string>& fileList, float dura)
 2 {
 3     SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(fileList.at(0));
 4     if (NULL == frame)
 5     {
 6         DEBUG_LOG("Error get frame of ‘%s‘", fileList.at(0).c_str());
 7         CCASSERT(frame, "Error get frame");
 8     }
 9     Sprite::initWithSpriteFrame(frame);
10
11     //动画
12     if (fileList.size() > 1)
13     {
14         Animation* animation = Animation::create();
15         animation->setDelayPerUnit(dura);
16         for (unsigned i = 0; i < fileList.size(); i++)
17         {
18             SpriteFrame* pFrame = CCSpriteFrameCache::getInstance()->getSpriteFrameByName(fileList[i]);
19             if (NULL == pFrame)
20             {
21                 continue;
22             }
23             animation->addSpriteFrame(pFrame);
24         }
25
26         //设置重复
27         Animate* animate = Animate::create(animation);
28         Repeat* repeat = Repeat::create(animate, CC_REPEAT_FOREVER);
29         m_pAnimateSequence = Sequence::create(repeat, NULL);
30         m_pAnimateSequence->retain();
31         runAction(m_pAnimateSequence);
32     }
33
34     return true;
35 }

这个函数是通过帧序列来初始化。这里有两个输入参数:fileList是图片列表,dura是每张图片之间个时间间隔。如何是骨骼动画呢?看下面这个代码:

 1 bool GameObject::initArmature(const std::string& armatureName, float scale)
 2 {
 3     if (armatureName.length() <= 0)
 4     {
 5         return true;
 6     }
 7
 8     m_pArmature = cocostudio::Armature::create(armatureName);
 9     m_pArmature->setPosition(getContentSize() / 2);
10     m_pArmature->getAnimation()->play(GlobalData::getInstance()->getArmatureData(armatureName)->defaultAction);
11     m_pArmature->setScale(scale);
12
13     addChild(m_pArmature);
14
15     return true;
16 }

首先通过骨骼动画的名称armatureName创建骨骼动画,然后执行默认动作defaultAction(defaultAction是从配置文件中获取的,配置文件的读写将在以后详述)。最后把骨骼动画添加到Sprite上。

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

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

下载参考代码

转载请注明:http://www.cnblogs.com/thorqq/p/5646509.html

下一篇开始,我们将逐个介绍GameObject的子类

时间: 2024-12-23 22:11:43

仿《雷霆战机》飞行射击手游开发--GameObject的相关文章

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

游戏介绍 本游戏是一款使用cocos2d-x开发的纵版飞行射击单机游戏,开发语言是C++.玩家可以控制一架飞机与敌机进行对战,飞机可以发射子弹.导弹甚至激光,除此之外,玩家还能对自己的飞机进行强化改造,提升基础属性.当玩家完成指定的任务后,还能获取各种类型的道具奖励.游戏操作简单,上手容易,画面逼真炫酷,并有多种道具可供使用. 本游戏支持三种游戏模式:闯关模式.无尽模式.急速模式. 闯关模式 这是一种最常见的玩法,即游戏给玩家多个关卡,每个关卡面对的敌人不同,任务也不同,随着任务的完成,剧情也会

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

需求分析 既然我们做的是打飞机游戏,那需要有哪些游戏对象呢?观察一下下面这个游戏中的图片.首先,主角当然是飞机,有玩家飞机.两侧的僚机.敌机.飞机上装有各式各样的武器:普通子弹.导弹.激光等.如果只是一成不变的飞机打飞机,子弹没有变化,飞机也没有变化,那也太没意思了.所以我们还增加了道具,当敌机被击落时,会有一定的几率爆出宝石和其他各种奖励道具,比如武器升级.战机暴走.修复护甲.超级必杀.量子护盾. 我们来总结一下: 飞机有哪些基本功能?    飞行.射击.爆炸: 飞机有哪些基本属性呢? 生命.

仿《雷霆战机》飞行射击手游开发--项目总览

目录结构 ├─Classes        C++源代码.核心的核心的核心. ├─cocosstudio    Cocos Studio工程文件,包括了游戏中的所有场景界面 ├─proj.android   Android项目文件 │  ├─jni          Android的编译mk文件以及第三方SDK的so │  ├─libs         存放第三方SDK的jar │  ├─res          Android资源文件,包括icon │  └─src          java

仿《雷霆战机》飞行射击手游开发--游戏的入口

游戏的入口AppDelegate 游戏启动后,首先实例化的是AppDelegate这个类,这这个类里,我们需要修改两个函数:applicationDidFinishLaunching和applicationDidEnterBackground. 首先介绍applicationDidFinishLaunching(),游戏启动后,首先进入的就是这个方法,这里,我们可以设置游戏的分辨率.帧率.第三方SDK的初始化,以及第一次要出现的场景. 1 bool AppDelegate::applicatio

OGEngine —— 基于JAVA的手游开发开源引擎

OGEngine是国际著名开源引擎AndEngine的一个分支,遵循LGPL开源协议使用OpenGL ES进行图形绘制.同时集成了Box2D物理引擎,因此可以实现复杂的物理效果. OGEngine主要使用Java语言开发,但在大运算量的耗时功能时,OGEngine使用了C/C++本地代码进行开发.比如物理引擎及音频处理.作为用户,你只需要关注Java端就可以了,它已经把所有的本地代码封装好了.相比于其他android游戏引擎,OGEngine的效率优势十分明显. AndEngine在国际上已成为

Cocos2d-x 3.X手游开发实例详解

Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰然网创始人杨雍力荐) 于浩洋 著   ISBN 978-7-121-23998-4 2014年9月出版 定价:59.00元 356页 16开 编辑推荐 以Cocos2d-x V3.0为框架全面讲解手游开发的知识和方法 以热门游戏2048.卡牌为例,完整再现手游的开发过程 Cocos2d-x作者之一林

手游开发攻防——二、基础篇

<手游开发攻防--二.基础篇>已经更新完.主要是通过一个官方的DEMO,来分析Unity3D开发中的一些知识点和应用.注意的事项.大家可以去看看.有什么的可以提出来交流. http://blog.csdn.net/kakashi8841/article/details/39451739

写给VR手游开发小白的教程:(四)补充篇,详细介绍Unity中相机的投影矩阵

这篇作为上一篇的补充介绍,主要讲Unity里面的投影矩阵的问题: 上篇的链接写给VR手游开发小白的教程:(三)UnityVR插件CardboardSDKForUnity解析(二) 关于Unity中的Camera,圣典里面对每一项属性都做了简要的介绍,没看过的小伙伴传送门在下面 http://www.ceeger.com/Components/class-Camera.html 一.裁剪面 先从这个专业的词汇开始,以下是圣典对裁剪面的介绍: The Near and Far Clip Plane

工具分享:GameplayKit苹果手游开发工具简析

6月9日WWDC2015大会上,苹果宣布iOS 9将推出两个非常重要的手游开发工具GameplayKi和ReplayKit,这两个工具对于iOS手游开发者及欧美游戏视频相关领域可能会产生比较大的影响.GameplayKit开发工具极有可能成为今后iOS手游开发的主流工具,小爱在这里向大家简单介绍下这款工具,有兴趣的iOS开发者可以尽早get新技能. GameplayKit是什么? GameplayKit是一款帮助新手开发者们在OS X和iOS平台创作游戏的基础工具和技术框架,它能提供游戏资源.模