Hatena::ブログ(Diary)

コロナはじめました。 RSSフィード

2011-07-20

[]transition.to応用編(起動ロゴ作ってみよう)


以前、transition.toを少し紹介しました。

今回は、そのtransition.toを使って簡単な起動画面を作ってみました。


毎度ですが、仕様はと言いますと。

仕様1.会社のロゴが段々と大きくなる

仕様2.タップすると次の画面(ゲームスタート)に遷移する。

仕様3.自動で次の画面(ゲームスタート)に遷移する。


仕様1.会社のロゴが段々と大きくなる

まず、イメージを作成します。その後、transition.to()を使用して、動きをつけます。

local startLogo = display.newImage("logo.png")
startLogo:setReferencePoint(display.CenterReferencePoint)
startLogo.x = display.contentCenterX
startLogo.y = display.contentCenterY
startLogo.xScale = 0.1
startLogo.yScale = 0.1

transition.to(startLogo,{ xScale = 1,yScale = 1,time = 3000})

ソースコードの意味は、

logo.pngのイメージを読む。

イメージのx,y軸基準をセンターにする。

ディスプレイの真ん中にイメージを置く

logoは、元の大きさの0.1倍から。

3000msec後に、縦、横ともに画像の本来の大きさまで。

これで仕様1は出来ました。


仕様2.タップすると次の画面(ゲームスタート)に遷移する。

addEventListener()で"tap"を許可します。

ここで気をつけたいのは、仕様1で実装したtransition.toがまだ動いてるかも知れません(というか動いてる)。

当然、キャンセルをする必要があります。それらを考慮したうえで実装しましょう。


まずは、"tap"を許可します。

local function tapFrameListener(event)
end

Runtime:addEventListener( "tap", tapFrameListener )


次に仕様1のtransition.toをキャンセルできるようにします。

 --★1
local trans_logo

local startLogo = display.newImage("logo.png")
startLogo:setReferencePoint(display.CenterReferencePoint)
startLogo.x = display.contentCenterX
startLogo.y = display.contentCenterY
startLogo.xScale = 0.1
startLogo.yScale = 0.1

local function tapFrameListener(event)
      --★2
      transition.cancel(trans_logo)
      startLogo:removeSelf()
      Runtime:removeEventListener( "tap", tapFrameListener )
end

--★3
trans_logo=transition.to(startLogo,{ xScale = 1,yScale = 1,time = 3000})
Runtime:addEventListener( "tap", tapFrameListener )

★3でハンドラーを取得しておきます。

そのハンドラーを"tap"イベント割り込み時にキャンセル(★2)するだけです。

(注)これで動きは止まりますが、画像が残ったままになりますので、イメージのremoveSelf()も追加しておきます。


「次の画面(ゲームスタート)に遷移する。」部分ですが、"START"というテキストを出すだけします。

(お好みで、画像出しても何でもいいです。)


ソースは以下のようになります。

function game_start()
    local startText = display.newText("Start",0,0,native.systemFontBold,50)
    startText:setReferencePoint(display.CenterReferencePoint)
    startText.x = display.contentCenterX
    startText.y = display.contentCenterY
end

function main()
    local trans_logo

    local startLogo = display.newImage("logo.png")
    startLogo:setReferencePoint(display.CenterReferencePoint)
    startLogo.x = display.contentCenterX
    startLogo.y = display.contentCenterY
    startLogo.xScale = 0.1
    startLogo.yScale = 0.1

    local function tapFrameListener(event)
        transition.cancel(trans_logo)
        startLogo:removeSelf()
        Runtime:removeEventListener( "tap", tapFrameListener )
        game_start()
    end

   trans_logo=transition.to(startLogo,{ xScale = 1,yScale = 1,time = 3000})
   Runtime:addEventListener( "tap", tapFrameListener )
end
main()

tapFrameListener()の中で、次の画面表示関数をコールするようにしてます。


仕様3.自動で次の画面(ゲームスタート)に遷移する。

自動といっても、traisition.toで設定したtimer満了したことがわかればいいだけです。

    local function transComp(obj)
        startLogo:removeSelf()
        Runtime:removeEventListener( "tap", tapFrameListener )
        game_start()
    end

    (略)

   trans_logo=transition.to(startLogo,{ xScale = 1,yScale = 1,time = 3000, onComplete=transComp})

transition.toにonCompleteパラメータを追加したのをおわかりいただけるでしょうか?

timeパラメータで指定した時間が満了するとonCompleteパラメータ指定の関数を処理します。

