一つの知識を確実に自分のものにしないまま次を積み重ねてぐちゃぐちゃになってませんか?
自分がコンピュータになったつもりでプログラムを「実行」してみましょう(アタマの中で。あるいは紙などにどんどん書いていってもいいですけれど)。
setup()はいいとして、draw()は何度も繰り返されるのでしたね。
(for文のコメントによってエラーが出るのでとりあえずコメントを外して考えます)
draw()に入ります。
houdaiに画像を読み込みます。
tekiに画像を読み込みます。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
キーが押されていなければ、ifの中身は飛ばします。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
draw()終わり。
draw()に入ります。
//キーが押されていなければ同上なので略
draw()終わり
//今度はキーが押されているとしましょう。
draw()に入ります。
houdaiに画像を読み込みます。
tekiに画像を読み込みます。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
キーが押されているので、ifの中に入ります。
for文の働きでi=0にします。
yつまり弾の縦位置から0を減じます。
画像をクリアします。
弾を描画します。
for文の働きでi=-1にします。
yから-(-1)つまり1を減じます。
画像をクリアします。
弾を描画します。
<for文の繰り返し略>
for文の働きでi=-6にします。
yから-(-6)つまり6を減じます。
画像をクリアします。
弾を描画します。
for文終わり。if文の中身終わり。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
draw()終わり。
//ここでキーが離されると...最初と同じ。敢えて書きますが
draw()に入ります。
houdaiに画像を読み込みます。
tekiに画像を読み込みます。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
キーが押されていなければ、ifの中身は飛ばします。
houdaiを250,450の位置に50,50のサイズで描画します。
tekiを250,50の位置に50,50のサイズで描画します。
draw()終わり。
さて。この最後のdraw()では、yの操作は何も出てきていませんね。しかも、画面のクリアもしていないし、弾の描画も行われていません。つまり、弾はなにも変化しないのです。
毎回keyを押さないと進まない状況です
そういうプログラムになっています。
ここまでが現状把握。
なんで思ったのと違う動作になったかを検討しないで、「正解」だけ聞いて満足しないこと。なんだかそれを繰り返して今に至っている気がするのだけど、違うかしら?
さて。booleanも別に魔法の呪文ではないので、それを使えばいきなり何かが解決するわけでもないですけれど、コトの本質としては
-
弾の位置はキーが押されていなくても変わらなければいけない。ので、if(keyPressed)
のif文の外で位置を変えて描画する操作をしないといけない。
-
ただし、弾はキーが押されるまでは発射されてはいけない。キーが押されたら弾が発射される。
というのを何とかしなきゃいけません。
とりあえず知っておいて欲しいこと。
processingの描画は、原則としてはdraw()とdraw()の合間で行われると考えて下さい。draw()の処理は大抵一瞬で終わってしまうので。
とすると、
processing
1 for (int i = 0; i >= -6; i--) {
2 y -= -i;
3 background(0);
4 rect(x, y, w, h);
5 }
ってのはアニメーションをしているつもりなのかも知れないけれど、実は一瞬のうちに21だけ弾が移動する効果しかありません。(そもそも、iを負の数にしてそれに対してy -= -i;
って...自分でも整理出来てないでしょ?) 単にどこかでBULLETSTEP=10;
とでもして、y-=BULLETSTEP;
だけで十分。そんなこんなで、1の基本形(単に弾が飛んでいくだけ)は
int BULLETSTEP=10;
int w = 10;
int h = 20;
int x = 270;
int y = 445;
void setup() {
size(500, 500);
background(0);
}
void draw() {
y -= BULLETSTEP;
background(0);
rect(x, y, w, h);
}
といったところでしょうか。
では、キーが押されたら弾が発射されるようにするには...?booleanは使いたくないの? どうしてもというならint型でも出来なくはないですけど、とにかく「過去にキーが押された」という履歴を覚えておく必要があります。覚えておくのですから変数です。押されたか押されてないかという情報(1bit)なのでbooleanでいいのですけれど、まぁint型でもいいでしょうか。int isShot=0;
とかいう変数を作りましょうか。0だとキーが押されたことはない、0以外だとキーが押されたことがある、という意味ということにしましょう。(boolean型ならfalse/trueとするところですが)
Processing
1int BULLETSTEP=10;
2int isShot=0;
3int w = 10;
4int h = 20;
5int x = 270;
6int y = 445;
7void setup() {
8 size(500, 500);
9 background(0);
10}
11void draw() {
12 background(0);
13 if (keyPressed) {//キーが押されている
14 isShot=1;//押されたことを覚えておく
15 }
16 if (isShot!=0) {//押されたことがあるなら
17 y -= BULLETSTEP;//弾を飛ばす
18 rect(x, y, w, h);
19 }
20}
弾が発射できるようにしました。一発だけ。
じゃあ、次の弾はいつ撃てるようになるの? 弾が画面の外に出たら。
Processing
1int BULLETSTEP=10;
2int Y0=445;
3int isShot=0;
4int w = 10;
5int h = 20;
6int x = 270;
7int y = Y0;
8void setup() {
9 size(500, 500);
10 background(0);
11}
12void draw() {
13 background(0);
14 if (keyPressed) {
15 y=Y0; //撃つ前に弾の位置を設定しなおす
16 isShot=1;
17 }
18 if (isShot!=0) {
19 y -= BULLETSTEP;
20 rect(x, y, w, h);
21 }
22 if(y<0){ //画面の外に出たら
23 isShot=0;//キーが押されたことを'忘れる'
24 }
25}
他にもいくつか問題はあるけれど、とりあえず質問に書いてあることはこれでなんとかなるかしら?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。