りょうのゲーム塾 -120ページ目

りょうのゲーム塾

再開、準備中。

チェックポイント
画面を左右に移動するUFOは敵キャラとして使用します。
今回はプレイヤキャラを追加してみましょう。


プレイヤを追加したサンプルプログラムは下記の通りです。

■プログラム
プレイヤを表示する

0001 ' initialize
0002 UFO_X = 0:UFO_F = 0
0003 PLY_X = 15
0004 ' game loop
0005 @LOOP
0006 VSYNC 1
0007 CLS
0008 ' UFO
0009 IF UFO_F!=0 GOTO @UFO_MVL
0010 ' move right
0011 LOCATE UFO_X, 0
0012 PRINT "A"
0013 UFO_X = UFO_X + 1
0014 IF UFO_X < 32 GOTO @UFO_END
0015 UFO_X = 31
0016 UFO_F = 1
0017 GOTO @UFO_END
0018 ' move left
0019 @UFO_MVL
0020 LOCATE UFO_X, 0
0021 PRINT "A"
0022 UFO_X = UFO_X - 1
0023 IF UFO_X >= 0 GOTO @UFO_END
0024 UFO_X = 0
0025 UFO_F = 0
0026 @UFO_END
0027 ' player
0028 LOCATE PLY_X,21
0029 PRINT "P"
0030 GOTO @LOOP


前回のサンプルとの変更点はUFOが移動するプログラムの後にプレイヤを表示する部分を追加しました。
それによりラベル@LOOPにジャンプしていた部分がラベル@UFO_ENDにジャンプするように変更されています。
その理由はUFOを移動した後にプレイヤを表示する部分を実行しなければいけないからです。
前のままだとUFOが移動した後@LOOPにもどりいつまでもプレイヤが表示されません。

それではこのプログラムを変更しプレイヤを移動してみましょう。
ちなみにプレイヤの表示を行っている PRINT "P" の"P"はプチコンの絵文字にうえ向きの宇宙船のようなキャラクタがあるのでそれを使ってくださいね。

次回、プログラミング例を掲載します。
チェックポイント
前回はUFOの移動を行うプログラムを作成しました。
しかしUFOは画面左上から右上に移動するだけでそれ以降は移動しません。
今回は移動の終了を判定する部分を追加してみたいと思います。


前回のサンプルプログラムは下記の通りです。

■プログラム
0001 X = 0
0002 @LOOP
0003 VSYNC 1
0004 CLS
0005 LOCATE X, 0
0006 PRINT "A"
0007 X = X + 1
0008 GOTO @LOOP


このプログラムを実行するとUFOが画面左上から右上に移動しなぜか左上で止まったままになります。
これは LOCATE文のX方向の指定で使える値が0から31の間なのですがUFOが右上に移動した後も右に行こうとしているからX方向の値が不適切な値になっているためです。

プログラムではこの様なことが起きないようにしなければなりません。
次のプログラムは右上に到達した場合プログラムを終了します。

■プログラム
0001 X = 0
0002 @LOOP
0003 VSYNC 1
0004 CLS
0005 LOCATE X, 0
0006 PRINT "A"
0007 X = X + 1
0008 IF X < 32 GOTO @LOOP
0009 END

■実行画面

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                               仝┃
┃OK                              ┃
┃_                               ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┃                                ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛


しかしこのままではすぐにプログラムは終了してしまうのでゲームにはなりません。
そこでこのUFOを画面上で左右に移動するように変更してみましょう。

■プログラム
0001 X = 0
0002 @LOOP1
0003 VSYNC 1
0004 CLS
0005 LOCATE X, 0
0006 PRINT "A"
0007 X = X + 1
0008 IF X < 32 GOTO @LOOP1
0009 X = 31
0010 @LOOP2
0011 VSYNC 1
0012 CLS
0013 LOCATE X, 0
0014 PRINT "A"
0015 X = X - 1
0016 IF X >= 0 GOTO @LOOP2
0017 X = 0
0018 GOTO @LOOP1


これでUFOは左右に移動するようになりました。
言い忘れたわけではないのですが新しい命令が使われています。

■書式
IF 条件式 GOTO @ラベル
条件式が成り立つときラベルのあるプログラム位置へジャンプする


この命令は IF 条件式 THEN GOTO @ラベルと同じです。

チェックポイント
ゲームのプログラムはキャラクタが移動したりする場合この様に処理を繰り返し行わなければなりません。
このような繰り返しはループと呼ばれていますが、特にゲームの1回のループの間にゲーム中で表示されているキャラクタすべてを実行しなければなりません。
このようなループをゲームループと呼んでいます。


このプログラムには問題があります。
ゲームループはゲーム中にひとつだけでないと不都合なのです。
このサンプルの場合ループが2つありますよね。
しかしこの説明もゲームの中での時間の概念を説明しなければならないのである程度理解ができたで頃に説明することにします。
ここでは『何故?』ではなくそうしなければならない理由があるということで勘弁してください。

それではこのループを一つにしてみましょう。

