“RUN” それは魔法の言葉

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

151.HSPでゲームを作ろう:技術研究 データベースを使ってみる その2

さて、サンプルプログラムの動きは分かったので、次は培養臼のハイスコア記録処理を考える。

とりあえずハイスコア記録用のテーブル構成をこんな感じにした。
 テーブル:scorelist
 カラム
  インデックス:ID(プライマリーキー、自動でカウントアップ)
  スコア:score
  ネーム:score_name
  クリアステージ:stage
  記録日時:rec_date

で、普通のデータベースなら、型を決めるので、SQLiteの型を調べてみたのだが、日付型がないのね…

NULL NULL値
INTEGER 符号付整数。1, 2, 3, 4, 6, or 8 バイトで格納
REAL 浮動小数点数。8バイトで格納
TEXT テキスト。UTF-8, UTF-16BE or UTF-16-LEのいずれかで格納
BLOB Binary Large OBject。入力データをそのまま格納

日付の処理は、どうやら関数を使うらしいので、とりあえず気にせず文字列でぶっこめば良いみたい。

ということで、サンプルプログラムを見ながら、テーブル作成のSQLを走らせる。

sql_q "CREATE TABLE IF NOT EXISTS scorelist (ID INTEGER PRIMARY KEY, score , score_name , stage , rec_date)"

ここからはHSP3ではなく、SQLの文法の話になるな。
CREATE TABLE文で、新しくテーブルを作るのだが、存在していなければという条件「IF NOT EXISTS」が付いている。
なぜこうしているかというと、スクレレでは、sql_open命令で指定したDBファイルが存在していなければ、自動で作成してくれる。
作成してくれても、テーブルは何もない状態。このままでは、SQLを実行できないので、CREATE TABLEを入れている。
存在していれば、実行されないのでテーブルが重複して作られたエラーにもならない。

ただ、培養臼では、ハイスコアを記録するためのDBなので、初めからトップテンのレコードが存在する状態にしたいと思っている。
なので、実際に作りこむときは、別の処理でチェックしよう。

長くなってきたのでもう少し続く。

150.HSPでゲームを作ろう:技術研究 データベースを使ってみる その1

培養臼のエクストラバージョンでは、ハイスコアをランキング形式で記録できる機能を作ろうと思っている。
テキストで管理すると、並べ替えが面倒なので、データベースを使いたい。

SQLite」というデータベースなら、HSP3から操作するための拡張モジュールsqlele(スクレレ)がバンドルされていた。
複雑なデータ取得や、大量のデータを扱うわけではないので、これで十分だろう。

そして、SQLは、まったくの素人ではないので、抵抗感もなく、すんなり始められるだろう。

早速サンプルプログラムを動かしてみる。

#include "sqlele.hsp"

  sql_open "サンプル.db"

  ; 「ログテーブル」がない場合、テーブル作成
  sql_q "CREATE TABLE IF NOT EXISTS [ログテーブル] (ID INTEGER PRIMARY KEY, [内容])"

  ; レコードを追加
  sql_q "INSERT INTO [ログテーブル] ([内容]) VALUES (datetime('now','localtime'))"

  ; テーブル内のデータをすべて抽出
  sql_q "SELECT * FROM [ログテーブル]"
  count = stat

  mes "記録件数 : " + count + " 件"
  repeat count
    mes "ID=" + sql_v("ID") + ", 内容=" + sql_v("内容")
    sql_next
  loop

  sql_close

ん?テーブルもカラムも日本語??
自分でDBを設計するなら、絶対に日本語は付けないから面食らったけど、別に自分で作るときは日本語を付けなければいいだけなので。

流れは、こんな感じか。

  1. スクレレをincludeする
  2. sql_open命令でデータベースファイルを開く
  3. sql_q命令でクエリを発行。
  4. sql_v命令でレコードごとのカラムの値を取得。
  5. ループさせつつ、sql_next命令で次のレコードにポインタを進める
  6. 処理が終わったらsql_close命令でデータベースファイルを閉じる

まぁ、データベースの使い方自体は、言語が違ってもそれほど変わらないから、わかりやすかったかな。
さて、これを踏まえて、組み込む準備をしますか。

149.HSPでゲームを作ろう:培養臼(BAIOUS) その26

ラストはおまけ。
↓のエントリーで書いた、ポーズ機能を作り直した話を少々。
coro3.hatenablog.jp

