「技術」カテゴリーアーカイブ

【C#】【ALTSEED】【数独】パレットに×を追加。

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

引き続き、パレットの中身を実装していきます。

パレットに×を追加します。

×のフォントをフォントジェネレータで作成して実装します。

    static class Resource
    {
        private static asd.Font _fontBatsu = null;

        public static asd.Font getFontBatsu()
        {
            if (_fontBatsu == null)
            {
                _fontBatsu = asd.Engine.Graphics.CreateFont("batsu.aff");
            }
            return _fontBatsu;
        }

これを使用します。

クラスは・・・PaletteSquareObjectを拡張しましょうか。

    class PaletteBatsuSquareObject : PaletteSquareObject
    {
        public PaletteBatsuSquareObject(int row, int col) : base(row, col)
        {
            _valueText.Font = Resource.getFontBatsu();
        }

        public void showBatsu()
        {
            _valueText.Text = "×";
        }

        public new void setPosition(asd.Vector2DF pos)
        {
            _x = _row * width + (int)pos.X;
            _y = _col * height + (int)pos.Y;

            _backTexture.Position = new asd.Vector2DF(_x, _y);
            _valueText.Position = new asd.Vector2DF(_x + fontOffsetX - 8, _y + fontOffsetY);
        }
    }

コンストラクタで、フォントを追加した物に指定、showBatsu()で×を表示します。

また、×の表示位置を調整するため、setPosition()をオーバーライドしています。

    class SquareObject
    {

        public void hide()
        {
            _valueText.Text = "";
        }

SquareObjectクラスにhide()を追加しました。これでわかりやすく文字を消すことができます。

これらをPaletteクラスに実装します。

    class Palette
    {
        PaletteBatsuSquareObject PaletteBatsuSquareObject = new PaletteBatsuSquareObject(0, -1);

        public void setEngine()
        {
            asd.Engine.AddObject2D(_texture);
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getBackTexture());
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getTextObject());
                }
            }
            asd.Engine.AddObject2D(PaletteBatsuSquareObject.getBackTexture());
            asd.Engine.AddObject2D(PaletteBatsuSquareObject.getTextObject());
        }

        public void show(asd.Vector2DF pos)
        {
            palettePosition = new asd.Vector2DF(pos.X, pos.Y - 64);
            _texture.Position = palettePosition;
            _texture.Texture = Resource.getPalette();
            int value = 1;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].setPosition(pos);
                    paletteSquareObjects[row, col].setValue(value);
                    value++;
                }
            }
            PaletteBatsuSquareObject.setPosition(pos);
            PaletteBatsuSquareObject.showBatsu();
        }

        public void hide()
        {
            _texture.Texture = null;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].hide();
                }
            }
            PaletteBatsuSquareObject.hide();
        }

やることは他の文字と同じで、Altseedエンジンへの追加、表示、消去を行います。

実行結果はこんな感じです。

まあまあですかね。

【C#】【ALTSEED】【数独】パレットの作成

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

パレットの中身を実装していきます。

まず、パレットに表示する数字ですが、これは、すでに作成しているSquareObjectを利用しましょうか。

