Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2007-01-31

[MyGame]まとめて render

描画プリミティブやキャラクタータスク等を配列に入れてまとめて render メソッドを呼ぶことが多い。具体的には次のような書き方。

tasks.each {|e| e.render }

あらかじめ render_all のようなメソッドを用意した方がいいかなあ。

render_all tasks

Symbol#to_proc よりもいいかなあ。

tasks.each &:render

--

あ、 Array を拡張してしまって、

tasks.render_all

とするのもあり? ライブラリを require するとこうなっちゃうのって良くないのかなあ。

2007-01-31

仕事が

終わったと思ったのに、今日になってとある情報がはいって大きく仕様変更することに。来週の納期ギリギリまでかかりそうだ。

2007-01-30

仕事が落ち着いた気がする

昨日までずっと私を悩ませていた不具合(というかとあるサウンドデバイスの変な現象)がとある対処でとつぜん直ったようで、これを最後に先の見えない仕事のタスクは消えた。 また突発的に忙しくなる可能性があるのは変わらないけど、余裕のある今のうちにたまっている作業を進めておきたい。

2007-01-29

[MyGame]タイマ割り込みみたいのがほしい

120フレーム後に画面切り替えとか、60フレームでフェイドアウトとか、いちいち自分でカウンタ用の変数を設けて処理するのがめんどくさい。ちゃんとしたゲームっぽく見せようとすると必ずこういう処理が必要になる。例えばキャラが動かせるようになるまでの微妙な間とか、死んだときに画面が切り替わるまでの間とか。

なんとなくイメージ。

add_timer
add_counter

set_cycle(1, 128) {|i| @bg.alpha = i * 2 }
set_timer(30) { @next_scene = :xxx }
set_conter
set_cycle_conter

もうひと月くらい悩んでいるのだけど、考えるだけじゃ良い API にたどり着けそうにないから、実験的に導入してみようかなあ。まあまだ正式リリースしてないのでなんとでもなるのだけどね……。

2007-01-29

[MyGame]press_key? → key_pressed? に名前を変えた

名前を付けるのは苦手だぁ。うーむ。

--

某件。最近サンプルゲームの作り込みばっかりやっているのだけど、デザイナーさんに頼んで絵を作ってもらったからかなりかっこよくなった。

今月は絵の発注と作り込みをずっと繰り返していた。90%くらい完成。

同じプログラムなのに絵が違うと、プログラムまですごいものに見えてしまうからサンプルゲームの絵は重要なのだ。

2007-01-29

三国志大戦DS おすすめプレー方法

三国志大戦DS(特典無し)

みなさんもうすっかりCPU戦には飽きていることと思いますが、そんなあなたにお勧めの遊び方。

武将の総コストを5にしてデッキを組んで「激」を選ぶ。これで暇なCPU戦が、アツイ戦いに変わります。

慣れるとコスト5でも9戦目までは楽に勝ててしまいます。その場合は、9戦目まではカードを一枚お城のなかに温存しつつコスト4で乗り切り、SR8枚の10戦目だけコスト5で戦うと良いです。これだと気を抜くと負けちゃうので楽しいです。

これくらい楽にできるようになってから全国対戦に挑戦すると、小技が身に付いているはずなので、ある程度勝てるようになるかも!?

--

この戦闘システムをRPGに取り入れたいんだよね。戦士とか魔法使いとか僧侶とか忍者、サムライとかに置き換えても楽しそうだもの。 というわけで研究中。

2007-01-20

[栽培日誌]カリフラワー収穫

あいかわらず、化学肥料を使わず、もちろん農薬も使わず、アパートの庭で地道にやっている。雑草はほとんど伸び放題で、夏に延びすぎたときだけ刈り取っている。

主な肥料は刈り取った草を積んで置いたものとたまに油粕を使うだけ。これまで化学肥料をいっさい使わずにやってきたけど、今年のイチゴは化学肥料を使ってみようかどうか迷っている。

ほうれん草

画像の説明画像の説明

こんなに立派なほうれん草が収穫できたのは初めて。

カリフラワー

画像の説明画像の説明

カリフラワーも大成功。前に一度育てたときはここまで大きくならなかった。

大根

画像の説明画像の説明

今年は大根が小さい。種まきが11月に入ってからだったのでやっぱり育成不良か。すべて三浦大根。

ネギ

画像の説明画像の説明

とてもうまそうだ。夏に一度雑草で埋もれたけど、一度それを取り除いたのが良かったようだ。確か夏前と雑草を刈ったときに油粕も撒いた。まあネギは失敗したことないな。たいへん丈夫だ。

ほうれん草、春菊、そらまめ

画像の説明画像の説明画像の説明

11月に入ってから種まきしたもの。ほうれん草と春菊は食べられるほどに育っていない。春菊は毎年このパターン。でも春になればきれいな花を咲かせてくれるだろう。食べられないけど。

