個人的なメモ

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

Xamarin + Cocos Sharp で iOS, Android 対応のゲームを開発する手順 (12) 敵キャラを移動させ、画面外に出たら消去する。

今回は画面をタッチして出した敵キャラを移動させ、画面外に出たら消去します。

具体的には、画面タッチで出現させた敵キャラは、横移動はなしで画面の下に移動し、画面外に消えていく動きを作成します。

キャラを移動する場合は、CCMoveTo で移動のアクションを作成し、Node の RunAction メソッドで動作開始となります。
※CCMoveTo はNodeの移動のアクションをカプセル化したオブジェクトです。

まずは、CCMoveTo に移動に必要な時間と移動後の目的地の座標を与えてインスタンスを作成します。

移動後の目的地の座標ですが Cocos Sharp の座標は左下が原点で(0, 0)なので、まっすぐに画面の下に移動したい場合、目的地の座標は、(敵キャラの現在のX座標, -100)のようになります。

次にそのアクションを Node の RunAction で動作開始させます。

// Y軸のみの移動で画面外まで行くアクションを適用
public void ApplyGoStraightFromTopDownAction(CCNode enemy)
{
	var destinationPoint = new CCPoint(enemy.PositionX, -100);
	var action = new CCMoveTo(8.0f, destinationPoint);
	enemy.RunAction(action);
}

配置した敵キャラに上記のアクションを適用します。

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.ApplyGoStraightFromTopDownAction(addingEnemy);

		this.AddChild(addingEnemy);
		return true;
	}
	return false;
}

このままだと、画面外に移動してしまった敵キャラがどんどん溜まっていってしまうので、画面外に出た敵キャラは定期的に消去します。

画面外かどうかはY座標の値で判定します。

// 画面外のNodeを除去
public void RemoveOffScreenNodes()
{
	foreach (var node in this.Children)
	{
		if (node.Position.Y < 0)
		{
			this.RemoveChild(node);
		}
	}
}

消去処理を定期的に実行します。

private void StartScheduling()
{
	this.Schedule(t => this.UpdatePlayer(), 0.02f);
	this.Schedule(t => this.RemoveOffScreenNodes(), 1.0f);// 定期的に消去
}

以上をまとめると、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)
		{
			Debug.WriteLine(this.ChildrenCount);
			// タッチした場所に敵キャラ配置
			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.ApplyGoStraightFromTopDownAction(addingEnemy);
				this.AddChild(addingEnemy);
				return true;
			}
			return false;
		}

		// Y軸のみの移動で画面外まで行くアクションを適用
		public void ApplyGoStraightFromTopDownAction(CCNode enemy)
		{
			CCPoint destinationPoint = new CCPoint(enemy.PositionX, -100);
			CCMoveTo action = new CCMoveTo(8.0f, destinationPoint);
			enemy.RunAction(action);
		}

		// 画面外のNodeを除去
		public void RemoveOffScreenNodes()
		{
			foreach (var node in this.Children)
			{
				if (node.Position.Y < 0)
				{
					this.RemoveChild(node);
				}
			}
		}

		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);
			this.Schedule(t => this.RemoveOffScreenNodes(), 1.0f);
		}

		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:20160827170933g:plain

今回は、ここまでです。

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