これをこのまま使用できないので、継承して機能拡張を行います。

    class SquareObject
    {
        protected int _x;
        protected int _y;
        protected int _row;
        protected int _col;
        private int _value;
        protected asd.TextureObject2D _backTexture;
        protected asd.TextObject2D _valueText;
        protected const int offsetX = 10;
        protected const int offsetY = 10;
        protected const int fontOffsetX = 19;
        protected const int fontOffsetY = 9;
        protected const int width = 64;
        protected const int height = 64;

privateからprotectedに書き換えました。

こうしなければ拡張先で変数を参照することができません。

    class PaletteSquareObject : SquareObject
    {

        public PaletteSquareObject(int row, int col) : base(row, col)
        {
        }

        public void setPosition(asd.Vector2DF pos)
        {
            _x = _row * width + (int)pos.X;
            _y = _col * height + (int)pos.Y;

            _backTexture.Position = new asd.Vector2DF(_x, _y);
            _valueText.Position = new asd.Vector2DF(_x + fontOffsetX, _y + fontOffsetY);
        }
    }

パレットの数字はマウスの位置によってコロコロ変わるので、自由に表示位置を変更できるようにします。

このクラスをPaletteクラスで使用します。

    class Palette
    {
        private asd.Vector2DF palettePosition;
        private const int width = 192;
        private const int height = 256;
        private asd.TextureObject2D _texture;
        PaletteSquareObject[,] paletteSquareObjects = new PaletteSquareObject[3, 3];

        public Palette()
        {
            _texture = new asd.TextureObject2D();
            for(int row = 0; row < 3; row++)
            {
                for(int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col] = new PaletteSquareObject(row, col);
                }
            }
        }

        public void setEngine()
        {
            asd.Engine.AddObject2D(_texture);
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getBackTexture());
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getTextObject());
                }
            }
        }

        public void Show(asd.Vector2DF pos)
        {
            palettePosition = new asd.Vector2DF(pos.X, pos.Y - 64);
            _texture.Position = palettePosition;
            _texture.Texture = Resource.getPalette();
            int value = 1;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].setPosition(pos);
                    paletteSquareObjects[row, col].setValue(value);
                    value++;
                }
            }
        }

        public void Hide()
        {
            _texture.Texture = null;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].setValue(0);
                }
            }
        }

まず、コンストラクタでPaletteSquareObjectを3×3で作成します。

Show()でPaletteSquareObjectの座標設定と、数値設定(これで数字が表示される)、Hide()で数字を消します。

あと、Altseedエンジンにオブジェクトを追加する処理を書き換えました。全部Paletteクラスの中で直接追加した方が都合がいいと思いました。

実行結果はこうなりました。

だんだん形になってきましたね。

【C#】【ALTSEED】【数独】パレットの表示、非表示

前回までの状況はこちら。

最新ソースはこちら(gitHub)。

https://github.com/takishita2nd/sudokuGUI

今回はマウスクリックで数字を入力するためのパレットを表示させます。

パレットには、こんな画像を用意しました。

これをマウスをクリックした箇所に表示させます。

それと同時に、マウスカーソルが示すマスの色も固定させます。

そして、パレットの外をクリックすると、パレットを消してマスの色も元に戻します。

