Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2006-12-28

[MyGame]MyGame::Task#run というメソッド名を変えたい

MyGame の多くのクラスはタスクとして管理する。タスクは最低限次のメソッドを持っている。

class Task
  def run
  end
  def draw
  end
end

描画プリミティブからゲーム全体を構成するシーンクラスまで全てがこのメソッドを持っていて、毎フレームそれぞれを一回呼び出す。

例えば、描画処理の負荷が大きい場合は、次のようにすると描画を一回キャンセルしてプログラム全体を倍速で動かすことが可能。

n = 2
main_loop do
  n.times { scene.run }
  scene.draw
end

で、この run というメソッド名はどーなのよという話。 run は何度も呼び出すようなイメージじゃないという意見を頂いたので、今はこの run は step に変わっている。ただ step も Ruby では繰り返しを行うメソッド名に使われたりしているので、どうも違和感を感じてきた。

シューティング本をみると move という関数でタスクの移動処理をやっていたけど、こっちのタスクは移動だけじゃなく描画以外の全てを行うし。

  • run …… run を何度も呼ぶのは違う気が
  • move …… 移動処理だけじゃないし
  • step …… 繰り返しっぽい?

どんな名前がいいのでしょうか。

2006-12-28

ぐお

昨日の夕方になって急遽もう一つのプロジェクトの締め切りが1月初旬となることが決定。この忙しいときに。ぐおぉぉ。まあこういう仕事だから仕方ないのだけど……。

2006-12-27

仕事が29日まで

11月から進めてきた仕事が今日で一区切り。いまエライ人ちに評価されているところ。大きな仕様変更がおこらないといいけど。

予定では28日が仕事納めだったのだけど、職場で新年一発目からの仕事があり、その準備のため事務所全員29日まで出社することになってしまった。まあこういう仕事だから仕方ない。

2006-12-27

[MyGame]リリースをアナウンスできるのはいつの日か

やっぱりサンプルゲームと最低限のリファレンスはほしいよね。 準備をはじめよう。

2006-12-27

Ruby が小さくみえてきた

Basic と C/C++ と スプーン一杯程度の Perl しか知らなかったオレにとって Ruby は受け入れやすかったし、てきとーに書いても怒られないしとても柔らかいという印象だった。 Ruby を知ったのは 1.8 がリリースされる頃だった。

Ruby を使っているうちにたくさんの知らないことに出会って、とてもとても全体を把握できなかったのだけど、それでも何となく書くことはできたし、 C++ よりも圧倒的に便利な場面はたくさんあった。すぐに C++ に対して興味をなくしてしまった。でもやっぱり Ruby は知らない概念がいっぱいあって、知れば知るほどとてつもなく大きなものに見えた。

この後かなりの時間をかけて何となく Ruby の全体像が見えてきた気がした。そして、知りうる知識で少しでもいいコードを書こうと集中するようになった。 Ruby をうまく使うとコードが驚くほど短くなることに気づいた。煩わしい低レベルな実装から解放され、意識が高いところで移った。なんというか実装を高レベルなレイヤーで考える習慣が身に付いた(自然と C でのプログラミングもより高い視点を意識できるようになった)。 Ruby をうまく使うと目的を実現することに集中できるということかな。

少しでもいいコードを書きたいという意識が強くなり、ただの1行のコードにたいする集中力が高くなった。 Ruby のコードに集中しているうちに、 Ruby の多くの概念や機能が意外と小さなコアの上に成り立っているように見えてきた。もっといいコードを書くためにもっと Ruby の深部を知りたい。しかも、それは昔感じた Ruby の印象よりもずっと小さいのかも……(←いまここ)

2006-12-26

Ruby × ゲーム

関西の方が盛り上がっているように見えるなあ。うらやましい。

2006-12-26

Ruby/SDLスターターキット

http://mono.kmc.gr.jp/~yhara/w/?RubySDLStarterKit

環境のセッティングなしにいきなり Ruby/SDL の開発環境を実現しようというプロジェクト。 ダウンロードして解凍すると、その中に game.exe というのがあり、これを実行すると main.rb が実行されるという仕組み。つまり スクリプトファイル名は main.rb に固定という割りきり。

エラー出力とかどうするのかと思ったら debug.exe というのがあって、こっちで main.rb を動かすと DOS 窓も開いてメッセージがこっちに出力される模様。

作ったアプリの配布は「全てのファイルを圧縮して公開せよ」という豪快さだ。

目指す方向性に賛同できるので影ながら応援しよう。

--

MyGame を組み込めばサンプルがもっとシンプルになりますよ!とか言えるようになりたいなあ。 そろそろ MyGame もリリースしたい。

