“RUN” それは魔法の言葉

私とコンピュータの思い出を、だらだらと綴ります。最近はHSP3でのゲーム作り日記です

57.ゲーム&ウォッチのマンホールを作ろう その4

2021年の初エントリーです。今年もよろしくお願い致します。

通行人を移動する処理をどうしようかと考えた。
通行人を左端(右端)から出現させたら、配列に場所を持たせて、カウントアップしていこうかと最初は思っていた。

でも、同時に10人程度表示されるようになるので、判定処理も面倒そうだなと却下。

そして、ふと思いついたのが、ビット演算。10カ所の表示位置があるので、それぞれビットとして扱い、ビットシフトさせることにした。
SHIFT関数を使って、右にビットを1つずつシフトしていく。

スタート:1000000000
      ↓ SHIFT
     0100000000
      ↓ SHIFT
     0010000000

ビットシフト演算のいいところは、シフトした一番右端のビットが、そのままなくなること。
だから、出現させて10回シフトさせたら、自動的に通行人が消えることになる。
出現させるには、一番左のビットを1にすればいい。10ビットなので左端は512。出現のタイミングで、512を足すだけでいい。
方向は上下で逆になるけど、考え方は同じ。
このビットの数値を変数に持ち、今度は各ビットごとに0か1かを取り出して、通行人のグラフィックのオン/オフを切り替えることにした。

ソースから抜粋したが、この移動処理に、ミスターマンホールが受け止めたらスコアを足して、いなければミスの処理にGOSUBで飛ぶようにもしている。

pa_cont: %通行人表示制御と判定

FOR k=10 TO 1 STEP -1 %10カ所分を処理

%とりあえず通行人の表示を消す
 GR.HIDE(pa_obj[1,k])
 GR.HIDE(pa_obj[2,k])

%上段の判定
%各ビットが1になっているかを判定

 IF BAND(upa,2^(k-1)) = 2^(k-1) THEN
  GR.SHOW(pa_obj[1,k])
  SW.BEGIN k
   SW.CASE 7 %穴があいてるポジションだったら
    IF pos=1 THEN %マンホールマンがそのポジションにいるか?
     sc+=1
     SOUNDPOOL.PLAY sp,3,0.99,0.99
     VIBRATE vpt[],-1
    ELSE
     miss+=1
     GR.HIDE(pa_obj[1,k])
     upa-=2^(k-1)
     mis_pos=1
     GOSUB miss_1
     K=11
    ENDIF
    SW.BREAK
   SW.CASE 4
    IF pos=2 THEN
     sc+=1
     SOUNDPOOL.PLAY sp,3,0.99,0.99
     VIBRATE vpt[],-1
    ELSE
     miss+=1
     GR.HIDE(pa_obj[1,k])
     upa-=2^(k-1)
     mis_pos=2
     GOSUB miss_1
     k=11
    ENDIF
    SW.BREAK
  SW.END

 ENDIF

%下段の判定

 IF BAND(dpa,2^(k-1)) = 2^(k-1) THEN
  GR.SHOW(pa_obj[2,k])
  SW.BEGIN k
   SW.CASE 7
    IF pos=4 THEN
     sc+=1
     SOUNDPOOL.PLAY sp,3,0.99,0.99
     VIBRATE vpt[],-1
    ELSE
     miss+=1
     GR.HIDE(pa_obj[2,k])
     dpa-=2^(k-1)
     mis_pos=4
     GOSUB miss_1
     K=11
    ENDIF
    SW.BREAK
   SW.CASE 4
    IF pos=3 THEN
     sc+=1
     SOUNDPOOL.PLAY sp,3,0.99,0.99
     VIBRATE vpt[],-1
    ELSE
     miss+=1
     GR.HIDE(pa_obj[2,k])
     dpa-=2^(k-1)
     mis_pos=3
     GOSUB miss_1
     K=11
    ENDIF
    SW.BREAK
  SW.END
 ENDIF
NEXT
RETURN

56.ゲーム&ウォッチのマンホールを作ろう その3

次は通行人を表示する。液晶パターンを見ると、通行人は上下ともに10か所に表示される。

