在 for 循环中框的颜色不会改变。 (表作为函数中的参数)

Box color won't change during the for loop. (Tables as parameters in functions)

最新的问题描述在最下方。 (表和函数)

动图:http://i.imgur.com/jZ9zmbG.gifv

所以在 for 循环中,我试图保存碰撞框的信息,然后在没有发生碰撞时应用它,在这种情况下,我需要这些框保持它们由 math.random 生成的原始颜色() 如果没有碰撞。

如果发生碰撞,我只需将碰撞框的颜色值更改为红色 (255, 0, 0)。

我很确定问题出在 for 循环和 if 语句块中。 我将 post 脚本的其余部分放在底部。这是区块:

function movePlayer(dt)
  player.pos.x, player.pos.y, cols, cols_len = world:move(
    player, 
    player.pos.x + player.velocity.x *dt, 
    player.pos.y + player.velocity.y *dt)
  for i=1, cols_len do 
    local col = cols[i].other
    local previousColors = {r, g, b}
    local previousBox 
    if cols[i].other then -- if collision is detected then
      lovebird.print(string.format("%s collided with %s's box.", player.name, cols[i].other.name))
      previousBox = i -- store collided box id
      previousColors.r = cols[previousBox].other.color.r -- store color value of the previous collided box
      previousColors.g = cols[previousBox].other.color.g --
      previousColors.b = cols[previousBox].other.color.b --
      cols[i].other.color.r = 255 -- change the color of collided box to red
      cols[i].other.color.g = 0 --
      cols[i].other.color.b = 0 --
      -- debug info --
      lovebird.print(string.format("previousColors: %d, %d, %d, previousBox: %d.", 
      previousColors.r,
      previousColors.g,
      previousColors.b,
      cols[i].other.name))
    else -- if collision is not detected then
      cols[previousBox].other.color.r = previousColors.r -- change color back to the previously saved one
      cols[previousBox].other.color.g = previousColors.g --
      cols[previousBox].other.color.b = previousColors.b --
    end
  end
end

整个脚本:

bump = require 'bump'
player = require 'player'
vector = require 'vector'
timer = require 'timer'
center = vector.new(lg.getWidth()/2, lg.getHeight()/2)
anim8 = require  'anim8'
lovebird = require 'lovebird'
local world = bump.newWorld()
local player = playerNew('sakvojaz', center, 50)

function randomColor()
  return math.random(64, 255)
end

function drawBox(box)
  love.graphics.setColor(box.color.r, box.color.g, box.color.b, 70)
  love.graphics.rectangle('fill', box.pos.x, box.pos.y, box.w, box.h)
  love.graphics.setColor(box.color.r/2, box.color.g/2, box.color.b/2)
  love.graphics.rectangle('line', box.pos.x, box.pos.y, box.w, box.h)
end

function drawPlayerBox(box, r, g, b)
  love.graphics.setColor(r, g, b, 70)
  love.graphics.rectangle('fill', box.pos.x, box.pos.y, box.w, box.h)
  love.graphics.setColor(r/2, g/2, b/2)
  love.graphics.rectangle('line', box.pos.x, box.pos.y, box.w, box.h)
end

function movePlayer(dt)
  player.pos.x, player.pos.y, cols, cols_len = world:move(
    player, 
    player.pos.x + player.velocity.x *dt, 
    player.pos.y + player.velocity.y *dt)
  for i=1, cols_len do 
    local col = cols[i].other
    local previousColors = {r, g, b}
    local previousBox 
    if cols[i].other then -- if collision is detected then
      lovebird.print(string.format("%s collided with %s's box.", player.name, cols[i].other.name))
      previousBox = i -- store collided box id
      previousColors.r = cols[previousBox].other.color.r -- store color value of the previous collided box
      previousColors.g = cols[previousBox].other.color.g --
      previousColors.b = cols[previousBox].other.color.b --
      cols[i].other.color.r = 255 -- change the color of collided box to red
      cols[i].other.color.g = 0 --
      cols[i].other.color.b = 0 --
      -- debug info --
      lovebird.print(string.format("previousColors: %d, %d, %d, previousBox: %d.", 
      previousColors.r,
      previousColors.g,
      previousColors.b,
      cols[i].other.name))
    else -- if collision is not detected then
      cols[previousBox].other.color.r = previousColors.r -- change color back to the previously saved one
      cols[previousBox].other.color.g = previousColors.g --
      cols[previousBox].other.color.b = previousColors.b --
    end
  end
