個人的なメモ

Tomohiro Suzuki @hiro128_777 のブログです。Microsoft MVP for Developer Technologies 2017- 本ブログと所属組織の公式見解は関係ございません。

Xamarin + Cocos Sharp で iOS, Android 対応のゲームを開発する手順 (11) タッチした場所に敵キャラを出す

今回は画面をタッチした場所に敵キャラを出します。
なお、敵キャラが出るのは画面の上部 1/4 をタッチした場合のみです。

まずは、敵キャラの画像をプロジェクトに追加します。

CocosSharpGameSample.iOS プロジェクトに敵キャラの画像を追加します。

f:id:hiro128:20160825145014p:plain

Resources/Images/Character/Enemy/Enemy001.png

f:id:hiro128:20160825145035p:plain

CocosSharpGameSample.Android プロジェクトに敵キャラの画像を追加します。

Assets/Images/Character/Enemy/Enemy001.png

f:id:hiro128:20160825145058p:plain

次にタッチした場所に敵キャラを配置します。

最初にタッチイベントのリスナーを作成し、ゲーム画面の CCLayer に追加します。
イベントハンドラはリスナーの OnTouchBegan プロパティにデリゲートとして登録します。

public GameLayer()
	: base()
{
	var listener = new CCEventListenerTouchOneByOne();
	listener.OnTouchBegan = this.CCEventListener_TouchBegan;
	this.AddEventListener(listener, this);
}

次に OnTouchBegan イベントハンドラを定義します。
OnTouchBegan イベントハンドラ内でタッチした位置を判定し、敵キャラ画面上に配置します。

OnTouchBegan イベントハンドラはラムダ式で書いても良いですが、ゲームの場合、ラムダ式の中身が大きくなってしまい可読性が下がりますので今回は別途定義しています。

OnTouchBegan の戻り値が true の場合、このイベント自体を処理し、その後の OnTouchEnded, OnTouchMoved, なども処理されます。
OnTouchBegan の戻り値が false の場合、このイベント自体が無視され、その後の OnTouchEnded, OnTouchMoved, なども無視されます。

protected bool CCEventListener_TouchBegan(CCTouch touch, CCEvent touchEvent)
{
	// タッチした場所に敵キャラ配置
	var touchedLocation = touch.Location;
	// 画面の上部25%なら敵キャラ配置
	if (touchedLocation.Y > GameSettings.ScreenHeight * 3 / 4)
	{
		var addingEnemy = new CCSprite("/Resources/Images/Character/Enemy/Enemy001.png", null);
		addingEnemy.Position = touchedLocation;
		addingEnemy.Tag = (int)NodeTag.Enemy;
		this.AddChild(addingEnemy);
		return true;
	}
	return false;
}

以上をまとめると、CocosSharpGameSample.Core プロジェクトの Layers/GameLayer.cs は以下の通りになります。

using System;
using System.Diagnostics;
using CocosSharp;

namespace CocosSharpGameSample.Core
{
	public class GameLayer : LayerBase
	{

		private CCNode player;

		public GameLayer()
			: base()
		{
			var listener = new CCEventListenerTouchOneByOne();
			listener.OnTouchBegan = this.CCEventListener_TouchBegan;
			this.AddEventListener(listener, this);
		}

		protected bool CCEventListener_TouchBegan(CCTouch touch, CCEvent touchEvent)
		{
			// タッチした場所に敵キャラ配置
			var touchedLocation = touch.Location;
			// 画面の上部25%なら敵キャラ配置
			if (touchedLocation.Y > GameSettings.ScreenHeight * 3 / 4)
			{
				var addingEnemy = new CCSprite("/Resources/Images/Character/Enemy/Enemy001.png", null);
				addingEnemy.Position = touchedLocation;
				addingEnemy.Tag = (int)NodeTag.Enemy;
				this.AddChild(addingEnemy);
				return true;
			}
			return false;
		}

		protected override void AddedToScene()
		{
			base.AddedToScene();
			// ゲーム画面の背景画像を配置
			var gameBackground = new CCSprite("/Resources/Images/Background/GameBackground.png", null);
			gameBackground.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
			AddChild(gameBackground);

			// 自機を配置
			this.AddPlayer();

			this.StartScheduling();
		}

		private void StartScheduling()
		{
			this.Schedule(t => this.UpdatePlayer(), 0.02f);
		}