ミスターマンホールと同じように、配置する座標は、あらかじめ調整しながら調べたものをベタ打ち。
そして、いったん全部表示して、非表示にしておく。
あとは通行人を登場させて、1サイクルで、一つ右(左)に動かして行く。

ゲーム&ウォッチでは、1つのサイクルで、物が動いていく。そして実際に遊んだことがある人はおわかりだろうが、得点の増加とともに、ゲームのテンポが速くなっていく。その部分を実現させるのによい命令があった。

TIMER.SET xxx
この命令を書くと、設定した数値のミリ秒ごとにタイマーイベントが発生する。

ON TIMER:というラベルを書いておけば、タイマーイベントがあると呼び出される。サブルーチンと同じ。処理が終わったらTIMER.RESUMEを書くと、元の処理に戻る。
これで、特定の時間間隔で、通行人を動かす処理を呼び出せばよい。
そして、得点が上がるごとにセットするタイマー値を短くすれば、その分速く通行人も動くようになる。

TIMER.SET 100 %100ミリ秒ごとにイベントを発生
…

ON TIMER: %100ミリ秒ごとにこのラベル以下のプログラムが実行される
・通行人を1つずつ進める
・そのほかの処理

TIMER.RESUME %元の処理に戻る

年内はこのエントリーで終了です。
来年もよろしくお願い致します。

55.ゲーム&ウォッチのマンホールを作ろう その2

まずは、主人公ミスターマンホールの表示と、移動から作成する。
ミスターマンホールの表示位置は4か所。4つのボタンを押すと、それぞれのポジションに移動する。

これを再現するのは、GR.TOUCHでタッチした座標が、画面に表示したゲーム&ウォッチのボタンの範囲と一致しているかを見ればいい。
4か所どのポジションになるかを判定して、あらかじめ非表示で配置したミスターマンホールの画像を1つだけ表示する。

f:id:CORO3:20201218001541j:plain

IF文のネストがダサいけど、動けばいいのでお許しをw

 GR.HIDE p_obj[pos]

 GR.TOUCH touched,x,y

 x=x/rate:y=y/rate

 IF x >=94 & x <=162 THEN
  IF y >=414 & y <=482 THEN
   pos=1
  ELSEIF y >=532 & y <= 600 THEN
   pos=3
  ENDIF
 ELSEIF x >=842 & x<=909 THEN
  IF y >=414 & y <=482 THEN
   pos=2
  ELSEIF y >=532 & y <= 600 THEN
   pos=4
  ENDIF
 ENDIF

 GR.SHOW p_obj[pos]

これで、ミスターマンホールの移動は完成。

54.ゲーム&ウォッチのマンホールを作ろう その1

キューブ避けゲームも、ひと段落したので、次のゲーム作成に取り掛かった。
何か凝ったゲームを作ろうとすると、途中でめげてしまいそうだったので、ゲーム&ウォッチを再現しようと考えた。

最初に作ったのは、「マンホール」。初めて自分で買ったG&Wで、めちゃくちゃ遊んだ。
f:id:CORO3:20201023215238p:plain

いざ作り始めて困ったのが、資料のなさ。
GAMEAとBがあって、200点と500点でミスがクリアされる、点数が上がるごとに通行人が増え、速度もあがるという断片的な記憶しかなかった。

そうはいっても始まらないので、まずは画像から準備した。
一から画像を書くのは、絵心もないこともあり却下。G&Wは、電池を入れた直後に液晶パターンが全部表示される。その画像をアップしているサイトがいくつかあったので、それを拝借することにした。
(あくまで個人的に楽しむためなので、ご容赦を。)
そしてその画像から、各液晶のパターンを画像編集ソフトで切り抜き、背景が透明になるように編集した。

f:id:CORO3:20201023221642j:plain
   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
f:id:CORO3:20201023221922j:plain

これと、液晶パターンを削除する加工をした画像を作成した。

BASIC!では、オブジェクトを描画した順番に、下からどんどん重なって表示していく。
なので、一番最初に背景になるG&Wの筐体とセロファンだけに加工した画像を描画して、そのあとに通行人やマンホールマンの画像を描画すれば
MSXで紹介した、スプライトのように扱える。

表示の方式はこれで確定した。