■プログラム
0001 ' initialize
0002 UFO_X = 0
0003 UFO_F = 0
0004 ' game loop
0005 @LOOP
0006 VSYNC 1
0007 CLS
0008 ' UFO
0009 IF UFO_F!=0 GOTO @UFO1
0010 ' move right
0011 LOCATE UFO_X, 0
0012 PRINT "A"
0013 UFO_X = UFO_X + 1
0014 IF UFO_X < 32 GOTO @LOOP
0015 UFO_X = 31
0016 UFO_F = 1
0017 ' move left
0018 @UFO1
0019 LOCATE UFO_X, 0
0020 PRINT "A"
0021 UFO_X = UFO_X - 1
0022 IF UFO_X >= 0 GOTO @LOOP
0023 UFO_X = 0
0024 UFO_F = 0
0025 GOTO @LOOP


今回は思い切ってプログラムを変更しました。
変更点は以下の通りです。
1)移動のために使っていた変数Xを今後のために変数UFO_Xに変更した。
2)ゲームループの中にUFOの移動プログラムがあるが右へ移動と左へ移動するプログラムを判断するためのフラグ変数UFO_Fを作った。
3)ゲームループを一つにした
4)プログラムに注釈を加えた。

UFOの移動は変数UFO_Fの値が0の時右へ移動、0でない時に左へ移動します。
右へ移動するプログラムも左に移動するプログラムもUFOの一つの動作を表しています。
そしてこの動作は同時には起きません。
この様に同じキャラクタのプログラムでありながら同時に実行されることがなくそれらが集まることでUFOが多彩な動きをすることができるこのようなプログラムをタスクと呼んでいます。

要するにUFOにとって0011行から0016行までが右移動のタスク、0018行から0025行までが左移動のタスクになります。
前回のサンプルはUFOを画面左上に表示し終了しました。
たった一度の表示なのでこのUFOを移動させることはできません。
なぜなら…移動とは物体が違う位置に動くことなのでたった一度の表示は静止を意味します。
要するにUFOを移動しようと思うならプログラムも実行し続けないといけません。
そこでプログラムを実行し続けるためにループ処理をしました。
サンプルプログラムは下記の通りです。

■プログラム
0001 @LOOP
0002 CLS
0003 LOCATE 0, 0
0004 PRINT "A"
0005 GOTO @LOOP

■実行結果
A


このプログラムで絶え間なくUFOは画面に表示されていますが…
問題がありますね?
問題点は以下の2つです。
1)画面が乱れている
2)UFOが動いていない。

画面が乱れているのは絶え間なく画面を消してはUFOを表示しているので我々には乱れて見えるのです。
この状況を解決するためにはゲーム中で使われている『時間』について説明が必要ですがここでは省略します。
そこで対策として表示が乱れない程度の待ち時間を作ります。

■書式
VSYNC フレーム数
指定されたフレーム数だけ待ちます


ではサンプルを変更してみましょう。

■プログラム
0001 @LOOP
0002 VSYNC 1
0003 CLS
0004 LOCATE 0, 0
0005 PRINT "A"
0006 GOTO @LOOP

■実行結果
A


これで画面の乱れがなくなりました。
しかしUFOは移動しませんね。
なにがいけないか解りますか?

プログラムのことが解らなくても問題が何かに気付いていないといけません。

現在のプログラムはUFOの表示位置を LOCATE 命令で指定してますがその位置は毎回X方向が0でY方向が0の位置ですよね。

同じ位置に表示しているんだからUFOは移動せずに0,0の位置に停止しているわけです。
では表示位置を変更するためにはどうしたら良いでしょうか?

LOCATE 命令で指定する位置を定数でなく変更できる数にしなければなりません。

そうです。変数を使う必要があるということですね。

ここではUFOを右方向に移動してみましょう。
X方向だけ変化すればいいのでX方向の位置を表すために変数Xを使用します。

■プログラム
0001 X = 0
0002 @LOOP
0003 VSYNC 1
0004 CLS
0005 LOCATE X, 0
0006 PRINT "A"
0007 GOTO @LOOP


変数Xには最初の値(初期値)を入れておきます。
そしてこの変数Xを LOCATE 命令で使用します。
これを実行してみてください。

結果は前と同じです。

これで移動する準備ができただけでまだ移動してはいません。
移動するためにはこの変数Xの値が変化しなければいけないのです。
そこで変数Xの値を変化させてみます。

■プログラム
0001 X = 0
0002 @LOOP
0003 VSYNC 1
0004 CLS
0005 LOCATE X, 0
0006 PRINT "A"
0007 X = X + 1
0008 GOTO @LOOP


このプログラムを実行するとUFOは右に移動したはずです。
移動しましたか?
ただまだこれは未完成ですからね。

0007行目の X = X + 1 は変数Xの値に1を足して変数Xに入れるという意味です。
これでX方向が+1されて右にひとつだけ移動します。
0008行目のGOTO文で@LOOPにジャンプしまた表示するわけです。