あとは、その関数の中で、次画面表示処理をすればいいだけです。

全体のソースは次のようになります。

function game_start()
    local startText = display.newText("Start",0,0,native.systemFontBold,50)
    startText:setReferencePoint(display.CenterReferencePoint)
    startText.x = display.contentCenterX
    startText.y = display.contentCenterY
end

function main()
    local trans_logo

    local startLogo = display.newImage("logo.png")
    startLogo:setReferencePoint(display.CenterReferencePoint)
    startLogo.x = display.contentCenterX
    startLogo.y = display.contentCenterY
    startLogo.xScale = 0.1
    startLogo.yScale = 0.1

    local function transComp(obj)
        startLogo:removeSelf()
        Runtime:removeEventListener( "tap", tapFrameListener )
        game_start()
    end

    local function tapFrameListener(event)
        transition.cancel(trans_logo)
        startLogo:removeSelf()
        Runtime:removeEventListener( "tap", tapFrameListener )
        game_start()
    end

   trans_logo=transition.to(startLogo,{ xScale = 1,yScale = 1,time = 3000, onComplete=transComp})
   Runtime:addEventListener( "tap", tapFrameListener )
end
main()


完成です。

sample codeは、こちらです。


技術部 藤井 洋祐


2011-07-14

[]「キーイベント」の取得方法 for Android

本日(2011/7/14)リリースされたデイリービルドSDK(2011.570)で、

ハードウェアキーイベントがサポートされました!!!!


それでは、さっそくソースコードを見ていきましょう。


main.lua

01: local evText = display.newText("Please press", 0, 0, native.systemFont, 25)
02: evText.x = display.contentWidth / 2
03: evText.y = display.contentHeight / 2
04: evText:setTextColor( 100, 100, 100 )
05: 
06: local function onKeyEvent( event )
07:	local phase = event.phase
08:	local keyName = event.keyName
09:
10:	if "menu" == keyName then
11:		evText.text = "MENU key, " .. phase
12:
13:	elseif "back" == keyName then
14:		evText.text = "BACK key, " .. phase
15:
16:	else
17:		evText.text = ""..keyName.." , " .. phase ..""
19:
20:	end
21:
22:	return true
23: end
24: 
25: Runtime:addEventListener( "key", onKeyEvent );

01〜04行目:キーイベントの情報を表示するテキストオブジェクトを画面中央に生成しています。

06〜23行目:eventオブジェクトからキー情報を取得する「onKeyEvent」関数を作成します。

      phase ⇒ キー押下状態(UP、DOWNなど)

      keyName ⇒ キーの種別(MENU、BACK、VOLUMEなど)

25行目:作成した「onKeyEvent」関数をRuntimeオブジェクトのaddEventListenerに"key"種別で登録します。



これで、キーイベントを受けることができるようになります。


主にAndroidになりますが、APKを作成し実機で確認すると以下のように動作します。


f:id:began_the_Corona:20110714212205p:image:mediumf:id:began_the_Corona:20110714212204p:image:mediumf:id:began_the_Corona:20110714212203p:image:medium

Xperia ArcAndroid Firmware 2.3.3)


あいにくエミュレータでは、キーイベントがサポートされていないようです。今後のサポートに期待ですね。



また、このSDKはデイリービルドですので、正式にサポートされるのはもう少し後になりそうです。


ハードキーが取得できることでアプリケーションとしての幅が大いに広がるので、非常に嬉しいサポートですね!!!



技術部 藤田竜史

2011-07-06

[]タッチイベントを使ってみる(その2)

タッチイベントを使ってみる(その1)で使用したタッチイベントをまた使ってみましょう。

またCoronaSDK付属のサンプルアプリFrame Animation 1を少し改造してみます。

今度の仕様はと言いますと。

仕様1.フルーツをタッチして

仕様2.ワイプできるようにする。

仕様3.指を離すと回転して、そこから画面を動き回る。


Frame Animation 1の元を見てみます。

local function animate(event)
	xpos = xpos + ( xspeed * xdirection );
	ypos = ypos + ( yspeed * ydirection );

	if ( xpos > screenRight - radius or xpos < screenLeft + radius ) then
		xdirection = xdirection * -1;
	end
	if ( ypos > screenBottom - radius or ypos < screenTop + radius ) then
		ydirection = ydirection * -1;
	end

	fruit:translate( xpos - fruit.x, ypos - fruit.y)
end

Runtime:addEventListener( "enterFrame", animate )

またもや、上のソースを変更していきます。

まずは、いつものように仕様1を満足させます。

fruitオブジェクトに対して、タッチイベント割り込みを発生させます。

local function onTouch(event)
end

fruit:addEventListener( "touch", onTouch )

ソースコードの意味は、

・fruitオブジェクト

・"touch"イベントが発生したら

・onTouchメソッドをコールしなさい

これで仕様1は出来ました。

次は、仕様2です。onTouch()の実装になります。

touchイベントは、event.phaseで、touch開始("began")、移動位置("moved")、指離す("ended")を

使用することによりタッチスクリーン上の指の動きをトレースできます。

これを使いましょう。

function onTouch(event)
    local object = event.target
    if (event.phase == "began") then
      prev_xpos = event.x
      prev_ypos = event.y
    elseif (event.phase == "moved") then
        Runtime:removeEventListener( "enterFrame", animate )
        object:translate( event.x - prev_xpos, event.y - prev_ypos)
        prev_xpos = event.x
        prev_ypos = event.y
    elseif (event.phase == "ended") then
        transition.to( object, { time=1000, rotation=360, onComplete=transitionCompleteCB} )
    end
end

ソースコードの意味は、

・"began"で、前回ポジションとしてX,Y座標を取得(初期値として)

・"moved"されたX,Y座標を取得し、translate()で、前回座標からの移動分だけ動かす

・"ended"で、対象オブジェクトを360度回転(rotation=360) ※仕様3の一部

上のソースコードで仕様3「指を離すと回転して」も実現させています。

仕様3の残りの、「そこから画面を動き回る。」を実装しましょう。

function transitionCompleteCB(obj)
  xpos = obj.x
  ypos = obj.y
 obj.rotation = 0
  Runtime:addEventListener( "enterFrame", animate )
end

ソースコードの意味は、

animate()で使用する動き出し位置のX,Y座標を保存

・"enterFrame"割り込みを再びコールし、animete()の処理を動かす

(注)obj.rotation = 0 をしないと、次のタッチイベント割り込みでフルーツが回転してくれません。

初期化しないと360を保持したままのため、これ以上、回りようが無くなるのです。


これらを元ソースに反映します。

以下が反映させた後のソースです。

local background = display.newImage( "grass.png" )

local radius = 40

local xdirection = 1
local ydirection = 1

local xspeed = 7.5
local yspeed = 6.4

local xpos = display.contentWidth * 0.5
local ypos = display.contentHeight * 0.5
local fruit = display.newImage( "fruit.png", xpos, ypos )

-- Get current edges of visible screen (accounting for the areas cropped by "zoomEven" scaling mode in config.lua)
local screenTop = display.screenOriginY
local screenBottom = display.viewableContentHeight + display.screenOriginY
local screenLeft = display.screenOriginX
local screenRight = display.viewableContentWidth + display.screenOriginX

local prev_xpos,prev_ypos   --add Brilliantservice Y.Fujii

local function animate(event)
	xpos = xpos + ( xspeed * xdirection );
	ypos = ypos + ( yspeed * ydirection );

	if ( xpos > screenRight - radius or xpos < screenLeft + radius ) then
		xdirection = xdirection * -1;
	end
	if ( ypos > screenBottom - radius or ypos < screenTop + radius ) then
		ydirection = ydirection * -1;
	end

	fruit:translate( xpos - fruit.x, ypos - fruit.y)
end

--add Start Brilliantservice Y.Fujii
function transitionCompleteCB(obj)
  xpos = obj.x
  ypos = obj.y
  obj.rotation = 0
  Runtime:addEventListener( "enterFrame", animate )
end

function onTouch(event)
    local object = event.target
    if (event.phase == "began") then
      prev_xpos = event.x
      prev_ypos = event.y
    elseif (event.phase == "moved") then
        Runtime:removeEventListener( "enterFrame", animate )
        object:translate( event.x - prev_xpos, event.y - prev_ypos)
        prev_xpos = event.x
        prev_ypos = event.y
    elseif (event.phase == "ended") then
        transition.to( object, { time=1000, rotation=360, onComplete=transitionCompleteCB} )
    end
end
prev_xpos,prev_ypos = 0
fruit:addEventListener( "touch", onTouch )
--add End   Brilliantservice Y.Fujii

Runtime:addEventListener( "enterFrame", animate )

完成です。

指の動きにあわせて、フルーツが動きます。

(当方、CoronaSimulatorおよびHTC Desireにて、このアプリを動作確認しました。)


技術部 藤井 洋祐

