-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgrid.rb
97 lines (83 loc) · 2.45 KB
/
grid.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class Grid
GRID_LEFT = 390
GRID_RIGHT = 670
GRID_TOP = 200
GRID_BOTTOM = 800
PX_PER_BLOCK = 28
GRID_LENGTH = 10
attr_accessor :filled, :lines
def initialize(window)
@image = Gosu::Image.new(window, 'block.png', false)
@filled = []
@gameover = Gosu::Sample.new(window, "shrink.wav")
@line = Gosu::Sample.new(window, "line.wav")
@song = Gosu::Song.new(window, "tetris.wav")
@song.play(true)
@window = window
@lines = 0
end
def self.nearest_x(x)
nearest_x = ((x - GRID_LEFT)/PX_PER_BLOCK).ceil
nearest_x = 0 if nearest_x < 0
nearest_x = GRID_LENGTH if nearest_x > GRID_LENGTH
nearest_x
end
def self.nearest_y(y)
nearest_y = ((GRID_BOTTOM-y)/PX_PER_BLOCK).round
nearest_y 0 if nearest_y <= -1
nearest_y
end
def self.y_to_px(y)
GRID_BOTTOM-y*PX_PER_BLOCK
end
def self.x_to_px(x)
GRID_LEFT+x*PX_PER_BLOCK
end
def fit_to_grid(piece)
@to_fill = []
firstxy = [Grid.nearest_x(piece.x), Grid.nearest_y(piece.y)]
firstxy = [firstxy[0], firstxy[1]+1] while @filled.include?(firstxy) || firstxy[1] < 0
@to_fill << firstxy
shift_up = 0
piece.shape.each do |shape_x,shape_y|
shapexy = [firstxy[0] + shape_x,firstxy[1] - shape_y + shift_up]
while @filled.include?(shapexy) || shapexy[1] < 0
shift_up += 1
@to_fill = @to_fill.map { |xy| [xy[0],xy[1]+ 1] }
shapexy = [shapexy[0], shapexy[1]+1]
end
@to_fill << shapexy
end
if @to_fill.any? { |x,y| Grid.y_to_px(y) <= GRID_TOP }
@song.stop
@gameover.play
sleep 3
@window.gameover
return
end
@filled = @filled | @to_fill
end
def check_for_lines
@filled.compact.map{|filled_x,filled_y| filled_y}.uniq.each do |filled_y|
if (0..GRID_LENGTH).all? { |grid_x| @filled.include? [grid_x,filled_y] }
@filled.compact.each { |xy| @filled.delete(xy) if xy[1] == filled_y }
@filled.compact!
@filled = @filled.map { |x,y| [x,y - 1] if y > filled_y }
@line.play
end
end
@lines+=1
end
def check_for_gaps
if @filled.compact.select{|x,y| y == 0}.length == 0
@filled = @filled.compact.map{|x,y| [x,y - 1] if y}
end
end
def draw
check_for_lines
@filled.compact!
check_for_gaps
@filled.each { |fill| @filled.delete(fill) if fill[0] < 0 || fill[1] < 0 || fill[0] > GRID_LENGTH}
@filled.each { |x,y| @image.draw(Grid.x_to_px(x),Grid.y_to_px(y), 100) if x && y }
end
end