Class: Doom::Wad::SpriteManager

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/wad/sprite.rb

Constant Summary collapse

THING_SPRITES =

Map thing types to sprite prefixes

{
  # Ammo
  2007 => 'CLIP', # Clip
  2048 => 'AMMO', # Box of ammo
  2008 => 'SHEL', # Shells
  2049 => 'SBOX', # Box of shells
  2010 => 'ROCK', # Rocket
  2046 => 'BROK', # Box of rockets
  2047 => 'CELL', # Cell charge
  17 => 'CELP',   # Cell pack

  # Weapons
  2001 => 'SHOT', # Shotgun
  2002 => 'MGUN', # Chaingun
  2003 => 'LAUN', # Rocket launcher
  2004 => 'PLAS', # Plasma rifle
  2006 => 'BFUG', # BFG 9000
  2005 => 'CSAW', # Chainsaw

  # Health/Armor
  2011 => 'STIM', # Stimpack
  2012 => 'MEDI', # Medikit
  2014 => 'BON1', # Health bonus
  2015 => 'BON2', # Armor bonus
  2018 => 'ARM1', # Green armor
  2019 => 'ARM2', # Blue armor

  # Keys
  5 => 'BKEY',    # Blue keycard
  6 => 'YKEY',    # Yellow keycard
  13 => 'RKEY',   # Red keycard
  40 => 'BSKU',   # Blue skull
  39 => 'YSKU',   # Yellow skull
  38 => 'RSKU',   # Red skull

  # Decorations
  2028 => 'COLU', # Light column
  30 => 'COL1',   # Tall green pillar
  31 => 'COL2',   # Short green pillar
  32 => 'COL3',   # Tall red pillar
  33 => 'COL4',   # Short red pillar
  34 => 'CAND',   # Candle
  44 => 'TBLU',   # Tall blue torch
  45 => 'TGRN',   # Tall green torch
  46 => 'TRED',   # Tall red torch
  48 => 'ELEC',   # Tall tech column
  35 => 'CBRA',   # Candelabra

  # Barrels
  2035 => 'BAR1', # Exploding barrel

  # Monsters
  3004 => 'POSS', # Zombieman
  9 => 'SPOS',    # Shotgun guy
  3001 => 'TROO', # Imp
  3002 => 'SARG', # Demon
  58 => 'SARG',   # Spectre (same as Demon)
  3003 => 'BOSS', # Baron of Hell
  3005 => 'HEAD', # Cacodemon
  3006 => 'SKUL', # Lost soul
  7 => 'SPID',    # Spider Mastermind
  16 => 'CYBR',   # Cyberdemon
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(wad) ⇒ SpriteManager

Returns a new instance of SpriteManager.



139
140
141
142
143
# File 'lib/doom/wad/sprite.rb', line 139

def initialize(wad)
  @wad = wad
  @cache = {}
  @rotation_cache = {}
end

Instance Method Details

#[](thing_type) ⇒ Object

Get default sprite (rotation 0 or 1)



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/doom/wad/sprite.rb', line 146

def [](thing_type)
  return @cache[thing_type] if @cache.key?(thing_type)

  prefix = THING_SPRITES[thing_type]
  return nil unless prefix

  # Try to find sprite with A0 (all angles) or A1 (front facing)
  sprite = Sprite.load(@wad, "#{prefix}A0") ||
           Sprite.load(@wad, "#{prefix}A1")

  @cache[thing_type] = sprite
  sprite
end

#get_rotated(thing_type, viewer_angle, thing_angle) ⇒ Object

Get sprite for specific rotation (1-8, or 0 for all angles) viewer_angle: angle from viewer to sprite in radians thing_angle: thing’s facing angle in degrees



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/doom/wad/sprite.rb', line 168

def get_rotated(thing_type, viewer_angle, thing_angle)
  prefix = THING_SPRITES[thing_type]
  return nil unless prefix

  # Check cache for rotation 0 (all angles) sprite
  cache_key = "#{prefix}A0"
  if @rotation_cache.key?(cache_key)
    return @rotation_cache[cache_key] if @rotation_cache[cache_key]
  else
    sprite = Sprite.load(@wad, cache_key)
    @rotation_cache[cache_key] = sprite
    return sprite if sprite
  end

  # Calculate rotation frame (1-8)
  # Doom rotations: 1=front, 2=front-right, 3=right, etc. (clockwise)
  # The angle we need is: viewer's angle to sprite - sprite's facing angle
  angle_diff = viewer_angle - (thing_angle * Math::PI / 180.0)

  # Normalize to 0-2π
  angle_diff = angle_diff % (2 * Math::PI)
  angle_diff += 2 * Math::PI if angle_diff < 0

  # Convert to rotation frame (1-8)
  # Each rotation covers 45 degrees (π/4 radians)
  # Add π/8 to center the ranges
  rotation = ((angle_diff + Math::PI / 8) / (Math::PI / 4)).to_i % 8 + 1

  cache_key = "#{prefix}A#{rotation}"
  unless @rotation_cache.key?(cache_key)
    @rotation_cache[cache_key] = Sprite.load(@wad, cache_key)
  end

  @rotation_cache[cache_key] || @cache[thing_type]
end

#prefix_for(thing_type) ⇒ Object

Get sprite prefix for a thing type



161
162
163
# File 'lib/doom/wad/sprite.rb', line 161

def prefix_for(thing_type)
  THING_SPRITES[thing_type]
end