-- screen functions
function border()
local w, h = term.getSize()
local s = "+"..string.rep("-", w - 2).."+"
term.setCursorPos(1, 1)
term.write(s)
for y = 2, h - 1 do
term.setCursorPos(1, y)
term.write("|")
term.setCursorPos(w, y)
term.write("|")
end
term.setCursorPos(1, h)
term.write(s)
end
function kirbyEnter()
local mY = mY/2
term.setCursorPos(2,mY)
write(">")
term.setCursorPos(2,mY)
sleep(.2)
write("')>")
term.setCursorPos(2,mY)
sleep(.2)
write(".')>")
term.setCursorPos(2,mY)
sleep(.2)
write("('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write("<('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V') ")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V')")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V')")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V')")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
end
function kirbyDance(mX,mY)
local mX = mX/2
local mY = mY/2
term.setCursorPos(mX - 4,mY)
write("^('.')>")
sleep(.5)
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("^('.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("^('.')>")
term.setCursorPos(mX - 4 ,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')> ")
sleep(.5)
term.setCursorPos(mX - 4,mY)
end
function select()
term.setCursorPos(2,10)
write("Make your selection")
term.setCursorPos(2,12)
write("Dance")
term.setCursorPos(2,17)
write("Selection: ")
--other options available in the future
local input = read()
if input == "dance" then
kirbyDance(mX, mY)
else
print("INVALID")
term.clear()
border()
select()
end
end
function kirbyIdle()
local mX = mX/2
local mY = mY/2
while true do
term.setCursorPos(mX - 4,mY)
write("<('.')>")
sleep(5)
term.setCursorPos(mX - 4,mY)
write("<(-.-)>")
sleep(.5)
end
end
-- end screen functions
mX, mY = term.getSize()
term.clear()
border()
kirbyEnter()
parallel.waitForAny(kirbyIdle,select)
So far, I only want this to run once. Waiting for the input, and then just stopping.
This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Proof of concept help, with parallel API.
Started by Cranium, 03 August 2012 - 11:10 PMPosted 04 August 2012 - 01:10 AM
I have been trying to complete a proof of concept, whereas a user could have an animated menu, while it is waiting for an input from the user. So far, I have it waiting for an input just fine, but I have been having problems with it trying to execute other code, since for an animation to work, I need for the first animation to loop. My goal with the proof of concept is to have a character, in this case Kirby, enter, and then wait in the middle of the screen for the user input. I have only one command to give Kirby at this time, and that is to DANCE! Problem is, when I give him the dance command, the idle command is still running due to the parallel API. Here is the code I have so far, and much of it has been generously worked on by the other members of the Ask a Pro section:
Posted 04 August 2012 - 01:36 AM
Well, I guess you could break the menu/selection loop, so the parallel call will return, then you use the selection from the menu to run the corresponding function. Put that in a loop and it should work. But there's an easier way: don't use parallel. Use another menu that doesn't call read, so you can simply use events. I'll work on it and post what I get.
Posted 04 August 2012 - 01:56 AM
I have made some modifications to your code fixed part of the animation and set up some control functions Please try this.
Spoiler
local bIsDancing = false
local termX,termY = 1,1
-- screen functions
function border()
local w, h = term.getSize()
local s = "+"..string.rep("-", w - 2).."+"
term.setCursorPos(1, 1)
term.write(s)
for y = 2, h - 1 do
term.setCursorPos(1, y)
term.write("|")
term.setCursorPos(w, y)
term.write("|")
end
term.setCursorPos(1, h)
term.write(s)
end
function kirbyEnter()
local mY = mY/2
term.setCursorPos(2,mY)
write(">")
term.setCursorPos(2,mY)
sleep(.2)
write("')>")
term.setCursorPos(2,mY)
sleep(.2)
write(".')>")
term.setCursorPos(2,mY)
sleep(.2)
write("('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write("<('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V') ")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V') ")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V')")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ( V')")
term.setCursorPos(2,mY)
sleep(.2)
write(" <( )>")
term.setCursorPos(2,mY)
sleep(.2)
write(" ('V )")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
term.setCursorPos(2,mY)
sleep(.2)
write(" <('.')>")
end
function kirbyDance(mX,mY)
local mX = mX/2
local mY = mY/2
term.setCursorPos(mX - 4,mY)
write("^('.')>")
sleep(.5)
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("^('.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("^('.')>")
term.setCursorPos(mX - 4 ,mY)
sleep(.5)
write("<('.')^")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write(" (>'.')>")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.'<) ")
term.setCursorPos(mX - 4,mY)
sleep(.5)
write("<('.')> ")
sleep(.5)
term.setCursorPos(mX - 4,mY)
end
function select()
term.setCursorPos(2,10)
write("Make your selection")
term.setCursorPos(2,12)
write("Dance")
term.setCursorPos(2,17)
term.clearLine()
write("Selection: ")
--other options available in the future
local input = read()
if input == "dance" then
bIsDancing = true
kirbyDance(mX, mY)
bIsDancing = false
else
print("INVALID")
end
end
function SelectControl()
while true do
select()
end
end
function BorderControl() --lol
while true do
termX,termY = term.getCursorPos()
border()
term.setCursorPos(termX,termY)
coroutine.yield()
end
end
function kirbyIdle()
local mX = mX/2
local mY = mY/2
while true do
if not bIsDancing then
termX,termY = term.getCursorPos()
term.setCursorPos(mX - 4,mY)
term.clearLine()
write("<('.')>")
term.setCursorPos(termX,termY)
end
sleep(5)
if not bIsDancing then
termX,termY = term.getCursorPos()
term.setCursorPos(mX - 4,mY)
term.clearLine()
write("<(-.-)>")
term.setCursorPos(termX,termY)
end
sleep(.5)
end
end
-- end screen functions
mX, mY = term.getSize()
term.clear()
border()
kirbyEnter()
parallel.waitForAny(kirbyIdle,SelectControl,BorderControl)
Posted 04 August 2012 - 02:11 AM
Ok, you totally fixed it!!! Now I just have to have Kirby dance a little better!I have made some modifications to your code fixed part of the animation and set up some control functions Please try this.Spoiler
local bIsDancing = false local termX,termY = 1,1 -- screen functions function border() local w, h = term.getSize() local s = "+"..string.rep("-", w - 2).."+" term.setCursorPos(1, 1) term.write(s) for y = 2, h - 1 do term.setCursorPos(1, y) term.write("|") term.setCursorPos(w, y) term.write("|") end term.setCursorPos(1, h) term.write(s) end function kirbyEnter() local mY = mY/2 term.setCursorPos(2,mY) write(">") term.setCursorPos(2,mY) sleep(.2) write("')>") term.setCursorPos(2,mY) sleep(.2) write(".')>") term.setCursorPos(2,mY) sleep(.2) write("('.')>") term.setCursorPos(2,mY) sleep(.2) write("<('.')>") term.setCursorPos(2,mY) sleep(.2) write(" ( V') ") term.setCursorPos(2,mY) sleep(.2) write(" <( )>") term.setCursorPos(2,mY) sleep(.2) write(" ('V )") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") term.setCursorPos(2,mY) sleep(.2) write(" ( V') ") term.setCursorPos(2,mY) sleep(.2) write(" <( )>") term.setCursorPos(2,mY) sleep(.2) write(" ('V )") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") term.setCursorPos(2,mY) sleep(.2) write(" ( V')") term.setCursorPos(2,mY) sleep(.2) write(" <( )>") term.setCursorPos(2,mY) sleep(.2) write(" ('V )") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") term.setCursorPos(2,mY) sleep(.2) write(" ( V')") term.setCursorPos(2,mY) sleep(.2) write(" <( )>") term.setCursorPos(2,mY) sleep(.2) write(" ('V )") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") term.setCursorPos(2,mY) sleep(.2) write(" <('.')>") end function kirbyDance(mX,mY) local mX = mX/2 local mY = mY/2 term.setCursorPos(mX - 4,mY) write("^('.')>") sleep(.5) term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.')^") term.setCursorPos(mX - 4,mY) sleep(.5) write("^('.')>") term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.')^") term.setCursorPos(mX - 4,mY) sleep(.5) write("^('.')>") term.setCursorPos(mX - 4 ,mY) sleep(.5) write("<('.')^") term.setCursorPos(mX - 4,mY) sleep(.5) write(" (>'.')>") term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.'<) ") term.setCursorPos(mX - 4,mY) sleep(.5) write(" (>'.')>") term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.'<) ") term.setCursorPos(mX - 4,mY) sleep(.5) write(" (>'.')>") term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.'<) ") term.setCursorPos(mX - 4,mY) sleep(.5) write("<('.')> ") sleep(.5) term.setCursorPos(mX - 4,mY) end function select() term.setCursorPos(2,10) write("Make your selection") term.setCursorPos(2,12) write("Dance") term.setCursorPos(2,17) term.clearLine() write("Selection: ") --other options available in the future local input = read() if input == "dance" then bIsDancing = true kirbyDance(mX, mY) bIsDancing = false else print("INVALID") end end function SelectControl() while true do select() end end function BorderControl() --lol while true do termX,termY = term.getCursorPos() border() term.setCursorPos(termX,termY) coroutine.yield() end end function kirbyIdle() local mX = mX/2 local mY = mY/2 while true do if not bIsDancing then termX,termY = term.getCursorPos() term.setCursorPos(mX - 4,mY) term.clearLine() write("<('.')>") term.setCursorPos(termX,termY) end sleep(5) if not bIsDancing then termX,termY = term.getCursorPos() term.setCursorPos(mX - 4,mY) term.clearLine() write("<(-.-)>") term.setCursorPos(termX,termY) end sleep(.5) end end -- end screen functions mX, mY = term.getSize() term.clear() border() kirbyEnter() parallel.waitForAny(kirbyIdle,SelectControl,BorderControl)
Posted 04 August 2012 - 02:17 AM
Ok, a little late but here's what I have:
It uses another menu, so it doesn't need parallel, and the animations are easier to change. I tested it and works fine, although I'm not sure if the enter animation should look like that :P/>/>
Spoiler
local tEnterAnimation = {
">",
"')>",
".')>",
"('.')>",
"<('.')>",
" ( V') ",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" <('.')>",
" <('.')>"
}
local tDanceAnimation = {
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
"<('.')> "
}
local tIdleAnimation = {
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<(-.-)>"
}
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local function drawAnimation(t)
for _,s in ipairs(t) do
clear()
write(s)
sleep(0.2)
end
end
local nFrame = 1
local function drawIdleAnimation()
term.setCursorPos(1, 1)
term.clearLine()
write(tIdleAnimation[nFrame])
end
local bExit = false
local tOptions = {
"Dance",
"Exit"
}
local tActions = {
function()
drawAnimation(tDanceAnimation)
end,
function()
bExit = true
end
}
local nSelected = 1
local function redrawMenu()
term.setCursorPos(1, 2)
for i, s in ipairs(tOptions) do
if i == nSelected then
print(">", s)
else
print(" ", s)
end
end
end
local function keyPressed(key)
if key == 208 then -- Down
if nSelected < #tOptions then
nSelected = nSelected + 1
else
nSelected = 1
end
elseif key == 200 then -- Up
if nSelected > 1 then
nSelected = nSelected - 1
else
nSelected = #tOptions
end
elseif key == 28 then -- Enter
tActions[nSelected]()
end
end
drawAnimation(tEnterAnimation)
clear()
local timer = os.startTimer(0.5)
while not bExit do
clear()
drawIdleAnimation()
redrawMenu()
local evt, arg = os.pullEvent()
if evt == "key" then
keyPressed(arg)
elseif evt == "timer" then
nFrame = nFrame + 1
if nFrame > #tIdleAnimation then
nFrame = 1
end
timer = os.startTimer(0.5)
end
end
clear()
Posted 04 August 2012 - 02:25 AM
I always find it interesting our differing philosophies I try to work with the provided code as much as possible and you make the best possible solution to the problem demonstrated very well in our codes above.Ok, a little late but here's what I have:
– snip –
It uses another menu, so it doesn't need parallel, and the animations are easier to change. I tested it and works fine, although I'm not sure if the enter animation should look like that :P/>/>
Posted 04 August 2012 - 02:30 AM
MysticT, I only have one question about your code:
What is the _,s in the drawAnimation() function, and what does it do? I have never seen that before.
What is the _,s in the drawAnimation() function, and what does it do? I have never seen that before.
Posted 04 August 2012 - 02:32 AM
It's just some variables used in the for loop. The _ is used normally to name variables that you don't use.MysticT, I only have one question about your code:
What is the _,s in the drawAnimation() function, and what does it do? I have never seen that before.
Posted 04 August 2012 - 02:40 AM
Ok, that's neat. BTW, the code you have is great, but it did not keep looping the idle after giving the initial command. Any way around this?
Posted 04 August 2012 - 02:45 AM
Did you try it? The idle animation works fine for me, even after doing the dance.
Posted 04 August 2012 - 02:49 AM
Yeah, when I hit enter to select dance, he just stays there after dancing. No more blinking eyes…
Edit: I am using a CC emulator…if that means anything. I'm using this one.
Edit: I am using a CC emulator…if that means anything. I'm using this one.
Posted 04 August 2012 - 02:52 AM
I tested it and I have same problem animation doesn't play because timer event occurs during animation meaning it ends the timer loopDid you try it? The idle animation works fine for me, even after doing the dance.
Posted 04 August 2012 - 02:55 AM
fixed MysticT's code
Spoiler
local tEnterAnimation = {
">",
"')>",
".')>",
"('.')>",
"<('.')>",
" ( V') ",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" <('.')>",
" <('.')>"
}
local tDanceAnimation = {
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
"<('.')> "
}
local tIdleAnimation = {
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<(-.-)>"
}
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local function drawAnimation(t)
for _,s in ipairs(t) do
clear()
write(s)
sleep(0.2)
end
end
local nFrame = 1
local function drawIdleAnimation()
term.setCursorPos(1, 1)
term.clearLine()
write(tIdleAnimation[nFrame])
end
local bExit = false
local tOptions = {
"Dance",
"Exit"
}
local tActions = {
function()
drawAnimation(tDanceAnimation)
end,
function()
bExit = true
end
}
local nSelected = 1
local function redrawMenu()
term.setCursorPos(1, 2)
for i, s in ipairs(tOptions) do
if i == nSelected then
print(">", s)
else
print(" ", s)
end
end
end
local function keyPressed(key)
if key == 208 then -- Down
if nSelected < #tOptions then
nSelected = nSelected + 1
else
nSelected = 1
end
elseif key == 200 then -- Up
if nSelected > 1 then
nSelected = nSelected - 1
else
nSelected = #tOptions
end
elseif key == 28 then -- Enter
tActions[nSelected]()
end
end
drawAnimation(tEnterAnimation)
clear()
local timer = os.startTimer(0.5)
while not bExit do
clear()
drawIdleAnimation()
redrawMenu()
local evt, arg = os.pullEvent()
if evt == "key" then
keyPressed(arg)
timer = os.startTimer(0.5)
elseif evt == "timer" then
nFrame = nFrame + 1
if nFrame > #tIdleAnimation then
nFrame = 1
end
timer = os.startTimer(0.5)
end
end
clear()
Posted 04 August 2012 - 02:55 AM
Hmm, you'r right, I forgot to reset the timer. This should work:
Spoiler
local tEnterAnimation = {
">",
"')>",
".')>",
"('.')>",
"<('.')>",
" ( V') ",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" ( V')",
" <( )>",
" ('V )",
" <('.')>",
" <('.')>",
" <('.')>"
}
local tDanceAnimation = {
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
"^('.')>",
"<('.')^",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
" (>'.')>",
"<('.'<) ",
"<('.')> "
}
local tIdleAnimation = {
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<('.')>",
"<(-.-)>"
}
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local function drawAnimation(t)
for _,s in ipairs(t) do
clear()
write(s)
sleep(0.2)
end
end
local nFrame = 1
local function drawIdleAnimation()
term.setCursorPos(1, 1)
term.clearLine()
write(tIdleAnimation[nFrame])
end
local bExit = false
local tOptions = {
"Dance",
"Exit"
}
local tActions = {
function()
drawAnimation(tDanceAnimation)
end,
function()
bExit = true
end
}
local nSelected = 1
local function redrawMenu()
term.setCursorPos(1, 2)
for i, s in ipairs(tOptions) do
if i == nSelected then
print(">", s)
else
print(" ", s)
end
end
end
local timer
local function keyPressed(key)
if key == 208 then -- Down
if nSelected < #tOptions then
nSelected = nSelected + 1
else
nSelected = 1
end
elseif key == 200 then -- Up
if nSelected > 1 then
nSelected = nSelected - 1
else
nSelected = #tOptions
end
elseif key == 28 then -- Enter
tActions[nSelected]()
timer = os.startTimer(0.5)
end
end
drawAnimation(tEnterAnimation)
clear()
timer = os.startTimer(0.5)
while not bExit do
clear()
drawIdleAnimation()
redrawMenu()
local evt, arg = os.pullEvent()
if evt == "key" then
keyPressed(arg)
elseif evt == "timer" then
nFrame = nFrame + 1
if nFrame > #tIdleAnimation then
nFrame = 1
end
timer = os.startTimer(0.5)
end
end
clear()
That would work, but it would reset the timer each time you press a key, so the idle animation wouldn't work correctly.fixed MysticT's code
– snip –