		private void AddPlayer()
		{
			this.player = new CCSprite("/Resources/Images/Character/Player/Player.png", null);
			this.player.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
			this.AddChild(this.player);
		}

		private void UpdatePlayer()
		{
			this.player.PositionX = this.player.PositionX;
			this.player.PositionY = this.player.PositionY;

			// 画面からはみ出ないように、位置の値の上限、下限を設定します。
			// 左
			if (this.player.PositionX < 0 + GameSettings.PlayerWidth)
			{
				this.player.PositionX = 0 + GameSettings.PlayerWidth;
			}
			// 右
			if (this.player.PositionX > GameSettings.ScreenWidth - GameSettings.PlayerWidth)
			{
				this.player.PositionX = GameSettings.ScreenWidth - GameSettings.PlayerWidth;
			}
			// 下
			if (this.player.PositionY < 0 + GameSettings.PlayerHeight)
			{
				this.player.PositionY = 0 + GameSettings.PlayerHeight;
			}
			// 上
			if (this.player.PositionY > GameSettings.ScreenHeight - GameSettings.PlayerHeight)
			{
				this.player.PositionY = GameSettings.ScreenHeight - GameSettings.PlayerHeight;
			}
		}

	}
}

以上で、タッチした場所に敵キャラが出現するようになりました。

f:id:hiro128:20160825145217p:plain

今回は、ここまでです。

何かご質問などございましたらコメント頂ければご回答させていただきますのでお気軽にどうぞ!

Xamarin + Cocos Sharp で iOS, Android 対応のゲームを開発する手順 (10) サンプルゲームの概要

ここまで、Cocos Sharp の基本をご説明してきましたが、ここから実際にサンプルゲームを作成していき、より実戦に即したゲーム作成についてご説明していきます。

ゲームの概要

ゲームプレイヤーは敵キャラを率いる超知性体となりの進撃を防ぎます。

画面にタッチで敵キャラが配置され自機への攻撃を行ないます。

自機は自動で動き、攻撃を行ない配置された敵キャラを攻撃、破壊します。

自機が3機破壊された時点での進入距離の短さがスコアとなります。

f:id:hiro128:20160809164945p:plain

これから、このサンプルゲームを作成しながら、Cocos Sharp の実践的な使い方をご説明していきます。

では、これまでに作成したサンプルコードをゲームの概要に適するように変更していきます。

まずは、CocosSharpGameSample.iOS プロジェクトの AppDelegate.cs です。

加速度センサーに関する部分を削除します。

以下を削除します。

// 加速度センサー
private CMMotionManager cMMotionManager;
// ロックキー
private object accelerometerSyncLock = new object();

FinishedLaunching から加速度センサーに関する部分を削除します。

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
	// ここから削除
	// 加速度センサーのセットアップ
	this.cMMotionManager = new CMMotionManager();
	// センサーの更新間隔
	cMMotionManager.AccelerometerUpdateInterval = 0.1d;
	// センサー更新時のハンドラの設定
	cMMotionManager.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, (data, error) =>
	{
		// センサーの値を書き込む
		lock (this.accelerometerSyncLock)
		{
			// 横向きなのでX,Yを入れ替え
			// X,Yの感度を調整するためセンサーのX,Y軸の取得値を調整
			AccelerometerInfo.Default.AccelerationX = data.Acceleration.Y * 8d;
			// 角度のオフセット
			double angleY = Math.Atan2(data.Acceleration.Z, data.Acceleration.X);
			AccelerometerInfo.Default.AccelerationY = Math.Sin(angleY - 30.6d) * 6d;
			AccelerometerInfo.Default.AccelerationZ = data.Acceleration.Z;
		}
	});
	// ここまで削除する

	// ゲームをを起動する。
	var application = new CCApplication();
	application.ApplicationDelegate = new SampleGameApplicationDelegate();
	application.StartGame();
	return true;
}

画面の向きを Portrait に固定に変更します。

// 画面の向きを Portrait に固定
[Export("application:supportedInterfaceOrientationsForWindow:")] 
public UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, IntPtr forWindow)
{
	return UIInterfaceOrientationMask.Portrait;
}

以上をまとめると、CocosSharpGameSample.iOS プロジェクトの AppDelegate.cs は以下の通りになります。

using System;
using Foundation;
using UIKit;
using CoreMotion;
using CocosSharp;
using CocosSharpGameSample.Core;

