This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
darth_den's profile picture

pullEvent("key") but continue to loop if no key is pressed

Started by darth_den, 05 February 2013 - 10:01 AM
darth_den #1
Posted 05 February 2013 - 11:01 AM
I am new to lua, as you will be able to tell from my code :)/>/>. I am trying to make the classic game snake/worm. My problem is that i would like to read the key, but if no key is pressed in time the key stays the same as last key pressed. I have managed to sort of get this working. I am getting some odd results, the problem is the snake seems to get faster and faster. Any help would be appreciated.


function locate(x,y)
    term.setCursorPos(x,y)
end
function clear()
    term.clear()
    term.setCursorPos(1,1)
end
function sizetable(tabledata)
    for k,v in pairs(tabledata) do
	    lastkey = k
    end
    return lastkey
end
function InitSnake()
    pos={}
    pos["acr"] = 10
    pos["dwn"] = 2
    table.insert(snake_,1,pos)
    pos={}
    pos["acr"] = 10
    pos["dwn"] = 3
    table.insert(snake_,1,pos)
    pos={}
    pos["acr"] = 10
    pos["dwn"] = 4
    table.insert(snake_,1,pos)
    pos={}
    pos["acr"] = 10
    pos["dwn"] = 5
    table.insert(snake_,1,pos)
    pos={}
    pos["acr"] = 10
    pos["dwn"] = 6
    table.insert(snake_,1,pos)
end
function head(acr,dwn,len)
    pos = {}
    pos["acr"] = acr
    pos["dwn"] = dwn
    table.insert(snake_,1,pos)
    if len ~= nil then
	   table.remove(snake_,len+1)
    end
end
function DisplaySnake()
   for i = sizetable(snake_),1,-1 do	   
	    locate(snake_[i]["acr"],snake_[i]["dwn"])
	    term.write("0")
   end
end

function TrapSnake(acr,dwn)
    if acr > right then
	    acr = left
    end
    if acr < left then
	    acr = right
    end
    if dwn > bottom then
	    dwn = top
    end
    if dwn < top then
	    dwn = bottom
    end
    if acr >= left and acr <= right then
	    acr = acr
    end
    if dwn >= top and dwn <= bottom then
	    dwn = dwn
    end
    return acr,dwn
end
top = 1
bottom = 17
left = 1
right = 51
snake_ = {}

acr_ = 10
dwn_ = 6

clear()
InitSnake()
DisplaySnake()

move = 208
while true do
   timerID = os.startTimer(1)
   event,p1 = os.pullEvent() 
    if event == "key" then
	    move = p1
	    p1 = "timer"		 
    end
    if event == "timer" then
	    if move == 200 then -- up
		    dwn_ = dwn_ - 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)	  
	    elseif move == 208 then -- dwn
		    dwn_ = dwn_ + 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)
	    elseif move == 203 then -- left
		    acr_ = acr_ - 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)   
	    elseif move == 205 then -- right
		    acr_ = acr_ + 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)	 
	    end
	    clear()
	    head(acr_,dwn_,5)
	    DisplaySnake()
    end
end

If you run the code, move the snake arround with cursor keys for a 20 seconds, you will see my problem
Lyqyd #2
Posted 05 February 2013 - 11:05 AM
Split into new topic.

Why not use the keys to set the direction of the snake and only move the snake on the actual timer events?
darth_den #3
Posted 05 February 2013 - 11:54 AM
So I know the forum says, please think before you post, as you can often answer your own question. I knid of have, but I think your comment was a catalyst to make me think a little differently so thank you.

This is the first time i have used the timer event, and I made a schoolboy error, not really understang how the event worked. My error was to startTimer on each itteration of the loop, therfore creating more and more timers, also updating the TimerID variable each loop leaveing me unable to reference the original timer. I doubt anyone else will do such a stoopid thing, but I will post how i fixed it for anyother future confused soul that may have the same problem.

I removed the os.StartTimer from the loop, and placed it outside the loop, then refired a new timer only when the original timers condition was resolved


move = 208
timerID = os.startTimer(1)
while true do
   event,p1 = os.pullEvent() 
    if event == "key" then
	    move = p1
    elseif event == "timer" and p1 == timerID then 
	    if move == 200 then -- up
		    dwn_ = dwn_ - 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)	  
	    elseif move == 208 then -- dwn
		    dwn_ = dwn_ + 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)
	    elseif move == 203 then -- left
		    acr_ = acr_ - 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)   
	    elseif move == 205 then -- right
		    acr_ = acr_ + 1
		    acr_,dwn_ = TrapSnake(acr_,dwn_)
			  
	    end
	    clear()
	    head(acr_,dwn_,5)
	    DisplaySnake()
	    timerID = os.startTimer(0.5)
    end
end