目次へもどる

落下アニメーションの改良

さて,もはや骨格はできたも同然なので少し細かいとこに突っ込んでいこう. それの第一弾が落下アニメーションの改良である.

例えば二つ重なったブロックが落下するとき, 下のブロックが落下し始め,すこし遅れて上のブロックが落下した方がそれっぽく見える*1

そこで落下するブロックは上にいくほど落下までにウェイトがかかるようにした.

class Field
  def falldown_line(r)
    return unless @table[r].compact!
    @fallen = true
    wait = 0
    @table[r].each.with_index do |block, l|
      next if block.line == l
      block.set_wait(wait) if wait != 0
      block.set_move_y(block.line * @block_s, l * @block_s, -6)
      block.line = l
      wait += 3
    end
  end
end

落下対象のブロックに出会う度にウェイト量を増加させていき,その時のウェイト量をset_waitメソッドでセットしている. このとき,以下のような問題が発生する.

b wait = 6

b wait = 3
b wait = 0

---

上記の仕様ではこのように一番上のブロックのウェイトは6になるが, すぐにわかる通り実際はウェイトは0でなければおかしい*2

しかし,これを実現するとウェイトによっては二番目のブロック(wait=3のとこ)に衝突してしまったりする. かつ別に上記の仕様でも実際には不自然さはそれほど感じいし,上記の様な事態自体*3そこまで発生しないので,現状のアルゴリズムでオッケーとする.

ちなみにset_waitはステーブルブロックに追加したアニメーションの一種で,ウェイトアニメーションが有効な間は他のアニメーションは更新されない.

class StableBlock < Block
  def init_animation
    @move_x = nil
    @move_y = nil
    @wait = nil
    @collapse = nil
    @draw_pos = [0,0]
  end
  def set_wait(time)
    @wait = {
      :counter => time
    }
  end
  def update_wait
    return false unless @wait
    @wait[:counter] -= 1
    @wait = nil if @wait[:counter] == 0
    return true
  end
  def update
    # update wait
    return if update_wait
    # update move_x move_y
    x = update_move(@move_x){@move_x = nil}
    y = update_move(@move_y){@move_y = nil}
    @draw_pos[0] = x ? x : @row * @block_s
    @draw_pos[1] = y ? y : @line * @block_s
    # update collapse
    update_collapse
  end
end

実行

これだけでも結構良い感じになる.

Loading the player ...

*1 実際の物理的にはどうかは知らんし興味もない
*2 物理的に
*3 ダジャレ!

添付ファイル: filePuyoPuyoChap19.flv 660件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-08-30 (金) 22:13:30 (4063d)