スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

auオープンアプリで曲のループをなんとかする

auオープンアプリの環境でMIDIファイルをループ再生すると、ループの継ぎ目のところで間が空いてしまいます。

これはかなりかっこ悪いのですが、プログラム側でどうにかする方法が思いつかないので、逆に曲の最後を短く切ってタイミングを合わせてみることにしました。

何度か試行錯誤してみたところ、テンポ120の曲で、4分音符+8分音符+16分音符分だけ曲を短くすると、ちょうどいい感じにループできることが分かりました。(機種はW52CA)

たまたまだと思いますが、エミュレータでもほぼ同じタイミングだったので、実機を手放してエミュレータ環境だけになってもなんとかなりそうです。

あとは、最後が4分音符+8分音符+16分音符分だけ休符になっても不自然でないような曲を用意するということになりますが、どうなんでしょ。ループが不自然になっても普通に曲を作ったほうがいいのかなぁ。

(追記)
あるいは、MIDIファイル自体に何ループ分か曲データを入れておく手もあるな。それでも長さが足りないときは、いったんフェードアウトしてから先頭に戻ればごまかせるかもしれない。プログラムでフェードアウトするのは面倒なので、当然曲データ自体をフェードアウトさせておく。
スポンサーサイト

tag : ケータイ

Vanargandプロジェクトでの悩みどころ

昨日Twitterでも書きましたが、Vanargandプロジェクトでちょっと悩みを抱えています。

まず、プログラムの中心部が巨大なステート遷移の塊になりそうなこと。単純にswitch-caseでごり押しすると、頭がついていけなくなって破綻しそうです。

これについては、switch-caseをいくつかの階層に分割することでなんとかなりそうな感じになってきました。

また、この辺の作り方について本やWebでもなかなか情報が見つからないとTwitterで書きましたが、手持ちの「ゲームプログラマになる前に覚えておきたい技術」(秀和システム)に該当する記述がありました。手法の詳細は違いますが、基本的な認識(決して簡単な問題ではないということ)と戦略は合っているようだったので安心しました。

#ゲームプログラマになりたいというのとはちょっと違うんですが、ゲームプログラミング関係の本はけっこう持ってます


次に問題になるのは、スクリプト関連です。スクリプトの解釈・実行というと字句解析・構文解析などがまず思い浮かぶのですが、この辺は参考になる情報もたくさんあるし、凝った文法にする気もないのでなんとかなるのではと思っています。

インタープリタ型とコンパイラ型のどちらにするかというのも考えましたが、ケータイJavaで動かすプログラムなので実行時にテキストの解釈をするのも非効率かと思い、予め中間コード形式にコンパイルしておいてそれを解釈・実行するようにしようかと思っています。

この辺りまではなんとか考えられたのですが、いま最も問題になっているのは、「メインループとスクリプトの解釈・実行をどうやって連携するか」です。

なんとなく、メインループとスクリプトエンジンは別々の処理の流れになりそうなのですが、単純に別スレッドにすればいいというわけでもない気がします。あまりよく理解してませんが、コルーチンというのを使えばうまくいくのでは? という気がしています。でも、ケータイJavaにコルーチンの機能なんてないはずだし、自前で実装できるとも思えないので、どうしたものかと悩んでいるわけです。

スクリプトエンジン関連の本は何冊か出ているので、参考のために買ってみるか? とも思いますが、スクリプトエンジンをいかにして利用するかというところまで解説されてるかなぁ…。

まぁ、もうしばらく悩んでみます。

(追記)
手持ちの「シューティングゲームプログラミング」(SoftBank Creative)に、スクリプトの解釈・実行に関する記述が少しありました。VanargandはシューティングではなくRPGなのですが、いくらか参考にできるかもしれません。

(追記2)
これも手持ちの「ロールプレイングゲームプログラミング」(SoftBank Publishing)にも、参考になる部分がありました。

が、一番知りたいことがなかなか解説されてません。それは結局のところ、「メインループからスクリプトエンジンを呼ぶ」要求と「スクリプトエンジンからメインループを呼ぶ」要求の両方をうまく両立する方法です。
両方から呼び合うような形になるのでコルーチンかな、と思っているのですが、はずしているかもしれません。

