Class: MiniGL::Ramp

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

Overview

Represents a ramp, i.e., an inclined structure which allows walking over it while automatically going up or down. It can be imagined as a right triangle, with a side parallel to the x axis and another one parallel to the y axis. You must provide instances of this class (or derived classes) to the ramps array parameter of the move method.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, y, w, h, left, inverted = false) ⇒ Ramp

Creates a new ramp.

Parameters:

x

The x-coordinate of the top left corner of a rectangle that completely (and precisely) encloses the ramp (thought of as a right triangle).

y

The y-coordinate of the top left corner of the rectangle described above.

w

The width of the ramp (which corresponds to the width of the rectangle described above).

h

The height of the ramp (which corresponds to the height of the rectangle described above, and to the difference between the lowest point of the ramp, where it usually meets the floor, and the highest).

left

Whether the height of the ramp increases from left to right. Use false for a ramp that goes down from left to right.

inverted

Whether the ramp is vertically inverted, i.e., the face that is parallel to the x-axis faces up and the sloped face faces down.



99
100
101
102
103
104
105
106
107
108
# File 'lib/minigl/movement.rb', line 99

def initialize(x, y, w, h, left, inverted = false)
  @x = x
  @y = y
  @w = w
  @h = h
  @left = left
  @inverted = inverted
  @ratio = @h.to_f / @w
  @factor = @w / Math.sqrt(@w**2 + @h**2)
end

Instance Attribute Details

#factorObject (readonly)

:nodoc:



78
79
80
# File 'lib/minigl/movement.rb', line 78

def factor
  @factor
end

#hObject (readonly)

The height of the ramp.



67
68
69
# File 'lib/minigl/movement.rb', line 67

def h
  @h
end

#invertedObject (readonly)

Whether the ramp is vertically inverted, i.e., the face that is parallel to the x-axis faces up and the sloped face faces down.



75
76
77
# File 'lib/minigl/movement.rb', line 75

def inverted
  @inverted
end

#leftObject (readonly)

Whether the height of the ramp increases from left to right (decreases from left to right when false).



71
72
73
# File 'lib/minigl/movement.rb', line 71

def left
  @left
end

#ratioObject (readonly)

:nodoc:



77
78
79
# File 'lib/minigl/movement.rb', line 77

def ratio
  @ratio
end

#wObject (readonly)

The width of the ramp.



64
65
66
# File 'lib/minigl/movement.rb', line 64

def w
  @w
end

#xObject (readonly)

The x-coordinate of the top left corner of a rectangle that completely (and precisely) encloses the ramp (thought of as a right triangle).



57
58
59
# File 'lib/minigl/movement.rb', line 57

def x
  @x
end

#yObject (readonly)

The y-coordinate of the top left corner of the rectangle described in the x attribute.



61
62
63
# File 'lib/minigl/movement.rb', line 61

def y
  @y
end

Instance Method Details

#check_can_collide(m) ⇒ Object

:nodoc:



132
133
134
135
# File 'lib/minigl/movement.rb', line 132

def check_can_collide(m)
  y = get_y(m) + (@inverted ? 0 : m.h)
  @can_collide = m.x + m.w > @x && @x + @w > m.x && m.y < y && m.y + m.h > y
end

#check_intersection(obj) ⇒ Object



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

def check_intersection(obj)
  return unless @can_collide && intersect?(obj)

  counter = @left && obj.prev_speed.x > 0 || !@left && obj.prev_speed.x < 0
  if counter && (@inverted ? obj.prev_speed.y < 0 : obj.prev_speed.y > 0)
    dx = get_x(obj) - obj.x
    s = (obj.prev_speed.y.to_f / obj.prev_speed.x).abs
    dx /= s + @ratio
    obj.x += dx
  end
  if counter && obj.bottom != self
    obj.speed.x *= @factor
  end

  obj.speed.y = 0
  obj.y = get_y(obj)
end

#contact?(obj) ⇒ Boolean

Checks if an object is in contact with this ramp (standing over it).

Parameters:

obj

The object to check contact with. It must have the x, y, w and h accessible attributes determining its bounding box.

Returns:

  • (Boolean)


115
116
117
118
# File 'lib/minigl/movement.rb', line 115

def contact?(obj)
  return false if @inverted
  obj.x + obj.w > @x && obj.x < @x + @w && obj.x.round(6) == get_x(obj).round(6) && obj.y.round(6) == get_y(obj).round(6)
end

#get_x(obj) ⇒ Object



155
156
157
158
159
# File 'lib/minigl/movement.rb', line 155

def get_x(obj)
  return obj.x if @left && obj.x + obj.w > @x + @w || !@left && obj.x < @x
  offset = (@inverted ? obj.y - @y : @y + @h - obj.y - obj.h).to_f * @w / @h
  @left ? @x + offset - obj.w : @x + @w - offset
end

#get_y(obj) ⇒ Object



161
162
163
164
165
# File 'lib/minigl/movement.rb', line 161

def get_y(obj)
  return @y + (@inverted ? @h : -obj.h) if @left && obj.x + obj.w > @x + @w || !@left && obj.x < @x
  offset = (@left ? @x + @w - obj.x - obj.w : obj.x - @x).to_f * @h / @w
  @inverted ? @y + @h - offset : @y + offset - obj.h
end

#intersect?(obj) ⇒ Boolean

Checks if an object is intersecting this ramp (inside the corresponding right triangle and at the floor level or above).

Parameters:

obj

The object to check intersection with. It must have the x, y, w and h accessible attributes determining its bounding box.

Returns:

  • (Boolean)


126
127
128
129
# File 'lib/minigl/movement.rb', line 126

def intersect?(obj)
  obj.x + obj.w > @x && obj.x < @x + @w &&
    (@inverted ? obj.y < get_y(obj) && obj.y + obj.h > @y : obj.y > get_y(obj) && obj.y < @y + @h)
end