namespace CocosSharpGameSample.iOS
{
	[Register("AppDelegate")]
	public partial class AppDelegate : UIApplicationDelegate
	{

		public override bool FinishedLaunching(UIApplication app, NSDictionary options)
		{
			// ゲームをを起動する。
			var application = new CCApplication();
			application.ApplicationDelegate = new SampleGameApplicationDelegate();
			application.StartGame();
			return true;
		}

		// 画面の向きを Portrait に固定
		[Export("application:supportedInterfaceOrientationsForWindow:")] 
		public UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, IntPtr forWindow)
		{
			return UIInterfaceOrientationMask.Portrait;
		}

	}
}


自機の画像を縦画面用に差換えます。

Resources/Images/Character/Player/Player.png

f:id:hiro128:20160809164837p:plain

※自機の画像はハムコロ様の素材を利用させていただきました。

f:id:hiro128:20160809164848p:plain

・制作者:ハムコロ様
・配付元:http://homepage2.nifty.com/hamcorossam

タイトルとゲームの背景画像を宇宙空間のものに差換えます。

Resources/Images/Background/GameBackground.png

f:id:hiro128:20160809164859p:plain

f:id:hiro128:20160809164906p:plain


次にCocosSharpGameSample.Android プロジェクトの MainActivity.cs を変更します。


加速度センサーに関する部分を削除します。

ISensorEventListener を削除します。

public class MainActivity : AndroidGameActivity/* この部分削除 , ISensorEventListener*/

以下を削除します。

// センサーマネージャ
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, OnResume, OnPauseを削除します。

// センサーの精度が変更されたときのハンドラ
public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
{
	// 何もしない
}

// センサーの値が変更されたときのハンドラ
public void OnSensorChanged(SensorEvent e)
{
	lock (this.accelerometerSyncLock)
	{
		// 横向きなのでX,Yを入れ替え
		// X,Yの感度を調整するためセンサーのX,Y軸の取得値を調整
		AccelerometerInfo.Default.AccelerationX = e.Values[1] * 1.5f;
		// 角度のオフセット
		double angleY = Math.Atan2(e.Values[2], e.Values[0]);
		AccelerometerInfo.Default.AccelerationY = Math.Sin(angleY - 29.1d) * 12f;
		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);
}

画面の向きを Portrait に固定に変更します。

// 画面の向きを Portrait に固定
public override ScreenOrientation RequestedOrientation
{
	get
	{
		return ScreenOrientation.Portrait;
	}
	set
	{
		base.RequestedOrientation = ScreenOrientation.Portrait;
	}
}

以上をまとめると、CocosSharpGameSample.Android プロジェクトの MainActivity.cs は以下の通りになります。

using System;
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
	{

		protected override void OnCreate(Bundle bundle)
		{
			base.OnCreate(bundle);
			// ゲームを起動する。
			var application = new CCApplication();
			application.ApplicationDelegate = new SampleGameApplicationDelegate();
			SetContentView(application.AndroidContentView);
			application.StartGame();
		}

		// 画面の向きを Portrait に固定
		public override ScreenOrientation RequestedOrientation
		{
			get
			{
				return ScreenOrientation.Portrait;
			}
			set
			{
				base.RequestedOrientation = ScreenOrientation.Portrait;
			}
		}

	}
}

自機の画像を縦画面用に差換えます。

Assets/Images/Character/Player/Player.png

f:id:hiro128:20160809165052p:plain

※自機の画像はハムコロ様の素材を利用させていただきました。

f:id:hiro128:20160809165059p:plain

・制作者:ハムコロ様
・配付元:http://homepage2.nifty.com/hamcorossam

タイトルとゲームの背景画像を宇宙空間のものに差換えます。

Assets/Images/Background/GameBackground.png

f:id:hiro128:20160809165109p:plain

f:id:hiro128:20160809165116p:plain

次に、CocosSharpGameSample.Core プロジェクト、CrossCuttingConcerns/GameSettings.cs の画面サイズ設定を縦画面対応に変更します。

// 画面のサイズ
public const float ScreenWidth = 720f;
public const float ScreenHeight = 1280f;

以上をまとめると、CocosSharpGameSample.Core プロジェクト、CrossCuttingConcerns/GameSettings.cs は以下の通りになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CocosSharpGameSample.Core
{
	public class GameSettings
	{
		// 自機のサイズ
		public const float PlayerWidth = 32f;
		public const float PlayerHeight = 32f;

		// 画面のサイズ
		public const float ScreenWidth = 720f;
		public const float ScreenHeight = 1280f;

		// 加速度センサーの取得値の増幅倍率
		public const float AccelerationRatio = 3f;
	}
}

