我正在为多人游戏制作一台服务器,并且在弄清楚如何制作逻辑模块方面遇到了一些问题。 当玩家移动我想要更新对象时,更新数据库记录并将移动发送到所有连接的客户端。 现在我这样做:

var socket = require('./socket');
var db = require('./db');

function Player(id, x, y) {
    this.id = id;
    this.x = x;
    this.y = y;
}

Player.prototype.move = function(x, y) {
    this.x = x;
    this.y = y;

    db.update({id: this.id}, {x: x, y: y});
    socket.emit('player moved', {x: x, y: y});
}

这将套接字和数据库紧密耦合到感觉错误的播放器对象。 但是,每次更新播放器对象时,我都不想在游戏循环中执行db.update和socket.emit。

这样做的正确方法是什么?

===============>>#1 票数:2

如果Player “class”的唯一目的是处理这些类型的更新,那么我看到的唯一真正的改变是参数化播放器代码而不是直接包含db和socket。 但这是一个非常小的变化,因为需求调用已经有点脱钩。

我可以看到三种方法:

  1. 让他们成为Player参数:

     function Player(id, x, y, db, socket) { this.id = id; this.x = x; this.y = y; this.db = db; this.socket = socket; } Player.prototype.move = function(x, y) { this.x = x; this.y = y; this.db.update({id: this.id}, {x: x, y: y}); this.socket.emit('player moved', {x: x, y: y}); }; 

但是你最终会在每个对象中都有这些引用。

  1. 使它们成为创建Player构造函数的构建器函数的参数

     exports.buildPlayerClass = function(db, socket) { function Player(id, x, y) { this.id = id; this.x = x; this.y = y; } Player.prototype.move = function(x, y) { this.x = x; this.y = y; db.update({id: this.id}, {x: x, y: y}); socket.emit('player moved', {x: x, y: y}); }; }; 

    然后在调用模块中使用:

     var socket = require('./socket'); var db = require('./db'); var Player = require('./player').buildPlayerClass(db, socket); // ... var p = new Player("some-id", 0, 0); 
  2. 使Player发出move事件的EventEmitter

     var EventEmitter = require('events').EventEmitter; function Player(id, x, y) { EventEmitter.call(this); this.id = id; this.x = x; this.y = y; } Player.prototype = Object.create(EventEmitter.prototype); Player.prototype.constructor = Player; Player.prototype.move = function(x, y) { this.x = x; this.y = y; this.emit('move', {p: this, x: x, y: y}); }; 

    用法是:

     var socket = require('./socket'); var db = require('./db'); // ... var p = new Player("some-id", 0, 0); p.on('move', function(e) { db.update({id: epid}, {x: ex, y: ey}); socket.emit('player moved', {x: ex, y: ey}); }); 
  3. Player使用常见的事件发射器:

     function Player(id, x, y, emitter) { this.id = id; this.x = x; this.y = y; this.emitter = emitter; } Player.prototype.move = function(x, y) { this.x = x; this.y = y; this.emitter.emit('move', {p: this, x: x, y: y}); }; 

    用法是:

     var playerEvents = new EventEmitter(); playerEvents.on('move', function(e) { db.update({id: epid}, {x: ex, y: ey}); socket.emit('player moved', {x: ex, y: ey}); }); // ... var p1 = new Player("p1", 0, 0, playerEvents); var p2 = new Player("p2", 0, 0, playerEvents); 

===============>>#2 票数:1 已采纳

我会做两件事:

1)让你的Player类发出事件。 这使您可以在将来添加更多触发器,而无需修改您的Player类

2)使用pos对象来保存x和y值。 这使代码更简洁。

// In Player file
var EventEmitter = require('events').EventEmitter;

function Player(id, pos) {
  this.id = id;
  this.pos = pos;
}

Player.events = new EventEmitter();

Player.prototype.move = function (pos) {
  Player.events.emit('move', this);
};

module.exports = Player;

// In database file...
var db = require('./db');
var Player = require('./Player');

Player.events.on('move', function (player) {
  db.update({id: player.id}, player.pos);
});

// In socket file...
var socket = require('./socket');
var Player = require('./Player');

Player.events.on('move', function (player) {
  socket.emit('player moved', player.pos);
});

===============>>#3 票数:0

我自己非常有兴趣看到在这种情况下脱钩的建议。 我个人的建议

Player.prototype.observers = [];
Player.prototype.observers.push(
      function(){
          if(conditionToUpdateDb){
              db.update({id: this.id}, {x: this.x, y: this.y});
          }
      });
Player.prototype.observers.push(
      function(){
          if(conditionToEmit){
              socket.emit('player moved', {x: this.x, y: this.y});
          }
      });

然后

Player.prototype.move = function(x, y) {
    this.x = x;
    this.y = y;

    for(key in this.observers){
        this.observers[key]();
    }
}

如果您想为不同的Players不同的observers ,您也可以这样做

function Player(id, x, y, observers) {
    this.id = id;
    this.x = x;
    this.y = y;
    this.observers = observers;
}

然后

for(key in this.observers){
        this.observers[key]();
    }

  ask by user1767586 translate from so

未解决问题?本站智能推荐: