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

时间:2022-09-16 14:17:57

So I have started making a game for a school project. It is a simpler version of Pokemon without graphics, just text. Currently my problem is I do not know how I would store a database of all the Pokemon (with each individual stat), moves (with their stats), etc.

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

Each Pokemon (151 different) has stats and specific info about each and each move (around 100) has specific stats and info too. So I can't really make a Pokemon class and 151 classes that extend from it. What I could do is make an array of Pokemon and Moves classes and have the constructor of a Pokemon class (or move class) have the stats.

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

What I am having trouble is figuring out how to give a Pokemon (lets roll with Pikachu) to the player (or enemy that I am battling) and edit the stats, level, experience, etc of that one Pokemon. I don't want to change the level of every Pikachu in the game, just a specific Pikachu for the player and a specific Pokemon for the enemy. Does that make sense?

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

I'm new-ish to Java and I'm not sure what I would do. I have seen some people try to do the same thing and people recommend using XML or something? I'm trying to keep it all within Java.

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

6 个解决方案

#1


1  

A very simple solution would be (pseudo code)

一个非常简单的解决方案是(伪代码)

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...]

To give a Pokemon to a player, you'd simply instantiate a new Pokemon with a name (such as "Pikachu"), and you would then instantiate some "Move" objects to associate with the Pokemon you just created. So, for example:

为了给玩家提供一个神奇宝贝,你只需要实例化一个带有名字的新口袋妖怪(例如“皮卡丘”),然后你会实例化一些“移动”对象以与刚刚创建的神奇宝贝相关联。所以,例如:

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.

You can change anything for this particular Pikachu, or you can make another Pikachu, or a Bulbasaur to give to another player.

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

To save a game state, you can have toString methods that output that object's properties in JSON/XML whatever, and you can then save those in a text file.

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

This is a fairly simple design. You can, of course, use complex design patterns as others have suggested to enhance functionality.

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

#2


1  

"What I am having trouble is figuring out how to give a Pokemon (lets roll with pikachu) to the player (or enemy that I am battling) and edit the stats, level, experience, ect of that ONE Pokemon. I don't want to change the level of every pikachu in the game, just a specific pikachu for the player and a specific Pokemon for the enemy. Does that make sense?"

“我遇到麻烦的是弄清楚如何给玩家(或者我正在与之战斗的敌人)一个神奇宝贝(让皮卡丘滚动)并编辑那个神奇宝贝的统计数据,等级,经验等等。我不知道我希望改变游戏中每个皮卡丘的等级,只为玩家提供一个特定的皮卡丘,为敌人设置一个特定的神奇宝贝。这有意义吗?“

Well you'll have a Pokemon class somewhere with these kinds of fields:

那么你会在这些领域的某个地方有一个Pokemon类:

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

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

Then somehow you decide the type and potential attributes of the Pokemon, whether you make Pokemon a superclass and subclass it or have fields for these things and load them from outside Java.

然后以某种方式决定Pokemon的类型和潜在属性,无论你是将Pokemon作为超类并将其子类化,还是拥有这些东西的字段并从Java外部加载它们。

Then your player will have an ArrayList that you will be accessing.

然后你的播放器将有一个你将访问的ArrayList。

If you want the player to be able to save the game and load their Pokemon you'll have to invent a simple file format and save/load each time. DataOutputStream and DataInputStream are maybe suited to this if you want to save mixed types without doing all the formatting to bytes yourself.

如果您希望玩家能够保存游戏并加载他们的宠物小精灵,您将不得不发明一种简单的文件格式并每次保存/加载。如果要保存混合类型而不自行完成所有格式化操作,DataOutputStream和DataInputStream可能适用于此。

As an example maybe you have a file structure that looks like this:

举个例子,你可能有一个如下所示的文件结构:

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

Where you can make a simple UTF header like so:

你可以在哪里制作一个简单的UTF标题:

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

Though typically headers/field id are ASCII and you can do that with bytes:

虽然通常标头/字段ID是ASCII,您可以使用字节来执行此操作:

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

And the FILE header is whatever you want it to be to identify your files so you don't rely on the extension.

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

When you want to save the file you will just loop through the array and write the fields to the file. Then when you want to load from a file you will have a basic structure something like this:

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

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

Recreating everything the player has by creating the objects from what the file indicates.

通过从文件指示的内容创建对象来重新创建玩家所拥有的一切。

If you do it this way I'd recommend sketching out your file structure on a piece of paper so you have it in front of you when you are coding your IO.

如果你这样做,我建议你在一张纸上勾勒出你的文件结构,这样你在编写IO时就可以把它放在你面前。

#3


