CoRサンプル集: テトリスのような落ちものパズルゲームのサンプル

テトリスのような落ちものパズルゲームのサンプル。
音楽・画像などの素材は一切使用していないので、コピペだけで移植出来ます。

操作方法
横移動:←→
ソフトドロップ:↓
ハードドロップ:↑
左回転:Z
右回転:X
ホールド:C
プレー:3 (人数:2) クリア:2 評価: 10 (1回)
タグが設定されていません
#============================================================================== # 描画関連ユーティリティ関数 #============================================================================== # グリッドの中心座標を取得する # # @return [Array<Integer>] グリッド原点のピクセル座標 [x, y] def get_grid_origin center_x = (CONFIG[:window_width] / 2).floor center_y = (CONFIG[:window_height] / 2).floor return center_x + CONFIG[:grid_offset_x], center_y + CONFIG[:grid_offset_y] end # グリッド座標がグリッド中央から何ピクセル離れているかを計算する # # @param grid_pos [Integer] グリッド座標 # @param width [Integer] グリッド幅 X座標が欲しいなら横マス数、Y座標なら縦マス数 # @return [Integer] ピクセル座標 def grid_center_offset(grid_pos, width, block_size) correction = block_size / 2 # 補正量 half_width = width / 2 return ((grid_pos - half_width) * block_size + correction).floor end # グリッド座標を画面座標(ピクセル)に変換する # # @param grid_x [Integer] グリッドX座標 # @param grid_y [Integer] グリッドY座標 # @return [Array<Integer>] ピクセル座標 [x, y] def get_grid_position(grid_x, grid_y) cell_size = CONFIG[:cell_size] origin_x, origin_y = get_grid_origin() px = origin_x + grid_center_offset(grid_x, CONFIG[:grid_width], cell_size) py = origin_y + grid_center_offset(grid_y, CONFIG[:grid_height], cell_size) return px, py end # グリッドとセル用スプライトを生成する # # @param sprite_name [String] セル描画用スプライト名 # @return [Array<Array>] グリッド配列とスプライト配列 def make_grid(sprite_name) height = CONFIG[:grid_height] width = CONFIG[:grid_width] grid = Array.new(height) { Array.new(width, 0) } cell_sprites = Array.new(height) do |y| Array.new(width) do |x| px, py = get_grid_position(x, y) put_text sprite_name do position px, py text '■' end end end return grid, cell_sprites end # グリッドの差分を計算する # # @param current [Array<Array>] 現在のグリッド # @param previous [Array<Array>, nil] 前回のグリッド(nil の場合は全描画) # @return [Array<Array<(Integer, Integer)>] 変更されたセルの座標ペア配列 def grid_diff(current, previous) height = CONFIG[:grid_height] width = CONFIG[:grid_width] # 初回描画または全描画の場合 return height.times.flat_map { |y| width.times.map { |x| [y, x] } } if previous.nil? diffs = [] height.times do |y| width.times do |x| diffs << [y, x] if previous[y][x] != current[y][x] end end return diffs end # グリッド上のブロックを描画する(変更箇所のみ) # # @param cell_sprites [Array<Array>] 各セルのスプライト配列 # @param grid [Array<Array>] 参照するグリッド # @param changed_cells [Array<(Integer, Integer)>] 変更されたセルの座標配列(全描画時は全て含む) def draw_grid(cell_sprites, grid, changed_cells) changed_cells.each do |y, x| current = grid[y][x] color = (current == 0) ? FREE_CELL_COLOR : BLOCK_PATTERNS.fetch(current, ERROR_BLOCK_COLOR) sprite = cell_sprites[y][x] sprite.color color sprite.scale 1.0, 1.0 end end # 描画後に前回グリッド情報を更新する # # @param prev_grid [Array<Array>] 前回グリッド(※参照元を変更する) # @param grid [Array<Array>] 現在グリッド # @param changed_cells [Array<(Integer, Integer)>] 変更されたセルの座標 def update_prev_grid!(prev_grid, grid, changed_cells) if prev_grid.nil? return end changed_cells.each do |y, x| prev_grid[y][x] = grid[y][x] end end # 行消去時のアニメーションを行う関数 # @param line_indices [Array<Integer>] 消去対象の行インデックス # @param cell_sprites [Array<Array>] セルスプライト配列 # @param duration [Integer] アニメーション全体の時間(ms) def animate_line_clear(line_indices, cell_sprites, duration = 100) cell_size = CONFIG[:cell_size] start_time = getLocalCurrentDate() while true time_diff = DateTimeArray.diff_ms(getLocalCurrentDate(), start_time) frame = [time_diff, duration].min # 経過フレームに応じた拡大率を決める scale = 1 - (frame / duration) line_indices.each do |y| cell_sprites[y].each do |sprite| sprite.scale scale, scale end end if time_diff >= duration return end wait_time(1) end end #============================================================================== # グリッド関連のロジック処理 #============================================================================== # 一列がすべて埋まっている行を削除し、空行を上に追加する # # @param grid [Array<Array>] 現在のグリッド(2次元配列) # @return [Array<Array>] 新しいグリッドと消去行 def clear_lines(grid) width = CONFIG[:grid_width] new_grid = [] cleared_line_indices = [] grid.each_with_index do |row, y| if row.include?(0) new_grid << row else cleared_line_indices << y end end # 消去行数に応じて上に空行を追加 empty_row = Array.new(width, 0) cleared_line_indices.length.times do new_grid.unshift(empty_row.dup) end return new_grid, cleared_line_indices end # ピースが衝突しない最上位置(y座標)を探す # # @param piece [Piece] チェック対象のピース # @param grid [Array<Array>] 参照するグリッド # @return [Integer] 衝突しない位置のy座標 def find_valid_spawn_y(piece, grid) y_offset = -1 while true unless piece.colliding?(0, y_offset, piece.blocks, grid, false) return piece.y + y_offset end y_offset -= 1 end end
投稿者:Material 185033 3 mini 光楼(114) 対象Lv1 公開日:2025年07月19日 20:48:05
プレー内容を公開する

違反を通報する

コメントする

コメントするには、ログインする必要があります。

コメント一覧

Rmakeic1 mini muga(投稿日:2025/07/19 23:10, 履歴)
すばらしいです!普通に遊べるところがすごいです!
プレー履歴
  • Rmakeic1 mini muga: スコア:1350
    (07/19 23:09)

全てのプレー履歴を見る

新着レビュー

レビューはまだ投稿されていません。 作品の感想を作者に伝えるためにレビューを投稿してみませんか?

全てのレビュー

フォロー/シェア

ブログ/Wiki/掲示板で共有する

Rmake内(ブログ/Wiki/掲示板)に貼り付ける場合は以下のタグを利用してください。

リンク

プレイヤー

外部ホームページに貼り付ける

外部ホームページに貼り付ける場合は以下のタグを利用してください。