2007-01-18

SDL-off 2007新春(関東)

http://d.hatena.ne.jp/isshiki/20070116/p1 経由で知る。

前に off 会でお話したことのある isshiki さんだけど、ブログを今まで知らなかったよ……。メモしておこう。

2007-01-16

[MyGame]draw → render

なかなか決心できなかったのだけど、清水の舞台から飛び降りる気持ちでコミット。

slime = Silme.new
main_loop do
  slime.update
  slime.render
end

うむ。

2007-01-14

rand(1..6) と slimes[rand(slimes).size]

前者はサイコロの目を出すのにこう書きたいよ、という話。 後者は攻撃するスライムをランダムに選ぶのにいちいちこう書きたくないよ、という話。

こう思うことがちょくちょくある。

たまたま mixi で

を教えてもらう。まさにこのあたりについての提案だ。将来のくまくまーを応援しながら一気に読むも、結局採用されず。まあ今の Ruby にないのだから提案が通らないのは予想できていたけど。

でも、ほしーなー。でも、なかなか必要性を感じてもらえないんだよねぇ。 くまくまーの人も Ruby で遊びをつくる人なのかなあ。

最後の『「そこに Kernel#rand があるから」です。』に爆笑。

2007-01-12

[MyGame]add_animation

アニメーションの設定は下記のようなインターフェースを考えていた。

@image.set_animation :down,  12, [ 0, 1, 2, 3]  # ↓ 向き
@image.set_animation :right, 12, [ 4, 5, 6, 7]  # → 向き
@image.set_animation :up,    12, [ 8, 9,10,11]  # ↑ 向き
@image.set_animation :left,  12, [12,13,14,15]  # ← 向き

しかし、実際のゲームではより多くのアニメパタンを定義するので、以下のように書きたくなった。

[
  [:down,  12, [ 0, 1, 2, 3]],  # ↓ 向き
  [:right, 12, [ 4, 5, 6, 7]],  # → 向き
  [:up,    12, [ 8, 9,10,11]],  # ↑ 向き
  [:left,  12, [12,13,14,15]],  # ← 向き
].each {|args| @image.set_animation *args }

でも、だったら最初から複数まとめて定義できるメソッドがあればいいような気がしてきた。

@image.set_animations = [
  [:down,  12, [ 0, 1, 2, 3]],  # ↓ 向き
  [:right, 12, [ 4, 5, 6, 7]],  # → 向き
  [:up,    12, [ 8, 9,10,11]],  # ↑ 向き
  [:left,  12, [12,13,14,15]],  # ← 向き
]

ふと、まとめて定義したり、ひとつだけ追加したりできるんだったら set じゃなくて add かなあと思った。

@image.add_animation :down,  12, [ 0, 1, 2, 3]  # ↓ 向き

それだったら、まとめて定義するのも add かな。

@image.add_animations = animations

--

<< もあり?。

@image.animations << [:down,  12, [ 0, 1, 2, 3]]  # ↓ 向き

いや、 Hash の方がいいか?

@image.add_animation :down => [12, [ 0, 1, 2, 3]]  # ↓ 向き

あれ、Hash の方がいい気がするぞ。

hash = {
  :down  => [12, [ 0, 1, 2, 3]],  # ↓ 向き
  :right => [12, [ 4, 5, 6, 7]],  # → 向き
  :up    => [12, [ 8, 9,10,11]],  # ↑ 向き
  :left  => [12, [12,13,14,15]],  # ← 向き
}
@image.add_animation hash

Hash にすると add_animations はいらないのか。

2007-01-10

[MyGame]MyGame で実装する「THE APPLE CATCHER」(3)

画像の説明

本家のサンプルでは横歩きのアニメパタンが使われていないようだったけど、画像の中には4方向のアニメパタンが描かれていたので使ってみた。

MyGame でのアニメーションの扱いについて解説。 次のサンプルは Player クラスを作成し、方向キーでキャラクターを歩かせるサンプル。キャラクターが移動するとともにアニメーションもその方向に変わる。

#!ruby -Ks
require 'mygame/boot'

# プレイヤークラス
class Player
  def initialize
    @image = TransparentImage.new("images/player.png", :x => 0, :y => 40)
    # 描画サイズを設定
    @image.w = 64
    @image.h = 64
    # アニメーションパタンをセット
    animations = {
      :down  => [12, [ 0, 1, 2, 3]],  # ↓ 向き
      :right => [12, [ 4, 5, 6, 7]],  # → 向き
      :up    => [12, [ 8, 9,10,11]],  # ↑ 向き
      :left  => [12, [12,13,14,15]],  # ← 向き
    }
    @image.add_animation animations
    # アニメーション開始
    @image.start_animation :down
    # 画面中央に配置
    @image.x = (screen.w - @image.w) / 2
    @image.y = (screen.h - @image.h) / 2
  end

  def move
    if key_pressed?(Key::RIGHT)
      @image.x += 4
      @image.start_animation :right
    end
    if key_pressed?(Key::LEFT)
      @image.x -= 4
      @image.start_animation :left
    end
    if key_pressed?(Key::DOWN)
      @image.y += 4
      @image.start_animation :down
    end
    if key_pressed?(Key::UP)
      @image.y -= 4
      @image.start_animation :up
    end
  end

  def update
    move
    @image.update
  end

  def render
    @image.render
  end
