cocos2d Advent Calendar 2011 23日目 「Cocos3dをさわってみた2。」 #cocos2d_2011_adca

  • cocos2d Advent Calendar 2011について。

cocos2d Advent Calendar 2011 : ATND
http://atnd.org/events/22814

  • 前日の記事。

xionchannel@software: coco2d Advent Calendar 2011 22日目: Tiledの使い方講座
http://xionchannel.blogspot.com/2011/12/coco2d-advent-calendar-2011-22-tiled.html

2回目の記事です。
前回に引続きCocos3dでサンプルを作ってみました。
今回は画面をタッチして3Dオブジェクトを検出する処理を中心に扱っています。

ダウンロードはgithubから。

KCSampleCC3TouchCube
http://github.com/kclab/KCSampleCC3TouchCube/zipball/master

起動すると画面中央にcubeをひとつ表示します。


cubeをタッチするとタッチした側面にさらにcubeが追加されます。

cubeを画面に表示する。

KCSampleCC3TouchCubeWorldのinitializeWorldでカメラとライトの設定が完了したら
cubeをひとつ生成してCC3Nodeツリーに追加します。

KCSampleCC3TouchCubeWorld

-(void) initializeWorld {
  ...

  CC3Node* firstCube = [self cubuTouchableSide];
  self.nodeCenter = firstCube;
  [self addChild:firstCube];
}

cubuTouchableSideメソッドでcubeの生成します。

KCSampleCC3TouchCubeWorld

- (CC3Node*)cubuTouchableSide {
  
  CC3Node* node = [CC3Node nodeWithName:@"nodeCenter"];
  node.location = cc3v(0.0, 0.0, 0.0);
  //node.rotation = cc3v(-30.0, 45.0, 0.0);
  
  CGFloat lengthOnSide = LENGTH_ON_SIDE_FOR_CUBE;
  CGFloat lengthOnSideHalf = lengthOnSide / 2;
  CGSize rectSize = CGSizeMake(lengthOnSide, lengthOnSide);
  
  // Front.
  {
    CC3PlaneNode* planeNode = [CC3PlaneNode nodeWithName:NODE_NAME_FRONT];
    [planeNode populateAsCenteredRectangleWithSize:rectSize];
    planeNode.color = ccYELLOW;
    planeNode.location = cc3v(0.0, 0.0, lengthOnSideHalf);
    planeNode.rotation = cc3v(0.0, 0.0, 0.0);
    planeNode.isTouchEnabled = YES;
    [node addChild:planeNode];
  }

  ...
}

大きさを持たないnodeを中心に6枚のPlaneNodeを貼りあわせて作成します。
各planeノードのisTouchEnabledを有効にするとそのノードはタッチしたときに検出可能になります。


タッチでcubeを検出する。

タッチしたノードを検出するためには、前回の「Cocos3dをさわってみた」でも解説したように、
CC3Layerを継承したKCSampleCC3TouchCubeLayerのisTouchEnabledを有効にします。

KCSampleCC3TouchCubeLayer

-(void) initializeControls {
  self.isTouchEnabled = YES;
}


次にKCSampleCC3TouchCubeWorldのメソッド-(void) nodeSelected...をオーバライドします。

KCSampleCC3TouchCubeWorld

-(void) nodeSelected: (CC3Node*) aNode byTouchEvent: (uint) touchType at: (CGPoint) touchPoint {
  LogDebug();
  LogInfo(@"You selected %@ at %@, or %@ in 2D.", aNode,
          NSStringFromCC3Vector(aNode ? aNode.globalLocation : kCC3VectorZero),
          NSStringFromCC3Vector(aNode ? [activeCamera projectNode: aNode] : kCC3VectorZero));
  
  LogDebug(@"touchPoint => %@", NSStringFromCGPoint(touchPoint));
  
  if ([aNode.name isEqualToString:NODE_NAME_FRONT]) {
    LogDebug(@"TAG_FRONT");
    CC3Node* aCube = [self cubuTouchableSide];
    aCube.location = cc3v(0.0, 0.0, LENGTH_ON_SIDE_FOR_CUBE);
    [aNode.parent addChild:aCube];

  ...

画面をタッチした場所にcubeが存在する場合、上記のメソッドが呼ばれます。
その後ノード生成時に登録した名前でcubeのどの側面か判別して側面に隣り合わせになるようにcubeをさらに追加しています。 

このように、Cocos3dではCC3NodeのオブジェクトのisTouchEnabledプロパティを有効にして、
"- (void) nodeSelected..."をオーバライドするだけで簡単に3D空間のオブジェクトを選択することができます。



次の記事

xionchannel@software: coco2d Advent Calendar 2011 24日目: オーバートップレイヤーのすすめ
http://xionchannel.blogspot.com/2011/12/coco2d-advent-calendar-2011-24.html