Class: Doom::Game::Intermission

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/game/intermission.rb

Overview

Intermission screen shown between levels. Displays kill%, item%, secret%, time, and par time.

Constant Summary collapse

PAR_TIMES =

Episode 1 par times in seconds (from Chocolate Doom)

{
  'E1M1' => 30, 'E1M2' => 75, 'E1M3' => 120, 'E1M4' => 90,
  'E1M5' => 165, 'E1M6' => 180, 'E1M7' => 180, 'E1M8' => 30, 'E1M9' => 165,
}.freeze
NEXT_MAP =

Next map progression

{
  'E1M1' => 'E1M2', 'E1M2' => 'E1M3', 'E1M3' => 'E1M4', 'E1M4' => 'E1M5',
  'E1M5' => 'E1M6', 'E1M6' => 'E1M7', 'E1M7' => 'E1M8', 'E1M8' => nil,
  'E1M9' => 'E1M4',
}.freeze
COUNT_SPEED =

Counter animation speed (percentage points per tic)

2
TICS_PER_COUNT =
1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wad, hud_graphics, stats) ⇒ Intermission

Returns a new instance of Intermission.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/doom/game/intermission.rb', line 27

def initialize(wad, hud_graphics, stats)
  @wad = wad
  @gfx = hud_graphics
  @stats = stats  # { map:, kills:, total_kills:, items:, total_items:, secrets:, total_secrets:, time_tics: }
  @finished = false
  @next_map = NEXT_MAP[stats[:map]]
  @tic = 0

  # Animated counters (count up from 0 to actual value)
  @kill_count = 0
  @item_count = 0
  @secret_count = 0
  @time_count = 0
  @counting_done = false

  # Target percentages
  @kill_pct = @stats[:total_kills] > 0 ? (@stats[:kills] * 100 / @stats[:total_kills]) : 100
  @item_pct = @stats[:total_items] > 0 ? (@stats[:items] * 100 / @stats[:total_items]) : 100
  @secret_pct = @stats[:total_secrets] > 0 ? (@stats[:secrets] * 100 / @stats[:total_secrets]) : 100
  @time_secs = @stats[:time_tics] / 35

  @par_time = PAR_TIMES[stats[:map]] || 0

  load_graphics
end

Instance Attribute Details

#finishedObject (readonly)

Returns the value of attribute finished.



25
26
27
# File 'lib/doom/game/intermission.rb', line 25

def finished
  @finished
end

#next_mapObject (readonly)

Returns the value of attribute next_map.



25
26
27
# File 'lib/doom/game/intermission.rb', line 25

def next_map
  @next_map
end

Instance Method Details

#handle_keyObject



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/doom/game/intermission.rb', line 120

def handle_key
  if @counting_done
    @finished = true
  else
    # Skip counting animation
    @kill_count = @kill_pct
    @item_count = @item_pct
    @secret_count = @secret_pct
    @time_count = @time_secs
    @counting_done = true
  end
end

#render(framebuffer) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
# File 'lib/doom/game/intermission.rb', line 71

def render(framebuffer)
  # Background
  draw_background(framebuffer)

  # "Finished" text + level name
  draw_sprite(framebuffer, @wifinish, 64, 4) if @wifinish
  level_idx = map_to_level_index(@stats[:map])
  lv = @level_names[level_idx]
  draw_sprite(framebuffer, lv, (320 - (lv&.width || 0)) / 2, 24) if lv

  # Kill, Item, Secret percentages
  y = 60
  draw_sprite(framebuffer, @wiostk, 50, y) if @wiostk
  draw_percent(framebuffer, 260, y, @kill_count)

  y += 24
  draw_sprite(framebuffer, @wiosti, 50, y) if @wiosti
  draw_percent(framebuffer, 260, y, @item_count)

  y += 24
  draw_sprite(framebuffer, @wiosts, 50, y) if @wiosts
  draw_percent(framebuffer, 260, y, @secret_count)

  # Time
  y += 30
  draw_sprite(framebuffer, @witime, 16, y) if @witime
  draw_time(framebuffer, 160, y, @time_count)

  # Par time
  draw_sprite(framebuffer, @wipar, 176, y) if @wipar
  draw_time(framebuffer, 292, y, @par_time)

  # "Entering" next level (after counting done)
  if @counting_done && @next_map
    y += 30
    draw_sprite(framebuffer, @wienter, 64, y) if @wienter
    next_idx = map_to_level_index(@next_map)
    nlv = @level_names[next_idx]
    draw_sprite(framebuffer, nlv, (320 - (nlv&.width || 0)) / 2, y + 18) if nlv
  end

  # "Press any key" hint after counting
  if @counting_done && (@tic / 17) % 2 == 0
    # Blink hint via skull
    skull = @skulls[@tic / 8 % 2]
    draw_sprite(framebuffer, skull, 144, 210) if skull
  end
end

#updateObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/doom/game/intermission.rb', line 53

def update
  @tic += 1
  return if @counting_done

  # Animate counters
  if @kill_count < @kill_pct
    @kill_count = [@kill_count + COUNT_SPEED, @kill_pct].min
  elsif @item_count < @item_pct
    @item_count = [@item_count + COUNT_SPEED, @item_pct].min
  elsif @secret_count < @secret_pct
    @secret_count = [@secret_count + COUNT_SPEED, @secret_pct].min
  elsif @time_count < @time_secs
    @time_count = [@time_count + 3, @time_secs].min
  else
    @counting_done = true
  end
end