Class: RPG::Sprite

Inherits:
Sprite show all
Defined in:
lib/rpg/sprite.rb

Constant Summary collapse

@@_animations =
[]
@@_reference_count =
{}

Instance Attribute Summary

Attributes inherited from Sprite

#angle, #bitmap, #blend_type, #bush_depth, #color, #mirror, #opacity, #ox, #oy, #src_rect, #tone, #viewport, #visible, #x, #y, #z, #zoom_x, #zoom_y

Instance Method Summary collapse

Methods inherited from Sprite

#disposed?, #flash

Constructor Details

#initialize(viewport = nil) ⇒ Sprite


9
10
11
12
13
14
15
16
17
18
# File 'lib/rpg/sprite.rb', line 9

def initialize(viewport = nil)
  super(viewport)
  @_whiten_duration = 0
  @_appear_duration = 0
  @_escape_duration = 0
  @_collapse_duration = 0
  @_damage_duration = 0
  @_animation_duration = 0
  @_blink = false
end

Instance Method Details

#animation(animation, hit) ⇒ Object

Plays the animation specified in animation (Animation) on the indicated sprite.

If hit is TRUE, then it will be handled as a hit; if FALSE, as a miss. This is used as a condition in [SE and Flash Timing].

The animation sprite is displayed at a Z-coordinate of 2000.

If the animation has multiple targets, simply call this method for each sprite. The class will automatically make all decisions internally, thus avoiding any overlapping of animations whose positions are set to [Screen].

The animation graphic(s) to be displayed are retrieved from the Cache module and, to save memory, are freed as soon as the animation is done playing. Therefore, the class uses an internal reference count. Usually there is no need to be conscious of this fact, but care must be taken when using an Cache module animation graphic in an external context.

If animation is set to nil, the animation will stop.


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/rpg/sprite.rb', line 148

def animation(animation, hit)
  dispose_animation
  @_animation = animation
  return if @_animation == nil
  @_animation_hit = hit
  @_animation_duration = @_animation.frame_max
  animation_name = @_animation.animation_name
  animation_hue = @_animation.animation_hue
  bitmap = RPG::Cache.animation(animation_name, animation_hue)
  if @@_reference_count.include?(bitmap)
    @@_reference_count[bitmap] += 1
  else
    @@_reference_count[bitmap] = 1
  end
  @_animation_sprites = []
  if @_animation.position != 3 or not @@_animations.include?(animation)
    for i in 0..15
      sprite = ::Sprite.new(self.viewport)
      sprite.bitmap = bitmap
      sprite.visible = false
      @_animation_sprites.push(sprite)
    end
    unless @@_animations.include?(animation)
      @@_animations.push(animation)
    end
  end
  update_animation
end

#animation_process_timing(timing, hit) ⇒ Object


413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/rpg/sprite.rb', line 413

def animation_process_timing(timing, hit)
  if (timing.condition == 0) or
     (timing.condition == 1 and hit == true) or
     (timing.condition == 2 and hit == false)
    if timing.se.name != ""
      se = timing.se
      Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch)
    end
    case timing.flash_scope
    when 1
      self.flash(timing.flash_color, timing.flash_duration * 2)
    when 2
      if self.viewport != nil
        self.viewport.flash(timing.flash_color, timing.flash_duration * 2)
      end
    when 3
      self.flash(nil, timing.flash_duration * 2)
    end
  end
end

#animation_set_sprites(sprites, cell_data, position) ⇒ Object


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# File 'lib/rpg/sprite.rb', line 375

