第6講 ブロック崩しその4(バーを描き、←→キーでバーを動かし、バーでボールを跳ね返し、ブロックに当たるとブロックが消えるようにする)
第10話 当たり判定社員(関数)の内容解説
コードキモ部分
void atarihantei() {
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 10; j++) {
if (arunasi[i][j] >0) {
if (mx >= 80 * j && mx <= 80 * (j + 1) &&
((my >= 40 * i + 94 && my <= 40 * i + 106) || (my >= 40
* (i + 1) + 94 && my <= 40 * (i + 1) + 106))) {
arunasi[i][j] = 0;
my_houkou *= houkougae;
}
}
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 10; j++) {
if (arunasi[i][j] >0) {
if (my >= 40 * i+100 && my <= 40 * (i + 1)+100 &&
((mx >= 80 * j - 4 && mx <= 80 * j + 4) || (mx >= 80 *
(j + 1) - 4 && mx <= 80 * (j + 1) + 4))) {
arunasi[i][j] = 0;
mx_houkou *= houkougae;
}
}
}
}
}
void maru() { //ボールの位置を計算して、その位置にボールを描く社員
・・・
if (my >= -2 && my<=2)my_houkou *= houkougae;
・・・
}
void sikaku() {
int i, j,a;
for (i = 0; i < 4; i++) {
for (j = 0; j < 10; j++) {
a = (10 * i + j) % 3;
if (arunasi[i][j] == 1) {
if (a == 0)DrawBox(80 * j, 40 * i + 100, 80 * (j + 1), 40 * (i + 1) + 100, aka, true);
if (a == 1)DrawBox(80 * j, 40 * i + 100, 80 * (j + 1), 40 * (i + 1) + 100, midori, true);
if (a == 2)DrawBox(80 * j, 40 * i + 100, 80 * (j + 1), 40 * (i + 1) + 100, ao, true);
}
}
}
}
解説
まず、
for (i = 0; i < 4; i++) {
for (j = 0; j < 10; j++) {
if (arunasi[i][j] >0) {
if (mx >= 80 * j && mx <= 80 * (j + 1) && ((my >= 40 * i + 94 && my <= 40 * i + 106) || (my >= 40 * (i + 1) + 94 && my <= 40 * (i + 1) + 106))) {
arunasi[i][j] = 0;
my_houkou *= houkougae;
}
}
}
}
において何をやっているのかから解説しましょう。
ここに置いては、ブロックの上下に当たったときに、
ブロックが消えるようにarunasi[i][j]値を0に変更することと、
跳ね返るようにしています。
(my >= 40 * i + 94 && my <= 40 * i + 106)
の部分は、スピードの設定が1であれば、
my == 40 * i + 100
(+ 100は天井とブロックの間を100としているからです。
簡単にトレースするとi = 0のときは、
my=40*0+100=100
ですから、ボールが天井で跳ね返り、
一番上のブロックの上端にぶつかったときに、
天井方向に跳ね返ることになります。)
でよいのですが、速さの縦方向myは今の設定では6です。
my += 6 * my_houkou;
でしたね。
初期位置int mx = 10, my = 950;
でしたからmyは950→944→948→・・・
のように変化していきます。
飛び飛びの値になりますので、
my == 40 * i + 100であると、ぴったり当てはまる値がない場合があります。
そこでmyの範囲を40 * i + 94以上40 * i + 106以下したわけです。
6飛びですから12もの幅を与える必要はありませんが、
ゲームモード設定で速さを自由に変えることができるように、
少し大きめに幅を設定しています。
12ぐらいの幅でも、ゲーム画面を起動して動きを見ると不自然ではありません。
幅をより小さくできるかもしれませんので、
皆さんは試行錯誤をしてください。
尚、
my >= 40 * i+100 && my <= 40 * (i + 1)+100 && ((mx >= 80 * j - 4 && mx <= 80 * j + 4) || (mx >= 80 * (j + 1) - 4 && mx <= 80 * (j + 1) + 4))
はとても複雑ですね。
&&は『そして』で||は『または』であると前に書いたこと覚えていますか。
(my >= 40 * i + 94 && my <= 40 * i + 106) || (my >= 40
* (i + 1) + 94 && my <= 40 * (i + 1) + 106)
の部分はmyが『40 * i + 94以上40 * i + 106以下』または『40 * (i + 1) + 94以上my <= 40 * (i + 1) + 106以下』
ならばという意味になります。
どうして2つの幅が選択になっているかと申しますと、
ブロックには上下があるからです。
ブロックの下からぶつかったときにも、上からぶつかったときにも、
反射ししますよね。
ブロック崩しゲームでは。
以上の説明から、
for (i = 0; i < 4; i++) {
for (j = 0; j < 10; j++) {
if (arunasi[i][j] >0) {
if (my >= 40 * i+100 && my <= 40 * (i + 1)+100 && ((mx >= 80 * j - 4 && mx <= 80 * j + 4) || (mx >= 80 * (j + 1) - 4 && mx <= 80 * (j + 1) + 4))) {
arunasi[i][j] = 0;
mx_houkou *= houkougae;
}
}
}
}
については皆さんおわかりですね。
今回は、ブロックの左右に当たったときに跳ね返るようにすることと
ブロックが消えるようにしています。
ここでは記述しませんが、
iとjを動かしてトレースしてください。
トレースをしないと理解するのは困難です。
一応ブロック崩しは一応完成しました。
まだ、得点をカウントしたりゲームオーバーやゲームクリアなどの画面がでませんので、
一応としたのです。
これらの課題は、第7講で行われます。
まず、グローバル変数
int tokuten = 0; //とくてん ゲームの得点をカウントする箱(変数)
を用意して、ゲームスコアが数えられるようにしましょう。
最初の段階では、1ブロック10点という単純な設定にしましょう。
そして、ゲーム得点を
第2講 ブロック崩しその1(ゲーム画面が立ち上がるまで)
第1話 目標
で述べた用に
と表示させましょう。
表示させるには、
DrawFormatStringを使います。
これは、
DrawFormatString(横位置, 縦位置, 色の指定, "〜");
として使います。
DrawFormatString(400, 700, GetColor(255, 255, 255), "ゲームを再開するにはZキーを押す");
とすると、横位置400縦位置700の位置に白で『ゲームを再開するにはZキーを押す』
と表示させます。
printfで、
と使えたように、
DrawFormatStringについても同様に使えます。
ですから、
DrawFormatString(*, *, *, "ゲームスコア:%d", tokuten); // 文字を描画する
のようにすればよいです。
では皆さん取り組んでください。
第9話へ 第7講第1話へ
初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc++ c言語 c++ 入門 初心者 基礎から応用まで
eclipse c++ 入門
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための]世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップへ