Class: TankPhysics

Inherits:
Component show all
Defined in:
lib/entities/components/tank_physics.rb

Instance Attribute Summary collapse

Attributes inherited from Component

#object

Instance Method Summary collapse

Methods inherited from Component

#draw

Constructor Details

#initialize(game_object, object_pool) ⇒ TankPhysics

Returns a new instance of TankPhysics.



4
5
6
7
8
9
# File 'lib/entities/components/tank_physics.rb', line 4

def initialize(game_object, object_pool)
  super(game_object)
  @object_pool = object_pool
  @map = object_pool.map
  @speed = 0.0
end

Instance Attribute Details

#collides_withObject

Returns the value of attribute collides_with.



2
3
4
# File 'lib/entities/components/tank_physics.rb', line 2

def collides_with
  @collides_with
end

#in_collisionObject

Returns the value of attribute in_collision.



2
3
4
# File 'lib/entities/components/tank_physics.rb', line 2

def in_collision
  @in_collision
end

#speedObject

Returns the value of attribute speed.



2
3
4
# File 'lib/entities/components/tank_physics.rb', line 2

def speed
  @speed
end

Instance Method Details

#boxObject

Tank box looks like H. Vertices: 1 2 5 6

 3   4

10   9

12 11 8 7



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/entities/components/tank_physics.rb', line 69

def box
  w = box_width / 2 - 1
  h = box_height / 2 - 1
  tw = 8 # track width
  fd = 8 # front depth
  rd = 6 # rear depth
  Utils.rotate(object.direction, x, y,
               x + w,      y + h,      #1
               x + w - tw, y + h,      #2
               x + w - tw, y + h - fd, #3

               x - w + tw, y + h - fd, #4
               x - w + tw, y + h,      #5
               x - w,      y + h,      #6

               x - w,      y - h,      #7
               x - w + tw, y - h,      #8
               x - w + tw, y - h + rd, #9

               x + w - tw, y - h + rd, #10
               x + w - tw, y - h,      #11
               x + w,      y - h,      #12
              )
end

#box_heightObject



55
56
57
# File 'lib/entities/components/tank_physics.rb', line 55

def box_height
  @box_height ||= object.graphics.height
end

#box_widthObject



59
60
61
# File 'lib/entities/components/tank_physics.rb', line 59

def box_width
  @box_width ||= object.graphics.width
end

#can_move_to?(x, y) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/entities/components/tank_physics.rb', line 11

def can_move_to?(x, y)
  old_x, old_y = object.x, object.y
  object.move(x, y)
  return false unless @map.can_move_to?(x, y)
  @object_pool.nearby(object, 100).each do |obj|
    next if obj.class == Bullet && obj.source == object
    if collides_with_poly?(obj.box)
      if obj.is_a? Powerup
        obj.on_collision(object)
      else
        @collides_with = obj
        # Allow to get unstuck
        old_distance = Utils.distance_between(
          obj.x, obj.y, old_x, old_y)
        new_distance = Utils.distance_between(
          obj.x, obj.y, x, y)
        return false if new_distance < old_distance
      end
    else
      @collides_with = nil
    end
  end
  true
ensure
  object.move(old_x, old_y)
end

#change_direction(new_direction) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/entities/components/tank_physics.rb', line 38

def change_direction(new_direction)
  change = (new_direction - object.direction + 360) % 360
  change = 360 - change if change > 180
  if change > 90
    @speed = 0
  elsif change > 45
    @speed *= 0.33
  elsif change > 0
    @speed *= 0.66
  end
  object.direction = new_direction % 360
end

#moving?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/entities/components/tank_physics.rb', line 51

def moving?
  @speed > 0
end

#updateObject



94
95
96
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
126
127
128
129
130
131
132
133
134
135
# File 'lib/entities/components/tank_physics.rb', line 94

def update
  if object.throttle_down && !object.health.dead?
    accelerate
  else
    decelerate
  end
  if @speed > 0
    new_x, new_y = x, y
    speed = apply_movement_penalty(@speed)
    shift = Utils.adjust_speed(speed) * object.speed_modifier
    case @object.direction.to_i
    when 0
      new_y -= shift
    when 45
      new_x += shift
      new_y -= shift
    when 90
      new_x += shift
    when 135
      new_x += shift
      new_y += shift
    when 180
      new_y += shift
    when 225
      new_y += shift
      new_x -= shift
    when 270
      new_x -= shift
    when 315
      new_x -= shift
      new_y -= shift
    end
    if can_move_to?(new_x, new_y)
      object.move(new_x, new_y)
      @in_collision = false
    else
      object.on_collision(@collides_with)
      @speed = 0.0
      @in_collision = true
    end
  end
end