FreeBASIC マニュアルのトップに戻る

FreeBASIC 拡張ライブラリ

目次→フォーラム→FreeBASIC→補足FreeBASIC Extended Library←オリジナル・サイト

FB 拡張ライブラリ 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

 FreeBASIC 拡張ライブラリは、コミュニティで開発された、FreeBASIC プログラミングのための、移植性のある、ライブラリ・セットです。
 拡張ライブラリは、多くの一般的に用いられる、ゲーム指向で、多目的な API を含んでいます。
 ユーザーが自由に使えるように、BSD 形式ライセンスで、許諾します。
拡張ライブラリの使い方
1.教本: カエル跳びゲーム(Frogger風)
2.拡張ライブラリー・アルゴリズム
3.拡張ライブラリ・テンプレート

教本: カエル跳びゲーム(Frogger風)

 sir_mud さんの作品です。

この教本では、拡張ライブラリーを使うと、単純なゲームを、簡単に、きわめて速く作ることができることを、示します。
この教本は、FreeBASIC 言語の実用的知識を持っている人を対象としています。
このゲームは、ライブラリーが提供する機能の、ごく一部分を使っているだけです。
拡張ライブラリーを使ってコードを書くと、プログラム・コードを作る全過程が、より速くより簡単になり、その過程での面倒が、なくなります。
画像をロードして操作するために、画一的で詳細なコードをたくさん書く必要はありません。
拡張ライブラリーは、高品質で信頼できる関数およびクラスを、提供します。
ここで、完全なソース・コードと画像[frogger.zip 8kb]をダウンロードできます。さあ飛び込んでみましょう。

上のコードで、描画モジュールのいくつかの部分を含めています。スプライト・クラス操作モジュールBMPファイル・ローダーと、付属の色定義です。
さらに、ext に、オプションを設定しました。
一番目は、コンパイル時間を速くするために使われます。私たちは、提供されるコンテナー・クラスのどれも使わないからです。
二番目は、これは小さな例で、依存状態を最小にしておきたかったので、使用されます。
他に利用できるオプションの一覧は、ドキュメントの本文を参照ください。

ここで、これらを後でコントロールするために使う、いくつかのマジックナンバーを、定義します。

これらは、このゲームのスプライト(妖精)の全てを保持する変数です。
配列は、複数のインスタンスを持つオブジェクトのために使われます。
スプライト・クラスがすることの1つは、それ自体の位置を保持することです。
これは、描画だけでなく、衝突検出にも使われます。 そして、それが衝突発見ならびにスケッチのために使われます。

ここで、ヒーローのために使う画像をロードします。
画像をロードして、必要により、それを回転し、再着色する方法について、注意して下さい。

お分かりのように、自動車や丸太やスイレンの葉でも、同じことをします。

ここで、競技場の描画を設定します。そして、後で画面を描き直す必要がある時に、これを簡単に配置できるように、格納します。

最後の部分で、ゲームをループし始める前に、スイレンの葉が、適切な場所に表示されるように、位置を設定します。また、ヒーローがいつ勝ったか伝えることができるようにします。
更に知りたい場合は、下のリンクを参照ください!

より多くの情報



この種類の目次に戻る↑ 補足に戻る

拡張ライブラリー・アルゴリズム

sir_mud さんの作品です。

ext/Algorithms は、要素の範囲を操るための、いろいろな一般的なアルゴリズムを提供します。
要素は、記憶域に隣接して保管され、一般に、範囲の中の最初の要素へのポインターと、範囲の端を過ぎるポインターによって表示されます。
アルゴリズムは、これらが様々な種類(UDT オブジェクトでさえ)の要素の範囲で使えるという意味で、総括的です。アルゴリズムが操作する要素について、一般に、ある必要最小限の条件がありますが。

単純な例として、下のコードは、配列で、要素を再編成するために、ext.QuickSort を使います:


# include once "ext/algorithms/quicksort.bi"

dim array(1 to 5) as integer = { 4, 1, 3, 5, 2 }

ext.QuickSort(array())

for i as integer = 1 to 5
    print "(" & array(i) & ")" ;
next : print
Sleep

そして、下の出力を生成します:


(1)(2)(3)(4)(5)

別の例として、次のコードは、ext.ReplaceIf を使って、文字列中の数字を、文字 x に置換します:


# include once "ext/algorithms/replaceif.bi"

function IsNumeric ( byref elem as const ubyte ) as ext.bool
    return 0 < instr( "0123456789", chr(elem) )
end function

var text = "abc 123 def"

dim first as ubyte ptr = strptr(text)
dim last as ubyte ptr = first + len(text)

ext.ReplaceIf( first, last, @IsNumeric, asc("x") )
print text
Sleep

そして、下の出力を生成します:


abc xxx def

明らかに、文字列の中で、数字を置換する最も効率的な方法ではないですが、文字列は、アルゴリズムが何を行っているかを示す簡単な方法を提供します。
この過程は、UDT 型要素で使う場合と類似しています。
次のコードは、Person オブジェクトの範囲を変形するために ext.Transform を使い、出力するために、ext.ForEach を使うからです。:


# include once "ext/algorithms/transform.bi"
# include once "ext/algorithms/foreach.bi"

type Person
    name as zstring ptr
    age as ubyte
    ismale as integer
end type

sub OutputPerson ( byref p as Person )
    var result = "( " & *p.name
    result &= ", " & p.age
    result &= ", " & *iif( p.ismale, @"male )", @"female )" )
    print result
end sub

function ChangeGender ( byref p as Person ) as Person
    var tmp = p
    tmp.ismale = not tmp.ismale
    return tmp
end function

