Java 如何设计一个易于扩展的游戏任务系统?
解释 假设我们有多个任务,完成某项任务后奖励玩家。以下示例显示了用户任务:Java 如何设计一个易于扩展的游戏任务系统?,java,php,oop,database-design,Java,Php,Oop,Database Design,解释 假设我们有多个任务,完成某项任务后奖励玩家。以下示例显示了用户任务: Name: Get a high score of 100 Requirement: Score of 100 Reward: 10 Coins Name: Get a high score of 5000 Requirement: Score of 5000 Reward: 10 Diamonds Name: Destroy 20 ships Requirement: Destroy 20 ships Reward
Name: Get a high score of 100
Requirement: Score of 100
Reward: 10 Coins
Name: Get a high score of 5000
Requirement: Score of 5000
Reward: 10 Diamonds
Name: Destroy 20 ships
Requirement: Destroy 20 ships
Reward: 5 Diamonds
Name: Reach level 5
Requirement: Level 5
Reward: 20 Coins, 10 Diamonds
然后我创建以下逻辑:
创建一个名为“Quest”的超类。
为每个任务创建一个子类;继承“任务”超类。
使用多态性,我们调用“CheckForCompletion”方法来检查任务需求是否得到满足。如果是这样,用户将获得奖励
问题
我的问题是我是否创建了一个名为“任务”的数据库表,并将上面的每个任务存储在表中
任务表数据示例:
名称:摧毁20艘船
要求:{“销毁”,“20”}
奖励:{“钻石”,“5”}
如果是这样,将每个任务加载到相应的类中的最佳方法是什么
或
我是否为每个任务创建一个类而不创建任务表?如果是这样的话,我怎么知道用户何时完成任务,这样用户就不会获得两次奖励
我知道我可以创建一个表并存储必要的需求。然后让一个类包含一堆if语句来执行正确的代码,但我觉得这并不正确。我要问的是;有更好的方法吗
谢谢
编辑1:
每个任务可以有多个需求。例如:摧毁5艘船,杀死10个单位,得分1000等
为了进一步解释want,我想消除if语句。我不想做这样的陈述
if (score == 100)
//process
else if (ships_destroyed == 5)
//process
else if (level == 5)
//process
else if (ships_destroyed == 5 && units_killed == 10 && score == 1000)
//process
我希望消除这个过程,因为我可能有数百个任务,我不认为它扩展得足够容易。有更好的方法吗?我有类似的要求:在游戏中添加成就/徽章 你应该考虑:
interface Precondition {
String type()
boolean check(Map<String, Object> config, Long userId);
}
class DestroyShipPrecondition{
public String type() {
return "destroy_ship"
}
public boolean check(Map<String, Object> config, Long userId){
Long expectdAmount = config.get("amount");
Long realAmount = getDestroyedShipsByUser(userId);
return expectedAmount<=realAmount;
}
}
我有类似的要求:在游戏中添加成就/徽章 你应该考虑:
interface Precondition {
String type()
boolean check(Map<String, Object> config, Long userId);
}
class DestroyShipPrecondition{
public String type() {
return "destroy_ship"
}
public boolean check(Map<String, Object> config, Long userId){
Long expectdAmount = config.get("amount");
Long realAmount = getDestroyedShipsByUser(userId);
return expectedAmount<=realAmount;
}
}
你的问题有几个相关的方面——和往常一样,答案是“视情况而定” 首先,我建议不要将你的“任务”类划分为子类——当然,这不是黑白的,但总的来说,我赞成 如果您确信游戏机制不会改变,我就不必为数据库表操心了——我会在您的编程语言(Java或PHP)中使用常量。从开发和性能的角度来看,在数据库中查找静态数据是非常昂贵的 如果你认为在调整游戏时这些数据可能需要改变,那么这可能太有限了——每次你想调整任务奖励的时候都要做一个完整的构建会让你很难获得正确的平衡。在这种情况下,我会使用一个配置文件——数据会发生变化,但只有在游戏开始时,而不是在游戏运行时 如果您的游戏机制要求在游戏期间更改奖励,并且这是一个多人游戏,那么您可能需要使用数据库
最后,大多数游戏引擎都满足了这种需求——也许你的计划有些过火,但值得考虑。你的问题有几个相关方面——和往常一样,答案是“视情况而定” 首先,我建议不要将你的“任务”类划分为子类——当然,这不是黑白的,但总的来说,我赞成 如果您确信游戏机制不会改变,我就不必为数据库表操心了——我会在您的编程语言(Java或PHP)中使用常量。从开发和性能的角度来看,在数据库中查找静态数据是非常昂贵的 如果你认为在调整游戏时这些数据可能需要改变,那么这可能太有限了——每次你想调整任务奖励时都要进行完整的构建,这将很难达到平衡
public class Game {
public static class GameState {
public int playerscore = 1750;
}
public enum Quest {
FIVE_HUNDRED_PT(
(GameState gamestate) -> gamestate.playerscore > 500,
() -> Game.trigger500pointHurray()
),
FIVE_THOUSAND_PT(
(GameState gamestate) -> gamestate.playerscore > 5000,
() -> Game.trigger5000pointHurray()
);
private final Function<GameState, Boolean> trigger;
private final Runnable action;
Quest(Function<GameState, Boolean> trigger, Runnable action) {
this.trigger = trigger;
this.action = action;
}
}
public static void gameloop(GameState state) {
// Do all game logic.
for (Quest q : Quest.values())
if (q.trigger.apply(state))
q.action.run();
}
public static void trigger500pointHurray() {
System.out.println("Hurray x500");
}
public static void trigger5000pointHurray() {
System.out.println("Hurray x5000");
}
public static void main(String[] args) {
gameloop(new GameState());
}
}