Class: GamesAndRpgParadise::Colliders

Inherits:
Object
  • Object
show all
Defined in:
lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(collider_name, buffer, centre_and_top_gap, centre_and_bottom_gap, centre_and_left_gap, centre_and_right_gap) ⇒ Colliders

initialize



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 15

def initialize(
    collider_name,
    buffer,
    centre_and_top_gap,
    centre_and_bottom_gap,
    centre_and_left_gap,
    centre_and_right_gap
  )
#collider_name is the name (a string) given to the collider layer in Tiled
#rest of arguments are the size of the gaps required between different parts of a sprite and the colliders
  @collider_name = collider_name
  @buffer = buffer
  @centre_and_top_gap = centre_and_top_gap
  @centre_and_bottom_gap = centre_and_bottom_gap
  @centre_and_left_gap = centre_and_left_gap
  @centre_and_right_gap = centre_and_right_gap
end

Instance Attribute Details

#bottom_collisionObject (readonly)

Returns the value of attribute bottom_collision.



10
11
12
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 10

def bottom_collision
  @bottom_collision
end

#left_collisionObject (readonly)

Returns the value of attribute left_collision.



11
12
13
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 11

def left_collision
  @left_collision
end

#right_collisionObject (readonly)

Returns the value of attribute right_collision.



12
13
14
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 12

def right_collision
  @right_collision
end

#top_collisionObject (readonly)

Returns the value of attribute top_collision.



9
10
11
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 9

def top_collision
  @top_collision
end

Instance Method Details

#bottom_collision_check(x, y, speed) ⇒ Object

bottom_collision_check



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 128

def bottom_collision_check(x, y, speed)
  @x = x
  @y = y
  @speed = speed
  player_bottom_and_buffer = y + @centre_and_bottom_gap - @buffer
  player_right = @x + 6
  player_left = @x - 6
  @bottom_collision = false 
  @line_ranges.each do |range|
    x_left = range[:x_range][0]
    x_right = range[:x_range][1]
    y_bottom = range[:y_range][0]
    if (player_left >= x_left) && (player_left <= x_right) && player_bottom_and_buffer < y_bottom && x_left != x_right
      if Gosu.distance(@x,player_bottom_and_buffer + @speed,@x,y_bottom) <= @buffer
        @bottom_collision = true
      end
    end
    if (player_right >= x_left) && (player_right <= x_right) && player_bottom_and_buffer < y_bottom && x_left != x_right
      if Gosu.distance(@x,player_bottom_and_buffer + @speed,@x,y_bottom) <= @buffer
        @bottom_collision = true
      end
    end 

  end

end

#calculate_linesObject

calculate_lines



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
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 34

def calculate_lines
  #loads the json map file exported from Tiled, with all its collider layers
  file = File.read('map.json')
  data_hash = JSON.parse(file)
  #locates the array named "objects" within the json file and assigns it. "objects" in the json file contains the coordinates for every point in the colliders
  data_hash['layers'].each { |x|
    if x["name"] == "#{@collider_name}"
      @data_from_tiled =  x["objects"]
    end
  }
#the coordinates for each point within the json file are relative and not actual. We'll need to adjust them using the origin of each collider

#first we set up an array to collect the points once we've adjusted them
@colliders = []
#this is a temp storage for each point. We'll use it later to pass each point seperately to @colliders
@temp_collider_storage = []
#then we go into the data from the json file and retrieve and assign the origin of each collider 
@data_from_tiled.each do |data|
  polyline_x_origin = data["x"]
  polyline_y_origin = data["y"]
  #then we take every coordinate for each point and adjust it relative to the collider's origin to get its 'true' value
  data["polyline"].each do |polyline_point|
    adjusted_polyline_x = polyline_point["x"] + polyline_x_origin
    adjusted_polyline_y = polyline_point["y"] + polyline_y_origin 
    #then we pass the adjusted coordinates of each point to the temp storage array
    @temp_collider_storage.push ({x: adjusted_polyline_x, y: adjusted_polyline_y})
  end
  #then we pass the adjusted coordinates to @colliders. Doing it like this ensures that each point is passed one at a time, as seperate objects
  @colliders.push @temp_collider_storage
  #this resets the temp storage array so it can be used to collect the next point's adjusted coordinates
  @temp_collider_storage = []
end