次に、CocosSharpGameSample.Core プロジェクト、Layers/GameLayer.cs からセンサーに関わる部分を削除します。

以下を削除します。

private CCLabel accelerationX;
private CCLabel accelerationY;
private CCLabel accelerationZ;

AddedToScene からセンサーに関わる部分を削除します。

protected override void AddedToScene()
{
	base.AddedToScene();
	// ゲーム画面の背景画像を配置
	var gameBackground = new CCSprite("/Resources/Images/Background/GameBackground.png", null);
	gameBackground.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
	AddChild(gameBackground);

	// ここから削除
	// モーションセンサーの値を表示するラベル
	this.accelerationX = new CCLabel(String.Empty, String.Empty, 40f, CCLabelFormat.SystemFont);
	this.accelerationX.HorizontalAlignment = CCTextAlignment.Left;
	this.accelerationX.VerticalAlignment = CCVerticalTextAlignment.Top;
	this.accelerationX.Color = CCColor3B.White;
	this.accelerationX.PositionX = 250f;
	this.accelerationX.PositionY = 120f;
	AddChild(this.accelerationX);

	this.accelerationY = new CCLabel(String.Empty, String.Empty, 40f, CCLabelFormat.SystemFont);
	this.accelerationY.HorizontalAlignment = CCTextAlignment.Left;
	this.accelerationY.VerticalAlignment = CCVerticalTextAlignment.Top;
	this.accelerationY.Color = CCColor3B.White;
	this.accelerationY.PositionX = 250f;
	this.accelerationY.PositionY = 80f;
	AddChild(this.accelerationY);

	this.accelerationZ = new CCLabel(String.Empty, String.Empty, 40f, CCLabelFormat.SystemFont);
	this.accelerationZ.HorizontalAlignment = CCTextAlignment.Left;
	this.accelerationZ.VerticalAlignment = CCVerticalTextAlignment.Top;
	this.accelerationZ.Color = CCColor3B.White;
	this.accelerationZ.PositionX = 250f;
	this.accelerationZ.PositionY = 40f;
	AddChild(this.accelerationZ);
	// ここまで削除

	// 自機を配置
	this.AddPlayer();

	this.StartScheduling();
}

StartScheduling からセンサーに関わる部分を削除します。

private void StartScheduling()
{
	// ここから削除
	this.Schedule(t => this.UpdateAccelerationLabels(), 0.2f);
	// ここまで削除
	this.Schedule(t => this.UpdatePlayer(), 0.02f);
}

UpdateAccelerationLabels を削除します。

// ここから削除
private void UpdateAccelerationLabels()
{
	this.accelerationX.Text = "X : " + (AccelerometerInfo.Default.AccelerationX >= 0 ? "+" : String.Empty) + AccelerometerInfo.Default.AccelerationX.ToString("0.00000000");
	this.accelerationY.Text = "Y : " + (AccelerometerInfo.Default.AccelerationY >= 0 ? "+" : String.Empty) + AccelerometerInfo.Default.AccelerationY.ToString("0.00000000");
	this.accelerationZ.Text = "Z : " + (AccelerometerInfo.Default.AccelerationZ >= 0 ? "+" : String.Empty) + AccelerometerInfo.Default.AccelerationZ.ToString("0.00000000");
}
// ここまで削除

UpdatePlayer からセンサーに関わる部分を削除します。

private void UpdatePlayer()
{
	// ここから削除
	float accelerationX = (float)AccelerometerInfo.Default.AccelerationX * GameSettings.AccelerationRatio;
	float accelerationY = -(float)AccelerometerInfo.Default.AccelerationY * GameSettings.AccelerationRatio;
	// ここまで削除

	// ここから変更
	this.player.PositionX = this.player.PositionX;
	this.player.PositionY = this.player.PositionY;
	// ここまで変更

	// 画面からはみ出ないように、位置の値の上限、下限を設定します。
	// 左
	if (this.player.PositionX < 0 + GameSettings.PlayerWidth)
	{
		this.player.PositionX = 0 + GameSettings.PlayerWidth;
	}
	// 右
	if (this.player.PositionX > GameSettings.ScreenWidth - GameSettings.PlayerWidth)
	{
		this.player.PositionX = GameSettings.ScreenWidth - GameSettings.PlayerWidth;
	}
	// 下
	if (this.player.PositionY < 0 + GameSettings.PlayerHeight)
	{
		this.player.PositionY = 0 + GameSettings.PlayerHeight;
	}
	// 上
	if (this.player.PositionY > GameSettings.ScreenHeight - GameSettings.PlayerHeight)
	{
		this.player.PositionY = GameSettings.ScreenHeight - GameSettings.PlayerHeight;
	}
}