0  

It's probably more manageable and desirable to store your data outside of the code. To keep it simple, I'd suggest a text file. You can have comma-separated values for each line of the file. Just store the pokemon info in there.

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

When the program loads up, ask the two players what pokemon characters they want to be. Then read your text file in. When you read a line with one of the names, parse out the data and create an instance of your pokemon class, filling in the stats.

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

As for moves, just go into a loop, where one player moves, then the other. Each move can be stored in an array, as a Move object, with the stats for that move. Or, if you just want to log it, and you don't need to do anything with the move stats once the move is acted on (pokemon's position has changed, or perhaps a pokemon is damaged), then you can instead write the move info to a file rather than putting the object into an array. Again, you can just store it as comma separated values in a line per move.

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

#4


0  

You could always make each Pikachu event-driven.

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

Start with the basic Pikachu, then record every event that happens which affects the stats, level, experience, etc. When you want to actually use an attribute, replay the events. Just chuck 'em in a list for each instance.

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

If performance is an issue then you can have a "snapshot" associated with the individual Pikachu, which is invalidated if any more events happen and recalculated as required.

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

You can even persist those events by associating them with an individual Pikachu's identity.

你甚至可以通过将这些事件与皮卡丘的个人身份联系起来来坚持这些事件。

(Note that I know nothing about Pokemon.)

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

#5


0  

You should read about strategy, abstract factory and visitor3 design patterns.

您应该阅读有关策略,抽象工厂和visitor3设计模式的内容。

What is common for your Pokemon is that it can perform different attack with different result. This mean the logic of an attack its quite complicated and depend on the attacker and victim. You can sole this using strategy pattern.

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

Additionally you will have to extend the creature do perform some actions, this can be achieved using Vistor pattern.

此外,你必须扩展生物做一些动作,这可以使用Vistor模式来实现。

At the end you will have to setup the creature depending on some experience that has. Give them special attacks or form. here you could use the abstract factory.

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

#6


0  

I am doing a similar project except it is a 2D Pokemon with a Archon based battle sequence. I am also struggling with storing unique values of the Pokemon. I have come up with two solutions, though i am not sure which is more effective.

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

Solution 1: Many, many classes which all extend the abstract Pokemon class which contains basic values such as type, hp, level, stats but fills them individually

解决方案1:许多很多类都扩展了抽象的Pokemon类,它包含类型,hp,level,stats等基本值,但是单独填充它们

Solution 2: (what i am trying) A generic Pokemon class which has a distinct enumeration as an id. The enumeration identifies the specific pokemon and searches a JDBC derby database for values. As an example:

解决方案2 :(我正在尝试的)一个通用的Pokemon类,它有一个不同的枚举作为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

      }
   }

}

I am not sure which is going to be more effective. I hope this helped some and i would love to collaborate on further development of code like this. Thanks!

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

#1


1  

A very simple solution would be (pseudo code)

一个非常简单的解决方案是(伪代码)

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...]

To give a Pokemon to a player, you'd simply instantiate a new Pokemon with a name (such as "Pikachu"), and you would then instantiate some "Move" objects to associate with the Pokemon you just created. So, for example:

为了给玩家提供一个神奇宝贝,你只需要实例化一个带有名字的新口袋妖怪(例如“皮卡丘”),然后你会实例化一些“移动”对象以与刚刚创建的神奇宝贝相关联。所以,例如:

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.

You can change anything for this particular Pikachu, or you can make another Pikachu, or a Bulbasaur to give to another player.

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

To save a game state, you can have toString methods that output that object's properties in JSON/XML whatever, and you can then save those in a text file.

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

This is a fairly simple design. You can, of course, use complex design patterns as others have suggested to enhance functionality.

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

#2


1  

"What I am having trouble is figuring out how to give a Pokemon (lets roll with pikachu) to the player (or enemy that I am battling) and edit the stats, level, experience, ect of that ONE Pokemon. I don't want to change the level of every pikachu in the game, just a specific pikachu for the player and a specific Pokemon for the enemy. Does that make sense?"

“我遇到麻烦的是弄清楚如何给玩家(或者我正在与之战斗的敌人)一个神奇宝贝(让皮卡丘滚动)并编辑那个神奇宝贝的统计数据,等级,经验等等。我不知道我希望改变游戏中每个皮卡丘的等级,只为玩家提供一个特定的皮卡丘,为敌人设置一个特定的神奇宝贝。这有意义吗?“

Well you'll have a Pokemon class somewhere with these kinds of fields:

那么你会在这些领域的某个地方有一个Pokemon类:

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

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