def animation_set_sprites(sprites, cell_data, position)
  for i in 0..15
    sprite = sprites[i]
    pattern = cell_data[i, 0]
    if sprite == nil or pattern == nil or pattern == -1
      sprite.visible = false if sprite != nil
      next
    end
    sprite.visible = true
    sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
    if position == 3
      if self.viewport != nil
        sprite.x = self.viewport.rect.width / 2
        sprite.y = self.viewport.rect.height - 160
      else
        sprite.x = 320
        sprite.y = 240
      end
    else
      sprite.x = self.x - self.ox + self.src_rect.width / 2
      sprite.y = self.y - self.oy + self.src_rect.height / 2
      sprite.y -= self.src_rect.height / 4 if position == 0
      sprite.y += self.src_rect.height / 4 if position == 2
    end
    sprite.x += cell_data[i, 1]
    sprite.y += cell_data[i, 2]
    sprite.z = 2000
    sprite.ox = 96
    sprite.oy = 96
    sprite.zoom_x = cell_data[i, 3] / 100.0
    sprite.zoom_y = cell_data[i, 3] / 100.0
    sprite.angle = cell_data[i, 4]
    sprite.mirror = (cell_data[i, 5] == 1)
    sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
    sprite.blend_type = cell_data[i, 7]
  end
end

#appearObject

Smoothly transitions a sprite from transparent to opaque. Used when a character is revived and when an enemy appears.


39
40
41
42
43
44
45
46
47
# File 'lib/rpg/sprite.rb', line 39

def appear
  self.blend_type = 0
  self.color.set(0, 0, 0, 0)
  self.opacity = 0
  @_appear_duration = 16
  @_whiten_duration = 0
  @_escape_duration = 0
  @_collapse_duration = 0
end

#blink?Boolean

Returns TRUE when the blink effect is on.


273
274
275
# File 'lib/rpg/sprite.rb', line 273

def blink?
  @_blink
end

Turns the blink effect off.


265
266
267
268
269
270
# File 'lib/rpg/sprite.rb', line 265

def blink_off
  if @_blink
    @_blink = false
    self.color.set(0, 0, 0, 0)
  end
end

Turns the blink effect on. Makes a sprite glow white, then repeats the effect at set intervals. Used on an actor while entering commands.


257
258
259
260
261
262
# File 'lib/rpg/sprite.rb', line 257

def blink_on
  unless @_blink
    @_blink = true
    @_blink_count = 0
  end
end

#collapseObject

Blends red with a sprite's color information and smoothly transitions it to transparent. Used when HP reaches 0 and the character collapses.


64
65
66
67
68
69
70
71
72
# File 'lib/rpg/sprite.rb', line 64

def collapse
  self.blend_type = 1
  self.color.set(255, 64, 64, 255)
  self.opacity = 255
  @_collapse_duration = 48
  @_whiten_duration = 0
  @_appear_duration = 0
  @_escape_duration = 0
end

#damage(value, critical) ⇒ Object

Displays the amount of damage or the word “Miss!”in a pop-up in front of the sprite.

If value is a positive number, the amount of normal damage will be displayed in white. If it is a negative number, the amount of recovery will be displayed in green with no negative sign. If value is text, it will be displayed in white, as is.

If critical is set to TRUE, the word “CRITICAL” will be displayed above the damage amount.

The damage sprite is displayed at a Z-coordinate of 3000.


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
119
120
121
122
123
124
125
# File 'lib/rpg/sprite.rb', line 86

def damage(value, critical)
  dispose_damage
  if value.is_a?(Numeric)
    damage_string = value.abs.to_s
  else
    damage_string = value.to_s
  end
  bitmap = Bitmap.new(160, 48)
  bitmap.font.name = "Arial Black"
  bitmap.font.size = 32
  bitmap.font.color.set(0, 0, 0)
  bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1)
  bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1)
  bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1)
  bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1)
  if value.is_a?(Numeric) and value < 0
    bitmap.font.color.set(176, 255, 144)
  else
    bitmap.font.color.set(255, 255, 255)
  end
  bitmap.draw_text(0, 12, 160, 36, damage_string, 1)
  if critical
    bitmap.font.size = 20
    bitmap.font.color.set(0, 0, 0)
    bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1)
    bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1)
    bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1)
    bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1)
    bitmap.font.color.set(255, 255, 255)
    bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1)
  end
  @_damage_sprite = ::Sprite.new(self.viewport)
  @_damage_sprite.bitmap = bitmap
  @_damage_sprite.ox = 80
  @_damage_sprite.oy = 20
  @_damage_sprite.x = self.x
  @_damage_sprite.y = self.y - self.oy / 2
  @_damage_sprite.z = 3000
  @_damage_duration = 40
