はじめに
目的
初心者向けProcessing講座の総まとめ、実践編ということで、ブロック崩しを作成しようと思います!
初心者向け講座の一覧は、以下のプログラミングコンテンツから確認してみてください!
実際のプログラムはどのような感じかを掴んでいただいて、自分でも何かしら作れるようになっていただけると幸いです!
コードを一つ一つ意図なども説明するので、考え方なども参考にしてみてください!
※時短したい方は各記事最後のコードを丸コピでもOKです。
最終成果物
最終成果物として、以下のようなブロック崩しが初心者でも作れます!
プログラムを1行ずつ解説するので4partに分かれますが、誰でも理解できます!
今回やること
part 1:図形の描写
part 2:ブロック、弾の移動
part 3:反射処理
part 4:シーン遷移、各種調整
今回はpart 1です!
図形描写まで行います!
今回使う知識
各解説のリンクを貼っているので、詳細を知りたい方は解説記事もご覧ください!
ブロック崩し制作 part 1
STEP 0 ファイル作成
新たにファイルを作ってください。
ファイル > 新規
今後はこのファイルにブロック崩しのコーディングをすることになるので、中断する際は「名前をつけて保存」等で消えないようにしてください!
STEP 1 変数の設定
何を変数にすれば良いのか
変数のメリットは、値を変更する際に何回も書かなくても良いことでした。
なので頻繁に変わりうる値や、設定で変えるかもしれない値は変数にしておくのがおすすめです。
図形描写のための変数設定
ブロック崩しで描写するのは以下の3種類の図形です。
- 操作ブロック
- 弾
- 障害物ブロック
各種類で必要な変数を考えてみましょう!
変数名は例なので、適時変えていただいてもOKです。
ですが他のpartでも以下の変数名は継続して使うので注意してください。
操作ブロック
操作ブロックは、長方形にしたいです。
長方形は、rect関数で描くことができ、
rect関数は、横位置、縦位置、横幅、縦幅の4つの値が必要でした。
横位置は頻繁に変わるので変数にします。
縦位置、横幅、縦幅は簡単に変えられるように変数にしておきましょう。
弾
弾は円にしましょう。
円はellipse関数で描くことができ、
ellipse関数は、中心の横位置、中心の縦位置、横直径、縦直径の4つの値が必要でした。
中心の横位置、縦位置は頻繁に変わるので変数にします。
真円にしたいので、横直径、縦直径は一つの変数として同じ値を使うようにしましょう。
後々の当たり判定などに半径を使うため、半径で宣言しておきます。
障害物ブロック
障害物ブロックは、今回は円にします。
長方形だと当たり判定、反射判定が難しくなってしまうからです。
円はellipse関数で描けましたね。
なので弾と同じように4つの値が必要です。
しかし、障害物は複数設置したいので、置きたい障害物の数、位置についての変数が必要です。
なので、障害物の位置は配列で書きましょう。
そのため、以下のように値を宣言しておきます。
障害物の数、障害物の円の半径、障害物の位置(配列)
STEP 2 図形描写の準備
ひとまず変数が設定できたので、わかりやすいように図形描写をしてみましょう!
そのための準備を行います。
関数の作成
ここで、setup関数とdraw関数を作成します。
setup関数は、draw関数の直前に実行される処理で、
draw関数は、プログラムが動いている間繰り返し実行される処理です。
なのでsetup関数などに初期処理の設定、
draw関数に図形描写を行います。
変数宣言
setup関数
draw関数
の順に書きましょう!
図形描写
まず、画面のウインドウサイズを決めたいので、setup関数内にsize関数を記入します。
今回は横500、縦500で指定してみましょう。
次にdraw関数内に、真っ黒な背景として以下を記述します。
どちらも記入して実行して、以下のように黒いウインドウが表示されると成功です!
操作ブロック
操作ブロックにの必要な変数はすべて宣言したので、rect関数に渡してあげましょう!
以下をdraw関数の中に書きます。
弾
弾に関しても必要な変数はすべて宣言したので、ellipse関数に渡しましょう!
宣言した変数は半径であることに注意です。(*2を忘れないように!!)
以下をdraw関数の中に書きます。
障害物ブロック
障害物の位置は配列、大きさ(半径)は変数で宣言しました。
配列を使うので、for文を使いましょう!
宣言した変数は半径であることに注意です。(*2を忘れないように!!)
以下をdraw関数の中に書きます。
STEP 2の成果物
以下のようになればSTEP 2は完了です。
STEP 3 初期値の設定
変数は、宣言しただけでは意図しない値が入っている場合があります。
そのため、STEP 2時点では左上の(0,0)付近に描写されています。
なので、宣言をした後に、初期値を設定する必要があります!
STEP 1で宣言した変数は全部で10個でした。
一部の変数は既に宣言時に値を入れているので参考にしてください!
ただ宣言時に値を設定していないものがちらほらあります。
一部の変数は宣言時点では初期値を設定しづらかったり、別の変数の値を使いたいためです。
初期値の設定
以下のコードはsetup関数内に記述してください。
なぜ宣言時に値を設定しなかったのかも併せて考えてみましょう!
操作ブロック初期位置
操作ブロックの初期位置を設定します。
始めの位置は画面下部の画面中央にしましょう。
しかしどちらも画面サイズを取得する必要があります。
ここでProcessingの以下の変数を使います。
width : 画面サイズの横幅の値
height : 画面サイズの縦幅の値
なのでこれを使用すると、以下のように書けますね。
しかし、このように書くと操作ブロックが表示されません。(実行してみるとわかります)
なぜなら、rect関数の仕様は、指定した座標から下向きに長方形を描写するので、
描写する際の引数の意味的に、画面の下端の位置から下向きに長方形を描写することになるからです。
なので以下のように書く必要があります。
弾初期位置
弾の初期位置は操作ブロックの真上にしましょう。
縦位置は操作ブロックで設定した値を利用しちゃいましょう!
障害物位置
障害物の位置は量が多いし、適切な場所が判断しづらいので、ランダムに設置するようにしましょう!
random(a, b); //a~bのfloatの範囲で乱数作成
障害物の中心が画面上部の70%ほどの範囲に描写したいと考えて、
上記のrandom関数とfor文を使うと、このように描けます。
STEP 3 の成果物
以下のように表示されれば成功です!
障害物の位置は実行する度に異なります。
まとめ
お疲れ様でした!
今回はpart 1 で図形の描写まで行いました。
一つ一つのコードに意味があって自分で作り上げている達成感があるのではないでしょうか?
次回はブロックと弾の移動を行います!
次の記事もぜひご覧ください!
Take It easy!Take It Breezy!
お疲れ様でした!
今回までのコード
/* TAKEのIT風万記
ブロック崩し サンプルコード*/
//操作ブロック
int block_pos_x; //ブロックの横位置
int block_pos_y; //ブロックの縦位置
int block_width = 100; //幅
int block_height = 10; //高さ
//弾
int ball_pos_x; //弾の横位置
int ball_pos_y; //弾の縦位置
int ball_radious = 5; //弾の半径
//障害物
int obs_num = 10; //障害物の数
int obs_radious = 20; //障害物の半径
int[][] obs_pos = new int[obs_num][2]; //障害物の位置 [障害物No][0:x、1:y]
//draw関数の前に一度だけ実行
void setup(){
size(500,500); //画面サイズ
//操作ブロック初期位置
block_pos_x = width/2;
block_pos_y = height - block_height;
//弾初期位置
ball_pos_x = width/2;
ball_pos_y = block_pos_y - block_height;
//障害物初期位置
for (int i = 0; i < obs_num; i++) {
obs_pos[i][0] = int(random(0, width));
obs_pos[i][1] = int(random(0, height * 7/10));
}
}
//繰り返し実行
void draw(){
background(0); //背景
//操作ブロック
rect(block_pos_x, block_pos_y, block_width, block_height);
//弾
ellipse(ball_pos_x, ball_pos_y, ball_radious*2, ball_radious*2);
//障害物ブロック
for(int i = 0; i < obs_num; i++){
ellipse(obs_pos[i][0], obs_pos[i][1], obs_radious*2, obs_radious*2);
}
}