Animacja nad obrazkiem. - Revlis - 15-06-18 22:03
W projekcie używam kilkunastu battlerów stworzonych ze zbitki różnego rodzaju obrazków, dzięki czemu przeciwnicy mogą w czasie atakowania poruszać kończynami czy wykonywać gesty itp. Problem polega na tym, że po zaatakowaniu takiego przeciwnika animacja ataku wyświetla się pod pokazanymi obrazkami, co mi nie przeszkadza bo wybredny nie jestem, ale dla innych wygląda po prostu brzydko. Tak więc - czy istnieje możliwość zmiany priorytetu wyświetlania tak, by animacje w czasie walki pokazywały się nad obrazkami? Szukałem na wielu forach i w różnych językach, ale najbliżej tego był skrypt na manualne wywołanie animacji komendą, co w zastosowaniu niesie ze sobą kilkaset typowych zdarzeń. Jeśli taka możliwość nie istnieje, alternatywnym rozwiązaniem byłoby wstrzymanie animacji w czasie walk z battlerami zbitymi z obrazków, gdyż sam brak animacji i tak wyglądałby lepiej niż animacja pojawiająca się pod nimi. Jeśli ktoś zna sposób/skrypt który pomógłby z jednym z wyżej wymienionych wariantów, byłbym bardzo wdzięczny.
RE: Animacja nad obrazkiem. - Yoroiookami - 15-06-18 22:35
Kod:
class Game_Interpreter
def anim_pic(pic_num, anim_id, mirror = false)
if $game_party.in_battle
pic = $game_troop.screen.pictures[pic_num]
else
pic = $game_map.screen.pictures[pic_num]
end
pic.anim_id = anim_id
pic.anim_mirror = mirror
end
end
class Game_Picture
attr_accessor :anim_id
attr_accessor :anim_mirror
alias theo_animpic_init initialize
def initialize(number)
theo_animpic_init(number)
@anim_id = 0
@anim_mirror = false
end
end
class Sprite_Picture
@@ani_checker = []
@@ani_spr_checker = []
@@_reference_count = {}
alias theo_animpic_init initialize
def initialize(viewport, picture)
@use_sprite = true
theo_animpic_init(viewport, picture)
end
alias theo_animpic_dispose dispose
def dispose
theo_animpic_dispose
dispose_animation
end
alias theo_animpic_update update
def update
theo_animpic_update
update_animation
@@ani_checker.clear
@@ani_spr_checker.clear
update_anim_flag
end
def update_anim_flag
if @picture.anim_id > 0
start_animation($data_animations[@picture.anim_id], @picture.anim_mirror)
@picture.anim_id = 0
end
end
def animation?
@animation != nil
end
def start_animation(animation, mirror = false)
dispose_animation
@animation = animation
if @animation
@ani_mirror = mirror
set_animation_rate
@ani_duration = @animation.frame_max * @ani_rate + 1
load_animation_bitmap
make_animation_sprites
set_animation_origin
end
end
def set_animation_rate
@ani_rate = 4 # Fixed value by default
@ani_rate = YEA::CORE::ANIMATION_RATE if $imported["YEA-CoreEngine"]
end
def load_animation_bitmap
animation1_name = @animation.animation1_name
animation1_hue = @animation.animation1_hue
animation2_name = @animation.animation2_name
animation2_hue = @animation.animation2_hue
@ani_bitmap1 = Cache.animation(animation1_name, animation1_hue)
@ani_bitmap2 = Cache.animation(animation2_name, animation2_hue)
if @@_reference_count.include?(@ani_bitmap1)
@@_reference_count[@ani_bitmap1] += 1
else
@@_reference_count[@ani_bitmap1] = 1
end
if @@_reference_count.include?(@ani_bitmap2)
@@_reference_count[@ani_bitmap2] += 1
else
@@_reference_count[@ani_bitmap2] = 1
end
Graphics.frame_reset
end
def make_animation_sprites
@ani_sprites = []
if @use_sprite && !@@ani_spr_checker.include?(@animation)
16.times do
sprite = ::Sprite.new(viewport)
sprite.visible = false
@ani_sprites.push(sprite)
end
if @animation.position == 3
@@ani_spr_checker.push(@animation)
end
end
@ani_duplicated = @@ani_checker.include?(@animation)
if !@ani_duplicated && @animation.position == 3
@@ani_checker.push(@animation)
end
end
def set_animation_origin
if @animation.position == 3
if viewport == nil
@ani_ox = Graphics.width / 2
@ani_oy = Graphics.height / 2
else
@ani_ox = viewport.rect.width / 2
@ani_oy = viewport.rect.height / 2
end
else
@ani_ox = x - ox + width / 2
@ani_oy = y - oy + height / 2
if @animation.position == 0
@ani_oy -= height / 2
elsif @animation.position == 2
@ani_oy += height / 2
end
end
end
def dispose_animation
if @ani_bitmap1
@@_reference_count[@ani_bitmap1] -= 1
if @@_reference_count[@ani_bitmap1] == 0
@ani_bitmap1.dispose
end
end
if @ani_bitmap2
@@_reference_count[@ani_bitmap2] -= 1
if @@_reference_count[@ani_bitmap2] == 0
@ani_bitmap2.dispose
end
end
if @ani_sprites
@ani_sprites.each {|sprite| sprite.dispose }
@ani_sprites = nil
@animation = nil
end
@ani_bitmap1 = nil
@ani_bitmap2 = nil
end
def update_animation
return unless animation?
@ani_duration -= 1
if @ani_duration % @ani_rate == 0
if @ani_duration > 0
frame_index = @animation.frame_max
frame_index -= (@ani_duration + @ani_rate - 1) / @ani_rate
animation_set_sprites(@animation.frames[frame_index])
@animation.timings.each do |timing|
animation_process_timing(timing) if timing.frame == frame_index
end
else
end_animation
end
end
end
def end_animation
dispose_animation
end
def animation_set_sprites(frame)
cell_data = frame.cell_data
@ani_sprites.each_with_index do |sprite, i|
next unless sprite
pattern = cell_data[i, 0]
if !pattern || pattern < 0
sprite.visible = false
next
end
sprite.bitmap = pattern < 100 ? @ani_bitmap1 : @ani_bitmap2
sprite.visible = true
sprite.src_rect.set(pattern % 5 * 192,
pattern % 100 / 5 * 192, 192, 192)
if @ani_mirror
sprite.x = @ani_ox - cell_data[i, 1]
sprite.y = @ani_oy + cell_data[i, 2]
sprite.angle = (360 - cell_data[i, 4])
sprite.mirror = (cell_data[i, 5] == 0)
else
sprite.x = @ani_ox + cell_data[i, 1]
sprite.y = @ani_oy + cell_data[i, 2]
sprite.angle = cell_data[i, 4]
sprite.mirror = (cell_data[i, 5] == 1)
end
sprite.z = self.z + 300 + i
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.opacity = cell_data[i, 6] * self.opacity / 255.0
sprite.blend_type = cell_data[i, 7]
end
end
def animation_process_timing(timing)
timing.se.play unless @ani_duplicated
case timing.flash_scope
when 1
self.flash(timing.flash_color, timing.flash_duration * @ani_rate)
when 2
if viewport && !@ani_duplicated
viewport.flash(timing.flash_color, timing.flash_duration * @ani_rate)
end
when 3
self.flash(nil, timing.flash_duration * @ani_rate)
end
end
end
Spróbuj wywołać w script call:
Kod:
anim_pic(picture_number, animation_id)
Tej panience pomogło, to może tobie też zadziała. 
https://www.rpgmakercentral.com/topic/27765-show-animation-over-pictures/
Albo możesz użyć skryptu który pokazuje obrazki pod bohaterami. Już kiedyś zresztą chyba ci coś znalazłem i mi działało?
RE: Animacja nad obrazkiem. - Revlis - 15-06-18 23:07
Testowałem już wtedy oba te skrypty. Pierwszy w istocie daje zamierzony efekt, ale do każdego ataku trzeba przyporządkować typowe zdarzenie dzielące się następnie na kilkanaście (a myśląc o przyszłości to nawet kilkadziesiąt) wariantów w zależności od napotkanego przeciwnika. To daje kilkaset kombinacji, więc szukam alternatyw (samo ustawianie zajęłoby wieki, a na razie nie mogę wymyślić innego sposobu). Problematyka tego skryptu polega na tym, że jest on przeznaczony do poszczególnych obrazków które ukazują się na mapie, a nie do setek animacji ataków podczas walk. A drugi skrypt nie działa podczas walki, więc niestety odpada z automatu.
RE: Animacja nad obrazkiem. - Ayene - 17-06-18 18:24
Wydaje mi się, że najlepiej by było nie używać polecenia picture w zdarzeniach walki, tylko skonfigurować animację poszczególnych przeciwników bezpośrednio w skryptach. Dzięki czemu nie występuje problem z tzw. "viewportem" i jego współrzędną z.
Może poniższe rozwiązanie Ci się przyda. Poszczególne animacje muszą być nazwane jak battler i dodane kolejno cyferki, np. battler nazywa się Slime, więc jego kolejne klatki będą Slime1, Slime2, Slime3, itd.
Następnie w konfiguracji na górze skryptu trzeba by było podać, że przeciwnik o id 1 (czyli slime), będzie miał np. 6 klatek animacji.
Nie wiem, czy korzystasz ze skryptu na sideview battle, jeśli tak to skrypt trzeba będzie przerobić, aby odnosił się do klasy Game_Enemy.
Kod:
class Sprite_Battler < Sprite_Base
ENEMY_FRAMES = { #id przeciwnika => liczba klatek animacji
1 => 6,
}
SZYBKOŚĆ_ANIMACJI = 32
#--------------------------------------------------------------------------
def initialize(viewport, battler = nil)
super(viewport)
@battler = battler
@battler_visible = false
@effect_type = nil
@effect_duration = 0
self.bitmap = Cache.battler(@battler.battler_name, @battler.battler_hue) if @battler
@duration = 0
@frame = 0
end
#--------------------------------------------------------------------------
def update_bitmap
@duration += 1
if @duration > SZYBKOŚĆ_ANIMACJI
@duration = 0
@frame = 1 if @frame >= ENEMY_FRAMES[@battler.enemy_id]
@frame += 1
new_bitmap = Cache.battler(@battler.battler_name + @frame.to_s, @battler.battler_hue)
if bitmap != new_bitmap
self.bitmap = new_bitmap
init_visibility
end
end
end
end
RE: Animacja nad obrazkiem. - Revlis - 17-06-18 23:15
Nie bardzo rozumiem (dla mnie w sekcji skrypty znaleźć można jedynie hieroglify i azteckie malunki). Przetestuję to w bólach, może prędzej czy później uda mi się to jakoś zastosować. Nie jestem tylko pewien czy akurat w tym przypadku dałoby radę przełożyć te animacje na klatki. Musiałbym mieć ogrom obrazków przypisany do każdego battlera, co wiązałoby się ze znacznym wzrostem wagi projektu. Obecnie używam jednej kopi każdego elementu battlera jako obrazek (które łącznie ważą tyle ile sam jeden-cały battler) i za pomocą komend (move/rotate) wprawiam je w ruch. Coś jak tutaj:
Znalazłem już jedno rozwiązanie dotyczące usunięcia animacji. Wszystkie użyte obrazki posiadają numery - każdy z nich można zwiększyć o jeden, a jako pierwszy (posiadający najwyższy priorytet) pokazać obrazek tła. W ten sposób animacje pokazywać się będą pod tłem, czyli dla gracza będą niewidoczne.
RE: Animacja nad obrazkiem. - Ayene - 18-06-18 07:37
To jeśli nie są to klatki animacji, tylko ruch, to mogłoby być nawet łatwiejsze do zaprogramowania w edytorze skryptów. Rozumiem jednak, że każdy battler ma indywidualnie ustawioną sekwencję ruchu?
RE: Animacja nad obrazkiem. - Revlis - 18-06-18 09:08
Jeśli jako battler rozumiemy poszczególne obrazki, to tak.
|