Then somehow you decide the type and potential attributes of the Pokemon, whether you make Pokemon a superclass and subclass it or have fields for these things and load them from outside Java.

然后以某种方式决定Pokemon的类型和潜在属性,无论你是将Pokemon作为超类并将其子类化,还是拥有这些东西的字段并从Java外部加载它们。

Then your player will have an ArrayList that you will be accessing.

然后你的播放器将有一个你将访问的ArrayList。

If you want the player to be able to save the game and load their Pokemon you'll have to invent a simple file format and save/load each time. DataOutputStream and DataInputStream are maybe suited to this if you want to save mixed types without doing all the formatting to bytes yourself.

如果您希望玩家能够保存游戏并加载他们的宠物小精灵,您将不得不发明一种简单的文件格式并每次保存/加载。如果要保存混合类型而不自行完成所有格式化操作,DataOutputStream和DataInputStream可能适用于此。

As an example maybe you have a file structure that looks like this:

举个例子,你可能有一个如下所示的文件结构:

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

Where you can make a simple UTF header like so:

你可以在哪里制作一个简单的UTF标题:

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

Though typically headers/field id are ASCII and you can do that with bytes:

虽然通常标头/字段ID是ASCII,您可以使用字节来执行此操作:

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

And the FILE header is whatever you want it to be to identify your files so you don't rely on the extension.

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

When you want to save the file you will just loop through the array and write the fields to the file. Then when you want to load from a file you will have a basic structure something like this:

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

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

Recreating everything the player has by creating the objects from what the file indicates.

通过从文件指示的内容创建对象来重新创建玩家所拥有的一切。

If you do it this way I'd recommend sketching out your file structure on a piece of paper so you have it in front of you when you are coding your IO.

如果你这样做,我建议你在一张纸上勾勒出你的文件结构,这样你在编写IO时就可以把它放在你面前。

#3


0  

It's probably more manageable and desirable to store your data outside of the code. To keep it simple, I'd suggest a text file. You can have comma-separated values for each line of the file. Just store the pokemon info in there.

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

When the program loads up, ask the two players what pokemon characters they want to be. Then read your text file in. When you read a line with one of the names, parse out the data and create an instance of your pokemon class, filling in the stats.

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

As for moves, just go into a loop, where one player moves, then the other. Each move can be stored in an array, as a Move object, with the stats for that move. Or, if you just want to log it, and you don't need to do anything with the move stats once the move is acted on (pokemon's position has changed, or perhaps a pokemon is damaged), then you can instead write the move info to a file rather than putting the object into an array. Again, you can just store it as comma separated values in a line per move.

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

#4


0  

You could always make each Pikachu event-driven.

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

Start with the basic Pikachu, then record every event that happens which affects the stats, level, experience, etc. When you want to actually use an attribute, replay the events. Just chuck 'em in a list for each instance.

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

If performance is an issue then you can have a "snapshot" associated with the individual Pikachu, which is invalidated if any more events happen and recalculated as required.

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

You can even persist those events by associating them with an individual Pikachu's identity.

你甚至可以通过将这些事件与皮卡丘的个人身份联系起来来坚持这些事件。

(Note that I know nothing about Pokemon.)

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

#5


0  

You should read about strategy, abstract factory and visitor3 design patterns.

您应该阅读有关策略,抽象工厂和visitor3设计模式的内容。

What is common for your Pokemon is that it can perform different attack with different result. This mean the logic of an attack its quite complicated and depend on the attacker and victim. You can sole this using strategy pattern.

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

Additionally you will have to extend the creature do perform some actions, this can be achieved using Vistor pattern.

此外,你必须扩展生物做一些动作,这可以使用Vistor模式来实现。

At the end you will have to setup the creature depending on some experience that has. Give them special attacks or form. here you could use the abstract factory.

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

#6


0  

I am doing a similar project except it is a 2D Pokemon with a Archon based battle sequence. I am also struggling with storing unique values of the Pokemon. I have come up with two solutions, though i am not sure which is more effective.

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

Solution 1: Many, many classes which all extend the abstract Pokemon class which contains basic values such as type, hp, level, stats but fills them individually

解决方案1:许多很多类都扩展了抽象的Pokemon类,它包含类型,hp,level,stats等基本值,但是单独填充它们

Solution 2: (what i am trying) A generic Pokemon class which has a distinct enumeration as an id. The enumeration identifies the specific pokemon and searches a JDBC derby database for values. As an example:

解决方案2 :(我正在尝试的)一个通用的Pokemon类,它有一个不同的枚举作为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

      }
   }

}

I am not sure which is going to be more effective. I hope this helped some and i would love to collaborate on further development of code like this. Thanks!

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