また、仮にコルーチンでうまくいくとしても、結局ケータイJavaの環境ではコルーチンを使わずに実装しなければならないので、別な手を考えています。(なかなか出てこないけど…)

(追記3)
まだおぼろげながら、メインループとスクリプトエンジンを連携させる方法が見えてきたかもしれません。
あとは、ある程度コードを書いてみて、うまくいくか試すしかないかなぁ。

tag : Java ケータイ Vanargand

S!アプリのビルド作業をRakeで自動化する

以前、はてなダイアリーで書いた記事のS!アプリ版を書きました。

S!アプリをEclipseで開発する環境を作ったものの、ProGuardを通す方法が分からなかったので、コマンドラインからrake一発で通せるようにしました。

なお、できたS!アプリの動作確認は、今のところエミュレータでしかしていません。

使い方:

1. Ruby、Rake、ProGuard、7-Zipを導入しておく(もしかすると、Rubyは半角スペースを含まないディレクトリにインストールするほうが安全かもしれません)
2. java,javacコマンドのあるディレクトリ(C:\Program Files\Java\jdk1.6.0_21\binなど)と、ruby,rakeコマンドのあるディレクトリ(C:\Program Files\ruby-1.8\binなど)にパスを通しておく
3. 普通にEclipseでS!アプリを作成(元になるjad,jarファイルができている必要あり)
4. 以下のコードをRakefileという名前でS!アプリプロジェクトのディレクトリに保存
5. 環境に合わせてパスなどを書き換え
6. コマンドラインでプロジェクトのディレクトリに移ってrakeと打てば、pkg/下にjadとjarができる

デフォルトでは全工程を実行しますが、Rakeのターゲットを指定すれば途中まで実行することもできます。

・rake preprocess # プリプロセスまで
・rake compile # コンパイルまで
・rake obfuscate # ProGuardによる難読化/最適化まで
・rake preverify # 事前検証まで

その他、

・rake clean # 中間生成物を削除
・rake clobber # すべての生成物を削除

です。

Javaソースの中で、//#ifdef DEBUG ~ //#endif で囲まれた行はプリプロセスでコメントアウトされます。

なお、差分ビルドはしていません。毎回、全ソースファイルを対象とします。


######## S!アプリ(MEXA) ビルド用Rakefile

require 'rake/clean'


### ↓↓↓環境に合わせて書き換える↓↓↓

# S!アプリ開発ツールMEXA SDKのインストール先
MEXA_DIR = "C:/PROGRA~1/SOFTBANK_MEXA_EMULATOR23"
# Eclipse向けプラグインfor MEXA SDKのインストール先
ECLIPSE_PLUGIN_DIR = "C:/Eclipse_MEXA/eclipse/plugins/com.mexa.emulator.eclipse.plugin_1.0.0"
# ProGuardのパス
PROGUARD_PATH = "C:/JavaDev/ProGuard/lib/proguard.jar"
# 7-Zipのパス
SEVENZIP_PATH = "\"C:/Program Files/7-Zip/7z.exe\""

# コンパイル対象のソース
source_files = FileList["src/*.java"]
source_files.exclude("**/Test*.java") # 除外したいファイルがあればここへ
# jarに含めるリソース
res_files = FileList["res/*"]

# jad、jarを生成するディレクトリ
PACKAGE_DIR = "pkg"

### ↑↑↑環境に合わせて書き換える↑↑↑


MEXA_LIB_DIR = "#{MEXA_DIR}/lib"
MEXA_CLASSPATH = "#{MEXA_LIB_DIR}/stubclasses.zip"
PREVERIFY_PATH = "#{ECLIPSE_PLUGIN_DIR}/bin/preverify.exe"

PREPROCESSED_DIR = "preprocessed"
COMPILED_DIR = "compiled"
OBFUSCATED_DIR = "obfuscated"
PREVERIFIED_DIR = "preverified"
PACKAGE_TMP_DIR = "pkg_tmp"

