Touch Events

5 replies [Last post]
AdamBucketz
User offline. Last seen 13 weeks 6 days ago. Offline
Joined: 10 Dec 2010

Hey there! Congratulations on the awesome app!

I saw in the other thread that lots of people were asking for touch events. I mocked up some code that simulates this, and thought you may be interested. I'm not working on an accelerometer based game right now, so I haven't bought the Remote, but let me tell you if it fired off tap events I'd be all over it!

Basically all my code does is loop through every display object, checks if the faked touch x and y fall within its bounds, and if they do fire off an event from that object. There's no Runtime dispatches or listeners at all, and it my testing I'm firing the event based off a timer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
local fakedTap = function(target, eX, eY)
    local properties = {
        phase = "ended",
        y = eY,
        yStart = eY,
        name = "touch",
        x = eX,
        target = target,
        time = system.getTimer(),
        id = nil,
        xStart = eX
    }
    target:dispatchEvent(properties)
end

Once you find out which object was touched, pass it and it's event.x and event.y to the above method and the listener will receive and react. I know all the looping will hurt performance, but hey this is a dev tool, and you're getting events from your device! In my mind it's worth any performance hit as long as it's functional. I'm sure you could come up with a more efficient way of doing it anyway.

Hope to see touch (or tap! I'd take either!) in a looming update!

Replies

Matthew Pringle
User offline. Last seen 37 weeks 6 days ago. Offline
Joined: 23 Feb 2010

Ive been experimenting but I hit a wall firing actual corona touch events to listeners assigned to objects rather than the runtime.

Could you show me how to loop though all the display objects and check for listeners.

What im trying to do is to find a way where the user doesnt have to alter their code to get the events.

AdamBucketz
User offline. Last seen 13 weeks 6 days ago. Offline
Joined: 10 Dec 2010

You don't actually have to check for whether or not they are listening. Each time to touch a button, it fires an event. Whether or not you are listening for the event dictates whether or not anything happens.

Here's a fully functional file to show you what I'm doing. Notice that the only Runtime event is listening for the accelerometer. To test this in the simulator, just fire the "shake" command until you see the tap (a little while box) hit the button. The button will change color and you'll see fun stuff output to your terminal.

The key thing here to note is that the button only has a "tap" listener on it, which you can easily set off by actually tapping it. Shaking your device is tapping at random points on the screen, which will eventually hit the button.

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
--== Functions ==--
local onTap, fakedTap, findTarget
local rand = math.random
 
--== Display Objects ==--
local myBtn
 
onTap = function( event )
    event.target:setFillColor(255, 0, 0)
    print("Tapped! ".. event.target.name)
    for i,v in pairs(event) do
        print(i,v)
    end
end
 
findTarget = function( event )
    print("... searching...")
    local eX, eY = rand(0,display.contentWidth), rand(0,display.contentHeight)
    --== Test for hit! ==--
    local test = function( obj )
        local oX, oY = obj.x - obj.width*.5, obj.y - obj.height * .5
        if oX <= eX and oX + obj.width >= eX then
            if oY <= eY and oY + obj.height >= eY then
                print("found!", obj)
                fakedTap(obj, eX, eY)
            end
        end
    end
 
    local stg = display.getCurrentStage()
    local kids = stg.numChildren
    while kids > 0 do
        local obj = stg[kids]
        test(obj)
        if obj.numChildren and obj.numChildren > 1 then
            local i = obj.numChildren
            while i > 0 do
                test(obj[i])
                i = i -1
            end
        end
        kids = kids - 1
    end
    display.newRect( eX, eY, 5, 5 )
end
 
fakedTap = function(trgt, eX, eY)
    properties = {
        x = eX,
        y = eY,
        name = "tap",
        target = trgt,
        time = system.getTimer(),
        numTaps = 1
    }
    trgt:dispatchEvent(properties)
end
 
myBtn = display.newRoundedRect( 0, 20, display.contentWidth, 40, 10 )
myBtn.name = "My Button"
myBtn:setFillColor(50, 50, 50)
myBtn:addEventListener("tap", onTap )
 
Runtime:addEventListener("accelerometer", findTarget)

Matthew Pringle
User offline. Last seen 37 weeks 6 days ago. Offline
Joined: 23 Feb 2010

I will have a look over the weekend.

Im not sure if it would get past the wall I hit before but im willing to give it a go.

AdamBucketz
User offline. Last seen 13 weeks 6 days ago. Offline
Joined: 10 Dec 2010

Hey Matthew,

Any chance you got to look into the touch events? Also, would it help to have a table of all display objects that are listening for touch or tap? That wouldn't be too terribly difficult to acquire if it would help.

Matthew Pringle
User offline. Last seen 37 weeks 6 days ago. Offline
Joined: 23 Feb 2010

Hey Adam

I was looking into it using the runtime event as a test, the tcp results were a bit choppy. Ive since been updating the remote to work using the async http api so it now runs really smoothly sending about double the amount of info from 10-15 times a sec to about 30. This also means I can now transmit more info without anything slowing down.

Ive been upgrading a few other things as well to make it work a bit better at users requests and currently I am working on trying to get it to work on windows ( windows doesn't have async yet ).

I will get on it shortly, probably next week, as I am going away shortly.

Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.