Is it possible to code using lua to play an animation sequence until a tap is received?
I ask as I have tried on windows 10 and all I get is a blank screen and non responsive app from which I have to cancel via the red X.
Is it possible to code using lua to play an animation sequence until a tap is received?
I ask as I have tried on windows 10 and all I get is a blank screen and non responsive app from which I have to cancel via the red X.
Could you provide us with the code you’re currently using?
I tried to put a delay in a repeat loop so the animation sequences continue and the sprite position is change for each itaration.
I have two problems. One is that I cant seem to get the thing to stop when esc is pressed on the PC but more importantly that the repeat goes so fast and completly ignores the delay I trying to use.
The code for the esc key is a simple key event and should if pressed set teh codition for the loop to finish. I know this will wokr as I setup a counter to limit the number of loops. but the debug details being presented only show at the end not during the iteration.
Here is the code for the delay routine which demonstates the problem.
local msg
local msgGroup = display.newGroup()
local sleepGroup
function endSleep()
msg = “END”
showmsg = display.newText(sleepGroup,msg,260,80,native.systemfont,50)
end
– Sleeps for x milliseconds
function usleep(nMilliseconds)
sleepGroup = display.newGroup()
msg = “SLEEP”
showmsg = display.newText(sleepGroup,msg,80,20,native.systemfont,50)
timer.performWithDelay(nMilliseconds,endSleep)
– display.remove(sleepGroup)
end
msg = “Start: test”
showmsg = display.newText(msgGroup, msg, 120, 80, native.systemFont, 36 )
usleep(5000)
msg = “Should see END”
showmsg = display.newText(msgGroup, msg, 140, 140, native.systemFont, 36 )
msg = “above before this”
showmsg = display.newText(msgGroup, msg, 140, 200, native.systemFont, 36 )
–display.remove(msgGroup)
What result are you expecting? Your code display all text (as it would) and then displays END after 5 seconds.
I don’t really see anything that you are animating there other than changing a text object from “SLEEP” to “END”.
It seems like you’re trying to implement busy-wait loops or a sleep function. Corona doesn’t work that way. It’s event driven. Things happen when some action happens like a screen touch occurs, or when a timer or a transition completes.
Corona sits in the background waiting for things to happen. Now depending on what your animation is, and that’s the code we need to see, the answer to how to make it stop on touch is going to vary. Are you using sprites for animation? Are you using transition.to() to move things? Do you need things to move every screen update?
We need more information on what you’re trying to accomplish.
Rob
When we hear the word animation, we think sprite: https://docs.coronalabs.com/api/library/display/newSprite.html
Just FYR, if you really want code execution to pause for 5 seconds then this will work (but not advised)
local function pause(seconds) local now = os.time() while os.time() \< now + seconds do end end print("pausing...") pause(5) print("pause finished")
@sgs,
It seems that if that works you would be essentially locking the frame for 5 seconds. i.e. That looks like it will block the game’s ability to move on and process the next frame.
Better to use events as Rob pointed out or if one really needs a passable piece of code, Coroutines: https://roaminggamer.github.io/RGDocs/pages/SSK2/external/#wait-starcrunch
I did say it was “not advised” as it is thread-blocking code. But there are times when it is useful.
For example, I use it in main.lua to force a hard pause to give my logo some display time before it is replaced with the main loading screen. (Yes I know there are other ways but pause(2) is just so simple).
It can also be useful in debugging if say you are logging lots of values to console but you need to cross-reference those values to display objects as it hard pauses transitions, animations and listeners.
Thanks for all the responses.
I am used to programming a game loop in which things happen even when there is no user input.
I wanted to use 4 movement sequences of a mouse running North, South, East, West and move the sprite around the screen by setting its x y and switching the sequence associated with the current direction and randomly switching for North/South to East/West.
I used a game loop in a repeat until in which this action takes place but when run the screen is blank and nothing is seen.
I programmed a counter so I could stop the loop after a number of iterations and when stopped the screen shows what I expected.
I should be able to stop the run by pressing esc key as I have a listener checking for that key and it sets the value of the until clause.
sample uses coroutine but same problem.
I wanted a delay so I could see the screen action but am unable to do that.
Having read the response about Corona not working that way (no wait or sleep or even release to the system) so it looks like I might need to look for another development tool.
copy of code here:
–
– main.lua
– run a mouse round the screen until user presses esc
myaudio = audio.loadSound(“mousesqueak.mp3”)
SCREEN_WIDTH = display.contentWidth
SCREEN_HEIGHT = display.contentHeight
direction = “S”
xstep=40
ystep=20
xplot=0
yplot=0
xpos=0
ypos=0
index=0
numFrames=3
frameSize=128
msg=""
options = {width=128,height=128,numFrames=12,sheetContentWidth=385,sheetContentHeight=512}
image = graphics.newImageSheet(“mouse.png”,system.ResourceDirectory,options)
myRect = display.newRect(SCREEN_WIDTH/2,SCREEN_HEIGHT/2,SCREEN_WIDTH,SCREEN_HEIGHT)
paint = {0}
– sequences tables
Move = {
– consecutive frames sequence
{
name = “Move”,
start = 6,
count = 2,
time = 1000,
loopCount = 0,
loopDirection = “bounce”
}
}
South = {
– consecutive frames sequence
{
name = “South”,
start = 1,
count = 3,
time = 1000,
loopCount = 0,
loopDirection = “bounce”
}
}
West = {
– consecutive frames sequence
{
name = “West”,
start = 4,
count = 3,
time = 1000,
loopCount = 0,
loopDirection = “bounce”
}
}
East = {
– consecutive frames sequence
{
name = “East”,
start = 7,
count = 3,
time = 1000,
loopCount = 0,
loopDirection = “bounce”
}
}
North = {
– consecutive frames sequence
{
name = “North”,
start = 4,
count = 3,
time = 1000,
loopCount = 0,
loopDirection = “bounce”
}
}
mainGroup = display.newGroup()
mainGroup.x = 0
mainGroup.y = 0
msgGroup = display.newGroup()
mouseMove = display.newSprite(mainGroup, image, Move )
mouseSouth = display.newSprite(mainGroup, image, South )
mouseWest = display.newSprite(mainGroup, image,West )
mouseEast = display.newSprite(mainGroup, image,East )
mouseNorth = display.newSprite(mainGroup, image,North )
loopit = true
mouse = display.newSprite(mainGroup,image,South)
mouse.x = display.contentCenterX
mouse.y = display.contentHeight - 100
mouse:setSequence(mouseMove)
xpos = mouse.x
ypos = mouse.y-ystep
mouse.y = ypos
mouse:play()
xplot = mouse.x
xpos = xplot
yplot = mouse.y
ypos = yplot
msg = “Start: xplot=” … tostring(xplot) … " yplot=" … tostring(yplot)
showmsg = display.newText(msgGroup, msg, 200, 80, native.systemFont, 36 )
–usleep(10000)
display.remove(msgGroup)
msgGroup = display.newGroup()
myRect:setFillColor(0.5)
myRect:setStrokeColor(1,0,0)
local function onKeyEvent(event)
if (event.keyName == “esc”) then
loopit=false
return true
end
return false
end
– Add the key event listener
Runtime:addEventListener( “key”, onKeyEvent )
gameLoop = coroutine.create(function()
repeat
msg = “Loop: " … tostring(loopCount) … " xplot=” … tostring(xplot) … " yplot=" … tostring(yplot)
showmsg = display.newText( msgGroup, msg, 220, 80, native.systemFont, 36 )
msg = “Screen: width=” … tostring(SCREEN_WIDTH) … " height=" … tostring(SCREEN_HEIGHT)
showmsg = display.newText(msgGroup, msg, 220, 140, native.systemFont, 36 )
msg = “Mouse: x=” … tostring(mouse.x) … " y=" … tostring(mouse.y)
showmsg = display.newText(msgGroup, msg, 220, 200, native.systemFont, 36 )
if (direction==“S”) then
mouse.x = xpos
mouse.y = ypos
yplot=yplot+ystep
if (yplot>SCREEN_HEIGHT) then
yplot=yplot-ystep
direction=“N”
ypos=yplot
mouse.x = xpos
mouse.y = ypos
mouse:setSequence(“North”)
end
if (yplot<(SCREEN_HEIGHT/2) and (math.random() >0.95)) then
direction=“E”
audio.play(myaudio)
mouse:setSequence(“East”)
end
ypos = yplot
mouse.y = ypos
mouse:play()
elseif (direction == “N”) then
mouse.x = xpos
mouse.y = ypos
yplot=yplot-ystep
if (yplot<0) then
yplot=yplot+ystep
direction=“S”
mouse:setSequence(“South”)
Ypos=Yplot
mouse.Y = Ypos
end
ypos=yplot
mouse.y = ypos
mouse:play()
elseif (direction == “E”) then
mouse.x = xpos
mouse.y = ypos
xplot=xplot+xstep;
if (xplot>SCREEN_WIDTH) then
xplot=xplot-xstep
direction=“W”
mouse.x = xplot
mouse.y = ypos
mouse:setSequence(“West”)
xpos=xplot
end
if ((xplot<SCREEN_WIDTH/2) and (math.random() >0.9)) then
direction=“N”
audio.play(myaudio)
mouse:setSequence(“North”)
xpos=xplot
mouse.x = xpos
end
xpos = xplot
mouse.x = xpos
mouse:play()
elseif (direction == “W”) then
mouse.x = xpos
mouse.y = ypos
xplot=xplot-xstep;
if (xplot<0) then
xplot=xplot+xstep
direction=“E”
mouse:setSequence(“East”)
end
xpos=xplot
mouse.x = xpos
mouse:play()
end
display.remove(msgGroup)
msgGroup = display.newGroup()
until loopit==false
mouse:pause()
end)
print(gameLoop)
Corona can do what you want, you just have to think a little differently.
There are three different ways to move objects under programming control.
Use transition.to() to move from x,y to newX,newY and when it’s complete, call another transition.to() to do the next move. Compute the newX, newY based on some random values where you want to switch from North/South to East/West and continue to repeat that pattern.
Use the Runtime “enterFrame” listener. This is as close to a “game loop” as Corona has. You set up your project to run at 30 frames per second or 60 frames per second. The enterFrame listener function will get called either 30 times per second or 60 times per second or each frame. In that event trigger you can move your object by a fractional amount. You can then make a per-frame determination if you need to change direction.
local function gameLoop( event ) – do your movements and checks to see if you need to turn end Runtime:addEventListener( “enterFrame”, gameLoop )
Use a timer perhaps with physics. You can set your mouse to move a certain direction using physics’ setLinearVelocity() then set a timer to trigger at a random time and call a function to change the linearVelocity in a different direction.
In all three when you determine you’re changing directions, you can change the sprite animation to the proper sequence.
Rob
Wonderful response.
I had developed this on HTML 5 and had
setInterval(loop, 1000 / 20)
to kick off the gameloop.
I was not aware of the similarity in Corona.
I will try that first and think about your other suggestions later for variations to help me to understand Corona better.
Thank you.
Quick addition. Looping is working and mouse wizzing around. Slowed down to 1 FPS and that’s what I wanted.
I changed my esc function to stop it but that is not working. I’m using Close Project at the moment.
Can you suggest anything?
Code segment:
local function onKeyEvent(event)
if (event.keyName == “esc”) then
loopit = false
Runtime:removeEventListener(“enterFrame”,gameLoop)
return true
end
return false
end
– Add the key event listener
Runtime:addEventListener( “key”, onKeyEvent )
Change
if (event.keyName == "esc") then
into
if (event.keyName == "escape") then
Also, if your animation is too fast then increment x and y by smaller values.
Thanks. I thought I read in the documentation that esc and escape were the same.
escape worked.
Changing stepping counts did the speed change.
May add a settings option later so the user can adjust the speed.
I will definitely look at linear velocity method.
Thank you for your patience and help.
The key is labeled “esc” on most keyboards and when people write about it, they will abbreviate it. However, software can only return one atomic value and in our case, the only string you will get back from the key event handler will be “escape”.
Rob
Could you provide us with the code you’re currently using?
I tried to put a delay in a repeat loop so the animation sequences continue and the sprite position is change for each itaration.
I have two problems. One is that I cant seem to get the thing to stop when esc is pressed on the PC but more importantly that the repeat goes so fast and completly ignores the delay I trying to use.
The code for the esc key is a simple key event and should if pressed set teh codition for the loop to finish. I know this will wokr as I setup a counter to limit the number of loops. but the debug details being presented only show at the end not during the iteration.
Here is the code for the delay routine which demonstates the problem.
local msg
local msgGroup = display.newGroup()
local sleepGroup
function endSleep()
msg = “END”
showmsg = display.newText(sleepGroup,msg,260,80,native.systemfont,50)
end
– Sleeps for x milliseconds
function usleep(nMilliseconds)
sleepGroup = display.newGroup()
msg = “SLEEP”
showmsg = display.newText(sleepGroup,msg,80,20,native.systemfont,50)
timer.performWithDelay(nMilliseconds,endSleep)
– display.remove(sleepGroup)
end
msg = “Start: test”
showmsg = display.newText(msgGroup, msg, 120, 80, native.systemFont, 36 )
usleep(5000)
msg = “Should see END”
showmsg = display.newText(msgGroup, msg, 140, 140, native.systemFont, 36 )
msg = “above before this”
showmsg = display.newText(msgGroup, msg, 140, 200, native.systemFont, 36 )
–display.remove(msgGroup)
What result are you expecting? Your code display all text (as it would) and then displays END after 5 seconds.
I don’t really see anything that you are animating there other than changing a text object from “SLEEP” to “END”.
It seems like you’re trying to implement busy-wait loops or a sleep function. Corona doesn’t work that way. It’s event driven. Things happen when some action happens like a screen touch occurs, or when a timer or a transition completes.
Corona sits in the background waiting for things to happen. Now depending on what your animation is, and that’s the code we need to see, the answer to how to make it stop on touch is going to vary. Are you using sprites for animation? Are you using transition.to() to move things? Do you need things to move every screen update?
We need more information on what you’re trying to accomplish.
Rob
When we hear the word animation, we think sprite: https://docs.coronalabs.com/api/library/display/newSprite.html