
ドローコントロールを扱う
単純な図形を描画する
画像を描画する
テキストを描画する
3Dオブジェクトを描画する
1ドローコントロールを扱う
1.1ドローコントロールを作成する
Kuinにおける2Dや3Dの高度なグラフィックスはすべて、ドローコントロールを使用して描画します。
ドローコントロールを作成するには「wnd@makeDraw(親ウインドウ,X座標,Y座標,幅,高さ,アンカーX,アンカーY,ドットバイドットにするかどうか)」とします(図1-1)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- while(wnd@act())
- do draw@render(60)
- end while
- end func
第6、7引数のアンカーは、親ウインドウのサイズが変わったときに、サイズを固定したままにするには「%fix」、一緒に拡縮するには「%scale」、右下にくっつくように移動するには「%move」とします。
第8引数は、コントロールのサイズが変わったときに描画内容を、ドットバイドット(等倍を維持)にするには「true」、コントロールのサイズに合わせて拡縮するには「false」とします。
ドローコントロールは、描画途中の結果が見えないように、一度バックバッファと呼ばれる見えないバッファに描画しておいてから最終的な画面に転送します。 9行目の「draw@render」は、バックバッファから最終的な画面に転送する関数で、いろいろな図形を描画した後にdraw@renderで転送する流れにします。
draw@renderの引数に0以外の値を渡すと、1秒間に指定回数だけ画面が更新(FPS)されるように、待機して時間を調整します。 例えば引数に60を渡すと、1秒間に60回画面が更新されるようになります。 ゲームを作る場合は60か30を指定することが多いです。 0を渡すと待機せずに描画結果の転送だけを行います。
実行すると図1-2のようになります。

1.2背景色を変える
draw@render関数で画面を転送したときに、バックバッファは自動でクリアされます。 このクリア時の背景色は変更でき、またクリアを自動ではせずに手動で行うようにもできます。
クリア時の背景色はデフォルトでは黒ですが、これを変更するには「draw@clearColor(色)」とします(図1-3)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- do draw@clearColor(0xFFCC6666)
-
- while(wnd@act())
- do draw@render(60)
- end while
- end func
色は16進数で2桁ずつ「0x不透明度赤緑青」と指定します。 例えば青は「0xFF0000FF」になります。 また白と黒は定数が定義されており、白(0xFFFFFFFF)は「draw@white」と書け、黒(0xFF000000)は「draw@black」と書けます。
実行すると図1-4のようになります。

draw@render関数の呼び出し時に自動でクリアをしないようにするには、事前に「autoClear(false)」を呼び出しておきます。 この場合「draw@clear()」を呼び出すことで手動でクリアできます。
1.3描画先のドローコントロールを切り替える
「draw@」ライブラリでの描画や操作はすべて、最後に作成したドローコントロールに対して行われます。 この操作対象のドローコントロールを切り替えるには「draw@target(ドローコントロール)」とします(図1-5)。
- var wndMain: wnd@Wnd
- var draw1: wnd@Draw
- var draw2: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @draw1 :: wnd@makeDraw(@wndMain, 0, 0, 797, 900, %fix, %fix, false)
- do @draw2 :: wnd@makeDraw(@wndMain, 803, 0, 797, 900, %fix, %fix, false)
-
- while(wnd@act())
- do draw@target(@draw1) {操作対象を@draw1に切り替え}
- do draw@clearColor(0xFFCC6666) {背景色を赤にする}
- do draw@render(0) {@draw1のバックバッファを転送してクリア}
- do draw@target(@draw2) {操作対象を@draw2に切り替え}
- do draw@clearColor(0xFF6666CC) {背景色を青にする}
- do draw@render(60) {@draw2のバックバッファを転送してクリア}
- end while
- end func
実行すると図1-6のようになります。

2単純な図形を描画する
2.1線分を描画する
線分を描画するには「draw@line(始点X,始点Y,終点X,終点Y,色)」または「draw2d@line(始点X,始点Y,終点X,終点Y,線の太さ,色)」とします(図2-1)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- while(wnd@act())
- do draw@line(1500.0, 100.0, 100.0, 800.0, 0xFFFFFF00)
- do draw2d@line(100.0, 100.0, 1500.0, 800.0, 5.0, 0xFFFFFF00)
- do draw@render(60)
- end while
- end func
draw@line関数は高速に描画できますが、アンチエイリアス処理は行われず、線の太さも指定できません。 単純な描画を行いたいとき以外はdraw2d@line関数を使ったほうが綺麗です。
実行すると図2-2のようになります。

2.2四角形を描画する
塗りつぶしの四角形を描画するには「draw@rect(始点X,始点Y,幅,高さ,色)」または「draw2d@rect(始点X,始点Y,幅,高さ,色)」とし、塗りつぶさない線だけの四角形を描画するには「draw@rectLine(始点X,始点Y,幅,高さ,色)」または「draw2d@rectLine(始点X,始点Y,幅,高さ,線の太さ,色)」とします(図2-3)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- while(wnd@act())
- do draw@rect(100.0, 100.0, 100.0, 200.0, 0xFF00FFFF)
- do draw@rectLine(300.0, 100.0, 100.0, 200.0, 0xFF00FF00)
- do draw2d@rect(500.0, 100.0, 100.0, 200.0, 0xFF00FFFF)
- do draw2d@rectLine(700.0, 100.0, 100.0, 200.0, 5.0, 0xFF00FF00)
- do draw@render(60)
- end while
- end func
draw@rect関数やdraw@rectLine関数は高速に描画できますが、アンチエイリアス処理は行われず、線の太さも指定できません。 単純な描画を行いたいとき以外はdraw2d@rect関数やdraw2d@rectLine関数を使ったほうが綺麗です。
実行すると図2-4のようになります。