end

#disposeObject


19
20
21
22
23
24
# File 'lib/rpg/sprite.rb', line 19

def dispose
  dispose_damage
  dispose_animation
  dispose_loop_animation
  super
end

#dispose_animationObject


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/rpg/sprite.rb', line 220

def dispose_animation
  if @_animation_sprites != nil
    sprite = @_animation_sprites[0]
    if sprite != nil
      @@_reference_count[sprite.bitmap] -= 1
      if @@_reference_count[sprite.bitmap] == 0
        sprite.bitmap.dispose
      end
    end
    for sprite in @_animation_sprites
      sprite.dispose
    end
    @_animation_sprites = nil
    @_animation = nil
  end
end

#dispose_damageObject


211
212
213
214
215
216
217
218
# File 'lib/rpg/sprite.rb', line 211

def dispose_damage
  if @_damage_sprite != nil
    @_damage_sprite.bitmap.dispose
    @_damage_sprite.dispose
    @_damage_sprite = nil
    @_damage_duration = 0
  end
end

#dispose_loop_animationObject


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/rpg/sprite.rb', line 237

def dispose_loop_animation
  if @_loop_animation_sprites != nil
    sprite = @_loop_animation_sprites[0]
    if sprite != nil
      @@_reference_count[sprite.bitmap] -= 1
      if @@_reference_count[sprite.bitmap] == 0
        sprite.bitmap.dispose
      end
    end
    for sprite in @_loop_animation_sprites
      sprite.dispose
    end
    @_loop_animation_sprites = nil
    @_loop_animation = nil
  end
end

#effect?Boolean

Returns TRUE when whiten, appear, escape, collapse, damage, or animation is on.

Neither loop_animation nor blink have any effect,


281
282
283
284
285
286
287
288
# File 'lib/rpg/sprite.rb', line 281

def effect?
  @_whiten_duration > 0 or
  @_appear_duration > 0 or
  @_escape_duration > 0 or
  @_collapse_duration > 0 or
  @_damage_duration > 0 or
  @_animation_duration > 0
end

#escapeObject

Smoothly transitions a sprite from opaque to transparent. Used when an enemy runs away.


51
52
53
54
55
56
57
58
59
# File 'lib/rpg/sprite.rb', line 51

def escape
  self.blend_type = 0
  self.color.set(0, 0, 0, 0)
  self.opacity = 255
  @_escape_duration = 32
  @_whiten_duration = 0
  @_appear_duration = 0
  @_collapse_duration = 0
end

#loop_animation(animation) ⇒ Object

Plays the animation specified in animation (Animation) in a loop on the indicated sprite.

Unlike normal animations, will loop back to the first frame after reaching the last frame, with no pause. Can be displayed at the same time as a normal animation. This method is used to display the animation specified in the status class (RPG::State).

If animation is set to nil, the animation will stop.


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/rpg/sprite.rb', line 186

def loop_animation(animation)
  return if animation == @_loop_animation
  dispose_loop_animation
  @_loop_animation = animation
  return if @_loop_animation == nil
  @_loop_animation_index = 0
  animation_name = @_loop_animation.animation_name
  animation_hue = @_loop_animation.animation_hue
  bitmap = RPG::Cache.animation(animation_name, animation_hue)
  if @@_reference_count.include?(bitmap)
    @@_reference_count[bitmap] += 1
  else
    @@_reference_count[bitmap] = 1
  end
  @_loop_animation_sprites = []
  for i in 0..15
    sprite = ::Sprite.new(self.viewport)
    sprite.bitmap = bitmap
    sprite.visible = false
    @_loop_animation_sprites.push(sprite)
  end
  update_loop_animation
end

#updateObject

Refreshes each effect. As a rule, this method is called once per frame.