end

function drawPlayer()
  drawPlayerBox(player, 0, 0, 255)
end

blocks = {}

local function addBlock(name, x, y, w, h, r, g, b)
  local block = {name=name, w=w, h=h}
  block.pos = {x=y, y=y}
  block.color = {r=r, g=g, b=b}
  blocks[#blocks+1] = block
  world:add(block, block.pos.x, block.pos.y, w, h)
end


for i=1, #blocks do 
  blocks[i] = addBlock()
end


local function drawBlocks()
  for _,block in ipairs(blocks) do
    drawBox(block)
  end
end

function love.load()
  world:add(player, player.pos.x, player.pos.y, 32, 32)

  for i=1,3 do
    addBlock(i, math.random(100, 600),
              math.random(100, 400),
              math.random(10, 100),
              math.random(10, 100), 
              randomColor(),
              randomColor(),
              randomColor()
    )
  end
end

function love.update(dt)
  --------------------------
  lovebird.update() -- console debug stuff
  --------------------------

  cols_len = 0
  player.Update(dt)
  movePlayer(dt)
end

function love.draw()
  drawPlayer()
  love.graphics.setColor(255, 255, 255, 255)
  player.Draw()
  drawBlocks()
end

所以我的猜测是 for 循环中的 "i" 迭代器只是检测到的碰撞数量。因为我需要跟踪 table 是什么,所以我想出了这个主意:

local function addBlock(id, x, y, w, h, r, g, b)
  local block = {}
  block[id] = {name=id, w=w, h=h}
  block[id].pos = {x=y, y=y}
  block[id].color = {r=r, g=g, b=b}
  blocks[#blocks+1] = block[id]
  world:add(block[id], block[id].pos.x, block[id].pos.y, w, h)
end

我会在函数中传递一个 id(数字)并将其分配给 table。 这样我就可以像这样单独访问每个 table:

previousBox = cols[i].other[id].name

但问题是我收到此错误:尝试索引全局 'block'(零值)

我认为这是问题所在:

function drawBox(box, id)
  love.graphics.setColor(box[id].color.r, box[id].color.g, box[id].color.b, 70)
  love.graphics.rectangle('fill', box[id].pos.x, box[id].pos.y, box[id].w, box.h)
  love.graphics.setColor(box[id].color.r/2, box[id].color.g/2, box[id].color.b/2)
  love.graphics.rectangle('line', box[id].pos.x, box[id].pos.y, box[id].w, box[id].h)
end

如何将具有正确索引的 table 传递给函数? 我很确定有更好的方法来做到这一点。

我认为你的问题是你在 for 循环中初始化变量,因为在每次迭代中你擦除 previousColorspreviousBox 的值,尝试在之前这样做循环:

function movePlayer(dt)
  player.pos.x, player.pos.y, cols, cols_len = world:move(
    player, 
    player.pos.x + player.velocity.x *dt, 
    player.pos.y + player.velocity.y *dt)
    local previousColors = {r, g, b}
    local previousBox
  for i=1, cols_len do
    if cols[i].other then -- if collision is detected then
      lovebird.print(string.format("%s collided with %s's box.", player.name, cols[i].other.name))
      previousBox = i -- store collided box id
      previousColors.r = cols[previousBox].other.color.r -- store color value of the previous collided box
      previousColors.g = cols[previousBox].other.color.g --
      previousColors.b = cols[previousBox].other.color.b --
      cols[i].other.color.r = 255 -- change the color of collided box to red
      cols[i].other.color.g = 0 --
      cols[i].other.color.b = 0 --
      -- debug info --
      lovebird.print(string.format("previousColors: %d, %d, %d, previousBox: %d.", 
      previousColors.r,
      previousColors.g,
      previousColors.b,
      cols[i].other.name))
    else -- if collision is not detected then
      cols[previousBox].other.color.r = previousColors.r -- change color back to the previously saved one
      cols[previousBox].other.color.g = previousColors.g --
      cols[previousBox].other.color.b = previousColors.b --
    end
  end
end