スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


このエントリーをはてなブックマークに追加

cocos2d-x ver3.0 物理空間における当たり判定(衝突)。ソースコードあり。

こんにちは、主夫ひろしです。

衝突1

衝突2

衝突3


物理空間を使った当たり判定で、Sprite同士が当たったはずなのにアニメーション中は無視されて通過してしまう現象がおこるので、衝突したらその場にストンと落ちるような実装をメモがてら紹介。

処理手順(アルゴリズム)はいたってシンプルで、衝突判定をして衝突したときに呼ばれるデリゲートメソッドでアニメーションをストップさせるだけです。


HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();

// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
virtual bool initPhysics();

// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);

// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);

// 衝突した時
bool onContactBegin(cocos2d::PhysicsContact& contact);
};

#endif // __HELLOWORLD_SCENE_H__



HelloWorldScene.cpp

#include "HelloWorldScene.h"
USING_NS_CC;

Scene* HelloWorld::createScene()
{
// 物理空間が付いたシーンを作成する。
auto scene = Scene::createWithPhysics();
// 物理空間を取り出す。
auto world = scene->getPhysicsWorld();
// 重力を設定する。
world->setGravity(Vect(0, -350));


// 'layer' is an autorelease object
auto 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()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}

// 画面サイズを取得
Size winSize = Director::getInstance()->getWinSize();


// 物理エンジンを初期化する。
initPhysics();

Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();

// add "HelloWorld" splash screen"
auto background = Sprite::create("PlayBG.png");
background->setScale(2.0f);

// position the sprite on the center of the screen
background->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

// add the sprite as a child to this layer
this->addChild(background, 0);


// キャラクター
// 主人公のスプライトを作成する。

auto spriteRunner = Sprite::create("runner.png");
spriteRunner->setScale(2);
// 主人公の位置を設定する。
spriteRunner->setPosition(Point(winSize.width / 5 * 1 , winSize.height / 4));

PhysicsBody* charaPb = PhysicsBody::createCircle(40);
// 重さを設定する
charaPb->setMass(100.0f); // 重さを指定(ここが無いと後で飛ばせなくなる)
spriteRunner->setPhysicsBody(charaPb);

// デフォルトのマテリアルを作成する。
auto material = PHYSICSBODY_MATERIAL_DEFAULT;
// 密度を設定する。
material.density = 1.0f;
// 反発係数を設定する。
material.restitution = 0.1f;
// 摩擦係数を設定する。
material.friction = 10.0f;


auto materialSprintRunner = PhysicsBody::createBox(spriteRunner->getContentSize(), material);

materialSprintRunner->setDynamic(true);
// 衝突する
materialSprintRunner->setContactTestBitmask(true);
spriteRunner->setPhysicsBody(materialSprintRunner);

addChild(spriteRunner);

// ジャンプアクション
auto jumpAction = JumpBy::create(3.0f, Point(winSize.width/8 * 5, winSize.height/3 * 0), 500, 1);
spriteRunner->runAction(jumpAction);


// 2人目を生成
auto spriteRunner2 = Sprite::create("runner.png");
spriteRunner2->setFlippedX(true);
spriteRunner2->setScale(2);
spriteRunner2->setPosition(Point(winSize.width / 5 * 4 , winSize.height / 4));

PhysicsBody* charaPb2 = PhysicsBody::createCircle(40);
// 重さを設定する
charaPb2->setMass(100.0f);

spriteRunner2->setPhysicsBody(charaPb2);
addChild(spriteRunner2);
auto jumpAction2 = JumpBy::create(3.0f, Point(-winSize.width / 8 * 5, winSize.height/4 * 0 ), 500, 1);
// デフォルトのマテリアルを作成する。
auto material2 = PHYSICSBODY_MATERIAL_DEFAULT;
// 密度を設定する。
material2.density = 1.0f;
// 反発係数を設定する。
material2.restitution = 0.1f;
// 摩擦係数を設定する。
material2.friction = 10.0f;
auto materialSprintRunner2 = PhysicsBody::createBox(spriteRunner2->getContentSize(), material2);
materialSprintRunner2->setDynamic(true);
materialSprintRunner2->setContactTestBitmask(true);
spriteRunner2->setPhysicsBody(materialSprintRunner2);

spriteRunner2->runAction(jumpAction2);


