ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

MSX User'sコミュのむりやりガッチ!/MSX/三毛乱ジェロ

  • mixiチェック
  • このエントリーをはてなブックマークに追加
自作プログラムです。
プログラムコード(テキスト)は>>2に、プログラム解説・変数一覧等は>>3に掲載します。

「むりやりガッチ!」
■ゲーム内容
右の絵のデコボコに合うように左の絵を削って形を合わせるゲームです。

■操作方法
カーソルキーで「ノミ」の移動、スペースキーで削ります(写真1)。
※一気に何ブロックでも削ることは出来ますが、削ったマスを復活させる事は出来ません
出来上がったら画面下の"[ DONE ]"にカーソルを移動してスペースキーを押してください。
画面下を飛んでいる「鳥」は残り時間を表しています。赤のブロックまで到達すると強制的に判定へ移行します。

■判定
[ DONE ]をクリックするか、タイムオーバーになると判定モードへ移行します。
1つ1つ合致しているか否か判定し、1つでも間違っていたらゲームオーバー(写真3)、全て当っていたらクリア(写真2)となり次のステージへと移ります。
縦のマスは4から始まって最大16。それ以降は16マスが延々と続きます。

■最後に
久々にMSXで何か作ろうと思い立ち、プログラムも他で応用が利くように機種依存文字は使わない方向で組み上げました。
スキルがあれば他(HSP等)で作ってみたいと思います。

コメント(14)

