2016-09-07 43 views
2

我試圖爲roguelike實現基於速度的轉彎系統。我已經建立了使用元方法一宗黑社會類,使分配以下的變量將產生一個暴徒到地圖在某些網格座標:如何動態檢索用於初始化實例的變量?

function Mob:spawn(x,y,m) 
    local mob = {} 
    setmetatable(mob, Mob) 
    mob.x = x 
    mob.y = y 
    mob.is_monster = m 
    return mob 
end 

一旦這樣做了,我把以下內容:

function Mob:roll_call() 
    who_is_here[self.y][self.x] = self.is_monster 
    self.turn_counter = self.turn_counter * math.random(0.9, 1.1) 
    table.insert(allTurnCounters, self.turn_counter) 
end 

這會將怪物的self.turn_counter放入表格中。與此同時,在另一個模塊中,我定義這兩個函數,問題的心臟:

function turn.decrement_counters(dt) -- runs in Dungeon.update(dt) and subtracts from allTurnCounters 
    for i = 1,#allMobsSpawned do 
      if allTurnCounters[i] <= 0 then 
        allTurnCounters[i] = 0 
        turn_active = true 
        whose_turn = i 
        return 
      elseif allTurnCounters[i] > 0 then 
        allTurnCounters[i] = allTurnCounters[i] - (10 * dt) 
      end 
    end 
end 

function turn.whose_is_it() -- called when an entry in allTurnCounters goes zero 
    if whose_turn == 1 then -- spots 1 and 2 in the spawn list are only ever for players 
      player1.my_turn = true -- turns on player 1's keys 
    elseif whose_turn == 2 then 
      player2.my_turn = true -- turns on player 2's keys 
    elseif whose_turn >= 3 then -- above 3 we're in monster territory 

    end 
end 

我已經決定,挑戰者的前兩個​​實例初始化永遠是玩家1和2,分配分別給變量player1和player2。而且,事實上,它可以在玩家之間來回傳遞控制權。但顯然,這對於一款功能齊全的遊戲還不夠。我也需要怪物。

allTurnCounters表從每個生成的怪物(一個既包含玩家又包括怪物的類別,因此可共享統計數據)中依次獲得新條目。這裏是我的問題:如何讓Lua動態檢索與該表中給定的turn_counter /值相關聯的表的名稱,並將其用於優先考慮,即使在我不知道程序化的情況下提前產卵或在產卵次序中佔據什麼位置?

我有3個想法,其中沒有一個我堅實如何實施。一種方法是將整個實例表發送到另一個表,而不僅僅是它們的turn_counters,然後以某種方式獲取一對值(表中的表本身和my_turn),直接更新my_turn的值。

另一種方法可能是使用環境_G ...以某種方式。我仍然在仔細閱讀PiL的第14章,試圖將它適用於我的目的,但value = _G [varname]似乎是我可以用於此的一個強大的代碼。不知道如何,只是尚未。

我最後的想法是寫一些可以在每個暴徒的表中獲取其他值的字符串感應查找替換,然後將其彈出到my_turn的前面。就像爲每個怪物類型分配一個已知模式的值,我可以在一個string.find中使用一個值,然後使用一個string.gsub,像...手動使代碼行按預期方式讀取。雖然似乎不雅。

我很高興在這裏問我以前的Lua/Love2D問題,所以我想我們在思考的時候把它拋出去!

+0

「我該如何讓Lua動態檢索與該表中給定的turn_counter/value相關聯的表的名稱?」 - 1)表沒有名稱,2)在你的代碼中,allTurnCounters中的條目和其他表/名稱/任何內容之間沒有關聯。 – immibis

+0

我的意思是「名稱」是與表相關的變量,用於初始化Mob類的實例。所以,例如,player1或small_ant1或其他。我知道這些可以重新定義,並且參考不是固定的。但我不確定如何以建設性的方式將這些知識用於這個應用程序,這就是我問的原因。這是正確的,所有的TurnCounters和其他都沒有關聯。你能提出一個解決這個問題的好方法嗎? –

回答

1

這裏是我的,你應該如何實現這個建議:

  1. 相反allTurnCounters[i],給小怪turn_counter屬性,並使用allMobsSpawned[i].turn_counter。然後,刪除allTurnCounters

  2. 而不是存儲暴民號​​碼whose_turn,存儲暴民本身。(注:當我說 「暴民本身」,這是短期的 「參考對暴民本身」)

    所以不是

    whose_turn = i 
    

    你會:

    whose_turn = allMobsSpawned[i] 
    
  3. 現在whose_turn擁有這個輪到它的人。你可以很容易地檢查whose_turn == player1,whose_turn == player2等。作爲獎勵,它不再依賴於玩家成爲第一個暴徒。

您可以通過whose_turn訪問暴民的屬性 - 如果whose_turn == player1例如是真的,那麼whose_turn.x訪問同一個字段作爲player1.x

+0

在間隔的時間內,我自己想出了一個稍微不同的解決方案。但是你的回答有一個很好的建議,我會用自己的回答少一些。 –

0

下面是可以通過結合方法進行更優雅幾分janky解決方案另一個答案。這就是我在等待答案時自己提出的。

-- in "Mob.lua" module 
function Mob:roll_call() 
    who_is_here[self.y][self.x] = self.is_monster 
    self.turn_counter = self.turn_counter * math.random(0.9, 1.1) 
    table.insert(allMobs, {self.name, self.turn_counter}) 
    if self.is_monster == true then 
     table.insert(allMonsters, {self.name, self.turn_counter}) 
    end 
end 

    function Mob:move(dx, dy) 
    who_is_here[self.y][self.x] = nil 
     self.x, self.y = self.x + dx, self.y + dy 
     who_is_here[self.y][self.x] = self.is_monster 
     self.turn_counter = 1 * self.speed 
     for k,v in ipairs(allMobs) do 
     if v[1] == self.name then 
      v[2] = self.turn_counter 
     end 
    end 
    self.my_turn = false -- flags turn is over 
    turn_active = false -- flags no active turn 
    end 

-- in "turn.lua" module 
function turn.decrement_counters(dt) 
    if turn_active == false then 
     for k,v in ipairs(allMobs) do 
      v[2] = v[2] - (10 * dt) 
      if v[2] < 0 then 
       v[2] = 0 
       turn_active = true 
       whose_turn = v[1] 
       return 
      end 
     end 
    else turn.whose_is_it() 
    end 
end 

function turn.whose_is_it() 
    if whose_turn == player1.name then 
     player1.my_turn = true 
    elseif whose_turn == player2.name then 
     player2.my_turn = true 
    elseif whose_turn == ant1.name then 
     ant1.my_turn = true 
    end 
end 

turn.whose_is_it()是需要精煉的部分。如果我使用immibis分配allMobs [i] .turn_counter的方法,這將大大簡化事情並允許將來擴展。這個答案只適用於player1,player2和特別是名爲ant1的螞蟻。

+0

當你有無限數量的螞蟻時,你會做什麼? (比如說,一個螞蟻女王每100回合就會在50回合後孵化一次蛋) – immibis

+0

我不明白你爲什麼不能把怪物本身放到所有怪獸和allMobs中。 – immibis

+0

這就是我最終做的。 –