-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnek_player.rb
129 lines (110 loc) · 3.07 KB
/
snek_player.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
require 'set'
require './config'
require './event_handler'
class SnekPlayer
def initialize(*)
@facing = :right
@last_calculated_facing = :right
@initial_color = Gosu::Color::AQUA.dup
EventHandler.register_listener(:fruit_eaten, self, :grow)
EventHandler.register_listener(:game_start, self, :reset)
# Required in initializer so that `draw` works on first draw
reset({})
end
def reset(context)
@visible_cells = [
Cell.new(
Config::CELL_SIZE * Config::CELLS_WIDTH / 2,
Config::CELL_SIZE * Config::CELLS_HEIGHT / 2,
@initial_color)
]
@occupied_coordinates = Set.new
@occupied_coordinates.add [@visible_cells[0].x, @visible_cells[0].y]
[Config::INITIAL_SIZE, 0].max.times { grow({}) }
end
def handle_keypress(id)
# Change the facing direction of the head, do not allow going directly opposite
# current direction, or else player instantly dies.
case id
when Gosu::KB_UP
@facing = :up unless @last_calculated_facing == :down
when Gosu::KB_DOWN
@facing = :down unless @last_calculated_facing == :up
when Gosu::KB_LEFT
@facing = :left unless @last_calculated_facing == :right
when Gosu::KB_RIGHT
@facing = :right unless @last_calculated_facing == :left
else
end
end
def next_cell_position(x, y, facing)
case facing
when :up
y -= Config::CELL_SIZE
when :down
y += Config::CELL_SIZE
when :left
x -= Config::CELL_SIZE
when :right
x += Config::CELL_SIZE
else
end
x %= Config::CELL_SIZE * Config::CELLS_WIDTH
y %= Config::CELL_SIZE * Config::CELLS_HEIGHT
return x, y
end
def movement_tick
@last_calculated_facing = @facing
head = @visible_cells.first
tail = @visible_cells.last
x, y = next_cell_position(head.x, head.y, @facing)
if @occupied_coordinates.include? [x, y]
EventHandler.publish_event(:snake_died)
end
color = head.color.dup
@visible_cells = [Cell.new(x, y, color)] + @visible_cells[0..-2]
@occupied_coordinates.add [x, y]
@occupied_coordinates.delete [tail.x, tail.y]
EventHandler.publish_event(:cell_entered, {:coordinates => [x, y]})
EventHandler.publish_event(:cell_exited, {:coordinates => [tail.x, tail.y]})
end
def grow(context)
last_cell = @visible_cells.last
next_cell = last_cell.dup
@visible_cells.append next_cell
@occupied_coordinates.add [next_cell.x, next_cell.y]
end
def draw
color = @initial_color.dup
@visible_cells.each do |cell|
cell.color = color
color.hue = (color.hue + 5) % 360
cell.draw
end
end
end
class Cell
attr_accessor :x, :y, :color
def initialize(x, y, color)
@x = x
@y = y
@color = color
@image = Gosu::Image.new("media/cell.bmp")
end
def dup
Cell.new(@x, @y, @color.dup)
end
def draw
x = @x + Config::OFFSET_X
y = @y + Config::OFFSET_Y
@image.draw(
x, y,
1,
Config::CELL_SCALE, Config::CELL_SCALE,
@color
)
end
def advance_hue
@color.hue = (@color.hue + 5) % 360
end
end