Corona学习指南之事件与监听器

一.基本的交互与事件检测

事件是Corona交互应用的基础,被用来触发应用中的响应,例如,屏幕的点击,特定系统事件的检测、定时器的完成、两个刚体之间的碰撞等。我们使用addEventListener()对象方法来检测发生的事件,这将引导Corona通过一个监听器函数来监听相关联的事件。

1.Runtime事件

Runtime事件会被派遣给全局的Runtime监听器来检测,这些事件不会直接到达任何特定的对象,相关,它们会广播给感兴趣的监听器。常见的Runtime事件包括:

  • enterFrame事件:每一帧都会发生这种事件
  • system事件:外部事件,例如设备需要挂起或者停止应用
  • orientation事件:设备方向发生改变的时候产生这种事件

以下的代码显示了如何处理system事件:

local function onSystemEvent( event )

    local eventType = event.type

    if ( eventType == "applicationStart" ) then
        --应用启动并且`main.lua`中代码执行完之后调用
    elseif ( eventType == "applicationExit" ) then
        --用户或者操作系统任务管理器停止应用时调用
    elseif ( eventType == "applicationSuspend" ) then
        --当设备挂起应用的时候,如手机来电,调用
    elseif ( eventType == "applicationResume" ) then
        --当应用从挂起状态继续执行的时候调用
    elseif ( eventType == "applicationOpen" ) then
        --当应用被指示打开URL时调用(Android和iOS)
    end
end

Runtime:addEventListener( "system", onSystemEvent )

2.本地(local)事件

本地事件会发送给一个单独的监听器,而不会广播给全局的Runtime。常见的本地事件如下:

  • hit事件:用户触摸手机屏幕时会产生这种事件
  • collision事件:两个刚体发生碰撞时产生这种事件
  • timer事件:定时器完成一个周期时产生这种事件
  • audio事件:音频文件播放完成会产生这种事件

3.函数(Function)和表(Table)监听器

监听器既可以是函数,也可以是表或者展示对象。

当一个函数监听器被唤起的时候,会将一个表类型的参数event传进去。

local myListener = function( event )
    print( "Listener called with event of type: "..event.name )
end

Runtime:addEventListener( "touch", myListener )
Runtime:addEventListener( "enterFrame", myListener )

有时候一个函数监听器是不方便的,因为当监听器被唤起的时候,某些变量不在作用域内。在这种情形下,我们应该使用表类型的监听器。表类型监听器必须要有一个实例方法,并且该实例方法的名称要与事件名对应。

--假定`myClass`和`myClass:new()`已存在

function myClass:enterFrame( event )
    print( "enterFrame called at time: "..event.time )
end

function myClass:touch( event )
    print( "touch occurred at: "..event.x..","..event.y )
end

local myObject = myClass:new() 

Runtime:addEventListener( "touch", myObject )
Runtime:addEventListener( "enterFrame", myObject )

4.理解hit(碰撞)事件

当用户触碰屏幕的时候,hit事件就会产生,然后派遣给显示层次中的显示对象。只有那些在屏幕上与碰撞点位置有交集的显示对象才会接收到事件。碰撞事件会以一个特定的顺序在这些显示对象中传播,默认,在显示层次中最前面的对象会第一个接收到事件。

hit(碰撞)事件会一直传播下去,除非得到处理。处理很简单,只需在事件监听器函数中返回true即可,这样便可以停止传播。

local function myTouchListener( event )

    if ( event.phase == "began" ) then
        --按钮被点击时会执行该代码
        print( "object touched = "..tostring(event.target) )  --'`event.target`' 是被触摸的物体
    end
    return true  --阻止事件往下面传播
end

local myButton = display.newRect( 100, 100, 200, 50 )
myButton:addEventListener( "touch", myTouchListener )

如果触碰事件经过整个展示层次后还没被处理,该事件被当做是一个全局事件传递给Runtime监听器。

5.设置焦点(Focus)

你可以为一个显示对象设置焦点来让所有的事件都针对该物体。拿一个典型的按钮来说,如果用户触摸按钮,并不抬起,然后滑着离开按钮,这时候按钮不会产生一个动作,如果手指到另一个物体上,可能会引起事件。为了处理这个问题,可以设置焦点:

local function myTouchListener( event )

    if ( event.phase == "began" ) then
        display.getCurrentStage():setFocus( event.target ) 

    elseif ( event.phase == "ended" or event.phase == "cancelled" ) then
        display.getCurrentStage():setFocus( nil )  --setting focus to 'nil' removes the focus

    end
    return true
end

local myButton = display.newRect( 100, 100, 200, 50 )
myButton:addEventListener( "touch", myTouchListener )

6.Tap(轻点)/Touch(触摸)/Multitouch(多点触摸)

7.事件监听器

事件会被派遣给事件监听器,通常是一个函数,而event参数总会传递给这个函数:

local function myTouchListener( event )

    print( "Touch X location"..event.x )
    print( "Touch Y location"..event.y )
end

local myButton = display.newRect( 100, 100, 200, 50 )
myButton:addEventListener( "touch", myTouchListener )

8.注册事件

我们可以使用addEventListener()对象方法来注册事件。只需要传递一个事件类型的字符串名称和一个处理事件的事件监听器名称。

myButton:addEventListener( "touch", myTouchListener )

Runtime:addEventListener( "system", onSystemEvent )

9.移除事件监听器

大多数的事件监听器,除了像enterFrame之类的Runtime监听器外,如果相关联的对象被移除后,也会被自动移除。当然,你可能需要显式地移除监听器,而不移除相关联的对象。

myButton:removeEventListener( "touch", myTouchListener )

二.Tap / Touch / Multitouch

1.Tap事件检测

Tap事件是屏幕交互的最基本形式。一个Tap指的是用户触摸屏幕,然后几乎在同一时刻抬起。

local function myTapListener( event )

    print( "object tapped = "..tostring(event.target) )  

    return true
end

local myButton = display.newRect( 100, 100, 200, 50 )
myButton:addEventListener( "tap", myTapListener ) 

注意:不像Touch事件,Tap事件没有phase属性。

二.Touch检测

Touch事件提供了一个更加高级的屏幕交互。通过该事件,你可以检测到用户什么时候开始点击屏幕,什么时候离开屏幕。Corona提供了event.phase属性来wanting这种检测,该属性有四个状态:beganmovedendedcancelled

local function myTouchListener( event )

    if ( event.phase == "began" ) then
        print( "object touched = "..tostring(event.target) ) 
    elseif ( event.phase == "moved" ) then
        print( "touch location in content coordinates = "..event.x..","..event.y )
    elseif ( event.phase == "ended" ) then
        print( "touch ended on object "..tostring(event.target) )
    end
    return true  --prevents touch propagation to underlying objects
end

local myButton = display.newRect( 100, 100, 200, 50 )
myButton:addEventListener( "touch", myTouchListener ) 

3.Multitouch事件

多点触摸默认是禁止的,所以你要使用system.activate("multitouch")来开启它。

system.activate( "multitouch" )

local myRectangle = display.newRect( 0, 0, 320, 480 )

local function multitouchListener( event )
    print( "Phase: "..event.phase )
    print( "Location: "..event.x..","..event.y )
    print( "Unique touch ID: "..tostring(event.id) )
    print( "----------" )
    return true
end

myRectangle:addEventListener( "touch", multitouchListener )

三.Local/Push Notifications 本地/远程推送

请看官方Local/Push Notifications

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值