質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1345閲覧

原点を正方形の真ん中に設定した時に描画をずらすべきか計算をずらすべきなのか知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/12/29 07:28

Collision関数の当たった座標に描画すると描画は左上なので計算の基準点?を画像の真ん中にすると描画での基準点は左上なのでずれてしまいます、その場合は計算で描画を補正するのか描画で補正する方がいいのかどっちがバグが出にくいのでしょうか?

/当たり判定/コメント部

/*---------------------------------------------------当たり判定----------------------------------------------------------------*/ void Collision_Update() { std::optional<Position> px1, px2, px3, px4; bool xR ,xL; xR = xL = false; Position now_x[2];//今いる座標 Position now_y[2];//今いる座標 Position future_x[2];//移動先 座標 Position future_y[2];//移動先 座標 now_x[0].x = pos->x + ((CELL) / 2); now_x[0].y = pos->y; now_x[1].x = pos->x + ((CELL) / 2); now_x[1].y = pos->y + (CELL); now_y[0].x = pos->x + ((CELL) / 2); now_y[0].y = pos->y + ((CELL) / 2); now_y[1].x = pos->x + ((CELL) / 2); now_y[1].y = pos->y + ((CELL) / 2); /*未来座標配列に現在座標をコピーする*/ future_x[0].x = now_x[0].x + move->x; future_x[0].y = now_x[0].y + move->y; future_x[1].x = now_x[1].x + move->x; future_x[1].y = now_x[1].y + move->y; future_y[0].x = now_y[0].x + move->x; future_y[0].y = now_y[0].y + move->y; future_y[1].x = now_y[1].x + move->x; future_y[1].y = now_y[1].y + move->y; for(int y = 0; y < 100; y++){ for(int x = 0;x < 100; x++){ if(Find_Map(x,y) == true){ // ofs<<"x y: "<<x <<" , "<<y<<std::endl; /*右移動*/ if(Direction->x > 0){ std::optional<Position> pt1, pt2; pt1 = cross_pos(now_x[0], future_x[0], Position(x * CELL + (CELL / 2), y * CELL), Position((x * CELL) + (CELL / 2), ((y + 1) * CELL))); pt2 = cross_pos(now_x[1], future_x[1], Position(x * CELL + (CELL / 2), y * CELL), Position((x * CELL) + (CELL / 2), ((y + 1) * CELL))); if (pt1 != std::nullopt) { px1 = pt1; ofs << " px1: " << px1->x << " , " << px1->y << std::endl; } if (pt2 != std::nullopt) { px2 = pt2; ofs << " px2: " << px2->x << " , " << px2->y << std::endl; } }else if(Direction->x < 0){ std::optional<Position> pt1,pt2; /*左移動 0になる原因*/ pt1 = cross_pos(now_x[0], future_x[0], Position((x * CELL) + (CELL / 2), y * CELL), Position(x * CELL + (CELL / 2), (y + 1) * CELL)); pt2 = cross_pos(now_x[1], future_x[1], Position((x * CELL) + (CELL / 2), y * CELL), Position(x * CELL + (CELL / 2), (y + 1) * CELL)); if(pt1 != std::nullopt) { px3 = pt1; } if (pt2 != std::nullopt) { px4 = pt2; } // ofs << " px4: " << px4->x << " , " << px4->y << std::endl; } } } } /*→に移動するときの補正*/ if (Direction->x > 0) { Position v3_x; Position v4_x; float lv1 = 0; float lv2 = 0; Position v1_x(px1->x - now_x[0].x, px1->y - now_x[0].y); Position v2_x(px2->x - now_x[1].x, px2->y - now_x[1].y); lv1 = sqrt((v1_x.x * v1_x.x) + (v1_x.y * v1_x.y)); lv2 = sqrt((v2_x.x * v2_x.x) + (v2_x.y * v2_x.y)); if ((lv1 <= lv2) && (lv1 != 0)) { pos->x = (px1->x - (CELL + CELL / 2)); } else if ((lv1 > lv2) && (lv2 != 0 )) { pos->x = (px2->x - (CELL + CELL / 2)); } else { pos->x += move->x; } } /*←に移動するときの補正*/ if(Direction->x < 0) { Position v3_x; Position v4_x; float lv1 = 0; float lv2 = 0; Position v1_x(px3->x - now_x[0].x, px3->y - now_x[0].y); Position v2_x(px4->x - now_x[1].x, px4->y - now_x[1].y); lv1 = sqrt((v1_x.x * v1_x.x) + (v1_x.y * v1_x.y)); lv2 = sqrt((v2_x.x * v2_x.x) + (v2_x.y * v2_x.y)); if((lv1 < lv2) && (lv1 != 0)){ pos->x = px3->x + (CELL / 2); }else if((lv1 >= lv2) && (lv2 != 0)){ pos->x = px4->x + (CELL / 2); }else{ pos->x += move->x; } } } /*-------------------------------------------------------------------------------------------------------------------------*/ /*-----------------------------計算----------------------------*/ void const Update() { key_Update(); Move(); Collision_Update(); //DrawFormatString(0, 0, GetColor(255, 255, 255), "Pos: %.2f , %.2f", pos->x, pos->y, true); DrawFormatString ( 0, 0, GetColor ( 255, 255, 255 ), "Pos: %.2f , %.2f", pos->x, pos->y, true ); //DrawFormatString(0, 32, GetColor(255, 255, 255), "move: %.2f , %.2f", move->x, move->y, true); DrawFormatString(0,32,GetColor(255,255,255),"move: %.2f , %.2f",move->x,move->y,true); //DrawFormatString(200, 200, GetColor(255, 255, 255), "block: %.2f , %.2f", block.x, block.y, true); // DrawFormatString(200, 200, GetColor(255, 255, 255), "block: %.2f, %.2f", block.x, block.y, true); //DrawFormatString(400, 400, GetColor(255, 255, 255), "%d", block.x, block.y, true); // DrawFormatString(200,0,GetColor(255,255,255),"Frame: %d",Fps::now(),true); // DrawFormatString(300, 0, GetColor(255, 255, 255), "move.x: %.2f", move->x, true); // DrawFormatString(450, 0, GetColor(255, 255, 255), "move.y: %.2f", move->y, true); DrawFormatString(450, 100, GetColor(255, 255, 255), "isGround: %d", isGround, true); //DrawFormatString(100, 100, GetColor(255, 255, 255), "Right", true); // DrawFormatString(100, 100, GetColor(255, 255, 255), "%d",dd, true); } /*-------------------------------------------------------------------------------------------------*/ /*----------------------------描画-----------------------------*/ void const Draw_Update() { //DrawGraph(7 * CELL ,(5 * CELL) - 32,map_graph[5],true); for (int y = 0; y < 100; y++) { for (int x = 0; x < 100; x++) { short int m = map[ y ][ x ]; switch ( m ) { case 1: DrawGraph(x * CELL,y * CELL,map_graph[0],true ); break; case 5://未実装 // DrawGraph( x * CELL, y * CELL, map_graph[ 5 ], true ); // ofs << x << " , " << y << std::endl; // block.x = (int)x * CELL; // block.y = (((int)y * CELL)); break; } /* if (map[y][x] == 1) { DrawGraph(x * 64,y * 64,map_graph[0],true); } else if (map[y][x] == 2)//まだない { DrawGraph(x * 64, y * 64, map_graph[0], true); } */ } } /*プレイヤーの反転処理*/ if (rev == 1) { // DrawTurnGraph((int)pos->x, (int)pos->y, player_graph[aniClip], true);//プレイヤー } if(rev == 0) { //DrawGraph((int)pos->x, 540, player_graph[aniClip], true);//プレイヤー //DrawGraph((int)pos->x, 450, player_graph[aniClip], true);//プレイヤー DrawGraph((int)pos->x , (int)pos->y, player_graph[aniClip], true);//プレイヤー } } /*------------------------------------------------------------*/ void const Debug_Draw() { } };

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ゲームなどのオブジェクトの原点をどこにおくか?ということですよね?
設計次第だと思いますが、一律に左上や中央固定とかではなく、オブジェクトごとに一番都合の良い点を原点として各オブジェクトに持たせ、そこからサイズなどを加味して計算するほうがいいと思います。

左上にするのは画面に描画するときの都合ですが、Collision判定以外にもスケールや回転などが必要になった場合に左上だと位置がずれてしまいますし余計な計算が必要になります。
余計な計算は設計段階で不要にしておいたほうがバグは少なくなるでしょう。

シューティングゲームのようにオブジェクトが2D平面上を縦横無尽に動くのであれば、大抵はオブジェクトの真ん中になるでしょうし、マリオみたいな2Dゲームなら足元(W/2, H)のほうが拡縮しても地面にめり込んだりしないから都合がいいでしょう。

投稿2019/12/30 02:06

編集2019/12/30 02:54
toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問