【Cocos2d-x】どのスプライト(画像)がタッチされたかを判定する

  • Pocket
  • このエントリーをはてなブックマークに追加
  • 162 follow us in feedly

まえがき

こんばんは、C++、Cocos2dx入門して3日ほどがたった私です。

前回はアプリでタッチ判定をとってラベルをいどうさせたりしましたが、今回はタッチされた座標にスプライト(画像)があるかを判定するようなサンプルソースを作ってみました。

完成品の動画

youtubeに完成品の動画をアップしておきました。

9つの画像があり、画像をタッチするとその画像のタグ(スプライトに設定できる数値)をログで出力しています。

タッチした座表に画像が存在しない場合は何も処理をしていません。

かなり見づらいと思いますが画像をタッチすると、こんな感じでログをはいています。

touch enemy tag is 3
Cocos2d: textRangeFromPosition
Cocos2d: textInRange
Cocos2d: textRangeFromPosition
Cocos2d: textInRange
touch enemy tag is 4
Cocos2d: textRangeFromPosition
Cocos2d: textInRange
Cocos2d: textRangeFromPosition
Cocos2d: textInRange
touch enemy tag is 5
Cocos2d: textRangeFromPosition
Cocos2d: textInRange
Cocos2d: textRangeFromPosition

開発環境

  • Cocos2dx 2.1.5
  • Xcode 5.0.1
  • シュミレーター iOS7

考え方。

自分のスプライトタッチ判定ソースの考え方です。

  • CCSpriteクラスを継承したクラス(今回はEnemySpriteとした)を作る
  • 継承したクラスに自分の画像の判定範囲(Rect)を求めるメソッドを追加する(求め方は画像の座標とサイズから画像の左上の座標を求め、そこから画像の幅、高さを加えたものを判定範囲とする。)
  • 座標情報(CCPoint)を引数にタッチ対象かどうかを返すメソッドをつくる。

っといったところ、説明下手くそですいません。

サンプルソース

EnemySpriteクラス

まずはCCSpriteを継承したEnemySpriteを作成する

#ifndef __SpriteTouchTestProject__EnemySprite__
#define __SpriteTouchTestProject__EnemySprite__

#include "cocos2d.h"

class EnemySprite : public cocos2d::CCSprite
{
public:
    
    EnemySprite();
    
    cocos2d::CCRect getRect();
    bool isTouchPoint(cocos2d::CCPoint);
    
};
#endif /* defined(__SpriteTouchTestProject__EnemySprite__) */

#include "EnemySprite.h"

using namespace cocos2d;

EnemySprite::EnemySprite()
{
}

/**
 *  スプライトの範囲を取得
 *
 *  @return CCRect
 */
CCRect EnemySprite::getRect()
{
    // スプライトの座標(画像の真ん中の座標のこと)
    CCPoint point = this->getPosition();
    
    // スプライトの幅と高さ
    int w = this->getContentSize().width;
    int h = this->getContentSize().height;
    
    // スプライトの範囲を返す
    return CCRectMake(point.x-(w/2), point.y-(h/2), w, h);
}

/**
 *  引数の座標がスプライトの範囲内かどうかを返す(タッチ時の座標情報を渡す)
 *
 *  @param point 座標ポイント
 *
 *  @return ture or false
 */
bool EnemySprite::isTouchPoint(CCPoint point)
{
    return this->getRect().containsPoint(point);
}

HelloWorldSceneクラス

最初にプロジェクトを作った時にできているHelloWorldSceneを流用してます

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
    virtual bool init();

    // there's no 'id' in cpp, so we recommend to return the class instance pointer
    static cocos2d::CCScene* scene();
    

    // スプライトを格納する配列
    cocos2d::CCArray enemys;
    
    
    // タッチ関係のイベント
    bool ccTouchBegan(cocos2d::CCTouch* pTouch, cocos2d::CCEvent* pEvent);

    CREATE_FUNC(HelloWorld);

};

#endif // __HELLOWORLD_SCENE_H__

