• チュートリアル
  • 機能解説
  • リファレンス
  • 初代Altseedはコチラ

    • 機能解説
    • エンジン
    • ノード
    • 画像
    • 文字
    • マテリアル
    • カメラ
    • ポストエフェクト
    • サウンド
    • ログ
    • プロファイラ
    • ファイル
    • ファイルパッケージ
    • ジョイスティック
    • キーボード
    • マウス
    • カーソル
    • シリアライズ
    • 衝突判定
    • 図形ノード
    • トランジション
    • メディアプレイヤー
    • Altseed2.Tools (.NETツール)

    衝突判定

    Altseed2では物理演算を用いて,2Dの衝突判定を行う機構が備わっています。

    Colliderクラス

    Colliderクラスは自身のメンバの情報をもとに他Colliderのインスタンスとの衝突の有無を判定します。
    Colliderと衝突判定の種類は以下の通りです。

    Collider 衝突判定のタイプ 使用するメンバ
    CircleCollider 円形 中心,半径
    PolygonCollider 多角形 各頂点の座標
    RectangleCollider 短形 左上の座標,サイズ(縦・横)
    EdgeCollider 線分 端点1,端点2

    Colliderとの衝突判定はGetIsCollidedWith(Collider)メソッドを使用します。
    指定したコライダと衝突していたらtrue,衝突していなかったらfalseを返します。

    ColliderNodeクラスとCollisionManagerNodeクラス

    この2つのクラスによって,コライダの衝突判定を自動で行う事が出来ます。

    ColliderNodeクラス

    このクラスはColliderクラスを内部に持っています。
    また,この派生クラスにCircleColliderNode,PolygonColliderNode, RectangleColliderNode, EdgeColliderNodeクラスがあり,それぞれCircleCollider, PolygonCollider, RectangleCollider, EdgeColliderクラスのインスタンスを内部に持っています。
    これらのクラスのプロパティを通して,内部コライダのメンバの操作を行う事が出来ます。

    Important

    このクラスは,衝突判定を行いたいノード(シューティングゲームで言う自機や弾となるノード)の子ノードとして使用される必要があります。

    CollisionManagerNodeクラス

    このクラスではColliderNodeクラスのインスタンスが自動的に登録され,GetIsCollidedWith(Collider)メソッドを自動的に実行します。

    Tip

    GetIsCollidedWith(Collider)メソッドによる衝突判定は,同じColliderNodeの組み合わせに対して1フレームにつき1度しか行われません。

    Important

    このクラスは衝突判定を行いたいノードの親ノードの子として使用される必要があります。
    また,1つのノードに対して,CollisionManagerNodeクラスのインスタンスは1つしか子として持つ事が出来ません。(登録しようとした場合は例外がスローされます。)

    実装の形式

    ColliderNodeクラスとCollisionManagerNodeクラスはそれぞれ以下の図のような関係でなければなりません。

    Caution

    ColliderNodeの自動登録には,シーンとなるノードに対して,CollisionManagerNodeが子ノードであり,かつColliderNodeが孫ノードである事が重要です。
    それ以外の場合におけるColliderNodeの自動的な追加/削除は発生しません。

    Structure

    Note

    衝突判定を行うノードがICollisionEventReceiverインターフェイスを実装している場合,

    • 衝突の開始
    • 衝突の継続
    • 衝突の終了

    においてそれぞれ対応したメソッドが呼び出されます。

    以上の点を踏まえた実装は以下のサンプルコードの通りです。

    using Altseed2;
    
    using System;
    
    namespace Sample
    {
        class Collision
        {
            static void Main(string[] args)
            {
                // Altseed2 を初期化します。
                Engine.Initialize("Collision", 640, 480);
    
                // 衝突判定が行われるノードの親ノードを作成します。
                var scene = new Node();
    
                // コライダを自動処理するノードをシーンに登録します。
                scene.AddChildNode(new CollisionManagerNode());
    
                // 衝突判定を持つスプライトノードを生成します。
                var node1 = new CollidableSprite()
                {
                    Position = new Vector2F(0, 100)
                };
    
                // 衝突時のイベントを実行する衝突判定を持つスプライトノードを生成します。
                var node2 = new EventRaisedCollidableSprite()
                {
                    Position = new Vector2F(300, 100)
                };
    
                // エンジンにノードを追加します。
                scene.AddChildNode(node1);
                scene.AddChildNode(node2);
                Engine.AddNode(scene);
    
                // メインループ。
                // Altseed のウインドウが閉じられると終了します。
                while (Engine.DoEvents())
                {
                    // 右側に移動させる
                    node1.Position += new Vector2F(5, 0);
    
                    // Altseed を更新します。
                    Engine.Update();
                }
    
                // Altseed の終了処理をします。
                Engine.Terminate();
            }
        }
    
        // 衝突判定が行われるノードのクラス
        class CollidableSprite : SpriteNode
        {
            // 円形コライダを持つノード
            private readonly CircleColliderNode colliderNode = new CircleColliderNode();
    
            // コンストラクタ
            public CollidableSprite()
            {
                // テクスチャを読み込みます。
                Texture = Texture2D.Load(@"TestData/IO/AltseedPink256.png");
    
                // 半径を設定します。
                colliderNode.Radius = Texture.Size.X / 2;
    
                // 中心を設定します。
                CenterPosition = Texture.Size / 2;
    
                // コライダを登録します。
                AddChildNode(colliderNode);
            }
        }
    
        // 衝突時の内容を実装できるクラス
        class EventRaisedCollidableSprite : CollidableSprite, ICollisionEventReceiver
        {
            // 衝突が開始された時に実行されます。
            void ICollisionEventReceiver.OnCollisionEnter(CollisionInfo info)
            {
                Color = new Color(255, 50, 50);
            }
    
            // 衝突が継続している時に実行されます。
            void ICollisionEventReceiver.OnCollisionStay(CollisionInfo info)
            {
                Angle++;
            }
    
            // 衝突が解除された時に実行されます。
            void ICollisionEventReceiver.OnCollisionExit(CollisionInfo info)
            {
                Color = new Color(255, 255, 255);
            }
        }
    }
    

    結果

    衝突を開始したときに色が赤くなり,以降衝突している間回転します。
    衝突終了時には色が戻ります。

    衝突範囲の描画

    ColliderVisualizeNodeFactory.Create(ColliderNode)を使用することで,衝突領域を描画できるノードを取得できます。

    Important

    得られたノードを,Node.AddChildNode(Node)で登録しなければ衝突判定の視覚化は行われません。 生成元のColliderNodeをCollisionManagerNodeの子にすることで,描画範囲を衝突範囲に同期することが出来ます。

    Caution

    衝突範囲の描画の同期は,元となるColliderNodeがCollisionManagerNodeの管理下にある必要があります。

    使い方は以下のサンプルコードを参考にしてください。

    using Altseed2;
    
    namespace Sample
    {
        class ColliderVisualization
        {
            static void Main(string[] args)
            {
                // Altseed2 を初期化します。
                Engine.Initialize("Collision", 640, 480);
    
                // 衝突判定が行われるノードの親ノードを作成します。
                var scene = new Node();
    
                // コライダを自動処理するノードをシーンに登録します。
                scene.AddChildNode(new CollisionManagerNode());
    
    
                // 衝突判定を持つSpriteNodeを生成します。
                var texture = Texture2D.Load(@"TestData/IO/AltseedPink256.png");
                var sprite = new SpriteNode()
                {
                    Position = new Vector2F(200f, 200f),
                    Scale = new Vector2F(0.5f, 0.5f),
                    Texture = texture,
                    CenterPosition = texture.Size / 2,
                };
    
                // 円形コライダノードを生成します。
                var collider = new CircleColliderNode()
                {
                    Radius = texture.Size.X / 2,
                };
    
                // colliderの衝突判定を視覚化できるノードを生成します。
                var visualizer = ColliderVisualizeNodeFactory.Create(collider);
    
                // エンジンにノードを追加します。
                scene.AddChildNode(sprite);
                sprite.AddChildNode(collider);
                collider.AddChildNode(visualizer);
                Engine.AddNode(scene);
    
                // メインループ。
                // Altseed のウインドウが閉じられると終了します。
                while (Engine.DoEvents())
                {
                    // Altseed を更新します。
                    Engine.Update();
                }
    
                // Altseed の終了処理をします。
                Engine.Terminate();
            }
        }
    }
    

    このコードを実行すると以下のように円形の当たり判定が赤色で示されます。

    Visualization

    Copyright © 2020 Altseed .