AnimateCCで 傾きセンサーを使った“ブロック崩し” を作ってみるよ![DeviceOrientation] HTML5 Canvas入門(スマホ対応)CreateJS

傾けて操作する “ブロック崩し” を作ってみるよ!

Adobe Animate CC のHTML5 Canvas でスマホの傾きセンサーをつかったアプリが作れることがわかったので、サンプルを作ってみました。

↓完成したサンプルです↓
タップすると画面に表示されます

「ゲームをはじめる」をクリックするとゲーム画面が開きます
005gyro ver.20181225

  • スマートフォン限定
  • スマホを左右に傾けるとラケットが左右に動かせます
  • 画面の上部に傾きセンサーの数値が表示されています
  • ブロック崩しとは関係ないビー玉が一つ動いています

ラケットの操作にY軸回転のgammaの値を割り当てて操作するようにしています。

また、ブロック崩しのゲームとはまったく無関係ですが、木枠に囲まれたビー玉の動きをつけています。ゲームのタイトル画面でも動いているので画面を空に向けて平らにし、少しずつ傾けてボールを動かしてみてください。

スマホの傾きを扱うコード

window.DeviceOrientationEvent
傾きが変化した時に発火するイベント
window.addEventListener("deviceorientation", onOrientation);
function onOrientation(e) {
	var alpha = e.alpha;
	var beta = e.beta;
	var gamma = e.gamma;
}

スマホの傾きを捉えるイベントが deviceorientation です。

パパ
パパ

「デバイス・オリエンテーション」って名前を聞いただけでは何をするためのものか判りませんよね

deviceorientationイベントのリスナーから呼ばれる関数(function)のイベントオブジェクト(e)にalpha, beta, gamma の値が収められています。

alpha:Z軸を中心に水平回転の値
範囲:0.0〜360.0(浮動小数)

スマホを机の上に置いて水平のままくるくる回すと値が変わります。反時計回り値が増えて起点を越えると0に戻ります。

真北が起点:0という端末もあるようですが、iPhoneではアプリ起動の度に起点は変わりました。

beta:X軸を中心に縦回転の値
範囲:-180.0〜180.0(浮動小数)

画面を空に向けた水平の状態が起点:0で、画面を手前に起こすと数値が増えます。画面が真下に向いた状態で180から-180に切り替わって、そのまま回転していくとマイナスの値から画面が真上を向いた時にプラスの値になります。

gamma:Y軸を中心に横回転の値
範囲:-90.0〜90.0(浮動小数)

画面を空に向けた水平の状態が起点:0。そのまま画面を右に向けるように回転すると数値が増えて垂直になった時点で値が90から-90に替わります。そのまま真下を向けると再び 0 になって画面が左向きに垂直になったときに90から-90に替わり、水平になるまでマイナスの値になります。

プラスからマイナスに切り替わる時に注意しましょう

このdeviceorientationをアプリで使うにあたり、実装上の注意が必要です。

例えばgammaの値は、スマホを横向きに90度立てた状態になると90から-90に突然切り替わります。今回は、この動きをコントロールする方法が思いつかずに放置してしまいました。

写真のように垂直に立てるとgammaの値が切り替わり、ラケットもビー玉もカクッと上に動いてしまいます。

gammaが-90になったら180足して90から繋がるような計算をすればいいかと思いきや、gammaについては水平の状態から左側に90度立てた位置までも0〜-90になるため、同じ値で2つの状態の可能性が出てきてしまいます。やっかいですよね。なぜこんな仕様にしたのか理解できませんが、仕方ありませんね。

まあ実際の操作にはほとんど影響はありませんので今回は放置してしまいました。

画面の回転(ポートレートとランドスケープ)のチェック

スマホだと端末を横向きにした時にプラウザが半回転して横長の画面になります。画面が90度回転してもdeviceorientationの値は変わらないので、縦長(ポートレートというそうです)から横長(ランドスケープというそうです)になったら縦と横のbetaとgammaを入れ替える工夫が必要です。

この画面がポートレートかランドスケープかを確認するコードは以下の通り。

if (window.orientation == 0){
	//縦向き(ポートレイト)
}else if (window.orientation == 90){ 
	//左向きの横向き(ランドスケープ)
}else if (window.orientation == -90){ 
	//横向き(ランドスケープ)
}
wondow.orientation
0:縦向き(ポートレート)
90/-90:横向き(ランドスケープ)

windowのorientationというプロパティを確認することでポートレート(縦)かランドスケープ(横)かを確認できます。この値は中間値は無く「0 / 90 / -90」のみのようです。

ブラウザが対応していないと機能しません

webアプリですからブラウザがwindow.DeviceOrientationEventに対応していないと機能しません。確認は以下のようなコードで行います。

if (window.DeviceOrientationEvent) {
  window.addEventListener("deviceorientation", onDeviceOrientation);
  //傾きの値を使ったアクション
}

一応、最近のiOS、Androidともだいたい対応しているようです。PCのブラウザも対応しているものが多いようですが、事実上傾きセンサーは使えないのでアプリの利用はできませんが、JavaScriptコンソールを表示すると擬似的に値を与えた動作確認はできました。

デバイスによってはジャイロスコープ(傾きセンサー)自体が搭載されていない場合があるようです。しかしOSやブラウザの仕様としては「対応している」振る舞いをするので自動的に判断もできません。
私の持っているCHUWIという中国製のタブレットでテストしていて、ぜんぜん動かないので「なんで?」と思いしばらく右往左往したのですが結果的にはセンサー自体が付いていないということが判りました。なんてこった。

パソコンで擬似的に操作する方法

MacのChromeの場合、メニューの「表示」から「開発 / 管理」>「JavaScript コンソール」を選びます。

さらに右下のウィンドウメニューから「Sensers」を選びます。

そして「Orientation」のタブから「Custom orientation…」を選ぶと、スマホのイメージ部分を動かして傾き情報を変化させられるようになります。

こんな感じ

パパ
パパ

これは開発時の確認用ですね。基本的にはスマホ専用ということになります

現実的には予め「スマホ専用」とするか、「傾きセンサー操作」と「タッチ操作」を手動で切り替えができるようにするべきだと思いました。

ぜひスマホでお試しください!

いろいろややこしいコーディングになってしまいましたがwebアプリとして完成してみると、とても面白い操作体験が実現されています。

しばらく触っていればすぐに慣れて、もともとのドラッグ操作よりも快適にブロック崩しがプレイできました。

ぜひ皆様も、ご自身のスマホで『傾きセンサー(ジャイロスコープ)操作』を体験してみてくださいね!