orig_jad = nil
orig_jar_path = nil
jad_info = nil
new_jad_path = nil
new_jar_path = nil

CLEAN.include(PREPROCESSED_DIR, COMPILED_DIR, OBFUSCATED_DIR, PREVERIFIED_DIR, PACKAGE_TMP_DIR)
if PACKAGE_DIR != "bin" # binディレクトリは削除対象にしない
CLOBBER.include(PACKAGE_DIR)
end

directory PREPROCESSED_DIR
directory COMPILED_DIR
directory OBFUSCATED_DIR
directory PREVERIFIED_DIR
directory PACKAGE_TMP_DIR
directory PACKAGE_DIR

desc "準備 (内部用)"
task :prepare => [] do
# オリジナルのjadファイルを読み込む
# 最初に見つかったjadファイルを採用。普通は1個なので大丈夫なはず。
orig_jad_path = FileList["*.jad"][0]
orig_jar_path = orig_jad_path.ext("jar")
if orig_jad_path.nil?
puts "jad file not found!"
exit
end
orig_jad = IO.readlines(orig_jad_path)

# jadファイルからHashを作る
jad_info = Hash.new
orig_jad.each do |line|
/^(\S+): (.*)$/ =~ line
jad_info[Regexp.last_match(1)] = Regexp.last_match(2)
end

# これから作るjadとjarのパス
new_jad_path = orig_jad_path.gsub(/[^\/]+\.jad/, "#{PACKAGE_DIR}/\\0")
new_jar_path = new_jad_path.ext("jar")
end

desc "プリプロセス"
task :preprocess => [:prepare, PREPROCESSED_DIR] do
rm Dir.glob("#{PREPROCESSED_DIR}/*")
source_files.each do |path|
source = IO.readlines(path)
prepro_source = Array.new
skip = false
### ↓↓↓環境に合わせて書き換える↓↓↓
# この辺りで好きなようにソースを加工できます。
source.each do |line|
# //#ifdef DEBUG ~ //#endif で囲まれた行をコメントアウトする
if /^\s*\/\/\s*#ifdef\s+DEBUG/ =~ line
skip = true
elsif /^\s*\/\/\s*#endif/ =~ line
skip = false
else
line.gsub!(/^/, "//") if skip
end
prepro_source.push(line)
end
### ↑↑↑環境に合わせて書き換える↑↑↑
prepro_path = path.gsub(/^src/, PREPROCESSED_DIR)
File.open(prepro_path, "w") do |file|
file.write(prepro_source)
end
end
end

desc "コンパイル"
task :compile => [:preprocess, COMPILED_DIR] do
rm Dir.glob("#{COMPILED_DIR}/*")
sh "javac -bootclasspath #{MEXA_CLASSPATH} -source 1.3 -target 1.3 -g:none -d #{COMPILED_DIR} #{PREPROCESSED_DIR}/*.java"
end

desc "難読化/最適化"
task :obfuscate => [:prepare, :compile, OBFUSCATED_DIR] do
rm Dir.glob("#{OBFUSCATED_DIR}/*")
sh "java -jar #{PROGUARD_PATH} -injars #{COMPILED_DIR} -outjars #{OBFUSCATED_DIR} -libraryjars #{MEXA_CLASSPATH} -keep public class #{jad_info['MIDlet-1'][/[^,\s]+$/]}"
end

desc "事前検証"
task :preverify => [:obfuscate, PREVERIFIED_DIR] do
rm Dir.glob("#{PREVERIFIED_DIR}/*")
sh "#{PREVERIFY_PATH} -classpath #{MEXA_CLASSPATH} -d #{PREVERIFIED_DIR} #{OBFUSCATED_DIR}"
end

desc "jar作成"
task :jar => [:preverify, PACKAGE_TMP_DIR, PACKAGE_DIR] do
rm_r Dir.glob("#{PACKAGE_TMP_DIR}/*")
rm_f new_jar_path
cp FileList["#{PREVERIFIED_DIR}/*"], PACKAGE_TMP_DIR, {:preserve => true}
cp res_files, PACKAGE_TMP_DIR, {:preserve => true}
cd PACKAGE_TMP_DIR do
sh "#{SEVENZIP_PATH} x ../#{orig_jar_path} META-INF"
sh "#{SEVENZIP_PATH} a -tzip -mx=9 -mfb=128 ../#{new_jar_path} *"
end
end

