Mar 122011
 

Corona For Newbies Part 3 covers dragging, confining an object to the screen and practical usage.

Download Corona For Newbies Part 3

It isn’t a big, exciting part of the mini series but it is new and it does cover some very, VERY handy things you will all use at some point while making iPhone apps with Lua and the fabulous Corona SDK.

Below, as included in a readme.txt file in the download, is a brief note accompanying this installment in the Corona For Newbies mini series;

Thanks for downloading part three of Techority’s mini series, Corona for Newbies.

Today we’re covering how to drag an object, how to keep an object within the confines of your screen and how to put these things to practical use.

There is a lot more I’d like to cover, but that can wait until part 4 – I wanted to give you something to play with in the meantime.

Enjoy! (If you enjoy it enough, you can show thanks by liking Techority on Facebook or making a small donation to the site. $5 feeds a hungry Peach for a day!)

Part 4 will be out soon, so leave your suggestions at Techority.com for me :)

Peach Pellen

http://twitter.com/peachpellen

I hope you will enjoy Corona For Newbies Part 3, please leave requests for part 4 below, or email me.

Peach Pellen :)

PS – If you haven’t already, check out my templates! There’s a big, obvious button on the right hand side of the page!

 

Like this post? Subscribe to the monthly newsletter!

 

  32 Responses to “Corona For Newbies – Part 3”

  1. Why not to add the wrap function in the same dragging function? wouldn’t it fire only when it is needed? I am really a newbie on this, but it makes more sense to me to have it only when you need it.

    Thanks for these tuts, you make look Corona really easy! I am considering a donation when I have some extra moolah ;)

    • Hey Adrian, you are correct – I elaborate more on that in other tutorials however for the 4 original Corona For Newbies sets I deliberately broke things up as much as possible. People who have never programmed before seem to have an easier time memorizing and understanding code when it is all broken up in such a way. (I noticed on your site you’ve got some experience coding; more than me from the looks of things ;))
      In any case, you’re right – and that’s my reasoning for not doing so in this particular tut ;)
      Thanks for the kind words.

  2. Ya it’s april 2012. I’m a honey badger.

    For those who want pixel perfect dragging (i.e. meaning you can grab object from the corner and it won’t “snap” into place)

    Drag the red box around, you’ll see :)

    WEEEeEeEEeEeeEEeEeeEEeeeEeeEeeEeeEeeEeeeeEEee!

    I SAID WEEEEEEEEEEEE

    WEEE WEE ALL DAY LONG NICE AND STRONG OOOOO WEEEE YA YA.

    lol. Ok, i’m calm now

    WOOT!

    here you go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
            --DECLARE PHYSICS
            local physics = require "physics"

            physics.start(true)
            physics.setGravity( 0, 10)
            physics.setDrawMode( "normal")

    --DECLARE WIDTH AND HEIGHT SHORTCUT VARIABLES  
            local _W = display.contentWidth
            local _H  = display.contentHeight

           
            local ground = display.newRect (0, 400, _W,20)
            physics.addBody(ground, "static")
            ground:setFillColor (0,255,0)

            local box = display.newRect (_W/2-50, _H/2, 100,100)
            physics.addBody(box, "static")
            box:setFillColor (255,0,0)


           
            --======================================================================================
                                            --------DRAG CODE (X AND Y TOUCH ACCURATE----
            --======================================================================================
            local function dragBody( event )
            --print ("drag started")
                    local body = event.target
                    local phase = event.phase
                    local stage = display.getCurrentStage()

                    if "began" == phase then
                   

                            stage:setFocus( body, event.id )
                            body.isFocus = true
                                            --Change body to dynamic
                            event.target.bodyType = "dynamic"

                            -- Create a temporary touch joint and store it in the object for later reference
                            body.tempJoint = physics.newJoint( "touch", body, event.x, event.y )
                           
                            --=====================
                            --=====================
                            --THIS PREVENTS ROTATION WHEN DRAGGING
                            --COMMENT OUT IF YOU DON'T WANT THIS
                            --body.isFixedRotation = true
                            --=====================          
                            --=====================
                           
                            elseif body.isFocus then
                            if "moved" == phase then

                                    -- Update the joint to track the touch
                                    body.tempJoint:setTarget( event.x, event.y )

                            elseif "ended" == phase or "cancelled" == phase then
                                    stage:setFocus( body, nil )
                                    body.isFocus = false
                                    event.target:setLinearVelocity( 0, 0 )
                            event.target.angularVelocity = 0

                                            --After the event ends, change body back to dynamic OR static.
                                            event.target.bodyType = "dynamic"
                                            --event.target.bodyType = "static"      
                                   
                                                       -- Remove the joint when the touch ends                
                                    body.tempJoint:removeSelf()
                                    --print ("drag ended")
                            end
                    end

                    -- Stop further propagation of touch event
                    return true
            end

           
            box:addEventListener( "touch", dragBody )
  3. Hey Jen,

    A delay could be added by doing;

    1
    transition.to(obj, {delay=1000, time=3000, x=0, y=0})

    Although obviously x and y wouldn’t be 0 ;)

    Is that what you mean by delay?

    Peach :)

  4. Hi Peach!

    I checked out your tutorial and it makes sense now why you had those extra checks to make sure the objects don’t collapse into one position when you touch them as I was trying to create something similar. Any hints/tips on creating move on an object with some delays? The objects in your example will move to the exact position were your finger is touching, but I want to have a delay / some fluidity to it before reaching the position where your finger is pointing. I saw this feature on an app and wanted to do the same. Please get back to me when you’re rested and get some time.

    Cheers!
    Jen

  5. Heh, well glad it was right even if you don’t know why you wanted to know ;)

    Peach

  6. @ peach

    SampleCode, Interface Dragme = yep that was it.

    I just launched the main.lua and it does allow me to drag edges…. I don’t know why I wanted to know I just did?

    Anyway, thanks for the response I’ll dig through the code and figure it out. Thanks a bunch!

    -Nick

  7. Hi Peach, I’ve gone through all of your tutorials, and now I am going through them again. I bought a 2nd ed prog in Lua book, the reference manual etc.

    Now I am really starting to tear things apart and I have a question

    In the following code example, I display a box on screen and I drag it around. That’s fine and dandy.

    What happens is when I touch the EDGE of the box, the box CENTERS on my mouse cursor in the simulator. I haven’t bought a Corona SDK license yet as I am waiting until I have enough of a app/game to actually put out there.

    How would I just drag the edge of a box without centering on my cursor (or on a piece of hardware, a finger/thumb)?

    This is from your part 3, Noobies guide to Corona, 1. Simple Dragging.

    I also commented the code to the extreme to get MY understanding of how this works in my own words. Am I on the right track with how the function, drag stuff works?

    Now I present, the code and comments below:

    local boxpic = display.newImage (“box.png”)
    boxpic.x = 230
    boxpic.y = 230

    –Creating a local function called ‘dragbox’ and tying touch events and tracking the object–

    local function dragbox (event)
    boxpic.x = event.x
    boxpic.y = event.y
    end
    boxpic:addEventListener (“touch”, dragbox)

    –[[
    The local function we define with a name of choosing - in this case that's 'dragbox'
    then we put in (event) *explained more below*
    Then have to take the local variable we created earlier 'local boxpic' (which is what represents the box.png)
    and then define how and when to track it. The how to track part is:

    boxpic.x = event.x
    boxpic.y = event.y
    end

    So basically what we are saying is I want to track the picture on whatever X and Y coordinates the picture is dragged to
    the = event.x and event.y are tied to the "addEventListener"

    Then we are defining what kind of event listener? in this case its "Touch", then we call the local function 'dragbox'
    "touch" is on boxpic, we want to match the event coordinates.

    What I understand about a touch even, is the event.x and event.y will follow the location of the touch -
    >>>as long as it is on the boxpic!!!!!
    --]]

    • I think I understand what you are asking – if so, look in the CoronaSDK folder at SampleCode, Interface, DragMe.

      That doesn’t center the object being dragged on the touch.

      Let me know if that’s what you wanted :)

      (Sorry, I’m a little dopey today.)

  8. I have an array of buttons

    mybutton[1] = display.newImage( ‘a.png’)
    mybutton[2] = display.newImage( ‘b.png’)

    I want to add listeners to each of the buttons

    mybutton[1]:addEventListener(“tap”, onTap) throws an error

    Any idea how to get it going? onTap function is declared elsewhere in the code.

  9. OK, well rather than using “left” (like in the above examples I gave you) you would use _G.left (that’s a global variable.)

    Then you’d change to a new screen/scene using director, add a background and then add some text, for example;

    1
    local leftText = display.newText ("You touched left " .. _G.left .. " times!", 170, 160, native.systemFont, 14)

    Make sense?

  10. Yep. Exactly!

  11. Hey Tim,

    I’m about to go back to bed (damn insomnia!) so I’m not totally with it right now; but is what you’re asking basically “How do I go to a gameover (or whatever) screen and on that screen display three different numbers, matching how many times my three things were touched?”

    Is that about right? Let me know. I’ll check in again when I’m awake :)

    Peach

  12. Gotcha…thanks.
    Sooo…..do ya have any examples of how I could have the scores all print onto a different ‘page’?
    For example, after touching the left, right & middle ‘x’ number of times, (using Director, of course), go to a different/next page to see the totals? :-}

  13. Hey Tim, that’s easy :)

    For each object, lets say the same as in your example, do this;

    left = 0
    middle = 0
    right = 0

    Then in the touch function add one line;

    left = left+1

    Do that for each, where you’d normally print, play a sound, etc – and that will work. If you’d like to see it printed how many times something has been touched add a line;

    print (left)

    Make sense? :)

  14. I got the event listener to work for each item touched (versus the background)…how can I keep track of the individual touches to each object versus a total score? Say I’ve got 3 items on the screen – I’d like to keep track of how many touches I make to the left vs middle vs right object.

    Thanks a million!

  15. Hey Ice Breaker,

    Glad you got it worked out; good feeling, isn’t it?

    Double check if you have any timers or Runtime listeners still going on that might cause the issues when you die. I do that all the time.

    Better run, hectic day, lots going on.

    Good luck with the other issues – and well done again!

    Peach :)

  16. I solved the blue balloon problem finally! Plus, the red balloon one that didn’t affect much on the terminal (Although it probably would’ve screwed everything up If I tried it on an iDevice).

    For the blue balloon it was a scope and recursive problem. First off,

    1
     local function function_name()

    Does NOT equal:

    <local function_name = function()

    for recursive functions.

    I know this because changing that ends up screwing me over. It seems using the first one, the shortcut, ends up defining things in a slightly different order, causing scope problems in very rare occasions. So, I swapped to the second way, after moving some stuff around, doing a few forward declarations, altering some local/global stuff, and TADA! Works like a charm…

    Except the fact that after death and you fade to the next screen it seems to have tons of errors that have no permanent affect. Odd. I think I’m forgetting to remove something, but I’ll fix it later.

    Anyways, I have to say, THANK YOU! :D You’ve been a great help. I never even thought about canceling the transition before removing the object, even though it was right in front of my face. Dx

    Well, that’s another obstacle or two cleared, and more knowledge for it.

  17. The forums are great; they’ll be better now I’m on them in an official capacity ^-^; Haha.

    You aren’t annoying at all; I just have trouble as I wake up and there’s a million emails waiting for me and yeah, easy to get overwhelmed I’m afraid.

    Do check the forums though; I think they’ll hold the answer for you – there have been several posts related to this kind of thing.

    Peach :)

  18. Yeah, I’ll probably get an account on Ansca so I can use the forums when I get the energy to stop being lazy. The pop function is indeed within the spawn function. Which is why I’m saying my code is messy in a way, I always seem to have a hundred functions withing functions calling functions, and then wonder why there’s an error. e_e

    Thanks for taking the time to try and help me. xD I know it must be annoying to have me post a thousand walls of text, and then be confronted by them as soon as you wake up. O:

  19. Hmmmm, is your pop function within the same function used to spawn the balloon?

    This might be worth posting on the Corona forums – I have some experience with it but there would be many better qualified to answer, I imagine.

    There are a few threads talking about transitions and timers and dealing with their annoyances ;)

    Peach

  20. Ok, it IS the transition most likely, and maybe the timer even. I noticed I’m not using local when defining variable timers and transitions. So, I tried to cancel it but it canceled all of my balloon transitions. I tried adding local but now it says it’s nil because it can’t find it. That’s really odd though because of where I defined them, it should be within scope.

    I define the timers and transitions right after defining the balloon and it’s functions, I even tried defining them at the same time because defining them at the same time doesn’t seem to screw up the functions at all. Still can’t use local. I find that odd, I define three variables; a balloon, a timer, and a transition, yet I can only access the balloon. I’m kind of stumped. I’m guessing I’m somehow supposed to pass the timer & transition i want to cancel to the Pop function and Cull functions then?

  21. I always try a timer with issues like that – I had to use one recently on something similar. I shouldn’t have, it didn’t make sense, but it DID make it work.

    As to it being in transition – YES. It is likely the issue – I should have read that before writing the above but just woke up.

    Try canceling the transition BEFORE removing it; that should work. Let me know :)

    Peach

  22. I guess I could use a timer with a one millisecond delay to call another function… Although I don’t see how it would help. I’ve looked at the code several times and it doesn’t seem to have anything wrong with it. Although another guy had a similar problem iirc, in the end it had some odd thing to do with looping, he also couldn’t use removeSelf from a table, the object directly, group etc. I tried collecting garbage after nil’ing out the balloon with a timer (no delay with timer for collection, oddly) but it doesn’t seem to help.

    It is in transition when I remove it in my pop function, do you think that could be the problem? All though I’m not sure why that’d call my Cull function even after the timer that calls it, the only caller, is removed.

    I’m guessing it’s some sort of scope + looping (it’s redone every few seconds) that’s the problem.

  23. So, I just woke up and that’s a lot of text, haha – but have you tried using a timer to remove the balloon, like in your function to remove it?

    Also, is it possible the balloon is still in transition when you try to remove that?

    Sorry if these are silly questions, my eyes are not letting me read all of the above right now – it’s like the drunk effect in World of Warcraft, haha XD

    Peach :)

  24. Thanks. I am using physics for another type of balloon already, and I need the gravity to stay upwards. As far as I know gravity can’t be assigned to individual objects separately, so I decided to use a transition. Originally I used ‘onComplete=cull’ but guess what happened? Not only did the HP not go down and the cull function wrecked whenever I got that error, but the transition would stop randomly! Seriously. After popping a balloon, the next one would immediately glitch and stop at a random point on screen.

    I’ve thought about adding physics to the blue balloons and as you said, adding a collision detector, but they’d collide with my red balloons going upwards. I could assign a bit to filter collisions, but that’s getting more complicated than I want to get. I’m thinking about reverting back to an ‘onComplete’ call, and just living with the random stopping. Make it a gameplay feature or something.

    I don’t know, what’s better?

    1. Letting the blue balloons move unimpeded, but half of them never removing themselves or lowering hp when they got across the screen…
    or 2. Letting the glitched ones stop on a random spot on screen so that they’d at least be pop-able.

    Also, the red balloons get the same problem, but their HP code almost always works and they don’t stop moving. I think I need to use more tables and arrays, but I have some trouble grasping the syntax.

    I know that this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- Defines table
    tablename = { }

    -- Sets values
    tablename = {1, 7, 8, blah, orange, purple, whatever}

    -- Retrieves values, [#] determines place

    variable = tablename[1]

    And that’s it. I fail when it come to making any practice use out of them, especially in handling functions. As you can see, I just kind of slap on functions within function within functions as things spawn… Of course this causes scope problems, etc.

    Also, I know that physics don’t work between children of different display groups; is there anyway to make two groups affect each other? I’m thinking of making a platformer once I get better, but one thing stumps me: camera. I figured I’d put every tile into a ‘camera’ group as it spawned, and move the whole stage left and right as the character moves. This obviously would not work. If I made the player and other not movable objects into another group, and put both the camera and player groups into another group, would they affect each other then?

    Example:

    1
    2
    3
    4
    playerGroup:insert(player)
    cameraGroup:insert(stageObject(s))
    world:insert(playerGroup)
    world:insert(cameraGroup)

    I’m guessing not, because now they’re just in separate groups within a group. Another option would be to make a physicsGroup in which everything that was to interact with each other would be added, besides other groups.

    So it would become:

    1
    2
    3
    physicsGroup:insert(player)
    physicsGroup:insert(stageObject(s))
    cameraGroup:insert(stageObject(s))

    I think that would work, as they’d share a group then…

    Look at me ramble on. Dx Sorry for taking up so much of your time if you managed to read through this wall of text! e_e

  25. It’s OK, your code isn’t too messy; you should see the stuff of mine I don’t post, haha.

    Now, if it works with your game, I’d suggest using physics – have a wall out of sight that will kill any balloons on hit.

    Alternatively, if you want to avoid physics there is likely something that could be put together – I’m exhausted right now so not the time to think on it – but if you are interested you could email me, I’ll take a look and see if I can fix it, then if I can – if you’re interested – I’d charge you a small fee. (I’d give you a quote before expecting any sort of commitment.)

    Peach :)

  26. This doesn’t pertain to this tutorial directly per say, but I am having a few problems.

    I have a function that spawns a balloon every few seconds, and along with the balloon two other functions pertaining to it are created as well; Cull, which removes the balloon when it’s off screen and lowers the player’s HP, and Pop, which pops the balloon and adds to the score when touched. The problem is Cull doesn’t want to work with every other balloon as shown by a print function.

    It seems Cull is being called, even after I remove the timer that calls it (I know it is successfully removed by testing earlier.) Of course, it tries to remove the balloon even though it no longer exists, so I tried removing the function as well as removing the balloon but no dice.

    The really odd thing is that it:

    1. Cull should not be called. (Possible scope problem?)
    2. The ‘if’ statement at the begging of the code that dictates whether to continue the function is skipped. (I honestly don’t know how this is even possible!)

    I thought the timer that calls the cull function could be calling other balloon’s cull functions just as they are being removed, but as I said I tried nil’ing out the cull function with no result. Nothing I do seems to work. Also, I should be using Tables and Arrays but their syntax and use with them is hard to grasp for me, I’m sure if you made a tutorial on the integration of tables and arrays to aid in handling basic functions many newbies such as myself would be thankful.

    I’ll post the balloon code here, I guess.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    -- Defines function that creates a Blue balloons
    local function insertBlueBalloon()
    local blueBalloon = display.newImage("blue balloon.png")
    blueBalloon.x = -100
    blueBalloon.y = math.random(100, display.contentHeight - 100)
    world:insert(blueBalloon)
        -- Defines function that destroys Blue balloons when touched
        local function popBlueBalloon(event)
        if event.phase == "began" then
        local poppingEffect = display.newImage("popped.png")
        poppingEffect.x = event.target.x
        poppingEffect.y = event.target.y
        poppingEffect:scale(0.8, 0.8)
        world:insert(poppingEffect)
        score = score + (110 + event.target.x)
        score = tonumber(string.format("%.0f", score))
        scoreText.text = score
        scoreText:setReferencePoint(display.CenterLeftReferencePoint)
        scoreText.x = 25
        event.target:removeSelf()
        event.target = nil
        timer.performWithDelay(1, function() collectgarbage("collect") end)
        timer.cancel(c)
        setHighScore()
        -- Defines function that removes popping effect created from touch
        local function removePoppingEffect()
        poppingEffect:removeSelf()
        poppingEffect = nil
        end
        timer.performWithDelay(100, removePoppingEffect)
        end
        end
        local function cull()
        if blueBalloon.x &gt;= 400 then
        blueBalloon:removeSelf()    -- Nil comparison/upvalue index problem in this line, !!!prevents hp loss and culling 1/6 times!!!
        blueBalloon = nil
        timer.performWithDelay(1, function() collectgarbage("collect") end)
        timer.cancel(c)
        hp = hp - 1
        print "HP lowered by 1."
        else if blueBalloon.x &lt;= 400 then
        end
        -- Checks to see if hp is zero, and if so, moves to correct screen
        if hp &lt; 1 then
        timer.cancel(irb)
        timer.cancel(ibb)
        saveValue( &quot;highscore.data&quot;, highScore )
        director:changeScene(&quot;menu&quot;, &quot;fade&quot;)
        end
        end
        end
        blueBalloon:addEventListener(&quot;touch&quot;, popBlueBalloon)
        transition.to( blueBalloon, {time = 5000, x = display.contentWidth + 100, y = blueBalloon.y--[[,  onComplete=cull--]]})
        c = timer.performWithDelay(6000, cull, 1)
    end

    I’ve tried several things, which is partly responsible for why my code is so dang messy. I’m sure there are a million and one things screwed up with this code, but aside from this:

    1
    2
    3
    4
    [C]: in function 'removeSelf'
    [File path]game.lua:172: in function '_listener'
    ?:Runtime error
    [File path]game.lua:172: attempt to call method 'removeSelf' (a nil value)
  27. Hah, hi Tim :P

    You would add an event listener to the object/s in question in question rather than to the background ^-^;

    Make sense? Let me know.

    Peach :)

  28. How about scoring when touching a specific object or objects (versus anywhere on the screen, as in your exising score tutorial)? ;-) [or did I miss something??]

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.