转载请注明出处:http://www.cnblogs.com/zisou/p/xianfan01.html
做一款游戏就先得制作好策划文档,和基本的人物世界构架的设计,然后架空在这样一个虚拟的世界中每一个环节都需要考虑到。
这些设计节点,都是环环相扣,相互影响依赖的关系;那么我想让我认识的同学,朋友一起相约到游戏世界中,并且能看到他和
他做交互呢?仙凡游戏的定义就是一款弱联网的游戏(HTTP为主要连接方式),那么弱联网怎么做这样一个交互非常强得功能呢?
看似不可能,不过作为手游,一切可以从简接近去模仿那种效果;
仙凡奇缘这款游戏的角色系统主要有这样一些功能:
人物基本信息
1,角色名称,性别,级别,称谓,账户ID,血,蓝,攻击,防御,攻速,经验值,移动速度;
2,技能ID(4个3个基本,一个必杀技),乘骑状态,坐骑ID,法宝ID,防具ID,首饰ID,背包格子数;
3,人物坐标,所在地图ID,所在地图坐标,场景名称等;
有很多没有列举出来,多达几十个字段的人物信息表,人物属性现在非常清晰了,每个字段都有它的功能;
详细说一下我自己对服务器端设计的架构:
1,服务器提供.aspx的post请求页面;由于C#有强大的托管机制,可以请求过程中运用反射+工厂
给服务器减轻了多人请求复杂数据,查询SQL速度快带来的优越;
2,socket辅助,提供心跳连接,和发送部分即使消息;
客户端通过http登陆后,会建立一个强连接socket连接我们的sockeserver服务器端,只是保持心跳,服务器,会一直
发送客户端心跳信息;实际上这块功能只是出发一些即时消息使用,如果玩家断线,失去连接,照样可以玩游戏,因为
主要通信还是http处理的主要业务;
看一个登陆模块的服务器代码,我在mac上用的是MonoDevelop开发环境,来开发服务器:
客户端创建角色:
ok,这就是基本创建角色部分;在之后进入游戏之后玩家就需要登陆了,登陆进入游戏前已经拿到了人物信息;
接下来就是进入场景之后,需要同步一次玩家(只同步一次即可),不需要玩家每一次的操作都去同步,那样
HTTP根本做不到,那么我们就把这个模拟出来,客户端同步其他玩家时,拿到其他玩家,在服务器上最后一次
切场景的坐标,然后进行本地客户端的AI操作,进行简单的移动即可;
部分代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
void Maps_XianFanTing::UpdataPlayerList(float time) { CCPoint randomrange = ccp(100,30); CCPoint randomrange2 = ccp(169,139); vector<MainRoledata> rolelist = GlobalInfo::getInstance()->get_playerlist(); for (int i = ROLE_PLAYERLIST; i <ROLE_PLAYERLIST+rolelist.size(); i++) { int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x); int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y); float acttodo = CCRANDOM_MINUS1_1(); CCPoint npc_nowp =randomrange2; CCPoint role_move_pc = ccp(npc_nowp.x+add_x,npc_nowp.y+add_y);//此处需要通过地图的视角把人物移动的坐标转化一下。 if(this->getChildByTag(i)!=NULL) { if(acttodo>0) { this->getChildByTag(i)->setZOrder(100); SpiritsPlayer::movemethod_Sp((CCSprite*)this->getChildByTag(i),3,role_move_pc,rolelist.at(i-ROLE_PLAYERLIST)); } else { this->getChildByTag(i)->setZOrder(99); } } } } void Maps_XianFanTing::MapUserListState(float time) { //加载其他玩家列表 if(GlobalInfo::getInstance()->getInstance()->get_mapuserlistflag()==true) { CCPoint randomrange = ccp(100,30); CCPoint randomrange2 = ccp(169,139); if(GlobalInfo::getInstance()->get_mapuserlistjsonlist().length()>0) { vector<MainRoledata> rolelist = JsonPush::ToGetRoleListdata(GlobalInfo::getInstance()->get_mapuserlistjsonlist()); vector<MainRoledata> oldrolelist = GlobalInfo::getInstance()->get_playerlist(); if(oldrolelist.size()>0) { for (int i = 0; i < oldrolelist.size(); i++) { if(this->getChildByTag(ROLE_PLAYERLIST+i)!=NULL) { this->removeChildByTag(ROLE_PLAYERLIST+i); } } } if(rolelist.size()>0) { for (int i = 0; i < rolelist.size(); i++) { SpiritsPlayer* roles = new SpiritsPlayer(rolelist.at(i),1); int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x); int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y); roles->npc->setPosition(ccp(randomrange2.x+add_x,randomrange2.y+add_y)); this->addChild(roles->npc,99,ROLE_PLAYERLIST+i); } } GlobalInfo::getInstance()->set_playerlist(rolelist); } GlobalInfo::getInstance()->set_mapuserlistflag(false); } }
效果:玩家可以做简单的移动,模仿出了玩家都在线的感觉就行;
换线的思路是在服务器中建立一个地图的分线表,里面的字段只有人物ID和地图ID和所在线ID,如果达到同屏,那就
在换线的时候,切换自己的线的ID,然后同步一次其他玩家数据(同步和自己所在一个线ID)的玩家,客户端做相应
的刷新,同步操作!
刚才我们看到1线人是非常多的,而且服务器根本不可能给我们提供所有玩家同屏信息,那么我约好一个朋友去2线;
就可以同屏看到我的小伙伴了,效果如下图:
上图可以清晰看到,我成功换到了2线,并且服务器给我同步了一次玩家操作,我来到2线后就可以看到想找的小伙伴!
这一篇大概介绍了一下制作这个游戏角色系统功能的详细方法和思路,其实这样看上去弱联网的游戏也能有非常好的
效果,下一篇我会说一下,弱联网情况下聊天制作,聊天同步的操作;
ps:仙凡奇缘官网 http://www.xianfancoco.com
cocos2dxQQ交流群:41131516