目錄
7.伺服器啟動後載入基礎資料,將對應的任務註冊到對應的處理器
前言:一直在寫Java 方面的,今天寫一寫遊戲設計方面的 一任務系統。任務系統是每個任務的標配,不管是普通的小遊戲,還是大型的端遊,手遊,沒了任務系統的遊戲是不完整的。任務系統是遊戲的驅動,是玩家的目標,有了目標才會有追求,正常完成任務都會獲得獎勵,有糖吃,開心。
任務其實本身就是一種「激勵制度」,接受任務-進行挑戰-完成獎勵,這個過程中的每一個環節,都是對玩家遊戲的激勵,所以任務在其中就起著這樣的這樣的作用。對於玩家自身來說,從心理學上,完成任務是對自己挑戰的肯定,會大大增加玩家遊戲的滿足感,即使沒有順利完成某一項任務,玩家感受到到了任務的難度,也會激起自己的挑戰慾望和探索心理,進一步提升了遊戲性。
任務的需求就不多說了,先說下之前的SLG 遊戲的任務型別。
根據任務型別分為 主線任務,支線任務,公會任務,勢力任務,每日任務,還有各種不同的功能根據需求的任務型別
根據進度型別分為 累計型進度,遞減型進度,達到型進度,啟用型任務進度,自定義型別進度等等。
任務是遊戲裡比較複雜的系統,所以設計的時候應該儘可能的方便擴充套件,在增加任務的時候能簡單的設定出來。
總結下設計原則:儘可能的解決問題,如果特殊需求可以有介面簡單可以實現。
讓我們操練起來吧!
設定是基礎資料,是策劃設定的,因此最簡單的設定就是
任務id 一 任務達成條件一獎勵
任務id 是測試自己建立唯一的id,任務達成條件是在遊戲內任務的判斷條件,當達到條件的時候發給玩家獎勵。
根據任務的需求,我們對任務進行拆分。
根據進度型別進行拆分:
對任務拆分之後,現在得想辦法實現我們的任務系統了。
首先先解決任務進度定義的問題:
package org.pdool.task;
import com.google.common.base.Joiner;
public enum TaskProgress {
/**
* 格式:x_n
* 專指完成某一任務幾次(完成一次扣一次)
* eq:送花{n}次
*/
PROGRESS_TYPE1 {
@Override
public String checkProgress(int roleId, String config, String current, Object paramArr) {
String configId = config.split("_")[0];
Object[] ext = (Object[]) paramArr;
String param = ext[0].toString();
long var = Long.parseLong(param);
int needNum = Integer.parseInt(current.split("_")[1]);
if (needNum > var) {
return "";
}
return Joiner.on("_").join(configId, needNum - var);
}
},
;
/**
* 檢測任務進度
* @param roleId 玩家id
* @param config 設定的任務條件
* @param current 當前的任務進度
* @param param 傳進的引數
* @return 當前的任務進度
*/
public abstract String checkProgress(int roleId, String config, String current, Object param);
}
/**
* @author 香菜
*/
public enum TaskTypeEnum {
// 1:送花 eg:1_100
SEND_FLOWER_1(TaskProgressEnum.PROGRESS_TYPE1, "1"),
;
// 任務進度處理型別
private TaskProgressEnum progressType;
// 任務事件啟用型別
private String taskType;
TaskTypeEnum(TaskProgressEnum taskType, String actType) {
this.progressType = taskType;
this.taskType = actType;
}
public TaskProgressEnum getProgressType() {
return progressType;
}
public String getTaskType() {
return taskType;
}
}
策劃可以設定的任務就是 1_100 表示 送花100 次則完成任務。
舉個例子,我們的創角七日任務,在伺服器啟動的時候載入就載入基礎資料,並且註冊到每日任務的處理器上,這樣在有任務過來的,就不會分配到其他的任務上,因此我們實現一個處理器的抽象類,一個任務型別列舉。
/**
* @author 香菜
*/
public enum TaskHandlerEnum {
// 主線任務
MAIN_TASK(1),
// 日常任務
DAILY_TASK(2),
;
private int type;
public int getType() {
return type;
}
private TaskHandlerEnum(int type) {
this.type = (byte) type;
}
}
至少得三個方法,一個建構函式,一個handle方法,一個註冊方法。
/**
* @author 香菜
*/
public abstract class AbsTaskHandler {
public TaskHandlerEnum handlerEnum;
private Map<TaskTypeEnum, Set<Integer>> canHandMap = Maps.newHashMap();
public AbsTaskHandler(TaskHandlerEnum handlerEnum) {
this.handlerEnum = handlerEnum;
}
/**
* 註冊任務到處理器
* @param taskType
* @param taskId
*/
protected void registerTask(TaskTypeEnum taskType, int taskId) {
Set<Integer> taskIdSet = canHandMap.computeIfAbsent(taskType, k -> Sets.newHashSet());
taskIdSet.add(taskId);
}
/**
* 每種任務型別單獨實現
* @param roleId
* @param paramMap
*/
protected abstract void handle(int roleId, Map<TaskTypeEnum, Object> paramMap);
}
import java.util.Map;
public class MainTaskHandler extends AbsTaskHandler {
public MainTaskHandler(TaskHandlerEnum handlerEnum) {
super(handlerEnum);
}
@Override
protected void handle(int roleId, Map<TaskTypeEnum, Object> paramMap) {
// do what you want
}
}
Map<TaskHandlerEnum ,AbsTaskHandler> handlerMap
registTaskToHanlder(TaskHandlerEnum,TaskType,TaskId)
sendMsgToTask(TaskType,param)
遍歷所有的處理器,能處理這個這個任務,則處理,不能處理則過
由於任務系統的複雜性,設計上必然有一些挑戰,但是這種系統如果理解了,也都是套路的問題,做的久了自然而然就會了,並且可以根據需求自由的調整,理解最重要。
基本的介紹了任務系統的設計實現,後面一些沒有做具體的展示,大家可以自己發揮,如果覺得有困難,並且又感興趣的小夥伴可以聯絡我。或者你有其他的更好的設計我們可以一起交流。堅持寫不容易,希望能獲得大家的支援,點贊,轉發 三連,謝謝。