今回は Android で加速度センサーの値を取得する方法です。
iOS のときの繰り返しになりますが、
Cocos Sharp でも CCAccelerometer で加速度センサーの値を取得できますが、
この方法だと、センサーの値が遅延して取得されるという不具合があるので、
ネイティブで取得したセンサーの値をグローバルで参照できるクラスに書込み、
その値を Cocos Sharp 側から参照する方法を採用しています。
CocosSharpGameSample.Core 側の準備は iOS 版で整っているので、
ネイティブ部分のみの実装です。
CocosSharpGameSample.Android プロジェクトの MainActivity.cs に、ISensorEventListener の継承を追加します。
public class MainActivity : AndroidGameActivity, ISensorEventListener
MainActivity.cs のフィールドに、SensorManager を定義します。
また、センサーの値を書き込む際のロックキーを定義します。
// センサーマネージャ private SensorManager sensorManager; // ロックキー private object accelerometerSyncLock = new object();
OnCreate メソッドに、センサーをセットアップする処理を追加します。
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // センサーのセットアップ this.sensorManager = (SensorManager)GetSystemService(Context.SensorService); // ゲームを起動する。 var application = new CCApplication(); application.ApplicationDelegate = new SampleGameApplicationDelegate(); SetContentView(application.AndroidContentView); application.StartGame(); }
センサーの精度が変更されたときにコールされる OnAccuracyChanged メソッド、
センサーの値が変更されたときにコールされる OnSensorChanged メソッドを実装し、
OnSensorChanged メソッドで加速度センサーの値を取得します。
// センサーの精度が変更されたときのハンドラ public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy) { // 何もしない } // センサーの値が変更されたときのハンドラ public void OnSensorChanged(SensorEvent e) { // 加速度センサーの値を取得 lock (this.accelerometerSyncLock) { AccelerometerInfo.Default.AccelerationX = e.Values[0]; AccelerometerInfo.Default.AccelerationY = e.Values[1]; AccelerometerInfo.Default.AccelerationZ = e.Values[2]; } }
OnResume メソッドで加速度センサーのリスナーを登録し、監視対象にします。
SensorDelay は値取得の頻度です。
ゲームを作成するので SensorDelay.Game にしておきます。
protected override void OnResume() { base.OnResume(); this.sensorManager.RegisterListener(this, sensorManager.GetDefaultSensor(SensorType.Accelerometer), SensorDelay.Game); } protected override void OnPause() { base.OnPause(); this.sensorManager.UnregisterListener(this); }
以上をまとめると MainActivity.cs は下記のようになります。
using Android.App; using Android.Content; using Android.Content.PM; using Android.Hardware; using Android.OS; using CocosSharp; using CocosSharpGameSample.Core; using Microsoft.Xna.Framework; namespace CocosSharpGameSample.Android { [Activity(Label = "CocosSharpGameSample.Android" , MainLauncher = true , Icon = "@drawable/icon" , AlwaysRetainTaskState = true , LaunchMode = LaunchMode.SingleInstance , ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden )] public class MainActivity : AndroidGameActivity, ISensorEventListener { // センサーマネージャ private SensorManager sensorManager; // ロックキー private object accelerometerSyncLock = new object(); protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // センサーのセットアップ this.sensorManager = (SensorManager)GetSystemService(Context.SensorService); // ゲームを起動する。 var application = new CCApplication(); application.ApplicationDelegate = new SampleGameApplicationDelegate(); SetContentView(application.AndroidContentView); application.StartGame(); } // 画面の向きを Landscape に固定 public override ScreenOrientation RequestedOrientation { get { return ScreenOrientation.Landscape; } set { base.RequestedOrientation = ScreenOrientation.Landscape; } } // センサーの精度が変更されたときのハンドラ public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy) { // 何もしない } // センサーの値が変更されたときのハンドラ public void OnSensorChanged(SensorEvent e) { lock (this.accelerometerSyncLock) { AccelerometerInfo.Default.AccelerationX = e.Values[0]; AccelerometerInfo.Default.AccelerationY = e.Values[1]; AccelerometerInfo.Default.AccelerationZ = e.Values[2]; } } protected override void OnResume() { base.OnResume(); this.sensorManager.RegisterListener(this, sensorManager.GetDefaultSensor(SensorType.Accelerometer), SensorDelay.Game); } protected override void OnPause() { base.OnPause(); this.sensorManager.UnregisterListener(this); } } }
これで、ゲーム画面でセンサーの値が更新されるようになりました。
今回はここまでです。