まず、パレットクラスを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Palette
    {
        private asd.Vector2DF palettePosition;
        private const int width = 192;
        private const int height = 256;
        private asd.TextureObject2D _texture;

        public Palette()
        {
            _texture = new asd.TextureObject2D();
        }

        public asd.TextureObject2D getPaletteTexture()
        {
            return _texture;
        }

        public void Show(asd.Vector2DF pos)
        {
            palettePosition = new asd.Vector2DF(pos.X, pos.Y - 64);
            _texture.Position = palettePosition;
            _texture.Texture = Resource.getPalette();
        }

        public void Hide()
        {
            _texture.Texture = null;
        }

        public bool isClick(asd.Vector2DF pos)
        {
            if(pos.X > palettePosition.X && pos.X < palettePosition.X + width
                && pos.Y > palettePosition.Y && pos.Y < palettePosition.Y + height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

getPaletteTexture()では、Altseedエンジンに追加するオブジェクトを返します。

show()でマウスのポジションを渡し、その座標にオブジェクトを設定してテクスチャを表示させます。(座標の位置は少しカスタマイズしています。)

Hide()でオブジェクトのテクスチャを消します。

isClick()では、渡されたマウスの座標がテクスチャの範囲内かどうかを返します。

これを使用して実装します。

        private bool mouseHold;
        private Palette palette = null;

:

            // パレット
            palette = new Palette();
            asd.Engine.AddObject2D(palette.getPaletteTexture());

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                if (!mouseHold)
                {
                    for (int row = 0; row < 9; row++)
                    {
                        for (int col = 0; col < 9; col++)
                        {
                            squareObjects[row, col].updateTexture(pos);
                        }
                    }
                }

                if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
                {
                    if (mouseHold)
                    {
                        if (!palette.isClick(pos))
                        {
                            palette.Hide();
                            mouseHold = false;
                        }
                    }
                    else
                    {
                        mouseHold = true;
                        palette.Show(pos);
                    }
                }

                // Altseedを更新する。
                asd.Engine.Update();
            }

今までMain関数に実装していた処理はSudokuUIクラスに移しました。(あまりMain関数にあれこれ書くのは好きじゃ無い。)

mouseHoldはマウスをクリックした状態を保持し、trueの場合はマウスをクリックされている状態で、パレットを表示している状態を示しています。

そして、mouseHold=trueのときは、マスのテクスチャの色を変える処理を行わないようにしています。

動かしてみると、こんな感じになります。

かなり、形が見えてきましたね。

【C#】【ALTSEED】【数独】マウスカーソルの移動で色を変える。

前回までの状況はこちら。

最新ソースはこちら(gitHub)。

https://github.com/takishita2nd/sudokuGUI

今回は、マウスカーソルがマスの上に移動すると、色を変化させる所までいきます。

やり方は簡単で、マスの座標の上にマウスカーソルが上に来ると、テクスチャを設定し、カーソルが外れると、テクスチャを消します。

        private const int width = 64;
        private const int height = 64;

        public void updateTexture(asd.Vector2DF pos)
        {
            if(pos.X > _x && pos.X < _x + width 
                && pos.Y > _y && pos.Y < _y + height)
            {
                _backTexture.Texture = Resource.getTexture();
            }
            else
            {
                _backTexture.Texture = null;
            }
        }

これを実装したマスオブジェクトを9×9に配置します。

            SquareObject[,] squareObjects = new SquareObject[9, 9];
            for(int row = 0; row < 9; row++)
            {
                for(int col = 0; col < 9; col++)
                {
                    var obj = new SquareObject(row, col);
                    obj.setValue(0);
                    asd.Engine.AddObject2D(obj.getBackTexture());
                    asd.Engine.AddObject2D(obj.getTextObject());
                    squareObjects[row, col] = obj;
                }
            }

ループ処理の中でマウスの座標を取得し、全マスオブジェクトに更新を行います。

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                for (int row = 0; row < 9; row++)
                {
                    for (int col = 0; col < 9; col++)
                    {
                        squareObjects[row, col].updateTexture(pos);
                    }
                }

                // Altseedを更新する。
                asd.Engine.Update();
            }

実行結果はこんな感じです。

うん、良い感じです。

【C#】【ALTSEED】【数独】マスクラスを実装する。

前回までの状況はこちら。

では、早速実装していきます。

まず、以前作成した数独解析プログラムはそのまま使用します。

しかし、出力処理部分はいまのところスケルトン化(クラス定義の形だけ残して、実際は何もしない)としておきます。

そして、新たにSquareObjectクラスを作成します。

これがマスのテクスチャなどを扱うクラスになります。

実装はこんな感じ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class SquareObject
    {
        private int _x;
        private int _y;
        private int _row;
        private int _col;
        private int _value;
        private asd.TextureObject2D _backTexture;
        private asd.TextObject2D _valueText;
        private const int offsetX = 10;
        private const int offsetY = 10;
        private const int fontOffsetX = 19;
        private const int fontOffsetY = 9;

        public SquareObject(int row, int col)
        {
            _row = row;
            _col = col;
            _x = row * 64 + offsetX;
            _y = col * 64 + offsetY;
            _value = 0;

            _backTexture = new asd.TextureObject2D();
            _backTexture.Position = new asd.Vector2DF(_x, _y);
            _backTexture.Texture = Resource.getTexture();

            _valueText = new asd.TextObject2D();
            _valueText.Font = Resource.getFont();
            _valueText.Position = new asd.Vector2DF(_x + fontOffsetX, _y + fontOffsetY);

        }
        
        public void setValue(int value)
        {
            _value = value;
            if(value == 0)
            {
                _valueText.Text = "";
            }
            else
            {
                _valueText.Text = value.ToString();
            }
        }

        public asd.TextureObject2D getBackTexture()
        {
            return _backTexture;
        }

        public asd.TextObject2D getTextObject()
        {
            return _valueText;
        }
    }
}

