目次へもどる

ガタガタする

ここで少し気になった部分があった. サイクルブロックだが,回転するときにガタガタするときがある. それは以下のような場合である.

b1 b2
b0 b3
   B0
-----

上記の様な状態で右に回転させると, rowはすぐに反映され,lineはアニメーションに基づいて決定される. よって回転操作直後は一時的に以下のようなブロックの配置になる.

[   ] b1/b2
b0/b3 [   ]
       B0
-----------

このため,コントロールブロックが1ブロック分だけ落下できる事になり,数フレーム下がる. その後,回転アニメーションが進み,回転後の配置になるためめり込み修正が入り, コントロールブロックが上昇する.

この現象によって回転時にガタガタしてしまう.

これを回避するために,サイクルブロックについて落下可能判定時にある種のバウンディングボックスを考える. すなわち,サイクルブロックは常にブロック4個分の正方形からなるコントロールブロックなので,ブロック1個単位のあたり判定で落下可能か判断するのではなく, 最も下にあるブロックのlineをコントロールブロック全体のあたり判定として判定する.

そんじゃまあ実装しましょう.

class CycleControlBlock < ControlBlock
  def can_falldown?(table, block_s)
    min_y = [@blocks[0], @blocks[3]].min_by{|block|
      block.draw_pos[1]
    }.draw_pos[1]
    row = @blocks[0].row
    fall_ys = [row, row + 1].map{|row|
      min_y >= 0 ? min_y - table[row].size * block_s : min_y
    }
    # fall_ys == 0 : can not fall
    #         >  0 : fall y
    #         <  0 : dent y
    return fall_ys.min
  end
end

サイクルブロックの下にあるのはb0とb3なのでそいつらだけを取り出し,小さい方のy座標を取得する*1. そしたらそれを基準にしてコントロールブロックの左側と右側両方のfall_ysを取得し,小さい方を返す*2

あとは横移動に関しても同様にバウンディングボックスの概念をもちいて改造.

class CycleControlBlock < ControlBlock
  def can_move_row?(imr, table, row_s)
    return false if imr == 0 # no move
    min_line = [@blocks[0], @blocks[3]].min_by{|block|
      block.draw_pos[1]
    }.line
    row_left = @blocks[0].row; row_right = @blocks[3].row
    [min_line, min_line + 1].each do |line|
      if imr > 0 # move right
        return false if row_right >= row_s - 1
        return false if table[row_right + 1][line]
      else # move left
        return false if row_left <= 0
        return false if table[row_left - 1][line]
      end
    end
    return true
  end
end

一番下のlineを元にバウンディングボックスを作る. rowは特に問題ないので,左右で決め打ちできる.

実行

おおガタガタしない.

Loading the player ...

*1 右回転ならb0,左回転ならb1が最小になるはず
*2 今思ったんだが,ysってなんだ?あ,複数のy座標って意味か.我ながら意味不明なネーミングしてるな

添付ファイル: filePuyoPuyoChap22.flv 700件 [詳細]

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