#include "HelloWorldScene.h"
#include "EnemySprite.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    if ( !CCLayer::init() )
    {
        return false;
    }
    
    // 画面サイズ取得
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
    
    // スプライトを表示する座標を設定
    float enemyPositionsX[9];
    float enemyPositionsY[9];

    enemyPositionsX[0] = winSize.width/2-200;
    enemyPositionsX[1] = winSize.width/2;
    enemyPositionsX[2] = winSize.width/2+200;
    enemyPositionsX[3] = winSize.width/2-200;
    enemyPositionsX[4] = winSize.width/2;
    enemyPositionsX[5] = winSize.width/2+200;
    enemyPositionsX[6] = winSize.width/2-200;
    enemyPositionsX[7] = winSize.width/2;
    enemyPositionsX[8] = winSize.width/2+200;
    
    enemyPositionsY[0] = winSize.height/2+200;
    enemyPositionsY[1] = winSize.height/2+200;
    enemyPositionsY[2] = winSize.height/2+200;
    enemyPositionsY[3] = winSize.height/2;
    enemyPositionsY[4] = winSize.height/2;
    enemyPositionsY[5] = winSize.height/2;
    enemyPositionsY[6] = winSize.height/2-200;
    enemyPositionsY[7] = winSize.height/2-200;
    enemyPositionsY[8] = winSize.height/2-200;
    
    
    // スプライトを9つ生成
    for(int i=0; i<9; i++){
        EnemySprite* enemy = new EnemySprite();
        enemy->initWithFile("Icon.png");
        enemy->autorelease();
        enemy->setPosition(ccp(enemyPositionsX[i], enemyPositionsY[i]));
        enemy->setTag(i);
        
        this->addChild(enemy);
        enemys.addObject(enemy);
    }
    
    // タッチの有効化
    this->setTouchEnabled(true);
    this->setTouchMode(kCCTouchesOneByOne);
    
    return true;
}

bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    CCObject* obj = NULL;
    CCARRAY_FOREACH(&enemys, obj){
        EnemySprite* enemy = (EnemySprite*)obj;
        if(enemy->isTouchPoint(touch->getLocation())){
            std::cout << "touch enemy tag is " << enemy->getTag() << std::endl;
        }
    }
    
    return true;
}

完成品はこんな感じに。。

cocos2dx-touch-sprite-1

あとがき

とりあえず試行錯誤で自分のやりたかったことはできました。

ただもっと、ちゃんとしたやり方?というか正規のやり方がありましたらご教授ください><

おすすめ書籍

cocos2d-xによるiPhone/Androidアプリプログラミングガイド
清水 友晶
マイナビ
売り上げランキング: 8,329
cocos2d-x入門
cocos2d-x入門
posted with amazlet at 13.11.13
清水 友晶
リックテレコム
売り上げランキング: 79,743

関連記事

405343706201

【Cocos2d-x】スコアをローカルに保存する方法

まえがき 今回はCocos2dxでローカルに値を保存する方法をメモ。...

記事を読む

iTunes_Connect.png証明書アシスタント.png

【iPhoneアプリ開発】リリースビルドできるようにするまでのメモ

まえがき iphoneアプリをAppleの審査まで運ぶことができました...

記事を読む

405343706201

【Cocos2d-x】画面のサイズを取得する

まえがき 今回はCocos2dxで画面のサイズを取得する方法。 色...

記事を読む

images

【Android開発Tips】WEBビューを使ってみる

まえがき けっこうお久しぶりのブログです。 それもそのはずで、今週...

記事を読む

Screeny-Shot-2013-08-11-21.40.56.pngScreeny-Shot-2013-08-11-21.40.56.png

AlloyでFacebookアプリっぽいスライドメニューを実装してみる

まえがき AlloyでFacebookとかでよく使われている左からビュ...

記事を読む

新着記事

no image

PHPでRubyのirbっぽいインタラクティブなスクリプトが実行できる「boris」

まえがき PHPでもRubyのirbみたいなことがしたくて探してみたと...

記事を読む

2015年の抱負と去年の振り返り〜よちよちWEB業界1年経験して〜

まえがき あけましておめでとうございます。今年もどうぞよろしくお願いし...

記事を読む

Java SE 7 Bronze試験(1Z0-802)を受けてきました

まえがき 以前から少し受けてみたかった試験『Java SE 7 Bro...

記事を読む

HubotでJenkinsのジョブを実行する

まえがき HubotをつかってJenkinsのジョブをじっこうしてみた...

記事を読む

no image

Hubotをforeverでデーモン化する

まえがき 今回はHubotをforeverを使ってデーモン化してみた時...

記事を読む

スポンサーリンク

  • Sorry. No data so far.

PAGE TOP ↑