この時の実現方法は、ポーズキーを押したら、gosubでポーズルーチンに飛ばし、無限ループにして、次にポーズキーが押されるまで、元の処理にreturnしないというものだった。
いろいろと情報を見てると、この方法は一部ヤバかった。
無限ループにしたときは、await命令を入れてないとだめというルールがあったのだ。

ただし、そのために1つだけHSPスクリプトを作る上で約束事があります。 HSPでは「キーを押さないと進まないなどの無限にループになる可能性のある部分では、 必ずwaitかawait命令を入れる必要がある」という約束事を覚えておいてください。

HSP3プログラミングマニュアルより

で、いくらポーズ機能を告知していなくても、このままヤバいものを公開しておくのも嫌なので、ポーズ機能を作り直すことにした。
今のルーチンへ単純にawait 5とかを入れるだけでも良かったが、この方法だと、redrawができないので、新たに何か表示を付け加えられない。
そこでもう少しいろいろ調べたら、スプライトの描画を行うes_drawには、処理を保留するフラグの引数があった。

値     マクロ名          内容
―――――――――――――――――――――――――――――
  0  ESDRAW_NORMAL        すべての処理を実行する
  1  ESDRAW_NOMOVE        移動処理を保留する
  2  ESDRAW_NOANIM        アニメーションを保留する
  4  ESDRAW_NOCALLBACK    コールバックルーチンを保留する
  8  ESDRAW_NODISP        表示を保留する
 16  ESDRAW_NOSORT        ソートを保留する

es_drawのヘルプより

複数の処理を保留したければ、HSP3ではお約束の通り、足した数を指定すればよい。
今回、ポーズ機能で使用したのは、1の移動処理保留と、2のアニメーションの保留。
なので、引数には3を指定すれば、その間、スプライトは表示されるけど、es_adirの自動移動は停止するし、もともとアニメパターンで定義していたスプライトは、アニメーションを停止できた。

こんな感じ。

es_draw ,,(pauseflg=1)*3,0,10000 ;スプライト描画

ポーズボタンを押したら、pauseflgを1にする。1になっていれば、論理式が成立して3を、通常の状態なら0を処理保留フラグとして指定する。
あとはポーズ中に移動を受け付けないようにしたり、ゲーム内カウンタがintの最大値を超えないように、カウンタリセットの処理を加えた。
何より、redraw 0~redraw 1の処理を行うので、ポーズ中は、画面内に「PAUSE」の文字を点滅表示できるようになったので、わかりやすくなった。

培養臼の作成に関するエントリーは、いったんこれで終了。
次からは、次作に向けての準備などについて書いて行こうと思う。

148.HSPでゲームを作ろう:培養臼(BAIOUS) その25

前回の続き。
ということで、自ウィンドウがアクティブじゃないときにキースキャンをしないフラグ設定すれば終わりじゃん!と思ったら、getkeyにそんなフラグはないのね…(できるなら誰か教えて偉い人w)

幸い、アクティブなウィンドウIDを取得することができ、HSP以外のウィンドウがアクティブ=自ウィンドウが非アクティブかは、-1が返ってくるか否かで判定できることがわかった。なので、アクティブウィンドウIDを調べて、0以上のときだけJStick命令を実行すればよさげ。
いちいちアクティブウィンドウIDを調べるコードを書かなきゃだめかと思って調べると、「hspdef.as」をインクルードしておけば、ginfo_actと書けば、現在のウィンドウIDが分かるらしい。便利。

ということで、培養臼のソースに組み込み始めたのだが、ふとこの処理をこれから先作るプログラムにもやらなきゃダメなのかと思った。正直避けたい。
「PAD設定さん」は、幸いソースも公開されている。そこで、JStick命令内で使用しているgetkeyを、非アクティブウィンドウ時は取得しないように処理を加えることにした。

これで、非アクティブウィンドウ時は、キー操作を受け付けなくできた。
と、安心していたら、ジョイスティック操作はまだ受け付ける…
どうやら、ジョイスティックの操作を取得する処理部分も、ウィンドウのアクティブ状態に関わらずすべて受け付けるらしい。

ということで潔くJStick命令の冒頭で、非アクティブウィンドウならそのままreturnするようにした。
培養臼で試す限りは、問題なさそうなので、これで対処を終了した。
新しいPCとかに移行したり、バージョンアップしたときは注意が必要だな。