end

player = Player.new
main_loop do
  player.update
  player.render
end

アニメーションパタンはあらかじめひとつの画像の中にならべて描いておく。 アニメーション名を示すシンボルとオフセット値を列挙してアニメーションを定義する。

animations = { # パターンを列挙した Hash オブジェクト
  :label  => [time, [*patten]] following,
  ・
  ・
  ・
}
image.add_animation animations

following には次のアニメーション名のシンボルを指定することができる。 デフォルトでは繰り返しループ。

追記(2007年3月31日):最新の MyGame に合わせてサンプルと解説を修正。

2007-01-10

[MyGame]MyGame で実装する「THE APPLE CATCHER」(2)

画像の説明

実装のポイントを簡単に解説。

以下はシーンクラスを使った画像表示の例。

#!ruby -Ks
require 'mygame/boot'

# ゲームシーン
class GameScene < Scene::Base
  # 初期化処理(シーン生成時に呼ばれる)
  def init
    # 背景色の設定
    MyGame.background_color = [128, 128, 240]
    # デフォルト ttf と表示サイズを変更
    Font.setup_default_setting("fonts/boxfont2.ttf", 40)

    @font   = ShadowFont.new("SCORE -----  HIGH -----")
    @player = TransparentImage.new("images/player.png", :x => 0, :y =>  40)
    @apple  = TransparentImage.new("images/apple.png",  :x => 0, :y => 300)
    @bomb   = TransparentImage.new("images/bomb.png" ,  :x => 0, :y => 380)
    @tasks  = [@player, @apple, @bomb, @font].flatten

    $highscore ||= 500
    @score = 0
  end

  # 終了処理(シーン終了時に呼ばれる)
  def quit
  end

  # 更新処理(毎フレーム呼ばれる)
  def update
    @font.string = "SCORE %05d  HIGH %05d" % [@score, $highscore]
    @tasks.each {|e| e.update }
  end

  # 描画処理(毎フレーム呼ばれる)
  def render
    @tasks.each {|e| e.render }
  end
end

Scene.main_loop GameScene

init の中で描画オブジェクトを生成している。 描画クラスには次のようなものがある。

  • Image …… 画像描画クラス
  • TransparentImage …… 透明色扱う画像描画クラス
  • Font …… フォント描画クラス
  • ShadowFont …… 影付きフォントの描画クラス

生成したオブジェクトの draw メソッドを呼び出すとスクリーンに描画される。

Scene::Base はシーンを簡易フレームワーク的に扱うクラスである。 シーンオブジェクトの中で以下のようにして次のシーンクラスをセットするとシーンが遷移する。

self.next_scene = FooScene

追記(2007年3月31日):最新の MyGame に合わせてサンプルと解説を修正。

2007-01-10

[MyGame]MyGame で実装する「THE APPLE CATCHER」

画像の説明

Ruby/SDLスターターキット に付属しているサンプルプログラム「THE APPLE CATCHER」を MyGame で実装してみた。

MyGame のサンプルとなることを意図しているのでゲーム的に複雑な仕様はカットしてある。また、ソース中にコメントを多く入れてある。

これを作るに当たり MyGame の BGM 再生に停止インターフェースがないことに気づいたので追加しておいた。

追記(2007年3月24日):

最新版(2007年3月24日版)の MyGame に対応。ついでに BGM がリセットされるバグも修正。 Ruby/SDL 1.3.0 と Win32 バイナリで環境により exe が起動できない問題が解決した模様。

追記(2007年4月1日):

旧バージョンは API が古くまぎらわしいので非公開に。2007年3月24日版に差し替え。

2007-01-07

[MyGame]updateにした

とりあえず今のところ実装は update になっている。違和感はない。

obj.update
obj.draw

より、

obj.update
obj.render

の方が字数が同じでいいかもと思ったり。

2007-01-07

[MyGame]RDoc に挑戦。

MyGame のリファレンス書かなきゃなーということで、ピッケル本に載っていた RDoc をはじめて使ってみた。

とりあえず生成はできた。 rdoc と打つだけでいいのか。これは簡単だ。

rdoc mygame/lib --main MyGame --charset shift_jis

http://dgames.jp/archive/mygame/doc/

