“RUN” それは魔法の言葉

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

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

もう一つやらなきゃいけないことがあった。
ハイスコアリストは、新規登録のみで済むように出来たけど、コンフィグ設定を記憶させたいなら、更新が必要。

更新するにはUPDATE文を使う。

UPDATE config SET clearstage=1 WHERE ID=1"

コンフィグ設定は1レコードしかないので、WHERE句では、ID=1を決め打ちでいい。
SET句の後は、カラム名とその値を設定する。
このSQL文は、どのステージまで到達したかを記録するもの。clearstageはデータベースのカラム名
実際にはステージ数じゃなくて、ステージデータのテキストファイルの何行目という情報にする予定。
培養臼に組み込むなら、ステージクリア時に判定して、データベースに記録された到達面よりも先に進んだら、このUPDATE文を実行してあげればいいかな?

あとは、トランザクション処理とかあるんだけど、基本1レコードずつしか処理しないので、今回は特にしなくていいかな。
さぁ、ハイスコアランキングと、コンフィグ設定機能を作りますかな♪

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

テーブルを作成したら、次はレコードを登録する。
これもsql_q命令でSQL文を実行するだけ。

SQLでレコードを追加するには、INSERT文を使う。文法はSQLiteでも一般的な構文でよさそう。

INSERT INTO scorelist (score,score_name,stage,rec_date) VALUES (100,'ALX','10',datetime('now','localtime'))

INSERT文は、INTOの後にテーブル名、カッコ内に更新したいカラム名、VALUESの後に各カラムに対応する登録したい値をセットする。

培養臼Exでは、ゲームオーバー時にハイスコアがトップ10に入ったら、ネームエントリー画面にして、データベースにINSERT文で追加しよう。

データベースには、適当なレコードを登録しておき、ハイスコアのトップテンを表示するための準備をしておいて、今度はデータを取得する。
データベースからデータを取得するには、SELECT文を使う。
全データを取得するのは無駄なので、上位10レコードだけを取得する。

SELECT * FROM scorelist ORDER BY score DESC ,rec_date LIMIT 10

SELECTの後には、カラム名を書くんだけど、*で全カラムの指定。FROMはテーブル名。
ORDER BYは、並べ替え。カラム名を書いてやるとその中の値で並べ替えてくれる。
DESCのキーワードは降順。これで、スコアの高い順に並べてくれる。
最後は、LIMIT句。これで何レコード取得するかを制限できる。LIMIT 10と書いておけば、スコアのトップテンが取得できる。

こうして実行したSQLの結果は、件数がstatに、それ以外は指定した変数に格納される。
変数指定を外せば、共通でtmparrという変数に入れてくれるので、よほどのことがなければ、省略でいい。
あとは、ループを回して、表示、次のレコードに進めると処理すれば、ハイスコアランキングが出来上がる(だろう)

sql_q "SELECT * FROM scorelist ORDER BY score DESC ,rec_date LIMIT 10"
count = stat

repeat count
  mes "score="+sql_v("score")
  sql_next
loop

培養臼に組み込むなら、この程度のテストで大丈夫かなぁ。

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命令でデータベースファイルを閉じる

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