simplay/bofrev

View on GitHub
demos/tetris/tetris_map.rb

Summary

Maintainability
A
25 mins
Test Coverage
require 'map'
require 'point2f'

require_relative 'shape'
require_relative 'shape_spawner'

require 'event'


class TetrisMap < Map

  def initialize(game)
    super(game)
    @go_one_down = Event.new(S_KEY)
    @shape_spawn_count = 0
    @line_deletion_count = 0
    spawn_new_shape
  end

  # spawns the next tetris shape and increases the shapes spawn count by one.
  def spawn_new_shape
    @shape = Tetris::ShapeSpawner.new(self).next
    @shape_spawn_count = @shape_spawn_count + 1
  end

  # iterate row-wise though grid and look for '4'-rows (w/e border).
  # Each such row should be deleted and a players score should be incremented accordingly.
  def check_for_combo
    @sound_effect.play(:kick)
    @grid.inner_height_iter.each do |idy|
      row_deletable = @grid.inner_row_at(idy).all? &:placed?
      if row_deletable
        clear(idy)
        down_by_one(idy-1)
        @game.update_score_by(10)
      end
    end
  end

  # handle tetris user input and update game state accordingly.
  # @param message [Event] has only a type
  def process_event(message)
    case message.type
    when D_KEY
      @shape.move_by(Point2f.new(1,0), :move_sidewards)
    when A_KEY
      @shape.move_by(Point2f.new(-1,0), :move_sidewards)
    when S_KEY
      @shape.move_by(Point2f.new(0, 1))
    when W_KEY
      return unless @shape.rotatable?
      was_rotated = @shape.rotate
      @sound_effect.play(:jump) if was_rotated
    end
  end

  def process_ticker
    process_event(@go_one_down)
  end

  private

  # sink all inner cells from row 1 (not zero) till :till_row_idx
  def down_by_one(from_row_idx)
    @line_deletion_count = @line_deletion_count + 1
    (1..from_row_idx).to_a.reverse.each do |row_idx|
      @grid.inner_width_iter.each do |idx|
        @grid.field_at(idx, row_idx+1).copy_state_from(@grid.field_at(idx, row_idx))
      end
    end
  end

end