存储口袋妖怪类型游戏信息的最佳方式是什么?

4
所以,我开始为一个学校项目制作游戏。这是一个更简单的Pokemon版本,没有图形,只有文本。目前我的问题是我不知道如何储存所有Pokemon(每个人的状态),招式(他们的状态)等数据库。
每个Pokemon(151种不同的)都有特定的信息和每个移动(大约100个)也都有特定的信息。所以我不能真的做一个Pokemon类和继承于它的151个类。我可以做的是制作一个Pokemon和Moves类的数组,并且使Pokemon类(或移动类)的构造函数有统计数据。
我遇到的问题是要想把一只Pokemon(让我们随便选择Pikachu)给玩家(或敌人),并编辑那个Pokemon的统计数据、等级、经验等等。我不想改变游戏中每只Pikachu的等级,只想改变玩家的某只特定的Pikachu和敌人的某只特定的Pokemon。明白了吗?
我对Java还比较新,不确定该怎么做。我看到有些人试图做同样的事情,人们推荐使用XML之类的东西?但我想把它全部放在Java里面。

3
有人建议使用XML或其他什么东西?我想把所有东西都保留在Java中。 XML不是计算机语言的一种,所以您可以毫不犹豫地在这样的任务中使用它。 JSE有几个API用于处理(解析/编写)XML。 - Andrew Thompson
更一般地说:如果你正在做学校作业,不应该过于执着于“全部使用Java”而忽略了他人的建议。 - millimoose
+1 for title. 这可能有点过头,但考虑将数据存储在某种类型的嵌入式数据库中。比如Derby。 - Branislav Lazic
如果是我,我会只制作151个子类。如果使用数据库,仍需手动输入所有信息。如果是为了学校,你可以将可用数量减少到25或50个。 - Radiodef
我同意其他人的观点。你需要将每个“pokemon”存储到某种实体中。无论是子类、模型、数据库、XML文件还是JSON,都有很多方法可以实现。作为开发者,当你顺应潮流而不是逆行时,你的生活会变得更加轻松。 - snowYetis
显示剩余3条评论
6个回答

1
一种非常简单的解决方案是(伪代码)
class Pokemon:
   String name
   String/int... other_stats
   Array<Move> moves // This is a simple strategy to store any moves 
                     // you want to associate with this pokemon.

class Move:
   String name
   int power
   [...other move stats...]

为了给玩家一个宝可梦,您只需实例化一个新的宝可梦并命名(例如“皮卡丘”),然后实例化一些“移动”对象与您刚创建的宝可梦相关联。因此,例如:
ArrayList<Move> moves = new ArrayList<Move>();
moves.add( new Move("Thunderbolt", 16) );
moves.add( new Move("Foobar", 10) );
Pokemon pikachu = new Pokemon( "Pikachu", moves )
// and now you can give pikachu to any player you want.

你可以更改这个特定的皮卡丘,或者制作另一个皮卡丘,或者制作一只妙蛙种子送给其他玩家。
为了保存游戏状态,你可以有toString方法,以JSON/XML等格式输出该对象的属性,然后将它们保存在文本文件中。
这是一个相当简单的设计。当然,你可以像其他人建议的那样使用复杂的设计模式来增强功能。

1
“我遇到的难题是如何将一个 Pokemon(我们以 Pikachu 为例)分配给玩家(或我正在战斗的敌人)并编辑那个 Pokemon 的状态、等级、经验等。我不想改变游戏中所有 Pikachu 的等级,只想改变特定的 Pikachu 对于玩家和敌人而言。你明白我的意思吗?”

好吧,你需要在某个地方有一个 Pokemon 类,其中包含这些字段:

class PStats {
    int defense = 1;
    int attack = 1;
}

class Pokemon {
    int level = 1;
    long xp = 0;
    PStats stats = new PStats();
}

然后,您需要决定Pokemon的类型和潜在属性,无论是将Pokemon作为超类和子类化还是具有这些字段并从Java外部加载它们。
然后,您的玩家将拥有一个ArrayList,您将访问该列表。
如果您希望玩家能够保存游戏并加载他们的Pokemon,则必须发明一种简单的文件格式,并每次保存/加载。如果您想保存混合类型而不必自己进行所有字节格式化,则DataOutputStream和DataInputStream可能适用于此。
例如,您可能有一个文件结构看起来像这样:
header, UTF (8 bytes)     [FILE]
int, 4 bytes              [number of Pokemon]

