帮助程序设计

发布于 2024-10-04 04:37:45 字数 819 浏览 3 评论 0原文

我目前正在创建一个简单的基于控制台的游戏,玩家可以在不同的房间之间移动、拾取和使用物品以及吃食物。在游戏目前的状态下,就是这样。

我需要帮助的是:

为我的游戏创建一个好的“Event”类。我希望它的工作方式是每个项目和房间都应该能够与事件关联。

由于我是新手,我希望能获得与此类程序相关的任何阅读材料,或者关于如何考虑以下几点最好地设置我的课程的建议,或者简单地如何解决此类问题(即难以决定如何设置类)

我希望能够创建不同类型的事件,例如:

  • 输出一些文本,然后向玩家提问。如果玩家给出了正确的答案,则执行某些操作。

  • 输出一些文本,然后从玩家的库存中删除一个项目,然后将玩家移动到另一个房间。

我试图避免的:

  • 游戏的重点是练习良好的类设计,因此责任驱动设计、内聚性和耦合等都是重要的方面。因此我希望它尽可能简单、可重用和独立。

  • 必须对每个事件进行硬编码,以便项目或房间只需调用 Event 类中的特定方法。

我现在在想什么:

创建一些子类,以便我可以使用以下方法创建新事件(并将它们关联起来): itemObject.setEvent(new Event(new Question("introText", "outroText", " CorrectAnswer")));

如果需要更多信息,请告诉我! 谢谢!

I'm currently creating a simple console-based game in which the player can move between different rooms, pick up and use items, and eat food. In the game's current state that's about it.

What I need help with is:

Creating a good "Event" class for my game. The way I'd like it to work is that every item and room should be able to be associated with an Event.

As I'm new to this I'd appreciate any reading material related to this kind of procedure, or suggestions as to how it would be best to set up my class(es) considering the points below, or simply how to attack this kind of problem (that is having trouble deciding how to set up classes).

I want to be able to create different kinds of events, for example:

  • Output some text, and then ask the player a question. If the player gives the correct answer, do something.

  • Output some text, then remove an item from the player's inventory, and then move the player to another room.

What I'm trying to avoid:

  • The entire point of the game is to practice good class design, so things such as responsibility-driven design, cohesion and coupling are important aspects. Thus I want it to be as simple, reusable and independent as possible.

  • Having to hard-code every event so that an item or room simply calls a specific method in the Event class.

What I'm thinking at the moment:

Creating a few sub-classes so that I could for example create new events (and associate them) using:
itemObject.setEvent(new Event(new Question("introText", "outroText", "correctAnswer")));

Please let me know if more info is needed!
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

近箐 2024-10-11 04:37:45

《游戏编程宝石》书籍很棒……尽管有点贵。

您可能可以在GameDev 的文章列表上找到一两篇相关文章,并且可能埋藏着一些好东西他们的论坛

对于 Event 类,您几乎肯定需要一个带有一定数量子类的基类(移动事件、库存事件等)。如果您确实想要避免硬编码,您应该在数据文件中定义您的游戏。房间、物品和活动……以及您稍后添加的任何其他内容。用于定义事物的格式完全取决于您。我推荐一些可以给您带来实践经验的东西,因为这是一个学习练习:例如您没有使用过的 XML 解析器。这不是最有效的解析格式,但这是一个控制台游戏,所以这不是一个问题。

我对事件子类的一个建议是可以将其他事件链接在一起。界面不会改变,它允许你执行诸如“将其添加到玩家的库存中,将其拿走,并将它们移到此处”之类的操作。

The Game Programming Gems books are great... though a bit pricey.

You can probably find a relevant article or two over on GameDev's Article list, and there's probably some good stuff buried in their forums

As for an Event class, you almost certainly want a base class with some number of subclasses (MoveEvent, InventoryEvent, etc). And if you really want to avoid hardcoding things, you should define your game in data files. Rooms, items, and events... plus anything else you tack on later. The format you use to define things is entirely up to you. I recommend something that will give you practical experience as this is a learning exercise: an XML parser you haven't used for example. Not the most efficient format to parse, but this is a console game, so that's not such an issue.

One suggestion I have for an Event subclass would be one that can chain other events together. The interface doesn't change, and it allows you to do things like "add this to the player's inventory, take that away, AND move them over here".

囍笑 2024-10-11 04:37:45

我要考虑的一件事是将输入文本的解析和输出文本的生成与底层域模型分开。您的问题似乎将两者混合在一起,而我将问题的文本部分视为表示层。

例如,您的域可以包含以下接口:

public enum Action { HIT, TALK_TO, EAT, USE };

public interface GameEntity {
  /**
   * Performs the specified action on this GameEntity, passing in zero or
   * more other GameEntity instances as parameters.
   */
  void applyAction(Action action, GameEntity... params);    
}

public interface Item extends GameEntity { }
public interface Person extends GameEntity { }

