cocos2d 2.0for iPhone       勉強会    cocos2dを覚えよう!	           初級編③
動作環境•  Mac OS X 10.8 Mountain Lion•  xcode 4.5.2•  cocos2d for iPhone 2.0 http://www.cocos2d-iphone.org/
はじめに•  cocos2dを覚えよう!初級編③•  ボタンで移動してみよう!
もくじ•    cocos2dの基本•    Sceneの構成要素•    忍ベーダー•    仮想スティック•    忍者の移動
cocos2dの基本•  まずはcocos2dについておさらい!
cocos2dについて•    オープンソース+無料で商用利用可能•    2Dに特化•    物理エンジン搭載(box2d,chipmunk)•    効果音やBGMの再生も可能•    OpenGL利用で高速描画•    Objective...
デメリット•  iPhone標準のUIが使えない。 (がんばれば使えるかも?)
cocos2dの基礎知識•  スプライト(sprite):一般的には、キャラ   クターを表示する技術。•  スプライトエンジン:スプライトを簡単   に管理、表示できる仕組み
cocos2dの座標•  座標は左下が(0,0)•  スプライトの基準点は中心(変更可能)                                      (480,320)                              ...
cocos2dの基礎知識•  CCSprite  –  回転、拡大、縮小、傾斜、透過•  CCAnimation  –  ぱらぱら漫画のような、画像切り替え•  CCAction  –  キャラクターに任意の動きを設定可能  –  イベント処理...
cocos2dの基礎知識•  CCTMXTiledMap  –  タイルマップの表示•  CCParticleSystem  –  パーティクルの表示•  CCSpriteBatchNode  –  スプライトをまとめて管理•  SimpleA...
こまったときは?•  こまったときは、プログラミングガイド   を見よう! –  http://www.cocos2d-iphone.org/wiki/    doku.php/prog_guide:index
Sceneの構成要素•  Sceneの構成要素を覚えよう!
Sceneは複数作れる
Sceneの中にはLayerをおける
Layerの中にはいろいろおける      CCSprite、CCMenu、CCLabelBMFont、	        CCSpriteBatchNode	        などを置くことができる
LayerとSprite  •  Layer	        •  Sprite(手裏剣1)	        •  Sprite(手裏剣2)	        •  Sprite(手裏剣3)	        •  Sprite(忍者)	    レ...
LayerにSpriteBatchNodeを置ける         SpriteBatchNodeを置いても、画         面には表示されない。	           	           SpriteBatchNodeに、Sprite...
LayerとSpriteBatchNodeとSprite          •  Layer	                •  BatchNode	                    •  Sprite(手裏剣1)	          ...
TagとZ•  Layerや、スプライトなど、CCNodeには、   TagとZが定義されています。•  Tagを一意にすることで、getChildByTag   で親Nodeから取得が可能です。•  Zは重ね合わせの優先順位を表します。•  ...
忍ベーダー•  次々と現れる侵略者(忍ベーダー)をたおしていこう!•  忍ベーダーが、ライフラインを超えるとゲームオーバー
ルール•  タイトル画面でボタンを押すとゲーム開始•  READY→STARTのあと、ゲーム開始•  忍ベーダーは、上から攻めてくる。大きさによって硬さ   や得点が違う•  忍者は、ボタンで左右移動•  忍者が止まると上を向いて、手裏剣を自動...
4inch対応     •  今回は画面上部の見        える部分を変更する        ことで対応します	       •  スコアなどの文字は、        画面の高さをもとに        表示して、画面内に        収ま...
がめんこうせいタイトルscene   メインscene
タイトルscene•  フロントlayer  –  スコア•  タイトルlayer  –  タイトルロゴ  –  スタートボタン  –  床•  背景layer  –  背景画像
メインscene•  フロントlayer  –  スコア•  スティックlayer  –  左右のボタン•  メインlayer  –    READY? 、START!  –    ゲームオーバー  –    忍ベーダー、手裏剣  –    忍...
今回作るところ  •  忍者が動くところまで     つくります!
音楽素材について①•  音楽素材については、PANICPUMPKIN様   のご好意により、使用させていただいてい   ます。•  http://panicpumpkin.omiki.com/•  ゲームBGMに特化したサイトなのでおす   す...
音楽素材について②•  有料でオリジナル曲を制作してもらえる   「PANSOUND」というサイトもあるので、   ぜひ利用してみてください!•  http://pansound.com/
仮想スティック•  仮想スティックをつくってみよう!
仮想スティックの仕様   •  左右に移動ボタン	     •  ボタンの状態を変数に      設定	  
ボタンの仕様 •  おしてるあいだは色が    変わる!	   •  おしてるあいだは、変    数(isL,	  isR)がYESに    なる	  
普通のボタンとの違い   •  普通のボタンは、おし      て離した時にイベント      が起きる	     •  コントローラーのボタ      ンは、押した時にON、      離した時にOFFになる	  
moveイベント  •  ONになったあと、指を     移動してボタン外に出     たらOFFになる。	    •  指を移動して、移動先     がボタンだったらONに     なる	  
マルチタッチ •  両手を使うため、マル    チタッチに対応する	   •  複数の指で同じボタン    が押された時も考慮す    る	   •  ボタンが押された時に    UITouchを配列に記録し    ておき、すべての指が    ...
StickLayer.h	  @property	  BOOL	  isL;	  @property	  BOOL	  isR;	  
GameData.h@property	  (nonatomic,	  retain)	  NSMutableArray	  *stickArrayL;	  @property	  (nonatomic,	  retain)	  NSMutab...
GameData.m-­‐	  (id)init{	  	  	  	  	  if((self	  =	  [super	  init])){	  	  	  	  	  	  	  	  	  self.stickArrayL	  =	  ...
マルチタッチ対応	  cocos2dはデフォルトで、マルチタッチに対応していないので対応させる!	  
AppDelegate.m  -­‐	  (BOOL)application:(UIApplication	  *)application	  didFinishLaunchingWithOptions:(NSDictionary	  *)la...
ボタン画像の表示•  ボタンのON,OFFの画像を所定の場所に表   示する	  •  ON画像は、非表示にしておく	  •  StickLayerにバッチノードを追加し、その   中にボタンを追加する
StickLayer.m①-­‐(void)initLayer{	  	  	  	  	  [[CCSpriteFrameCache	  sharedSpriteFrameCache]	  addSpriteFramesWithFile:@"...
StickLayer.m②CCSprite	  *sp;	  	  	  	  	  sp	  =	  [CCSprite	  spriteWithSpriteFrameName:@"button_off.png"];	  	  	  	  	 ...
StickLayer.m③sp	  =	  [CCSprite	  spriteWithSpriteFrameName:@"button_off.png"];	  	  	  	  	  sp.position	  =	  ccp(320	  -...
タッチイベントを有効•  StickLayerで、タッチイベントを有効にす   る	  
StickLayer.m-­‐	  (id)init{	  	  	  	  	  self	  =	  [[super	  init]	  autorelease];	  	  	  	  	  if	  (self)	  {	  	  	 ...
タッチイベント•  タッチされたら、タッチ座標を取得	  •  タッチ座標がボタンの位置だったら	   –  UITouchを保存する	   –  ボタンが押されたことにする	   –  ONのボタンを表示する(今回は、OFFのボタ    ンを...
StickLayer.m①-­‐(void)ccTouchesBegan:(NSSet	  *)touches	  withEvent:(UIEvent	  *)event	  {	  	  	  	  	  CCSpriteBatchNode...
StickLayer.m②	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  CCSprite	  *sp_off_r	  =	  (CCSprite*)[ninvadersBatchNode	 ...
TIPS①•  touchesの中に複数のタッチイベントが   入っているので、1個ずつ処理を行う	    –  for(UITouch*	  touch	  in	  touches){	    –  }	  •  touch	  座標を、c...
TIPS②•  CGRectContainsPointで、Rectの中にPointが   含まれているかをチェックできる	  •  スプライトのRectは、sp_off_l.boundingBox   で取得できるので、そのなかにタッチ座標   ...
タッチ終了イベント•  保存してあるUITouchを削除する	  •  全部のTouchが離されていたら	   –  ONのボタンを非表示にする	   –  ボタンが押されていないことにする	  
StickLayer.m①-­‐(void)ccTouchesEnded:(NSSet	  *)touches	  withEvent:(UIEvent	  *)event	  {	  	  	  	  	  CCSpriteBatchNode...
StickLayer.m②                                                   	  for(UITouch*	  touch	  in	  touches){	                 ...
StickLayer.m③	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  CCSprite	  *sp_on_r	  =	  (CCSprite*)[ninvadersBatchNode	 ...
タッチ移動イベント•  いったんタッチを離したことにする	  •  移動先が押されたことにする	  	  
StickLayer.m-­‐(void)ccTouchesMoved:(NSSet	  *)touches	  withEvent:(UIEvent	  *)event	  {	  	  	  	  	  [self	  ccTouchesE...
アプリが裏に回ったら?•  アプリが裏に回ったら、タッチ終了イベン   トがこないくせに、次回起動時にタッチし   てない状態でアプリが始まる!	  •  アプリの再開時に、保存してあるTouchを   クリアしよう!
AppDelegate.m-­‐(void)	  applicationWillEnterForeground:(UIApplication*)application	  {	                          	  if(	 ...
忍者の移動•  忍者のキャラクターを移動させよう!
忍者の仕様  •  ボタンがおされてい     るあいだ移動する	    •  移動中は、アニメー     ションする	    •  ボタンを離すと手裏     剣をなげるために、     上を向く	  
忍者の実装•  忍者クラスを作ってメインLayerで呼び出   す	  •  忍者クラスの中に、SPRITEをもっておく	  •  メインLayerの中で、忍者のクラスのtickを   呼び出す	  •  忍者のクラス内では、ボタンの状態を見て...
忍者クラスを作成•  メインLayerで忍者クラスを作成	  •  スティックLayerを参照できるように、忍   者クラスにメインSceneを設定	  •  忍者クラス内のスプライトを、メイン   Layerに追加
MainLayer.m       //	  忍者                 CCSpriteBatchNode	  *gameBatchNode	  =	  (CCSpriteBatchNode*)[self	  getChildByT...
忍者を動かす•  メインLayerのスケジュールの中で、忍者   クラスの関数を呼び出し忍者の移動を行う
MainLayer.m-­‐(void)gamePlay:(ccTime)dt{	  	  	  	  	  //	  忍者移動	  	  	  	  [self.ninja	  tick:dt];	  }
忍者の移動①•  忍者クラスの中で、スティックLayerの状   態を調べて移動処理を行う	  •  ボタンが押されていた場合	   –  その方向を向いていなかった場合	     •  その方向を向いたアニメーション	   –  忍者の座標を...
Ninja.m	  if(self.mainScene.stickLayer.isL){	  	  	  	  	  	  	  	  	  if(self.way	  !=	  NINJYA_WAY_LEFT){	  	  	  	  	  ...
TIPS•  CCAnimation	  を使うと、パラパラ漫画のよ   うなコマを切り替えるアニメーションが   できる	  •  向きが変わった時だけアニメーションを   開始することで、自然に動きをつけること   ができる
忍者の移動②•  ボタンが押されていない場合は、停止処理   を行う	  •  アニメーションを止める	  •  忍者の向きを見てスプライトを変更する	  •  self.waitCountをカウントアップして、一定   時間経過したら、上を向...
Ninja.melse{	  	  	  	  	  	  	  	  	  [self.sprite	  stopAllActions];	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	...
TIPS•  setDisplayFrameでスプライトの画像を変更   できる	  
忍者の移動③•  忍者の移動先を確認して、画面外であれば   はみださないように修正する	  
Ninja.m	  float	  xx	  =	  self.sprite.position.x	  +	  x;	  	  	  	  	  if(xx	  <	  30){	  	  	  	  	  	  	  	  	  xx	  =	...
できた!•  忍者が動いた!
まとめ•  キャラクターをボタンで移動できるよう   になった!•  cocos2d 1.0.の資料だけど、参考に! –  http://tonosamart.com/blog/
とのさまラボ!•  勉強会に参加した人どうしのコミニュティがほしい!   勉強会の開催日時の告知がほしい! という意見をみなさまからいただいたので、 コミニュティを作成しました! ぜひ「いいね!」をお願いします!https://www.face...
おわり主催(共同開催):株式会社 gooyahttp://www.gooya.co.jp/メドレー株式会社http://www.medley.co.jp/講師:西田 寛輔 (Tonosamart)http://www.facebook.com/...
Upcoming SlideShare
Loading in …5
×

㉕cocos2dを覚えよう!初級編③

8,717 views

Published on

https://www.facebook.com/TonosamaLabo

Published in: Technology
  • Be the first to comment

㉕cocos2dを覚えよう!初級編③

  1. 1. cocos2d 2.0for iPhone 勉強会 cocos2dを覚えよう!   初級編③
  2. 2. 動作環境•  Mac OS X 10.8 Mountain Lion•  xcode 4.5.2•  cocos2d for iPhone 2.0 http://www.cocos2d-iphone.org/
  3. 3. はじめに•  cocos2dを覚えよう!初級編③•  ボタンで移動してみよう!
  4. 4. もくじ•  cocos2dの基本•  Sceneの構成要素•  忍ベーダー•  仮想スティック•  忍者の移動
  5. 5. cocos2dの基本•  まずはcocos2dについておさらい!
  6. 6. cocos2dについて•  オープンソース+無料で商用利用可能•  2Dに特化•  物理エンジン搭載(box2d,chipmunk)•  効果音やBGMの再生も可能•  OpenGL利用で高速描画•  Objective-Cで書かれている
  7. 7. デメリット•  iPhone標準のUIが使えない。 (がんばれば使えるかも?)
  8. 8. cocos2dの基礎知識•  スプライト(sprite):一般的には、キャラ クターを表示する技術。•  スプライトエンジン:スプライトを簡単 に管理、表示できる仕組み
  9. 9. cocos2dの座標•  座標は左下が(0,0)•  スプライトの基準点は中心(変更可能) (480,320) (基準点) (0,0) ※単位はpointで、通常1point=1px,retinaでは1point=2px
  10. 10. cocos2dの基礎知識•  CCSprite –  回転、拡大、縮小、傾斜、透過•  CCAnimation –  ぱらぱら漫画のような、画像切り替え•  CCAction –  キャラクターに任意の動きを設定可能 –  イベント処理 (CCSendMessage、CCCallFunc)
  11. 11. cocos2dの基礎知識•  CCTMXTiledMap –  タイルマップの表示•  CCParticleSystem –  パーティクルの表示•  CCSpriteBatchNode –  スプライトをまとめて管理•  SimpleAudioEngine –  効果音、BGMを簡単に再生
  12. 12. こまったときは?•  こまったときは、プログラミングガイド を見よう! –  http://www.cocos2d-iphone.org/wiki/ doku.php/prog_guide:index
  13. 13. Sceneの構成要素•  Sceneの構成要素を覚えよう!
  14. 14. Sceneは複数作れる
  15. 15. Sceneの中にはLayerをおける
  16. 16. Layerの中にはいろいろおける CCSprite、CCMenu、CCLabelBMFont、   CCSpriteBatchNode   などを置くことができる
  17. 17. LayerとSprite •  Layer   •  Sprite(手裏剣1)   •  Sprite(手裏剣2)   •  Sprite(手裏剣3)   •  Sprite(忍者)   レイヤーの中に、スプライトを置くことが できる  
  18. 18. LayerにSpriteBatchNodeを置ける SpriteBatchNodeを置いても、画 面には表示されない。     SpriteBatchNodeに、Spriteを置く と画面に表示される  
  19. 19. LayerとSpriteBatchNodeとSprite •  Layer   •  BatchNode   •  Sprite(手裏剣1)   •  Sprite(手裏剣2)   •  Sprite(手裏剣3)   •  BatchNode   •  Sprite(忍者)   レイヤーの中に、バッチノードをおいて、そ の中に、スプライトを置く     バッチノードの中には、その中に含まれてい るスプライトしかおけない  
  20. 20. TagとZ•  Layerや、スプライトなど、CCNodeには、 TagとZが定義されています。•  Tagを一意にすることで、getChildByTag で親Nodeから取得が可能です。•  Zは重ね合わせの優先順位を表します。•  Zが値が大きい方が上に描画されます。
  21. 21. 忍ベーダー•  次々と現れる侵略者(忍ベーダー)をたおしていこう!•  忍ベーダーが、ライフラインを超えるとゲームオーバー
  22. 22. ルール•  タイトル画面でボタンを押すとゲーム開始•  READY→STARTのあと、ゲーム開始•  忍ベーダーは、上から攻めてくる。大きさによって硬さ や得点が違う•  忍者は、ボタンで左右移動•  忍者が止まると上を向いて、手裏剣を自動で打つ•  ライフラインに忍ベーダーが来たらゲームオーバー•  GAMEOVERを表示して、タイトル画面に戻る
  23. 23. 4inch対応 •  今回は画面上部の見 える部分を変更する ことで対応します   •  スコアなどの文字は、 画面の高さをもとに 表示して、画面内に 収まるようにします。   •  忍ベーダーや手裏剣 は、4inchの座標で計 算します。3.5inchでも 得ない画面外の部分 でも処理を行います。  
  24. 24. がめんこうせいタイトルscene メインscene
  25. 25. タイトルscene•  フロントlayer –  スコア•  タイトルlayer –  タイトルロゴ –  スタートボタン –  床•  背景layer –  背景画像
  26. 26. メインscene•  フロントlayer –  スコア•  スティックlayer –  左右のボタン•  メインlayer –  READY? 、START! –  ゲームオーバー –  忍ベーダー、手裏剣 –  忍者 –  点線、床•  背景layer –  背景画像
  27. 27. 今回作るところ •  忍者が動くところまで つくります!
  28. 28. 音楽素材について①•  音楽素材については、PANICPUMPKIN様 のご好意により、使用させていただいてい ます。•  http://panicpumpkin.omiki.com/•  ゲームBGMに特化したサイトなのでおす すめ!(曲数も多いです)•  利用報告、 著作表記、リンクなどの明記 不要で商用利用可能の音楽素材を多数公 開されています。
  29. 29. 音楽素材について②•  有料でオリジナル曲を制作してもらえる 「PANSOUND」というサイトもあるので、 ぜひ利用してみてください!•  http://pansound.com/
  30. 30. 仮想スティック•  仮想スティックをつくってみよう!
  31. 31. 仮想スティックの仕様 •  左右に移動ボタン   •  ボタンの状態を変数に 設定  
  32. 32. ボタンの仕様 •  おしてるあいだは色が 変わる!   •  おしてるあいだは、変 数(isL,  isR)がYESに なる  
  33. 33. 普通のボタンとの違い •  普通のボタンは、おし て離した時にイベント が起きる   •  コントローラーのボタ ンは、押した時にON、 離した時にOFFになる  
  34. 34. moveイベント •  ONになったあと、指を 移動してボタン外に出 たらOFFになる。   •  指を移動して、移動先 がボタンだったらONに なる  
  35. 35. マルチタッチ •  両手を使うため、マル チタッチに対応する   •  複数の指で同じボタン が押された時も考慮す る   •  ボタンが押された時に UITouchを配列に記録し ておき、すべての指が 離れたらOFFにする  
  36. 36. StickLayer.h  @property  BOOL  isL;  @property  BOOL  isR;  
  37. 37. GameData.h@property  (nonatomic,  retain)  NSMutableArray  *stickArrayL;  @property  (nonatomic,  retain)  NSMutableArray  *stickArrayR;
  38. 38. GameData.m-­‐  (id)init{          if((self  =  [super  init])){                  self.stickArrayL  =  [NSMutableArray  array];                  self.stickArrayR  =  [NSMutableArray  array];                  [self  resetScore];          }    return  self;  }    -­‐(void)resetStickArray{          [self.stickArrayL  removeAllObjects];          [self.stickArrayR  removeAllObjects];  }
  39. 39. マルチタッチ対応  cocos2dはデフォルトで、マルチタッチに対応していないので対応させる!  
  40. 40. AppDelegate.m -­‐  (BOOL)application:(UIApplication  *)application  didFinishLaunchingWithOptions:(NSDictionary  *)launchOptions  {  :   //  マルチタッチを有効にする   [glView  setMultipleTouchEnabled:YES];   return  YES;  }    
  41. 41. ボタン画像の表示•  ボタンのON,OFFの画像を所定の場所に表 示する  •  ON画像は、非表示にしておく  •  StickLayerにバッチノードを追加し、その 中にボタンを追加する
  42. 42. StickLayer.m①-­‐(void)initLayer{          [[CCSpriteFrameCache  sharedSpriteFrameCache]  addSpriteFramesWithFile:@"NInvadersResource.plist"];          CCSpriteBatchNode  *ninvadersBatchNode  =  [CCSpriteBatchNode  batchNodeWithFile:@"NInvadersResource.pvr.ccz"  capacity:100];          [self  addChild:ninvadersBatchNode  z:OBJECT_STICK  tag:OBJECT_STICK];    
  43. 43. StickLayer.m②CCSprite  *sp;          sp  =  [CCSprite  spriteWithSpriteFrameName:@"button_off.png"];          sp.position  =  ccp(42,  92);          [ninvadersBatchNode  addChild:sp  z:SPRITE_STICK_L_OFF  tag:SPRITE_STICK_L_OFF];                    sp  =  [CCSprite  spriteWithSpriteFrameName:@"button_on.png"];          sp.position  =  ccp(42,  92);          sp.visible  =  NO;          [ninvadersBatchNode  addChild:sp  z:SPRITE_STICK_L_ON  tag:SPRITE_STICK_L_ON];  
  44. 44. StickLayer.m③sp  =  [CCSprite  spriteWithSpriteFrameName:@"button_off.png"];          sp.position  =  ccp(320  -­‐  42,  92);          [ninvadersBatchNode  addChild:sp  z:SPRITE_STICK_R_OFF  tag:SPRITE_STICK_R_OFF];                    sp  =  [CCSprite  spriteWithSpriteFrameName:@"button_on.png"];          sp.position  =  ccp(320  -­‐  42,  92);          sp.visible  =  NO;          [ninvadersBatchNode  addChild:sp  z:SPRITE_STICK_R_ON  tag:SPRITE_STICK_R_ON];  }
  45. 45. タッチイベントを有効•  StickLayerで、タッチイベントを有効にす る  
  46. 46. StickLayer.m-­‐  (id)init{          self  =  [[super  init]  autorelease];          if  (self)  {                  //  イベントの無効/有効 self.isTouchEnabled  =  YES;                  self.isAccelerometerEnabled  =  NO;                                    //  変数 GameData  *gameData  =  [GameData  getInstance];                  [gameData  resetStickArray];                                    //レイヤーの初期化                [self  initLayer];          }          return  self;  }  
  47. 47. タッチイベント•  タッチされたら、タッチ座標を取得  •  タッチ座標がボタンの位置だったら   –  UITouchを保存する   –  ボタンが押されたことにする   –  ONのボタンを表示する(今回は、OFFのボタ ンを非表示にしなくてもいいデザインなので、 OFFボタンはそのまま)  
  48. 48. StickLayer.m①-­‐(void)ccTouchesBegan:(NSSet  *)touches  withEvent:(UIEvent  *)event  {          CCSpriteBatchNode  *ninvadersBatchNode  =  (CCSpriteBatchNode*)[self  getChildByTag:OBJECT_STICK];          GameData  *gameData  =  [GameData  getInstance];    for(UITouch*  touch  in  touches){      CGPoint  touchPoint  =  [touch  locationInView:[touch  view]];      touchPoint  =  [[CCDirector  sharedDirector]  convertToGL:touchPoint];                    CCSprite  *sp_off_l  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_L_OFF];                  CCSprite  *sp_on_l  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_L_ON];      if(CGRectContainsPoint(sp_off_l.boundingBox,  touchPoint)){                          [gameData.stickArrayL  addObject:touch];                          sp_on_l.visible  =  YES;        self.isL  =  TRUE;      }
  49. 49. StickLayer.m②                                  CCSprite  *sp_off_r  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_R_OFF];                  CCSprite  *sp_on_r  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_R_ON];      if(CGRectContainsPoint(sp_off_r.boundingBox,  touchPoint)){                          [gameData.stickArrayR  addObject:touch];                          sp_on_r.visible  =  YES;        self.isR  =  TRUE;      }    }  }  
  50. 50. TIPS①•  touchesの中に複数のタッチイベントが 入っているので、1個ずつ処理を行う   –  for(UITouch*  touch  in  touches){   –  }  •  touch  座標を、cocos2dの座標に変換する   –  CGPoint  touchPoint  =  [touch  locationInView: [touch  view]];   –  touchPoint  =  [[CCDirector  sharedDirector]   convertToGL:touchPoint];  
  51. 51. TIPS②•  CGRectContainsPointで、Rectの中にPointが 含まれているかをチェックできる  •  スプライトのRectは、sp_off_l.boundingBox で取得できるので、そのなかにタッチ座標 が含まれているかをチェックする   –  if(CGRectContainsPoint(sp_off_l.boundingBox,   touchPoint)){
  52. 52. タッチ終了イベント•  保存してあるUITouchを削除する  •  全部のTouchが離されていたら   –  ONのボタンを非表示にする   –  ボタンが押されていないことにする  
  53. 53. StickLayer.m①-­‐(void)ccTouchesEnded:(NSSet  *)touches  withEvent:(UIEvent  *)event  {          CCSpriteBatchNode  *ninvadersBatchNode  =  (CCSpriteBatchNode*)[self  getChildByTag:OBJECT_STICK];          GameData  *gameData  =  [GameData  getInstance];    
  54. 54. StickLayer.m②  for(UITouch*  touch  in  touches){      CGPoint  touchPoint  =  [touch  locationInView:[touch  view]];      touchPoint  =  [[CCDirector  sharedDirector]  convertToGL:touchPoint];                                    CCSprite  *sp_on_l  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_L_ON];      [gameData.stickArrayL  removeObject:touch];      if([gameData.stickArrayL  count]  ==  0){                          sp_on_l.visible  =  NO;        self.isL  =  FALSE;      }  
  55. 55. StickLayer.m③                                  CCSprite  *sp_on_r  =  (CCSprite*)[ninvadersBatchNode  getChildByTag:SPRITE_STICK_R_ON];      [gameData.stickArrayR  removeObject:touch];      if([gameData.stickArrayR  count]  ==  0){                          sp_on_r.visible  =  NO;        self.isR  =  FALSE;      }    }  }  
  56. 56. タッチ移動イベント•  いったんタッチを離したことにする  •  移動先が押されたことにする    
  57. 57. StickLayer.m-­‐(void)ccTouchesMoved:(NSSet  *)touches  withEvent:(UIEvent  *)event  {          [self  ccTouchesEnded:touches  withEvent:event];          [self  ccTouchesBegan:touches  withEvent:event];  }  
  58. 58. アプリが裏に回ったら?•  アプリが裏に回ったら、タッチ終了イベン トがこないくせに、次回起動時にタッチし てない状態でアプリが始まる!  •  アプリの再開時に、保存してあるTouchを クリアしよう!
  59. 59. AppDelegate.m-­‐(void)  applicationWillEnterForeground:(UIApplication*)application  {    if(  [navController_  visibleViewController]  ==  director_  )      [director_  startAnimation];            //  Stickの初期化 GameData  *gameData  =  [GameData  getInstance];          [gameData  resetStickArray];  }
  60. 60. 忍者の移動•  忍者のキャラクターを移動させよう!
  61. 61. 忍者の仕様 •  ボタンがおされてい るあいだ移動する   •  移動中は、アニメー ションする   •  ボタンを離すと手裏 剣をなげるために、 上を向く  
  62. 62. 忍者の実装•  忍者クラスを作ってメインLayerで呼び出 す  •  忍者クラスの中に、SPRITEをもっておく  •  メインLayerの中で、忍者のクラスのtickを 呼び出す  •  忍者のクラス内では、ボタンの状態を見て 移動を行う
  63. 63. 忍者クラスを作成•  メインLayerで忍者クラスを作成  •  スティックLayerを参照できるように、忍 者クラスにメインSceneを設定  •  忍者クラス内のスプライトを、メイン Layerに追加
  64. 64. MainLayer.m //  忍者 CCSpriteBatchNode  *gameBatchNode  =  (CCSpriteBatchNode*)[self  getChildByTag:OBJECT_GAME];          self.ninja  =  [[[Ninja  alloc]  init]autorelease];          self.ninja.mainScene  =  (MainScene*)[self  parent];          [gameBatchNode  addChild:self.ninja.sprite  z:SPRITE_GAME_NINJYA  tag:SPRITE_GAME_NINJYA];
  65. 65. 忍者を動かす•  メインLayerのスケジュールの中で、忍者 クラスの関数を呼び出し忍者の移動を行う
  66. 66. MainLayer.m-­‐(void)gamePlay:(ccTime)dt{          //  忍者移動        [self.ninja  tick:dt];  }
  67. 67. 忍者の移動①•  忍者クラスの中で、スティックLayerの状 態を調べて移動処理を行う  •  ボタンが押されていた場合   –  その方向を向いていなかった場合   •  その方向を向いたアニメーション   –  忍者の座標をdt*speed動かす  
  68. 68. Ninja.m  if(self.mainScene.stickLayer.isL){                  if(self.way  !=  NINJYA_WAY_LEFT){                          [self.sprite  stopAllActions];                                                    NSMutableArray  *animFrames  =  [NSMutableArray  array];                          [animFrames  addObject:[[CCSpriteFrameCache  sharedSpriteFrameCache]  spriteFrameByName:@"ninjya_l.png"]];                          [animFrames  addObject:[[CCSpriteFrameCache  sharedSpriteFrameCache]  spriteFrameByName:@"ninjya_l2.png"]];                                                    CCAnimation  *animation  =  [CCAnimation  animationWithSpriteFrames:animFrames  delay:0.2f];                          id  repeatAnim  =  [CCRepeatForever  actionWithAction:[CCAnimate  actionWithAnimation:animation]];                          [self.sprite  runAction:repeatAnim];                          self.way  =  NINJYA_WAY_LEFT;                  }                                    self.waitCount  =  0;                  x  =  x  -­‐  dt  *  NINJA_SPEED;          }
  69. 69. TIPS•  CCAnimation  を使うと、パラパラ漫画のよ うなコマを切り替えるアニメーションが できる  •  向きが変わった時だけアニメーションを 開始することで、自然に動きをつけること ができる
  70. 70. 忍者の移動②•  ボタンが押されていない場合は、停止処理 を行う  •  アニメーションを止める  •  忍者の向きを見てスプライトを変更する  •  self.waitCountをカウントアップして、一定 時間経過したら、上を向くようにする  
  71. 71. Ninja.melse{                  [self.sprite  stopAllActions];                                    if(self.way  ==  NINJYA_WAY_LEFT){                          CCSpriteFrame  *sf  =  [[CCSpriteFrameCache  sharedSpriteFrameCache]  spriteFrameByName:@"ninjya_l.png"];                          [self.sprite  setDisplayFrame:sf];                  }else  if(self.way  ==  NINJYA_WAY_RIGHT){                          CCSpriteFrame  *sf  =  [[CCSpriteFrameCache  sharedSpriteFrameCache]  spriteFrameByName:@"ninjya_r.png"];                          [self.sprite  setDisplayFrame:sf];                  }                                    self.waitCount  +=  dt;                  if(self.way  !=  NINJYA_WAY_UP  &&  self.waitCount  >=  NINJA_UP_DELAY){                          self.waitCount  =  0;                                                    CCSpriteFrame  *sf  =  [[CCSpriteFrameCache  sharedSpriteFrameCache]  spriteFrameByName:@"ninjya_u.png"];                          [self.sprite  setDisplayFrame:sf];                          self.way  =  NINJYA_WAY_UP;                  }          }  
  72. 72. TIPS•  setDisplayFrameでスプライトの画像を変更 できる  
  73. 73. 忍者の移動③•  忍者の移動先を確認して、画面外であれば はみださないように修正する  
  74. 74. Ninja.m  float  xx  =  self.sprite.position.x  +  x;          if(xx  <  30){                  xx  =  30;          }else  if(xx  >  (320  -­‐  30)){                  xx  =  (320  -­‐  30);          }                    self.sprite.position  =  ccp(xx,  self.sprite.position.y);
  75. 75. できた!•  忍者が動いた!
  76. 76. まとめ•  キャラクターをボタンで移動できるよう になった!•  cocos2d 1.0.の資料だけど、参考に! –  http://tonosamart.com/blog/
  77. 77. とのさまラボ!•  勉強会に参加した人どうしのコミニュティがほしい! 勉強会の開催日時の告知がほしい! という意見をみなさまからいただいたので、 コミニュティを作成しました! ぜひ「いいね!」をお願いします!https://www.facebook.com/TonosamaLabo  
  78. 78. おわり主催(共同開催):株式会社 gooyahttp://www.gooya.co.jp/メドレー株式会社http://www.medley.co.jp/講師:西田 寛輔 (Tonosamart)http://www.facebook.com/tonosamart

×