遊戲任務系統太複雜,帶你一步一步實現

2020-09-28 12:01:54

 

目錄

        1、任務的分類.

2、基礎資料的定義

3、系統的設計

4、show me the fuck code !

1.任務進度定義:

2.定義任務型別列舉

3.定義任務模組列舉

4.定義任務處理器的抽象類

5.實現主線任務處理類

6.在伺服器啟動的時候將所有的處理器加入到map

7.伺服器啟動後載入基礎資料,將對應的任務註冊到對應的處理器

8.通知任務系統做檢測

5、總結


前言:一直在寫Java 方面的,今天寫一寫遊戲設計方面的 一任務系統。任務系統是每個任務的標配,不管是普通的小遊戲,還是大型的端遊,手遊,沒了任務系統的遊戲是不完整的。任務系統是遊戲的驅動,是玩家的目標,有了目標才會有追求,正常完成任務都會獲得獎勵,有糖吃,開心。

  任務其實本身就是一種「激勵制度」,接受任務-進行挑戰-完成獎勵,這個過程中的每一個環節,都是對玩家遊戲的激勵,所以任務在其中就起著這樣的這樣的作用。對於玩家自身來說,從心理學上,完成任務是對自己挑戰的肯定,會大大增加玩家遊戲的滿足感,即使沒有順利完成某一項任務,玩家感受到到了任務的難度,也會激起自己的挑戰慾望和探索心理,進一步提升了遊戲性。

1、任務的分類.

任務的需求就不多說了,先說下之前的SLG 遊戲的任務型別。

根據任務型別分為 主線任務,支線任務,公會任務,勢力任務,每日任務,還有各種不同的功能根據需求的任務型別

根據進度型別分為 累計型進度,遞減型進度,達到型進度,啟用型任務進度,自定義型別進度等等。

任務是遊戲裡比較複雜的系統,所以設計的時候應該儘可能的方便擴充套件,在增加任務的時候能簡單的設定出來。

總結下設計原則:儘可能的解決問題,如果特殊需求可以有介面簡單可以實現。

讓我們操練起來吧!

2、基礎資料的定義

設定是基礎資料,是策劃設定的,因此最簡單的設定就是

任務id 一 任務達成條件一獎勵

任務id 是測試自己建立唯一的id,任務達成條件是在遊戲內任務的判斷條件,當達到條件的時候發給玩家獎勵。

3、系統的設計

根據任務的需求,我們對任務進行拆分。

根據進度型別進行拆分:

4、show me the fuck code !

對任務拆分之後,現在得想辦法實現我們的任務系統了。

首先先解決任務進度定義的問題:

1.任務進度定義:

 
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);
}

2.定義任務型別列舉

 
/**
* @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 次則完成任務。

3.定義任務模組列舉

舉個例子,我們的創角七日任務,在伺服器啟動的時候載入就載入基礎資料,並且註冊到每日任務的處理器上,這樣在有任務過來的,就不會分配到其他的任務上,因此我們實現一個處理器的抽象類,一個任務型別列舉。


/**
* @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;
  }
}

4.定義任務處理器的抽象類

至少得三個方法,一個建構函式,一個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);
}

5.實現主線任務處理類


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
  }
}

6.在伺服器啟動的時候將所有的處理器加入到map

Map<TaskHandlerEnum ,AbsTaskHandler>  handlerMap

7.伺服器啟動後載入基礎資料,將對應的任務註冊到對應的處理器

registTaskToHanlder(TaskHandlerEnum,TaskType,TaskId)

8.通知任務系統做檢測

sendMsgToTask(TaskType,param)

遍歷所有的處理器,能處理這個這個任務,則處理,不能處理則過

5、總結

 由於任務系統的複雜性,設計上必然有一些挑戰,但是這種系統如果理解了,也都是套路的問題,做的久了自然而然就會了,並且可以根據需求自由的調整,理解最重要。

 基本的介紹了任務系統的設計實現,後面一些沒有做具體的展示,大家可以自己發揮,如果覺得有困難,並且又感興趣的小夥伴可以聯絡我。或者你有其他的更好的設計我們可以一起交流。堅持寫不容易,希望能獲得大家的支援,點贊,轉發 三連,謝謝。