Class: Entity::Block

Inherits:
OwnedEntity show all
Defined in:
lib/game_2d/entity/block.rb

Constant Summary collapse

MAX_LEVEL =
5
HP_PER_LEVEL =
5
MAX_HP =
MAX_LEVEL * HP_PER_LEVEL

Constants included from EntityConstants

EntityConstants::CELL_WIDTH_IN_PIXELS, EntityConstants::MAX_VELOCITY, EntityConstants::PIXEL_WIDTH, EntityConstants::WIDTH

Instance Attribute Summary collapse

Attributes inherited from OwnedEntity

#owner_id

Attributes inherited from Entity

#a, #moving, #space, #x, #x_vel, #y, #y_vel

Instance Method Summary collapse

Methods inherited from OwnedEntity

#owner, #owner=

Methods inherited from Entity

#above, #accelerate, #angle_to_vector, #beneath, #bottom_cell_y, #cx, #cy, #direction, #direction_to, #doomed?, #draw, #draw_angle, #draw_animation, #draw_image, #draw_zorder, #drop_diagonal, #empty_above?, #empty_on_left?, #empty_on_right?, #empty_underneath?, #entities_obstructing, #going_past_entity, #grab!, #grabbed?, #i_hit, #initialize, #left_cell_x, #move, #move_x, #move_y, #moving?, #next_to, #occupied_cells, #on_left, #on_right, #opaque, #pixel_x, #pixel_y, #release!, #right_cell_x, #sleep_now?, #slide_around, #slow_by, #slower_speed, #teleportable?, #top_cell_y, #underfoot, #vector_to_angle, #wake!, #warp

Methods included from ClassMethods

#bottom_cell_y_at, #constrain_velocity, #left_cell_x_at, #right_cell_x_at, #top_cell_y_at

Methods included from Transparency

#transparent?

Methods included from Registerable

#nullsafe_registry_id, #registry_id, #registry_id=, #registry_id?, #registry_id_safe

Methods included from Serializable

#<=>, #==, as_json, #eql?, from_json, #hash, #to_json

Constructor Details

This class inherits a constructor from Entity

Instance Attribute Details

#hpObject

Returns the value of attribute hp.



10
11
12
# File 'lib/game_2d/entity/block.rb', line 10

def hp
  @hp
end

Instance Method Details

#all_stateObject



14
# File 'lib/game_2d/entity/block.rb', line 14

def all_state; super.push(hp); end

#as_jsonObject



15
# File 'lib/game_2d/entity/block.rb', line 15

def as_json; super.merge!(:hp => hp); end

#destroy!Object



123
124
125
# File 'lib/game_2d/entity/block.rb', line 123

def destroy!
  owner.disown_block if owner
end

#harmed_by(other, damage = 1) ⇒ Object



118
119
120
121
# File 'lib/game_2d/entity/block.rb', line 118

def harmed_by(other, damage=1)
  self.hp -= damage
  @space.doom(self) if hp <= 0
end

#image_filenameObject



133
# File 'lib/game_2d/entity/block.rb', line 133

def image_filename; "#{level_name}.gif"; end

#levelObject



127
# File 'lib/game_2d/entity/block.rb', line 127

def level; (hp - 1) / HP_PER_LEVEL; end

#level_nameObject



129
130
131
# File 'lib/game_2d/entity/block.rb', line 129

def level_name
  %w(dirt brick cement steel unlikelium)[level]
end

#look_ahead_for_supportObject

Find the highest (if dropping) or lowest (if rising) height that meets the requirements for support



88
89
90
91
92
# File 'lib/game_2d/entity/block.rb', line 88

def look_ahead_for_support
  support_heights = yield *possible_sources_of_support

  (y_vel > 0) ? support_heights.min : support_heights.max
end

#look_ahead_for_support_both_sidesObject

Need a source of support at the exact same height on both sides



72
73
74
75
76
# File 'lib/game_2d/entity/block.rb', line 72

def look_ahead_for_support_both_sides
  look_ahead_for_support do |left, right|
    left & right
  end
end

#look_ahead_for_support_either_sideObject

Any source of support will do, either side or both



80
81
82
83
84
# File 'lib/game_2d/entity/block.rb', line 80

def look_ahead_for_support_either_side
  look_ahead_for_support do |left, right|
    left + right
  end
end

#possible_sources_of_supportObject

Sources of support must intersect with the points next to us, and be:

  • Level with our lower edge, if dropping

  • A point above our upper edge, if rising

  • Close enough that our current velocity will

take us past that point during this tick

This just returns the heights at which we might find support



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/game_2d/entity/block.rb', line 102

def possible_sources_of_support
  target_height = if y_vel > 0 # dropping
    y + HEIGHT - 1
  else # rising
    y - 1
  end

  left_support = opaque(space.entities_at_point(x - 1, target_height)).collect(&:y)
  right_support = opaque(space.entities_at_point(x + WIDTH, target_height)).collect(&:y)

  # Filter out heights we aren't going to reach this tick with
  # our current velocity
  not_too_far = lambda {|its_y| (its_y - y).abs <= y_vel.abs }
  [left_support.find_all(&not_too_far), right_support.find_all(&not_too_far)]
end

#should_fall?Boolean

Returns:

  • (Boolean)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/game_2d/entity/block.rb', line 22

def should_fall?
  return false if owner || !empty_underneath?

  case level
    when 0
      true
    when 1
      !(supported_on_left && supported_on_right)
    when 2
      !(supported_on_left || supported_on_right)
    when 3
      empty_on_left? && empty_on_right? && empty_above?
    when 4
      false
  end
end

#supported_on_leftObject



39
40
41
# File 'lib/game_2d/entity/block.rb', line 39

def supported_on_left
  opaque(space.entities_exactly_at_point(x - WIDTH, y)).any?
end

#supported_on_rightObject



43
44
45
# File 'lib/game_2d/entity/block.rb', line 43

def supported_on_right
  right_support = opaque(space.entities_exactly_at_point(x + WIDTH, y)).any?
end

#to_sObject



135
# File 'lib/game_2d/entity/block.rb', line 135

def to_s; "#{super} (#{@hp} HP)"; end

#updateObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/game_2d/entity/block.rb', line 47

def update
  if should_fall?
    # applies acceleration, but that's all
    space.fall(self)
  else
    self.x_vel = self.y_vel = 0
  end
  # Reduce velocity if necessary, to exactly line up with
  # an upcoming source of support (so we don't move past it)
  if x_vel == 0 && y_vel != 0
    case level
      when 1
        new_y = look_ahead_for_support_both_sides
        self.y_vel = new_y - y if new_y
      when 2
        new_y = look_ahead_for_support_either_side
        self.y_vel = new_y - y if new_y
    end
  end

  move
end

#update_from_json(json) ⇒ Object



17
18
19
20
# File 'lib/game_2d/entity/block.rb', line 17

def update_from_json(json)
  self.hp = json[:hp] if json[:hp]
  super
end