desc "jad作成"
task :jad => [:jar, PACKAGE_DIR] do
# jarファイルサイズを得る
jar_size = File.size(new_jar_path)

# 新しくjadファイルを作る
new_jad = Array.new
orig_jad.each do |line|
new_line = line.dup
new_line.gsub!(/(MIDlet-Jar-Size: ).*$/, "\\1#{jar_size}")
new_jad.push(new_line)
end

# jadファイルを書き出す
File.open(new_jad_path, "w") do |file|
file.write(new_jad)
end
end

task :default => [:jad, :jar]

tag : Java ケータイ Eclipse Ruby

Eclipse備忘録 - SoftBank S!アプリ(MEXA)編

トップに戻る

★必要なもの

2010年9月現在Mobile Creationのサイトで公開されているS!アプリ開発用のツールは「S!アプリ開発ツール MEXA SDK」と「Eclipse向けプラグイン for MEXA SDK」の2つです。

Eclipseで開発する場合、2つとも必要になります。

なお、事前検証ツール(preverify.exe)がEclipse向けプラグインのほうに含まれるため、Eclipseを使わずに開発する場合、別途preverify.exeを用意する必要があります。

★MEXA Emulatorのプロジェクトを作っておく

インストール後、プログラムを開発し始める前に、MEXA Emulatorのプロジェクトを作っておくと良いと思います。
これは、Eclipseのプロジェクトとは別物で、エミュレータの中に用意される疑似端末のようなものらしいです。(AndroidでいうAVDみたいなもの)

あらかじめサンプルのプロジェクトが1つ用意されていますが、別に作ったほうがいいでしょう。

Eclipseでプロジェクトを新規作成するとき

MEXAプロジェクトを新規作成するとき、「MEXA Emulatorの実行パス」「MEXA Emulatorのプロジェクトパス」「ビルド用クラスパス」がオプションで指定できますが、実質これらは必須項目になります。(デフォルト値のままでは正常に動かないため)
プロジェクト作成後に修正することもできますが、先に指定しておくほうが楽でしょう。

S!アプリ開発ツール MEXA SDKをデフォルト設定でインストールしている場合、これらのパスは以下のようになります。

MEXA Emulatorの実行パス: C:\Program Files\SOFTBANK_MEXA_EMULATOR23

MEXA Emulatorのプロジェクトパス: C:\SOFTBANK_MEXA_EMULATOR23\projects\(※)\(※).vjp
※=MEXA Emulatorのプロジェクト名

ビルド用クラスパス: C:\Program Files\SOFTBANK_MEXA_EMULATOR23\lib\stubclasses.zip

なお、S!アプリ開発ツール MEXA SDKのバージョンが上がると、これらのパスは変わるものと思われます。

★リソースファイルの置き場所

元記事はこちら

画像などのリソースファイルの置き場所ですが、デフォルトではsrcフォルダになっているようです。

ソースコードとは別に管理したいので、resフォルダを作ってそこに入れるようにします。

1. エクスプローラなどで、プロジェクトフォルダの下にresフォルダを作る。
2. プロジェクト名を右クリックして、コンテキストメニューの「リフレッシュ」を選択
3. メニューの「プロジェクト」→「プロパティー」を選択
4. ツリーから「Java のビルド・パス」を選択
5. 「ソース」タブを選択して、「フォルダーの追加...」ボタンを押下
6. resフォルダにチェックを入れて、「OK」ボタンを押下

★ProGuardを通す

S!アプリもケータイJavaの一種なので、ProGuardなどでサイズ削減を図りたいわけですが、Eclipseから実行する方法がどうしても分かりませんでした。

そこで、コマンドラインから実行できるようにしてみました。実行にはRuby、Rakeなどいくつかのツールが必要になりますが、手作業でProGuardを通すよりはかなり便利になります。

詳細はこちらの記事でどうぞ。

