タップイベント(ダブルタップ)

このエントリーをはてなブックマークに追加




 タップ動作の認識方法と使い方についてです。タップとは画面を触って、同じ場所で放す行為です。ちなみに画面を触り、少しでも移動させたらタップではなくタッチになります。
 「タップ」イベントはオブジェクト(図や文字など)に関連付けて使用します。オブジェクトをタップすると、「タップ」イベントが発生し、指定した関数の処理を実行します。


1. 「タップ」の流れ

 タップイベントを行う際、必要な処理は以下の3つです。
  1. タップ動作に反応させるオブジェクトを作成
  2. タップしたときに実行する処理を作成(関数の作成)
  3. 作成したオブジェクトにタップイベントを追加


1.1 タップの使い方

 タップ時の処理の流れを確認するために、簡単なプログラムを作成します。ある特定のオブジェクトをタップした際、タップイベントが発生するようにします。今回は円を描画し、その円をタップすると色が変わるようにしたいと思います。

— タップ動作で反応させる円を作成します。色は緑色にしています。
local circle = display.newCircle(display.contentCenterX, display.contentCenterY, 100)
circle:setFillColor(0, 1, 0, 1)

— タップした際、その描画オブジェクトの色を赤色にします。
local function onTap(event)
    event.target:setFillColor(1, 0, 0, 1)
    return true
end

— 作成した描画オブジェクトにタップイベントを登録します。
circle:addEventListener("tap", onTap)

 以上が、タップすると円が緑色から赤色に変わるプログラムです。取りあえず流れを知るためのプログラムなので、とても単純です。次章から詳しい使い方についてです。


2. タップイベントの追加と削除

2.1 タップイベントの追加

 描画オブジェクトにタップイベントを追加するには、「addEventListener」関数を使用します。

object:addEventListener("tap", listener)

引数名 説明
eventName イベント名
今回はタップなので:"tap"とします
listener 実行する関数


2.2 タップイベントの削除

 描画オブジェクトのタップイベントを解除するには、「removeEventListener」関数を使用します。
 リファレンスを見ると関数と引数は以下の通りです。

object:removeEventListener("tap", listener)

引数名 説明
eventName イベント名
今回はタップなので:"tap"とします
listener 削除する関数


2.3 複数の関数を実行

 ちょっと変わった使い方として、以下のように1つのオブジェクトに2つの関数を登録することも可能です。

object:addEventListener("tap", onTap1)
object:addEventListener("tap", onTap2)

 このようにすると、タップした際、「onTap1」が呼ばれ、続いて「onTap2」が実行されます。ただ、不具合を組み込む原因になりそうなので、このような使い方はお勧めしません。


3. タップイベントで呼び出す関数の引数

 タップイベントで呼ばれる関数に渡される引数についてです。タップイベントで呼ばれる関数の引数には「event」という引数をつけておきます。「event」でなくても問題なく動作しますが、リファレンスではその様に使われているので、ここでは「event」とします。

local function onTap(event)

 eventはテーブル形式となっています。中身は以下の通りです。

テーブルのID 説明
target タップイベントを発生させたオブジェクト(テーブル)
name "tap"が入っています
numTaps タップした回数
x タップした位置:x座標
y タップした位置:y座標


3.1 イベントを発生させたオブジェクト:event.target

 「event.target」にアクセスすることで、呼び出したオブジェクトを操作することができます。


3.1.1 単体のオブジェクトでのイベント
 サンプルで紹介したような描画オブジェクトをそのまま使用する場合、通常扱うように使用することができます。サンプルでは円を描画し、タップをした際、その円の色を「setFillColor」関数を用いて変更しています。また、以下のようなことも可能です。

— オブジェクトの作成
local circle = display.newCircle(display.contentCenterX, display.contentCenterY, 100)
— オブジェクトにnameというIDを追加し名前を登録
circle.name = "Circle"

local function onTap(event)
    — 登録した名前の表示
    print(event.target.name)
    return true
end
— タップイベントの登録
circle:addEventListener("tap", onTap)

 上記プログラムでは、円のオブジェクトにnameというIDを追加して名前をつけています。このようにするとどのオブジェクトがタップイベントを発生させたのかを確認することができます。


3.1.2 グループでのイベント
 グループオブジェクトにタップイベントを追加することもできます。この場合、「event.target」を使用してアクセスする方法が少し変わります。グループオブジェクトはテーブルと同様なアクセス方法になるので、登録した1つ目にアクセスする場合「event.target[1]」とし、2つ目は「event.target[2]」となります。サンプルを以下に示します。

— グループを作成
local tapTestGroup = display.newGroup()
— 大きい円を作成しグループに登録
local circle01 = display.newCircle(tapTestGroup, display.contentCenterX, display.contentCenterY, 100)
circle01:setFillColor(0, 1, 0, 1)
— 小さい円を作成しグループに登録
local circle02 = display.newCircle(tapTestGroup, display.contentCenterX, display.contentCenterY, 50)
circle02:setFillColor(0, 0, 1, 1)

— タップイベント発生時の処理
local function onTap(event)
    event.target[1]:setFillColor(1, 0, 0, 1)
    event.target[2]:setFillColor(1, 1, 0, 1)
    return true
