落下アニメーションの改良 †さて,もはや骨格はできたも同然なので少し細かいとこに突っ込んでいこう. それの第一弾が落下アニメーションの改良である. 例えば二つ重なったブロックが落下するとき, 下のブロックが落下し始め,すこし遅れて上のブロックが落下した方がそれっぽく見える*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 ...
|