SquareObjectの中で、テクスチャオブジェクトとテキストオブジェクトを作成し、getメソッドで返すようにします。

setValueで数字を設定するときに表示する数字をテキストに設定します。しかし、0が入力されたときはテキストは表示しないようにします。

そして、Resourceクラスを作成しました。

テクスチャやフォントはここからgetして使用します。

実装はこんな感じです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    static class Resource
    {
        private static asd.Texture2D _texture = null;
        private static asd.Font _font = null;

        public static asd.Texture2D getTexture()
        {
            if(_texture == null)
            {
                _texture = asd.Engine.Graphics.CreateTexture2D("square.png");
            }
            return _texture;
        }

        public static asd.Font getFont()
        {
            if (_font == null)
            {
                _font = asd.Engine.Graphics.CreateFont("number.aff");
            }
            return _font;
        }
    }
}

staticクラスで作成し、最初に作成したオブジェクトをみんなで使い回す設計になっています。

テクスチャで用意した絵はこんな感じです。

メインの処理はこんな感じで実装してみました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("squares.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            var square = new asd.TextureObject2D();
            square.Position = new asd.Vector2DF(offsetX, offsetY);
            square.Texture = texture;
            asd.Engine.AddObject2D(square);

            var obj = new SquareObject(0, 0);
            obj.setValue(1);
            asd.Engine.AddObject2D(obj.getBackTexture());
            asd.Engine.AddObject2D(obj.getTextObject());

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

実行すると、こんな感じです。

テキストを0に設定するとこうなります。

うん、いいんじゃ無いでしょうか?

次回はマウス操作でテクスチャをON/OFFする実装を追加して、9×9マスを作成したいと思います。

【C#】【ALTSEED】【数独】UIを考える。

前回までの状況はこちら。

Windowsのフォームとかではなく、ゲームのグラフィックスをうまく利用したUIにしようと思いまして、こんな感じで数独GUIを考えてみました。

まず、マスの上にマウスカーソルがある場合、そのマスの色を変えます。

入力対象のマスをわかりやすくするためです。

雑コラですまん。

マスをクリックすると、数字パネルを表示します。

このパネルの数字をクリックすると、その数字がマスに入力されます。

×をクリックすると、マスの数字を削除します。

パネルの外をクリックすると、パネルを消去します。

基本的なUIはこんな感じで、後は解析開始ボタンを設置すれば十分かと思います。

よし、これでいこう。

【C#】【ALTSEED】【数独】マウス操作をいろいろ

前回までの状況はこちら。

今回はマウス操作を試してみます。

マウスカーソルの位置をリアルタイムで表示、さらに左クリックするとその座標を表示する、という感じでやってみます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("squares.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            var square = new asd.TextureObject2D();
            square.Position = new asd.Vector2DF(offsetX, offsetY);
            square.Texture = texture;
            asd.Engine.AddObject2D(square);

            int fontOffsetX = 19;
            int fontOffsetY = 9;
            var font = asd.Engine.Graphics.CreateFont("number.aff");
            var obj = new asd.TextObject2D();
            obj.Font = font;
            obj.Position = new asd.Vector2DF(offsetX + fontOffsetX, offsetY + fontOffsetY);
            obj.Text = "1";
            asd.Engine.AddObject2D(obj);

            var obj2 = new asd.TextObject2D();
            obj2.Font = font;
            obj2.Position = new asd.Vector2DF(64 + offsetX + fontOffsetX, 64 + offsetY + fontOffsetY);
            obj2.Text = "2";
            asd.Engine.AddObject2D(obj2);

            var mouseXText = new asd.TextObject2D();
            mouseXText.Position = new asd.Vector2DF(700, 600);
            mouseXText.Font = font;
            asd.Engine.AddObject2D(mouseXText);

            var mouseYText = new asd.TextObject2D();
            mouseYText.Position = new asd.Vector2DF(700, 670);
            mouseYText.Font = font;
            asd.Engine.AddObject2D(mouseYText);

            var mouseHXText = new asd.TextObject2D();
            mouseHXText.Position = new asd.Vector2DF(800, 600);
            mouseHXText.Font = font;
            asd.Engine.AddObject2D(mouseHXText);

            var mouseHYText = new asd.TextObject2D();
            mouseHYText.Position = new asd.Vector2DF(800, 670);
            mouseHYText.Font = font;
            asd.Engine.AddObject2D(mouseHYText);


            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                mouseXText.Text = string.Format("{0}", pos.X);
                mouseYText.Text = string.Format("{0}", pos.Y);

                if(asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
                {
                    mouseHXText.Text = string.Format("{0}", pos.X);
                    mouseHYText.Text = string.Format("{0}", pos.Y);
                }

                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

なかなか良さそうです。

じゃあ、次回からUIをもっと詰めて、クラス構成を考えてみましょう。

【C#】【ALTSEED】【数独】文字列を表示する

前回までの状況はこちら。

実際に文字、というか、数字を画面に表示するのですが、

ゲームライブラリを使用しているので、普通に文字を表ずる事ができないのですよ。

このライブラリではフォントジェネレータというツールを使って、使用する文字を別ファイルで用意する必要があります。

こんなテキストファイルを作成して、

こんな感じでフォントファイルを作成します。

このとき生成されるaffファイルとpngファイルを実行プログラムと同じ場所に設置します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("squares.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            var square = new asd.TextureObject2D();
            square.Position = new asd.Vector2DF(offsetX, offsetY);
            square.Texture = texture;
            asd.Engine.AddObject2D(square);

            var font = asd.Engine.Graphics.CreateFont("number.aff");
            var obj = new asd.TextObject2D();
            obj.Font = font;
            obj.Position = new asd.Vector2DF(100, 100);
            obj.Text = "1357";
            asd.Engine.AddObject2D(obj);

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

とりあえず、数字を表示することは問題なさそう。

あとは、フォントサイズと表示位置を微調整する。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("squares.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            var square = new asd.TextureObject2D();
            square.Position = new asd.Vector2DF(offsetX, offsetY);
            square.Texture = texture;
            asd.Engine.AddObject2D(square);

            int fontOffsetX = 19;
            int fontOffsetY = 9;
            var font = asd.Engine.Graphics.CreateFont("number.aff");
            var obj = new asd.TextObject2D();
            obj.Font = font;
            obj.Position = new asd.Vector2DF(offsetX + fontOffsetX, offsetY + fontOffsetY);
            obj.Text = "1";
            asd.Engine.AddObject2D(obj);

            var obj2 = new asd.TextObject2D();
            obj2.Font = font;
            obj2.Position = new asd.Vector2DF(64 + offsetX + fontOffsetX, 64 + offsetY + fontOffsetY);
            obj2.Text = "2";
            asd.Engine.AddObject2D(obj2);

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

うん、いいんじゃないでしょうか。

【C#】【Altseed】【数独】マスを作成する

とりあえず、下地となるマスを書いてみます。

最初考えたのは、

こんな画像を用意して、9×9に並べてみました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("square.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            int width = 64;
            int height = 64;

            for(int row = 0; row < 9; row++)
            {
                for(int col = 0; col < 9; col++)
                {
                    var square = new asd.TextureObject2D();
                    square.Position = new asd.Vector2DF(width * row + offsetX, height * col + offsetY);
                    square.Texture = texture;
                    asd.Engine.AddObject2D(square);
                }
            }


            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

イメージとしては上の画像をテクスチャとして並べただけです。

スクショでは分かりませんが、内側の線が全て太く描画されてしまいました。

これは、ちょっと見づらいですね・・・

よし、9×9マスの画像を作成して、1枚のテクスチャーにしよう。

上の画像を修正して、

これを一つのテクスチャオブジェクトに貼り付けます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sudokuGUI
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            // Altseedを初期化する。
            asd.Engine.Initialize("数独解析ツール", 1000, 800, new asd.EngineOption());

            // 下地
            var background = new asd.GeometryObject2D();
            asd.Engine.AddObject2D(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1000, 800);
            background.Shape = bgRect;

            // テクスチャー
            asd.Texture2D texture = asd.Engine.Graphics.CreateTexture2D("squares.png");

            // マス
            int offsetX = 10;
            int offsetY = 10;
            var square = new asd.TextureObject2D();
            square.Position = new asd.Vector2DF(offsetX, offsetY);
            square.Texture = texture;
            asd.Engine.AddObject2D(square);


            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                // Altseedを更新する。
                asd.Engine.Update();
            }

            // Altseedを終了する。
            asd.Engine.Terminate();
        }
    }
}

うん、いいんじゃないでしょうか。

次は文字の作成をやってみます。

【C#】openTKを使用してみる

前回はAltseedというライブラリを使用してみたのですが、

このライブラリって調べてみると、構造はシンプルでゲーム制作に必要な機能は一通り揃っている(と思う)のですが、

シンプルすぎるというか、基本的なグラフィックス機能が少々貧弱な気がします。

例えば、四角形を表示させる場合、色の指定はできず、基本的に画像をテクスチャとして表示する、というイメージです。

なので、もうちょっと調べてみました。

ゲームライブラリにこだわらず、グラフィックスライブラリという括りで検索してみると、openTKというライブラリを発見しました。

https://opentk.net/index.html

これはopenGLのラッパーのライブラリですね。

openGLの機能はほぼほぼ使用できると考えていいようです。

NuGetに登録されているのでNuGetからopenTKを検索するとダウンロードして参照できるようになります。

サンプルコードを入力してみました。

https://masuqat.net/programming/csharp/OpenTK00-03.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;

namespace OpenTK_sample
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            using (Game window = new Game())
            {
                window.Run(30.0);
            }
        }
    }

    class Game : GameWindow
    {
        public Game() : base(800, 600, GraphicsMode.Default, "0-3:GameWindow")
        {
        }

        //ウィンドウの起動時に実行される。
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            GL.ClearColor(Color4.Black);
            GL.Enable(EnableCap.DepthTest);
        }

        //ウィンドウのサイズが変更された場合に実行される。
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
            GL.MatrixMode(MatrixMode.Projection);
            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)Width / (float)Height, 1.0f, 64.0f);
            GL.LoadMatrix(ref projection);
        }

        //画面描画で実行される。
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.MatrixMode(MatrixMode.Modelview);
            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.LoadMatrix(ref modelview);

            GL.Begin(BeginMode.Quads);

            GL.Color4(Color4.White);                            //色名で指定
            GL.Vertex3(-1.0f, 1.0f, 4.0f);
            GL.Color4(new float[] { 1.0f, 0.0f, 0.0f, 1.0f });  //配列で指定
            GL.Vertex3(-1.0f, -1.0f, 4.0f);
            GL.Color4(0.0f, 1.0f, 0.0f, 1.0f);                  //4つの引数にfloat型で指定
            GL.Vertex3(1.0f, -1.0f, 4.0f);
            GL.Color4((byte)0, (byte)0, (byte)255, (byte)255);  //byte型で指定
            GL.Vertex3(1.0f, 1.0f, 4.0f);

            GL.End();

            SwapBuffers();
        }
    }
}

これだけではちょっと難しそうだけど、必要なものだけ使用すればうまくいきそう。

ただ、一番の問題は座標系。

openGLの世界では、(0,0)がウインドウの中心にあり、左上が(-1.0-1.0)で右下が(1.0,1.0)になる。

これはこれで扱いが難しい。

うーん、ハードルが高い・・・。

CGを使うにはちょうどいいかもしれないけどね。