* 初心者向けプログラミング体験ワークショップ#3
-(by [[K]], 2021.12.03)
** (0)
-今回紹介するのは、「ハンバーガーキャッチ・ゲーム」です。30行で書けます。
-このページは[[「初心者向けプログラミング体験ワークショップ」>a21_edu01]]の教材のうちの一つです。
** (1) ストーリー & ルール
-ぼくはときどき近所のハンバーガー屋さんでアルバイトをしています。そこのハンバーガーはとてもおいしいのだけど、ちょうりしつが2階にあって、売り場が1階なので、そこまで運ぶのがいつもたいへんです。
-ちょうりがかりのおじさんは、ハンバーガー作りがうまくいきはじめると、売り場にむかってできたてのバーガーをなげはじめます。ちょっとわるいくせなんです。もちろんうまくキャッチできないとすごくしかられます。でもうまくキャッチできるとおじさんはどんどんきげんがよくなります。
-おじさんは食べ物をそまつにしているのではなくて、ぼくがうまくキャッチできるのをしんじていて、そうしているだけなのです。ぼくは今日もおじさんのきたいにこたえたいです!
----
| http://k.osask.jp/files/pic20211203a.png | http://k.osask.jp/files/pic20211203b.png | http://k.osask.jp/files/pic20211203c.png |
|こんなゲームです|やった、レベル6もクリアです!|しまった!!|
-画面の上から黄色のハンバーガーが1つずつ落ちてきます。水色のお皿をカーソルキーで操作して、ハンバーガーをキャッチしてください。レベル2以上では、ハンバーガーの上にハンバーガーをのせる必要があります。ちょっとむずかしいですががんばってください。
-ふつう、ハンバーガーキャッチ・ゲームというと、パンや野菜やお肉が上から落ちてきてそれらをうまい順番にはさんでおいしいバーガーを作るゲームのようですが、このゲームにはそういう要素はなくて、ただできあがったバーガーを受け止めるだけになっています。30行ではこれくらいが限界なので許してください。
-ゲームをやめたくなったら、いつでも ESCキー を押せば終了できます。
-なお、HLXでは現在開いているゲームウィンドウよりも大きなウィンドウを開くことができません。ですから、たとえばもし「坂道を走ってきれいな石を拾い集めるゲーム」を遊んだ後にこれを実行しようとするとエラーになるはずです。その場合は、お手数ですがHLXを一度終了させて、もう一度HLXを起動して、それからcatch.txtやcatch.cをrunしてください。
** (2-1) HLX-BASICでのプログラム(30行)
-プログラム中に日本語で説明を書き込んでいますが、その部分は入力しないでください。矢印も入力しないでください。
CANVAS 20,24,"CATCH"; ← ゲーム画面を作ります。よこ20マス、たて24マスの大きさです。
HI=0; ← ハイスコアを0に設定します。
FOR; ← 繰り返し命令で、一番下のNEXTまでの範囲を繰り返します。
SC=0; ← スコアを0点に設定します。
FOR LV=1,9999; ← LV=1から順番に上がっていくための繰り返しです。
PX=9; ← PXはお皿の位置です。
FOR BG=0,LV; ← バーガーをLVの数だけ降らせるための繰り返しです。
BX=RND(20); BY=0; ← バーガーの初期位置を乱数で決めています。
FOR T=0,9999; ← ゲーム内時間を数えるために変数Tを使います(表示されません)。
CLS@ 0; ← 画面をまず黒(色番号0)で消します
PRINT@ 0,0,7,0,"LEVEL:%02d SCORE:%05d HIGH:%05d",LV,SC,HI; ← 画面の上の方に、レベル、点数、ハイスコアを表示します。
IF T%4==0 AND NOT(PX==BX AND BY>=22-BG) THEN BY++; FI; ← もしゲーム内時間Tが4の倍数だったら、バーガーを1マスだけ落とします。
CHAR@ BX,BY,2,6,0; ←バーガーを場所(BX,BY)に表示します。キャラクターは丸(番号2)、色は(6,0)です。
CHAR@ PX,23,4,3,0; ←水色のお皿を場所(PX,23)に表示します。キャラクターは横棒(番号4)、色は(3,0)です。
CHARBOX@ 1,BG,PX,23-BG,2,6,0; ←積みあがったバーガーを(PX,23-BG)からBG個表示します。キャラクターは丸(番号2)、色は(6,0)です。
IF PX==BX AND BY==22-BG BREAK; ←もしバーガーがキャッチできたら、TのFOR~NEXTから抜けます。
IF BY==23 GOTO OVER; ←もしバーガーが床に落ちてしまったら、OVERにジャンプします。
I=INKEY@WRC(50); ←50ミリ秒(0.05秒)だけ待ってからキー入力状態を確認します。
TX=MINMAX(PX+XMOVE(I),0,19); ←キー入力での移動先をTXに計算します。MIXMAXを使って、0~19の範囲から出ないようにしています。
IF NOT(TX==BX AND BY>=23-BG) THEN PX=TX; FI; ←もしもTXにお皿を移動した時に、落下中のバーガーと衝突しなかったら、PXを更新します。
NEXT; ←TのためのFORのところに戻ります。このときにTは1増えます。
SC++; ←SCに1を足します。
HI=MAX(HI,SC); ←SCとHIのうち、大きいほうをHIとします。
NEXT; ←BGのためのFORのところに戻ります。このときにBGは1増えます。
PRINT@ 6,20,0,2,"LEVEL:%02d CLEAR!",LV; ←クリアした時のメッセージを書きます。
WAIT 3000; ←3000ミリ秒(=3秒)だけ待ちます。
NEXT; ←LVのためのFORのところに戻ります。このときにLVは1増えます。
OVER:
WAITKEY@ 10; ←Enterキーが押されるまで待ちます。
NEXT; ←一番最初のFORのところに戻って、ゲームを最初からやり直します。
-ほそく説明:
--PRINT@の中の%以降には、数字のゼロや小文字のdがあります。英語のオーではないので注意してくださいね。
--色番号の表
|0:黒|1:青|2:みどり|3:水色|4:赤|5:むらさき|6:黄色|7:白|
--色を2つの数字で表すときは、1つ目の数がキャラクターの色で、2つ目の数が背景の色です。
--キャラクターの表示位置は、2つの数字で表します。1つ目が左から数えて何番目のマスか(0番から数えます)、2つ目が上から数えて何番目のマスか(0番から数えます)。
---このゲームでは20x24マスを用意しているので、0,0~19,23までが使えます。
--キャラクター番号の表
|0:空白|1:四角|2:丸|3:バツ|4:よこぼう|5:たてぼう|6:顔マーク|7:ひしがた|8:ななめせん|9:ななめせん|
--RND(20)について: RNDは乱数(らんすう)の命令で、RND(20)は0~19までのどれかの数を適当に決める命令です。
** (2-2) HLX-BASICのプログラムを実行するための方法(大人の方へ)
-もしWindowsでHLX-BASICを使うなら、話は簡単です!
-[[a21_hlx003]]のページへ行って、 hlx003b.zip をダウンロードして、中にある hlx_x86_win.exe を入手してください。それだけあれば十分で他のファイルは捨ててしまってもかまいません。
-[[a21_hlx003]]のページへ行って、 hlx003c.zip をダウンロードして、中にある hlx_x86_win.exe を入手してください。それだけあれば十分で他のファイルは捨ててしまってもかまいません。
-このhlx_x86_win.exeを適当なフィルだ内において、同じフォルダの中にcatch.txtというテキストファイルを作ります。このテキストファイルをお子さんに入力させてあげてください。
--入力の際にはまずテキストエディタを開き(メモ帳でもいいですが、私はTeraPadが好きです)、キーボードのCapsLockをオンにした状態で、大人がテキストを一文字ずつ読んであげて、お子さんがキーを探して入力する、というスタイルがおすすめです。大人は1とI、0とOの入力間違いが起こりやすいので、特にそこを注意してみてあげます。
--キーを見つけられないときは、ほらここにあるよと教えてあげますが、それでもキーボードのキーを指さすだけにして、実際の入力はお子さんにやらせてあげてください。入力ミスがあった時の訂正も、「矢印キーを使ってカーソルをここに動かして、そこでDelキーを押して。」みたいに操作の指示はしても、実際の操作はお子さんにやらせてみてください。
--そうすると、「これは全部自分がやった。」という満足感が得られるはずです。
--(何回もやって慣れてきたら、自分でプログラムを読んで入力できるようになると思います。)
-入力が終わったら、先ほどのhlx_x86_win.exeを起動して、そこで
hlx>run catch.txt
-と入力してください。入力ミスがなければゲームが始まるはずです。
-ミスがあった場合は、エラーメッセージを見ながら間違いを探して直してください(エラーメッセージはかなり不親切なので、大人の方の手伝いが不可欠です。よろしくお願いします。お手数をおかけしてすみません)。
-なおゲーム中のキー操作は、ゲーム画面が入力アクティブになっていないと有効ではありませんので、あれ?操作が効かないなと思ったら、ゲーム画面が一番上のウィンドウになっているかどうかをまず確認してください。
-Windows以外のOSの方は、[[a21_hlx003]]のページを見て、ソースコードからhlxをビルドしなければいけません。そこがクリアできれば、あとは同じようにできるはずです。
** (2-3) 改造のポイント
-このゲームは自分で入力したのですから、自分で改造することだってできます。ただ遊ぶだけじゃなくて改造も楽しんでほしいです。
-もしこのゲームが簡単で、すぐにレベル10とかに行けるのなら、少しむずかしくしましょう。一番簡単な改造はゲームのスピードを速くすることです。
-速さを変えるには、50ミリ秒待っているところの数字を変えます。さて速くするには数字を30にすればいいでしょうか?それとも100にすればいいでしょうか?(正解は自分でやって確かめてみてね!)
-もしこのゲームがむずかしすぎたなら、やっぱりまずはゲームの速さを変えるのが簡単です。それは上の説明を参考にしてみてください。
-もしくは、ゲームの速度はそのままで、バーガーだけゆっくり落としたければ、 IF T%4==0 のところを変えます。4の倍数ではなく10の倍数の時だけ落ちるようにすれば、だいぶゆっくりになるはずです。
-別の改造としては、「おじさん」のコントロールを良くしてバーガー落ちる場所を狭くしましょう。そうすれば拾いやすくなります。BX=RND(20); の RND(20) を RND(5) に変えてみてください。
** (3-1) C言語でのプログラム(aclライブラリ利用)(34行)
-内容的に、(2-1)とほぼ一対一で対応しているので、細かい説明は省略します。
#include <acl.c>
void aMain()
{
int hi = 0, sc, px, tx, bx, by, t, bg, lv, i;
AWindow *w = aOpenWinEx(20, 24, "catch", 0);
for (;;) {
sc = 0; px = 9;
for (lv = 1;; lv++) {
for (bg = 0; bg < lv; bgr++) {
bx = aRnd(20); by = 0;
for (t = 0;; t++) {
aCls(w, 0);
aGrPrintf(w, 0, 0, 7, 0, "Level:%02d Score:%05d High:%05d", lv, sc, hi);
if (t % 4 == 0 && !(tx == bx && by >= 22 - bg)) by++;
aEch(w, bx, by, 2, 6, 0);
aEch(w, px, 23, 4, 3, 0);
aEchBox(w, 1, bg, px, 23 - bg, 2, 6, 0);
if (px == bx && by == 22 - bg) break;
if (by == 23) goto over;
i = aInkey_waitRC(w, 50);
tx = aSaturateInt(px + aMoveDx(i), 0, 19);
if (!(tx == bx && by >= 23 - bg)) px = tx;
}
sc++;
hi = aMax(hi, sc);
}
aGrPrintf(w, 6, 20, 0, 2, "Level:%02d Clear!", lv);
aWait(3000);
}
over:
aWaitKey(w, AKEY_ENTER);
}
}
** (3-2) C言語のプログラムを実行するための方法(大人の方へ)
-このプログラムは、C言語でありながらHLXのサポート範囲内の機能だけで書かれているので、HLXで実行することができます。この場合、C言語やaclライブラリのインストールは不要です(もしWindows以外で、まずhlx自身のビルドからやらなければいけない場合は、Cコンパイラやaclライブラリのインストールが必要です)。
-使い方もほとんど同じで、catch.cを作って、
hlx>run catch.c
-とするだけでOKです。
-もし、HLXを使わずに普通のCコンパイラとaclライブラリの組み合わせでやる場合は、[[a21_acl01]]のページを見てaclライブラリを使えるようにしたうえで、上記のcatch.cをビルドしてください。
-そのほかの操作方法や改造方法などは、(2-2)、(2-3)と同等なのでここでは省略します。
** (4) バグ修正
-バーガーをぎりぎりでキャッチした時に画像の更新が追い付かなかったので、以下の2行の位置をINKEY@WRCの直前に移動させました。
IF PX==BX AND BY==22-BG BREAK; ←もしバーガーがキャッチできたら、TのFOR~NEXTから抜けます。
IF BY==23 GOTO OVER; ←もしバーガーが床に落ちてしまったら、OVERにジャンプします。
* こめんと欄
#comment