C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: アクションゲームのマップの当たり判定


(過去ログ 100 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■59533 / inTopicNo.1)  アクションゲームのマップの当たり判定
  
□投稿者/ どん (1回)-(2011/05/30(Mon) 21:41:18)

分類:[C#] 

C#とDXライブラリを使ってVC#2008を用いてアクションゲームをつくり始めました。が,いままでSTGはつくったことがあるのですが,アクションゲームだといろんな原理がわからなくて困っています。
とりあえず,二次元配列でマップのブロックの位置を格納し,1はブロック,0は何もおかないことをあらわすことにしました。そして,キャラクターとブロックの判定をとり,位置を補正する(あたったらとめる)関数をhttp://hakuhin.jp/as/collide.html#COLLIDE_01を参考にしてつくってみました。しかし,うまくいきません。

public class Block
    {
        const int CHIP_SIZE = 40;
        const int MAX_LENGTH = 10;
        int i, j;
        static int bl_rect_x;  // 矩形x座標
        static int bl_rect_y;  // 矩形y座標
        static int bl_rect_w;  // 矩形幅
        static int bl_rect_h;  // 矩形高さ
        public static int bl_x_min; // x最小
        public static int bl_y_min;             // y最小
        public static int bl_x_max;  // x最大
        public static int bl_y_max;  // y最大
        int[,] haiti = 
            {
                { 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                { 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                { 0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,1},
                { 0,1,0,0,1,1,0,1,1,0,0,0,0,0,0,1},
                { 0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,1},
                { 0,1,0,0,1,1,0,1,1,0,0,0,0,0,0,1},
                { 0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,1},
                { 0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
                { 0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,1},
                { 0,1,1,1,1,0,1,0,1,1,1,0,0,0,1,1},
                { 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
                { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
            };
        public void DrawBlock()
        {
            for (i = 0; i < 12; i++)
            {
                for (j = 0; j < 16; j++)
                {
                    if (haiti[i, j] == 1)
                    {
                        DX.DrawBox(j * CHIP_SIZE, i * CHIP_SIZE, (j + 1) * CHIP_SIZE, (i + 1) * CHIP_SIZE, DX.GetColor(0, 255, 255), 1);
                    }
                }
            }

        }
        public string Atari(int x_max, int y_max, int x_min, int y_min)
        {
            for (i = 0; i < 12; i++)
            {
                for (j = 0; j < 16; j++)
                {
                        if (haiti[i, j] == 1)
                        {
                            bl_rect_x = j * 40;
                            bl_rect_y = i * 40;
                            bl_rect_w = 40;
                            bl_rect_h = 40;
                            bl_x_min = bl_rect_x;
                            bl_y_min = bl_rect_y;
                            bl_x_max = bl_x_min + bl_rect_w;
                            bl_y_max = bl_y_min + bl_rect_h;  
                            if (x_max < bl_x_min)
                            {
                            }
                            else if (y_max < bl_y_min)
                            {
                            }
                            else if (x_min > bl_x_max)
                            {
                            }
                            else if (y_min > bl_y_max)
                            {
                            }
                            else
                            {
                                // ブロックの上端
                                if (y_max - bl_y_min < MAX_LENGTH)
                                {
                                    return "上";
                                }

                                // ブロックの下端
                                if (bl_y_max - y_min < MAX_LENGTH)
                                {
                                    return "下";
                                }

                                // ブロックの左端
                                if (x_max - bl_x_min < MAX_LENGTH)
                                {
                                    return "左";
                                }

                                // ブロックの右端
                                if (bl_x_max - x_min < MAX_LENGTH)
                                {
                                    return "右";
                                }
                                else 
                                {
                                    return "あたってないです";
                                }
                            }
                        }
                }
            }
            return "あたってないです";
        }
    }
}


そして,動かすキャラクターのクラスで,
 public class Ship
    {
        public static int x, y;
        static int my_rect_x = -10;  // 矩形x座標(座標からのオフセット)
        static int my_rect_y = -10;  // 矩形y座標(座標からのオフセット)
        static int my_rect_w = 20;   // 矩形幅
        static int my_rect_h = 20;   // 矩形高さ
        static int my_x_min = my_rect_x + x;
        static int my_y_min = my_rect_y + y;
        static int my_x_max = my_x_min + my_rect_w;
        static int my_y_max = my_y_min + my_rect_h;
        //省略
        public void AtariPlayer(Block bl)
        {
            string atari = bl.Atari(my_x_max, my_y_max, my_x_min, my_y_min);
            if (atari == "上")
            {
                y = Block.bl_y_min - my_rect_y - my_rect_h;
            }
            else if (atari == "下")
            {
                y = Block.bl_y_max - my_rect_y;
            }
            else if (atari == "左")
            {
                x = Block.bl_x_min - my_rect_x - my_rect_w;
            }
            else if (atari == "右")
            {
                x = Block.bl_x_max - my_rect_x;
            }
            else
            {

            }
        }
    }

この処理を実行しても,キャラクターが当たったことにはなっていません。どうやって直せばいいでしょうか?

引用返信 編集キー/
■59539 / inTopicNo.2)  Re[1]: アクションゲームのマップの当たり判定
□投稿者/ やじゅ (1912回)-(2011/05/31(Tue) 00:45:33)
やじゅ さんの Web サイト
2011/05/31(Tue) 00:51:47 編集(投稿者)

No59533 (どん さん) に返信
> この処理を実行しても,キャラクターが当たったことにはなっていません。どうやって直せばいいでしょうか?

各座標のところに、Debug.WriteLineを仕組んで、値を確認してみてはどうですか

VS.NETでデバッグ・メッセージを出力するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/140debugonvs/debugonvs.html
[出力]ウィンドウが使いたくない場合、ファイルにデバッグ情報を出力する
http://www.atmarkit.co.jp/fdotnet/dotnettips/146debugonfile/debugonfile.html


引用返信 編集キー/
■59589 / inTopicNo.3)  Re[2]: アクションゲームのマップの当たり判定
□投稿者/ おのでら (2回)-(2011/06/01(Wed) 12:49:55)
おのでら さんの Web サイト
どんさんこんにちは、おのでらです。

今回の現象が発生する原因については、おそらくあたり判定処理が中途半端に終わっている(returnで戻る)せいではないかと思います。

たとえば、壁座標を(x, y)として (1, 0) と (1, 1) は壁になっていますが、その壁の間にキャラクターを置いた場合、ロジックの流れから見ると(1, 0)とのあたり判定が行われた後にキャラクターが下方向に押し戻されますが、そのタイミングではその下の(1, 1)の壁とのあたり判定は行われません。

次のフレームでは下の壁とのあたり判定が行われるようなイメージを持つかと思いますが、キャラクターが下に押し戻されていても(1, 0)の壁とのあたり判定で引っかかってしまいますのでやはり下の壁とのあたり判定は行われません。

一応一例として原因をあげましたがおそらくこれ以外にもいろいろ原因があると思います。キャラクターと壁とのあたり判定ロジックは結構面倒なところがあるので根気よく考えてみてください。まずはキャラクターが付近にある壁すべてとあたり判定できるようにしてみるところから考えてみるといいと思います。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -