4

所以我开始为学校项目制作游戏。这是一个更简单的口袋妖怪版本,没有图形,只有文字。目前我的问题是我不知道如何存储所有口袋妖怪(每个单独的统计数据)、移动(及其统计数据)等的数据库。

每个口袋妖怪(151 个不同)都有关于每个动作的统计数据和特定信息(大约 100 个)也有特定的统计数据和信息。所以我不能真正制作一个 Pokemon 类和从它扩展的 151 个类。我能做的是制作一组 Pokemon 和 Moves 类,并让 Pokemon 类(或 move 类)的构造函数具有统计信息。

我遇到的麻烦是弄清楚如何将口袋妖怪(让我们与皮卡丘一起滚动)给玩家(或我正在战斗的敌人)并编辑那个口袋妖怪的统计数据、等级、经验等。我不想改变游戏中每个皮卡丘的等级,只是给玩家一个特定的皮卡丘,给敌人一个特定的口袋妖怪。那有意义吗?

我是 Java 新手,我不确定我会做什么。我看到有些人尝试做同样的事情,人们建议使用 XML 或其他东西?我试图将它全部保留在 Java 中。

4

6 回答 6

1

“我遇到的麻烦是弄清楚如何将口袋妖怪(让皮卡丘滚动)给玩家(或我正在战斗的敌人)并编辑那个口袋妖怪的统计数据、等级、经验等。我不想改变游戏中每一个皮卡丘的等级,只给玩家一个特定的皮卡丘,给敌人一个特定的口袋妖怪。这有意义吗?”

好吧,您将在某个地方拥有一个带有这些字段的 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。

如果您希望玩家能够保存游戏并加载他们的口袋妖怪,您必须发明一种简单的文件格式并每次都保存/加载。如果您想保存混合类型而不自己对字节进行所有格式化,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
};

并且 FILE 标头是您想要识别文件的任何内容,因此您不依赖扩展名。

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

// 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 时将其放在您面前。

于 2013-10-28T00:03:33.337 回答
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...]

要将 Pokemon 提供给玩家,您只需用名称(例如“Pikachu”)实例化一个新的 Pokemon,然后实例化一些“Move”对象以与您刚刚创建的 Pokemon 相关联。因此,例如:

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.

你可以为这个特定的皮卡丘改变任何东西,或者你可以制作另一个皮卡丘,或者一个 Bulbasaur 给另一个玩家。

要保存游戏状态,您可以使用 toString 方法以 JSON/XML 格式输出该对象的属性,然后您可以将它们保存在文本文件中。

这是一个相当简单的设计。当然,您可以使用其他人建议的复杂设计模式来增强功能。

于 2013-10-27T23:55:02.933 回答
0

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

当程序加载时,询问两位玩家他们想成为什么口袋妖怪角色。然后读入您的文本文件。当您读取包含其中一个名称的行时,解析数据并创建口袋妖怪类的实例,并填写统计信息。

至于移动,只需进入一个循环,一个玩家移动,然后另一个玩家移动。每个动作都可以存储在一个数组中,作为一个 Move 对象,其中包含该动作的统计信息。或者,如果您只是想记录它,并且一旦采取行动(口袋妖怪的位置已经改变,或者口袋妖怪被损坏),您不需要对移动统计数据做任何事情,那么您可以改为编写移动信息到文件中,而不是将对象放入数组中。同样,您可以将其作为逗号分隔值存储在每次移动的一行中。

于 2013-10-27T23:15:52.350 回答
0

你总是可以让每个皮卡丘事件驱动。

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

如果性能是一个问题,那么您可以拥有与单个皮卡丘相关的“快照”,如果发生更多事件并根据需要重新计算,则该快照无效。

您甚至可以通过将这些事件与单个皮卡丘的身份相关联来保持这些事件。

(请注意,我对口袋妖怪一无所知。)

于 2013-10-27T23:16:01.457 回答
0

你应该阅读策略抽象工厂和访问者3设计模式。

你的口袋妖怪的共同点是它可以执行不同的攻击并产生不同的结果。这意味着攻击的逻辑非常复杂,并且取决于攻击者和受害者。你可以使用策略模式来解决这个问题。

此外,您必须扩展该生物执行一些操作,这可以使用 Vistor 模式来实现。

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

于 2013-10-27T23:19:43.257 回答
0

我正在做一个类似的项目,除了它是一个基于执政官的战斗序列的 2D 口袋妖怪。我也在努力存储口袋妖怪的独特价值。我想出了两个解决方案,但我不确定哪个更有效。

解决方案 1:很多很多类都扩展了抽象 Pokemon 类,其中包含基本值,如类型、hp、级别、统计信息,但单独填充它们

解决方案2:(我正在尝试)一个通用的口袋妖怪类,它有一个独特的枚举作为id。枚举识别特定的 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

      }
   }

}

我不确定哪个会更有效。我希望这对一些人有所帮助,我很乐意合作进一步开发这样的代码。谢谢!

于 2016-05-20T16:24:21.807 回答