fbext_Instanciate( fbext_ForEach, ((Person)) )
fbext_Instanciate( fbext_Transform, ((Person)) )

const N = 5
dim people(1 to N) as Person = _
{ _
    ( @"John", 34, -1 ), _
    ( @"Jacob", 12, -1 ), _
    ( @"Jennifer", 24, 0 ), _
    ( @"Joseph", 55, -1 ), _
    ( @"Jasmine", 18, 0 ) _
}

ext.ForEach( @people(1), @people(1) + N, @OutputPerson )
ext.Transform( @people(1), @people(1) + N, @people(1), @ChangeGender )
ext.ForEach( @people(1), @people(1) + N, @OutputPerson )
Sleep

fbext_Instanciate( ..., ((Person)) ) 行は、外部テンプレート・ライブラリーの一部です。拡張ライブラリ・テンプレート を参照下さい。
ここでは、この行が、ext.Transformext.ForEach が、Person 要素の範囲で使えるようにするということを知っておけば十分です。
デフォルトで、すべてのアルゴリズムは、内蔵の数値 (IntegerDoubleなど) と、String 要素で、動作します。

より多くの情報



この種類の目次に戻る↑ 補足に戻る

拡張ライブラリ・テンプレート

sir_mud さんの作品です。

FreeBASIC 拡張ライブラリーは、テンプレート(template)の例示化用のプリプロセッサーAPIを含んでいます。これはユーザ定義マクロの形をした、数個の汎用コードです。
テンプレートの1つの(典型的な)利点は、これがコード重複を最小にすることができるということです。
たとえば、配列で UByte 要素の範囲のなかで繰り返す、手続き、アルゴリズムです:


' Gets an iterator `it` to the first element in the range [first,last) for
' which `*it = value` is true, or `last` if there is no such element.

function Find ( first as ubyte ptr, last as ubyte ptr, value as ubyte ) as byte ptr
    do while first < last
        if *first = value then exit do
        first += 1
    loop
    return first
end function

ただ、効果的な手続きは、単に UByte 要素の範囲の中で走査できるだけです。
同じ振る舞いを備えた手続きが必要で、それが Integer 要素で働く場合、1つのオプションは、Find を多重定義して、二番目のバージョンを定義することです:


' Gets an iterator `it` to the first element in the range [first,last) for
' which `*it = value` is true, or `last` if there is no such element.

function Find overload ( first as ubyte ptr, last as ubyte ptr, value as ubyte ) as ubyte ptr
    do while first < last
        if *first = value then exit do
        first += 1
    loop
    return first
end function

' Gets an iterator `it` to the first element in the range [first,last) for
' which `*it = value` is true, or `last` if there is no such element.

function Find ( first as integer ptr, last as integer ptr, value as integer ) as integer ptr
    do while first < last
        if *first = value then exit do
        first += 1
    loop
    return first
end function

どれだけのコード(またドキュメンテーション!)がこのシナリオで複写されるか、注目してください。
ただ一つの違いは署名です。署名は、UByteInteger のいずれかのパラメーター型を指定します。
他の要素型の範囲を含むために、Find の機能性を広げるために、一般的に、同じコードは、それぞれのために複写されなければなりません。これは、テンプレートが便利な点です:


# include once "ext/templates.bi"

' ElementType - the type of elements iterated through.
# macro Find_Define( __, ElementType )
:
    ' Gets an iterator `it` to the first element in the range [first,last) for
    ' which `*it = value` is true, or `last` if there is no such element.
    function Find overload ( first as fbext_TypeName(ElementType) ptr, _
                             last as fbext_TypeName(ElementType) ptr,  _
                             value as fbext_TypeName(ElementType)      _
    ) as fbext_TypeName(ElementType) ptr
    
        do while first < last
            if *first = value then exit do
            first += 1
        loop
        return first
    
    end function
:
# endmacro

fbext_Instantiate( Find, ((ubyte)) )
fbext_Instantiate( Find, ((integer)) )
fbext_Instantiate( Find, ((double)) )

新しいコードは、ext/templates.bi を含めることから始まります。ext/templates.bi は、テンプレート・システムで使われるマクロを、すべて含んでいます。
次に、Find_Define と呼ぶ、1つの、マクロを定義します。Find_Define は、2つのテンプレート・パラメーターを持っています。
テンプレート・パラメーターの2番目は、ElementType と呼ばれる要素の型で、Findが、繰り返すことができます。
この型を指定するために、マクロの fbext_TypeName が、パラメータ・リストで使われます。
このマクロは、ElementType の値を、fbc が理解できるものに、翻訳します。
最後に、手続きテンプレート Find は、fbext_Instantiate(最初の引数として、テンプレートの名前、この場合は Find、をとるマクロ)で、インスタンス化されます。
第2の引数は、template arguments の順番; 括弧で囲まれた、1つ以上の値です。この順番は、テンプレート引数として Find_Define に渡されます。
ここで、最後の3行の振る舞いは、


Find_Define( __, (ubyte) )
Find_Define( __, (integer) )
Find_Define( __, (double) )

に類似しています。背後で行われた何かとともに。

このように、3つの Find が多重定義されます。これは、ひとつだけの手続き定義で、要素の異なる型で繰り返します。
手続き記述コメントは、振る舞いは同様に一定であるという事実を強調するために、リファクタリング(ソースコードの意味・動作を保ったまま、保守性・可読性を高めるように書き直すこと。)の全体にわたって同じままです。

より多くの情報



この種類の目次に戻る↑ 補足に戻る

リンク

補足 に戻る
←リンク元に戻る プログラム開発関連に戻る
(翻訳作成)ページ歴史:2012-04-20
日本語翻訳:WATANABE Makoto

ホームページのトップに戻る

表示-非営利-継承