2015年12月28日月曜日

graphvizを使ってわかりやすいプログラミングを

はろはろ、セルディアです。

やだ…私のコード、汚すぎ…?


しばらく触っていないソースコードを見るときとかに、よく思います。

「この変数、色んな所に散らばってるけど、何のための変数なんだ…?」
「この関数、中身を変更したいけど、どこで呼ばれているんだ…?」
「ぎゃあ! 勘違いして処理を書き換えて、とんでもない動きをした!」

頭を抱えたくなります、そして昔の自分を小一時間問い詰めたくなります。

そんなことにならないように、少しでも理解を助ける資料があってもいいものです。

今回の便利グッズ


今回は「graphviz」を紹介します。

こいつは、テキストで書いたグラフ構造を、自動的に画像出力してくれるツールです。
様々な意味の点を定義して、点と点の繋がりを決めると、あとはえんやこらさして適切な配置で線を引いてくれるのです。

いったい何の役に立つのか、シューティングで一つ例を挙げてみます。




シューティングというゲームがどんな流れで実装すべきか、ちょっとした図でまとめてみました。
タイトル画面でボタンを押すと、メニューが出てきます。
一番左の流れは、ゲームスタートを押すと、機体選択画面へ、選択するとステージプレイ画面へ行きます。(実際の、十字キーで動いて、弾を撃って、弾を避けてっていう画面ですね)
その他、ステージセレクトやオプションにも行けます。

恐らく、プログラミングではこの流れを、関数やif文条件分岐で実装しますが、プログラムが大きくなってくると、パッと見ただけではこの流れがわかりづらくなります。逆に、パッと見ただけでわかる、という資料は、思っている以上にとても強い味方になります。
関数や変数の役割は、あるとき、ふっ…と忘れてしまうものなので、大まかな流れだけでも図に残しておきましょう。きっとミスや勘違いを減らしてくれます。

これは単なる使い方の一例ですが、想像力を膨らませていろんな使い方ができるようになると、もっとプログラミングが楽になるかもしれません。

簡単な使い方


実は上の図は以下のようにDOT言語で書かれています。

----------------sample.dot----------------------
digraph graph_name {
graph [
   charset = "UTF-8";
fontname="MS ゴシック";
]
node [
   charset = "UTF-8";
fontname="MS ゴシック";
fontsize = 14;
]
edge [
   charset = "UTF-8";
fontname="MS ゴシック";
fontsize = 10;
]
  TITLE [label = "タイトル画面"]
  MENU [label = "メニュー画面"]
  SELECT_PLAYER [label = "機体選択画面"]
  PLAY_STAGE [label = "ステージプレイ画面"]
  RESULT [label = "リザルト画面"]
  GAMEOVER [label = "ゲームオーバー画面"]
  ENDING [label = "エンディング画面"]
  SELECT_STAGE [label = "ステージセレクト画面"]
  PLAY_SELECT [label = "ステセレ用プレイ画面"]
  OPTION [label = "オプション画面"]
  
  {rank = same; SELECT_PLAYER; SELECT_STAGE; OPTION;}
  
  TITLE -> MENU [taillabel = "決定ボタン押下"];
  MENU -> SELECT_PLAYER;
  SELECT_PLAYER -> PLAY_STAGE;
  PLAY_STAGE -> RESULT [taillabel = "ステージクリア"];
  PLAY_STAGE -> GAMEOVER[taillabel = "残機0"];
  GAMEOVER -> TITLE;
  RESULT -> PLAY_STAGE [taillabel = "最終面以外"];
  RESULT -> ENDING [taillabel = "最終面クリア"];
  ENDING -> TITLE;
  MENU -> SELECT_STAGE;
  SELECT_STAGE -> PLAY_SELECT;
  PLAY_SELECT -> SELECT_STAGE;
  MENU -> OPTION;
  OPTION -> MENU;
}
----------------sample.dot----------------------

このdotファイルをコマンドプロンプト上で次のように指定します。

dot -Tgif sample.dot -o sample.png

これでグラフ構造を書いたテキストファイルから、画像出力できます。

(コマンドプロンプトを使わないGUI版もあるようですが、詳しく調べていないのであしからず)

参考サイト


Graphvizとdot言語でグラフを描く方法のまとめ
http://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d
Graphvizでできることがわかりやすくまとめられています。
上から読むだけでGraphvizマスター。

Graphviz チュートリアル
http://homepage3.nifty.com/kaku-chan/graphviz/
もう少し詳しい、グラフとノードとエッジの仕様が書かれています。
思い通りの配置にしたいときに。

Graphvizで日本語を使う
http://d.hatena.ne.jp/simply-k/20100705/1278326617
日本語文字を使うときに嵌らないためのメモです。

2015年12月12日土曜日

HSPからCへのコード変換について

やはー、セルディアです。

ある日突然訪れる恐怖


HSPには、AndroidやiPhoneアプリを開発できるHSP3dishという環境があります。(何度目かの説明)
そして、HSP3dish Helperを使えば、さらに簡単にアプリを作れます。

しかし…それは突然やってくる…。

Helperのビルドを押すとエラーが出る日々が…!!

その原因は


Androidの場合は、ビルドしたときに、HSPからCへコード変換されたコードがプロジェクトフォルダにできます。
<プロジェクトフォルダ>\jni\hsp3embed
hspsource.cpp

このファイルを見ると、Cコードがぶつ切りのような終わり方になっています。
下手をすると、関数を閉じていないのにEOFが来ていたり…。まともなソースじゃない。

実際にコード変換しているのは、HSP3インストールフォルダにある「hsp3cnv.exe」です。
Dishからビルドするときにも呼び出されています。
果たしてこれが打つ手なしの詰み、あきらめてくださいになるのかと言えば、意外とそうではないです。HSPは開発にかかわる様々なソースを公開しています。

OpenHSP

今回のhsp3cnv.exeもソースが公開されていたので、うまく変換できるように改造できるか挑戦してみました。

具体的な手順


まずソースをビルドして実行ファイルを作れる環境を入手します。

あっさり言っていますが、一からやるとかなりめんどうです。
今回私はVisual Studio 2012 Expressを使いました。無料で使えますが、たぶんダウンロードしてインストールするまで、けっこう手順を踏みます。

実行ファイルを作れるようになったら、OpenHSPからhsp3cnvディレクトリのファイルをダウンロードします。そして、これをビルドするためにはhsp3ディレクトリのファイルも必要なので、こちらもダウンロードします。

これは、おそらく、になりますが、HSPからCへソース変換する過程のテキストデータはCHsp3クラスの中に抱え込んでいて、main.hspファイルの129行目のhsp3.SaveOutBuf( oname );で吐き出されている…と思います。

その変換過程のテキストデータを蓄えるバッファはCMemBufクラスで実装されているのですが、どうもこいつは文字列が長くなると、自動的にバッファを拡張する機能を持っているみたいです。こいつ自体に問題はなさそう。

いろいろソースを覗いたのですが、さすがに機能を全部解析するわけにもいかず、らちが明かず。

結局手あたり次第改造することにしました。

その結果、キャラ型配列変数が、バッファ用に適当に長さ4096で作られているのがどうも怪しいと感じ、これまた適当に伸ばしてみました。(4096->65536)
すると、ビルドしてできたhsp3cnv.exeを使って、無事にコード変換することができました。

改造箇所から考えると、ソースコードが一定の長さ以上になるか、コード変換時のなんらかのスタック処理が、変換処理の想定を超えてしまうとファイルがぶつ切りになってしまうようです。

最終的に力技になったけど気にしない!

ファイル配布


せっかく問題を解決できたので、できあがったhsp3cnv.exeを配布します。
BSDライセンスなので問題ない…ハズ。ライセンスは明記しときます。


ファイルを「hsp3cnv.exe」にリネームして、HSP3インストールフォルダのファイルを上書きしてください。(もちろん前のファイルは取っておいた方がいいですよ)

脅しのようにお決まりの言葉を載せますが、このファイルを使って起きた、いかなる問題にも私は責任を負いません。
あくまで自己責任で使ってください。

2015年12月1日火曜日

シューティング「空飛ぶ赤いワイン樽」

はろはろー、セルディアです。

今回のシューティングは


今回は「橙汁」様から出ている「空飛ぶ赤いワイン樽」を勧めます。

空飛ぶ赤いワイン樽(以下ワイン樽)は、トゥーン調のかわいらしい見た目でありながら、ゲーム性はかなり硬派な熱いシューティングです。

無制限弾数の「バルカン」と、弾数は限られながらも高威力で弾も消せる「ミサイル」の二つの武器を使って戦います。

難易度が三種類から選べるので、初心者でも上級者でも楽しめる内容となっています。


敵を倒すとコインが出てきて、たくさん回収するとミサイルが補充されていきます。
ミサイルは敵に当たると爆風が生まれ、敵にダメージを与えるとともに、敵弾も消してくれます。
バルカンだけでは心許ない火力なので、ミサイルをいかに使っていくかがカギになります。

