基本的なロジック/計算に取り掛かると、答えは「いいえ」です。トリックを見逃していません。少なくとも計算に関しては、各ターゲットを一度に 1 つずつチェックする方法を見つけたことがありません。多くの方法でコードをよりきれいにすることができます。「bool IsIn( int x, int y )」メソッドを公開する GuiElement クラスを使用できます。次に、大きなケースステートメントは次のようになります。
bool handle_mouse_leftClick(int x, int y, SDL_Surface *button)
{
if (Button1.IsIn( mouseX, mouseY )
{
// do this
}
else if (Button2.IsIn( mouseX, mouseY ))
{
// do that
}
else
{
return false;
}
}
次に、リストまたはテーブルを使用して量のコードをさらに減らすことができます。
int handle_mouse_leftClick(int x, int y, SDL_Surface *button)
{
for (unsigned int i = 0; i < buttonList.size(); i++
{
if (buttonList[i].IsIn( mouseX, mouseY ))
{
return i; // return index of button pressed
}
return -1; // nothing pressed
}
}
しかし、それでも最終的には各長方形を一度に 1 つずつ調べています。
カップルの注意事項:
各アイテムのヒットボックスをチェックするのに実際の計算上のオーバーヘッドはあまりないと思います - あなたが非常に高いフレームレートでそれをしているのでない限り.
確かに、ある種の空間インデックス (画面上のボタンの位置によって編成された b ツリーまたはクアッド ツリーなど) を使用してチェックを最適化することはできますが、#1 を参照してください。;-)
10 個または 15 個のボタン/コントロールの代わりに何千ものボタン/コントロールがある場合は、#1 が当てはまらないため、おそらく #2 を実行する必要があります。
** * ** * ** *アップデート* ** * ** * ****
これに使用できるクラスの簡単なサンプルを次に示します。.h と main.cpp に関する限り、典型的なアプローチは、ヘッダーを「Button.h」に配置し、実装 (コード) を「Button.cpp」に配置することですが、これを main の先頭に配置することもできます。 .cpp を使用して開始します。クラス定義にすべてのロジックが含まれています。
私が実際に新しいコードを書いていないことに気付くでしょう。「IsIn()」テストはあなたの論理そのものです。クラスに合わせて変数名を変更しただけです。そして、既に 1 つのボタンがあるので、そのボタンをレンダリングするコードを Render() メソッドで再利用できると思います。
そして最後に、 に慣れていない場合は、リスト/ベクトルを作成する必要はまったくありません。ボタンをレンダリングするコードは、単に「okButton.Render()」を呼び出し、続いて「cancelButton.Render()」を呼び出すことができます。
「ボタン」クラスのサンプル:
class Button
{
private:
int m_x, m_y; // coordinates of upper left corner of control
int m_width, m_height; // size of control
public:
Button(int x, int y, int width, int height, const char* caption)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
// also store caption in variable of same type you're using now for button text
}
bool IsIn( int mouseX, int mouseY )
{
if (((mouseX > m_x) && (mouseX < m_x + m_width))
&& ((mouseY > m_y) && (mouseY < m_y + m_height ) ) ) {
return true;
} else {
return false;
}
}
void Render()
{
// use the same code you use now to render the button in OpenGL/SDL
}
};
次に、それ/それらを作成します(リストアプローチを使用):
Button okButton( 10, 10, 100, 50, "OK" );
buttonList.push_back( okButton );
Button cancelButton( 150, 10, 100, 50, "Cancel" );
buttonList.push_back( cancelButton );
そしてあなたのレンダリングループで:
void Update()
{
for (unsigned int i = 0; i < buttonList.size(); i++
{
buttonList[i].Render();
}
}