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

Timer that does not interrupt the game

Started by Sir.Mongoose, 26 October 2013 - 09:51 AM
Sir.Mongoose #1
Posted 26 October 2013 - 11:51 AM
Timer that does not interrupt the game
I need a timer for my game that counts down, and prints it's count number and does not interrupt the game's functions.
Yevano #2
Posted 26 October 2013 - 12:40 PM
In your main game loop where you catch events, catch timer events. When you get a timer event, check that the id is that of the last timer you started and start a new timer. Keep a count of how many seconds it has been since the first timer was started so you can print the countdown. Remember that before the loop is started, you'll need an initial timer to get things going.

Here's some example code.


local id = os.startTimer(1)
local count = 10
print(count)
while true do
	local event, p1, p2, p3 = os.pullEvent()
	if event == "timer" and p1 == id then
		id = os.startTimer(1)
		count = count - 1
		print(count)
	end
end
Sir.Mongoose #3
Posted 26 October 2013 - 02:45 PM
I'm a real novice programmer, what are some examples of initial timers?
Kingdaro #4
Posted 26 October 2013 - 03:11 PM
I'd like to point out that os.pullEvent can only take one event filter at a time, and if given multiple, it'll only wait for the first one.
Yevano #5
Posted 26 October 2013 - 03:56 PM
I'd like to point out that os.pullEvent can only take one event filter at a time, and if given multiple, it'll only wait for the first one.

Ah, thanks for the correction. I'll fix the code. It should just be no parameters for any event.

I'm a real novice programmer, what are some examples of initial timers?

The initial timer I was talking about would be the first timer you fire. In the code example, it's the call to os.startTimer on line 1.
Sir.Mongoose #6
Posted 26 October 2013 - 04:21 PM
Okay I put in the example code that you wrote. It works! Though the game is now very slow. Everything updates slowly. :huh:/>
Yevano #7
Posted 26 October 2013 - 04:50 PM
Okay I put in the example code that you wrote. It works! Though the game is now very slow. Everything updates slowly. :huh:/>

Show me your code.
Bomb Bloke #8
Posted 26 October 2013 - 06:36 PM
You'd want to fire up two timers: One for the numeral counter, and one that controls the speed of the game. To modify Yevano's code:

local id, gamespeed = os.startTimer(1), os.startTimer(.2)
local count = 10
print(count)
while true do
        local event, p1, p2, p3 = os.pullEvent()
        if event == "timer" and p1 == id then
                id = os.startTimer(1)
                count = count - 1
                print(count)
        elseif event == "timer" and p1 == gamespeed then
                gamespeed = os.startTimer(.2)  -- The less this value is, the faster the game can go.

                -- Rest of the stuff you previously had in your game loop goes in here instead, eg automatic enemy movement.

        end
end

This code is also not ideal for all situations; you'll need to add more elseifs to handle other events you might be interested in (eg keyboard input).
Sir.Mongoose #9
Posted 26 October 2013 - 07:54 PM
My code. It turns out, the timer does not work. So disregard last. I put in the timer you wrote as an example, Yevano. I spent a little time messing with where to put it. It seems to work if it's the first thing to load below the "while true do" to run, but then it would only count down and display it… But I can't seem to get it to work with the rest of the game. (Btw the code may be a little messy.)
Yevano #10
Posted 27 October 2013 - 09:45 AM
My code. It turns out, the timer does not work. So disregard last. I put in the timer you wrote as an example, Yevano. I spent a little time messing with where to put it. It seems to work if it's the first thing to load below the "while true do" to run, but then it would only count down and display it… But I can't seem to get it to work with the rest of the game. (Btw the code may be a little messy.)

You don't want all your other code within the timer catching if statement. Also you shouldn't call os.pullEvent multiple times in your loop, because you'll miss events. The while loop should look more like this.


while true do
    -- Get the event here.
    local event, p1, p2, p3 = os.pullEvent()

    -- If the previous timer fired...
    if event == "timer" and p1 == id then
        -- Start a new timer and write the countdown.
        id = os.startTimer(1)
        count = count - 1
        term.setTextColor(colors.lightBlue)
        term.setCursorPos(18, 1)
        term.write(" Time Left: "..count.." ")
        term.setTextColor(colors.white)
    end

    -- No matter what happens, go ahead and update game.
    oUpdate()
    display()
    mBoundries()

    if event == "key" then
        -- Get key from p1.
        local key = p1
        if key == 17 or key == 200 then --up
            curY = curY - 1
            char = "^"
        elseif key == 31 or key == 208 then --down
            curY = curY + 1
            char = "v"
        elseif key == 30 or key == 203 then --left
            curX = curX - 1
            char = "<"
        elseif key == 32 or key == 205 then --right
            curX = curX + 1
            char = ">"
        elseif key == 14 then --bspace
            os.reboot()      
        end
    end
end

I commented the code to show exactly what's happening. I also indented your code. It should be more apparent where the if statement begins and ends.
Sir.Mongoose #11
Posted 27 October 2013 - 06:35 PM
Thanks, it works! Though I feel like its lagging a bit when I try to use keys to move. Anyways, thanks!