轉載請注明出處: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操作,進行簡單的移動即可;
部分代碼如下:

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