基于cocos2dx的横版动作游戏制作(一)

本人最近几个月在工作之余,都有断断续续地去学习cocos2dx的一些东西,在一些论坛上参考有关资料,源码,比如www.9miao.com,泰然网等等,毕竟开源,而且较为有趣。

7月份离职后,希望换个方向做手游(我之前一直做的是JAVA,web,数据库),发现没有工作经验真的是不好找....,笔试过了,面试总会问:“你有没有什么作品”,一想想,平时都是做一些demo,或者是参阅别人的项目源码,好像真的没有完整的弄一样东西出来。

为此,我准备做一个横版的动作游戏(因为是第一次做,前后总共花了6天时间才基本完成)

在看官您阅读以下内容时,我认为您是对cocos2x是有一些基础了解的。

在做这个游戏之前,我们先来设想一下,我们游戏需要哪些对象,内容等等到这些东西呢?

1.在一个战斗场景中,我们需要一副地图作为基础,所以你可能需要用到Tiled 这个工具,来制作我们的地图(在此我会认为您对瓦片地图是有了解的);

2.我们需要控制操作英雄(hero),怪物(AI)要来攻击英雄,hero和AI的闲置,行走,战斗都是需要不停地播放动画的,所以你可能需要自己去找一些人物素材(这玩意还真是不好找),然后为了方便加载使用,你可能还需要将帧动画序列打包,所以你很可能需要用到TexturePacker工具

3.英雄需要释放各种技能,还需要能使用血瓶加血,魔瓶加蓝,同时我们还需要左上角能够显示当前英雄的血量,蓝量和等级等等信息,我们还需要一个摇杆来操控英雄,等等......麻雀虽小,东西也不能少啊.....,这些素材都需要自己去找,准备好了布局又是一个问题了,这里你可能需要用到CocosStudio的UI编辑器了

4.素材的处理:你找的素材不一定都能直接用,你很可能还得自己去用PotoShop进行加工....

好了,以上这些介绍东西,已经大概能支撑我们做一款横版游戏最基础的“砖石”了,当然还有cocos2dx了,不管你在XCode下还是在VS下,这是你各人的喜好了,这里就不介绍cocos2d的配置了,网上有很多这方面的帖子。

在此我们来整理一下,我们上面说到要用到的一些工具:

1.Tiled :用来做瓦片地图的

2.TexturePacker :帧动画打包的

3.CocosStudio:UI制作的

4.PotoShop:素材加工

在此,我先放张图出来,看看开发完成之后的效果

这张图就是最基本的效果了。

接下来,我们开动之前还需要做些预备工作,那就是设计啦.....,我们不能直接拿上素材就开搞。

//------------------------设计部分----------------------------

整个战斗场景我们可以将他看成两层:

一个是游戏层(GameLayer):这里包括英雄,怪物,地图,已经地图上的掉落,道具等等.....

一个是操作层(OptionLayer):这里包括操作摇杆,技能UI,物品UI,人物头像属性UI

然后我们需要考虑一下一些面向对象的东西,在这里,英雄跟怪物是有很多共性的.我们可以将他们看成是一类角色(Role).....(包括你可能需要加一些非敌对类的NPC等都可归为这一类),怪物和英雄都可继承自它,这样我们能省很多事.....

我们最后还得考虑以下,各个对象直接的交互访问问题....因为一个场景里的各个对象有时候需要相互访问,那这个对象的实例怎么获取比较方便呢,这里我们用一个单例来保存这些对象的指针或者引用(如果您对单例设计模式不了解的话,可以先去稍微了解一十几分钟)

好了,设计部分好像说的差不多了(再往下说就没个模块的细节设计了,这点我们后面结合代码将),看起来是不是很简单呢?(是的,一目了然,但是我们做的最多的工作永远都是细节上的处理)

//---------------------地图的处理-------------

我们将地图图片的可达区域和不可区域理解为地面(floor)和墙壁(wall)两个Layer

这在后续控制英雄和怪物移动位置是能较好把握好范围,毕竟,地图的每个区域不应该都是可达的(具体的编辑细节可自己摸索和参考网上的资料,这里不再赘述);

总之你做好之后,在后续开发时肯定会用到它,以下是地图的加载......

