2011-08-06 10 views
5

Cuando se trata de varias clases en un juego Javascript/NodeJS, estoy teniendo problemas para averiguar qué clase debe emitir sucesos y qué clases deben escuchar el. Estoy siguiendo esta guía para la creación de juegos basados ​​en eventos: http://pragprog.com/magazines/2011-08/decouple-your-apps-with-eventdriven-coffeescriptEn un juego NodeJS con cada objeto como una clase, ¿cómo deben tratarse los eventos?

Estoy escribiendo un pequeño juego y haber dividido mis clases en las siguientes controladores:

mundo - crea el mundo del juego y progresa a través de una serie de 'gira' para determinar una lógica de juego simple (es decir, un personaje debería moverse, una torre debería disparar).

torre - una torre se asienta sobre una rejilla de 10x10 y tiene un alcance. Cuando un objeto entra en rango, puede disparar.

mobs (enemigos): una turba se genera en la cuadrícula de 10x10 y se mueve cada 3 segundos. En algún momento, vaga en el rango de una torre.

He estado leyendo sobre EventEmitters todo el día, pero parece que no puedo encontrar la manera correcta de diseñar mis eventos. ¿Deben las multitudes disparar un evento cuando se mueven, y la torre escucha un evento de "movimiento"? ¿O debería el mundo controlar todos los eventos y las torres/multitudes escuchan al mundo?

Véase más abajo para ejemplo de código.

Antecedentes: He estado trabajando en un simple juego TowerD para NodeJS y he decidido implementar el servidor primero. Estoy almacenando todas las entidades en MongoDB y usando el cálculo geoespacial para determinar si los objetos están en el rango para disparar. Actualmente estoy usando un bucle rudimentario de 3 segundos para 'marcar' el juego y progresar en la lógica, pero me gustaría pasar a un modelo verdaderamente orientado a eventos y estoy luchando.

Mundial:

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] 

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

Torre:

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 

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

(ver completa fuente de mobs.coffee: https://github.com/bdickason/node-towerd/blob/master/controllers/mobs.coffee)

fuente completo del proyecto: https://github.com/bdickason/node-towerd

Cualquier ayuda sería apreciada evento. He usado más de 15 juegos de nodejs en github y aún no he encontrado a nadie que use este patrón :(

Respuesta

2

Usaría un EventEmitter personalizado que admita "padres", por ejemplo, propagación de eventos de burbujeo. Entonces lo haría de la siguiente manera:.

  • cuando una multitud se mueve, dispara un evento "se mueven" en la misma con un parámetro como {mob: @,x: x, y: y} (el evento y luego se propaga hacia arriba al mundo)
  • el mundo escucha de "movimiento" eventos. Cuando recibe uno, comprueba en la base de datos para buscar las torres que necesitan ser notificadas y emite el evento en ellas.
+1

Ahaha the lovely parent event emitter thing: D Asegúrese de pasar algún tiempo en el diseño del sistema. p.ej. dando el grupo de objetos para que escuches en el mundo "golbin.move" y en cada nivel que subas desactives en el duende, el mundo, etc. en los parámetros de devolución de llamada. –

+0

Gracias thejh e Ivo, ¡estas son excelentes sugerencias! Estoy teniendo un poco de tiempo para entender el concepto de 'burbujeo', pero todo lo demás está claro. ¿Podría aclarar el "desvío" en el duende o el mundo con un ejemplo rápido? –

+1

Claro, imagina que el duende dispara un movimiento. Los oyentes en el globin se verían como 'goblin.bind ('move', function (x, y) {' ahora los oyentes en el mundo se verían como 'world.bind ('goblin.move', function (goblin, x , y) {'y así sucesivamente –

Cuestiones relacionadas