2011-07-04

[]スクロールビューの使い方について。

長い文字や画像を表示する場合、一画面内に収まりきらないケースあります。

そういった時、Coronaでもスクロールビューを使うことができ、

次画面を作らなくても一画面内で構築することができます。


それではさっそく見ていきましょう。

main.lua

 1: local scrollView = require("scrollView")
 2: 
 3: local topBoundary = display.screenOriginY
 4: local bottomBoundary = display.screenOriginY
 5: local scrollView = scrollView.new{top = topBoundary, bottom = bottomBoundary}
 6: 
 7: local myText = display.newText("Hello !!\nBRILLIANTSERVICE.\n\n\n\n\nab\n\ncd\n\nef\n\
                ngh\n\nij\n\nkl\n\nmn\n\nop\n\nqr\n\nst\n\nuv\n\nwx\n\nyz",
                0, 0, native.systemFont, 25)
 8:
 9: myText.top = 0
10: myText.left = 0
11: myText:setTextColor(255, 110, 110)
12:
13: scrollView:insert(myText)
14:
15: scrollView:addScrollBar(255, 110, 110)

1行目:scrollViewを読み込んでいます。(CoronaSDKの「Sample Code\Interface\SlideView\scrollView.lua」を自分のプロジェクトへコピーしておきます。

7行目:表示するテキストを生成しています。文字列の自動改行は後日解説します。(★)

9行目/10行目:テキストを表示する位置を設定しています。

11行目:テキストのカラーを設定しています。

13行目:生成したテキストをscrollViewに追加します。

15行目:スクロールバーを色を指定して追加します。


生成したテキストをscrollViewへ追加するだけで、スクロールビューの画面を構築することができます。

また、スクロールバーも引数RGBを設定するだけで色を指定することができます。



f:id:began_the_Corona:20110704204623p:image

f:id:began_the_Corona:20110704204632p:image


非常に簡単ですね!!




技術部 藤田竜史

2011-06-28

[]今度はタップイベントを使ってみる


前回

object:addEventListener("touch",listener)

を使用し、オブジェクトに動きをつけてみました。

今回は

object:addEventListener("tap",listener)

で動きをつけてみます。

仕様は、前回と同じです。

仕様1.フルーツをタッチしたら

仕様2.回転しながら消えていく。

今回は前回の

object:addEventListener("touch",listener)

に変わって

object:addEventListener("tap",listener)

を使ってタップイベント割り込みとします。

まずは、仕様1を満足させます。

fruitオブジェクトに対して、tapイベント割り込みを発生させます。

function onTap(event)
end

fruit:addEventListener( "tap", onTap )

前回のソースは以下です。

local function onTouch(event)
end

fruit:addEventListener( "touch", onTouch )

touch→tapに変えただけです。

#ややこしいので、listenerも名前を変えてます。

これで仕様1は出来ました。

次は、仕様2ですが、ここは前回と同じです。

function transitionCompleteCB(obj)
    fruit:removeSelf()
end
transition.to( fruit, { time=1000, alpha=0, rotation=360, onComplete=transitionCompleteCB} )

以上、2つの変更を元ソースへ反映します。

local function animate(event)
	xpos = xpos + ( xspeed * xdirection );
	ypos = ypos + ( yspeed * ydirection );

	if ( xpos > screenRight - radius or xpos < screenLeft + radius ) then
		xdirection = xdirection * -1;
	end
	if ( ypos > screenBottom - radius or ypos < screenTop + radius ) then
		ydirection = ydirection * -1;
	end

	fruit:translate( xpos - fruit.x, ypos - fruit.y)
end

-- ↓↓↓追加ここから↓↓↓
function transitionCompleteCB(obj)
    obj:removeSelf()
    Runtime:removeEventListener( "enterFrame", animate )
end

function onTap(event)
    fruit:removeEventListener( "tap", onTap )
    transition.to( fruit, { time=1000, alpha=0, rotation=360, onComplete=transitionCompleteCB} )
end

fruit:addEventListener( "touch", onTouch )
-- ↑↑↑追加ここまで↑↑↑

Runtime:addEventListener( "enterFrame", animate )

tapイベントを使用して

フルーツが回転しながら消えていくアプリの完成です。


このままでは、"touch"と"tap"は、使用シーンによっては、どちらを使用してもいいような感じがします。

しかし、違うイベントして用意されているからには得手、不得手があります。

次回投稿は、"touch"イベントについて、もう少し違う使い方をしてみます。


技術部 藤井 洋祐