#for-loop #lua #love2d
#для цикла #lua #love2d
Вопрос:
Я создаю игру палача. Прямо сейчас мне нужно, чтобы, если пользователь нажимает клавишу буквы, которая находится в заданном слове, она отображается на экране в правильном порядке. Например: когда слово «word», нажатие «w» покажет w _ _ _ на экране. Затем, если затем нажать d, будет указано w _ _ d . Однако этого не происходит. Вместо этого он показывает _ _ _ d, когда d нажимается после w и стирает w с экрана. Я думаю, что моя проблема может быть связана с моим циклом for в love.draw или чем-то в ключе.нажат. Я очень озадачен, поэтому буду признателен за любую помощь! Я скопировал love.keypressed , love.draw и другие важные переменные ниже в том порядке, в котором они вызываются в моем коде.
Код:
wrongCount=0
randomWord = "word"
wordSpots = {}
wordList = {}
numBlanks = string.len(randomWord)
Ltext = " "
function love.keypressed(key)
pressed = key
if key == "escape" then --one of the letters in the word
love.event.quit()
elseif key == "a" or key == "b" or key == "c" or key == 'd' or key == "e" or key == 'f' or key == 'g' or key == "h" or key == "i" or key == 'j' or key == 'k' or key == 'l' or key == 'm' or key == 'n' or key == "o" or key == "p" or key == 'q' or key == 'r' or key == 's' or key == 't' or key == 'u' or key == "v" or key == "w" or key == 'x' or key == 'y' or key == 'z' then
Ltext = pressed
--guess function
LrandomWord = string.lower(randomWord) --ensure no problems with capitalization
letterWrong=0
wordSpots = {}
for i=1, #LrandomWord, 1 do
c = LrandomWord:sub(i,i)
if Ltext == c then
Cguess=Ltext
table.insert(wordSpots, i)
else
letterWrong= letterWrong 1
end
end
if letterWrong == #LrandomWord then
wrongCount = wrongCount 1
end
end
end
function love.draw()
push:apply('start')
love.graphics.clear(40/255,45/255,52/255,255/255)
love.graphics.printf(Ltext, 0, 80, VIRTUAL_WIDTH 30, "center")
love.graphics.printf("Welcome to Hardcore Hangman!", 0, 10, VIRTUAL_WIDTH, "center")
--hanging pole
love.graphics.rectangle('fill', VIRTUAL_WIDTH/2 -80, VIRTUAL_HEIGHT/2 40, 160, 5) --base
love.graphics.rectangle('fill', VIRTUAL_WIDTH/2 - 60, VIRTUAL_HEIGHT/2 - 80, 5, 120) --pole
love.graphics.rectangle('fill', VIRTUAL_WIDTH/2-60, VIRTUAL_HEIGHT/2 -80, 45, 5) --upper base
love.graphics.rectangle('fill', VIRTUAL_WIDTH/2 - 15, VIRTUAL_HEIGHT/2 -80, 5, 15) -- small down pole
for i=1, 4,1 do
love.graphics.rectangle('fill', VIRTUAL_WIDTH/2-4, VIRTUAL_HEIGHT/2 - 15*i, 20,5)
end
-- creates blanks for guessing
blankPos = VIRTUAL_WIDTH/6
for i=1, #randomWord,1 do
love.graphics.rectangle('fill', blankPos, VIRTUAL_HEIGHT/2 80, 25, 5)
blankPos= blankPos 35
end
push:apply('end')
tableLen = #wordSpots
love.graphics.printf(tableLen, 0, 80, VIRTUAL_WIDTH 30, "center")
for i=1, tableLen, 1 do
spot = wordSpots[i]
love.graphics.print(Cguess, blankPos*spot 10, VIRTUAL_HEIGHT/2 80)
end
end
Комментарии:
1. Каждый раз, когда вы вызываете
love.keypressed
, вы устанавливаетеwordSpots = {}
, стирая все предыдущие достижения. Удалите эту строку из функции.2. Изменил несколько вещей, чтобы заставить эти буквы выстраиваться в линию — github.com/doyousketch2/hangman — Я напечатаю объяснение сегодня днем.
Ответ №1:
Здесь много чего нужно распаковать. Вкратце:
elseif key == "a" or key == "b" -- etc.
Ltext = pressed -- <<< overwrites Ltext
--guess function
LrandomWord = string.lower(randomWord) --ensure no problems with capitalization
letterWrong=0
wordSpots = {} -- <<< clears wordSpots
Вероятно, это (часть) вашей проблемы. Глядя дальше, кажется, вы решили переписывать wordSpots
каждый раз, потому что чуть ниже вы используете
if Ltext == c then
Cguess=Ltext
table.insert(wordSpots, i)
else
несмотря wordSpots
на то, что он не «похож на массив». Вы также не присваиваете ему значение для вставки, поэтому table.insert
переместите все вправо i
на одно место дальше вправо, а затем вставьте nil
— обе вещи, которые вам не нужны. Вы, наверное, просто хотите сказать wordSpots[i] = Ltext
.
Далее, в функции рисования:
tableLen = #wordSpots
— учитывая, что вы задаете только отдельные значения wordSpots
, wordSpots
не является массивом и не имеет реальной длины — поэтому в большинстве случаев вы получите 0. Если вы хотите использовать #
, вы должны инициализировать wordSpots
с false
помощью во всех слотах — например.
randomWord = "word"
wordSpots = {}
for i = 1, #randomWord do wordSpots[i] = false end
но в качестве альтернативы (это, вероятно, лучший подход) вы могли бы выполнить итерацию до #randomWord
вместо #wordSpots
или (еще один подход) выполнить итерацию pairs( wordSpots )
, если вы просто хотите получить все (position,letter)
пары из wordSpots
(они могут встречаться в любом порядке! но здесь все должно быть в порядке.)
Надеюсь, после того, как вы разобрались со всем этим, это должно сработать. (Но это действительно предположение, потому что я не могу следовать вашему коду… Кроме того, я не могу запустить ваш код, потому что некоторые части, похоже, отсутствуют. Что касается вашего следующего вопроса, постарайтесь (а) сделать его работоспособным, (б) постарайтесь сохранить как можно больше материала local
(иначе вы рискуете жутким (взаимодействующим) действием на расстоянии) и (в) удалить материал, который не имеет значения — например, рисование арки. Также есть много «шума», который вы могли бы сначала убрать — например for i=1, tableLen, 1 do
, не требуется ,1
в конце — по умолчанию используются шаги размером 1 — и удаление всех этих дополнительных символов облегчит понимание того, что на самом деле имеет значение. Глядя на весь пример кода, похоже, что в какой-то момент вы добавили ошибку, которая вас смутила, а затем добавили все больше и больше вещей сверху, чтобы попытаться исправить это, и просто сделали это еще более запутанным. Идите в другом направлении, удаляйте материал, пока не увидите, почему что-то (не) работает.)
Совершенно несвязанное замечание по стилю:
Вы, наверное, заметили, как elseif key == "a" or key == "b" or key == "c" or
… «немного» неудобно.
Есть хороший шаблон для обработки входных данных:
typed_letter = function( key )
-- body of the elseif goes here
end
keys = {
escape = love.event.quit,
}
for key in ("abcdefghijklmnopqrstuvwxyz"):gmatch "." do -- copy to a thru z
keys[key] = typed_letter
end
function love.keypressed( key )
local action = keys[key]
if action then return action( key ) end
end
Это превращает статическую elseif
цепочку, написанную вручную, в динамическую структуру данных, которую легко сгенерировать или изменить. (Например, после того, как вы нажали букву, вы можете отключить ее, чтобы нажатие в другой раз ничего не дало — просто удалив ее из таблицы; конечно, в следующем раунде вам придется заново скопировать слоты обратно. Вы также можете заменить всю таблицу другой, если добавите что-то вроде меню, и вам не нужно ничего менять love.keypressed
.)
Ваше соглашение об именах также сбивает с толку. Что означает префикс ‘L’? Для чего ‘C’? Если вы хотите использовать «пробелы в именах», вы можете просто использовать реальные таблицы!(И тогда вы также можете дать им лучшие имена …)