Class: AuthorEngine::CollisionDetection

Inherits:
Object
  • Object
show all
Defined in:
lib/author_engine/collision_detection/collision_detection.rb

Defined Under Namespace

Classes: BoundingBox, Color

Instance Method Summary collapse

Constructor Details

#initialize(game_sprites, game_levels, spritesheet) ⇒ CollisionDetection

Returns a new instance of CollisionDetection.



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
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 6

def initialize(game_sprites, game_levels, spritesheet)
  @game_sprites = game_sprites
  @game_levels  = game_levels

  @sprites= []
  @levels = []

  @known_collisions = []

  spritesheet_blob = RUBY_ENGINE == "opal" ? spritesheet.to_blob.each_slice(4).to_a : spritesheet.to_blob.bytes.each_slice(4).to_a
  (spritesheet.rows / 16).times do |y|
    (spritesheet.columns / 16).times do |x|
      blob = []

      16.times do |sy|
        16.times do |sx|
          blob << spritesheet_blob[(y * 16 + sy) * spritesheet.columns + (x * 16 + sx)]
        end
      end

      add_sprite(blob.flatten!)
    end
  end

  @game_levels.each { |level| add_level(level) }
end

Instance Method Details

#add_level(level_array) ⇒ Object



41
42
43
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 41

def add_level(level_array)
  @levels << level_array # TODO: Put level's into an optimized structure for fast quadrant look-ups
end

#add_sprite(blob) ⇒ Object



37
38
39
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 37

def add_sprite(blob)
  @sprites << {blob: blob, box: bounding_box(blob)}
end

#box(sprite_index) ⇒ Object



45
46
47
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 45

def box(sprite_index)
  @sprites[sprite_index][:box]
end

#clearObject



33
34
35
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 33

def clear
  @known_collisions.clear
end

#colliding_edge(sprite_index, sprite_x, sprite_y, target_sprite_index, target_x, target_y) ⇒ Object



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
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 66

def colliding_edge(sprite_index, sprite_x, sprite_y, target_sprite_index, target_x, target_y)
  sprite_box = box(sprite_index)
  target_box = box(target_sprite_index)

  edges = {top: false, left: false, right: false, bottom: false}

  # https://gamedev.stackexchange.com/a/24091
  wy = (sprite_box.width + target_box.width) * ((sprite_y - sprite_box.height) - (target_y - target_box.height/2));
  hx = (sprite_box.height + target_box.height) * ((sprite_x - sprite_box.width) - (target_x - target_box.height/2));

  if (wy > hx)
    if (wy > -hx)
      edges[:bottom] = true
    else
      edges[:left] = true
    end
  else
    if (wy > -hx)
      edges[:right] = true
    else
      edges[:top] = true
    end
  end

  return edges
end

#debug_draw_level(level_index) ⇒ Object



97
98
99
100
101
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 97

def debug_draw_level(level_index)
  @levels[level_index].each do |sprite|
    render_bounding_box(sprite.sprite, box(sprite.sprite), sprite.x, sprite.y)
  end
end

#debug_draw_sprite(sprite_index, sprite_x, sprite_y) ⇒ Object



93
94
95
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 93

def debug_draw_sprite(sprite_index, sprite_x, sprite_y)
  render_bounding_box(sprite_index, box(sprite_index), sprite_x, sprite_y)
end

#render_bounding_box(sprite_index, box, sprite_x, sprite_y, edges = {}, z = Float::INFINITY, color = 0xc800ff00, collision_color = 0xc8ff00ff) ⇒ Object



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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 103

def render_bounding_box(sprite_index, box, sprite_x, sprite_y, edges = {}, z = Float::INFINITY, color = 0xc800ff00, collision_color = 0xc8ff00ff)
  if RUBY_ENGINE == "opal"
    color = "green"
    collision_color = "purple"
  end
  paint_color = color
  # EDGE: TOP
  # TOP LEFT TO TOP RIGHT
  if edges[:top] then paint_color = collision_color; else paint_color = color; end
  draw_line(
    box.x + sprite_x, box.y + sprite_y,
    box.x + sprite_x + box.width, box.y + sprite_y,
    paint_color, z
  )

  # EDGE: RIGHT
  # TOP RIGHT TO BOTTOM RIGHT
  if edges[:right] then paint_color = collision_color; else paint_color = color; end
  draw_line(
    box.x + sprite_x + box.width, box.y + sprite_y,
    box.x + sprite_x + box.width, box.y + sprite_y + box.height,
    paint_color, z
  )

  # EDGE: BOTTOM
  # BOTTOM RIGHT to BOTTOM LEFT
  if edges[:bottom] then paint_color = collision_color; else paint_color = color; end
  draw_line(
    box.x + sprite_x + box.width, box.y + sprite_y + box.height,
    box.x + sprite_x, box.y + sprite_y + box.height,
    paint_color, z
  )

  # EDGE: LEFT
  # BOTTOM LEFT TO TOP LEFT
  if edges[:left] then paint_color = collision_color; else paint_color = color; end
  draw_line(
    box.x + sprite_x, box.y + sprite_y + box.height,
    box.x + sprite_x, box.y + sprite_y,
    paint_color, z
  )
end

#sprite_vs_level(sprite_index, sprite_x, sprite_y, level) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 53

def sprite_vs_level(sprite_index, sprite_x, sprite_y, level)
  detected = []

  collider = box(sprite_index)
  @levels[level].each do |sprite|
    if bounding_boxes_intersect?(collider, sprite_x, sprite_y, box(sprite.sprite), sprite.x, sprite.y)
      detected << sprite
    end
  end

  return detected
end

#sprite_vs_sprite(sprite_index, sprite_x, sprite_y, target_sprite_index, target_x, target_y) ⇒ Object



49
50
51
# File 'lib/author_engine/collision_detection/collision_detection.rb', line 49

def sprite_vs_sprite(sprite_index, sprite_x, sprite_y, target_sprite_index, target_x, target_y)
  bounding_boxes_intersect?(box(sprite_index), sprite_x, sprite_y, box(target_sprite_index), target_x, target_y)
end