//初始化地图
void GameDisplayLayer::initMapWithFile(const char * path){CCTMXTiledMap *tileMap = CCTMXTiledMap::create(path);CCObject *pObject = NULL;//遍历tmx地图中的LayerCCARRAY_FOREACH(tileMap->getChildren(), pObject){CCTMXLayer *child = (CCTMXLayer*)pObject;child->getTexture()->setAliasTexParameters();}tileMap->setAnchorPoint(ccp(0,0));tileMap->setPosition(ccp(0,0));this->addChild(tileMap, 0); global->tmxTileMap = tileMap;
}

加载完后,若我们想要知道对象要移动的点到底在不在floor这一区域内呢?以下是转换和判断位置代码(这里我提前贴出代码.....省的后面忘记)

//判断位置是否在地图可移动范围内
bool Global::tileAllowMove(CCPoint MovePoint){CCTMXLayer *floor = global->tmxTileMap->layerNamed("floor");//计算当前touchpoint在地图中的GidCCPoint tileGid = Global::tilePosFromLocation(MovePoint);if(0 == floor->tileGIDAt(tileGid)){//CCLog("current touchPoint tileGIDAt(?) is Empty ");return false;}return true;
}//将CCPoint转换成Gid位置
CCPoint Global::tilePosFromLocation(CCPoint MovePoint, CCTMXTiledMap *map) { if(NULL == map){map = global->tmxTileMap;}// 移动点的屏幕坐标必须减去瓷砖地图的坐标 - 因为地图可能比屏幕大,很多时候地图会随着操作移动,地图位置不一定在(0,0)点上了CCPoint point = ccpSub(MovePoint, map->getPosition()); // 将得到坐标值转换成整数 CCPoint pointGID = ccp(0,0);pointGID.x = (int) (point.x / map->getTileSize().width); pointGID.y = (int) ((map->getMapSize().height * map->getTileSize().height - point.y) / map->getTileSize().height); //CCLog("pointGID.x,%f,%f",pointGID.x,pointGID.y);return pointGID;
} 

//----------------------Role类设计--------------------------------------

Role类是怪物和英雄的基类,它定义了两者所共有的属性,方法等.......以下是代码示例,Role.h的头文件

注意:每个序列帧动画Animation 需要在怪物和英雄的init()中给其初始化

