実は前回の日記の後にzxcさんが随分と書き換えてくれて、ファイル分割まで行ってくださいました。 が、それを理解する頭が無かったようで、放棄していました
zxcさん申し訳ないです。
で、だ。 先ほど20分ほどコードを見返して当時自分が何してたか思い出してみて、とりあえずゲーム自体(実際に遊ぶ所)ってのはそれらしく見えていたので、タイトル、オプション、等の
画面「遷移」をさせなければいけません、ISLeさんの指摘は「個々を抽象化し、独立させること」です。
つまりコレは何を意味するんだ、と 。。。相変わらず分からん^^; と言うか抽象化するためにどのようにコーティングすればいいか分からない所理解出来ていないということでしょうISLe さんが書きました:一例としては、Ball_tの中で世界の端を判定しているので、ステージの大きさや形がBall_tに依存しています。
反射するかどうかも含めてボールの挙動を決めるのはボール自身。
外部から与えるのは挙動を決めるヒントのみであるべき。
ということを考えるのが抽象化です。
そうやって抽象化を進めると、壁もブロックもそれ自身が独立して存在できるようになります。
あらゆるオブジェクトが同時に並行に存在することができるよう(な仕組み)になります。
#そうするとプログラムのどこからでも作っていけるようになるので開発がしやすくなります。
フローチャートは全体としての状態の変化を表すもので、オブジェクトの構造を表すものではありません。
カタログから想像でモノを作るのは容易ではありませんから、きちんと設計図(に相当するもの)を準備しましょう。
ただ行動せにゃ何も始まらんので、とりあえずこの一例に習い、Ball_tで判定していた世界の端をField_tで判定させてみました。
前
Ball_t Update
void Ball_t::Update()
{
//壁際では跳ね返るよね
if (x[0] get_x(), ball->get_y(), ball->get_r(), bar->get_x(), bar->get_y(), bar->get_rect_x(), bar->get_rect_y());
for (int i = 0; i get_flag(i, k))
{
ball_block[i][k] = HitTest(ball->get_x(), ball->get_y(), ball->get_r(), blocks->get_x(i, k), blocks->get_y(i, k), blocks->get_rect_x(), blocks->get_rect_y());
if (ball_block[i][k]) blocks->isnotthere(i, k);
if (ball_bar == STRIPE || ball_block[i][k] == STRIPE) hit_ball = STRIPE;
if (ball_bar == HORIZON || ball_block[i][k] == HORIZON) hit_ball = HORIZON;
if (ball_bar == BOTH || ball_block[i][k] == BOTH) hit_ball = BOTH;
if (ball_block[i][k] != 0)break;
}
}
//ボールが何かにぶつかっていればボールをぶつかってるよと教える
if (hit_ball == STRIPE) ball->isHitted_Stripe();
if (hit_ball == HORIZON) ball->isHitted_Horizon();
//if (hit_ball == BOTH) ball->isHitted_Lean();
//デバッグ用
DrawFormatString(0, 420, GetColor(255, 0, 0), "State:%d", hit_ball);
//そして更新
ball->Update();
blocks->Update();
bar->Update();
}
Ball_t Update()
void Ball_t::Update()
{
//各状態が有効なら:水平方向の接触時はy座標の速度を反転、垂直方向はx座標の速度を反転
if (Horizon){v_y[0] = -v_y[0], Horizon = false;}
if (Stripe){ v_x[0] = -v_x[0], Stripe = false; }
//if (Lean){ v_x[0] = -v_x[0], v_y[0] = -v_y[0], Lean = false; } 保留です。
//座標に対し移動させる
x[0] += v_x[0];
y[0] += v_y[0];
}
void Field_t::Update()
{
int ball_bar = NO,
ball_block[8][8];
int hit_ball = NO;
//各ブロックに対してあたり判定を行う
ball_bar = HitTest(ball->get_x(), ball->get_y(), ball->get_r(), bar->get_x(), bar->get_y(), bar->get_rect_x(), bar->get_rect_y());
for (int i = 0; i get_flag(i, k))
{
ball_block[i][k] = HitTest(ball->get_x(), ball->get_y(), ball->get_r(), blocks->get_x(i, k), blocks->get_y(i, k), blocks->get_rect_x(), blocks->get_rect_y());
if (ball_block[i][k]) blocks->isnotthere(i, k);
if (ball_bar == STRIPE || ball_block[i][k] == STRIPE) hit_ball = STRIPE;
if (ball_bar == HORIZON || ball_block[i][k] == HORIZON) hit_ball = HORIZON;
if (ball_bar == BOTH || ball_block[i][k] == BOTH) hit_ball = BOTH;
if (ball_block[i][k] != 0)break;
}
}
//世界の端との判定
if (ball->get_x() get_r() || zxc::GetWinSizeX() get_x() + ball->get_r())hit_ball = STRIPE;
if (ball->get_y() get_r())hit_ball = HORIZON;
//ボールが何かにぶつかっていればボールをぶつかってるよと教える
if (hit_ball == STRIPE) ball->isHitted_Stripe();
if (hit_ball == HORIZON) ball->isHitted_Horizon();
//if (hit_ball == BOTH) ball->isHitted_Lean();
//デバッグ用
DrawFormatString(0, 420, GetColor(255, 0, 0), "State:%d", hit_ball);
//そして更新
ball->Update();
blocks->Update();
bar->Update();
}
加えずに実行することが出来ました、 ただコレがどう画面遷移に繋がるのかは未だわからないです。
ただFieldの4行目あたり
ball_block[8][8];
の部分がマズいと思います。Fieldでボール対ブロックの縦横の個数を決定してしまっている。
というか判定部分も整数値8をそのまま使用してる、この場合Block_tの縦横のブロック個数が変更された場合正常に当たり判定が行えない気がする...
というわけでBlock_tに縦横の個数を返すゲッターを作ってFieldで判定するように変更するのであった...(ただしできなかった)
#当たり判定の時に使う配列の要素数の指定の時に定数値を与えないとダメだけどゲッターで取得する変数が定数値だと断定できないため要素数を指定出来ない
と、今回は実質的に何も進展しない回でした。
高2前期も終わるところなのでもうそろそろプログラミングを本気でやりたい(勉強しろ)
添付されたファイルですが、ソースコードと同じ階層にDxLibという名前のフォルダでDXライブラリ突っ込めば
動くと思います(多分...)