0

2P Connect 4 ゲームを作成中ですが、トークンを等間隔に配置するための円形領域を取得できないようです。

各円の位置を初期化するコードは次のとおりです。

POINT tilePos;

for (int i = 0; i < Board::Dims::MAXX; ++i) 
{
    tileXY.push_back (std::vector<POINT> (Board::Dims::MAXY)); //add column

    for (int j = 0; j < Board::Dims::MAXY; ++j)
    {
        tilePos.x = boardPixelDims.left + (i + 1./2) * (boardPixelDims.width / Board::Dims::MAXX);
            tilePos.y = boardPixelDims.top + (j + 1./2) * (boardPixelDims.height / Board::Dims::MAXY);

        tileXY.at (i).push_back (tilePos); //add circle in column
    }
}

POINTs, の2D ベクトルを使用しtileXYて位置を格納します。ボードは、幅 7 円、高さ 6 円であることを思い出してください。

私の論理では、最初の円は (X の場合) 次の場所から始まります。

left + width / #circles * 0 + width / #circles / 2

width / #circlesこれは、円の数が少ない場合に簡単に想像できます。

後で、次のように円を描きます。

for (const std::vector<POINT> &col : _tileXY)
{
    for (const POINT pos : col)
    {
        if (g.FillEllipse (&red, (int)(pos.x - CIRCLE_RADIUS), pos.y - CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS) != Gdiplus::Status::Ok)
            MessageBox (_windows.gameWindow, "FillEllipse failed.", 0, MB_SYSTEMMODAL);
    }
}

これらのループは、ベクトルの各要素を繰り返し処理し、各円を赤で描画します (現時点で目立つように)。int 変換は、関数呼び出しのあいまいさを解消するためのものです。ブラシの後の最初の 2 つの引数は左上隅で、CIRCLE_RADIUS50 です。

問題は、私のボードが次のようになっていることです (少し目が痛い場合は申し訳ありません)。

円が上に離れすぎています。

ご覧のとおり、円は上と左に行き過ぎています。それらも小さすぎますが、簡単に修正できます。一部の int を double に変更しようとしましたが、最終的にこれが実際のパターンに最も近いものになりました。位置の拡張式 ((i + 1./2) の拡張) も同様に見えます。

細部を見逃したのでしょうか、それとも私のロジック全体が間違っているのでしょうか?

編集: 要求に応じて、次のように入力します:

tilePos.x: POINT (Windows API のもの、使用される型は LONG)
boardPixelDims.*: double
Board::Dims::MAXX/MAXY: 列挙値 (整数、それぞれ 7 と 6 を含む)

4

2 に答える 2

2

CIRCLE_SIZE が半径または直径として意図されているかどうかに応じて、FillEllipse 呼び出しで 2 つのパラメーターが間違っているようです。直径の場合は、場所をpos.x - CIRCLE_SIZE/2およびに設定する必要がありpos.y - CIRCLE_SIZE/2ます。半径の場合、高さと幅のパラメーターはそれぞれ、CIRCLE_SIZE ではなく 2*CIRCLE_SIZE にする必要があります。

更新 - 変数名を CIRCLE_RADIUS に変更したため、後者のソリューションが明らかに正しいものになりました。

于 2012-05-02T00:33:22.970 に答える
0

形状に関連する関数が取る引数を覚える最も簡単な方法は、常に長方形で考えることです。FillEllipse は、楕円を描画して、指定した長方形を塗りつぶします。x、y、幅、高さ。

練習するための簡単な実験は、呼び出しを FillRect に変更し、すべてを適切に配置してから、それらを FillEllipse に変更することです。

于 2012-05-05T05:09:10.373 に答える