libro
www.tuyano.com
初心者のためのCocos2d-xゲームプログラミング入門

物理エンジンを使おう (3/4)

作成:2015-06-20 11:34
更新:2015-06-20 11:34

■物理マテリアルについて

これで基本的な物理演算は行えるようになりました。が、PhysicsWorldで設定したのは、単に重力と速度の設定だけです。各スプライトには、物理演算による動きをONにする、とかいった基本的な機能のON/OFF設定ぐらいしかありません。

現実世界ではすべて同じ重力の影響を受けていても、物によってその動きは変わってきます。それは、例えばそれぞれの物質の密度であったり、ぶつかった時の跳ね返る力や、他のものと触れている時の摩擦の大きさなどがそれぞれの物質ごとに異なっているからです。ボーリングのボールとバスケットボールは、落とすと同じように弾むわけがありません。

こうしたそれぞれのスプライトに物理的な特性を設定するには、単にPhysicsBodyを組み込んだだけではだめです。ではどうするのか?というと、「物理マテリアル(PhysicsMaterial)」というものを使うのです。

マテリアルというのは、モデルの表面に関する情報を扱うもので、3Dの世界でよく用いられていますね。物理マテリアルは、剛体の表面(外部と接する部分)に物理的な特性を追加します。

これを利用するには以下のような手順で作業をします。


1. インスタンスの作成
auto material = PHYSICSBODY_MATERIAL_DEFAULT;

インスタンスの作成はとても簡単です。Cocos2d-xには、PHYSICSBODY_MATERIAL_DEFAULTという定数として、デフォルト設定されたPhysicsMaterialが用意されています。これをそのまま利用します。


2. 物理特性の設定
material.density = 値; // 密度
material.restitution = 値; // 反発係数
material.friction = 値; // 摩擦係数
次に、PhysicsMaterialの設定を行います。この構造体には、密度、反発係数、摩擦係数といった値が用意されています。これらに値を代入していきます。


3. PhysicsBodyの作成
auto 変数 = PhysicsBody::createBox(《Size》,《PhysicsMaterial》);
auto 変数 = PhysicsBody::createCircle(《float》,《PhysicsMaterial》);
最後に、PhysicsMaterialを指定してPhysicsBodyを作成します。createBoxcreateCircleでインスタンスを作成する際、第2引数にPhysicsMaterialを指定することで、これに用意された設定値を使って剛体が作成されるようになります。


では、先ほどのサンプルに手を加え、PhysicsMaterialで物理特性の値を指定してスプライトを作成するようにしてみましょう(下リスト参照)。変数material内の値をいろいろと書き換えて動作を確認してみるといいでしょう。

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

#pragma execution_character_set("utf-8")

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::createWithPhysics();
    PhysicsWorld* world = scene->getPhysicsWorld();
    world->setGravity(Vec2(0, -500));
    world->setSpeed(1.0f);
    world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

bool HelloWorld::init()
{
    if (!Layer::init())
    {
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    Director::getInstance()->setDisplayStats(false);

    auto material = PHYSICSBODY_MATERIAL_DEFAULT;
    material.density = 1.0f;
    material.restitution = 0.1f;
    material.friction = 0.5f;

    sprite1 = Sprite::create("base.png");
    sprite1->setPosition(origin.x + visibleSize.width / 2, origin.y + 100);
    this->addChild(sprite1, 1);

    auto baseBody = PhysicsBody::createBox(sprite1->getContentSize(), material);
    baseBody->setDynamic(false);
    baseBody->setRotationEnable(false);
    sprite1->setPhysicsBody(baseBody);

    sprite1->setScaleX(2.0);
    sprite1->setRotation(10.0f);

    sprite2 = Sprite::create("character.png");
    sprite2->setPosition(origin.x + visibleSize.width / 2, origin.y + 300);
    this->addChild(sprite2, 1);

    auto charBody = PhysicsBody::createCircle(sprite2->boundingBox().size.width / 2, material);
    charBody->setMass(10.0f);
    charBody->setDynamic(true);
    charBody->setRotationEnable(true);
    sprite2->setPhysicsBody(charBody);

    return true;
}
※関連コンテンツ

「初心者のためのCocos2d-xゲームプログラミング入門」に戻る