在基于文本的游戏中,如何将对象放置在房间内?

How do you place an Object inside a Room in a text-based game?

本文关键字:对象 房间 于文本 文本 游戏      更新时间:2023-10-16

我是一个编码新手(尽管我的用户名可能暗示我远非专业人士),我正在尝试编写自己的基于文本的冒险游戏。我有两个问题。

首先,我想实现一个 Object 类。这些物品有名称和描述,可以放置在房间中,也可以由玩家捡起和携带。让我感到困惑的是,这些物体应该知道他们最初在哪个房间,可以说是他们的"教室"。

我不确定如何让每个房间知道他们在其中放置了对象。我尝试做的一切都无法编译。

我尝试将房间 r 作为私有变量包含在 Object 中.cpp并将 Room 包含在 Object 构造函数中。

Object::Object(string name, string description, Room *r)
{
name_ = name; 
description_ = description; 
r_ = r; //assume r_ is a private variable
}

其次,关于指针...此赋值指定我必须具有对象的指针向量。会是这样吗?

vector<Object*>objectsInRoom; 

在main.cpp中,我还需要一个对象的向量。Room 类中的向量是否跟踪每个房间中的对象?并且是主要的矢量.cpp跟踪玩家携带的所有物体。为什么房间类必须有一个对象的指针向量?拥有对象的向量就不够了吗?

(如果这听起来含糊不清,我深表歉意;这个游戏是基于一个可以在这里找到的任务。如果你向下滚动到"额外学分"部分并转到标记为 10 分的第一段块,你会发现我试图在上面压缩的更广泛的解释。

房间.cpp

// Room.cpp: implementation of the Room class.
//
//////////////////////////////////////////////////////////////////////
#include "Room.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Room::Room()
{
name_ = "The void";
description_ = "There is nothing but blackness in every direction.";
int i;
for(i = 0; i < 4; i++) // set all exits to "closed"
exits_.push_back(NULL);

}
Room::Room(string name, string desc)
{
name_ = name;
description_ = desc;
int i;
for(i = 0; i < 4; i++) // set all exits to "closed"
exits_.push_back(NULL);

}
Room::~Room()
{
cout << "Destroying: " << name_ << endl; 
// make sure all exits to this room are
// destroyed so that no one can try to enter
// this room from another location
if(exits_[NORTH] != NULL)
disconnect(NORTH);
if(exits_[EAST] != NULL)
disconnect(EAST);
if(exits_[SOUTH] != NULL)
disconnect(SOUTH);
if(exits_[WEST] != NULL)
disconnect(WEST);
}
// --- inspectors ---
Room * Room::north() const
{
return exits_[NORTH];
}
Room * Room::south() const
{
return exits_[SOUTH];
}
Room * Room::east() const
{
return exits_[EAST];
}
Room * Room::west() const
{
return exits_[WEST];
}

string Room::name() const
{
return name_;
}
string Room::description() const
{
return description_;
}
/*
vector<Object> Room::object() const
{
return roomObjects; 
}
*/
// --- mutators ---
void Room::set_name(string n)
{
name_ = n;
}
void Room::set_description(string d)
{
description_ = d;
}
/*
void Room::set_object(Object o)
{
allObjects.push_back(o); 
}
*/
// --- facilitators ---
bool Room::connect(Direction exit, Room *r, Direction to)
{
// check that both exits are free
if (exits_[exit] != NULL or r->exits_[to] != NULL)
return false;
// make connection
exits_[exit] = r;
r->exits_[to] = this;
return true;
}
// --- private methods ---
void Room::disconnect(Direction d)
{
// disconnects ALL exits from another
// room to this one.  It's sloppy, but
// that's OK.
Room * other_room;
other_room = exits_[d];
int i;
for(i = 0; i < 4; i++)  {
if (other_room->exits_[i] == this)
other_room->exits_[i] = NULL;
}
}
// --- operators ---
ostream & operator<<(ostream & out, const Room & r) {
out << r.name() << endl;
out << r.description() << endl;
return out;
}

对象.cpp

#include "Object.h"; 
Object::Object()
{
name_ = "Object"; 
description_ = "The object lies in the room"; 
}
Object::Object(string name, string description)
{
name_ = name; 
description_ = description; 

}

编辑:所以,如果我只是在 Room.h 的私有属性下添加vector<Object*> allObjects,我会在这里得到这些输入图像描述。抱歉,我还不允许嵌入图像。

我建议(尽量遵守您提出的架构)定义一个方法void Room::pushObject(Object* argObject)。在构造函数Object::Object中,您可以添加一个调用r->pushObject(this)。然后,一旦您进入房间,您就可以遍历您的向量。

此外,链表std::deque将是满足您需求的更好解决方案,因为它旨在更快地插入和删除。然后,您可以room1.insert(room0.erase(yourObjPtr))移动对象。

请注意,答案是理论上的,我没有检查这些是否编译。

编辑 1:

为什么房间类必须有一个对象的指针向量?

你也可以有一个指向对象实例本身的向量,但是当你希望将对象移动到另一个房间时,程序必须复制所有内容,而不是传递单个指针。此外,它将禁止使用继承(您可能会在不久的将来使用它:))

编辑2:我现在也看到我误解了你的设计。您打算使用单个全局向量。可以这么说,我以为你想使用一种更"面向对象"的方法。我会为每个房间放一个std::deque,但如果你想保持这种方式,关于你的主要问题

我不确定如何让每个房间知道他们在其中放置了对象。

你可能会做这样的事情(思考效率低下):

void Room::processMyObjects(void)
{
for (int i = 0; i < globalObjectVector.size(); i++)
{
if (globalObjectVector[i]->r_ == myRoomId)
{
// do whatever you want here.
}
}
}

此外,您要么必须声明r_公共,编写公共 getter 函数,要么以这种方式在Object声明中声明friend class Room,否则Room看不到Object的私有变量。

在这种情况下,您有一个多到五月的关系。房间不拥有对象,对象房间中。您可以使用稀疏地图对多到五月关系进行建模。说,std::unordered_multimap<Room*, Object*>.使用这种方法,您可以轻松查询特定房间中的所有对象,或者通过关联不同的键将对象移动到另一个房间。如果您想知道哪个房间包含您的对象,您将需要一个反向地图std::unordered_multimap<Object*, Room*>。此外,智能指针不会帮助您,因为您不会经常创建和销毁对象。最好将对象的生存期与与其关联的级别的生存期绑定在一起。