10 ' MURIYARI GACTH! BY MICHELAN-GELO.
20 ' INITIALIZE -----
30 SCREEN1,0,0:COLOR15,0,0:KEYOFF:WIDTH32:DEFINTA-Z:DIMA(16),B(16):C=4:R=RND(-TIME)
40 ' MAKE SCREEN -----
50 GOSUB570:VPOKE8204,85:VPOKE8205,153
60 CLS:X=14:Y=1:D=10:T=30:FORI=1TOC:FORJ=1TO2:J=2:E=(RND(1)*5)-2:D=D+E:IFD>14ORD<5THENJ=1:D=D-E
70 NEXTJ:LOCATE1,I:PRINTSTRING$(14,"h"):LOCATE30-D,I:PRINTSTRING$(D,"a"):A(I)=14:B(I)=D:NEXTI:LOCATE9,18:PRINT"[ DONE ]":LOCATE1,20:PRINT"LIMIT":LOCATE1,21:PRINT"o"
80 PLAY"T150O4L16CGFEDR16CR16":GOSUB540
90 ' MAIN ROUTINE -----
100 ' ----- MOVE
110 ONINTERVAL=60GOSUB270:INTERVALON
120 S=STICK(0):IFS=3ANDX<14THENX=X+1
130 IFS=7ANDX>1THENX=X-1:IFY=18THENX=X+1
140 IFS=3ANDX<14THENX=X+1
150 IFS=1ANDY>1THENY=Y-1:IFY>CTHENY=C
160 IFS=5ANDY<17THENY=Y+1:IFY>CTHENY=18:X=14
170 PUTSPRITE0,(X*8+3,Y*8-3),3
180 IFSTRIG(0)=-1THEN210
190 GOTO120
200 ' ----- DONE OR DIG
210 IFY=18THEN310
220 ' ----- DIG
230 IFX-1<A(Y)THENA(Y)=X-1:LOCATEX,Y:PRINTSTRING$(15-X," "):PUTSPRITE0,(X*8+2,Y*8-2),2
240 PLAY "","T210S11M9000O5F16":GOSUB540
250 GOTO 120
260 ' ----- TIME LIMIT ROUTINE
270 T=T-1:PUTSPRITE1,(T*8+16,168),7,(TMOD2)+1
280 IFT<=0THEN310
290 RETURN
300 ' JUDGEMENT -----
310 LOCATE9,18:PRINT"JUDGEMENT!":PUTSPRITE0,(0,0),0:INTERVALOFF:PLAY"T150O5L16CEDFEA":GOSUB540
320 G=A(1)+B(1):H=0
330 FORI=1TOC:F=A(I)+B(I):B$=" GOOD! ":C$="O5A16R16"
340 LOCATE1,I:PRINTSTRING$(29-B(I)+(F-G),"h")
350 IFG<>FTHENH=1:B$=" N G ! ":C$="O3C8"
360 LOCATE3,I:PRINTB$:PLAY"","T150SM9000"+C$:GOSUB540
370 NEXT
380 IFH=1THEN480
390 ' CLEAR -----
400 LOCATE9,18:PRINT" CLEAR!!! "
410 PUTSPRITE1,(0,0),0
420 PLAY"T150L16O5ABAGFEDEGA":GOSUB540
430 LOCATE8,21:PRINT"PUSH SPACE KEY"
440 IFSTRIG(0)=0THEN440
450 C=C+1:IFC=>16THENC=16
460 GOTO 60
470 ' GAME OVER -----
480 LOCATE9,18:PRINT"GAME OVER "
490 PLAY"T150L16O5GFDECR16O6C":FORI=0TO64:PUTSPRITE1,(T*8+16-(I\2),I+168),4:NEXT:GOSUB540
500 LOCATE8,21:PRINT"PUSH SPACE KEY"
510 IFSTRIG(0)=0THEN510
520 C=4:GOTO60
530 ' ----- PLAY STOP ROUTINE
540 IFPLAY(0)=-1THEN540
550 RETURN
560 ' CHARACTER MAKING -----
570 Z$= CHR$(&B00001110)
580 Z$=Z$+CHR$(&B00010011)
590 Z$=Z$+CHR$(&B00110001)
600 Z$=Z$+CHR$(&B00011001)
610 Z$=Z$+CHR$(&B00011110)
620 Z$=Z$+CHR$(&B00100100)
630 Z$=Z$+CHR$(&B11000000)
640 Z$=Z$+CHR$(&B11000000)
650 SPRITE$(0)=Z$
660 Z$= CHR$(&B00000111)
670 Z$=Z$+CHR$(&B00011110)
680 Z$=Z$+CHR$(&B00101100)
690 Z$=Z$+CHR$(&B11111100)
700 Z$=Z$+CHR$(&B00111100)
710 Z$=Z$+CHR$(&B00000110)
720 Z$=Z$+CHR$(&B00000000)
730 Z$=Z$+CHR$(&B00000000)
740 SPRITE$(1)=Z$
750 Z$= CHR$(&B00000000)
760 Z$=Z$+CHR$(&B00011000)
770 Z$=Z$+CHR$(&B00101100)
780 Z$=Z$+CHR$(&B11111100)
790 Z$=Z$+CHR$(&B00111110)
800 Z$=Z$+CHR$(&B00001110)
810 Z$=Z$+CHR$(&B00000011)
820 Z$=Z$+CHR$(&B00000000)
830 SPRITE$(2)=Z$
840 RETURN
850 ' THANK YOU FOR PROGRAMING
860 ' AND PLAYING!
870 ' 2008 MAY MICHELAN-GELO.
変数一覧
A(n),B(n) 各ラインのブロック数
C     縦のマス数
D     ブロック数(ステージ作成用)
G     クリア判定用(ブロック数の合計)
H     成功か否かの判定フラグ(0:成功、1:失敗)
I,J    FOR-NEXT用
S     カーソルキー入力用
T     残り時間
X     ノミの横位置
Y     ノミの縦位置
B$,C$   クリア判定の表示用
Z$     キャラクター作成用

解説(ブロックの判定)
・最初の1行目を「正解している」と仮定して、左右のブロック数を合計します(例として右12、左7→合計19)。
・2行目以降はブロックの合計が19ならば合っていると証明できます(右10ならば左9で合致)
・2行目以降全て合計が19ならばクリアと判定します。
・1つでも合計が違うならばゲームオーバーと判定します。


感想、バグ報告、意見等はこのトピのレスでお願いします。
実機( FS-A1ST, Z80モード) で動かしてみました。

感想:
いやぁ、なんか凄く懐かしい気分になりました(笑)
ゲーム内容もシンプルでわかりやすく、素直に入り込めました (^o^)
あえて難を挙げさせていただきますと、カーソルの移動が速すぎる(これもゲーム性?)ので、
STICK(0), STRIG(0) ではなく INKEY$ を使った方が良いかなと思いました。

