technical

【Blender】メッシュにボーン(Armature)を入れてポーズ変更できるようにする

お仕事関連のメモがてら、3Dソフトのtipsをお送りいたします。その2
続きを読む…

  • Category: technical / Blender
  • Posted: 2015/9/11 12:00
  • Author: ユーリ
technical

【Blender】Sculptrisで作成したモデルをBlenderへインポートする

お仕事関連のメモがてら、3Dソフトのtipsをお送りいたします。
続きを読む…

  • Category: technical / Blender
  • Posted: 2015/9/4 12:00
  • Author: ユーリ
technical

【SVG】raphael.jsを使ったらすんごい色々捗った

こんにちは、ユーリです!
少し前、SVGでアニメーションを行う記事を書きましたが、
その後の開発でブラウザ間の挙動の違いや、古いブラウザでうまく動かなかったりと色々と苦労いたしました。

うおー、やはり一定数の古い環境は切り捨てるしかないのかッ…!対応コードを書けば書くほど煩雑になってゆく!

そこに現れた救世主!!
SVG制御用ライブラリ… Raphael.js っ!!  ↓さんぷる

自前のコードだけでの対応に限界を感じ、ライブラリを使用してめんどくさいところは全部吸収してもらうことにしました。
まさにうってつけのライブラリが見つかりました!
それがraphael.jsでございます。


raphael.jsのココがスゴイ!


■IEやsafqriの古いバージョンでも動作
特に何も意識せずとも、raphael.jsからの処理を使ってSVGを操作すれば、古いブラウザでもしっかり表示され、animateも問題なく動作してくれます!
svg要素を直接うごかしていたら、animateが動作しなかったり、変な位置に表示されたりしてしまい、たいへん苦労いたしました。
■jQueryライクな記述で、直感的に要素や値を操作できる
jQueryのような値の指定やメソッドチェーンが利用できます。
jQueryに慣れている方であればすんなり飲み込めるのではないでしょうか。
■基本的なeventをサポート
マウスオーバーやクリックのような処理も、svgの要素単位で実装ができます。
svg要素はマウス判定の範囲に複雑な形状を利用できるため、リッチな動作を実現できます。

サンプルコード


SVG要素を作成し、図形を描画する

