CastleDB/Haxe

CastleDB

CastleDBをHaxeで使う方法

概要

このページではCastleDBをHaxeで使う方法を紹介します



1. データベースの作成

まずはデータベースを作成します。

シートの作成

CastleDBを起動したら「Create a sheet」をクリックして、シートを作成します。

001.png

シート名には「enemies」と入力して「Create」ボタンをクリックします。

002.png

項目の作成

次に「Add a column」をクリックして項目を作成します。

003.png

項目のプロパティが表示されるので、以下のように入力します。

004.png
  • Column name: id
  • Column type: Unique Identifier
  • Required: チェックを入れたままにする

項目名を「id」、データ型は「ユニークID」、必須入力とする、という設定となります。 設定できたら、Createをクリックします。

続けて、作成した項目「id」のところにマウスを移動させて右クリックし、ポップアップから「Add Column」を選びます。

005.png

項目のプロパティは以下のように入力します。

006.png
  • Column name: hp
  • Column type: Integer
  • Display: Default
  • Required: チェックを入れたままにする

これは敵のHPとなります。 入力できたらCreateをクリックして項目を作成します。

データ入力

項目ができたので、敵のデータを入力します。「Insert Line」をクリックします。

007.png

するとデータ行が追加されます。

008.png

id項目が「#MISSING」となっているのでユニークIDを設定します。idは「Slime」として、hpには「10」と入力します。

009.png

入力できたら、入力した行を右クリックして、ポップアップから「Insert」を選びます。

010.png

idには「Dragon」、hpには「9999」と入力します。

011.png

これでデータベースは完成です。

保存

メニューから「File > Save As...」を選んでファイル名を「MyDB.cdb」として任意の場所に保存します。

012.png

2. castleライブラリのインストール

以下のコマンドで、castleライブラリをインストールします

haxelib install castle

3. テストプロジェクトの作成

任意の場所でテストプロジェクトを作成します。

flixel tpl -n "Test"

4. CastleDBの読み込み

Project.xmlの設定

以下の記述で castleライブラリを有効にします

  <!-- castleライブラリ有効 -->
  <haxelib name="castle"/>

MyDB.cdbの配置

作成したデータベース「MyDB.cdb」を 「Test/source/dat」(datフォルダは新規作成) に配置します

020.png

sourceフォルダに配置するのは、Haxeのコードから直接読み込んでマクロで展開するためです。

Data.hxの作成

CastleDBを展開するモジュール「Data.hx」を作成します。場所は「Test/source/dat」に配置します。

021.png

Data.hxは以下のように記述します。

package dat;

private typedef Init = haxe.macro.MacroType<[cdb.Module.build("dat/MyDB.cdb")]>;

上記コードは、シート名や項目名をマクロで展開するものです。これによりCastleDBのデータにアクセスしやすくなります。

Haxeで読み込む

Project.xmlに「MyDB.cdb」を読み込めるように assets path を登録します。

  <!-- MyDB.cdbを読み込めるようにする -->
  <assets path="source/dat/MyDB.cdb" />

MenuState.hx に読み込み処理を記述します。

package;

import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.text.FlxText;
import flixel.ui.FlxButton;
import flixel.util.FlxMath;
import openfl.Assets;
import dat.Data;

/**
 * A FlxState which can be used for the game's menu.
 */
class MenuState extends FlxState
{

