1. 程式人生 > >cocos2d-x,lua的Layer.onClick點選事件封裝

cocos2d-x,lua的Layer.onClick點選事件封裝

cocos2d-x3.4,lua版本Layer封裝了onTouch事件,但沒有封裝onClick事件,遊戲按鈕資源通常是一張圖片,使用ccui.Button有點浪費;

在Layer.onTouch事件中判斷是否點選圖片比較麻煩,began事件後,移動手勢,ended事件座標點就會跟began事件不在一個點上;

檢視widget原始碼可知,按鈕點選事件是在onTouchBegan,onTouchMoved、onTouchEnded中呼叫hitTest判斷圖片矩形是否與觸控點一致,都重合時才會觸發點選事件;

這裡對Layer的onTouch修改下,讓其在限定範圍內的移動小於20畫素(容差值)才觸發點選事件,在onClick方法中再判斷是否點選目標圖片即可,這樣可以省去很多觸控判斷,也可以實現點選功能,省去ccui.Button類效能也相應得到些提升;

開啟檔案:src/cocos/framework/extends/LayerEx.lua,編輯以下程式碼:

--[[

Copyright (c) 2011-2014 chukong-inc.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

]]

local Layer = cc.Layer

function Layer:onTouch(callback, isMultiTouches, swallowTouches)
    if type(isMultiTouches) ~= "boolean" then isMultiTouches = false end
    if type(swallowTouches) ~= "boolean" then swallowTouches = false end
    self.touchhandler__ = true
    local began = nil
    self:registerScriptTouchHandler(function(state, ...)
        local args = {...}
        local event = {name = state}
        if isMultiTouches then
            args = args[1]
            local points = {}
            for i = 1, #args, 3 do
                local x, y, id = args[i], args[i + 1], args[i + 2]
                points[id] = {x = x, y = y, id = id}
            end
            event.points = points
        else
            event.x = args[1]
            event.y = args[2]
        end
        local bool = callback(event)
        
        --自定義新增點選事件 by jt 2016/04/20
        if self.clickCallBack ~= nil then
            if state == "began" then
                began = event
            elseif state == "ended" then
                local offset = 20--誤差值,
                local rect = cc.rect(began.x-offset,began.y-offset,began.x+offset,began.y+offset)
                if event.x >= rect.x and event.y >= rect.y and event.x <= rect.width and event.y <= rect.height then
                    self.clickCallBack(event)
                end 
            end
        end
        return bool
    end, isMultiTouches, 0, swallowTouches)
    self:setTouchEnabled(true)
    return self
end

function Layer:onClick(callback)
    self.clickCallBack = callback
    if not self.touchhandler__ then
        self:onTouch(function(event)
            return true
        end)
    end
    return self
end

function Layer:removeTouch()
    self:unregisterScriptTouchHandler()
    self:setTouchEnabled(false)
    return self
end

function Layer:onKeypad(callback)
    self:registerScriptKeypadHandler(callback)
    self:setKeyboardEnabled(true)
    return self
end

function Layer:removeKeypad()
    self:unregisterScriptKeypadHandler()
    self:setKeyboardEnabled(false)
    return self
end

function Layer:onAccelerate(callback)
    self:registerScriptAccelerateHandler(callback)
    self:setAccelerometerEnabled(true)
    return self
end

function Layer:removeAccelerate()
    self:unregisterScriptAccelerateHandler()
    self:setAccelerometerEnabled(false)
    return self
end
使用方法:
local LoginView = class("LoginView",cc.load("mvc").ViewBase)

local MotionUtil = {}

----------------------
---- @param #node
---- @param #event 
---- @return bool(是否目標觸屏物件)
function MotionUtil:checkPointToNode(node,event)
    if not node:isVisible() then return false end
    local point =  node:convertToNodeSpace(event)
    local size = node:getContentSize()
    local rect = cc.rect(0,0,size.width,size.height)
    if cc.rectContainsPoint(rect,point) then
        return true
    end 
    return false
end


function LoginView:ctor()
	self.spr_btn = cc.Sprite:create("btn_test.png"):addTo(self)--圖片路徑請自行定義修改

	--事件層
    self.touchLayer = display.newLayer()
        :onTouch(handler(self, self.onTouch))
        :onClick(handler(self, self.onClick))
        :addTo(self)
end

function LoginView:onTouch(event)
    --onTouch事件處理,比如觸控按下圖片變顏色,鬆開還原

    return true --這裡要返回true,onClick才會被呼叫
end


function LoginView:onClick(event)
	
<span style="white-space:pre">	</span>if MotionUtil:checkPointToNode(self.spr_btn,event) then
		print("點中了spr_btn")
	end

end



相關推薦

cocos2d-xlua的Layer.onClick事件封裝

cocos2d-x3.4,lua版本Layer封裝了onTouch事件,但沒有封裝onClick事件,遊戲按鈕資源通常是一張圖片,使用ccui.Button有點浪費; 在Layer.onTouch事件中判斷是否點選圖片比較麻煩,began事件後,移動手勢,ended事件座標