291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/rpg/sprite.rb', line 291

def update
  super
  if @_whiten_duration > 0
    @_whiten_duration -= 1
    self.color.alpha = 128 - (16 - @_whiten_duration) * 10
  end
  if @_appear_duration > 0
    @_appear_duration -= 1
    self.opacity = (16 - @_appear_duration) * 16
  end
  if @_escape_duration > 0
    @_escape_duration -= 1
    self.opacity = 256 - (32 - @_escape_duration) * 10
  end
  if @_collapse_duration > 0
    @_collapse_duration -= 1
    self.opacity = 256 - (48 - @_collapse_duration) * 6
  end
  if @_damage_duration > 0
    @_damage_duration -= 1
    case @_damage_duration
    when 38..39
      @_damage_sprite.y -= 4
    when 36..37
      @_damage_sprite.y -= 2
    when 34..35
      @_damage_sprite.y += 2
    when 28..33
      @_damage_sprite.y += 4
    end
    @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32
    if @_damage_duration == 0
      dispose_damage
    end
  end
  if @_animation != nil and (Graphics.frame_count % 2 == 0)
    @_animation_duration -= 1
    update_animation
  end
  if @_loop_animation != nil and (Graphics.frame_count % 2 == 0)
    update_loop_animation
    @_loop_animation_index += 1
    @_loop_animation_index %= @_loop_animation.frame_max
  end
  if @_blink
    @_blink_count = (@_blink_count + 1) % 32
    if @_blink_count < 16
      alpha = (16 - @_blink_count) * 6
    else
      alpha = (@_blink_count - 16) * 6
    end
    self.color.set(255, 255, 255, alpha)
  end
  @@_animations.clear
end

#update_animationObject


347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/rpg/sprite.rb', line 347

def update_animation
  if @_animation_duration > 0
    frame_index = @_animation.frame_max - @_animation_duration
    cell_data = @_animation.frames[frame_index].cell_data
    position = @_animation.position
    animation_set_sprites(@_animation_sprites, cell_data, position)
    for timing in @_animation.timings
      if timing.frame == frame_index
        animation_process_timing(timing, @_animation_hit)
      end
    end
  else
    dispose_animation
  end
end

#update_loop_animationObject


363
364
365
366
367
368
369
370
371
372
373
# File 'lib/rpg/sprite.rb', line 363

def update_loop_animation
  frame_index = @_loop_animation_index
  cell_data = @_loop_animation.frames[frame_index].cell_data
  position = @_loop_animation.position
  animation_set_sprites(@_loop_animation_sprites, cell_data, position)
  for timing in @_loop_animation.timings
    if timing.frame == frame_index
      animation_process_timing(timing, true)
    end
  end
end

#whitenObject

Makes sprite white for a weak flash effect. Used when a battler is moving.


27
28
29
30
31
32
33
34
35
# File 'lib/rpg/sprite.rb', line 27

def whiten
  self.blend_type = 0
  self.color.set(255, 255, 255, 128)
  self.opacity = 255
  @_whiten_duration = 16
  @_appear_duration = 0
  @_escape_duration = 0
  @_collapse_duration = 0
end

#x=(x) ⇒ Object


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/rpg/sprite.rb', line 434

def x=(x)
  sx = x - self.x
  if sx != 0
    if @_animation_sprites != nil
      for i in 0..15
        @_animation_sprites[i].x += sx
      end
    end
    if @_loop_animation_sprites != nil
      for i in 0..15
        @_loop_animation_sprites[i].x += sx
      end
    end
  end
  super
end

#y=(y) ⇒ Object


451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# File 'lib/rpg/sprite.rb', line 451

def y=(y)
  sy = y - self.y
  if sy != 0
    if @_animation_sprites != nil
      for i in 0..15
        @_animation_sprites[i].y += sy
      end
    end
    if @_loop_animation_sprites != nil
      for i in 0..15
        @_loop_animation_sprites[i].y += sy
      end
    end
  end
  super
end