2015-10-23 4 views
0

Я новичок в короне и пытался сделать какой-то объект пула на движущихся платформах. Когда они выходят из экрана, они переместились с visibleBlocks на blocks. Когда я регистрирую подсчеты обеих моих таблиц, числа не совпадают с тем, как они должны ... и в моих блоках появляются большие пробелы, появляющиеся на экране. поколениеCorona SDK Lua: Перемещение предметов из одного стола в другой

Мои блоки:

local color = 'red' 
for i = 1, 10 do 
    local block = display.newRect(0, 0, 60, 2) 
    block.index = i 
    block.name = 'block' 
    block.isVisible = false 
    physics.addBody(block, 'static') 
    blocks[i] = block 
    sceneGroup:insert(block) 

    block.color = color 

    color = switchColor(block) 
end 

код обнаружения, когда блоки оставили экран

function update() 

    for k, block in pairs(visibleBlocks) do 
     block.y = block.y - 1 
     if block.y < 0 then 
      removeBlock(block) 
     end 
    end 

код removeblock

function removeBlock(block) 

    block.isVisible = false 
    block.isBodyActive = false 
    blocks[block.index] = block 
    visibleBlocks[block.index] = nil 


    print (' ') 
    print('blocks: ' .. #blocks) 
    print('visible blocks: ' .. #visibleBlocks) 

end 

addblock, которая выполняется по таймеру

function addBlock() 
    local block = table.remove(blocks) 
    if block ~= nil then 
     block.isVisible = true 
     block.isBodyActive = true 
     visibleBlocks[block.index] = block 

     block.x = math.random( 
      block.contentWidth/2 + 20, 
      display.contentWidth - block.contentWidth/2 - 20 
     ) 
     block.y = display.contentHeight 

    end 
end 

мой вывод консоли выглядит следующим образом:

Oct 23 08:50:16.281: blocks: 0 
Oct 23 08:50:16.281: visible blocks: 9 
Oct 23 08:50:17.289: 
Oct 23 08:50:17.290: blocks: 0 
Oct 23 08:50:17.290: visible blocks: 8 
Oct 23 08:50:18.329: 
Oct 23 08:50:18.329: blocks: 10 
Oct 23 08:50:18.329: visible blocks: 7 
Oct 23 08:50:19.353: 
Oct 23 08:50:19.354: blocks: 9 
Oct 23 08:50:19.354: visible blocks: 6 
Oct 23 08:50:20.313: 
Oct 23 08:50:20.314: blocks: 8 
Oct 23 08:50:20.314: visible blocks: 5 
Oct 23 08:50:21.339: 
Oct 23 08:50:21.340: blocks: 0 
Oct 23 08:50:21.340: visible blocks: 10 
Oct 23 08:50:22.376: 
Oct 23 08:50:22.376: blocks: 7 
Oct 23 08:50:22.376: visible blocks: 10 
Oct 23 08:50:23.390: 
Oct 23 08:50:23.390: blocks: 6 
Oct 23 08:50:23.390: visible blocks: 10 
Oct 23 08:50:24.392: 
Oct 23 08:50:24.393: blocks: 5 
Oct 23 08:50:24.393: visible blocks: 10 
Oct 23 08:50:25.457: 
Oct 23 08:50:25.457: blocks: 4 
Oct 23 08:50:25.458: visible blocks: 10 

эти цифры всегда должны добавить до 10 верно? что-то здесь совсем не так

+3

Я не полностью следую логике здесь, но вы почти наверняка создаете «дыры» в своих таблицах, перебирая индексы между ними. И '#' определяется только на таблицах без отверстий. –

ответ

0

Говоря visibleBlocks[block.index] = nil в removeBlock, вы создаете отверстия в своем «массиве», что означает, что # does уже не определено четко. В качестве примера,

function footest(t) print(("%d,%s"):format(#t, tostring(t[2]))) end 
footest { 1, nil, 3 } 
--> 3,nil 
footest { 1, [3] = 3 } 
--> 1,nil 
t = { 1, 2, 3 } ; t[2] = nil ; footest(t) 
--> 3,nil 
u = { 1, 2, 3 } ; u[1] = nil ; footest(u) 
--> 3,2 
u[2] = nil ; footest(u) 
--> 3,nil 
u[3] = nil ; footest(u) 
--> 0,nil 

(по крайней мере, это то, что в настоящее время происходит на моей машине ... В то время как вы могли бы посмотреть на источник и узнать, что будет происходить во всех этих случаях для конкретной версии вы находитесь используя, справочное руководство просто говорит, что то, что происходит, не определено.)


Так как это исправить?

Один из способов сделать это - использовать table.remove вместо nil -поля. (table.remove(t, n) будет смещаться все элементы «право» n в «массиве» один влево, чтобы закрыть разрыв, то есть для

t = { [1] = 1, [2] = 2, [3] = 3 } 

говоря

table.remove(t, 1) 

результаты в

t = { [1] = 2, [2] = 3, [3] = nil } 

и не оставлять пробел внутри массива.) Это хорошо работает, когда вы зависеть от порядка вещей в таблице/«массиве», но не от их абсолютного положения.

К сожалению, похоже, вы полагаетесь на фиксированные позиции для всех блоков (block.index) - если это так, это не сработает. (Если это делает работу, и я просто неправильно интерпретировать код, это, вероятно, самый простой способ исправить это.)


Так лучший способ может быть назначение false вместо nil.Вы должны настроить update (и, возможно, другой код, который я не видел), но изменения незначительны:

Ваш

function update() 
    for k, block in pairs(visibleBlocks) do 
     block.y = block.y - 1 
     if block.y < 0 then 
      removeBlock(block) 
     end 
    end 
end 

превращается в

function update() 
    for k, block in ipairs(visibleBlocks) do 
     if block then 
      block.y = block.y - 1 
      if block.y < 0 then 
       removeBlock(block) 
      end 
     end 
    end 
end 

Первое изменение - заменить pairs на ipairs - это то, что вы должно делать в любом случае всякий раз, когда вы используете таблицу в виде массива. (ipairs остановится в первом зазоре, а это означает, что если вы случайно создадите отверстие, вам не хватит много материала, и вы получите довольно очевидную ошибку, которую легче отладить, чем эти незначительные сбои. Кроме того, если ваш массив содержит дыры, pairs не может перебрать все в порядке возрастания - попробуйте с t = { 1, 2, 3, [9] = 9, [12] = 12 }, переборе с pairs может производить порядка 1, 2, 3, 12, 9)

Единственное изменение является проверка if block then …, поскольку некоторые блоки могут отсутствовать! , как представлено false, и не будет пропускаться без звука, как при использовании nil и pairs.

Результат будет хорошим, если вы будете зависеть от позиции (и, неявно, порядка) элементов в таблице/«array», а «это на самом деле блок?» - проверка не так уж плоха.


Третий вариант - если вы полагаетесь ни на заказ, ни на абсолютное положение элементов - бы не пытаться использовать таблицу как массив. Просто используйте каждый блок в качестве ключа и назначьте его фиктивное значение (обычно true). (В качестве бонуса, вам не нужно запоминать дополнительный block.index - блок является индекс!)

Чтобы добавить блок, просто сказать blocks[block] = true, чтобы удалить, просто сказать blocks[block] = nil. Для перебора всех блоков,

for block in pairs(blocks) do 
    … 
end 

, но если вам нужно рассчитывать блоки, вам нужна функция, как

function size(t) 
    local count = 0 
    for _ in pairs(t) do count = count + 1 end 
    return count 
end 

Эта версия сломается ужасно, когда вы полагаетесь на относительном порядке, что и порядок рисования или что-то в этом роде: всякий раз, когда вы вставляете элемент, порядок всех записей может полностью измениться, что приведет к случайному появлению блоков выше/ниже других. Сравните:

t = { [5] = 1, [2] = 1, [8] = 1 } 
for k in pairs(t) do print(k) end 
--> 8, 5, 2 
t[3] = 1 
for k in pairs(t) do print(k) end 
--> 8, 5, 2, 3 
t[6] = 1 
for k in pairs(t) do print(k) end 
--> 2, 3, 5, 6, 8 

(., И вы можете получить совершенно иной порядок, если вы запустите это)

Если потенциальная проблема не распространяется это на самом деле может привести к простейшему кода в целом (даже если вы» вероятно, придется немного перестроить.)

Смежные вопросы