此外,您可以定义一个 TextParser 类,该类将处理输入字符串并对域层进行最终调用,或者返回默认响应:“我不明白。”。例如,输入短语“use key ondoor”将导致方法调用:

key.applyAction(Action.USE, door);

One thing I would consider is separating the parsing of input text and generation of output text from the underlying domain model. Your question appears to mix the two together whereas I would consider the text portion of the problem as the presentation layer.

For example, your domain could consist of the following interfaces:

public enum Action { HIT, TALK_TO, EAT, USE };

public interface GameEntity {
  /**
   * Performs the specified action on this GameEntity, passing in zero or
   * more other GameEntity instances as parameters.
   */
  void applyAction(Action action, GameEntity... params);    
}

public interface Item extends GameEntity { }
public interface Person extends GameEntity { }

In addition you could define a TextParser class that would process the input string and make resulting calls to the domain layer or else return a default response: "I do no understand.". For example, the input phrase "use key on door" would result in the method call:

key.applyAction(Action.USE, door);
我不是你的备胎 2024-10-11 04:37:45

当谈到事件时,我们会想到观察者模式。您可以认为您的游戏是由多个状态机在内部呈现的(您也可以在维基百科上查找这一点,由于对 SO 不熟悉,我自己无法添加第二个链接)。从一个阶段到另一个阶段的每次转换都是一个事件,可以将其传达给该事件的注册观察者。

例如:

使用钥匙开锁:触发拔出钥匙并打开门;隐式“级联”到下一个事件,无需额外的用户交互(打开门):触发具有额外出口等的房间。

When speaking of events the observer pattern comes to mind. You can think of your game to be internally presented by several state machines (you can look this up at Wikipedia, too, I can't add 2nd link myself due to being new to SO). Each transition from one stage to another is an event that can be communicated to registered oberservers of that event.

At example:

USE KEY ON LOCK: triggers removal of key and opening of door; implictly "cascading" to next event without additonal user interaction (opening of door): triggers room having additional exit etc.

尐籹人 2024-10-11 04:37:45

我最近实现了与您所描述的类似的东西。我首先创建一个具有“发布”和“订阅”方法的 EventManager 类。当系统启动时,它会扫描所有加载的程序集(库)以查找实现 IEventListener 接口的类:

/// <summary>
/// A class that intends to listen for specific events to be published by an
/// event manager.
/// <see cref="EventManager"/>
/// </summary>
public interface IEventListener
{
    /// <summary>
    /// Subscribes to the event types that this listener wishes to listen for.
    /// </summary>
    /// <param name="eventManager"></param>
    void RegisterSubscriptions(EventManager eventManager);
}

...并对每个类调用 RegisterSubscriptions 方法。 (EventManager 只有一个实例在各处使用;我使用依赖注入将其绑定为单例实例。)

RegisterSubscriptions 将简单地为给定类要处理的每种事件类型和处理程序调用 Subscribe 方法。 (我使用的是 .NET,因此事件和处理程序更容易使用,但您可以使用匿名子类在 Java 中执行相同的操作。)

典型的事件可能类似于 RoomEntered,以及与此事件关联的参数将包括房间 ID 以及房间的一些其他属性。当用户进入房间时,游戏引擎会发布此事件,并为该房间提供适当的事件参数,然后 EventManager 类负责调用已订阅该事件类型的每个处理程序。该事件的一个处理程序可能是“HandleEnterRoomWithMonsters”,它检查房间是否有怪物,并相应地执行操作。

这总体上有意义吗?您对这种方法有任何疑问吗?

I've recently implemented something similar to what you're describing. I began by creating an EventManager class that has a "Publish" and "Subscribe" method. When the system starts up, it scans all the loaded assemblies (libraries) for classes that implement the IEventListener interface:

/// <summary>
/// A class that intends to listen for specific events to be published by an
/// event manager.
/// <see cref="EventManager"/>
/// </summary>
public interface IEventListener
{
    /// <summary>
    /// Subscribes to the event types that this listener wishes to listen for.
    /// </summary>
    /// <param name="eventManager"></param>
    void RegisterSubscriptions(EventManager eventManager);
}

... and calls the RegisterSubscriptions method on each of them. (There is only one instance of the EventManager that gets used everywhere; I use dependency injection to bind it as a singleton instance.)

RegisterSubscriptions will simply call the Subscribe method for each event type and handler that the given class is intended to handle. (I'm using .NET, so events and handlers are a little easier to work with, but you can do the same thing in Java using anonymous subclasses.)

A typical event might be something like RoomEntered, and the arguments associated with this event would include the room ID and maybe some other properties about the room. The game engine publishes this event when the user enters a room, providing the appropriate event arguments for that room, and the EventManager class is then responsible for invoking each handler that has subscribed to that event type. One handler for this event might be "HandleEnterRoomWithMonsters", which checks to see whether the room has monsters, and performs an action accordingly.

Does this make sense overall? Do you have any questions about this approach?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文