Class: Game

Inherits:
Object
  • Object
show all
Defined in:
lib/game.rb

Constant Summary collapse

EMPTY =
Gosu::Color::BLACK

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(window, x, y, height, width, block_size, difficulty) ⇒ Game

Returns a new instance of Game.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/game.rb', line 9

def initialize(window, x, y, height, width, block_size, difficulty)
  @window = window
  @x = x
  @y = y
  @height = height
  @width = width
  @block_size = block_size
  @difficulty = difficulty
  @current_difficulty = difficulty.zero? ? 1 : difficulty

  @data = Array.new(height) { Array.new(width, EMPTY) }

  @ticks = 0
  @score = 0
  @game_over = false

  create_new_player_entity

end

Instance Attribute Details

#current_difficultyObject (readonly)

Returns the value of attribute current_difficulty.



7
8
9
# File 'lib/game.rb', line 7

def current_difficulty
  @current_difficulty
end

#game_overObject (readonly)

Returns the value of attribute game_over.



7
8
9
# File 'lib/game.rb', line 7

def game_over
  @game_over
end

#scoreObject (readonly)

Returns the value of attribute score.



7
8
9
# File 'lib/game.rb', line 7

def score
  @score
end

Instance Method Details

#collision?Boolean

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/game.rb', line 60

def collision?
  (0..@player.width - 1).each do |x|
    (0..@player.height - 1).each do |y|
      next unless @player.is_brick(x, y)

      return true if @data[@player.y + y][@player.x + x] != EMPTY
    end
  end

  false
end

#compare_color(a, b) ⇒ Object



93
94
95
96
97
98
# File 'lib/game.rb', line 93

def compare_color(a, b)
  a.alpha == b.alpha &&
      a.red == b.red &&
      a.green == b.green &&
      a.blue == b.blue
end

#create_new_player_entityObject



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/game.rb', line 40

def create_new_player_entity
  entities = [Triangle, Square, El, ElTwo, Tower, Zet, ZetTwo]
  random = rand(0..entities.size - 1)
  @player = entities[random].new(@width / 2, 0)
  @player.x = @player.x - @player.width / 2

  if collision?
    @game_over = true
    @window.add_score(@score)
  end

end

#draw(context) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/game.rb', line 139

def draw(context)
  context.draw_rect(@x, @y, @width * @block_size, @height * @block_size, Gosu::Color::GRAY)
  (0..@width - 1).each do |x|
    (0..@height - 1).each do |y|
      next if @data[y][x] == EMPTY

      draw_brick(context, x, y, @data[y][x])
    end
  end

  draw_player(context)

  if game_over
    context.font.draw_text('Game over!', 250, 100, ZOrder::UI, 1.0, 1.0, Gosu::Color::YELLOW)
  end
end

#draw_brick(context, x, y, color) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/game.rb', line 168

def draw_brick(context, x, y, color)
  outer_color = Gosu::Color.new(color.alpha / 2, color.red, color.green, color.blue)

  context.draw_rect(@x + x * @block_size,
                    @y + y * @block_size,
                    @block_size,
                    @block_size,
                    outer_color)

  padding = 2
  context.draw_rect(@x + x * @block_size + padding,
                    @y + y * @block_size + padding,
                    @block_size - 2 * padding,
                    @block_size - 2 * padding,
                    color)
end

#draw_player(context) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/game.rb', line 156

def draw_player(context)
  return if game_over

  (0..@player.width - 1).each do |x|
    (0..@player.height - 1).each do |y|
      next unless @player.is_brick(x, y)

      draw_brick(context, @player.x + x, @player.y + y, @player.color)
    end
  end
end

#fast_moveObject



118
119
120
121
122
123
# File 'lib/game.rb', line 118

def fast_move
  @player.y += 1 while !collision? && is_within_bounds(0, 1)

  @player.y = @player.y - 1
  move(0, 1)
end

#full_row?(row_id) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/game.rb', line 100

def full_row?(row_id)
  @data[row_id].filter { |x| !compare_color(x, EMPTY) }.size == @width
end

#imprint_player_to_gridObject



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/game.rb', line 104

def imprint_player_to_grid
  (0..@player.width - 1).each do |x|
    (0..@player.height - 1).each do |y|
      next unless @player.is_brick(x, y)

      @data[@player.y + y][@player.x + x] = @player.color
    end
  end

  (@player.y..@player.y + @player.height - 1).each do |row_id|
    score_and_update_row(row_id) if full_row?(row_id)
  end
end

#is_within_bounds(x_offset, y_offset) ⇒ Object



53
54
55
56
57
58
# File 'lib/game.rb', line 53

def is_within_bounds(x_offset, y_offset)
  @player.x + x_offset >= 0 &&
      @player.x + x_offset + @player.width - 1 < @width &&
      @player.y + y_offset >= 0 &&
      @player.y + y_offset + @player.height - 1 < @height
end

#move(x_offset, y_offset) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/game.rb', line 72

def move(x_offset, y_offset)
  return if !is_within_bounds(x_offset, y_offset) || game_over

  @player.x = @player.x + x_offset
  @player.y = @player.y + y_offset

  if collision?
    @player.x = @player.x + x_offset * -1
    @player.y = @player.y + y_offset * -1

    if y_offset == 1
      imprint_player_to_grid
      create_new_player_entity
    end
  elsif @player.y + @player.height >= @height
    imprint_player_to_grid
    create_new_player_entity
  end

end

#rotateObject



125
126
127
128
129
# File 'lib/game.rb', line 125

def rotate
  @player.rotate

  @player.rotate_rollback if !is_within_bounds(0, 0) || collision?
end

#score_and_update_row(row_id) ⇒ Object



131
132
133
134
135
136
137
# File 'lib/game.rb', line 131

def score_and_update_row(row_id)
  @data.delete_at(row_id)
  @data.prepend(Array.new(@width, EMPTY))
  @score += @current_difficulty

  @current_difficulty += 1 if @difficulty.zero? && @current_difficulty < Difficulty::MAX_DIFFICULTY
end

#updateObject



29
30
31
32
33
34
35
36
37
38
# File 'lib/game.rb', line 29

def update
  return if game_over

  @ticks += 1
  threshold = 60.0 - 5 * @current_difficulty
  if @ticks >= threshold
    move(0, 1)
    @ticks = 0
  end
end