//基础角色类,主角和NPC都需要继承它
class Role :public CCSprite
{
public:Role(void);~Role(void);CC_SYNTHESIZE(std::string,Name,Name);                        //角色名称
CC_SYNTHESIZE(CCAnimation*,idleAnimation,IdleAnimation);                //角色空闲时序列CC_SYNTHESIZE(CCAnimation*,movingAnimation,MovingAnimation);            //角色移动时动画帧序列CC_SYNTHESIZE(CCAnimation*,attackAnimation,AttackAnimation);            //角色普通攻击时动画帧序列
CC_SYNTHESIZE(CCAnimation*,attackAnimation_1,AttackAnimation_1);    //角色特殊攻击1动画帧序列CC_SYNTHESIZE(CCAnimation*,attackAnimation_2,AttackAnimation_2);    //角色特殊攻击2动画帧序列CC_SYNTHESIZE(CCAnimation*,attackAnimation_3,AttackAnimation_3);    //角色特殊攻击3动画帧序列CC_SYNTHESIZE(CCAnimation*,attackAnimation_4,AttackAnimation_4);    //角色特殊攻击4动画帧序列
CC_SYNTHESIZE(CCAnimation*,hurtAnimation,HurtAnimation);                //角色受伤时动画帧序列CC_SYNTHESIZE(CCAnimation*,deadAnimation,DeadAnimation);            //角色死亡时动画帧序列
CC_SYNTHESIZE(float,curtLifeValue,CurtLifeValue);        //角色当前生命值CC_SYNTHESIZE(float,sumLifeValue,SumLifeValue);            //角色总体生命值CC_SYNTHESIZE(float,attackStrenth,AttackStrenth);        //角色当前攻击力
CC_SYNTHESIZE(ActionState,actionState,ActionState);        //当前Action状态(据此状态处理各个动画之间的衔接问题)
CC_SYNTHESIZE(Direction, roleDirection, RoleDirection);        //角色朝向(分向左还是向右)CC_SYNTHESIZE(bool, allowMove, AllowMove);        //角色是否允许移动,例如:攻击,受伤等动画执行期间不可移动CC_SYNTHESIZE(CCPoint, _vector, Vector);        //偏移量,AI自动移动时下一帧的偏移向量void Role::callBackAction(CCNode* pSender);    //动画执行完毕的通用回调处理//action methodsvirtual void RunIdleAction();            //执行闲置动画virtual void RunMovingAction();        //执行移动行走动画virtual void RunAttackAction();        //执行普通攻击动画virtual void RunAttackAction_1(); //执行特殊攻击1动画virtual void RunHurtAction();            //执行被攻击后受伤动画//......死亡动画等
};
//-------------下面我再给出动画执行部分的代码和回调-----------------------
void Role::RunAttackAction()
{if(this->getActionState() == ActionStateNone || this->getActionState() == ActionStateIdle || this->getActionState() == ActionStateMove){this->setAllowMove(false);this->stopAllActions();this->setActionState(ActionStateAttack);CCFiniteTimeAction *sequence = NULL;CCAnimate * AttackAnimate = CCAnimate::create(this->getAttackAnimation());CCFiniteTimeAction * callFuncN = CCCallFuncN::create(this, callfuncN_selector(Role::callBackAction));  sequence = CCSequence::create(AttackAnimate, callFuncN,NULL); //最后加上NULL,否则报错this->runAction(sequence);}
}//动画执行结束后的通用回调,可在子类自己定义回调
void Role::callBackAction(CCNode* pSender){if(pSender != 0) {  this->setActionState(ActionStateNone);this->setAllowMove(true);    //非行走类动画结束角色可以移动this->RunIdleAction();    //继续执行空闲动画
     }
}

//这里我再给出英雄(hero)类的初始化init()方法中帧动画的初始动作,怪物类可依葫芦画瓢.......

bool Hero::init(){//预加载精灵图片CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("MyImages/role_ac_monkey.plist");//获取纹理缓存CCSpriteFrameCache *spriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache();Hero::initWithSpriteFrameName("39597-1.png");int frameNum = 0; //取几帧int frameStart = 0;//起始numberCCArray *actionArry  = CCArray::createWithCapacity(20);CCSpriteFrame *spriteFrame = NULL;//------------------------------idle action 空闲----------------------frameNum = 4; //取几帧frameStart = 1;//起始numberfor(int i=frameStart;i<frameNum;i++){spriteFrame = spriteFrameCache->spriteFrameByName(CCString::createWithFormat("39597-%d.png",i)->getCString());actionArry->addObject(spriteFrame);}CCAnimation* idleAnimation = CCAnimation::createWithSpriteFrames(actionArry,0.2f);actionArry->removeAllObjects();idleAnimation->retain();this->setIdleAnimation(idleAnimation);//......还有行走,攻击动画等等初始化//---------------------释放array--------------------------------------actionArry->release();return true;
}

//-----------------------摇杆控制英雄行走的设计---------------------

怪物和英雄都有同样的属性,血量,攻击,状态,是否允许移动等等,貌似做的事情还不少,为了能看到某种效果,我们先来看看如何通过触摸摇杆来控制hero行走

为此我们设计一个专门的腰杆类来处理英雄的移动控制,摇杆的控制为此我做单章说明,请参考:http://www.cnblogs.com/zouly/p/3841830.html

//---------------------技能UI,及技能遮罩冷却效果-------------------------

为了使本篇幅看起来不是太长,我还希望在介绍本功能点时能开单章说明技能UI的制作过程,冷却遮罩处理,请参考:http://www.cnblogs.com/zouly/p/3842333.html

好了,为了使本文篇幅看起来不至于太长,我们第一部分就介绍到这里

另外,实现这个游戏参考了很多文章,记不住了,也不一一列举了

http://pan.baidu.com/s/1jGh0wJk 这是源代码,在vs2012 cocos2dx 2.2.2上运行,3.0~2.0版本的应该是都可以运行的

posted on 2014-07-14 11:24 慵懒的猫 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/zouly/p/3841794.html

基于cocos2dx的横版动作游戏制作(一)相关推荐

  1. 基于cocos2dx的横版动作游戏制作(二)

    基于cocos2dx的横版动作游戏制作(二) 如果你看过第一部分介绍,你应该大体知道一个横版游戏该怎么样去做,需要什么东西了....本部分介绍一些细节设计... 第一个:单例对象我们应该怎么设计才比较 ...

  2. Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 2

    本文是"使用Cocos2D 3.x开发横版动作游戏"系列教程的第二篇,同时也是最后一篇.是对How To Make A Side-Scrolling Beat Em Up Game ...

  3. 【CSON原创】基于HTML5的横版射击游戏发布

    功能说明: 基于HTML5的横版射击游戏,参考自flash游戏<双面特工>.左右方向键控制移动,下方向键蹲下,上方向键跳跃,空格键射击.体验前请先关闭输入法. 该游戏基于自己开发的HTML ...

  4. Unity学习笔记3 简易2D横版RPG游戏制作(三)

    这一篇本来应该是在上一篇后面直接补进去的.不过因为排版的问题.所以我就另开一篇来整理了,好了,废话不多说,马上整理: 十八.关卡的锁定与解锁 前面我们已经解决了在游戏开始时可以选择关卡的问题,接下来我 ...

  5. 【独立游戏】Sunset——二次元横版动作游戏

    SUNSET是一个动漫风横版动作同人游戏,讲述了在虚拟现实发达的未来,白帽黑客们与骇客的斗争 游戏中你不仅可以获得传统动作游戏的爽快打击感,还能运用各种科技道具体验到不一样的快感 游戏由南昌大学游戏部 ...

  6. 微店新品!微店首款《疯狂野蛮人》横版动作游戏来啦!

    <疯狂野蛮人>周瑜作品,微店首款横版过关游戏,冒险盗玩法,二段跳跃,支持Tiled编辑关卡内容! 游戏名称:疯狂野蛮人 游戏类型:单机:平台:12关. 玩家扮演小野蛮人,通过各种陷阱(死亡 ...

  7. Unity学习笔记2 简易2D横版RPG游戏制作(二)

    十二.敌人受攻击时的闪烁和Player的生命值的修正 上一篇中,我们利用Controller2D中的IEnumerator TakenDamage接口,使得我们的Player受到攻击时会进行闪烁,我们 ...

  8. Unity学习笔记1 简易2D横版RPG游戏制作(一)

    这个教程是参考一个YouTube上面的教程做的,原作者的教程做得比较简单,我先参考着做一遍,毕竟我也只是个初学者,还没办法完全自制哈哈.不过我之前也看过一个2D平台游戏的系列教程了,以后会整合起来,做 ...

  9. Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 1

    本文是对教程How To Make A Side-Scrolling Beat Em Up Game Like Scott Pilgrim with Cocos2D – Part 1的部分翻译,加上个 ...

最新文章

  1. 对象分割--Fully Convolutional Instance-aware Semantic Segmentation
  2. DisplayPageBoundaries 打开word后自动将页面间空白隐藏 (auto+定时器)
  3. Mysql错误1366 - Incorrect integer value解决方法
  4. 2016-04-25-信息系统实践手记5-CACHE设计一例
  5. IP地址不是唯一的吗?为什么路由器的IP地址都是这样的呢?
  6. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法
  7. 小时候有哪些丑事,让你终身难忘?
  8. 2021年宇华实验中学高考成绩查询,2021年河南高考状元多少分,今年河南高考状元资料名单...
  9. linux常用命令集(用户和组操作-共15个)
  10. 计算机三级数据库技术复习资料总结
  11. 一篇文章读懂 Ad Network、Ad Exchange、DSP、SSP、DMP的区别?
  12. 创建API Signing Key
  13. 搭建直播平台过程中的全能“辅助”——流媒体服务器
  14. 如何将一个向量投影到一个平面上_向量的各种积
  15. 模糊测试工具Sulley开发指南(2)——与Peach比较
  16. 坎坎坷坷的深度学习之路(一)-环境搭建
  17. 教程篇(6.4) 07. 诊断和故障排除 ❀ FortiManager ❀ Fortinet 网络安全专家 NSE 5
  18. css彩色波浪动画,纯css实现波浪动画【转】
  19. Nginx最新教程通俗易懂
  20. 第28届奥运会奖牌榜

热门文章

  1. log4jdbc-log4j2浅析(sqlfx客户端采集日志的来源)-java 输出sql执行时间
  2. 拾人牙慧,浅记一些C++的类
  3. 老杨说运维 | 农信行业运维数字化和智能化转型实践分享
  4. 递归:汉罗塔问题的程序实现
  5. 红队攻击演练过程中必须具备哪些能力
  6. 职业自我认知的测试软件,职业生涯规划___自我认知测试.pdf
  7. python推箱子代码详细讲解_Python使用tkinter模块实现推箱子游戏
  8. 计算机设备的快捷命令,快速打开设备管理器的快捷键教程
  9. Alpine镜像介绍
  10. 单细胞分析可视化工具盘点