这将是我在stackoverflow上的第一个问题,希望这很顺利。 我一直在开发游戏(使用电晕SDK),我使用Node.js编写一个小型服务器来处理客户端之间的聊天消息,没有任何问题。 现在我正在努力扩展这个小服务器以做更多工作,我想要做的是创建一个外部文件(模块),它将包含一个对象,该对象具有我需要表示的所有函数和变量在我的游戏中的房间" Lobby",其中2个人可以相互竞争,每次我有2个玩家准备玩,我会为他们创建这个空房间的副本,并且然后在那个房间初始化游戏。 所以我在我的主项目文件中有一个数组,每个单元格都是一个房间,我的计划是将我的模块导入到该数组中,然后我就可以在特定的#34; room"中启动游戏,玩家会玩,游戏会继续,一切都会好......但是......我的代码在main.js中:
var new_game_obj = require('./room.js');
games[room_id] = new_game_obj();
games[room_id].users = [user1_name,user2_name];
现在,在我的room.js中,我有类似的东西:
var game_logistics = {};
game_logistics.users = new Array();
game_logistics.return_users_count = function(){
return game_logistics.users.length;
}
module.exports = function() {
return game_logistics;
}
到目前为止一切顺利,这项工作很好,我可以简单地说:
games[room_id].return_users_count()
我会得到0,或1或2,具体取决于有多少用户加入这个房间。 一旦我打开一个新房间就会出现问题,因为如果我现在创建一个新的房间,即使我删除和/或删除了旧房间,Node.js也会对我创建的模块进行实例化而不会复制它。房间,它将包含我已经更新的旧房间的所有信息,而不是新的洁净室。例如:
var new_game_obj = require('./room.js');
games["room_1"] = new_game_obj();
games["room_2"] = new_game_obj();
games["room_1"].users = ["yuval","lahav"];
_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
即使这样做:
var new_game_obj = require('./room.js');
games["room_1"] = new_game_obj();
var new_game_obj2 = require('./room.js');
games["room_2"] = new_game_obj2();
games["room_1"].users = ["yuval","lahav"];
_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
给出相同的结果,它是所有"副本中的相同模块的所有相同实例"我做到了。 所以我的问题很简单,如何创建一个" clean"我的原始模块的副本,而不是一遍又一遍地实例化,实际上最后只有一个凌乱的房间?
答案 0 :(得分:1)
你正在做的是这个(用返回的内容替换你的require()
电话);
var new_game_obj = function() {
return game_logistics;
}
因此,每次拨打new_game_obj
时,都会返回game_logistics
的相同实例。
相反,您需要让new_game_obj
返回game_logistics
的新实例;
// room.js
function Game_Logistics() {
this.users = [];
this.return_users_count = function(){
return this.users.length;
};
}
module.exports = function() {
return new Game_Logistics();
}
这是心态的转变。您会看到我们在new
的{{1}}上使用Game_Logistics
,每次调用module.exports
时都会返回新的实例。< / p>
您还会看到Game_Logistics
内,Game_Logistics
被用于所有地方,而不是this
;这是为了确保我们引用Game_Logistics
的正确实例而不是构造函数。
我还将您的Game_Logistics
函数大写,以遵循广泛遵循的命名约定,即构造函数应该大写(more info)。
当您使用多个函数实例时,建议您利用JavaScript中的原型链。您可以仔细阅读有关“javascript原型继承*(例如this one)的各种文章,但就目前而言,上述内容将满足您的需求。