tag : Java Eclipse ケータイ

Eclipse備忘録 - docomo iアプリ(Star)編

トップに戻る

★Star-1.3向け開発ツールに注意

Star-1.3向けの開発環境から、ビルド時の事前検証プロセスがなくなっており、このためStar-1.3向けの開発環境でビルドしたプログラムはStar-1.3の実行環境が載ったケータイでしか動作しないそうです。
これは、設定でターゲットプロファイルを切り替えてもダメらしいです。

Star-1.3の実行環境が載ったケータイというと、2010年夏現在、ほぼ最新に近い端末のみなのではないかと思われます。

私は、最新の端末でなくてもプログラムが動いてほしいので、Star-1.2の開発ツールを使っています。

Eclipse3.5でも動く模様

公式には、iアプリ(Star)向けのEclipseプラグインはEclipse3.0/3.1に対応ということになっているようですが、Eclipse3.5でも動く模様です。ただし、私はまだあまり使い込んでいないので、不具合に遭遇していないだけかもしれませんが。

★iアプリ(DoJa)の環境とは別にする必要あり

iアプリ(Star)のEclipseプラグインとiアプリ(DoJa)のプラグインは1つのEclipseの中に共存できません。
Eclipse環境を2つ作って、それぞれにインストールする必要があります。

★プラグインをインストールするフォルダに注意

プラグインをインストールするとき、Eclipseをインストールしたフォルダを指定しますが、これはeclipse.exeがあるフォルダです。こんなところで間違う人はいないかもしれませんが、私は間違えて1つ上のフォルダを指定して、ハマりました。orz

★エミュレータが起動後すぐ終了してしまうとき

DoJaのときよりプラグインが改善されたのか、設定でコンパイラー準拠レベルを変更していなくても、プロジェクトのプロパティーで自動的にコンパイラー準拠レベルを1.4にしてくれるようです。
そのため、基本的にはこの問題は起こらない気がしますが、もし起こった場合はDoJaと同様にコンパイラー準拠レベルの設定を変更するといいかもしれません。(あくまで推測です)

1. メニューの「ウィンドウ」→「設定」を選択
2. ツリーから「Java」→「コンパイラー」を選択
3. 「コンパイラー準拠レベル」を1.4にする

Javadocを参照できるようにする

元記事はこちらこちらです。

Star向けのEclipse環境を作っただけだとJavadocが参照できなくて不便ですが、参照できるようにする方法があります。
ただし、プロジェクト毎に個別に設定しないといけないようです。全体の設定でできたらいいのに……。

1. パッケージ・エクスプローラでプロジェクトを選択しておいて、メニューの「プロジェクト」→「プロパティー」を選択
2. ツリーから「Java のビルド・パス」を選択
3. 「ライブラリー」タブを選択
4. 「STAR_CLASS_ZIP」「STAR_STARCLASS_ZIP」のツリーを展開
5. それぞれの「Javadoc ロケーション」を選択して「編集...」ボタンを押下
6. 「Javadoc URL」を選択して、Javadocを展開してあるローカルフォルダを指定
STAR_CLASS_ZIPのJavadocにはCLDC1.1のJavadocを指定
STAR_STARCLASS_ZIPのJavadocにはStar APIのJavadocを指定

CLDC1.1のJavadocは、こちらからダウンロードできるようです。
ただし登録が必要です。私は、以前登録していたユーザー名でログインを試みましたが、はねられました……orz
前にダウンロードは済ませてあったので問題ないですけど。

Star APIのJavadocは、docomoのサイトからダウンロードできます。

★ターゲットプロファイルを変更したいとき

1. メニューの「ウィンドウ」→「設定」を選択
2. ツリーから「Star-1.2 Environment」→「ビルド設定」を選択
3. ターゲットプロファイルを変更

なお、既存のプロジェクトに変更を反映するのは、手動でやる必要があると説明が出るのですが、自動でやってくれているように見えます。この辺りはよく分かりません。

tag : Java Eclipse ケータイ

検索フォーム
RSSリンクの表示
リンク
QRコード
QRコード
FC2カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。