以上をまとめると、CocosSharpGameSample.Core プロジェクト、CrossCuttingConcerns/GameLayer.cs は以下の通りになります。

using System;
using System.Diagnostics;
using CocosSharp;

namespace CocosSharpGameSample.Core
{
	public class GameLayer : LayerBase
	{

		private CCNode player;

		public GameLayer()
			: base()
		{
		}

		protected override void AddedToScene()
		{
			base.AddedToScene();
			// ゲーム画面の背景画像を配置
			var gameBackground = new CCSprite("/Resources/Images/Background/GameBackground.png", null);
			gameBackground.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
			AddChild(gameBackground);

			// 自機を配置
			this.AddPlayer();

			this.StartScheduling();
		}

		private void StartScheduling()
		{
			this.Schedule(t => this.UpdatePlayer(), 0.02f);
		}

		private void AddPlayer()
		{
			this.player = new CCSprite("/Resources/Images/Character/Player/Player.png", null);
			this.player.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
			this.AddChild(this.player);
		}

		private void UpdatePlayer()
		{
			this.player.PositionX = this.player.PositionX;
			this.player.PositionY = this.player.PositionY;

			// 画面からはみ出ないように、位置の値の上限、下限を設定します。
			// 左
			if (this.player.PositionX < 0 + GameSettings.PlayerWidth)
			{
				this.player.PositionX = 0 + GameSettings.PlayerWidth;
			}
			// 右
			if (this.player.PositionX > GameSettings.ScreenWidth - GameSettings.PlayerWidth)
			{
				this.player.PositionX = GameSettings.ScreenWidth - GameSettings.PlayerWidth;
			}
			// 下
			if (this.player.PositionY < 0 + GameSettings.PlayerHeight)
			{
				this.player.PositionY = 0 + GameSettings.PlayerHeight;
			}
			// 上
			if (this.player.PositionY > GameSettings.ScreenHeight - GameSettings.PlayerHeight)
			{
				this.player.PositionY = GameSettings.ScreenHeight - GameSettings.PlayerHeight;
			}
		}

	}
}

次に、CocosSharpGameSample.Core プロジェクト、Layers/TitleLayer.cs のタイトル背景画像を差換えます。

protected override void AddedToScene()
{
	base.AddedToScene();
	// タイトル画像を配置
	var title = new CCSprite("/Resources/Images/Background/GameBackground.png", null);// 画像を GameBackground.png に差換えます。
	title.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
	this.AddChild(title);

	// スタートボタンを配置
	var startButton = new CCSprite("/Resources/Images/Button/ButtonStart.png", null);
	startButton.Position = new CCPoint(this.ContentSize.Center.X, 100f);

	// 後から参照できるようにタグを設定
	startButton.Tag = (int)NodeTag.StartButton;
	this.AddChild(startButton);

	// ボタンタップ検出用のイベントリスナー作成
	var eventListener = new CCEventListenerTouchOneByOne();
	eventListener.OnTouchBegan = this.EventListener_TouchBegan;
	eventListener.OnTouchEnded = this.EventListener_TouchEnded;
	this.AddEventListener(eventListener, this);
}

以上をまとめると、CocosSharpGameSample.Core プロジェクト、CrossCuttingConcerns/TitleLayer.cs は以下の通りになります。

using CocosSharp;

namespace CocosSharpGameSample.Core
{
	public class TitleLayer : LayerBase
	{

		public TitleLayer()
			: base()
		{
		}