解決 jQuery 動態新增節點無法觸發 onclick 事件的問題

     問題: 當我們在網頁載入完成後, 使用 JQuery 給頁面動態增加增加節點時, 會發現新增節點無法觸發點選事件      處理: 使用 live() 或 on() 方法給新增節點新增點選事件    !

微信分享獲取分享事件登入後才可以分享

1.登入微信公眾平臺 2.獲取開發者ID(AppID),開發者密碼(AppSecret) 3.配置js安全域名,下載.txt檔案放到專案跟目錄 4.控制器 <?php namespace M\Controller; use Think\Controller; class

獲取場景中的所有按鈕並新增事件

void Start() {//初始化時 獲取 所有按鈕新增監聽 Addlisteningevent(); } public void Addlisteningevent() {//查詢所有按鈕 Button[] allObj =

自定義通知欄並註冊事件

描述 如題 效果圖 程式碼 /** * function: 自定義通知欄 * Created by wiky on 2016/6/27. */ public class MyNotification { private static f

使用華為推送向伺服器註冊並接收訊息處理訊息事件

華為推送是華為公司推出的,優秀的推送服務,在專案中,我使用了華為的推送服務,記錄下來,供其他同學參考。 1.配置Maven庫 在allprojects->repositories 裡面配置HMSSDK的maven倉。  allprojects {         

ionic開發——百度地圖InfoWindow資訊視窗上新增按鈕無法觸發事件問題解決辦法

ionic開發中,在使用百度地圖的時候,有時我們需要在點選地圖上標註的海量點彈出一個infowindow的資訊視窗,自定義資訊視窗的內容後,我們想要可以在資訊視窗上面點選的時候,發現點選沒有效果。 我

Cocos2d-x例項:單觸控事件

為了讓大家掌握Cocos2d-x中的事件機制,下面我們以觸控事件為例,使用事件觸發器實現單點觸控事件。該例項如圖8-3所示,場景中有三個方塊精靈,顯示順序如圖8-3所示,拖拽它們可以移動它們,事件響應優先順序是按照它們的顯示順序。下面我們再看看具體的程式程式碼,首先看一下HelloWorldScene.h檔案

ButterKnife onclick事件沒反應問題

在新增依賴的時需要新增兩個,如果點選沒反應,可能是少了下面那一句。 compile 'com.jakewharton:butterknife:x.x.x' annotationProcessor 'c

js追加html如何新增事件

$("#product").on("click", ".items", function () { $.app.product.displayProduct($(this).attr("id")); }

JS onclick事件圖片切換其他圖片

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <

textView autolink 和onclick 事件衝突

http://blog.csdn.net/dadzyl/article/details/39315445 extView設定autolink後,點選會自動響應超連結的處理,想要點選除超連結的部分實現跳轉到其他activity,現實現自定義控制元件。 1.自定義Auto

Android 選單個按鈕或者其他的View在view上出現水波紋效果然後執行事件

1.自定義一個佈局,得到點選的view,在view上繪畫水波紋,水波紋的圓心是view的中點,半徑為寬和高一半的最小值。 package com.example.waterview; import java.util.ArrayList; import android.

appium獲取不到固定鍵盤使用tap()事件

1.獲取當前頁面的元素但是獲取不到固定鍵盤的元素;2.開啟開發者模擬裡選中指標位置,如圖;3.開啟模擬器或者手機當前頁面,點選選中的固定鍵盤上的文字,按住不動,在模擬器或者手機上邊顯示x軸,y軸座標,如圖;4.self.action.baseFind.driver.tap([

在adapter中對item的某個控制元件並在事件中對其他item控制元件進行設定

今天做專案的時候遇到了這個問題,現在將解決方案的程式碼記錄下來,以便大家遇到同樣的問題時能夠方便處理。 final TextView tv_state = holder.tv_download_st

UILabel設定屬性字串可以增加事件

1.首先啊,label可以設定屬性字串,設定不同的字型顏色,字型大小,但是要增加點選事件,不好操作。 2.所以文章是設定textView來完成的。 - (UITextView *)textView { if (!_textView) { _tex

取消html 移動端 onclick事件高亮效果

-webkit-tap-highlight-color:rgba(0,0,0,0) //webkit是蘋果瀏覽器引擎,tap點選,highlight背景高亮,color顏色,顏色用數值調節。 原因如

Android Button按鈕兩次之後才執行事件的操作。

    在我的專案裡有個頁面同時存在 一個EditText和一個Button。如圖。 由於每次進入這個頁面都彈出軟鍵盤,所以我在這個提交訂單頁面的AndroidManifest.xml中聲明瞭一句 android:windowSoftInputMode="stateH

cocos2DX-lua 事件封裝

宣告按鈕TAG標籤 local TAGEBTN_TEST1 =0x01 local TAGEBTN_TEST2 =0x02 繫結事件 binBtn(“Button_1”,TAGEBTN_TEST1) binBtn(“Button_2”,TA

cocos2d-x中解決事件上層響應下層不響應

解決方案是重寫一個Layer,加在上下層中間,即可只響應上層事件,阻斷了下層的事件,設定優先順序,程式碼如下 #ifndef _TouchBlockLayer_H_ #define _TouchBlockLayer_H_ class TouchBlockLayer: