組み込みJython のデフォルトエンコーディング指定

java プログラムからjython を使ってpython スクリプトを実行するときに日本語文字列がpython スクリプトに含まれてると例外で落ちるのですが、


python だとデフォルトエンコーディングを指定するのにlib/site-packages/sitecustomize.py を作成して下記のコードを記述しておくのが一般的な解決方法です。

import sys
sys.setdefaultencoding("utf-8")

jython の場合、インストールしてあるディレクトリのLib/site-packages/ にsitecustomize.py を作成してもうまくいきません。

http://bugs.jython.org/issue1552 によれば、sitecustomize.py を呼び出している元のsite.py が組み込みjython からは呼び出されないそうです。逆に言うと、通常はsite.py の中でsys モジュールから削除されるsetdefaultencoding がそのまま残っているということで、

PythonInterpreter jython = new PythonInterpreter();
String script = "import sys\n" +
                "if hasattr(sys, \"setdefaultencoding\"):\n" +
                "    sys.setdefaultencoding(\"utf-8\")\n";
jython.exec(script);
jython.exec("print \"あああ\"");

これでOKっぽい*1です。
sys がsetdefaultencoding を持っているかどうか確認したうえで呼び出すようにしておきつつsitecustomize.py も用意しておけば、site.py が読み込まれるように修正されてもそのまま動くはず。

*1:ただ、eclipse のコンソールには"あああ"の代わりに"???"って表示されましたが…。自分の目的はコンソールへの出力ではなかったので例外投げずに動いたのを確認して以降は追いかけてません。

Flash のイージングの計算式

t:フレーム区間を正規化した値。0<=t<=1
e:イージングを100 で割った値。-1<=t<=1

イーズイン

e が負の時はイーズイン(加速する動き)
e' = -e
t' = e' * t + (1 - e') * t * t
t' = (1-e') * t + e' * t * t

考え方

t' = t とt' = t * t をe' で補間

イーズアウト

e が正の時はイーズアウト(減速する動き)
t' = 1 - ( (1-e) * (1 - t) + e * (1 - t) * (1 - t) )

考え方

t'=1-t とt'=1-t*t のt を逆にした物をe で補間
1-(1-t) と1-(1-t) * (1-t) をe で補間するので
1-( (1-e) * (1-t) + e * (1-t) * (1-t) )

ぷよぷよ練習アプリ改良

http://puyoren.srv7.biz/ で公開しているぷよぷよ練習アプリですがiPhone の電池の消耗が激しいため改良を加えました。


30fps で毎フレーム全画面再描画というゲーム機と同じ処理がまずかろうということで、以下の修正を加えました。

自動更新とイベント更新の切り替え

自由落下させていないので操作中に表示が切り替わることはありません。そこで操作中はキーとボタンのイベントが来たときだけ更新・再描画を行うように変更しました。じっくり置き方を考えるためのアプリなので操作中の時間は必然的に長くなりますので、これは結構効果があるのではないかと思います。

再描画範囲の変更

派手なグラフィックのエフェクトはなく、アニメーションも最低限なので、壁の内側とNEXT 表示部分だけを更新するようにしました。今のところは手抜きで、壁を毎回描画したり、壁の内側で何もない空間も一度に矩形でクリアしてます。クリアする面積が54% 程になるのでその分は負荷が軽減されるはず。

FPS 変更

どうせ30fps も出てなさそうだったので20fps にしました。これだけで負荷が2/3 になるはず!



で、電池の消費はかなり改善された感じです。体感ですが…。

電池食いすぎ

さっそくiPhone でぷよ練習アプリを動かしてみましたが通勤の40 分間で15% も電池を消費しました。普通にゲームを作るのと同じように、ほぼ全画面を30fps で描き換えてたので電池食うだろうなーとは思ってましたが…。


今のところリアルタイムに動かす要素があんまりないので必要な時に必要な領域だけを描画するようにしないとなー。

ぷよぷよ練習アプリ

ぷよぷよの連鎖が下手すぎて泣けてきたのでじっくり練習するためのアプリを作りました。

iPhone でもできるようにJavaScript で作って、無料サイトに登録してやりました。http://puyoren.srv7.biz/
html5canvas というキーワードを最近ちょくちょく目にしていて気になったのでその練習も兼ねてみました。

昔から、いつかぷよぷよを自分で作れるようになりたいと思っていたのですが、やってみたら割とすぐできたので、さすがにこの10年位は無駄ではなかったのだなと安心しました。

pyExcelerator で行の高さを自由に設定する

python でXLS 形式のデータを作成できるpyExcelerator というのがありますが、そのままだと行の高さを自由に設定することができません。スクリプトを修正してやると自由に設定できるようになります。


いじるのは、Row.py です。Python/Lib/site-pacages/pyExcelerator/Row.py です。


まず109 行目

        self.__has_default_format = 0
        self.__has_default_height = 0 #0x01
        self.__height = 0x00FF

self.__has_default_height が1 で初期化されているのを0 に変更します。


続いて191 行目

        options |= (self.hidden & 0x01) << 5
        options |= (0x01 & 0x01) << 6 # (0x00 & 0x01) から変更
        options |= (0x01 & 0x01) << 8

options の6 ビット目に1 が設定されるように変更します。この意味は、BiffRecords.py のクラスRowRecord のコメントをみると書いてありますが、行の高さとデフォルトのフォントの高さが一致していないフラグだそうです。なぜここをいじるとうまくいくのかはちゃんと調べたわけではありません。勘でいじったらたまたまうまくいきました。


この様にスクリプトを修正したうえで、

from pyExcelerator import *
wb = Workbook()
ws = wb.add_sheet("test")
ws.write(0, 0, "test")
ws.row(0).height = 180     # 単位は1/20 ポイント
wb.save("test.xls")

こんな感じでスクリプトを書いてやれば高さを自由に変更できます。行の高さは1/20 ポイント単位なので、結構大きめの数字にしないと行がつぶれて見えません。1 ポイントが何ピクセルになるのかは、とりあえず大体で事足りているので調べてません。前に調べたかも知れませんが忘れてしまいました。