====== プレイ画面を作っていくぅ ======
前回まででついに、前準備とゲームとしてのひな型ができたと思う。(基本的なゲームの状態移行)\\
現在はプレイ画面に移行したときに、文字で"プレイ画面"って出てるだけなので、とりあえずボード(タイルの並び)が表示されるところまで作ろう\\
==== ボードとタイルの導入 ====
ボードとタイルは、コンソール版で作ったやつを使っていく。\\
まったく一緒のものを使ってつくっていく。\\
const int BOARD_WIDTH = 4;
const int BOARD_HEIGHT = 4;
const int BLANK_POS = 16;
struct Board
{
// 行 列
int tile[BOARD_HEIGHT][BOARD_WIDTH];
};
後はコンソールで、文字で表示していたものを、どうグラフィックで表示するかって話になる。\\
とりあえず、BOARD_WIDTH xBOARD_HEIGHT = 4x4で、タイルっぽい矩形(四角)を表示する処理を書いてみようか。\\
ちなみに、キャラクターのサイズはファミコンのキャラが8x8, 16x16などの8の倍数規定だったこともあり、8の倍数で指定することが多い(画面のサイズも2の倍数とか8の倍数のことが多いよね)\\
タイルのサイズを128ぐらいで指定してみよう(128 x 4 = 512)。そうすると縦横に512x512の画面サイズが必要となる。\\
* Window::Resize({幅, 高さ})
で、ウィンドウの大きさを、指定した大きさに変更できるので、Mainのループに入る前の初期設定するときに大きさを、タイルに合わせて変えてあげよう!\\
//タイル1枚のサイズ 幅、高さ
const Size TILE_SIZE = { 128, 128 };
//windowの大きさ 4x {128, 128} 縦横同じなのでどっちかかけてやる
const Size WSIZE = BOARD_WIDTH * TILE_SIZE;
void Main()
{
//省略 背景書いたり、フォントアセット登録したりの次くらい
Window::Resize(WSIZE);
=== 実行例 ===
実行したときにウィンドウサイズが512x512になっていればOK\\
{{:game-engineer:classes:2023:something-else:summertime-special-cource:slidetitle.png?400|}}
大きさのアジャストされたタイトル画面
ついでにデバッグするたびに、スタートボタンを押すのはめんどくさいので、__初期設定のstateをPLAYにしておこう__!\\
当然だけど、PLAY画面から始まるようになるよ\\
==== タイルの描画 ====
次はタイルを書いてみよう!\\
{{:game-engineer:classes:2023:something-else:summertime-special-cource:recta.png?400|}}
Siv3DのRect型は、矩形の左上の座標と幅と高さ(正方形の場合はどっちか一方)を指定して.draw()してやると、矩形を描画してくれる。\\
2重ループを使って、うまいことRect型を作ってみよう\\
ちょっと、プログラム的には無駄が多いけどstruct Boardに、Rectをタイル数分作ってあげよう(本当にタイルを収める枠を作る感じ)\\
struct Board
{
// 行 列
int tile[BOARD_HEIGHT][BOARD_WIDTH];
Rect tileRec[BOARD_HEIGHT][BOARD_WIDTH];
};
この枠に、実際の描画座標を割り当ててやる\\
ボードを初期化数関数InitBoardで、ついでにやってしまおう!\\
void InitBoard(Board& _board)
{
for (int j = 0; j < BOARD_HEIGHT; j++)
{
for (int i = 0; i < BOARD_WIDTH; i++)
{
_board.tile[j][i] = j * BOARD_WIDTH + i + 1; //[j][i] = [列][行]の位置のタイル番号
_board.tileRec[j][i] = Rect{ { X座標の計算, Y座標の計算}, 幅(高さ) };
}
}
}
PlayDrawとPlayUpdateの処理には、Boardのデータが必要となる。\\
それらの関数を、Board型の引数をとるように書き換える。\\
省略
void TitleUpdate();
void TitleDraw();
void PlayUpdate(Board& _board);
void PlayDraw(Board& _board);
void ClearUpdate();
void ClearDraw();
省略
void PlayUpdate(Board& _board)
{
}
void PlayDraw(Board& _board)
{
// 背景の色を設定する | Set the background color
Scene::SetBackground(Palette::Lemonchiffon);
//StringはSiv3Dだけでつかえる stringの上位互換型
String PlayStr = U"プレイ画面";
FontAsset(U"TITLE_FONT")(PlayStr).drawAt(Scene::Center(), Palette::Cadetblue);
}
省略
んで、MainでBoard型の変数を作ってやって、初期化して、実際にPlayUpdateとPlayDrawに渡してゆくぅ\\
void Main()
{
//タイトル画面とスタートボタンのフォント(ンでそのままほかのシーンに使いまわし)
FontAsset::Register(U"TITLE_FONT", FontMethod::SDF, 40, Typeface::Bold);
FontAsset::Register(U"BUTTON_FONT", FontMethod::SDF, 20, Typeface::Mplus_Heavy);
Window::Resize(WSIZE);
Board myboard;
InitBoard(myboard);
while (System::Update())
{
switch (state)
{
case TITLE:
TitleUpdate();
TitleDraw();
break;
case PLAY:
PlayUpdate(myboard);
PlayDraw(myboard);
break;
case CLEAR:
ClearUpdate();
ClearDraw();
break;
case GAMEOVER:
break;
default:
break;
}
}
}
次に、PlayDrawをInitBoardで作った枠を描画できるようにdrawFrameで輪郭を描画するよう変更する\\
**drawFrame(枠内側の太さピクセル数, 枠外側の太さピクセル数, 色);**\\
実際に書き換えてゆくぅ、これはこのまま書けばよい\\
void PlayDraw(Board& _board)
{
// 背景の色を設定する | Set the background color
Scene::SetBackground(Palette::Lemonchiffon);
//StringはSiv3Dだけでつかえる stringの上位互換型
String PlayStr = U"プレイ画面";
FontAsset(U"TITLE_FONT")(PlayStr).drawAt(Scene::Center(), Palette::Cadetblue);
for (int j = 0; j < BOARD_HEIGHT; j++)
{
for (int i = 0; i < BOARD_WIDTH; i++)
{
_board.tileRec[j][i].drawFrame(2, 0, Palette::Red);
}
}
}
描画処理がうまくいくとこんな感じに表示される。\\
{{:game-engineer:classes:2023:something-else:summertime-special-cource:20230804-175753-041.png?400|}}
タイル枠の表示
;#;
[[game-engineer:classes:2023:something-else:summertime-special-cource:slidepuzle-siv3d-4|その4 プレイ画面の作成2]]
;#;