ミサイルを敵に当てると倍率が上がり、スコアも上がってコインも多くなるため、ミサイルを撃ちまくって稼げば稼ぐほど、より攻略が楽になっていきます。高難易度では重要なテクニックです。



リプレイ


せっかく撮ったので、私のリプレイを添付します。


難易度:hard
スコア:8162219

各ステージ内訳



それなりにスコアを稼いでいます。それなり…

2015年11月27日金曜日

HSP3dishで文字を描きたい

おはろー、セルディアです。

文字を表示するのは一苦労


HSPでは、もちろん標準で、文字を表示するmes命令というものが備わっています。
そしてもちろん、HSP3dishでもmes命令を使って文字列を描画することができます。

と簡単に思ったら大間違いだ。

立ちはだかる不具合


HSP3dishでは、なぜか、文字列が他の描画に対して最優先される特性を持っています。

動作を確認するために、以下のプログラムをHSPで実行してみましょう。

――――――――――――
#include "hsp3dish.as"

redraw 0

pos 0, 0
color 255, 255, 255
mes "test"

color 0, 0, 255
boxf 0, 0, 480, 800

redraw 1
――――――――――――

白い文字を表示してから、青い矩形を描画しています。

描画順を考えると、文字は矩形の下に隠れて見えないはずなのですが、実行してみると、はっきりくっきり文字が見えます。ちなみに最初のinclude行を取り除くと、dishではなく通常のHSP環境で実行されますが、このときは文字は見えません。

残念ながら、これを防ぐ方法は見当たりませんでした。

大胆な回避策


mes命令ではこの問題を回避できませんが、実に大胆かつ効果的な回避策があります。

文字をあらかじめ画像にしておいて、画像コピーで代替してしまえばいいのです。

そして、それを実現した夢のようなモジュールが既にあります。しまくろねこさんが製作した、mod_picmes.asモジュールです。(以下のリンクにあります)

簡単に使い方としては、「mod_picmes-Editor.exe」で作成した画像を元に、コード側で「mod_picmes.as」をインクルードして機能を利用します。

もともと、Androidでmes命令を使えない問題を解決するために作られたモジュールのようですが、このような使い道もあります。というか汎用性ありすぎて便利すぎます、しまくろねこ様ありがとうございます。

その他メリット、デメリット


今はAndroidでのmesも正式サポートされていますが、この方法には他のメリットもあります。

  • 表示レイアウトが環境間で変化しない
標準mes命令では、Windows、iOS、Androidそれぞれの文字列描画関数を呼び出しているので、当然、各環境で表示も微妙に変わってきます。文字を画像にしておけば、どの環境でも見た目が変わりません。
  • ふち付き、影付き文字が作れる
mod_picmes-Editor.exeについている機能ですが、なんと文字にふちをつけたり影をつけたりできます。ふち付きにしておけば、周りと色がかぶって見づらいシーンでも、視認性が高くなります。

ただ、1文字で1つ画像をコピーするとあって、処理に負担がかかることもあります。Android環境が厳しく、Nexus 7でテストした限りでは、感覚的にだいたい100~200文字表示すると、処理時間は1/60秒を超えてしまいます。
celputm命令で高速化を図って改善されないかも試してみましたが、やはり厳しかったです…こればっかりは仕方ない。
Windows環境ではDirectXの賜物か、特に気にすることはありません。

2015年11月19日木曜日

HSPの暗号化DPMについて

おっす、セルディアです。

HSP3.5beta2で暗号化DPMが使えません…。
色々試しましたが、ぜんぜん言うことを聞いてくれませんでした。

ゲームデータ見放題や!!


HSPではDPMという、zipのように複数のファイルを1つのファイルにまとめる機能を持っています。DPMにまとめるとHSPから通常のファイルと同じようにアクセスできるのですが、そのままではテキストエディタで開いたり、バイナリエディタで覗くとあっという間にデータが露見してしまいます。情報のリークです、事件ですよ奥さん。

暗号化DPMを使うと、単純にファイルを開くだけでは全く中身の見当もつかなくなります(はずです)。エンディングの文章やCGを見られる心配がなくなるわけです。これは大事だ。

しかし!! 実際に作ってみると動いてくれません!!

スクリプト側の準備は


DPMを使うにあたって、スクリプト側に準備が必要です。
次の行を入れておきましょう。

chdpm "data.dpm"

詳しくはF1のヘルプを見ましょう。

実は、DPMに含めるファイルは、「ファイル名が12文字以内」という制限があります。(拡張子含めずに8文字ということになります)意外に見落とすこともあるので注意しましょう。
これでうまくいかないと、「エラー12 ファイルが見つからないか無効な名前です」「エラー13 画像ファイルがありません」などのエラーが出ます。

とりあえず作り方は


DPMを作るには、いくつか方法があります。

  • 「実行ファイル自動生成」を実行
    →実行後、HSPスクリプトエディタから「ツール」→「PACKFILE編集」
    →編集後、「ツール」→「DPMファイル作成」
恐らく一番正攻法の作り方…だと思います。
暗号化は「PACKFILE編集」の中のチェックボックスをONにすればできます。
と思わせてできません。実は暗号化しない方法も全く効きません。
具体的には、EXEファイルを実行したときに、「エラー12 ファイルが見つからないか無効な名前です」「エラー13 画像ファイルがありません」などのエラーが出ます。
この方法は忘れてください。
  • 「実行ファイル自動生成」を実行
    「指定フォルダからDPM作成」で必要なファイルを含める
    DPMを実行ファイルと同じフォルダに置いて実行
どうもとあるバージョンから追加された方法のようです。
こちらだと、暗号化の際に鍵を指定することができて、「おお、なんか暗号化っぽい」と期待しますが、ダメです。同じくエラー12、13が出ます。

  • 「#pack」「#epack」プリプロセッサ命令を使う
DPMに含めず、EXEファイルにくっつけることになります。要するにEXEファイルの容量が増えます。実はこの方法だと…暗号化できます。当初の目的と違うけど暗号化できたからええか。

結論


WindowsでDPMはあきらめてください。#epackを使いましょう。

実はAndroid版だと、2番目の方法で「暗号化しなかったら」使えます。
(Androidのリファレンスマニュアルで、暗号化DPMは未対応とあります)

意外と知られていない…


インターネットをいろいろ巡りましたが、あまりこの件で騒いでる人がいないのが気がかりです。
実は以下の点が原因では…?

  • バージョン3.5beta2からの問題?
もしや単なるバグでは。
  • HSP3Dishだけの問題?
通常のWindowsのみ版では動くのだろうか。
  • わしの勘違い?
これだったら石を投げられても致し方なし。

2015年11月12日木曜日

無駄な権限(パーミッション)は万病の元?

お疲れ様です、セルディアです。

あやしいアプリ…


HSP3Dishでは、現在の最新バージョン3.5beta2からネットワーク機能が実装されているようです。もちろん、もちろん便利なのですが…その分、インストールするときに「ネットワークのフルアクセス権限」が要求されます。

ユーザにとってこれは気味が悪い。なんでゲーム内にネットワークを利用する場面なんてないのにネットワークアクセスなんて、すわスパイウェア!?

なんてことになるので、使わない場合はこの権限を要求しないようにします。

解決方法


HSP3Dish Helperで新規プロジェクトを作成したフォルダ直下に、「AndroidManifest.xml」ファイルがあります。その中に以下の2行があるので削除します。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

ちなみに「android.permission.VIBRATE」はバイブレーション機能ですね…まあ別にこれはいいでしょう…っていうかHSP3Dishにバイブレーション命令あるの? と思ったらあった。

いざHSP3Dishでインターネット接続を使ったアプリを作った! ってときにパーミッションがなくて「アクセスできない! なぜだ!!」と騒ぐよりは、最初から許可して置いて「必要なかったら削除してね☆」のほうがいいですね。

ちなみに、これはとある方から助言を頂いて気づくことができました。ぶっちゃけAndroidアプリを開発する人にとっては常識のような気がする…精進せねば…。

ぷちぎるどver0.62がAndroidでリリースされました!

やっほー、セルディアです。

Androidでリリースされました


ついに、ぷちぎるどVer0.62がAndroidでリリースされました!
Google Playの紹介ページがこちらです。


ちょっとしたバージョンアップについて


実は、Windows版よりちょっとだけバージョンアップしています。

といっても、追加点はささいですが…。

  • アイテム、キャラなどのリストスクロールが画面外に出ないようになりました。
  • 敵に与えたダメージ量に応じて、数字表示も大小変化するようになりました。
    (絶対値ではなく、その攻撃で与えられる最小・最大ダメージによって縮小・拡大します)
ばっちりHSP3DishでAndroidアプリが作れました。