︿
TOP
啊!我被攻擊了!部落衝突的尋找不在線攻擊目標實作技巧
7/22/2016
瀏覽數:2755
芬蘭遊戲開發商Super Cell所發行的手機遊戲《部落衝突》,自推出後深受全球玩家歡迎,營收高達每日數百萬美金,換算成台幣每日營收超過一億,如此驚人的吸金實力,讓許多遊戲開發商也加入戰局,一時之間,線上模擬策略類型遊戲如雨後春筍般上市,而玩家不在線上將會被其他玩家攻擊的玩法,也讓遊戲保有一定的在線率與回流率。
有些開發者會使用資料庫來記錄目前在線玩家,當玩家登入遊戲,資料庫中便記錄此一玩家,玩家離線登出,資料庫便將此玩家從在線記錄上移除,有了資料庫的協助,接著只要想辦法利用SQL指令,從這個資料庫表格中「隨機」挑選一個玩家出來,然後讀取這個玩家的資料,然後開始進行攻擊。
遊戲的攻擊畫面與操作不是我們現在要探討的重點,對於多人連線的遊戲端與伺服器的協同作業才是我們要教導大家的,在介紹之前,請容小編再囉唆幾句:
千萬不要從用戶端直接存取資料庫
千萬不要從用戶端直接存取資料庫
千萬不要從用戶端直接存取資料庫
千萬不要從用戶端直接存取資料庫
千萬不要從用戶端直接存取資料庫
沒錯,部落衝突就是這麼設計的,從排行榜查看頂尖玩家第一名的部落,小編很慶幸無論是攻擊或被攻擊,頂尖玩家都和我無關,這是因為小編的級數和頂尖玩家差太多了,所以系統在挑選目標時,絕對不會把級數與經驗值相差如此懸殊部落配在一起。
當玩家被挑選成被攻擊的對象時,系統得標記正被攻擊中,免得又被「隨機」選出給另外的玩家;攻擊結束後,系統會依照被攻擊的結果,決定要再多久才能再被選出,這就是部落衝突「護盾」的設計概念。
回到我們的主題,要隨機挑選一個線上玩家,我們得有周延的邏輯思維:
一定要隨機
要滿足玩家級數對等,或是級數相差不能太大
被選出後,到整個攻擊結束前,絕對不能再被別人挑選
被選過之後,要經過一段時間才能再被挑選
選定與定義暫存器:
ax = 0 可被挑選
ax = 1 已被挑選出來,正被攻擊中
ax = 2 護盾保護中,bx存放護盾有效時間的秒數
因為很重要,所以要講三次,如果聽不懂,請參考這篇:「就說千萬不要從用戶端直接存取資料庫,講都講不聽!」
不想要把遊戲專案搞得太複雜,資料庫、遊戲伺服器就免了,但如果只是這樣,那就太弱了,前面小編很囉唆的講了三次「千萬不要從用戶端直接存取資料庫」當然是有目的的,這就是我們一直在宣導的,遊戲專案一定要有伺服器邏輯程式,幸好用arcalet用分散式插件(DP)寫伺服器邏輯程式比寫用戶端程式還簡單,如此一來,你的遊戲就可以免除反向工程的攻擊,別忘了,你的遊戲程式是在玩家的設備上執行,任何人都可以拿到你的遊戲程式進行反向工程,而伺服器邏輯程式是在雲端主機執行,就不會有機會被人拿去進行反向工程,除非內神通外鬼偷了你的程式。
所以我們現在要教大家的是在伺服器邏輯程式上面執行挑選目標玩家,過程中只需使用ArcaletGame物件中的suGetRandomPlayer() 和suSetPlayerRegister() 函式,當遊戲程式需要挑選攻擊目標時,就發出私訊給DP伺服器邏輯程式。
挑選條件:
Online
ax=0 or (ax=2 and now-axstamp>bx)
ax=0 or (ax=2 and now-axstamp>bx)
Online
ax=0 or (ax=2 and now-axstamp>bx)
suGetRandomPlayer()有個功能,在呼叫之後可以指定變更暫存器的值,我們就是要用這個功能,當它挑選出玩家之後,立刻把ax暫存器值改為1,當中沒有時間差,因此可以讓被挑選出來的玩家處於被攻擊的狀態,邏輯運算上不滿足上面的挑選條件第2點,就不會同時又被其它玩家攻擊。攻擊結束後,我們再用suSetPlayerRegister()設定ax=2,bx=護盾有效秒數,整個挑選攻擊目標的功能就大功告成了。程式碼只有不到20行,是不是很棒棒呢?
C#
public class Attach
{
/* 挑選被攻擊的對象 */
public static void GetOnePlayerToAttach(ArcaletGame game, int grade, int SafeSeconds, OnCallCompletionWithData cb, object token)
{
/* 基本挑選條件 */
string baseCond = "ax=0 or (ax=2 and now-axstamp>bx)";
/* 按照等級條件,上下各一級才能被挑出 */
baseCond = baseCond + " and (bx <= " + (grade + 1).ToString() + " and bx >= " + (grade - 1).ToString() + ")";
game.suGetRandomPlayer(true, "ax=0 or (ax=2 and now-axstamp>bx)", cb, token);
}
/* 設定護盾保護時間,單位: 秒數 */
public static void SetProtectShield(ArcaletGame game, int second, OnCallCompletion cb)
{
game.SetPlayerRegister(null, second, null, null, cb, null);
}
}
您也可能喜歡這些文章
留言給作者
不公開此留言
登入即可留言
讀者留言
載入更多留言
文章列表