テキスト貼り付け方式:
フロッピー上の空ファイルにコピペするだけでMSXから読める状態になるので、
非常にお手軽な感じがしました。
ASCII形式なので、MSX側の LOADに時間がかかりますが、SAVEし直せば問題ないですし。
まずはバグ報告。
120行目、
120 S=STICK(0) の後のIF文は不要です。
あっても影響しないので修正していませんでしたm(_ _)m
あとトピ本文、
「>>2と>>3」は「>>1と>>2」の間違いです。
滅多に立てないもので不慣れで申し訳ございませんm(_ _)m

>nc30toriさん
いえいえ。あんなので宜しければ。
とりあえず「公開」サンプルですので皆様の本文に関する意見もどしどしと。
歳は取ってもMSXへの思いはあのままです。

>HRA!さん
感想ありがとうございます。
カーソルですが、メインルーチンを移動とスペースキーの判定に絞って簡略化した為(残り時間の処理はONINTERVALという割り込みで処理の為メインルーチンを圧迫しません)ちょっと制御出来てないのは申し訳ございません。
ただINKEY$ですとキーバッファが溜まってしまい動作的にみっともなくなりますのでSTICK命令で処理しました。

あとテキスト貼り付け方式が好評?のようで。
やり方は少々面倒ですが(プログラムをアスキー形式でフロッピーに保存→windpwsのデスクトップ等にファイルを移動→メモ帳を立ち上げてファイルを投入→保存)機種依存文字制限を省けば確実な方法かと思えます。
ちなみに、本文と>>2のような解説はベーマガを参考にしています。
ベーマガのプログラムの紹介ってこんな感じで細かく丁寧にプレゼンしていたのを記憶していましたので
記憶を頼りに「これも必要かな」と書いてました。

やはりプログラム発表という意味で「解析」される方へのアドバイスは必須だと思ってます(特にバグが抜け出せない方にとっては)。
いくらサンプルとはいえ今ではなかなか出来ない事の場を設けてもらった事は私も大変感謝しております。
> ただINKEY$ですとキーバッファが溜まってしまい

↓こんなサブルーチンでもキーバッファクリアできます。
1000 IF INKEY$<>"" THEN 1000 ELSE RETURN
(キーバッファは、最大でも 255文字しか溜まらないので、無限ループには
なりません。)