// 当たり判定
auto listener= EventListenerPhysicsContact::create();
listener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);

// ディスパッチャーに登録
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);

// あたり判定でキャラクターをタグで取得するためにタグ付け
spriteRunner->setTag(1);
spriteRunner2->setTag(2);

// アクションにタグ付け
jumpAction->setTag(1);
jumpAction2->setTag(2);

return true;
}

bool HelloWorld::onContactBegin(PhysicsContact& contact){
// スプライトをタグから取得
auto runner1 = this->getChildByTag(1);
auto runner2 = this->getChildByTag(2);

// アニメーションを止める
runner1->stopActionByTag(1);
runner2->stopActionByTag(2);


return true;
}


// 物理空間初期化
bool HelloWorld::initPhysics()
{
// 床を作成する。
auto wallBottom = Node::create();
// 床をシーンに追加する。
addChild(wallBottom);

// アンカーポイントを左下にする。
wallBottom->setAnchorPoint(Vect::ZERO);
// 位置をを(0,0)にする。
wallBottom->setPosition(Vect::ZERO);
// 左右方向に大きなサイズにする。
wallBottom->setContentSize(Size(4292967295, 57 * 5));

// デフォルトのマテリアルを作成する。
auto material = PHYSICSBODY_MATERIAL_DEFAULT;
// 密度を設定する。
material.density = 1.0f;
// 反発係数を設定する。
material.restitution = 0.0f;
// 摩擦係数を設定する。
material.friction = 0.0f;
// 剛体を作成する。
auto body = PhysicsBody::createBox(wallBottom->getContentSize(), material);
// 重力の影響を受けない。
body->setDynamic(false);
// 衝突する。
body->setContactTestBitmask(false);

// スプライトに剛体を関連付ける。
wallBottom->setPhysicsBody(body);

return true;
}




void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
return;
#endif

Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}




ランキング参加してます。
↓ポチッと協力していただけると嬉しいです♪


にほんブログ村 ライフスタイルブログ 心地よい暮らしへ
スポンサーサイト


このエントリーをはてなブックマークに追加

テーマ : iPhoneアプリ
ジャンル : 携帯電話・PHS

コメントの投稿

非公開コメント

博多でオススメのお店
プロフィール

ぽてぴ×ひろし

Author:ぽてぴ×ひろし
訪問ありがとうございます。
しゅふ友2人(主婦&主夫)で始めたブログです。
日々の出来事、つぶやき、お役立ち情報などなど書いていこうと思ってます。

ブログを書いてる人
その①主婦ぽてぴ
 主婦歴:8年
 家族:旦那クンと猫2匹
 得意技:怪しい創作料理
     家事手抜き技の探求
 趣味:アンチエイジング奮闘

その②主夫ひろし
 主婦歴:1か月
 家族:嫁サンと2人暮らし
 得意技:けさ固め、体落とし
 趣味:焼酎を飲みながらプリン
    体と奮闘中

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
楽天
オススメサイト
ブログランキング
↓ポチッ!お願いします♪
iPhoneアプリ
はかたべんももたろう
カテゴリ: 教育, エンターテインメント
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa

Horror Surprised !! 〜どきどきホラー!
カテゴリ: エンターテインメント, ライフスタイル
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa
計画タイマーまねじめん
カテゴリ: ライフスタイル, フード/ドリンク
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa
5文字に思いを込めろ!
カテゴリ: エンターテインメント, ライフスタイル
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa
TOEIC攻略タイマー
カテゴリ: 教育, ビジネス
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa
お買い物べんり電卓〜直感で簡単操作〜
カテゴリ: ライフスタイル, フード/ドリンク
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa


動画:お買い物べんり電卓〜直感で簡単操作〜

脳トレとぅんとぅん
カテゴリ: ゲーム, 教育, 教育, スポーツ
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa


円スケジュール-1日を素早く計画
カテゴリ: ライフスタイル, 仕事効率化
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa


にこにこサッカー
カテゴリ: ゲーム, エンターテインメント, アクション, スポーツ
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa


Todoリスト-優先度で簡単仕分け
カテゴリ: 仕事効率化, ビジネス
価格: 無料 (掲載時)
販売元: Hiroshi Nakagawa


Twitter
食品&飲料
RSSリンクの表示
電子書籍
amazon
ヘルス&ビューティー
リンク
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。