  /**
   * Function that is called up when to state is created to set it up. 
   */
  override public function create():Void
  {
    super.create();

    // CDBファイルの読み込み
    var content:String = openfl.Assets.getText("source/dat/MyDB.cdb");
    // ロード実行
    Data.load(content);
    // 値の取得
    trace("Slime: HP=" + Data.enemies.get(Slime).hp);
    trace("Dragon: HP=" + Data.enemies.get(Dragon).hp);

実行すると、HPの値を取得することができます。

Slime: HP=10
Dragon: HP=9999

カラムのマッピング

カラムに指定したデータ型に対応する、Haxeにおける型は以下のようになります

カラム説明 / 例
行データシート名の先頭を大文字にしたもの"enemies"の場合は、"Enemies"という型になる
Unique Identifierシート名+Kind"enemies"シートの場合、"EnemiesKind?"という型になる
TextString
BooleanBool
IntegerInt
FloatFloat
ColorInt
Enumerationシート名_カラム名"enemies"シートの"attr"カラムの場合は、"Enemies_attr"でアクセスできる
Flagscdb.Types.Flags<シート名_カラム名>ビットが立っているかどうかを判定するには cdb.Types.Flags<T> のメソッド利用する
Reference指定したシートの型"enemies" シートなら "Enemies" になる
FileStringcdbファイルからの相対パス。指定がない(#MISSING)の場合は空文字「""」となります。
ImageStringMD5のキーのみ。現時点では画像の読み込みはサポートしていない
Tilecdb.Types.TilePos?contains the tileset file and size、 the x/y position and optional width/height (by default it is 1)
Listcdb.Types.ArrayRead?<シート名_カラム名>cdb.Types.ArrayRead?<T>のメソッドで、イテレート、インデックスアクセスやサイズが取れる
CustomSheetName_ColumnName?values are converted on-the-fly to the enum created as it has been declared.
DynamicDynamicdata as-it.
Data Layercbd.Types.Layer<SheetName?>you can decode the layer by passing the Data.sheetName.all array to the decode() function.
Tile Layercbd.Types.TileLayer?you can decode the layer by using the t.data.decode() function. It will automatically decompress data and will return an Array of 16-bits values. If the tile layer is in tile/ground mode、 this gives you width x height values. If it is in object mode、 see the object layer encoding section.

Unique Identifierの詳細

例えば、enemiesシートのUnique Identifierに「Slime」がある場合、以下の記述でアクセスできます。

    // スライムの情報を取得
    var e:Data.Enemies = Data.enemies.get(Data.EnemiesKind.Slime);
    trace(e);

以下のように省略してアクセスすることも可能です。

    // スライムの情報を取得
    var e:Data.Enemies = Data.enemies.get(Slime);
    trace(e);

Referenceとの連携

Unique Identifierをわざわざ定義する理由は、Referenceとの連携があるからです。 例えば、敵の出現グループ(RPGでスライムx3が現れるなど)のテーブルを定義したいときに、ドロップダウンで選択可能になります。 敵出現テーブルを作成して、カラムを「Reference」にすると参照するシートを選ぶことができます。

UniqueIdentifier002.png

ここで敵定義テーブルの「enemies」を選ぶと、ドロップダウンで敵の種類を選ぶことができます。

UniqueIdentifier003.png

なお、Referenceを指定したカラムにはUnique Identifierを指定しますが、実際にはそのデータの参照(行データ)が含まれることになります

Enumerationの詳細

値は定義した順番で「0」から連番の数値となります。 例えば、enemiesシートのattrカラムに、「Phys,Gun,Fire」が定義されている場合は「0,1,2」となります

    trace(Data.Enemies_attr.Phys); // 0
    trace(Data.Enemies_attr.Gun);  // 1
    trace(Data.Enemies_attr.Fire); // 2

また、COUNTで項目の最大数、NAMESで項目の文字列を取得することが可能です。

    trace(Data.Enemies_attr.COUNT); // 3
    trace(Data.Enemies_attr.NAMES); // [Phys,Gun,Fire]

Flagsの詳細

例えばFlagsのカラム名に"flag"、Possible Valuesに"[a,b,c,d]"を指定した場合は、以下の方法でビットが立っているかどうかをチェックできます。

    // cdb.Types.Flags<T>.has()で判定
    var e:Data.Enemies = Data.enemies.get(Data.EnemiesKind.Slime);
    if(e.flag.has(Data.Enemies_flag.a)) {
      trace("a is on");
    }
    if(e.flag.has(Data.Enemies_flag.b)) {
      trace("b is on");
    }
    if(e.flag.has(Data.Enemies_flag.c)) {
      trace("c is on");
    }
    if(e.flag.has(Data.Enemies_flag.d)) {
      trace("d is on");
    }

また、COUNTで項目の最大数、NAMESで項目の文字列を取得することが可能です。

Listの詳細

例えば、敵テーブルにドロップアイテムのカラム「dropitem」を追加し、50%で1番、30%で2番、20%で4番のアイテムをドロップするようにしました

List001.png

CastleDBのList型は Haxeの Array とほぼ同等で、lengthでサイズを取得したり、インデックスアクセスができます。以下はイテレートする例です。

    var e:Data.Enemies = Data.enemies.get(Data.EnemiesKind.Slime);
    for(info in e.dropitem) {
      trace(info.item, info.ratio);
    }

カラムのマッピングをコードで確認する

以下のコマンドで、マッピングがどうなっているのか確認できます

haxe Data.hx -D dump=pretty -lib castle

Tips

シート内の全要素にアクセスしたい

シート名.all ですべての要素にアクセスできます

    // equipmentシートのすべての要素にアクセス
    for(info in MyDB.equipment.all) {
    }

データ数を取得する

シート名.all.length でデータ数を取得できます

  trace(MyDB.equipment.all.length);

参考