マップエディタの開発後記です。
4月頃から半年くらいかけて開発を進めてきたC#.NETのゲーム素材作成ビジュアルエディタの第一版をgitへリリースしましたので、ここで記事にまとめていきたいと思います。
主要機能の紹介です。
それと今回以降C#の連載を不定期にするので、ここまでC#、OOP(オブジェクト指向言語)を取り扱ってきての感想を反省会も兼ねて寄稿します。
主な仕様
マップデータ(バイナリファイル、*.bin)
このエディタでは、グラフィックチップを読み取ってそのチップをタイル状に並べたものをバイナリデータ(バイトデータの羅列)にしてファイルへエクスポートする機能があります。
ゲームを開発する上で、必ずと言っていいほど使われるツールがこのビジュアルエディタだそうで、開発精度や開発効率に直接的な影響を及ぼす重要なツールです。
バイナリエディタを直接弄って、ゲームの背景や構造を作る作業は難しく、苦痛を伴うものです。
このビジュアルエディタはそういった問題を劇的に解消するものであり、私にとっては後述します通り、プログラミングの良い経験になりました(^^)
バイナリファイルを採用した理由ですが、単純にファイルサイズを小さくしようと思った事と、バイナリデータの操作では、ゲームプログラミングのコードに柔軟性を持たせるため(拡張性)です。
それはつまり、やりたい事をゲームプログラム側で即座に対応できる事を意味しています。
ゲームのマップデータが画像データの羅列である場合、画像データが修正された場合に再度ビジュアルエディタで再編集を強いられる事になり、それは無駄な作業である可能性があります。
その手順はあまりにも開発効率が悪くなるであろうという魂胆だからです。
バイナリデータは256バイト単位にぺージ分割させて構成され、ヘッダ部分0x10バイト、ステージ構造0xF0バイト、その定義は以下のようになっています。
グラフィックチップデータ(*jpg、*.png、*bmp)
グラフィックチップは以下の右の枠に一定間隔で並んでいる画像(ボタン)です。
このプログラムは元々VB.Netの別のアプリケーションでしたが、今回C#.NETへ移植した際にコード量を半分以下にして保守性を高めた上で、動作が高速になりました。
元のアプリケーションはタイリング(タイル状に並べる処理)でTableLayoutPanelコントロールを使用していましたが、今回はPanelコントロールにボタンコントロールを配置するように変更し、継承を用いてPanelに機能追加をしたクラスを定義しています。
元に直す/やり直し
いわゆるUndo/Redo処理です。
この機能があるのとないのとでは、ツールの利便性が大きく変わります。
まさに必需品レベルの機能。
この機能はエディタ開発の初期の頃から実装していた要素で、このブログでも開発ノウハウを何度か紹介しました。
もし興味があれば以下をご覧ください(^^)/
実装した機能一覧
- Undo/Redo機能
- C++などのメモリアクセレエーター系言語のライブラリにあるデック(deque)を仮想実装して作成。
- スタックに積み上げるデータ量の上限を設定できるようにした。
- Commandパターンを使用。
- バイナリデータ入出力の機能
- ファイルを開く、ファイルに保存する処理は標準ライブラリを使用して作成。
- 静的クラス化して、メンバリソースを削減。
- エラーハンドリング処理
- 例外処理を単一メソッド化して、ラムダ式で呼び出せるようにした。
- タイリング処理関連
- 元々はデザイナー上にテーブルオブジェクトを敷いていたが、リソース削減のためこれを削除し、ファイルロード時に同じ挙動の配置処理をコードで実装。
- オブジェクトが減ったのでメモリ消費を削減した。
- グラフィックチップデータはボタンコントロールを動的に生成するため、ボタンコントロールはマップエディット用にカスタムインデックスを増設し、FactoryMethodパターンでオブジェクトを生成するように変更。
- 具象クラスの依存関係の解決
- 複数オブジェクトでデータを共有する箇所については、DIコンテナを使用してSingletonパターンで同じインスタンスを参照できるようにした。
- 複数インターフェースを実装しているクラスも同様にDIコンテナへ格納。
- トグルスイッチを実装
- .NET開発のコントロールにはトグルスイッチがなかったので実装した。
以上が現時点で実装した主な内容ですかね。
トグルスイッチなどはないのですが、ちょっとコードを追加するだけでユーザーコントロールが作成できるのはさすがといった感じです。
オブジェクト指向書いてる!って感じ(笑)
ダウンロード
aa-mapeditor Version 0.1をダウンロード
※上記のリンクからダウンロードできない場合はこの記事へコメントして頂くか、メールでお知らせください。
またこのソフトウェアはライセンスフリーでソースコードはご自由にお使いください。
C#とオブジェクト指向プログラミングに触れてみた感想
正直言うと最初は結構悩んで悩んでコードが書けない日がありました😅
C#が~というよりか、オブジェクト指向が難しいと言った感想です。
事の発端は、VB.Netのレガシーコードからの脱却というタイトルを掲げてスタートした本企画だったのですが、途中から元ソースはほとんど見ていません。
むしろ元アプリケーションから継承しているのは全体のレイアウト構成だけで、ほぼ一から再構築したものになってしまいました。
そしてもう一つはこの本を自宅から掘り出した事です。
オブジェクト指向でなぜつくるのか 第3版 | 日経BOOKプラス
オブジェクト指向の考え方は、今まで私が戦ってきたC言語のような手続き型言語プログラム・パラダイムとは全く違うものでした。
それは例えば、関数(OOPの世界ではクラス、メソッドなどとも)の区切る感覚も異なっています。
一般的に手続き型言語では変数や関数の定義をデータやスコープの都合から考察して設計を行っていきますが、オブジェクト指向言語では物・動きなどをオブジェクトとして定義して、そのオブジェクトに処理を定義していくスタイルでした。
それは、今までデータを多く作らない主義、グローバル変数を定義しない主義、スコープを小さくする主義者だった私にとって理解に苦しみました。
ある種、プログラムの完成形からオブジェクト単位に処理を切り離して考える思考が必要になります。
だんだん抽象的な話になってきてしまってますが、OOPとはそういうもので、オブジェクト同士の結合は、インターフェースなどの抽象化されたクラス(構造体のようなもの)を使って行う。
それは今までC言語ではポインタでした。
こういった基礎概念から大きく異なる言語に挑戦したのは本当に良い経験になりましたね😊
最近は、オブジェクト指向より更に発展したイベントドリブン1が主流になりつつあるようで、こちらも何かの機会にかじってみたいですね。
- マウスのクリックや信号の受信などをトリガーにしてプログラムフローが構築されるプログラミング・パラダイムの1つ。GUIアプリケーションなどで利用されている ↩︎
Version 0.2以降について
この後も開発を続けるかは分からないですが、残っている課題とかを書いて今回の記事は終わりにします。
- ページを増やす/ページを削除する
- 実は今現在のページが増やせられないのでバイナリエディタでコピーして増やすしかないです(笑)
なのでそのUIを実装しないといけません。
- 実は今現在のページが増やせられないのでバイナリエディタでコピーして増やすしかないです(笑)
- マップフィールドのタイルの範囲コピー
- タイルを配置したエリア内のタイルの指定範囲コピーをする機能。同じパターンのタイルを毎回配置するのはかなり面倒なので。
- マップフィールドにセル罫線を表示する
- マップフィールドのタイル位置にカラーマーキングをする
- マップフィールドのタイルに半透明の任意の色を着色するマーカー機能。テキストエディタのブックマーク機能に該当するもの。
- マーカーの一覧をリスト化できればベター。
- ヘッダー情報の隣接部屋に移動するジャンプ機能
- 上下左右の部屋にワンクリックで移動できるようにする。
- ステージセットXML
- マップデータとグラフィックチップリストでセットの状態保存ができるようにする。
- エディタ専用のXMLファイル。
- ソリューションデータXML
- ステージセットを複数読み込んで切り替えができるようにする
- 変更後にアプリケーションを終了しようとすると警告を表示
他にもあるかもしれませんが、割愛します。
元々あった機能で言うと後実装されてないのは、ステージセットの保存機能とページの追加・削除くらいですね。
まあ続きを作ったらまた記事に書きます。
しばらくはC++(ゲーム開発側)に戻るかなあ(゚∀゚)
ようやく本体の開発😂💦
そっちのversion 0.01も早く公開したい🤤✨
コメント