2006-12-24

Exerb で(2)

昨日の続き。今の環境は以下のものを使わせてもらっている。

  • ActiveScriptRuby 1.8.4.2
  • Ruby/SDL Win32's binary(ver 1.2.0) for Ruby 1.8

Exerb で作った exe を動かしたときにだけ Win32API Error というのが出るから、 Exerb 用のコアと sdl.so のバイナリの相性の問題か。 古いバージョンのバイナリを試してみよう。

--

うーん、 Ruby/SDL の ver 1.0 のバイナリでも同じ現象か。

--

この画像表示サンプルプログラムを exe 化したもの (imageangle_20061224_0.zip, 2,306,517 bytes) とかが手元の PC でだけ実行できない。

こんなエラーウィンドウが出ずに回転する画像が表示される場合は正常。

2006-12-23

[Ruby] Ruby/SDL を使ったアプリを Exerb で

exe 化して実行したときに、手元のノート PC でだけ次のエラーがでて実行できない。

sdl.rb:17:in `require': Win32API Error #5 --- アクセスが拒否されました。
 (ExerbRuntime::Error)
        from sdl.rb:17

sdl.rb の 17 行目というのは以下の部分だ。

16: # 
17: require 'sdl.so'
18: require 'forwardable'

これ過去にも同じ現象に出会っていて、なぜかいつのまにか解決したように思っていたけど、実はこの PC でだけ出るエラーなようだ。今まで他の PC で exe を実行していたから気がつかなかった。他の3つのWindowsマシンではちゃんと動くのに。うーむ。

もしも sdl.so がない場合は、

sdl.rb:17:in `require': No such file to load -- sdl.so (LoadError)
        from sdl.rb:17

このようなエラーになるはずだから、単純にファイルが見つからないというわけではないようだけど……。

他の PC と違うところといったら WindowsXP を SP2 にしてないとかもあるのだけど、関係あるのかしら。

続く。

2006-12-22

Rubyの本読書会に行ってきた

この読書会はなぜかとっても楽しい。毎回読書会の日が待ち遠しくてしょうがない。 毎回とっても勉強になる。それが楽しい。

今回は書記もやらずにすんだし、たださんがグループに参加してくださったのでらくちんだった。

純粋にみんなで Ruby に向かい合うのが楽しいのかも。

2006-12-22

うむ

仕事が落ち着いてきたかな。実機チェックに入ったのでレポート待ちの状態。 あとは上がってきたレポートを対処してゆけばよい。企画的にゆれている仕様には手を出さない、早すぎる最適化もしていない。なので細かい作業はたくさん出てくるのだろうけど。疲労がピークに達していて朝起きた瞬間にもう頭から煙が出ている。

2006-12-22

ぐあ

今週は仕事。たまっている仕事を一気に片付ける。だいたい終わったかなあ。 残っているぶんを明日中に片付けてしまって、例の件に集中できるようにしておきたい。

2006-12-15

[Ruby]アビリティーとモジュール

ということはだよ。例えば、そーだな、 FF5 みたいなジョブシステムだったとしよう。

キャラクターが戦闘中に使える能力は、現在のジョブとあと任意に自分が過去に習得したアビを一個選べるといった仕様だったと思う。

そしたら、そのジョブアビリティーを module として定義して、そいつをキャラクターインスタンスに extend してやる。すると、キャラクターが使えるアビの判定をメソッド呼び出しの結果をもって実現することができる。

module ナイト1
  def かばう
  end
end

module ナイト2
  def 守る
  end
end

module ナイト3
  def 両手持ち
  end
end

character.extend ナイト1
character.extend ナイト3
character.かばう      # => アクション発動
character.両手持ち    # => nil か true
character.黒魔法      # => NoMethodError → そのメソッドは覚えていません

深くは考えていないけど、なんとなくこんなイメージ。 もう少し考えて、実装案を具体化したい。

2006-12-14

[Ruby]スライムクラスとドラゴンクラス

C++ 使ってたころは Monster クラスを継承させた Slime クラスとか Dragon クラスとか、実際そんなことしないよなーと思っていた。だって、現実問題モンスターの種類は何十、何百となるわけで、そのデータはテーブル化したい。だったら、共通の Monster クラスのオブジェクトに値を設定する形にしないと不便だから。

でも Ruby だったら、モンスター固有のパラメータとか振る舞いをクラスやモジュールとして DSL 的に定義するのもありだね。モンスター名を示す文字列やシンボルから、それぞれのクラスのインスタンスを作れるもの。

monster = Monster.create(:dragon)

うーん、この発想はなかったわ。 Ruby ぜんぜん使いこなせてないなー。

