“RUN” それは魔法の言葉

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

122.HSPでゲームを作ろう:技術研究 ジョイスティックに対応しよう「PAD設定さん」

ゲームウォッチぐらいなら、キーボードだけで操作しても問題ないけど、シューティングゲームやアクションゲームを作るときは、ジョイスティックにも対応させたい。
HSP3では、標準モジュールでジョイスティックに対応するものがあるのだが、いかんせん使い方に関するよい資料を見つけられなかった。

そんな中で一番情報が揃っていたのが、GENKIさん作のPAD設定さんだった。
mclab.uunyan.com

PAD設定さんの「m_joystick.hsp」をincludeした後、標準のstick命令を、JStrick命令に書き換えるだけ。これだけ。
あっさりとカーソルキーとジョイスティックのどちらでも自機を移動できるようになった!

単純にこれだけでなく、接続したジョイスティックのIDの取得や、ボタンのコンフィグに対応できるような便利な命令群が拡張されている。
少なくとも、シューティングゲームを作るなら、ショットのボタンを自分で好きなボタンに割り当てられるようにしたいので、ありがたく使わせていただきたいと思います。

<余談>
試したのは、メガドラミニのUSBパッドが最初。十字キーは普通に読み込めたが、その他のボタンは一般的な配置で取得できるものとはちょっと違っていたので、今回使ったPAD設定さんのようなモジュールを使って、キーコンフィグができるようにしないといけないかな。
また、むかーし買ったHORIのアナログスティック付きのPSライクなコントローラも引っ張り出して繋いでみたら、こっちも問題なし。
しかも左のアナログスティックでも動く!ソース書き換えたの一か所だけですけど。すげー。
アナログスティックを使うゲームは、今のところ作る予定もアイデアもないけど、覚えておこう。

121.HSPでゲームを作ろう:技術研究 2Dスプライト機能 その3

初めは、プログラミングガイドを読んでいたが、PCの画面で読んでもイマイチ頭に入ってこない。なので、サンプルシューティングゲーム「マジカル タマホーキ」のソースをプリントアウトして、何の処理をしているかメモを取りながら勉強した。

f:id:CORO3:20220226175455j:plain

年齢的なものもあるが、この方法が一番しっくりくる。今の子供は紙の教科書だけでなく、タブレットや、オンラインで授業を受けなくてはならないが、理解できるのだろうか。
と、余計な話は置いておいて。

HSPの標準スプライト機能は、単純に座標を指定して表示するだけではなく、便利な機能が満載だった。

まずはアニメーション。パターンを登録するときに、es_patanim命令を使うと、連続するパターンを一括で登録できて、さらに、指定したフレーム数で画像を切り替えてくれる。

スプライトの移動を自動でやってくれる命令がある。
es_apos命令は、X座標の移動量、Y座標の移動量、移動スピードを指定すると、勝手に動いてくれる。
シューティングゲームなどで、直線的に動くモノに使えば、移動処理をいちいち書かなくていい。
例えば、自機の弾なんかもこれが使える。

も一つ移動系で便利なのは、es_aim命令。
これは、X座標、Y座標、移動スピードを指定すると、その座標に向かって勝手に動いてくれる。
これもシューティングゲームでよくある、自機を狙ってくる敵弾や、ホーミングする敵に使える。
sin、cosを使って、移動方向を決めなくてもいいのが便利。

あとは、弾幕で使えそうな、移動方向を指定して移動し続けてくれるes_adir命令がある。

es_aimes_aposes_adirの3つだけで、シューティングゲームの基本の動きを作れるのがすばらしい。

そして、スプライト同士の衝突判定も簡単。es_check命令が用意されている。
指定したスプライトと衝突しているスプライトNoを知ることができる。

es_checkと合わせて使うと便利なのが、es_type命令と、es_find命令。

es_typeは、任意のタイプ番号をスプライトに設定できる命令。
ビットで処理するため、数字は1,2,4,8…と、2のn乗の値を設定する。

これだけだと何のことやらとなるんだけど、es_findes_checkでは、このタイプ番号を持つスプライトだけを検索、チェック対象にできる。

使い方の一つに、自機のショットと敵の当たり判定がある。
例えば、ショットはタイプ番号2、敵はタイプ番号4と設定したとする。

es_findで、タイプ番号2のスプライトを探して、es_checkで、そのスプライト番号と、タイプ番号が4のスプライトが衝突しているかを判定できる。

普通に考えると、ショット1発、敵1体ごとの座標を配列などに格納しておいて、判定するとかを考えるのだけど、配列を使わなくて単純なループだけで衝突判定ができる。

これをもとに、それっぽい何かwを作ったのがこちら。
youtu.be

BASIC!で、初めて作ったキューブ避けゲームの画像を使って、キューブが張り付く処理も加えてみた。これも上で説明した命令群で簡単に作れた。

これから作ろうとしているアイデアの大半を、実現できそうということが分かったことが、大きな収穫だった。

#include "hsp3dish.as"

screen 0,800,600,0
es_ini ;スプライト初期化

buffer 2
picload "bg.png"

buffer 3 ;バッファを作成
picload "meta.png" ;画像を読み込み
es_size 42,23 ;パターンサイズ
es_pat 0,0,0 ;パターンを読み込み
buffer 4 
picload "cube.png"
es_size 53,58,60
es_patanim 1,3,0,0,10
es_patanim 11,3,0,0,0
gsel 0 ;操作バッファを0に戻す
  px=300:py=200
  es_set 0,px,py,0,0,1

  gamecnt=0
  cubenum=99
  showcube=0

  randomize

