初めまして、トイロジックの新人プログラマーS.Hです。
トイロジックでは毎年新入社員の研修として「iPhone用ゲーム開発研修」が行われています。本記事では、この研修でレベルエディタを作成するにあたって、どのような考えで設計をしたのか振り返りとともに解説をしたいと思います。(ツール作成にはPython2.7を使用しています)
レベルエディタの解説
今回、私たちが作成したゲームはスマホを縦と横に持ち替えることで2匹のアリを切り替えてゴールを目指す斬新アクションパズルゲーム『色違いのトルとポル』です。
- 2022年度制作『色違いのトルとポル凸凹アリコンビ『トル』と『ポル』を操作して、二匹一緒にゴールを目指すパズルアクション。
iPhoneの画面を回転させて二匹一緒にゴールさせよう。
★特設ページ
このゲームはステージ制のパズルゲームで、ワールドが進むにつれて、登場するギミックも増えて複雑になっていきます。このステージを作成するために使用したツールが今回紹介させていただくレベルエディタです。
ツールの見た目は画像のようになっています。まず、左側が実際にオブジェクトを配置していくフレームとなっています。ステージはグリッド線で区切られており、配置したいタイルをマウスで選択してオブジェクトを配置していきます。右側は配置するオブジェクトのリストを表示し各種パラメーターの設定および確認もできるようになっています。
また、左上のファイルからレベルの新規作成、既存のレベルを開く、保存、エディタの終了を選択することができます。
この他にもレベルの拡大縮小
やオブジェクトの回転
、反転
、直前の操作を元に戻したりやり直す機能
もあります。
使いやすいツールにするために
今回、ツール作成経験のなかった私が使いやすいツールにするために意識したこと。それは…他のソフトウェアと同じ操作方法を実装するということです。これによって使用者は直感的に操作できるようになります。
例えば、ほとんどの方がメモ帳やWordを使ったことがあるかと思います。そこで直前の操作を取り消したいなと思ったときあなたはどうしますか? そうですね、Ctrl + Z
を押しますね。これと同じ操作方法をツールにも実装することで、使用者が元に戻したいなと思ったときに迷うことなくCtrl+Zを押すことができます。
この他にもCtrl + Y
で取り消した操作のやり直しができたり、保存やファイルを開く際にファイルダイアログを出すことで迷わず操作できるようにしています。
このように、他のソフトウェアと同じ操作方法を実装することで使用者が直感的に操作を理解でき使いやすいツールにすることができます。
Redo/Undo機能の実装方法
Redo/Undo機能
の実装に当たって、GoFのデザインパターンにおけるコマンドパターンを活用しました。具体的なコードは以下の通りになります。
# コマンドインターフェースクラス
class Command():
# 抽象基底クラスにする
__metaclass__ = ABCMeta
# @abstractmethodを指定すると純粋仮想関数になる
# 実行される命令
@abstractmethod
def execute(self):
pass
# execute()を取り消す命令
@abstractmethod
def undo(self):
pass
# オブジェクトを生成するCommand派生クラス
class CreateObjectCommand(Command):
def execute(self):
# 以下にオブジェクトを生成する処理を書く
def undo(self):
# 以下にオブジェクトを削除する処理を書く
# コマンドリスト
command_list = []
# 現在参照しているコマンドリストの位置
current_command_index = -1
# オブジェクトの生成
def CreateObject():
new_command = CreateObjectCommand()
# コマンドの命令を実行
new_command.execute()
# 現在の参照位置が最後尾でないなら後ろのコマンドを削除する
if current_command_index < len(command_list) - 1:
del command_list[current_command_index+1:]
# コマンドリストに新しいコマンドを追加
command_list.append(new_command)
current_command_index += 1
# 命令の取り消し(今回の場合だとCtrl+Zが押されたときに呼ばれる)
def Undo():
if current_command_index >= 0:
command_list[current_command_index].undo()
current_command_index -= 1
# 命令の再実行 (今回の場合だとCtrl+Yが押されたときに呼ばれる)
def Redo():
if current_command_index < len(command_list) - 1:
current_command_index += 1
command_list[current_command_index].execute()
コードではオブジェクトの生成コマンドしか書かれていませんが、オブジェクトの削除や回転もCommandクラス
を継承して<code>execute()</code>
,<code>undo()</code>
に適切な処理を書くことで同じ操作で使用できるようになります。
最後に
いかがでしたでしょうか?自分が作ったツールを他の人に使ってもらえるととても嬉しい気持ちになります。今回著者が作成したものもまだまだ改善すべき点がたくさんありますので、今後もより良いものを作れるように努力していきたいと思います。