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

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

操作方法
横移動:←→
ソフトドロップ:↓
ハードドロップ:↑
左回転:Z
右回転:X
ホールド:C
プレー:3 (人数:2) クリア:2 評価: 10 (1回)
タグが設定されていません
require_code 'defines.rb' # ゲームの基本設定 require_code 'piece.rb' require_code 'grid_util.rb' require_code 'hold.rb' require_code 'input_manager.rb' require_code 'input_handler.rb' require_code 'score.rb' require_code 'datetime_array.rb' require_code 'extension.rb' scene 'main' do # シーン内で使う変数の定義 ren = nil # 連鎖数 score = nil # スコア prev_score = nil # 1つ前のスコアを記憶 grid = nil prev_grid = nil frame_count = nil is_game_over = nil need_new_piece = nil is_render_grid = nil should_process_piece = nil next_pieces = nil # 次のピースのリスト prev_next_pieces = nil bag = nil # バッグシステム用リスト hold_locked = nil # インスタンス input_manager = nil current_piece = nil render_piece = nil hold_piece = nil prev_hold_piece = nil hold_out_piece = nil # スプライト cell_sprites = nil piece_sprites = nil next_piece_sprites = nil hold_piece_sprites = nil score_sprites = nil message_sprites = nil preload do end create do # グリッドの初期化 grid, cell_sprites = make_grid('cell-sprite') prev_grid = Array.new(CONFIG[:grid_height]) { Array.new(CONFIG[:grid_width], nil) } # 1つ前のグリッドを記憶 # prev_grid = nil # 毎回全描画するならnilを代入 is_render_grid = true # ピースの初期化 max_blocks = PIECE_BLOCKS.values.map { |shape| shape.flatten.count(1) }.max piece_sprites = make_piece_sprites('cell-sprite', max_blocks) current_piece = render_piece = nil need_new_piece = true # ネクストピースの初期化 put_text 'next-title-sprite' do position NEXT_PIECE_CONFIG[:x], NEXT_PIECE_CONFIG[:title_y] text 'Next' end next_piece_sprites = Array.new(CONFIG[:next_piece_count]) do make_piece_sprites('next-piece-sprite', max_blocks) end next_pieces = [] prev_next_pieces = [] bag = [] # ホールド機能の初期化 if CONFIG[:enable_hold] put_text 'hold-title-sprite' do position HOLD_CONFIG[:x], HOLD_CONFIG[:title_y] text "Hold:#{CONFIG[:controls][:hold]}キー" end hold_piece_sprites = make_piece_sprites('hold-piece-sprite', max_blocks) hold_locked = false end hold_piece = prev_hold_piece = hold_out_piece = nil # スコア用の初期化 ren = 0 score = prev_score = 0 score_sprites = put_text 'score_text' do position HOLD_CONFIG[:x], 160 text CONFIG[:score_format] % score end # その他の初期化 # メッセージ用スプライトを用意 message_sprites = put_text 'game_message' do position (CONFIG[:window_width] / 2).floor, (CONFIG[:window_height] / 2).floor text '' bold true end input_manager = InputManager.new # 入力キー管理 is_game_over = false frame_count = 0 should_process_piece = false end update do start_time = getLocalCurrentDate() if !CONFIG[:enable_hold] # ホールド機能が無効ならhold_lockedをtrueにしてホールド処理をさせない hold_locked = true end # ピース操作 unless current_piece.nil? # ホールド処理を試みる if input_manager.key_pressed?(keyboard, CONFIG[:controls][:hold], start_time) hold_successful, hold_piece, hold_out_piece, hold_locked = try_hold(current_piece, hold_piece, hold_locked) if hold_successful current_piece = nil need_new_piece = true next # 落下や操作はスキップ end end # 入力操作(移動・回転) should_process_piece ||= handle_input(current_piece, input_manager, start_time, grid) # 自動落下タイミング should_process_piece ||= frame_count % CONFIG[:drop_interval] == 0 end # ピースの落下、または着地時処理 if should_process_piece should_process_piece = false if current_piece.colliding?(0, 1, current_piece.blocks, grid, false) if current_piece.place(grid) current_piece = nil wait_time(1) # 処理を一旦renderへ渡す grid, cleared_line_indices = clear_lines(grid) clear_lines_count = cleared_line_indices.length if clear_lines_count == 0 ren = 0 else ren += 1 is_render_grid = false animate_line_clear(cleared_line_indices, cell_sprites) # prev_gridの消した行をnilに書換え unless prev_grid.nil? cleared_line_indices.each do |y| prev_grid[y] = Array.new(CONFIG[:grid_width]) end end is_render_grid = true end score = scoring(score, grid, clear_lines_count, ren) hold_locked = false # ピースがロックされた後、hold_lockedをリセットする need_new_piece = true else # ゲームオーバーへ is_game_over = true end else current_piece.move(0, 1, grid) end end # ピース生成 if need_new_piece need_new_piece = false if hold_out_piece.nil? # 次のピースのリストを用意(生成分+待機分) while next_pieces.length <= CONFIG[:next_piece_count] if bag.empty? # バッグが空なら更新 bag = next_bag(PIECE_BLOCKS.keys) end piece_type = bag.shift # バッグ先頭から切り出し next_pieces << Piece.new(piece_type, [piece_type]) # ピースを作成 # next_pieces << Piece.new(piece_type, BLOCK_PATTERNS.keys) # ピースを作成(ブロックランダム) end # 次のピースを取得 current_piece = next_pieces.shift else # ホールドしていたピースを出す current_piece = hold_out_piece hold_out_piece = nil end # ピースのポジションを設定 current_piece.initialize_position if current_piece.colliding?(0, 0, current_piece.blocks, grid) # ゲームオーバーへ current_piece.y = find_valid_spawn_y(current_piece, grid) is_game_over = true end end # ゲームオーバー if is_game_over message_sprites.text "Game Over" # ゲームオーバー後もピースを描画させる render_piece = current_piece current_piece = nil wait_time(1000) openActivityFeedWindow("スコア:#{score}") game_clear end frame_count += 1 end render do # グリッド if is_render_grid diff = grid_diff(grid, prev_grid) draw_grid(cell_sprites, grid, diff) update_prev_grid!(prev_grid, grid, diff) end # ピース if !is_game_over render_piece = current_piece end draw_piece(render_piece, piece_sprites) # ネクスト if next_pieces != prev_next_pieces draw_next_piece(next_pieces, next_piece_sprites) prev_next_pieces = next_pieces.dup end # ホールド if CONFIG[:enable_hold] && hold_piece != prev_hold_piece draw_hold_piece(hold_piece, hold_piece_sprites) prev_hold_piece = hold_piece end # スコア if prev_score != score score_sprites.text CONFIG[:score_format] % score prev_score = score end end end # ------------------------------ # スプライトの定義 # ------------------------------ # セル用 text 'cell-sprite' do origin :center font_size CONFIG[:cell_size] color FREE_CELL_COLOR end # ネクストピース用 text 'next-piece-sprite' do origin :center font_size NEXT_PIECE_CONFIG[:block_size] color FREE_CELL_COLOR end text 'next-title-sprite' do origin :center font_size NEXT_PIECE_CONFIG[:title_size] color '#FFFFFF' end # ホールド機能用 text 'hold-piece-sprite' do origin :center font_size HOLD_CONFIG[:block_size] color FREE_CELL_COLOR end text 'hold-title-sprite' do origin :center font_size HOLD_CONFIG[:title_size] color '#FFFFFF' end # スコア text 'score_text' do origin :center font_size 32 color '#FFFFFF' end # ゲームメッセージ text 'game_message' do origin :center # :left_top font_size 64 color '#FFFFFF' end start_scene 'main'
投稿者: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/掲示板)に貼り付ける場合は以下のタグを利用してください。

リンク

プレイヤー

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

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