*main
  redraw 0
  stick key,1+2+4+8
  if key&1 : px=px-5 ;カーソル左
  if key&4 : px=px+5 ;カーソル右
  if key&2 : py=py-5 ;カーソル上
  if key&8 : py=py+5 ;カーソル下
  px=limit(px,0,800-42)
  py=limit(py,0,600-23)
  
  if key&128 : end ;ESCでゲーム終了(暫定)

  pos 0,0
  gcopy 2,0,0,800,600
  color 255,0,0:gmode 2
  pos 0,0:mes "残りCUBE="+str(cubenum)
  gamecnt++
  es_pos 0,px,py
  gosub *addenemy
  es_draw ,,0,1,100

  ;自機の当たり判定はいったんコメントアウト
  ;es_check hitf,0
  ;if hitf>0 : assert

  redraw 1
  await 1000/60
  goto *main
  
*addenemy
  ;キューブの追加処理
  if showcube<3 and cubenum>0 {
    es_exnew snum,100,200,1
    es_set snum,800,rnd(600),1,,100
    es_type snum,2
    es_apos snum,-(rnd(10)+1),0
    showcube++
    cubenum--
  }

  ;キューブを自機に向かって飛ばすか?
  if gamecnt\50=0 {
    es_find n,2,100
    if n>0 {
      ;向きを変えるキューブの属性を取得
      es_get nocurve,n,ESI_OPTION
      es_getpos n,cubex,cubey
      ;もし、一度も向きを変えていなくて、X座標が300未満なら向きを変える
      if nocurve=0 and cubex>300 {
        es_aim n,px,py,1000
        es_setp n,ESI_OPTION,1 ;向きを変えたことをOPTIONに持たせる
      }
    }
  }

  ;キューブの当たり判定処理
  n=100
  repeat
  es_find n,2,n
  if n=-1 : break
  es_check cubeco,n,4
  es_getpos n,cx,cy,0
  if cx<=0 or cy<=0 or cy>=600-58 or cubeco>0 {
    es_get pt,n,ESI_CHRNO
    es_type n,4
    es_apos n,0,0
    es_chr n,pt+10
    showcube--
  }
  n+
  loop
    
  return

120.HSPでゲームを作ろう:技術研究 2Dスプライト機能 その2

標準スプライト機能のマニュアルも用意されている。
www.onionsoft.net
これと、スプライト機能を使用した、サンプルシューティングゲーム「マジカルタマホーキ」のソースが公開されたので、参考にする。
珠音ちゃんサンプルゲーム マジカルタマホーキ

まずは、hsp3dish.as をincludeする。
次に、スプライト機能を使うためのおまじない、es_ini命令を書く。

スプライトの定義には、画像ファイルがそのまま使える。
picload命令でバッファに画像を読み込んでおく。透過色を使いたいので、ここでも画像はPNG形式を使う。
そして、es_size命令で、1つのキャラが何ドット×ドットなのかを定義した後、es_pat命令で、バッファのどの座標から取り込むかパターン番号と、座標を指定する。
こんな感じ。

#include "hsp3dish.as"

es_ini ;スプライト初期化

buffer 3 ;バッファを作成
picload "meta.png" ;画像を読み込み
es_size 42,23 ;パターンサイズ
es_pat 0,0,0 ;パターンを読み込み

gsel 0 ;操作バッファを0に戻す

es_patはスプライト定義だけなので、表示するにはスプライトを登録する必要がある。
es_setで、スプライト番号、X,Y座標、es_patで設定したパターン番号を指定する。
そして、dishのおまじないである、redraw 0 ~ redraw 1で1サイクルを囲むのと、awaitを入れるんだけど、スプライトの描画はes_draw命令でまとめて行う。
スプライトを表示するプログラムはこんな感じになる。

#include "hsp3dish.as"

es_ini ;スプライト初期化

buffer 3 ;バッファを作成
picload "meta.png" ;画像を読み込み
es_size 42,23 ;パターンサイズ
es_pat 0,0,0 ;パターンを読み込み

gsel 0 ;操作バッファを0に戻す
es_set 0,320,200,0

*main
  redraw 0
  es_draw
  redraw 1
  await 1000/60
  goto *main

119.HSPでゲームを作ろう:技術研究 2Dスプライト機能 その1

2022年のHSPコンテストにも、応募したいなと思い、ネタをいくつか検討中。
そのうちの一つを作るために、技術研究としていくつかやってみる。
まずは、2Dスプライト機能を使ってみる。

スプライトといえば、自分の知識の中ではMSXの物だけ。
このブログでも、久しぶりに使ってみた。
coro3.hatenablog.jp

スプライトの利点は、背景とは別扱いなので、キャラクタを動かしても、背景との重ね合わせを気にしなくてもよいこと。
でも、HSP3Dishでは、redraw 0 実行時点で画面は全部消えてしまい、どっちにしても毎回背景とキャラを描かなくてはならない。
さらに、celputで、透過PNGを読み込めるので、背景との重ね合わせも簡単で、ほぼスプライトと同じ感覚で使えていた。

では、なぜスプライト機能なのか。
HSP3.6のスプライト機能には、ゲームを作るのに便利な機能が満載だったからなのだ。
自分で使いたいなと思ったのは、アニメーション、勝手に動いていけ!命令w、スプライトが何のキャラなのかを識別するタイプ番号定義かな。
さて、次回からは少しずつ標準スプライトのサンプルをもとにして、使い方と動きを確認してみよう。