しかも、 Ruby の場合はスクリプトが設定ファイルになるから、直接 DSL 的にデータを書けばいいわけだ。まあ作業分担するとエクセルを使いたがる人が多いから、実際はエクセルをパースして Ruby スクリプトをジェネレートするとかになりそうだけど。

--

まだまだ C の呪縛に縛られすぎなんだよね。発想が。 動的なんだよ、動的。真に目覚めるのはいつの日か。

2006-12-10

[MyGame]キーシンボル

今は Ruby/SDL の定数をそのまま使っているので A キーは Key::A で表す。

puts "A" if key_press?(Key::A)
puts "SPACE" if key_press?(Key::SPACE)

この Key::A をシンボルにしたほうがいいのかなあ。

puts "A" if key_press?(:a)
puts "SPACE" if key_press?(:space)

とか、

puts "A" if key_press?(:A)
puts "SPACE" if key_press?(:SPACE)

とか。うーむ。

2006-12-10

[MyGame]フォント機能を真面目に実装

Font クラスの完成度が低かったので修正しつつ機能を付け足す。

最後の start_effect は文字がすごしずつ見えてくるようになるエフェクトなんだけど名前がいまいちだ。

require 'mygame/boot'

def clear_screen
  screen.fill_rect 0, 0, screen.w, screen.h, [0, 0, 128]
end

def wait
  loop_game { break if press_new_key?(Key::N) }
  clear_screen
end

MyGame::background_color = nil
clear_screen

Font.draw "Hello"
wait

Font.draw "pos(100, 0)", 100, 0
wait

Font.default_size = 80

SFont.draw "Shadow Font"
wait

fnt = Font.new("Font Object")
fnt.draw
wait

fnt.color = [32, 32, 32]
fnt.shadow_color = [255, 255, 255]
fnt.draw
wait

fnt = SFont.new("Font Object")
fnt.ttf_path = "../mygame/fonts/mikachan.ttf"
fnt.draw
wait

fnt.size /= 2
fnt.draw
wait

Font.setup_default_setting
Font.draw "setup_default_setting"
wait

fnt = SFont.new("Font Object WEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE!")
fnt.start_effect(0.5)
loop_game do
  fnt.run
  fnt.draw
  break if press_new_key?(Key::N)
end
2006-12-10

[MyGame] フォントに関する問題

MyGame には TTF を扱う Font クラスがある。

今まではアプリケーションが毎回 ttf ファイルの絶対パスを指定する方針だったのだが、これでは何かと面倒だ。 MyGame にデフォルトの ttf を同梱して MyGame インストール時に ttf ファイルも Ruby へぶち込んでしまえば、利用者はなにも考えなくていいので楽なんじゃないかと思った。

Ruby のディレクトリを見てみると share というのがあったので、もしかしてこれがそういう用途のために用意されているものじゃないだろうか。

インストーラに以下を追加。

mygame_datadir = File.join(datadir, 'mygame')
FileUtils.mkpath(datadir, option)
FileUtils.mkpath(mygame_datadir, option)
Dir.glob("fonts/*.ttf"){|fname| FileUtils.install(fname, mygame_datadir, option)}

でもって Font クラスには以下を追加して、何も設定しなくてもデフォルトのフォントを使うようにする。

require 'rbconfig'
class Font < DrawPrim
  def self.setup_default_setting(ttf = nil, size = nil)
    datadir = Config::CONFIG["datadir"]
    mygame_datadir = File.join(datadir, 'mygame')
    @@default_ttf_path = ttf || File.join(mygame_datadir, 'fontname.ttf')
    @@default_size = size || 16
  end
  setup_default_setting
end

フォント描画の例。

require 'mygame/boot'
Font.draw "Hello"

一行減った。わーい。

2006-12-10

本を書いています

既に直接面識のある何人かの Rubyist には相談させてもらっていますが、今 Ruby を使った某件に関する書籍を執筆中です。 詳しいことについてはまだ発表できませんが、なんとなく想像はつくかと。

17日に笹田さんにご協力いただいて原稿のレビュー会をやります。 もし興味がある方がいらっしゃいましたら私宛にメールをください。 念のためご報告だけ。

2006-12-07

Rubyの本読書会第二回 に行ってきた

プログラミングRuby 第2版 言語編(Dave Thomas/Chad Fowler/Andy Hunt)

この読書会はとっても勉強になる。 この読書会に出席するために買ったピッケル本だけど、これがまた実にすばらしい本だ(いや、古いのも持ってたけどRubyをはじめたときに買ったからとうてい全部は理解できなかった)。が、しかし、ちょっとだけ難しい。そして長い。読んでると眠くなる。そこで読書会ですよ。 これほどに集中してじっくり読める環境は本当にすばらしい。すばらしい場だ。

