Class: Termfront::Enemy::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/termfront/enemy/base.rb

Direct Known Subclasses

Crawler, Executor

Constant Summary collapse

DIFFICULTIES =
[
  { name: "Easy",      hp_mult: 1, cooldown_mult: 1.5, extra_enemies: 0 },
  { name: "Normal",    hp_mult: 2, cooldown_mult: 1.0, extra_enemies: 1 },
  { name: "Hard",      hp_mult: 3, cooldown_mult: 0.7, extra_enemies: 3 },
  { name: "Very Hard", hp_mult: 4, cooldown_mult: 0.5, extra_enemies: 5 }
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x:, y:, wp_a:, wp_b:, hp:) ⇒ Base

Returns a new instance of Base.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/termfront/enemy/base.rb', line 15

def initialize(x:, y:, wp_a:, wp_b:, hp:)
  @x = x
  @y = y
  @wp_a = wp_a
  @wp_b = wp_b
  @wp_t = 0.0
  @wp_dir = 1
  @last_fire = 0.0
  @alive = true
  @hp = hp
  @max_hp = hp
end

Instance Attribute Details

#aliveObject

Returns the value of attribute alive.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def alive
  @alive
end

#hpObject

Returns the value of attribute hp.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def hp
  @hp
end

#last_fireObject

Returns the value of attribute last_fire.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def last_fire
  @last_fire
end

#max_hpObject

Returns the value of attribute max_hp.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def max_hp
  @max_hp
end

#wp_aObject

Returns the value of attribute wp_a.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def wp_a
  @wp_a
end

#wp_bObject

Returns the value of attribute wp_b.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def wp_b
  @wp_b
end

#wp_dirObject

Returns the value of attribute wp_dir.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def wp_dir
  @wp_dir
end

#wp_tObject

Returns the value of attribute wp_t.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def wp_t
  @wp_t
end

#xObject

Returns the value of attribute x.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def x
  @x
end

#yObject

Returns the value of attribute y.



6
7
8
# File 'lib/termfront/enemy/base.rb', line 6

def y
  @y
end

Class Method Details

.build(type, enemy_def, difficulty_index) ⇒ Object



95
96
97
98
99
100
# File 'lib/termfront/enemy/base.rb', line 95

def build(type, enemy_def, difficulty_index)
  klass = registry[type] || raise(ArgumentError, "Unknown enemy type: #{type}")
  sx, sy, ax, ay, _type = enemy_def
  hp = compute_hp(klass, difficulty_index)
  klass.new(x: sx, y: sy, wp_a: [sx, sy], wp_b: [ax, ay], hp: hp)
end

.generate_extras(base_list, count, difficulty_index) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/termfront/enemy/base.rb', line 102

def generate_extras(base_list, count, difficulty_index)
  return [] if count == 0 || base_list.empty?

  extras = []
  count.times do |i|
    src = base_list[i % base_list.size]
    sx, sy, ax, ay, type = src
    offset = 0.3 + (i * 0.2)
    klass = registry[type] || raise(ArgumentError, "Unknown enemy type: #{type}")
    hp = compute_hp(klass, difficulty_index)
    extras << klass.new(
      x: sx + offset, y: sy + offset,
      wp_a: [sx + offset, sy + offset],
      wp_b: [ax + offset, ay + offset],
      hp: hp
    )
  end
  extras
end

.register(type, klass) ⇒ Object



91
92
93
# File 'lib/termfront/enemy/base.rb', line 91

def register(type, klass)
  registry[type] = klass
end

.registryObject



87
88
89
# File 'lib/termfront/enemy/base.rb', line 87

def registry
  @registry ||= {}
end

Instance Method Details

#base_hpObject

Raises:

  • (NotImplementedError)


35
# File 'lib/termfront/enemy/base.rb', line 35

def base_hp   = raise(NotImplementedError)

#cooldownObject

Raises:

  • (NotImplementedError)


30
# File 'lib/termfront/enemy/base.rb', line 30

def cooldown  = raise(NotImplementedError)

#damageObject

Raises:

  • (NotImplementedError)


28
# File 'lib/termfront/enemy/base.rb', line 28

def damage    = raise(NotImplementedError)

#dead?Boolean

Returns:

  • (Boolean)


37
# File 'lib/termfront/enemy/base.rb', line 37

def dead? = !@alive

#drop_ammoObject

Raises:

  • (NotImplementedError)


33
# File 'lib/termfront/enemy/base.rb', line 33

def drop_ammo = raise(NotImplementedError)

#drop_typeObject

Raises:

  • (NotImplementedError)


32
# File 'lib/termfront/enemy/base.rb', line 32

def drop_type = raise(NotImplementedError)

#patrol(dt) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/termfront/enemy/base.rb', line 70

def patrol(dt)
  seg_len = Math.sqrt(
    (@wp_b[0] - @wp_a[0])**2 + (@wp_b[1] - @wp_a[1])**2 + 0.01
  )
  @wp_t += @wp_dir * speed * dt / seg_len
  if @wp_t >= 1.0
    @wp_t = 1.0
    @wp_dir = -1
  elsif @wp_t <= 0.0
    @wp_t = 0.0
    @wp_dir = 1
  end
  @x = @wp_a[0] + (@wp_b[0] - @wp_a[0]) * @wp_t
  @y = @wp_a[1] + (@wp_b[1] - @wp_a[1]) * @wp_t
end

#rangeObject

Raises:

  • (NotImplementedError)


29
# File 'lib/termfront/enemy/base.rb', line 29

def range     = raise(NotImplementedError)

#speedObject

Raises:

  • (NotImplementedError)


31
# File 'lib/termfront/enemy/base.rb', line 31

def speed     = raise(NotImplementedError)

#sprite_idObject

Raises:

  • (NotImplementedError)


34
# File 'lib/termfront/enemy/base.rb', line 34

def sprite_id = raise(NotImplementedError)

#take_damage(amount) ⇒ Object



39
40
41
42
43
44
# File 'lib/termfront/enemy/base.rb', line 39

def take_damage(amount)
  @hp -= amount
  return unless @hp <= 0

  @alive = false
end

#update(dt, player, projectiles, map, game_time, difficulty:) ⇒ Object



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

def update(dt, player, projectiles, map, game_time, difficulty:)
  return unless @alive

  patrol(dt)

  edx = player.x - @x
  edy = player.y - @y
  edist = Math.sqrt(edx * edx + edy * edy)
  cd = cooldown
  cd *= DIFFICULTIES[difficulty][:cooldown_mult] if difficulty
  return unless edist < range && (game_time - @last_fire) > cd
  return unless map.line_of_sight?(@x, @y, player.x, player.y)

  @last_fire = game_time
  ndx = edx / edist
  ndy = edy / edist
  projectiles << Projectile.new(
    x: @x, y: @y,
    vx: ndx * Config::PROJ_SPEED,
    vy: ndy * Config::PROJ_SPEED,
    type: sprite_id
  )
end