1st Pokemon chunk id      [PKMN]
int, 4 bytes              [level]
long, 8 bytes             [experience]
                          [other fields...]

2nd Pokemon chunk id      [PKMN]
                          [level]
and so on...

您可以像这样创建一个简单的UTF头:

static final char[] PKMN {
    'P', 'K', 'M', 'N'
};

尽管通常标题/字段 ID 是 ASCII,您可以使用字节来实现:

static final byte[] PKMN {
    0x50, 0x4B, 0x4D, 0x4E
};

文件头可以自定义,以便识别您的文件,不要依赖于文件扩展名。

当您想保存文件时,只需遍历数组并将字段写入文件即可。然后,当您想从文件加载时,将具有以下基本结构:

// read header and anything else you put at the start of the file

while (/*next bytes are the PKMN id*/) {
    Pokemon pToAdd = new Pokemon();

    pToAdd.level = dis.readInt();
    pToAdd.xp = dis.readLong();

    // and so on

    playerPokemon.add(pToAdd);
}

重新创建玩家拥有的一切,通过根据文件指示创建对象。
如果您采用这种方式,我建议您在纸上勾画出文件结构,这样在编写IO时就可以把它放在面前。

0

将数据存储在代码之外可能更易于管理和更可取。为了简单起见,我建议使用文本文件。您可以为文件的每一行设置逗号分隔值。只需在其中存储宝可梦信息。

当程序加载时,请询问两个玩家想要成为哪个宝可梦角色。然后读取您的文本文件。当您读取到一个名称的行时,请解析数据并创建您的宝可梦类的实例,填充统计信息。

至于移动,只需进入循环,其中一个玩家移动,然后另一个玩家移动。每个移动都可以存储在数组中,作为Move对象,并带有该移动的统计信息。或者,如果您只想记录它,并且在执行移动后不需要对移动统计信息进行任何操作(宝可梦的位置已更改,或者可能会损坏宝可梦),则可以将移动信息写入文件而不是将对象放入数组中。同样,您可以将其仅存储为每个移动的逗号分隔值的行。


0

你可以将每个皮卡丘都变成事件驱动的。

从基本的皮卡丘开始,记录每一个影响其属性、等级、经验等的事件。当你想要使用某个属性时,重新播放这些事件。只需为每个实例将它们放入列表中即可。

如果性能是一个问题,那么你可以为每个皮卡丘关联一个“快照”,如果发生任何更多的事件,则该快照将无效,并根据需要重新计算。

你甚至可以通过将这些事件与每个皮卡丘的身份关联来持久化它们。

(请注意,我对宠物小精灵一无所知。)


0

你应该了解策略, 抽象工厂和访问者3设计模式。

对于你的宝可梦来说,它可以使用不同的攻击方式并产生不同的效果是很常见的。这意味着攻击的逻辑相当复杂,并且取决于发起攻击者和被攻击者。你可以使用策略模式来解决这个问题。

此外,你还需要扩展生物来执行一些动作,这可以通过使用访问者模式来实现。

最后,你将根据一些经验来设置生物。给它们特殊的攻击或形态。在这里,你可以使用抽象工厂。


0

我正在做一个类似的项目,只是它是一款2D口袋妖怪游戏,具有基于Archon的战斗序列。我也在努力存储口袋妖怪的唯一值。我想出了两个解决方案,但我不确定哪个更有效。

解决方案1:许多类都继承自抽象的Pokemon类,其中包含基本值,如类型、hp、级别和统计数据,但是它们各自填充。

解决方案2:(我正在尝试)一个通用的Pokemon类,它具有独特的枚举作为标识符。该枚举标识特定的口袋妖怪并搜索JDBC Derby数据库以获取值。例如:

public enumeration PokeId{
    Pikachu(),
    Mew(),
    Ditto();
}

public class Pokemon{

   private PokeId id;

   public Pokemon(PokeId id){
      this.id = id;
      if(id == PokeId.Pikachu){
         //load from derby

      }
   }

}

我不确定哪个方法会更有效。希望这能帮到你们,我很乐意参与进一步开发类似于这样的代码。 谢谢!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接