SVG要素の大きさを指定する方法はいろいろありますが、いろいろ試した結果、
divなどのブロック要素で任意の大きさを指定し、その中にsvgをwidth:100%、height:100%で配置するのがいちばん安定しました。
この方法の場合、あとからdiv要素の大きさが変わっても、中身のSVG要素もあわせて伸び縮みしてくれます。
viewboxでサイズ指定するとさらに堅牢です。
PCで閲覧している方は、このページを表示しているウィンドウ自体のサイズを変えてみていただけると伸び縮みに対応していることを確認できるハズです。
<!--svg配置用のdiv要素--> <script> $(function(){ var paper = Raphael("svg_wrap","100%","100%"); //Raphael()でSVG要素を生成する //引数1:生成する対象要素のid 引数2:width 引数3:height paper.setViewBox(0,0,600,200,true); //viewBoxの大きさを指定 paper.add([ //図形を追加する { type : "rect" , //四角形を追加 x : 10 , //X座標 y : 70 , //Y座標 width : 240 , //width height : 120 , //height fill : "#6E6" , //fill = 塗りつぶしの色 stroke : "#C33" , //stroke = 線の色 "stroke-width": 5, //線の太さ }, { type : "circle" ,//円を追加 cx : 280 , //X座標(circle) cy : 40 , //Y座標(circle) r : 80 , //半径 fill : "#AAF" , //fill = 塗りつぶしの色 stroke : "#66E" , //stroke = 線の色 "stroke-width": 5, //線の太さ } ]); var tri = paper.path("M350,10 L350,170 L 530,90 Z"); //パスを追加する(三角形) tri.attr({ //パス(三角形)のプロパティを変更 fill : "#C77" , stroke : "#F33" , opacity : 0.80 , //透明度 "stroke-width" : 10, //線の太さ }); }); </script>

上記のコードで、このように表示されます。

クリックやマウスオーバーなど、イベントの処理を書く

SVGを表示できたらぐにぐに動かしたいですよね!
先ほどようにSVGを生成してから、その要素に対してclick、mouseover、mouseoutの処理を定義してみます。
SVG要素が複雑な形をしていても、その形の通りに当たり判定が適応されます。
	var paper = Raphael("svg_wrap","100%","100%");
	paper.setViewBox(0,0,600,200,true);	//viewBoxの大きさを指定
	var path = paper.path("M548,95v8H349C347,130,326,150,300,150c-19,0-36-11-45-28c-8,16-25,28-45,28s-36-11-45-28c-8,16-25,28-45,28c-26,0-47-20-49.8-45H50v-8h20C72,70,93,50,120,50c19,0,36,11,45,28c8-16,25-28,45-28s36,11,45,28c8-16,25-28,45-28c26,0,47,20,49,45H548z"); //パスを追加する
	path.attr({	//パスのプロパティを変更
		fill	: "#AAA" ,
		stroke	: "#666" ,
		"stroke-width" : 3, //線の太さ
	});
	path.click(function(){	//クリック時の処理
		var r = Math.floor(Math.random () * 256);	//赤ランダム
		var g = Math.floor(Math.random () * 256);	//緑ランダム
		var b = Math.floor(Math.random () * 256);	//青ランダム
		var color = "rgb("+r+","+g+","+b+")";		//ランダム色生成
		path.attr({	//パスのプロパティを変更
			fill  : color,	//塗りつぶしの色を変える
		});
	});
	path.mouseover(function(){	//マウスオーバー時の処理
		path.attr({	//パスのプロパティを変更
			"stroke-width"  : 8,	//線の太さを変える
			opacity			: 0.8	//透明度を変える
		});
	});
	path.mouseout(function(){	//マウスアウト時の処理
		path.attr({	//パスのプロパティを変更
			"stroke-width"  : 3,	//線の太さを戻す
			opacity			: 1.0	//透明度を戻す
		});
	});
上記のコードで、このように表示されます。マウスイベントに対応しています!

アニメーションを行う

前回のSVGの記事で苦労してアニメーション処理を書きましたが、raphael.jsにかかれば、非常に簡単にアニメーション処理ができてしまいます;;
記述方法はjQueryのanimateとほぼ同じで、アニメーションさせるプロパティにsvg要素の色や座標を指定すればOKです。
	path.mouseover(function(){	//マウスオーバー時の処理
		path.animate({path:"M548,95v8H349c-54,7-23,2-49,2c-19.8,0-18,2-45,2c-25,2-25-1-45-1s-19,3-45-1c-27,5-25-1-45-1c-26,0-13,5-49-0.6H50v-8h20c31-2,23-1,49-1c19,0,17-11,45-0.8c25-3,25-3,45-3s22-3,45,3c29-4,25-1.2,45-1c26,0,27-0.7,49,3H548z"},250);	//パスの形を変更
	});
	path.mouseout(function(){	//マウスアウト時の処理
		path.animate({path:"M548,95v8H349C347,130,326,150,300,150c-19,0-36-11-45-28c-8,16-25,28-45,28s-36-11-45-28c-8,16-25,28-45,28c-26,0-47-20-49-45H50v-8h20C72,70,93,50,120,50c19,0,36,11,45,28c8-16,25-28,45-28s36,11,45,28c8-16,25-28,45-28c26,0,47,20,49,45H548z"},100);	//パスの形を戻す
	});
マウスオーバーでアニメーションします!
この前の苦労はなんだったのか…。

集合要素に対して処理を行う

要素をたくさん並べて処理をしたい場合、setという配列のようなクラスを使用して、forEachでそれぞれの要素に対してまとめて処理を行うことができます。
	var paper = Raphael("svg_wrap","100%","100%");
	paper.setViewBox(0,0,600,200,true);	//viewBoxの大きさを指定
	var rectarray = paper.set();		//svg要素の集合を格納する"set"を作成
	for( var i = 0, j = 20; i < j ; i++ ){	//20回繰り返す
		rectarray.push(						//setに対してsvg要素を追加する
			paper.rect(i*(j+10),100,20,80)	//paperの中に四角形を作成(x,y,w,h)
		);
	}
	rectarray.forEach(function(e,i){		//setの中身の要素それぞれに対して処理(element,index)
		e.attr({	//プロパティを変更
			fill	: "#8CC" ,	//塗りつぶしの色
		});
		e.mouseover(function(){	//マウスオーバー時の処理
			if( e.attr("y") == 0 ){	//yの値が0の場合
				e.animate({y:100,fill:"#88C"},200,"<>");	//下に移動するアニメーション
			}else{					//yの値が0でない場合
				e.animate({y:0,fill:"#C88"},200,"<>");	//上に移動するアニメーション
			}
		});
	});
マウスオーバーでアニメーションします!
やっぱりSVGはなめらかでたのしい!
これくらい手軽に扱えれば、どんどん夢が広がっていきます!

  • Category: technical / svg
  • Posted: 2015/4/16 19:00
  • Author: ユーリ
technical

【備忘録】SVGのpathをJavaScriptでぬるぬる動かしたかった

ぬるんぬるん!ぐねんぐねん!

こちらは、最近流行りのSVG!gif画像ではありません。
クリックして色を変えるなどの処理がリアルタイムで行えます。
IEやsafariなど一部のブラウザではうまく動作しないかもしれません。ゴメンナサイ。
これをjavascriptで制御しようとしたところ、いろいろ大変だった話。

※この記事は、SVGが動作する環境の方へ向けて書いています。動かない方はゴメンナサイ。

SVGは、ドットの集まりではなく、パス(点と線)の集まりである為、解像度は無限大です!
また、パスの値は数値で書かれていて、ページが表示されてからでも、パスの値を調節すれば、見た目をぐにぐに変えちゃったりもできます!
ただし、現時点ではブラウザによって対応していない環境があったり、大きさの指定がややこしかったりと、いろいろ課題もございます。

今回は、どうしてもSVGをぬるぬる動かしたい!という案件がございまして、工数はかかりましたが、なんとか要件を満たすことができました。
拙いやり方でしたが、とりあえず備忘録として書いておきます。

今回は、こちらのSVGを例にご説明いたします。
このSVGのソースはこちらになります。
	<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 180 180" enable-background="new 0 0 180 180" xml:space="preserve">
		<path fill="#88BB33" d="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z" >
		</path>
	</svg>
	
これを別のhtmlページにコピペすると、上に表示されている緑色の円がそっくりそのまま表示されるはずです。
とてもシンプルな構造ですよね!

このソースの中には、図形を表すための図形の頂点の位置図形の線の太さや塗りつぶしの色、などが書かれています。
20150313_1
ブラウザはこれを読んで描画を行うわけです。
例えば、この例の場合、円の形(点と線の集まり)を表しているのはこの部分です。↓
d=”M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z”
そして、この中に書かれている点の位置を書きかえてしまえば、その場で表示を変えることができる、という寸法です。

ここまで前置き。詳しい説明に移ります。



SVG要素を動的に変更したい場合は、animateタグを使用する、もしくはJavaScriptで直接値を打ち込む、などの方法がございます。
まずは、animateタグについて。
animateタグの中身には、変更したい要素名と、動作スピード動作条件などを記載します。
		<animate attributeName="fill" 
					values="#88BB33;#CC6699"
					dur="2.0s"
					repeatCount="indefinite" >
	
上記の例では、
[attributeName]…「fill」という要素、この場合fillなので塗りつぶしの色を、
[values]…「#88BB33;#CC6699」すなわち#88BB33から#CC6699に、
[dur]…「2.0s」2秒間かけて変化させる。という命令が書いてあります。
また、繰り返し回数[repeatCount]…「indefinite」で、アニメーションを無限に繰り返すという指定をしました。

このタグをどこに書くかというと、アニメーションさせたいSVG要素の内側に書きます。
こんな感じ。
	<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 180 180" enable-background="new 0 0 180 180" xml:space="preserve">
		<path fill="#88BB33" d="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z" >
			<animate attributeName="fill" 
					values="#88BB33;#CC6699"
					dur="2.0s"
					repeatCount="indefinite" >
		</path>
	</svg>
	

これを実際に実行したものがこちら。
色が緑から赤にだんだんと変わっています。
延々と変わっています。

これくらいなら簡単な変化でありますが、このanimateタグは、pathの形状の変化にも使えてしまうのです。

そのためには、pathについて「動作前の状態」「動作後の状態」を用意する必要があるわけです。
ということでAdobe Illustratorにてパス形状を編集する画面を例にいたします。
(SVGを書き出せるソフトウェアでしたら、他のものでも構いません。)
こちらが、動作前の状態とします。
20150313_2
次が、動作後の状態とします。
20150313_3
それぞれ、別名で保存からsvgとして保存します。
20150313_4
そして、保存したSVGファイルをテキストエディタで開きます。
図形の形状を表すpathの中の“d”の値がそれぞれ違うことが確認できます。
20150313_5
動作前の”d”:
M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z

動作後の”d”:
M154,89c0,27-52,49-79,49s-49-22-49-49S47,40,75,40.6S154,62,154,89z

この”d”の中身の値を抽出して、animateタグに打ち込めば良いわけです!
animateタグの[attributeName]の中身を、図形の形状を表す“d”に変更し、
実際に変化する値である、[values]の中身に動作前、動作後のパス形状を”;”セミコロンで区切って入力。
こんなタグになりました。
	<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 180 180" enable-background="new 0 0 180 180" xml:space="preserve">
		<path fill="#88BB33" d="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z" >
			<animate attributeName="d" 
					values="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z;
							M154,89c0,27-52,49-79,49s-49-22-49-49S47,40,75,40.6S154,62,154,89z"
					dur="1.2s"
					repeatCount="indefinite" >
		</path>
	</svg>
	
動作させてみます。
ぬるっと動きました!
しかし、このままでは延々とアニメーションしてしまいます。
そこで、アニメーションの動作を制御するbegin要素を追加します。
begin=”indefinite”とすることで、animateの動作タイミングをJavaScriptで制御できます。
さらに繰り返し回数[repeatCount]…「1」と設定することで、動作回数を1度だけとします。
そしてこのanimateタグにidを付与します。
また、この後の動作のためにpathのタグにもidを付与しておきます。
	<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 180 180" enable-background="new 0 0 180 180" xml:space="preserve">
		<path id="circle_path" 
			fill="#88BB33" d="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z" >
			<animate attributeName="d" 
					values="M124,89c0,27-22,49-49,49s-49-22-49-49S47,40,75,40.6S124,62,124,89z;M154,89c0,27-52,49-79,49s-49-22-49-49S47,40,75,40.6S154,62,154,89z"
					dur="1.2s"
					repeatCount="1" 
					begin="indefinite" 
					id="circle_animate" >
		</path>
	</svg>
	
そして、JavaScriptからidをもとにanimateタグをゲットし、
beginElement();を呼ぶことで、アニメーションを動作させることができます!
		//アニメを動作させる
		var animate = document.getElementById('circle_animate');
		animate.beginElement();
	
ボタンクリックで、beginElement();を呼ぶようにしてみました。
クリック!

クリックでアニメを動かすことに成功!ひとつ前に進んだ!

ただし、このままではアニメーションしても元に戻ってしまいます。
何故かというと、表示されているSVGの形状は、pathの場合”d”の中身で決まっていて、
アニメーションした後はその値による表示に戻ってしまうためです。
そこで今度は、アニメーションしたあとにpath要素自体の”d”の値をJavaScriptで書き換えてしまうようにします。
		//アニメを動作させる
		var animate = document.getElementById('circle_animate');
		animate.beginElement();
		//pathそのものの形状を変化させる
		var path = document.getElementById('circle_path');
		path.setAttribute('d','M154,89c0,27-52,49-79,49s-49-22-49-49S47,40,75,40.6S154,62,154,89z');
	
むくり!

アニメ後も、要素の形状がそのままになりました!

ここで、疑問が生まれます。 動作前と後で、どんなパスを入れてもちゃんとアニメーションしてくれるのか?という問題です。
ためしに、単純なパスと複雑なパスをanimateタグで繋げてみます。
20150313_6
20150313_7
	<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 180 180" enable-background="new 0 0 180 180" xml:space="preserve">
		<path fill="#88BB33" d="M150.8,93l-58,62.2L29.2,95.8C44,79,69.1,51.3,87.2,33.6L150.8,93z" >
			<animate attributeName="d" 
				values="M150.8,93l-58,62.2L29.2,95.8C44,79,69.1,51.3,87.2,33.6L150.8,93z;
						M112.9,90.5l16.5,32.3l-35.7-6.5L68.2,142l-4.9-36L30.9,89.6c13.9-5.7,19.4-9.5,32.7-15.7L69.2,38l25.1,26.3l35.8-5.8L112.9,90.5z"
                dur="1.2s"
                repeatCount="indefinite"" >
		</path>
	</svg>
	
あれ。ぬるぬるしない。
調査の結果、どうやら動作前と後で、「パスを表す構成」が同じでなければうまく動いてくれないようです。
具体的には、点の数が変わったり、座標の指定方法が変わったりすると、ダメみたいです。
たとえば頂点が4つしか無い四角形から、頂点が5つある五角形に変形、ということはできないようです。
ただし、「頂点が5つだけど最初だけ四角形に見えるパス」などを用意すれば、その限りではありません。
20150313_8

さて、脱線しましたが、animateタグは「動作前」と「動作後」だけでなく、一つのタグでいくつも動作をつなげることができます。
変化させたいパスを“;”セミコロンでどんどん繋げていけば、こんな動きもできちゃうわけです!
↑クリックすると色が変わります(笑)
<animate dur="2.4s" attributeName="d" 
values="M152.7,128.7c0,27.2-22.1,49.4-49.3,49.4S54,155.9,54,128.7s22.1-49.3,49.3-49.3S152.7,101.4,152.7,128.7z;
M152.7,128.7c0,27.2-22.1,49.4-49.3,49.4S54,155.9,54,128.7s22.1-49.3,49.3-49.3S152.7,101.4,152.7,128.7z;
M152.7,128.7c0,27.2-22.1,49.4-49.3,49.4S54,155.9,54,128.7s72.1-49.3,99.3-49.3S152.7,101.4,152.7,128.7z;
M202.7,128.7c0,27.2-72.1,49.4-99.3,49.4s0.7-22.2,0.7-49.4s72.1-49.3,99.3-49.3S202.7,101.4,202.7,128.7z;
M222.7,158.7c0,27.2-52.1,19.4-79.3,19.4s-19.3-52.2-19.3-79.4s52.1-19.3,79.3-19.3S222.7,131.4,222.7,158.7z;
M316.7,65c0,27.2-132.1,109.4-159.3,109.4s10.7-62.2,10.7-89.4s82.1-59.3,109.3-59.3S316.7,37.7,316.7,65z;
M392.7,85c0,27.2-132.1,29.4-159.3,29.4s32.7-36.2,32.7-63.4s50.1-25.3,77.3-25.3S392.7,57.7,392.7,85z;
M447.7,84c0,27.2-94.1,13.4-121.3,13.4s-27.2-15.3-15.3-57.4s50.1-25.3,77.3-25.3S447.7,57.3,447.7,84.6z;
M498.7,78.6c0,27.2-24.1,63.4-51.3,63.4s-27.2-30.2-65.3-57.4s0.1-45.3,27.3-45.3 S498.7,51.3,498.7,78.6z;
M534.7,96.9c0,27.2-4.1,78.4-31.3,78.4s-27.2-32.2-67.3-59.4s-5.9-53.3,21.3-53.3 S534.7,69.7,534.7,96.9z;
M558.7,130.6c0,27.2-25.1,47.4-52.3,47.4s-55.3-15.2-55.3-42.4s4.1-47.3,31.3-47.3 S558.7,103.3,558.7,130.6z;
M559.7,130.6c0,27.2-25.1,47.4-52.3,47.4s-52.3-20.2-52.3-47.4s24.1-49.3,51.3-49.3 S559.7,103.3,559.7,130.6z;
M152.7,128.7c0,27.2-22.1,49.4-49.3,49.4S54,155.9,54,128.7s22.1-49.3,49.3-49.3S152.7,101.4,152.7,128.7z"
repeatCount="indefinite" >
	
さらに、複雑な動作をさせたい方には、keyTime、keySplinesという、アニメーションのスピードを細かく設定できる要素もあります!
今回は少々手間のかかる方法でしたが、もっと簡単に動かせる仕組みが一般化していくとよいですね!

  • Category: technical / svg
  • Posted: 2015/3/18 17:10
  • Author: ユーリ
technical

cocos2d-xの環境構築をしたら次は何をすればよいのか

こんにちは、ユーリです!
最近、次のスマホゲームを作成するべく、cocos2d-xでの開発をはじめました!

※cocos2d-xとは、iphoneとAndroid、両方のプラットフォームで2dゲーム開発ができるフレームワークです。
この記事は、ある程度プログラムへの知識がある方へ向けて書いています。


環境構築については、うまくまとめていらっしゃるサイト様がたくさんありますので、この場では省きます!
ですが、環境構築をして、テストプロジェクトを作り、サンプルの動作を確認、まで行ったら…次になにをしたらいいか、パッと見つからなかったため、私なりにまとめてみました。
※実行環境
mac OS X ver 10.9.5
cocos2d-x ver 3.3
Xcode ver 6.1.1


メインシーン用クラスを作る


ひとまずHelloWorldの次のステップとして、オリジナルの画面をつくることですね。
デフォで存在している「Classes」フォルダの中にオリジナルシーン用のクラスを作成します。
20150127_1
New File…でファイル作成。

20150127_2
C++ Fileを選びます。

20150127_3
クラス名を決めます。何でもいいんですが、MainSceneにしました。

20150127_4
決定すると、
MainScene.cpp と
MainScene.h の二つのファイルが作成されます。
ソースファイルはこのようにシーンごとに作成します。

Sceneの骨組みと、入力に反応するメソッドを作る


次に、シーンを制御するコンストラクタとデストラクタ、
そして入力に反応するイベントリスナーを実装します。
まずはヘッダファイルから。

//
//  MainScene.h
//  testproject
//
//  Created by yuri on 2015/01/26.
//
//

#ifndef __testproject__MainScene__
#define __testproject__MainScene__

#include "cocos2d.h"

class MainScene :public cocos2d::Layer
{
protected:
    MainScene();            //コンストラクタ
    virtual ~MainScene();   //デストラクタ
    bool init() override;   //初期化処理

public:
    static cocos2d:: Scene* createScene();
    CREATE_FUNC(MainScene);                 //createメソッドを作成
    CC_SYNTHESIZE_RETAIN(cocos2d::Sprite *, _cursor,Cursor);    //_cursor変数を作成し、ゲッターとセッターを実装する
};

#endif /* defined(__testproject__MainScene__) */

まずは必要最低限の実装です。
シーンクラスは、SceneではなくLayerを継承して作成します。 CREATE_FUNC(MainScene); はマクロで、create();関数の生成を行います。
CC_SYNTHESIZE_RETAIN(cocos2d::Sprite *, _cursor,Cursor); では、入力に反応して動くカーソル用のスプライトを生成します。

続いて、ソースファイルです。

//
//  MainScene.cpp
//  testproject
//
//  Created by yuri on 2015/01/26.
//
//

#include "MainScene.h"

USING_NS_CC;

MainScene::MainScene()
: _cursor(NULL) //コンスタラクタ内での初期化
{

}

MainScene::~MainScene()
{
    CC_SAFE_RELEASE_NULL(_cursor);  //オブジェクトをリリースする
}

Scene* MainScene::createScene()
{
    auto scene = Scene::create();
    auto layer = MainScene::create();
    scene -> addChild(layer);
    return scene;
}

bool MainScene::init()
{
    if(!Layer::init()){
        return false;
    }
    auto director = Director::getInstance();    //Directorを取り出す

    //初期化を行う
    this -> setCursor(Sprite::create("CloseSelected.png")); //指定画像をリソースにスプライトを生成
    _cursor -> setPosition(Vec2(100,100));                  //位置の定義
    this -> addChild(_cursor);                              //生成したスプライトをシーンに追加

    //タッチ操作の動作定義
    auto listner = EventListenerTouchOneByOne::create();    //一点タッチされたときのイベント定義
    listner -> onTouchBegan = [this](Touch* touch,Event* event){
        //タッチされたときの処理(この定義は必須である)
        auto touchPosition = touch -> getLocation(); //タッチした位置を取得
        _cursor -> setPosition(touchPosition);    //カーソルの座標にタッチ座標を格納
        log("タッチ位置 : %f , %f" , touchPosition.x , touchPosition.y );
        return true;
    };
    listner -> onTouchMoved = [this](Touch* touch,Event* event){
        //タッチしたあと移動した場合
        auto touchPosition = touch -> getLocation(); //タッチした位置を取得
        _cursor -> setPosition(touchPosition);    //カーソルの座標にタッチ座標を格納
    };
    director->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listner, this);  //作成したイベントを画面にひもづける

    return true;
}

カーソル用の画像は、今回はデフォルトでリソースに入っているボタン画像を使っちゃいました。
20150127_5
お好みのものを使いたい場合、Resourcesフォルダ内に画像を追加する必要があります。

今回は初期化用の関数 init()と、Directorというクラスがポイントになります。
init()内では、リソース内の画像ファイルからスプライトの生成、タッチした時の挙動をイベントリスナーに登録。という二つの動作を実装しています。
Directorはゲーム全体を管理するクラスで、画面サイズや端末情報を得る際に使用します。
今回はこのDirectorクラスを通じて、画面にイベントリスナーを追加しています。
その他の部分はだいたいおまじないです。

あとは、AppDelegate.cpp内のHelloWorldの部分をMainSceneに置き換えれば完成です。

#include "AppDelegate.h"
//#include "HelloWorldScene.h"
#include "MainScene.h"
    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

    // create a scene. it's an autorelease object
    //auto scene = HelloWorld::createScene();
    auto scene = MainScene::createScene();

背景は真っ暗ですが、タッチするとタッチした位置にカーソルがついてくる画面が完成しました!
20150127_6

今日はここまでに致します…。

  • Category: technical / cocos2d-x
  • Posted: 2015/1/27 13:00
  • Author: ユーリ