end
— グループにタップイベントを追加
tapTestGroup:addEventListener("tap", onTap)

 上記プログラムでは、緑色の大きな円と青色の小さな円が描画されます。タップすると大きな円が赤色になり、小さな円が黄色になります。


3.1.3 注意事項
 以上の事から、単体のオブジェクトとグループのオブジェクトでは「event.target」に入っている内容、アクセス方法が変わります。注意しないとnilにアクセスしてしまいプログラムが異常終了する可能性があります。
 そこで、オブジェクトと関数をもっと密着させて使用する方法があります。詳しくは4章でまとめています。


3.2 タップ回数(ダブルタップ確認):event.numTaps

 シングルタップ、ダブルタップなどタップ回数を知りたいことがあります。その様なときに使用するのが「event.numTaps」変数です。ここにはタップした回数が登録されています。例えば以下のようにタップイベントで呼び出される関数に条件を追加すると、ダブルタップを確認することができます。

local function onTap(event)
    print(event.numTaps)
    if (event.numTaps == 2) then
        print("Double Tap")
    end
    return true
end


4. タップ時に動作する関数の登録方法

 タップイベント発生時に登録する関数の登録方法についてです。色々な方法がありますので、いくつかを紹介します。


4.1 普通に関数を登録

 サンプルで紹介してきた方法です。

— オブジェクトの作成
local circle = display.newCircle(display.contentCenterX, display.contentCenterY, 100)
— タップイベント発生時の処理
local function onTap(event)
    print("Tap")
    return true
end
— タップイベントの追加
circle:addEventListener("tap", onTap)


4.2 オブジェクトをテーブルにしてIDに"tap"を追加

4.2.1 IDを追加

— オブジェクトの作成
local circle = display.newCircle(display.contentCenterX, display.contentCenterY, 100)
— タップイベント発生時の処理
local function onTap(self, event)
    print("Tap")
    — selfがオブジェクトになります
    self:setFillColor(1, 0, 0, 1)

    return true
end
— オブジェクトにID「tap」を追加
circle.tap = onTap
— オブジェクトにタップイベントを追加
circle:addEventListener("tap", circle)


4.2.2 関数をオブジェクトに追加

— オブジェクトの作成
local circle = display.newCircle(display.contentCenterX, display.contentCenterY, 100)
— タップイベント発生時の処理(localをつけてはいけません
function circle:tap(event)
    — selfがオブジェクトになります
    self:setFillColor(1, 0, 0, 1)

    return true
end
— タップイベントの追加
circle:addEventListener("tap", circle)


5. タップイベントの影響範囲(どこまで伝わる?)

 さて、タップイベントはどこまで伝わっていくのでしょうか。答えは戻り値で「true」が来るまでです。戻り値で「true」を返さない限り下に伝わっていきます。では、プログラムで説明したいと思います。

— 赤色の円
local circle01 = display.newCircle(display.contentCenterX, display.contentCenterY – 50, 100)
circle01:setFillColor(1, 0, 0, 1)
function circle01:tap(event)
    self:setFillColor(1, 1, 1, 1)
end
circle01:addEventListener("tap", circle01)

— 緑色の円
local circle02 = display.newCircle(display.contentCenterX – 50, display.contentCenterY + 50, 100)
circle02:setFillColor(0, 1, 0, 0.6)
function circle02:tap(event)
    self:setFillColor(1, 1, 1, 1)
end
circle02:addEventListener("tap", circle02)

— 青色の円
local circle03 = display.newCircle(display.contentCenterX + 50, display.contentCenterY + 50, 100)
circle03:setFillColor(0, 0, 1, 0.6)
function circle03:tap(event)
    self:setFillColor(1, 1, 1, 1)
end
circle03:addEventListener("tap", circle03)


 上記プログラムでは3つの円を少しずつ重なるようにしています。重なりが見えるように上のふたつの円は半透明にしています。重なり方の順番は1番下が赤色、2番目が緑色、3番目が青色になっています。現状のプログラムでは、タップイベントはタップした部分にある円全てで発生します。すなわち、中心部分の3個重なっている部分をタップすると、全タップイベントの関数が呼ばれ、全ての円が白色に変化します。タップイベント発生時の処理の流れは以下の通りです。

  1. 円の中心をタップ
  2. 1番上にある青色の円のタップイベントが発生(青色のtap関数を実行)
  3. 2番目の緑色の円のタップイベントが発生(緑色のtap関数を実行)
  4. 3番目(1番下)の赤色の円のタップイベントが発生(赤色のtap関数を実行)

 以上のように、タップした部分にある円全てでタップイベントが発生します。
 しかし、アプリやゲームではタップしたオブジェクトのみ処理させたいことがあります。その様な場合、下に伝わらないように、その関数で処理を止める必要があります。その方法はとても簡単で、戻り値で「true」を返すことです。上記プログラムでは、各タップイベント処理関数の最後に「return true」を追加するだけです。すると、重なり合っている部分をタップしても、その1番上のオブジェクトのみ処理されます。
 動きがあったほうがわかりやすいと思うので、動画を作成しましたので確認してください。







       



<更新履歴>

更新日 Corona SDKのバージョン
新規作成 2015年12月2日 v2015.2731






前へ          メニューへ          次へ



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)