ここ何年かRubyを使ってきた経験は、まるでこの本に書いてあることをすべて理解するためにあったかのようにさえ思える。さすがにRubyばっかり使ってきたから読んでいてわからないということはいまのところない。

しかも、その経験のおかげか前回は初心者組みのメンバーの質問に答える人という役に任命された。実は初心者にわかりやすく説明しようと努力するのが大好きなのだ。説明する立場の方こそ勉強になるし。

今度も休まずにずっと出席し続けて、あの集中力で無事最後まで読破することができたら、間違いなくレベルアップできるね!

2006-12-07

[MyGame] install_mygame.rb

今まで MyGame を手元で使うときは、アプリケーションを動作させるディレクトリに mygame.rb と mygame/boot.rb を置いていた。しかし、これではプロジェクトが増えてくると面倒だ。

そこで、 Ruby/SDL に添付されている install_rubysdl.rb の見よう見まねで MyGame のインストーラを作ってみた。

これがあれば MyGame 動作環境の構築は次のような手順でOKだ。

  1. ActiveScriptRuby をダウンロードしてインストール
  2. Ruby/SDL(Windows' binary) をダウンロードして install_rubysdl.rb をダブルクリック
  3. MyGame をダウンロードして install_mygame.rb をダブルクリック(まだ公開してないけど)

これだけだ。うん、だいぶ簡単になったぞ。

MyGame は次のような構成になっている。

mygame.rb
mygame/boot.rb

mygame_boot.rb の方がいいのだろうか?

以下 Ruby/SDL の install_rubysdl.rb を参考にして作ったもの。 Ruby に自作のスクリプトをインストールしようなんて考えたことなかったからこれでいいのかちょっと不安。

require 'rbconfig'
require 'fileutils'
require 'optparse'

dlldir = nil
option = { :noop => false, :verbose => true }

ARGV.options do |opt|
  opt.on('--dlldir DIR'){|dir| dlldir = dir}
  opt.on('--no-harm'){ option[:noop] = true }
  opt.on('--quiet'){ option[:verbose] = false }

  opt.parse!
end

dlldir ||= Config::CONFIG["bindir"]
sitelibdir = Config::CONFIG["sitelibdir"]
mygame_sitelibdir = File.join(sitelibdir, 'mygame')

FileUtils.mkpath(sitelibdir, option)
FileUtils.mkpath(mygame_sitelibdir, option)

Dir.glob("lib/*.rb"){|fname| FileUtils.install(fname, sitelibdir, option)}
Dir.glob("lib/mygame/*.rb"){|fname| FileUtils.install(fname, mygame_sitelibdir, option)}
2006-12-05

Rubyの本読書会第二回 初心者組みのログ

まだページがないようなので、とりあえず忘れないうちにここにメモ。

  • 初心者組みのメンバー数は10人弱?
    • プログラミング初心者は2名
  • まずは第三章をたんたんと読む
    • ほとんど雑談がなかったのでサクサク進む。
  • @はクラス変数?
    • →インスタンス変数です。クラス変数は@@
  • しばしばささださんが巡回に来てくれた
  • 読み終わってから三章の最初に戻って雑談開始
  • 継承とMixinの使い分けは?
    • →経験です。あとこの本を読んでもわかりません。それが一番むずかしい
    • Rubyist はあんまり継承を使わない
  • シンボルって何?
    • →説明が難しい。特に意味はないただの名前とか?
    • Yugui さんが文字列とシンボルの違いを書いてくれるらしい。お楽しみに
  • 初心者にはクラスとかオブジェクトって何?じゃないかと思います
    • →クラスは設計図で、オブジェクトは設計図から作られる実体
    • →どうぶつの話とか。哺乳類とか、犬、猫……
  • super って何?
  • attr にはシンボルだけじゃなくて "文字列" も渡せるよ
    • でも結果が変わるのでは?→同じです
    • attr はセッターとゲッターを作ってくれるもの。メソッド名が渡せれば文字列でもよい
  • private とか protected とか最初は気にするな
    • 人に渡すようなコードじゃないなら書かなくていいでしょ(ささださん)
    • 私は書かない(ささださん)
    • protected は使うなって青木さんが書いてたよ!
  • 曲名の Bicylops ってどういう意味?
    • 誰もわからなかった
2006-12-01

[プラポケ]今後の予定

プラポケですが、個人的にばたばたしているので再開は来年の3月くらいを予定しています。 ご協力頂いていた方、毎日のプレーを楽しみにして頂いていた方(もしいらっしゃればだけど)申し訳ございません。