Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Triggering the pause function Codea has _ FIXED wrote some Lua code

edited July 3 in Questions Posts: 276
Hi all,

Has anyone had any luck coding in the pause function that Codea has when you test your games? Am looking to trigger a game pause and instigate a button to unpause or go back to the game's menu

Thanks
Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 5,896

    Are you talking about the physics.pause . There isn't a true pause for Codea because it's always running. If you want a pause, you have to code it yourself. It isn't hard if you plan for it early in the coding cycle.

  • Posts: 276
    Thanks @dave1707 - no it's the Codea pause level I'm hoping to expose. You know when you run your program and have access to the buttons bottom left, one is a pause in Xcode that overrides the play state of Lua.
  • dave1707dave1707 Mod
    Posts: 5,896

    @Majormorgan Oh, that one. I don't do anything with XCode, so I can't give you any help with that.

  • Posts: 207

    @Majormorgan I know how to do it, but it has to be written in Obj-C, I have the code on my computer, do you want me to put it on this thread

  • Posts: 1,983
    Why does it specifically have to be the Codea pause?
  • Posts: 276
    Hey @CamelCoder that would be cool. I might be able to get that to work!

    Hey @yojimbo2000 - it's only because it's the only code I know that totally pauses everything in Codea. To go in and write code that will stop everything in Lua might not be feasible with how far I've come with it. A lot of code is independent - for example each alien shoots, moves and detects according to its own time. I'll look into it, but I know the Codea code overrides everything.

    Thanks!
  • dave1707dave1707 Mod
    Posts: 5,896

    @Majormorgan The Codea pause doesn't pause everything. Try the below program of a physics ball falling. Press the Codea pause button just after starting the program. Notice what the y value is. Wait a few seconds and press the pause button again to restart the code. The ball will be completely off the screen. Notice what the y value is again.

    function setup()
        b=physics.body(CIRCLE,30)
        b.x=WIDTH/2
        b.y=HEIGHT
    end
    
    function draw()
        background(40, 40, 50)
        fill(255)
        ellipse(b.x,b.y,60)
        text("y value = "..b.y//1,120,HEIGHT-100)
    end
    
  • Posts: 1,983

    @Majormorgan If we think about what Codea executes each frame other than the draw loop: physics, tweens, sounds, responses to touch events and orientation changes. Physics has a pause command, tweens can be paused with the code here: https://codea.io/talk/discussion/4474/pause-resume-tweens

  • dave1707dave1707 Mod
    Posts: 5,896

    @Majormorgan Here's another problem with trying to pause Codea. It doesn't stop the screen touch. Run this program and press Codea pause. You'll see the draw count stop. Tap the screen 10 times and then press Codea pause to resume the code. You'll see the touch count shows how many times you tapped the screen. Apparently the iOS touch routine buffers the touches and then passes them to Codea once it restarts.

    function setup()
        drawCnt=0
        tchCnt=0
    end
    
    function draw()
        background(40, 40, 50)
        fill(255)
        drawCnt=drawCnt+1
        text("draw count  "..drawCnt,200,500)
        text("touch count  "..tchCnt,200,400)
    end
    
    function touched(t)
        if t.state==BEGAN then
            tchCnt=tchCnt+1
        end
    end
    
  • Posts: 207

    @Majormorgan In my most recent app, I do show ads if the user wants to watch them for free coins. I had to pause Codea when the ads show just so nothing continues while the ad is being played. While I was testing it, I realized that the music and sounds in the background still play! So @yojimbo2000 and @dave1707 are correct. Btw, I'll get the code up for how to do it once my iTunes stops acting up, it won't let me go to xCode.

  • Posts: 1,983

    To go in and write code that will stop everything in Lua might not be feasible with how far I've come with it.

    @Majormorgan that right there is your code saying "for the love of God stop adding new features and refactor me!"

    What you should aim for is no function longer than 10 lines, clean separation of concerns, updating logic and rendering logic kept separate, and so on. Then it's as simple as:

    function draw()
        if not paused then
            currentState:update()
        end
        currentState:draw()
    end
    
  • JohnJohn Admin Mod
    Posts: 404

    The real question is that once codea is paused, how do you plan to unpause it?

  • Posts: 207

    @Majormorgan Basically, you just have to go to a .m file that has a StandaloneViewController imported. Then, in the function where you want to pause Codea, say StandaloneViewController *cc=self.viewController, then the view controller will be stored into the cc variable, then to pause it, do:

    cc.paused=YES;
    

    @John To unpause it, it’s as simple as...

    cc.paused=NO;
    
  • JohnJohn Admin Mod
    Posts: 404

    @CamelCoder I was under the assumption that he wanted to pause and unpause within Codea rather than from the Obj-C end.

  • Posts: 207

    @John I was sort of confused why you asked the question, I was like... “He made Codea, does he really not know how to do it?” Then, before I went to sleep last night, I rethought the question, and I thought to myself, “Ah! I’m such an idiot” Sorry if that response before came out condescending, just a misunderstanding. :|

  • Posts: 276
    Yeah you're all right. The whole engine is quite big and unwieldy, but for so many reasons. Mainly me learning how to do more and more things. I think I have a way to do it within Codea and that is the preferred way as I don't have a clue about Xcode and objective C - but it's gonna take a lot of checking I have everything wrapped up. It will be worth it.

    When you factor in all the things I've made the game do, each objects specific hit states, buttons, reusing classes to create different aliens that do very different things I can see where it all became unwieldy. To be honest when I made Mightymower I should have remembered I needed a pause function and to bake it in.

    Things like the music carrying on are fine. Even the sound as they are triggered by time events anyway, be it the global leveltimer or self.timer within classes.

    I'll have a think and see what I can do.

    Thanks all for the advice!

    "May the Starsceptre be with you...!"
  • Posts: 276
    @John 's question is right. And whilst @CamelCoder has a cool answer my problems begin to explode wider than my not bad grasp on Lua over Objective C. I'm a creative who works in pictures and video. I'm lucky to have scored big with Codea as it makes my app making life so much easier than having to try to learn another way. Programming never ever came easy to me and Lua just seems to have clicked although my functions are very very basic. I mean my game is basically a ton of 'if' statements.

    That's not an excuse for me to not go back and redo stuff, rather my total lack of time is. But you guys have all taught me so much and I know my next game will be a ton easier to code because of it.

    I will sleep on my in Codea solution and test the new pause function my brain thinks I can achieve over the next few days.

    Thanks again
  • Posts: 276
    Morning all. I've written the code in Lua this morning and have it fully working for pretty much 85% of objects. Just gotta go work through each class and it's done. Thank you all
  • Posts: 276

  • dave1707dave1707 Mod
    Posts: 5,896

    @Majormorgan You can use debug to pause a program. It doesn't pause music or physics objects and I haven't looked at what else it doesn't pause. The only problem is once I call the debug hook function loop, there isn't anything manual I can do to get out of it. Right now I use os.time and pause for 10 seconds. You have to stay in the function loop so nothing else in Codea can execute.

    function setup()
        x=10
        y=400
        xv=1
        yv=1
        cnt=0
        sec=10
        debug.sethook(loop,"l")
    end
    
    function loop()
        while pause do
            ct=os.time()
            if ct>st+sec then
                pause=false
            end  
        end
    end
    
    function draw()
        background(40, 40, 50)
        fill(255)
        text("tap screen to pause for "..sec.." seconds.",WIDTH/2,HEIGHT/2)
        x=x+xv
        if x>WIDTH or x<0 then
            xv=xv*-1
        end
        y=y+yv
        if y>HEIGHT or y<0 then
            yv=yv*-1
        end
        ellipse(x,y,20)
        cnt=cnt+1
        text(cnt,WIDTH/2,HEIGHT-50)
    end
    
    function touched(t)
        if t.state==BEGAN then
            st=os.time()
            pause=true
        end
    end
    
  • Posts: 96

    Maybe you can try coroutine, this is the example code:

    function setup()
        pause = false
        -- Create a new coroutine for the function f
        co = coroutine.create(f)
    
        box = { x = 10, y = 10,
                width = 20, height = 20,
                fillColor = color(24, 28, 202, 255) }
    
        -- Here we can not use tween.
        -- t = tween(10, box, {x = 1000, y = 1000})
    end
    
    -- Put all your draw code in f
    function f()
        while not pause do
    
            background()
            fontSize(40)
            fill(0,255,0)
            text(os.time(),WIDTH/2,HEIGHT/2)
    
            fill(box.fillColor)
            box.x, box.y = box.x+1,box.y+1
            rect(box.x,box.y,box.width,box.height)
    
            coroutine.yield()
        end
    end
    
    function draw()
        if not pause then
            coroutine.resume(co)
        end
    end
    
    function touched(t)
        -- Click left screen to pause, click right screen to resume
        if t.state == BEGAN and t.x >=WIDTH/2 then
            pause = false
        elseif t.state == BEGAN and t.x <WIDTH/2 then
            pause = true
        end
    end
    

    Using coroutine, good news is that you can control the flow exactly, bad news is that: 1) you need to control everything manually; 2) the performance will have to be affected.

  • Posts: 276
    Thanks @dave1707 and @binaryblues

    The code I had in the end was a simple:
    ~~~
    If pauser= false then
    ~~~
    Which I would put around key parts in each class or functions that were increasing the game leveltimer - so when I hit a button for pause, pauser would be true.

    It was dead easy in the end I was kicking myself!

    Thanks
  • Posts: 207

    @Majormorgan I think it would be better to have a pause variable connected to the classes themselves. For example, if you want some things to stop (pause) and some others to continue there moving, you wouldn't be able to, because it's all connected to one variable. I think in the class, you should say for each object, if not self.paused then, followed by the code to move the object. Then when you want to pause everything,

    for i,v in ipairs(table_containing_all_game_objects) then
       v.paused=true
    end
    
  • Posts: 276
    Thanks @CamelCoder - that's an awesome piece of code. I think when I come to make an update or new game I'll use your code. Thanks!
  • dave1707dave1707 Mod
    edited July 16 Posts: 5,896

    @Majormorgan Instead of wrapping your code as you show above and what I show below, you can do something like what I show in the second and third part. You just have to add one line unless you want to do something special in a function when pauser is true.

    -- Wrap the code like what you show above.
        if pauser==false then
    
            Code
            Code
            Code
    
        end
    
    -- Don't wrap the code. Just add a single pause line to return.
        if pauser then return end
    
        Code
        Code
        Code
    
    -- Don't wrap the code. If running special pause code, then return.
        if pauser then 
           pause code
           pause code
           return
       end
    
        Code
        Code
        Code
    
  • Posts: 276

    Thanks @dave1707 - so does return mean it goes back to the 'if paused then' part or back up to the top of then class?

    It sounds cool. And could be something I use too.

    The advantage I have with where the code is currently is when I pause you can still see the object on screen and it's stopped too. This is because I wrap all the movement, shooting, hit detection and redrawing code within the 'if pauser = true' part. So it feels like a real paused moment.

    That way, the drawing of the mesh is outside of that code enabling all the original on screen data like position, size, frame and art are drawn from the moment they were paused.

  • dave1707dave1707 Mod
    Posts: 5,896

    return means don't execute anymore code in this function and to return to the calling function. Here's a very simple example showing return.

    displayMode(FULLSCREEN)
    
    function setup()
        xr,yr=200,400
        xg,yg=100,600
        xrv,yrv=3,3
        xgv,ygv=2,2
        cnt=0
    end
    
    function draw()
        background(40, 40, 50)
        showText()
        updateRed()
        updateGreen()
    end
    
    function showText()
        -- show text
        fill(255)
        text("Tap screen to pause/unpause",WIDTH/2,HEIGHT-50)
        text(cnt,WIDTH/2,HEIGHT/2)
    
        if pause then return end    -- code to pause
    
        -- update count
        cnt=cnt+1
    end
    
    function updateRed()
        -- draw ellipse
        fill(255,0,0)
        ellipse(xr,yr,30)
    
        if pause then return end    -- code to pause
    
        -- update ellipse position
        xr=xr+xrv
        yr=yr+yrv
        if xr<0 or xr>WIDTH then
            xrv=xrv*-1
        end
        if yr<0 or yr>HEIGHT then
            yrv=yrv*-1
        end    
    end
    
    function updateGreen()
        -- draw ellipse
        fill(0,255,0)
        ellipse(xg,yg,30)
    
        if pause then return end    -- code to pause
    
        -- update ellipse position
        xg=xg+xgv
        yg=yg+ygv
        if xg<0 or xg>WIDTH then
            xgv=xgv*-1   end
        if yg<0 or yg>HEIGHT then
            ygv=ygv*-1
        end    
    end
    
    function touched(t)
        if t.state==BEGAN then
            pause=not pause
        end
    end
    
  • Posts: 207

    @Majormorgan Basically what return does is it exits out of the function. To exit out of an if statement, there are a couple ways you can do it.
    First way is to setup a one-time loop

    for i=0,0 do
       if not pauser then
          --Then to end the if statement
          if shouldQuitIfStatement then break end
       end
    end
    

    Another way to do it is like @dave1707 did above, which is to split it up into multiple functions, which is highly recommended.

    Lastly, you can use Lua's goto function. The syntax gets a bit weird in this one.

    local bool=true
    ::beforeIf::
    if bool then
       if shouldQuitIfStatement then
          bool=false
          goto beforeIf
       end
    end
    
Sign In or Register to comment.