So, basically I’m trying to get my program to wait for a user interaction OUTSIDE THE DRAW() FUNCTION.
So far I’ve tried repeat loops, while loops, the CurrentTouch var, the function touched(t), I’ve even tried using coroutines in order to set a specific position upon the next user interaction.
What should explain my case best is:
while not touched do
if not (CurrentTouch.state == ENDED) then
touched = true
pos = vec2(CurrentTouch.x, CurrentTouch.y)
end
end
This was also one if my (unsuccessful) tries.
Can anyone help me with that?
@TheMcSebi If you want to wait for user interaction, the touched() function is the best. But I don’t understand what you’re trying to accomplish. You’re question and example don’t help me very much.
@TheMcSebi How close is this to what you want. When you touch the screen the code will execute. When you lift your finger, some of the code won’t execute. If this isn’t what you’re after, can you explain more.
displayMode(FULLSCREEN)
function setup()
x,y=WIDTH/2,200
counter=0
fontSize(30)
end
function draw()
background(0)
if not touch then
fill(255)
text("waiting for someone to touch the screen",WIDTH/2,HEIGHT/2)
text(counter,WIDTH/2,HEIGHT/2-100)
sprite("Planet Cute:Character Horn Girl",x,y)
sprite("Planet Cute:Character Boy",WIDTH-x,HEIGHT-y)
return
end
text("someone touched the screen",WIDTH/2,HEIGHT/2)
text("so the rest of function draw will run",WIDTH/2,HEIGHT/2-50)
x=(x+5)%WIDTH
y=(y+5)%HEIGHT
sprite("Planet Cute:Character Horn Girl",x,y)
sprite("Planet Cute:Character Boy",WIDTH-x,HEIGHT-y)
counter=counter+1
text(counter,WIDTH/2,HEIGHT/2-100)
end
function touched(t)
if t.state==BEGAN then
touch=true
end
if t.state==ENDED then
touch=false
end
end
@dave1707
I’ve tried to accomplish this without using the draw function in any way.
For example if I press a button which executes a function (let’s say setPosition()) This function then requires a screen touch to continue.
function setup()
somePositionThing = vec2(0, 0)
parameter.action("set some position stuff", "setPosition")
end
function setPosition()
local pos = "the next touch on screen, but idle as long as the screen hasn't been touched"
somePositionThing = pos
end
Maybe this example makes it more clear, thanks for your help
It’s not a huge problem if this isn’t possible, I’m just trying to keep my code as clean as possible. If there is no way to achieve this in LUA, I’m simply gonna use the draw loop with a little helper function.
This didn’t work because i guess the touched function only gets refreshed after the draw function has successfully ended. Or something like that. The viewer freezes every time this function gets called because apparently it never reaches the position where it sets ‘touched’ to true.
function theButton()
while not touched do
for k,touch in pairs(touches) do
while not (touch.state == ENDED) do
myPos = vec2(touch.x, touch.y)
touched = true
end
end
end
end
function touched(touch)
if not touches then touches = {} end
if touch.state == ENDED then
touches[touch.id] = nil
else
touches[touch.id] = touch
end
end
That I initialized the touches table within the first screen touch is NOT the problem, because until it reaches the ‘for in pairs’-loop there will always be at least a few screen touches.
Well, I know it can be simple as that, but my intention was to achieve all that without writing anything inside the draw function. Since that doesn’t seem to be possible I guess I have to create a hook then… Thank you anyway
If I find a fancy way using coroutines I’m going to post it here for educational purpose.
@TheMcSebi - I really can’t see why you don’t want to put anything in draw. Although it’s called draw, it is really an “update everything” function, which suits your purpose. So you could write a very compact draw function
function draw()
RunChecks() --do checks for touched, other housekeeping
DrawScreen() --draw on screen, based on state of program
end
The fundamental difference in Codea is that it is a movie, ticking by at 60 frames a second. It’s not a normal program where you can pause execution while waiting for a touch. In Codea, you must keep the draw function ticking along, and do checks inside it if you want.
Using coroutines or hooks or other fancy techniques is a distortion of Codea’s design, and completely unnecessary. Codea users have written many hundreds of different and often complex programs without any need for this. If you want to do it for fun, so be it, but it’s likely to just create unnecessary complexity.
@TheMcSebi Here’s a program that doesn’t use draw() or anything else besides the touched() function. If you don’t use the draw() function, you can’t show anything on the screen. As you can see here, the only thing you can do is print something in the output window. If printing information is all you want to do based on where someone touches the screen, then this will work. In one of your posts above you say “If I press a button which executes a function”, guess what, you can’t display a button without using draw().
function touched(t)
if t.state==BEGAN then
output.clear()
print("began")
if t.y>HEIGHT/2 then
print("you touched above the middle")
else
print("you touched below the middle")
end
end
if t.state==MOVING then
print("moving")
end
if t.state==ENDED then
print("end")
end
end
@Ignatz I have to disagree on one of your statements above ‘all Lua code must finish before draw or touched will run’. If you put a very large ‘for’ loop in draw that takes several seconds to complete, the touched function will still execute. For instance, if you put a counter in the touched function that increments every time the screen is touched, you can touch the screen and it will recognize how many times you touched the screen even though the ‘for’ loop is still running. Here’s an example. You can adjust the for loop size.
function setup()
cnt=0
end
function draw()
print("start")
for z=1,50000000 do
a=math.sqrt(z)
end
print("end")
end
function touched(t)
if t.state==BEGAN then
cnt=cnt+1
print(cnt)
end
end
@se24vad Even though the touched function knows about touches during a long loop, it still doesn’t allow you to do anything with the information until the loop is finished. That tells me that Codea isn’t the one seeing the touch. I think it’s the operating system that’s getting the touch information, then when Codea finishes the loop, the touched function executes and gets the information and processes it. So I don’t think there’s any asynchronous code. Everything just waits it’s turn.
@se24vad This verifies my thoughts above, about the operating system recognizing the touches and then when the for loop and draw is finished, the touched() function gets its turn and gets the information. I added a time when draw start and ends and when the touch gets processed. If you run this and tap the screen several times while the for loop is running, the time reported by the screen touches happens after the draw end time, even though the touches actually happened before draw ended.
function setup()
cnt=0
end
function draw()
print("start",os.clock())
for z=1,50000000 do
a=math.sqrt(z)
end
print("end",os.clock())
end
function touched(t)
if t.state==BEGAN then
cnt=cnt+1
print(cnt,os.clock())
end
end
Hey, maybe that’s how quantum mechanics works - there is a draw loop and a touch event - so the whole universe is a Codea program, running on a rather large iPad! :-j