		protected override void AddedToScene()
		{
			base.AddedToScene();
			// タイトル画像を配置
			var title = new CCSprite("/Resources/Images/Background/GameBackground.png", null);
			title.Position = new CCPoint(this.ContentSize.Center.X, this.ContentSize.Center.Y);
			this.AddChild(title);

			// スタートボタンを配置
			var startButton = new CCSprite("/Resources/Images/Button/ButtonStart.png", null);
			startButton.Position = new CCPoint(this.ContentSize.Center.X, 100f);

			// 後から参照できるようにタグを設定
			startButton.Tag = (int)NodeTag.StartButton;
			this.AddChild(startButton);

			// ボタンタップ検出用のイベントリスナー作成
			var eventListener = new CCEventListenerTouchOneByOne();
			eventListener.OnTouchBegan = this.EventListener_TouchBegan;
			eventListener.OnTouchEnded = this.EventListener_TouchEnded;
			this.AddEventListener(eventListener, this);
		}

		private bool EventListener_TouchBegan(CCTouch touch, CCEvent e)
		{
			// OnTouchBegan で true を返却しないと、OnTouchEndedが発動しない。
			return true;
		}

		private void EventListener_TouchEnded(CCTouch touch, CCEvent e)
		{
			// タッチした座標でボタンが押されたかを判定
			CCNode startButton = this.GetChildByTag((int)NodeTag.StartButton);
			if (startButton.BoundingBox.ContainsPoint(touch.Location))
			{
				// 移動先のシーンを作成
				var newScene = new CCScene(this.Window);
				var gameLayer = new GameLayer();
				newScene.AddChild(gameLayer);

				// シーン切り替え時の効果を設定
				CCTransitionScene cCTransitionScene = new CCTransitionFade(1.0f, newScene);

				// ゲーム画面へシーン切り替え
				this.Director.ReplaceScene(cCTransitionScene);
			}
		}

	}
}

これで、縦画面のゲーム作成の準備が整いました。

今回は、ここまでです。

Xamarin iOS + Azure Storage の利用方法(1) ストレージ アカウントの作成

モバイルアプリのバックエンドにAzureを使用し、画像データなどを管理したい場合は、Azure Storageを利用できます。

まず、Azureにストレージ アカウントを作成します。

新規 → データ + ストレージ → ストレージ アカウントをクリック

f:id:hiro128:20160728103639p:plain

アカウントの情報を入力し、「作成」をクリックします。

f:id:hiro128:20160728103816p:plain

作成が完了するのを待ちます。

次に、BLOBのコンテナーを作成します。

サービスの「BLOB」をクリックし、「+コンテナー」をクリックします。

f:id:hiro128:20160728104053p:plain

コンテナーの名前とアクセスの種類を入力します。
アクセスの種類は「BLOB」にします。

f:id:hiro128:20160728104215p:plain

「作成」をクリックします。

コンテナーが作成されました。

f:id:hiro128:20160728104251p:plain

今回はここまでです。

Xamarin iOS + Azure Mobile Apps の利用方法 (6) カスタム API に検索条件を付加してみる (Easy API)

第4回でViewの代わりにEasy APIでカスタムクエリの結果セットを取得しましたが、今回はさらに検索条件を設定できるようにします。

まずは Azure ポータルにログインします。

すべてのリソース → あなたが作成したWebApp → すべての設定 → Easy API をクリック。

作成された API、ExtendedTestItem をクリックし、
Edit Script をクリックします。

Visual Studio Online で、当該 API の Node.js 編集画面が開きますので、
スクリプトを修正します。

request.query.[GETのパラメータ名]でクエリ文字列を取得できます。

f:id:hiro128:20160727194622p:plain

Postmanで動作確認します。

f:id:hiro128:20160727194807p:plain

無事データが取得できました。

複数のパラメータの場合でも、javascriptで加工して条件設定すれば任意の結果セットを取得可能です。

今回は以上です。

Xamarin iOS + Azure Mobile Apps の利用方法 (5) Dynamic Schema をオフにする (Easy Tables)

実は、Azure の Easy Tables にはかな~り余計なお世話な機能がついています。

その名も Dynamic Schema という機能です。

これは、エンティティに設定されたプロパティがテーブル内に存在しないとき、自動的にテーブルにカラムを追加する機能です。

この機能、誰得なんでしょうか??

というわけで、Dynamic Schema をグローバルでオフにする方法です。

Azure ポータルにログインし、

あなたの作成したWebApp → 全ての設定 → アプリケーション設定をクリック

f:id:hiro128:20160627211531p:plain

アプリ設定のセクションに、キー:MS_DynamicSchema, 値:false を設定し、保存ボタンをクリックします。

f:id:hiro128:20160627211736p:plain

再起動ボタンをクリックし、アプリケーションを再起動します。

以上です。