#next, we set up an array to pair-up the points of each line that makes up every collider. 
#Each line (like any line) will have two points ie coordinates. The end coordinate of one line will be the starting coordinate of the next line in the collider
@lines = []
#so we take each point...
@colliders.each { |point|
  #...and access each of its coordinates, along with each coordinate's array index (its numercal location in the array)
  point.each_with_index do |coordinate, i|  
    #if the coordinate doesn't have a following coordinate, nothing happens. 
    #Otherwise the coordinate is pushed with its ajacent coordinate into @lines (each pair of coordinates, or points, now represents a line in its collider)
    if point[i + 1].nil?
      0
    else
      next_coordinate = point[i+1]
      @lines.push [coordinate, next_coordinate]
    end
  end
}
# Now we want to work out the 'range' of each line so we can find out if the player will bump into it
# First set up an array to collect the ranges for each line
@line_ranges = []
#Then for each line we extract the two x values and sort them from low to high. Same with y values. Then push to @lines_ranges.
@lines.each do |line|
  x_values_sorted = [line[0][:x], line[1][:x]].sort!
  y_values_sorted = [line[0][:y], line[1][:y]].sort!
  @line_ranges.push ({x_range: x_values_sorted, y_range: y_values_sorted})
end
#@lines_ranges can now be passed to whatever entity needs to know colliders
@line_ranges
end

#left_collision_check(x, y, speed) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 155

def left_collision_check(x, y, speed)
  @x = x
  @y = y
  @speed = speed
  player_top = @y + @centre_and_top_gap
  player_bottom = @y + @centre_and_bottom_gap
  player_right = @x + @centre_and_right_gap
  player_left_and_buffer = @x - @centre_and_left_gap + @buffer
  @left_collision = false 
  @line_ranges.each do |range|
    y_top = range[:y_range][0]
    y_bottom = range[:y_range][1]
    x_left = range[:x_range][0]
    if (player_top >= y_top) && (player_top <= y_bottom) && player_left_and_buffer > x_left && y_top != y_bottom
      if Gosu.distance(player_left_and_buffer - @speed,@y,x_left,@y) <= @buffer
        @left_collision = true
      end
    end
    if (player_bottom >= y_top) && (player_bottom <= y_bottom) && player_left_and_buffer > x_left && y_top != y_bottom
      if Gosu.distance(player_left_and_buffer - @speed,@y,x_left,@y) <= @buffer
        @left_collision = true
      end
    end 
  end
end

#right_collision_check(x, y, speed) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 181

def right_collision_check(x, y, speed)
  @x = x
  @y = y
  @speed = speed
  player_top = @y + @centre_and_top_gap
  player_bottom = @y + @centre_and_bottom_gap
  player_right_and_buffer = @x + @centre_and_right_gap - @buffer
  @right_collision = false 
  @line_ranges.each do |range|
    y_top = range[:y_range][0]
    y_bottom = range[:y_range][1]
    x_right = range[:x_range][1]
    if (player_top >= y_top) && (player_top <= y_bottom) && player_right_and_buffer < x_right && y_top != y_bottom
      if Gosu.distance(player_right_and_buffer + @speed,@y,x_right,@y) <= @buffer
        @right_collision = true
      end
    end
    if (player_bottom >= y_top) && (player_bottom <= y_bottom) && player_right_and_buffer < x_right && y_top != y_bottom
      if Gosu.distance(player_right_and_buffer + @speed,@y,x_right,@y) <= @buffer
        @right_collision = true
      end
    end
  end

end

#top_collision_check(x, y, speed) ⇒ Object

top_colision_check



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
# File 'lib/games_and_rpg_paradise/gui/gosu/final_fantasy/colliders.rb', line 97

def top_collision_check(x, y, speed)
  @x = x
  @y = y
  @speed = speed
  player_top_and_buffer = y + @centre_and_top_gap + @buffer
  player_right = @x + 6
  player_left = @x - 6
  #at the start of every check, we assume there is no collision
  @top_collision = false
  #Then we look to see if we are within the x values in all the lines (colliders) we have. 
  @line_ranges.each do |range|
    x_left = range[:x_range][0]
    x_right = range[:x_range][1]
    y_top = range[:y_range][0]
    #if we are within x range, then check to see we are below the line (as that's the only way we can top collide with it)
    # I've used '&& x_left != x_right' to exclude vertical lines
    if (player_left >= x_left) && (player_left <= x_right) && player_top_and_buffer > y_top && x_left != x_right
      if Gosu.distance(@x,player_top_and_buffer - @speed,@x,y_top) <= @buffer  
        @top_collision = true
      end
    end
    if (player_right >= x_left) && (player_right <= x_right) && player_top_and_buffer > y_top && x_left != x_right
      if Gosu.distance(@x,player_top_and_buffer - @speed,@x,y_top) <= @buffer
        @top_collision = true
      end
    end 
  end
  @top_collision
end