さしあたって日本語のリファレンスが必要なのだけど、ということはコード内に直接日本語を書かないといけないのか。ちょっと悩んだけど、他にいい方法が浮かばないのでコードに日本語を埋め込んでしまった。日本語コードも何を使うか悩んだのだけど結局 SJIS で。 SJIS が嫌な人はコメントを消すなり、変換するなりしてくれるでしょう、と思って。

2007-01-05

[Ruby]Exerb コアのメンテナが arton さんに

今ごろになって、年末からの ruby-list を見たりしていたら、 Exerb コアのメンテナが募集されていて、それに arton さんが立候補されたことを知る。これは嬉しい。 もうすっかり ASR に乗り換えてしまったことだし。

2007-01-05

[アイデア]ターン制の戦闘システム

休み中に新しい戦闘システムのアイデアを考えていた。今回のテーマはターン制。

ルールを考える。頭の中で実行。ルールを付け足す。また実行。ひたすらこれの繰り返しでイメージを具体化し、ルールを細かく決めてゆく。これがとっても楽しい。市販のゲームなんていらない。想像力が必要、でも想像力に限界があるのでルールが穴だらけ。ふと気が付くと移動の概念がすっぽり抜けていたりとか。そして、穴に気づいてはそれを埋めてゆく。

今回できあがった(頭の中で)のは FE のマップとユニットの様な移動システムに、セブンのダメージ計算を用いたようなもの。ターン制だけどコマンドは敵味方共同じタイミングで入力し、キャラが素早さ順に動く。

コンセプトは以下。

  • 3 人のプレイヤーで 1 パーティを組む。ひとりのプレイヤーが 3 〜 4 体のキャラを操る
  • 3 人の役割分担は以下
    • アタッカー、盾役
    • 攻撃支援役、防御支援役
    • 回復役。長距離攻撃と防御結界。テレポート、エリアからの離脱

メモ。

  • 攻撃・防御支援はメイジ・忍者が。忍者は諜報活動も行う
  • 回復は僧侶・シスター。結界を作って相手の魔法攻撃を防ぐ
  • フラッグに近いほど結界の力が強い。相手フラッグ付近にテレポートするにはより大きなパワーが
  • 防御支援のタイプ
    • バリア……強力だが効果は初弾のみ
    • シールド……ターン中効果が続く。重ね掛けが可能。攻撃を受ける度に削られる
    • 盾……装備品の盾もシールドと同じ効果。毎ターン効果がある
  • 攻撃支援のタイプ
    • 電撃……特殊な武器にパワーを耐電させる。初回攻撃のみ。飛び道具には使えない
    • 通常支援……アタッカーの攻撃をサポート。飛び道具による援護射撃とか残像剣、分身攻撃も支援効果?
  • 忍者は変わり身の術!
  • 敵味方合わせて素早さ順に攻撃。乱数なし
    • 支援役は素早くないと意味がない
    • STR 値を超える装備重量は AGI を下げる。 3 倍下げる
    • 支援役に合わせてわざとアタッカーの素早さを下げる
  • アクションコマンドは複数登録・実行できる。 and / or 条件
    • 移動 and 攻撃
    • 攻撃 or 移動
  • ヒットアンドアウェイで攻撃
  • ↑動きながらの攻撃うざい
    • 攻撃→移動はなし
    • 移動すると支援効果が消える(これだ!)
    • 移動→攻撃→防御支援を受ける。が精一杯
  • 基本的にフラッグ戦。死んだキャラはフラッグの所から時間ペナルティでリスタート
  • アタッカーに後ろから3キャラで支援。相手のアーチャーが支援役をねらい撃ちとか
  • 時間を稼いでパワーを貯めて、敵陣にテレポートして一気にフラッグをとるとか
  • 戦士最強。でも戦士だけのパーティはメイジに負ける
  • 盾役は1トップか2トップ
    • 1トップは防御支援を集中できるので守りやすい。でもここが崩れると総崩れで全滅
    • 2 トップは相手の物理的な進入を食い止めるのに有利
    • 3 トップを捨て駒的に使うのもありかなあ?というかここまでイメージの中だけでやってもなあ
  • それにしても忍者はタチが悪い。嫌な相手だ

--

だいたいメモできたかなあ。ハイ、これでゲーム終了(無料で遊べたよラッキー)。仕事に戻ろう。

2007-01-05

休み終わり

今日から仕事。3日まで完全に休んでいた。パソコンにも触らなかった。美味しいもの食べて、ビール飲んで、すんご〜く高くまでたこ揚げしたり。

疲労が抜けて力が戻った。

2007-01-01

年末年始

結局 31 日まで会社に出勤してた。夜帰ってきておそばを食べて、もうくたくただったので21時過ぎに布団に入りそのまま寝てしまって、今(朝10時)起きた。もうへとへとで集中力が出ないので 3 が日は休む。