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

发布于 2024-11-28 01:28:37 字数 3146 浏览 0 评论 0原文

在处理 Javascript/NodeJS 游戏中的多个类时,我很难确定哪个类应该发出事件以及哪些类应该监听事件。我按照本指南创建事件驱动游戏: http ://pragprog.com/magazines/2011-08/de Couple-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

参见完整的 towers.coffee: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 游戏,但还没有发现有人使用这种模式:(

When dealing with multiple classes in a Javascript/NodeJS game, I'm having trouble figuring out which class should emit events and which classes should listen for the. I am following this guide to creating event-driven games: http://pragprog.com/magazines/2011-08/decouple-your-apps-with-eventdriven-coffeescript

I'm writing a small game and have split my classes into the following controllers:

world - creates the game world and progresses through a number of 'turns' to determine some simple game logic (i.e. a character should move, a tower should shoot).

tower - a tower sits on a 10x10 grid and has a range. When an object comes into range, it can shoot.

mobs (enemies) - a mob spawns on the 10x10 grid and moves every 3 seconds. At some point, it wanders in range of a tower.

I have been reading about EventEmitters all day but can't seem to figure out the right way to architect my events. Should the mobs fire an event when they move, and the tower listen for a 'move' event? Or should the world control all of the events and the tower/mobs listen to the world?

See below for example code.

Background: I've been working on a simple TowerD game for NodeJS and decided to implement the server first. I'm storing all entities in MongoDB and using geospatial calculation to determine if objects are in range to shoot. Currently i'm using a rudimentary 3 second loop to 'tick' the game and progress logic but I'd like to move to a truly event-driven model and am struggling.

World:

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]

(see full world.coffee: https://github.com/bdickason/node-towerd/blob/master/controllers/world.coffee)

Tower:

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

(see full towers.coffee: https://github.com/bdickason/node-towerd/blob/master/controllers/towers.coffee)

Mobs:

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] + ')'

(see full source of mobs.coffee: https://github.com/bdickason/node-towerd/blob/master/controllers/mobs.coffee)

Full source of project: https://github.com/bdickason/node-towerd

Any event help would be appreciated. I've poured over about 15 nodejs games on github and haven't found anyone using this pattern yet :(

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

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

发布评论

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

评论(1

星星的軌跡 2024-12-05 01:28:37

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

  • 当生物移动时,它会使用类似 {mob: @,x: x, y: y} 的参数在自身上触发“移动”事件(该事件然后冒泡到世界)。
  • 全世界都在倾听“移动”事件。当它收到一个消息时,它会在数据库中检查以查找需要通知的塔并在其上发出事件。

I'd use a custom EventEmitter that supports "parents", e.g. bubbling event propagation. Then I would do it the following way:

  • When a mob moves, it fires an "move" event on itself with a parameter like {mob: @,x: x, y: y} (the event then bubbles up to the world).
  • The world listens for "move" events. When it receives one, it checks in the database to look up the towers that need to be notified and emits the event on them.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文