在NodeJS游戏中,每个对象都是一个类,如何处理事件?

时间:2011-08-06 21:57:13

标签: javascript node.js coffeescript eventemitter

在Javascript / NodeJS游戏中处理多个类时,我无法确定哪个类应该发出事件以及哪些类应该监听。我按照本指南创建了事件驱动的游戏:http://pragprog.com/magazines/2011-08/decouple-your-apps-with-eventdriven-coffeescript

我正在写一个小游戏并将我的班级分成以下控制器:

世界 - 创造游戏世界并通过一些“转弯”来确定一些简单的游戏逻辑(即一个角色应该移动,一个塔应该射击)。

塔楼 - 塔楼位于10x10格栅上并且有一个范围。当物体进入射程时,它可以射击。

怪物(敌人) - 一个怪物在10x10网格上产生并且每3秒移动一次。在某些时候,它在一个塔的范围内徘徊。

我整天都在阅读有关EventEmitters的内容,但似乎无法找到构建我的活动的正确方法。当小怪移动时,小怪是否应该开火,并且塔会听“移动”事件?或者世界是否应该控制所有事件,塔/小怪应该倾听世界?

请参阅下面的示例代码。

背景:我一直在为NodeJS开发一个简单的TowerD游戏,并决定先实现服务器。我将所有实体存储在MongoDB中并使用地理空间计算来确定对象是否在射程范围内。目前我正在使用一个基本的3秒循环来“勾选”游戏和进度逻辑,但我想转向真正的事件驱动模型并且正在挣扎。

世界:

exports.World = class World extends EventEmitter

  constructor: ->
    ### Initial config ###
    @gameTime = 3000  # every 3000ms, the game progresses

    ### Start the game!! ###
    @game = setInterval ->
      world.gameLoop()
    , @gameTime

    ### Load the map ###
    # First level: Hidden Valley
    @maps = []
    @maps.push new map 'hiddenvalley'

### Load the mobs ###
    # First map has one mob: Warrior
    @mobs = []

    # Let's create two of them  
    @mobs.push new mob @maps[0].mobs[0]
    @mobs.push new mob @maps[0].mobs[0]

(参见完整的world.coffee:https://github.com/bdickason/node-towerd/blob/master/controllers/world.coffee

塔:

exports.Tower = class Tower
  constructor: (name) ->
    name = name.toLowerCase() # In case someone throws in some weird name

  # Check for anything within range
  checkTargets: (callback) ->
    mobModel.find { loc : { $near : @loc , $maxDistance : @range } }, (err, hits) -> 
      if err
        console.log 'Error: ' + err
      else
        callback hits

(参见完整的塔。咖啡:https://github.com/bdickason/node-towerd/blob/master/controllers/towers.coffee

怪物:

exports.Mob = class Mob extends EventEmitter

  move: (X, Y, callback) ->
    @loc = [@loc[0] + X, @loc[1] + Y]
    newloc = @loc
    mobModel.find { uid: @uid }, (err, mob) ->
      if(err)
        console.log 'Error finding mob: {@uid} ' + err
      else
        mob[0].loc = newloc
        mob[0].save (err) ->
          if (err)
            console.log 'Error saving mob: {@uid} ' + err
    console.log 'MOB ' + @uid + ' [' + @id + '] moved to (' + @loc[0] + ',' + @loc[1] + ')'

(参见mobs.coffee的完整资料来源:https://github.com/bdickason/node-towerd/blob/master/controllers/mobs.coffee

完整的项目来源:https://github.com/bdickason/node-towerd

任何活动帮助将不胜感激。我已经在github上倾注了大约15个nodejs游戏,并且还没有找到任何人使用这种模式:(

1 个答案:

答案 0 :(得分:2)

我使用支持“父母”的自定义EventEmitter,例如冒泡事件传播。然后我会按照以下方式进行:

  • 当一个怪物移动时,它会使用{mob: @,x: x, y: y}之类的参数触发一个“移动”事件(该事件随后向世界冒泡)。
  • 世界聆听“移动”事件。当它收到一个时,它会检查数据库以查找需要通知的塔并在其上发出事件。