POKE文で強引にキーバッファをクリアする裏技(?)もありますが、
わかりにくくなるので秘密にしておきます (^_^;

> ベーマガのプログラムの紹介ってこんな感じで細かく丁寧にプレゼン

あの紹介記事って、作者の人が自分で書くので、ソフトごとに微妙に書き方が
違っているのが面白かったですね。
実際、私が掲載されたときも、投稿時に用意した原稿がそのまま載りましたから (^_^;
掲載されると多少のお金がもらえたわけですが、しっかり「原稿料」という扱いになってました。

ベーマガ風だと、Dr.D とか影さん、編さん、つぐみさんの CheckerFlag (でしたっけ?)
もほしくなりますね(笑)

>HRA!さん
ありがとうございます。
なるほど。キーバッファが無くなるまでループ、ですね。

ちなみに私は投稿はしましたが採用されませんでした(明日のスタープログラマーには載った事がありました)。
あのプログラム+プレゼン能力が試されるというのも本当に「有望な若手」を育てる環境だったんですね。

checker Flagは誰かのレビューという形でw
HSPというプログラム言語でむりやりガッチ!をwindowsで遊べるように作ってみました。

http://www.ma.mctv.ne.jp/~miche/zatsu/gacth.lzh

まだ効果音とか作ってない暫定版のようなバージョンですが操作感覚と基本システムはMSX版と同じ(追加要素として判定時にNGのラインの色を変えてあります)です。
プログラム見させて頂きました。
ちょっと、バグの原因になりそうな記述がありましたので、コメントしますね。
280行のインターバルタイマ割り込みで呼ばれる記述ですけども、
280 IFT<=0THEN310
判定処理への分岐は、THEN310ではなく、THEN RETURN 310とすべきです。
そうしないと1ステージ終わる毎にスタックがどんどん埋まっていきます。
幸い、MSX-BASICは優秀なので、この場合はスタックオーバーフローはおきないはずですが・・・・。
機種(MSX以外のBASICや他言語など)によっては、ゲームを続けているとエラーが出てしまう可能性がありますね。

さらに言うならば、ここから直接結果判定への分岐は避けて、メインループ(たとえば180行などで)で、T=0になった場合に強制的に判定処理に飛ばした方が安全です。
なぜなら、230行で削る処理を実行している最中にタイマー割り込みがかかった場合(正確に言うなら230行でA(Y)に代入してからPRINT文までの間に割り込みがかかった場合)、実際に変数に持っている値と、画面表示が一致しないまま判定処理に進んでしまい、見かけ上誤判定が起きてしまう可能性があるからです。



あとは、個人的趣味で記述の方法が気にいらないとかはありますけどね(笑)。
まあそんなのはホントに趣味の問題なので深くは追求しませんけども、たとえば、STICK(0)の値からXを計算する付近(120〜140行目)とかだと、
X=X+(S=7ANDX>1ANDY<>18)-(S=3ANDX<14) と、書くと、1行にまとめられるかなー、とか。
でも見た目はIFの方がわかりやすいですよね。

こういった議論とかもできると、お互いのスキル向上にもなるんではないかなとも思います。
当時は、投稿者と読者が話し合える機会なんてありませんでしたし。
> X=X+(S=7ANDX>1ANDY<>18)-(S=3ANDX<14)

これ懐かしいです! (^-^)

知らない人のために解説しますと、BASICでは、比較演算子(=,<,>,<=,>=,<>)
の比較結果が成立した場合 -1 を、不成立の場合 0 を返します。
(S=7ANDX>1ANDY<>18) が成立する場合、X=X+(-1)+(0) となり、X=X-1 と同じ意味に。
(S=3ANDX<14) が成立する場合、X=X+(0)-(-1) となり、X=X+1 と同じ意味になります。
※S=7 と S=3 の条件があるので、両方同時に成立することはありません

BASICは、実行時に逐次解析しながら処理されるので、見た目が短いと処理速度も
速くなりますね。

MSX-BASICは、プログラム入力時にも、ある程度の解析処理を実施していますが、
予約語(IF, THEN, AND 等)を1バイトに変換する程度なので、行をまとめるのは効果が大きいです。

処理速度が必要なゲームを作るときにはぜひ使いたい技ですね。
>えりーさん
ご指摘ありがとうごさいます。
議論大歓迎です。自分では気付かないところが見えるので公開してよかったと思っています。
IF文を使わない計算はちょっと今回迷いました。というのも
IFY>CTHENY=C
IFY>CTHENY=18:X=14
この2行がある為に単純に1を足したり-1を足したりする訳には、と思いまして。
自分もキャラ定義(570-840行)の部分をもっと簡略化出来るのですが「機種依存文字は使わない」と決めていたので
SPRITE$(0)="xxxxxxx"
とかしたかったのですが、16進数の&Hではなくあえて0と1だけで作成できる&Bにしました。

>HRA!さん
元々1画面に収めようと頑張ってましたが、ごちゃごちゃになると応用が利きにくいと思いましたので
今回1画面制約を無視して作ってました。
機会があればどこまで縮めれるかもやってみたいですね。
> IF〜THEN〜ELESって、「0なり-1」を返されることで判定されていたのですね?

IF文は、IF 条件式 THEN 文 の形で、「条件式が 0 以外の場合」に「文」が実行されます。

IF 1 THEN ?"TRUE" ELSE ?"FALSE"

この 1 を 0 に変えて動作を比べてみてください。行番号を入れなければ、即時に実行されます。
1 のときと、0 のときで、それぞれ TRUE, FALSE と出力が変わるのを確認できると思います。
ちなみに、? は、PRINT の省略記述です (^_^;

この辺は、BASIC言語としての挙動なので、ほかの BASIC でも同じように動作するはずです。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

MSX User's 更新情報

MSX User'sのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング