2011-08-06 21 views
5

Khi giao dịch với nhiều lớp trong một trò chơi Javascript/NodeJS, tôi gặp khó khăn trong việc tìm ra lớp nào sẽ phát ra các sự kiện và lớp nào nên lắng nghe. Tôi làm theo hướng dẫn này để tạo ra trò chơi hướng sự kiện: http://pragprog.com/magazines/2011-08/decouple-your-apps-with-eventdriven-coffeescriptTrong trò chơi NodeJS với từng đối tượng như một lớp, các sự kiện nên được xử lý như thế nào?

Tôi đang viết một trò chơi nhỏ và đã chia các lớp học của tôi vào bộ điều khiển sau:

thế giới - tạo ra các trò chơi thế giới và tiến bộ thông qua một số 'lượt' để xác định một số logic trò chơi đơn giản (tức là một nhân vật nên di chuyển, một tháp nên bắn).

tháp - tháp nằm trên lưới 10x10 và có dải ô. Khi một vật thể đi vào phạm vi, nó có thể bắn.

mobs (kẻ thù) - một đám đông sinh ra trên lưới 10x10 và di chuyển sau mỗi 3 giây. Tại một số điểm, nó đi lang thang trong phạm vi của một tòa tháp.

Tôi đã đọc về EventEmitters cả ngày nhưng dường như không thể tìm ra đúng cách để kiến ​​trúc sư cho các sự kiện của tôi. Nếu đám đông bắn một sự kiện khi họ di chuyển, và tháp lắng nghe một sự kiện 'di chuyển'? Hay thế giới nên kiểm soát tất cả các sự kiện và tháp/mobs lắng nghe thế giới?

Xem bên dưới để biết mã ví dụ.

Thông tin cơ bản: Tôi đã làm việc trên một trò chơi TowerD đơn giản cho NodeJS và quyết định triển khai máy chủ trước tiên. Tôi đang lưu trữ tất cả các thực thể trong MongoDB và sử dụng tính toán không gian địa lý để xác định xem các đối tượng nằm trong phạm vi để bắn hay không. Hiện tại tôi đang sử dụng vòng lặp thứ 2 thô sơ để 'đánh dấu' trò chơi và logic tiến độ nhưng tôi muốn chuyển sang một mô hình theo hướng sự kiện thực sự và đang đấu tranh.

thế giới:

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] 

(xem toàn 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 

(xem toàn 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] + ')' 

(xem nguồn đầy mobs.coffee: https://github.com/bdickason/node-towerd/blob/master/controllers/mobs.coffee)

nguồn đầy đủ của dự án: https://github.com/bdickason/node-towerd

Bất kỳ trợ giúp sự kiện sẽ được đánh giá. Tôi đã đổ khoảng 15 trò chơi nodejs trên github và chưa tìm thấy ai sử dụng mẫu này: (

Trả lời

2

Tôi muốn sử dụng EventEmitter tùy chỉnh hỗ trợ "cha mẹ", ví dụ như tuyên truyền sự kiện bubbling. theo cách sau:.

  • Khi một đám đông di chuyển, nó cháy một "di chuyển" sự kiện trên chính nó với một tham số như {mob: @,x: x, y: y} (sự kiện này sau đó bong bóng lên đến trên thế giới)
  • thế giới lắng nghe cho "di chuyển" Khi nó nhận được một, nó sẽ kiểm tra trong cơ sở dữ liệu để tra cứu các tòa tháp cần được thông báo và phát ra sự kiện trên chúng.
+1

Ahaha điều kiện phát hiện sự kiện cha mẹ đáng yêu: D Đảm bảo bạn dành chút thời gian cho việc thiết kế hệ thống. ví dụ. cho nhóm của đối tượng, do đó bạn sẽ nghe trên thế giới cho "golbin.move" và mỗi cấp độ bạn đi lên bạn unshift trong goblin, thế giới vv vào params gọi lại. –

+0

Cảm ơn thejh và Ivo, đây là những gợi ý tuyệt vời! Tôi có một chút hiểu biết về khái niệm 'sủi bọt', nhưng mọi thứ khác đều rõ ràng. Bạn có thể làm rõ 'unshift' trong yêu tinh hoặc thế giới bằng ví dụ nhanh không? –

+1

Chắc chắn, hãy tưởng tượng có một con yêu tinh. Những người nghe trên globin sẽ trông giống như thế này 'goblin.bind (' move ', function (x, y) {'bây giờ người nghe trên thế giới sẽ giống như' world.bind (' goblin.move ', function (goblin, x , y) {'và như vậy trên –

Các vấn đề liên quan