2.3円を描画する
塗りつぶしの円を描画するには「draw2d@circle(中心X,中心Y,半径X,半径Y,色)」とし、塗りつぶさない線だけの円を描画するには「draw2d@circleLine(中心X,中心Y,半径X,半径Y,線の太さ,色)」とします(図2-5)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- while(wnd@act())
- do draw2d@circle(200.0, 200.0, 100.0, 100.0, 0xFFFF00FF)
- do draw2d@circleLine(500.0, 200.0, 100.0, 100.0, 5.0, 0xFFFF00FF)
- do draw@render(60)
- end while
- end func
実行すると図2-6のようになります。

3画像を描画する
3.1画像ファイルを描画する
画像ファイルを描画するには「draw@makeTex(ファイルパス)」で読み込んでから、「draw@Tex.draw(転送先X,転送先Y,転送元X,転送元Y,転送元幅,転送元高さ,色)」で描画します(図3-1)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- var tex: draw@Tex :: draw@makeTex("res/dot_back_side.png")
-
- while(wnd@act())
- do tex.draw(0.0, 0.0, 0.0, 0.0, 800.0, 450.0, draw@white)
- do draw@render(60)
- end while
- end func
読み込める画像ファイルの形式は、「.png」「.jpg」「.dds」です。
「res/dot_back_side.png」に画像ファイルを用意して実行すると図3-2のようになります。

3.2画像を拡縮して描画する
画像を拡縮して描画するには「draw@Tex.drawScale(転送先X,転送先Y,転送先幅,転送先高さ,転送元X,転送元Y,転送元幅,転送元高さ,色)」とします(図3-3)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- var tex: draw@Tex :: draw@makeTex("res/dot_back_side.png")
-
- while(wnd@act())
- do tex.drawScale(0.0, 0.0, 1600.0, 900.0, 0.0, 0.0, 800.0, 450.0, draw@white)
- do draw@render(60)
- end while
- end func
実行すると図3-4のようになります。

3.3画像を回転して描画する
画像を回転して描画するには「draw@Tex.drawRot(転送先X,転送先Y,転送先幅,転送先高さ,転送元X,転送元Y,転送元幅,転送元高さ,回転中心座標X,回転中心座標Y,回転角度(ラジアン),色)」とします(図3-5)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- var tex: draw@Tex :: draw@makeTex("res/dot_back_side.png")
-
- while(wnd@act())
- do tex.drawRot(0.0, 0.0, 800.0, 450.0, 0.0, 0.0, 800.0, 450.0, 0.0, 0.0, lib@pi / 4.0, draw@white)
- do draw@render(60)
- end while
- end func
実行すると図3-6のようになります。

4テキストを描画する
4.1テキストを描画する
テキストを描画するには「draw@makeFont(フォント名,サイズ,太字かどうか,斜体かどうか,プロポーショナルかどうか,文字の間隔)」でフォントを読み込んでから、「draw@Font.draw(描画先X,描画先Y,テキスト,色)」で描画します(図4-1)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- var font1: draw@Font :: draw@makeFont(null, 60, false, false, false, 60.0)
- var font2: draw@Font :: draw@makeFont(null, 60, false, false, true, 0.0)
-
- while(wnd@act())
- do font1.draw(0.0, 0.0, "Hello, world!", 0xFFFF9999)
- do font2.draw(0.0, 120.0, "Hello, world!", 0xFF9999FF)
- do draw@render(60)
- end while
- end func
draw@makeFontの第1引数のフォント名を「null」にすると、Windowsに標準でインストールされている「"Meiryo UI"」になります。
draw@makeFontの第5引数を「false(等幅)」にしたときは、文字間隔は第6引数で指定した幅になります。 「true(プロポーショナル)」にしたときは、文字間隔は自然になるように自動調整されますが、さらに第6引数で指定した幅が加算されるため幅を増減させることができます。
実行すると図4-2のようになります。

4.2テキストを中央揃えや右揃えで描画する
テキストを中央揃えや右揃えで描画するには「draw@Font.calcWidth(テキスト)」で幅を取得してから描画します(図4-3)。
- var wndMain: wnd@Wnd
- var drawMain: wnd@Draw
-
- func main()
- do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
- do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
-
- var font: draw@Font :: draw@makeFont(null, 60, false, false, true, 0.0)
-
- while(wnd@act())
- const text: []char :: "Hello, world!"
- var width: float :: font.calcWidth(text)
- do draw@line(800.0, 0.0, 800.0, 900.0, 0xFFFFFF99)
- do font.draw(800.0, 0.0, text, 0xFF9999FF)
- do font.draw(800.0 - width / 2.0, 120.0, text, 0xFF9999FF)
- do font.draw(800.0 - width, 240.0, text, 0xFF9999FF)
- do draw@render(60)
- end while
- end func
実行すると図4-4のようになります。

53Dオブジェクトを描画する
(この記事は執筆中です!)