minigl 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +19 -19
- data/README.md +35 -36
- data/Rakefile +11 -11
- data/lib/minigl.rb +4 -4
- data/lib/minigl/forms.rb +1485 -1485
- data/lib/minigl/game_object.rb +379 -379
- data/lib/minigl/global.rb +729 -729
- data/lib/minigl/map.rb +256 -256
- data/lib/minigl/movement.rb +585 -585
- data/lib/minigl/text.rb +190 -188
- data/test/data/img/barbg.svg +73 -73
- data/test/data/img/barfg.svg +106 -106
- data/test/data/img/square.svg +66 -66
- data/test/data/img/square2.svg +66 -66
- data/test/data/img/square3.svg +76 -76
- data/test/data/img/tile1.svg +66 -66
- data/test/data/img/tile2.svg +66 -66
- data/test/game.rb +150 -150
- data/test/game_object_tests.rb +108 -108
- data/test/iso_game.rb +39 -39
- data/test/map_tests.rb +57 -57
- data/test/mov_game.rb +76 -76
- data/test/movement_tests.rb +86 -86
- data/test/res_tests.rb +45 -45
- data/test/vector_tests.rb +55 -55
- metadata +24 -24
data/lib/minigl/map.rb
CHANGED
@@ -1,256 +1,256 @@
|
|
1
|
-
require_relative 'global'
|
2
|
-
|
3
|
-
module MiniGL
|
4
|
-
# This class provides easy control of a tile map, i.e., a map consisting of
|
5
|
-
# a grid of equally sized tiles. It also provides viewport control, through
|
6
|
-
# its camera property and methods.
|
7
|
-
class Map
|
8
|
-
SQRT_2_DIV_2 = Math.sqrt(2) / 2 # :nodoc:
|
9
|
-
MINUS_PI_DIV_4 = -Math::PI / 4 # :nodoc:
|
10
|
-
|
11
|
-
# A Vector where x is the tile width and y is the tile height.
|
12
|
-
attr_reader :tile_size
|
13
|
-
|
14
|
-
# A Vector where x is the horizontal tile count and y the vertical count.
|
15
|
-
attr_reader :size
|
16
|
-
|
17
|
-
# A Rectangle representing the region of the map that is currently
|
18
|
-
# visible.
|
19
|
-
attr_reader :cam
|
20
|
-
|
21
|
-
# Creates a new map.
|
22
|
-
#
|
23
|
-
# Parameters:
|
24
|
-
# [t_w] The width of the tiles.
|
25
|
-
# [t_h] The height of the tiles.
|
26
|
-
# [t_x_count] The horizontal count of tiles in the map.
|
27
|
-
# [t_y_count] The vertical count of tiles in the map.
|
28
|
-
# [scr_w] Width of the viewport for the map.
|
29
|
-
# [scr_h] Height of the viewport for the map.
|
30
|
-
# [isometric] Whether to use a isometric map. By default, an ortogonal map
|
31
|
-
# is used.
|
32
|
-
# [limit_cam] Whether the camera should respect the bounds of the map
|
33
|
-
# (i.e., when given coordinates that would imply regions
|
34
|
-
# outside the map to appear in the screen, the camera would
|
35
|
-
# move to the nearest position where only the map shows up
|
36
|
-
# in the screen).
|
37
|
-
def initialize(t_w, t_h, t_x_count, t_y_count, scr_w = 800, scr_h = 600, isometric = false, limit_cam = true)
|
38
|
-
@tile_size = Vector.new t_w, t_h
|
39
|
-
@size = Vector.new t_x_count, t_y_count
|
40
|
-
@cam = Rectangle.new 0, 0, scr_w, scr_h
|
41
|
-
@limit_cam = limit_cam
|
42
|
-
@isometric = isometric
|
43
|
-
if isometric
|
44
|
-
initialize_isometric
|
45
|
-
elsif limit_cam
|
46
|
-
@max_x = t_x_count * t_w - scr_w
|
47
|
-
@max_y = t_y_count * t_h - scr_h
|
48
|
-
end
|
49
|
-
set_camera 0, 0
|
50
|
-
end
|
51
|
-
|
52
|
-
# Returns a Vector with the total size of the map, in pixels (x for the
|
53
|
-
# width and y for the height).
|
54
|
-
def get_absolute_size
|
55
|
-
return Vector.new(@tile_size.x * @size.x, @tile_size.y * @size.y) unless @isometric
|
56
|
-
avg = (@size.x + @size.y) * 0.5
|
57
|
-
Vector.new (avg * @tile_size.x).to_i, (avg * @tile_size.y).to_i
|
58
|
-
end
|
59
|
-
|
60
|
-
# Returns a Vector with the coordinates of the center of the map.
|
61
|
-
def get_center
|
62
|
-
abs_size = get_absolute_size
|
63
|
-
Vector.new(abs_size.x * 0.5, abs_size.y * 0.5)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Returns the position in the screen corresponding to the given tile
|
67
|
-
# indices.
|
68
|
-
#
|
69
|
-
# Parameters:
|
70
|
-
# [map_x] The index of the tile in the horizontal direction. It must be in
|
71
|
-
# the interval <code>0..t_x_count</code>.
|
72
|
-
# [map_y] The index of the tile in the vertical direction. It must be in
|
73
|
-
# the interval <code>0..t_y_count</code>.
|
74
|
-
def get_screen_pos(map_x, map_y)
|
75
|
-
return Vector.new(map_x * @tile_size.x - @cam.x, map_y * @tile_size.y - @cam.y) unless @isometric
|
76
|
-
Vector.new ((map_x - map_y - 1) * @tile_size.x * 0.5) - @cam.x + @x_offset,
|
77
|
-
((map_x + map_y) * @tile_size.y * 0.5) - @cam.y
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns the tile in the map that corresponds to the given position in
|
81
|
-
# the screen, as a Vector, where x is the horizontal index and y the
|
82
|
-
# vertical index.
|
83
|
-
#
|
84
|
-
# Parameters:
|
85
|
-
# [scr_x] The x-coordinate in the screen.
|
86
|
-
# [scr_y] The y-coordinate in the screen.
|
87
|
-
def get_map_pos(scr_x, scr_y)
|
88
|
-
return Vector.new((scr_x + @cam.x) / @tile_size.x, (scr_y + @cam.y) / @tile_size.y) unless @isometric
|
89
|
-
|
90
|
-
# Obtém a posição transformada para as coordenadas isométricas
|
91
|
-
v = get_isometric_position scr_x, scr_y
|
92
|
-
|
93
|
-
# Depois divide pelo tamanho do quadrado para achar a posição da matriz
|
94
|
-
Vector.new((v.x * @inverse_square_size).to_i, (v.y * @inverse_square_size).to_i)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Verifies whether a tile is inside the map.
|
98
|
-
#
|
99
|
-
# Parameters:
|
100
|
-
# [v] A Vector representing the tile, with x as the horizontal index and
|
101
|
-
# y as the vertical index.
|
102
|
-
def is_in_map(v)
|
103
|
-
v.x >= 0 && v.y >= 0 && v.x < @size.x && v.y < @size.y
|
104
|
-
end
|
105
|
-
|
106
|
-
# Sets the top left corner of the viewport to the given position of the
|
107
|
-
# map. Note that this is not the position in the screen.
|
108
|
-
#
|
109
|
-
# Parameters:
|
110
|
-
# [cam_x] The x-coordinate inside the map, in pixels (not a tile index).
|
111
|
-
# [cam_y] The y-coordinate inside the map, in pixels (not a tile index).
|
112
|
-
def set_camera(cam_x, cam_y)
|
113
|
-
@cam.x = cam_x
|
114
|
-
@cam.y = cam_y
|
115
|
-
set_bounds
|
116
|
-
end
|
117
|
-
|
118
|
-
# Moves the viewport by the given amount of pixels.
|
119
|
-
#
|
120
|
-
# Parameters:
|
121
|
-
# [x] The amount of pixels to move horizontally. Negative values will
|
122
|
-
# cause the camera to move to the left.
|
123
|
-
# [y] The amount of pixels to move vertically. Negative values will cause
|
124
|
-
# the camera to move up.
|
125
|
-
def move_camera(x, y)
|
126
|
-
@cam.x += x
|
127
|
-
@cam.y += y
|
128
|
-
set_bounds
|
129
|
-
end
|
130
|
-
|
131
|
-
# Iterates through the currently visible tiles, providing the horizontal
|
132
|
-
# tile index, the vertical tile index, the x-coordinate (in pixels) and
|
133
|
-
# the y-coordinate (in pixels), of each tile, in that order, to a given
|
134
|
-
# block of code.
|
135
|
-
#
|
136
|
-
# Example:
|
137
|
-
#
|
138
|
-
# map.foreach do |i, j, x, y|
|
139
|
-
# draw_tile tiles[i][j], x, y
|
140
|
-
# end
|
141
|
-
def foreach
|
142
|
-
for j in @min_vis_y..@max_vis_y
|
143
|
-
for i in @min_vis_x..@max_vis_x
|
144
|
-
pos = get_screen_pos i, j
|
145
|
-
yield i, j, pos.x, pos.y
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def set_bounds
|
153
|
-
if @limit_cam
|
154
|
-
if @isometric
|
155
|
-
v1 = get_isometric_position(0, 0)
|
156
|
-
v2 = get_isometric_position(@cam.w - 1, 0)
|
157
|
-
v3 = get_isometric_position(@cam.w - 1, @cam.h - 1)
|
158
|
-
v4 = get_isometric_position(0, @cam.h - 1)
|
159
|
-
if v1.x < -@max_offset
|
160
|
-
offset = -(v1.x + @max_offset)
|
161
|
-
@cam.x += offset * SQRT_2_DIV_2
|
162
|
-
@cam.y += offset * SQRT_2_DIV_2 / @tile_ratio
|
163
|
-
v1.x = -@max_offset
|
164
|
-
end
|
165
|
-
if v2.y < -@max_offset
|
166
|
-
offset = -(v2.y + @max_offset)
|
167
|
-
@cam.x -= offset * SQRT_2_DIV_2
|
168
|
-
@cam.y += offset * SQRT_2_DIV_2 / @tile_ratio
|
169
|
-
v2.y = -@max_offset
|
170
|
-
end
|
171
|
-
if v3.x > @iso_abs_size.x + @max_offset
|
172
|
-
offset = v3.x - @iso_abs_size.x - @max_offset
|
173
|
-
@cam.x -= offset * SQRT_2_DIV_2
|
174
|
-
@cam.y -= offset * SQRT_2_DIV_2 / @tile_ratio
|
175
|
-
v3.x = @iso_abs_size.x + @max_offset
|
176
|
-
end
|
177
|
-
if v4.y > @iso_abs_size.y + @max_offset
|
178
|
-
offset = v4.y - @iso_abs_size.y - @max_offset
|
179
|
-
@cam.x += offset * SQRT_2_DIV_2
|
180
|
-
@cam.y -= offset * SQRT_2_DIV_2 / @tile_ratio
|
181
|
-
v4.y = @iso_abs_size.y + @max_offset
|
182
|
-
end
|
183
|
-
else
|
184
|
-
@cam.x = @max_x if @cam.x > @max_x
|
185
|
-
@cam.x = 0 if @cam.x < 0
|
186
|
-
@cam.y = @max_y if @cam.y > @max_y
|
187
|
-
@cam.y = 0 if @cam.y < 0
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
@cam.x = @cam.x.round
|
192
|
-
@cam.y = @cam.y.round
|
193
|
-
if @isometric
|
194
|
-
@min_vis_x = get_map_pos(0, 0).x
|
195
|
-
@min_vis_y = get_map_pos(@cam.w - 1, 0).y
|
196
|
-
@max_vis_x = get_map_pos(@cam.w - 1, @cam.h - 1).x
|
197
|
-
@max_vis_y = get_map_pos(0, @cam.h - 1).y
|
198
|
-
else
|
199
|
-
@min_vis_x = @cam.x / @tile_size.x
|
200
|
-
@min_vis_y = @cam.y / @tile_size.y
|
201
|
-
@max_vis_x = (@cam.x + @cam.w - 1) / @tile_size.x
|
202
|
-
@max_vis_y = (@cam.y + @cam.h - 1) / @tile_size.y
|
203
|
-
end
|
204
|
-
|
205
|
-
if @min_vis_y < 0; @min_vis_y = 0
|
206
|
-
elsif @min_vis_y > @size.y - 1; @min_vis_y = @size.y - 1; end
|
207
|
-
|
208
|
-
if @max_vis_y < 0; @max_vis_y = 0
|
209
|
-
elsif @max_vis_y > @size.y - 1; @max_vis_y = @size.y - 1; end
|
210
|
-
|
211
|
-
if @min_vis_x < 0; @min_vis_x = 0
|
212
|
-
elsif @min_vis_x > @size.x - 1; @min_vis_x = @size.x - 1; end
|
213
|
-
|
214
|
-
if @max_vis_x < 0; @max_vis_x = 0
|
215
|
-
elsif @max_vis_x > @size.x - 1; @max_vis_x = @size.x - 1; end
|
216
|
-
end
|
217
|
-
|
218
|
-
def initialize_isometric
|
219
|
-
@x_offset = (@size.y * 0.5 * @tile_size.x).round
|
220
|
-
@tile_ratio = @tile_size.x.to_f / @tile_size.y
|
221
|
-
square_size = @tile_size.x * SQRT_2_DIV_2
|
222
|
-
@inverse_square_size = 1 / square_size
|
223
|
-
@iso_abs_size = Vector.new(square_size * @size.x, square_size * @size.y)
|
224
|
-
a = (@size.x + @size.y) * 0.5 * @tile_size.x
|
225
|
-
@isometric_offset_x = (a - square_size * @size.x) * 0.5
|
226
|
-
@isometric_offset_y = (a - square_size * @size.y) * 0.5
|
227
|
-
if @limit_cam
|
228
|
-
actual_cam_h = @cam.h * @tile_ratio
|
229
|
-
@max_offset = actual_cam_h < @cam.w ? actual_cam_h : @cam.w
|
230
|
-
@max_offset *= SQRT_2_DIV_2
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def get_isometric_position(scr_x, scr_y)
|
235
|
-
# Escreve a posição em relação a origem (no centro do mapa)
|
236
|
-
center = get_center
|
237
|
-
position = Vector.new scr_x + @cam.x - center.x, scr_y + @cam.y - center.y
|
238
|
-
|
239
|
-
# Multiplica por tile_ratio para obter tiles quadrados
|
240
|
-
position.y *= @tile_ratio
|
241
|
-
|
242
|
-
# O centro do mapa também é deslocado
|
243
|
-
center.y *= @tile_ratio
|
244
|
-
|
245
|
-
# Rotaciona o vetor posição -45°
|
246
|
-
position.rotate! MINUS_PI_DIV_4
|
247
|
-
|
248
|
-
# Retorna a referência da posição para o canto da tela
|
249
|
-
position += center
|
250
|
-
|
251
|
-
# O mapa quadrado está centralizado no centro do losango, precisa retornar ao canto da tela
|
252
|
-
position.x -= @isometric_offset_x; position.y -= @isometric_offset_y
|
253
|
-
position
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
1
|
+
require_relative 'global'
|
2
|
+
|
3
|
+
module MiniGL
|
4
|
+
# This class provides easy control of a tile map, i.e., a map consisting of
|
5
|
+
# a grid of equally sized tiles. It also provides viewport control, through
|
6
|
+
# its camera property and methods.
|
7
|
+
class Map
|
8
|
+
SQRT_2_DIV_2 = Math.sqrt(2) / 2 # :nodoc:
|
9
|
+
MINUS_PI_DIV_4 = -Math::PI / 4 # :nodoc:
|
10
|
+
|
11
|
+
# A Vector where x is the tile width and y is the tile height.
|
12
|
+
attr_reader :tile_size
|
13
|
+
|
14
|
+
# A Vector where x is the horizontal tile count and y the vertical count.
|
15
|
+
attr_reader :size
|
16
|
+
|
17
|
+
# A Rectangle representing the region of the map that is currently
|
18
|
+
# visible.
|
19
|
+
attr_reader :cam
|
20
|
+
|
21
|
+
# Creates a new map.
|
22
|
+
#
|
23
|
+
# Parameters:
|
24
|
+
# [t_w] The width of the tiles.
|
25
|
+
# [t_h] The height of the tiles.
|
26
|
+
# [t_x_count] The horizontal count of tiles in the map.
|
27
|
+
# [t_y_count] The vertical count of tiles in the map.
|
28
|
+
# [scr_w] Width of the viewport for the map.
|
29
|
+
# [scr_h] Height of the viewport for the map.
|
30
|
+
# [isometric] Whether to use a isometric map. By default, an ortogonal map
|
31
|
+
# is used.
|
32
|
+
# [limit_cam] Whether the camera should respect the bounds of the map
|
33
|
+
# (i.e., when given coordinates that would imply regions
|
34
|
+
# outside the map to appear in the screen, the camera would
|
35
|
+
# move to the nearest position where only the map shows up
|
36
|
+
# in the screen).
|
37
|
+
def initialize(t_w, t_h, t_x_count, t_y_count, scr_w = 800, scr_h = 600, isometric = false, limit_cam = true)
|
38
|
+
@tile_size = Vector.new t_w, t_h
|
39
|
+
@size = Vector.new t_x_count, t_y_count
|
40
|
+
@cam = Rectangle.new 0, 0, scr_w, scr_h
|
41
|
+
@limit_cam = limit_cam
|
42
|
+
@isometric = isometric
|
43
|
+
if isometric
|
44
|
+
initialize_isometric
|
45
|
+
elsif limit_cam
|
46
|
+
@max_x = t_x_count * t_w - scr_w
|
47
|
+
@max_y = t_y_count * t_h - scr_h
|
48
|
+
end
|
49
|
+
set_camera 0, 0
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a Vector with the total size of the map, in pixels (x for the
|
53
|
+
# width and y for the height).
|
54
|
+
def get_absolute_size
|
55
|
+
return Vector.new(@tile_size.x * @size.x, @tile_size.y * @size.y) unless @isometric
|
56
|
+
avg = (@size.x + @size.y) * 0.5
|
57
|
+
Vector.new (avg * @tile_size.x).to_i, (avg * @tile_size.y).to_i
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns a Vector with the coordinates of the center of the map.
|
61
|
+
def get_center
|
62
|
+
abs_size = get_absolute_size
|
63
|
+
Vector.new(abs_size.x * 0.5, abs_size.y * 0.5)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the position in the screen corresponding to the given tile
|
67
|
+
# indices.
|
68
|
+
#
|
69
|
+
# Parameters:
|
70
|
+
# [map_x] The index of the tile in the horizontal direction. It must be in
|
71
|
+
# the interval <code>0..t_x_count</code>.
|
72
|
+
# [map_y] The index of the tile in the vertical direction. It must be in
|
73
|
+
# the interval <code>0..t_y_count</code>.
|
74
|
+
def get_screen_pos(map_x, map_y)
|
75
|
+
return Vector.new(map_x * @tile_size.x - @cam.x, map_y * @tile_size.y - @cam.y) unless @isometric
|
76
|
+
Vector.new ((map_x - map_y - 1) * @tile_size.x * 0.5) - @cam.x + @x_offset,
|
77
|
+
((map_x + map_y) * @tile_size.y * 0.5) - @cam.y
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the tile in the map that corresponds to the given position in
|
81
|
+
# the screen, as a Vector, where x is the horizontal index and y the
|
82
|
+
# vertical index.
|
83
|
+
#
|
84
|
+
# Parameters:
|
85
|
+
# [scr_x] The x-coordinate in the screen.
|
86
|
+
# [scr_y] The y-coordinate in the screen.
|
87
|
+
def get_map_pos(scr_x, scr_y)
|
88
|
+
return Vector.new((scr_x + @cam.x) / @tile_size.x, (scr_y + @cam.y) / @tile_size.y) unless @isometric
|
89
|
+
|
90
|
+
# Obtém a posição transformada para as coordenadas isométricas
|
91
|
+
v = get_isometric_position scr_x, scr_y
|
92
|
+
|
93
|
+
# Depois divide pelo tamanho do quadrado para achar a posição da matriz
|
94
|
+
Vector.new((v.x * @inverse_square_size).to_i, (v.y * @inverse_square_size).to_i)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Verifies whether a tile is inside the map.
|
98
|
+
#
|
99
|
+
# Parameters:
|
100
|
+
# [v] A Vector representing the tile, with x as the horizontal index and
|
101
|
+
# y as the vertical index.
|
102
|
+
def is_in_map(v)
|
103
|
+
v.x >= 0 && v.y >= 0 && v.x < @size.x && v.y < @size.y
|
104
|
+
end
|
105
|
+
|
106
|
+
# Sets the top left corner of the viewport to the given position of the
|
107
|
+
# map. Note that this is not the position in the screen.
|
108
|
+
#
|
109
|
+
# Parameters:
|
110
|
+
# [cam_x] The x-coordinate inside the map, in pixels (not a tile index).
|
111
|
+
# [cam_y] The y-coordinate inside the map, in pixels (not a tile index).
|
112
|
+
def set_camera(cam_x, cam_y)
|
113
|
+
@cam.x = cam_x
|
114
|
+
@cam.y = cam_y
|
115
|
+
set_bounds
|
116
|
+
end
|
117
|
+
|
118
|
+
# Moves the viewport by the given amount of pixels.
|
119
|
+
#
|
120
|
+
# Parameters:
|
121
|
+
# [x] The amount of pixels to move horizontally. Negative values will
|
122
|
+
# cause the camera to move to the left.
|
123
|
+
# [y] The amount of pixels to move vertically. Negative values will cause
|
124
|
+
# the camera to move up.
|
125
|
+
def move_camera(x, y)
|
126
|
+
@cam.x += x
|
127
|
+
@cam.y += y
|
128
|
+
set_bounds
|
129
|
+
end
|
130
|
+
|
131
|
+
# Iterates through the currently visible tiles, providing the horizontal
|
132
|
+
# tile index, the vertical tile index, the x-coordinate (in pixels) and
|
133
|
+
# the y-coordinate (in pixels), of each tile, in that order, to a given
|
134
|
+
# block of code.
|
135
|
+
#
|
136
|
+
# Example:
|
137
|
+
#
|
138
|
+
# map.foreach do |i, j, x, y|
|
139
|
+
# draw_tile tiles[i][j], x, y
|
140
|
+
# end
|
141
|
+
def foreach
|
142
|
+
for j in @min_vis_y..@max_vis_y
|
143
|
+
for i in @min_vis_x..@max_vis_x
|
144
|
+
pos = get_screen_pos i, j
|
145
|
+
yield i, j, pos.x, pos.y
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def set_bounds
|
153
|
+
if @limit_cam
|
154
|
+
if @isometric
|
155
|
+
v1 = get_isometric_position(0, 0)
|
156
|
+
v2 = get_isometric_position(@cam.w - 1, 0)
|
157
|
+
v3 = get_isometric_position(@cam.w - 1, @cam.h - 1)
|
158
|
+
v4 = get_isometric_position(0, @cam.h - 1)
|
159
|
+
if v1.x < -@max_offset
|
160
|
+
offset = -(v1.x + @max_offset)
|
161
|
+
@cam.x += offset * SQRT_2_DIV_2
|
162
|
+
@cam.y += offset * SQRT_2_DIV_2 / @tile_ratio
|
163
|
+
v1.x = -@max_offset
|
164
|
+
end
|
165
|
+
if v2.y < -@max_offset
|
166
|
+
offset = -(v2.y + @max_offset)
|
167
|
+
@cam.x -= offset * SQRT_2_DIV_2
|
168
|
+
@cam.y += offset * SQRT_2_DIV_2 / @tile_ratio
|
169
|
+
v2.y = -@max_offset
|
170
|
+
end
|
171
|
+
if v3.x > @iso_abs_size.x + @max_offset
|
172
|
+
offset = v3.x - @iso_abs_size.x - @max_offset
|
173
|
+
@cam.x -= offset * SQRT_2_DIV_2
|
174
|
+
@cam.y -= offset * SQRT_2_DIV_2 / @tile_ratio
|
175
|
+
v3.x = @iso_abs_size.x + @max_offset
|
176
|
+
end
|
177
|
+
if v4.y > @iso_abs_size.y + @max_offset
|
178
|
+
offset = v4.y - @iso_abs_size.y - @max_offset
|
179
|
+
@cam.x += offset * SQRT_2_DIV_2
|
180
|
+
@cam.y -= offset * SQRT_2_DIV_2 / @tile_ratio
|
181
|
+
v4.y = @iso_abs_size.y + @max_offset
|
182
|
+
end
|
183
|
+
else
|
184
|
+
@cam.x = @max_x if @cam.x > @max_x
|
185
|
+
@cam.x = 0 if @cam.x < 0
|
186
|
+
@cam.y = @max_y if @cam.y > @max_y
|
187
|
+
@cam.y = 0 if @cam.y < 0
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
@cam.x = @cam.x.round
|
192
|
+
@cam.y = @cam.y.round
|
193
|
+
if @isometric
|
194
|
+
@min_vis_x = get_map_pos(0, 0).x
|
195
|
+
@min_vis_y = get_map_pos(@cam.w - 1, 0).y
|
196
|
+
@max_vis_x = get_map_pos(@cam.w - 1, @cam.h - 1).x
|
197
|
+
@max_vis_y = get_map_pos(0, @cam.h - 1).y
|
198
|
+
else
|
199
|
+
@min_vis_x = @cam.x / @tile_size.x
|
200
|
+
@min_vis_y = @cam.y / @tile_size.y
|
201
|
+
@max_vis_x = (@cam.x + @cam.w - 1) / @tile_size.x
|
202
|
+
@max_vis_y = (@cam.y + @cam.h - 1) / @tile_size.y
|
203
|
+
end
|
204
|
+
|
205
|
+
if @min_vis_y < 0; @min_vis_y = 0
|
206
|
+
elsif @min_vis_y > @size.y - 1; @min_vis_y = @size.y - 1; end
|
207
|
+
|
208
|
+
if @max_vis_y < 0; @max_vis_y = 0
|
209
|
+
elsif @max_vis_y > @size.y - 1; @max_vis_y = @size.y - 1; end
|
210
|
+
|
211
|
+
if @min_vis_x < 0; @min_vis_x = 0
|
212
|
+
elsif @min_vis_x > @size.x - 1; @min_vis_x = @size.x - 1; end
|
213
|
+
|
214
|
+
if @max_vis_x < 0; @max_vis_x = 0
|
215
|
+
elsif @max_vis_x > @size.x - 1; @max_vis_x = @size.x - 1; end
|
216
|
+
end
|
217
|
+
|
218
|
+
def initialize_isometric
|
219
|
+
@x_offset = (@size.y * 0.5 * @tile_size.x).round
|
220
|
+
@tile_ratio = @tile_size.x.to_f / @tile_size.y
|
221
|
+
square_size = @tile_size.x * SQRT_2_DIV_2
|
222
|
+
@inverse_square_size = 1 / square_size
|
223
|
+
@iso_abs_size = Vector.new(square_size * @size.x, square_size * @size.y)
|
224
|
+
a = (@size.x + @size.y) * 0.5 * @tile_size.x
|
225
|
+
@isometric_offset_x = (a - square_size * @size.x) * 0.5
|
226
|
+
@isometric_offset_y = (a - square_size * @size.y) * 0.5
|
227
|
+
if @limit_cam
|
228
|
+
actual_cam_h = @cam.h * @tile_ratio
|
229
|
+
@max_offset = actual_cam_h < @cam.w ? actual_cam_h : @cam.w
|
230
|
+
@max_offset *= SQRT_2_DIV_2
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def get_isometric_position(scr_x, scr_y)
|
235
|
+
# Escreve a posição em relação a origem (no centro do mapa)
|
236
|
+
center = get_center
|
237
|
+
position = Vector.new scr_x + @cam.x - center.x, scr_y + @cam.y - center.y
|
238
|
+
|
239
|
+
# Multiplica por tile_ratio para obter tiles quadrados
|
240
|
+
position.y *= @tile_ratio
|
241
|
+
|
242
|
+
# O centro do mapa também é deslocado
|
243
|
+
center.y *= @tile_ratio
|
244
|
+
|
245
|
+
# Rotaciona o vetor posição -45°
|
246
|
+
position.rotate! MINUS_PI_DIV_4
|
247
|
+
|
248
|
+
# Retorna a referência da posição para o canto da tela
|
249
|
+
position += center
|
250
|
+
|
251
|
+
# O mapa quadrado está centralizado no centro do losango, precisa retornar ao canto da tela
|
252
|
+
position.x -= @isometric_offset_x; position.y -= @isometric_offset_y
|
253
|
+
position
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|