第7講 ブロック崩しその5(得点のカウントと表示・ゲームはじめの画面とゲームの切り替え・ゲームクリアとゲームオーバー画面表示)
第10話 ゲーム級を選べるブロック崩しの完成
#include "DxLib.h"
void maru(); //bar(バー)区別するためにボールをmaruとする maru用の変数はmx等と表す。
void sikaku(); //bar(バー)と区別するためにblock(ブロック)をsikaku(しかく)とする。sikaku用の位置を表す変数はsy、sxとする。
void bar(); //bar(バー)の位置を計算して、その位置にバーを描く仕事する社員(関数)
void syokika();
//しょきか 最初はブロックがすべて存在している状態にする。
//将来的には、ブロックの層数やボールの速さなどを決める(設定する)仕事も担当する
void atarihantei(); //あたりはんてい ブロックへの当たりの判定を行いブロックに対応するa[?][?]に0を代入する
void main(); //ゲームを進行させる社員
void saisyonogamen(); //さいしょのがめん ゲームの初期画面を描く社員(関数)
void make(); //まけ ゲームオーバーを描く社員(関数)
void kachi(); //かち ゲームクリアを描く社員(関数)
int arunasi[4][10]; //あるなし ブロックが ある:1 ない:0 とする
int mx, my; //bar(バー)やblock(ブロック)と区別するためにball(ボール)はmaru(まる)とする。
int sx, sy; //sikaku(しかく)すなわちブロックの横位置と縦位置
int bx, by; //bar(バー)の横位置と縦位置
const int s_y = 10, s_t = 4; //ブロック横数と縦数
int syh, sth; //ブロック横幅と縦幅
int b_y = 0, b_t; //バーの横幅と縦幅
const int houkougae = -1; //ほうこうがえ 方向チェンジ
int mo; //ボールの大きさ
int mxh; //ボールの横方向の速さ
int myh; //ボールの縦方向の速さ
int bh; //バーの速さ
int mx_houkou; //mxの方向
int my_houkou; //myの方向
int kiiro; //黄色の出席番号収納する箱
int aka; //黄色の出席番号収納する箱
int midori; //緑色の出席番号収納する箱
int ao; //青色の出席番号収納する箱
int siro; //白色の出席番号収納する箱
int mizuiro; //水色の出席番号収納する箱
int tokuten; //とくてん ゲームの得点をカウントする箱(変数)
int kosu; //ブロック個数
int m; //ゲームの状態 0:ゲーム始め 1:ゲーム 2:ゲームオーバー 3:ゲールクリア
int aki; //天井からブロック上端までの空きの大きさ
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
ChangeWindowMode(true);//ウィンドウモードの切り替え
SetGraphMode(800, 800, 32); //ウインドウサイズの変更
if (DxLib_Init() == -1)return(-1);// DXライブラリ初期化処理
syokika();
//しょきか 最初はブロックがすべて存在している状態にする。
//将来的には、ブロックの層数やボールの速さなどを決める(設定する)仕事も担当する
m = 0; //ゲームの状態 0:ゲーム始め 1:ゲーム 2:ゲームオーバー 3:ゲールクリア
SetDrawScreen(DX_SCREEN_BACK); //裏画像を描画対象に加える(2017/06/28追加) 画面のちらつき対策
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
switch (m) { //mはゲームの状態 0:ゲーム始め 1:ゲーム 2:ゲームオーバー 3:ゲールクリア
case 0:
saisyonogamen(); //さいしょのがめん ゲームの初期画面を描く社員(関数)
break;
case 1:
main(); //ゲームを進行させる社員(関数)
break;
case 2:
make(); //まけ ゲームオーバーを描く社員(関数)
break;
case 3:
kachi(); //かち ゲームクリアを描く社員(関数)
break;
default:
break;
}
}
WaitKey();// キー入力待ち
DxLib_End();// DXライブラリ終了処理
return 0;
}
void make() {
SetFontSize(65); //フォントサイズを65に変更
DrawBox(0, 0, 800, 800, ao, true);
DrawFormatString(100, 100, siro, "(>_<)"); // 文字を描画する
DrawFormatString(100, 300, siro, "ゲームオーバーです"); // 文字を描画する
SetFontSize(32); //フォントサイズを32に変更
DrawFormatString(20, 500, kiiro, "ゲームを再開するときはZキーを、"); // 文字を描画する
DrawFormatString(20, 540, kiiro, "ゲーム初期画面に戻るときはQキー"); // 文字を描画する
DrawFormatString(20, 580, kiiro, "を押してください。"); // 文字を描画する
if (CheckHitKey(KEY_INPUT_Z) != 0) {
syokika();
m = 1;
}
if (CheckHitKey(KEY_INPUT_Q) != 0) {
syokika();
m = 0;
}
}
void kachi() {
SetFontSize(65); //フォントサイズを65に変更
DrawBox(0, 0, 800, 800, mizuiro, true);
DrawFormatString(100, 100, kiiro, "ヾ(^v^)k"); // 文字を描画する
DrawFormatString(100, 300, kiiro, "ゲームクリアです"); // 文字を描画する
SetFontSize(32); //フォントサイズを32に変更
DrawFormatString(20, 500, siro, "ゲームを再開するときはZキーを、"); // 文字を描画する
DrawFormatString(20, 540, siro, "ゲーム初期画面に戻るときはQキー"); // 文字を描画する
DrawFormatString(20, 580, siro, "を押してください。"); // 文字を描画する
if (CheckHitKey(KEY_INPUT_Z) != 0) {
syokika();
m = 1;
}
if (CheckHitKey(KEY_INPUT_Q) != 0) {
syokika();
m = 0;
}
}
void main() {
maru(); //ボールの位置を計算して、その位置にボールを描く社員
atarihantei();
sikaku(); //ブロックの位置を計算して、その場所にブロックを描く社員する
bar(); //バーの位置を計算して、その場所にバーを描く社員
SetFontSize(32); //フォントサイズを32に変更
DrawFormatString(450, 600, siro, "ゲームスコア:%d", tokuten); // 文字を描画する
}
void saisyonogamen() {
DrawBox(0, 0, 800, 800, siro, true);
int gazou;
gazou = LoadGraph("画像/02.png");
DrawGraph(200, 100, gazou, false);
if (CheckHitKey(KEY_INPUT_A) != 0) {
mxh = 1; //ボールの横方向の速さ
myh = 4; //ボールの縦方向の速さ
b_y = 120; //バーの横幅
}
if (CheckHitKey(KEY_INPUT_B) != 0) {
mxh = 2; //ボールの横方向の速さ
myh = 4; //ボールの縦方向の速さ
b_y = 60; //バーの横幅
}
if (CheckHitKey(KEY_INPUT_C) != 0) {
mxh = 4; //ボールの横方向の速さ
myh = 6; //ボールの縦方向の速さ
b_y = 30; //バーの横幅
}
if (b_y == 0) { //AまたはBまたはCを押し忘れている場合には、初心者モードに設定
mxh = 1; //ボールの横方向の速さ
myh = 4; //ボールの縦方向の速さ
b_y = 120; //バーの横幅
}
if (CheckHitKey(KEY_INPUT_Z) != 0) m = 1;
}
void syokika() {
int i, j;
for (i = 0; i < s_t; i++) {
for (j = 0; j < s_y; j++) {
arunasi[i][j] = 1;
}
}
mx = 400; //ボールの初期の横位置
my = 720; //ボールの初期の縦位置
mo = 10; //ボールの大きさ(半径)
sx = 0; //sikaku(しかく)=ブロックの最初の横位置
sy = 100; //sikaku(しかく)=ブロックの最初の横位置
mx_houkou = 1; //ボールの横方向の最初の向き
my_houkou = -1; //ボールの縦方向の最初の向き
bx = 0; //バーの最初の横位置
by = 760; //バーの最初の縦位置
b_t = 20; //バーの縦幅
bh = 8; //バーの速さ
aki = 100; //天井からブロック上端までの距離
kiiro = GetColor(255, 255, 0); //黄色に出席番号を割り振りその番号を箱kiiroに収納
aka = GetColor(255, 0, 0); //黄色に出席番号を割り振りその番号を箱kiiroに収納
midori = GetColor(0, 255, 0); //緑色に出席番号を割り振りその番号を箱midoriに収納
ao = GetColor(0, 0, 255); //青色に出席番号を割り振りその番号を箱aoに収納
siro = GetColor(255, 255, 255); //白色に出席番号を割り振りその番号を箱siroに収納
mizuiro = GetColor(0, 200, 200); //水色に出席番号を割り振りその番号を箱mizuiroに収納
tokuten = 0; //とくてん 0に初期化
kosu = s_y * s_t; //ブロック個数 s_y:ブロック横数 s_t:ブロック縦数
syh = 800 / s_y; //syh:ブロック横幅 s_y:ブロック横数
sth = syh / 2; //sth:ブロック縦幅 ブロック縦幅
bh = 8; //バーの速さ
}
void atarihantei() {
int i, j;
for (i = 0; i < s_t; i++) {
for (j = 0; j < s_y; j++) {
if (arunasi[i][j] >0) {
if (mx >= syh * j && mx <= syh * (j + 1) && ((my >= sth * i + aki - 6 && my <= sth * i + aki + 6) || (my >= sth * (i + 1) + aki - 6 && my <= sth * (i + 1) + aki + 6))) {
arunasi[i][j] = 0;
my_houkou *= houkougae;
tokuten += 10;
kosu--;
if (kosu == 0)m = 3;
}
}
}
}
for (i = 0; i < s_t; i++) {
for (j = 0; j < s_y; j++) {
if (arunasi[i][j] >0) {
if (my >= sth * i + aki && my <= sth * (i + 1) + aki && ((mx >= syh * j - 4 && mx <= syh * j + 4) || (mx >= syh * (j + 1) - 4 && mx <= syh * (j + 1) + 4))) {
arunasi[i][j] = 0;
mx_houkou *= houkougae;
tokuten += 10;
kosu--;
if (kosu == 0)m = 3;
}
}
}
}
}
void maru() { //ボールの位置を計算して、その位置にボールを描く社員
DrawCircle(mx, my, mo, kiiro, true); //ボールを描く
if (mx <= mo)mx_houkou *= houkougae; //左の壁で反射
if (mx >= 800 - mo)mx_houkou *= houkougae; //右の壁で反射
if (my <= mo)my_houkou *= houkougae; //天井の壁で反射
if (mx >= bx && mx <= bx + b_y && my >= 756)my_houkou *= houkougae; //バーで反射
if (my >= 800)m = 2; //ゲームオーバー
mx += mxh * mx_houkou; //mx:ボールの横位置 mxh:ボール横方向の速さ
my += myh * my_houkou; //my:ボールの縦位置 myh:ボール縦方向の速さ
}
void sikaku() {
int i, j, a;
for (i = 0; i < s_t; i++) {
for (j = 0; j < s_y; j++) {
a = (10 * i + j) % 3;
if (arunasi[i][j] == 1) {
switch (a) {
case 0: //赤のブロックを描く
DrawBox(syh * j, sth * i + aki, syh * (j + 1), sth * (i + 1) + aki, aka, true);
break;
case 1: //緑のブロックを描く
DrawBox(syh * j, sth * i + aki, syh * (j + 1), sth * (i + 1) + aki, midori, true);
break;
case 2: //青のブロックを描く
DrawBox(syh * j, sth * i + aki, syh * (j + 1), sth * (i + 1) + aki, ao, true);
break;
default:
break;
}
}
}
}
}
void bar() {
if (CheckHitKey(KEY_INPUT_RIGHT) != 0 && bx + b_y <= 800) {
bx = bx + bh; //bx:バーの左端の横位置 bh:バーの速さ
}
if (CheckHitKey(KEY_INPUT_LEFT) != 0 && bx >= 0) {
bx = bx - bh; //bx:バーの左端の横位置 bh:バーの速さ
}
DrawBox(bx, by, bx + b_y, by + b_t, siro, true);
//bx:バーの左端の横位置 b_y:バーの横幅 b_t:バーの縦幅
}
コピペ用添付ファイル
ようやく完成しました。
本当にご苦労様でした。
2,3講を費やせばできると思っていましたが、
結局第2講から第7講まで6講を投入する羽目になりました。
第8講で挑戦するゲームは、RPG風のアクションパズルです。
これは、書籍
『株式会社ラトルズ 大槻有一郎著
14歳からはじめるC言語わくわくゲームプログラミング教室Visual Studio 2013編』
を参照させていただきましたが、
私なりの工夫をたくさん入れ、
コードも小学生が理解できるように改良してあり、
私の創造した作品であるといえるようになっていますので、
著作権の問題は全くないといえるでしょう。
画像もここで提供されているものは使わずに、
2次配布にならないようにします。
第9話へ 第8講第1話へ
初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc++ c言語 c++ 入門 初心者 基礎から応用まで
eclipse c++ 入門
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための]世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップ