Behind-View Battle System By Jet and Efeberk http://gamesvts.org I) Giới thiệu: Được cải tiến từ Simple Side-View của Jet, Behind-View Battle System cho phép sử dụng Characters trong những trận chiến với góc nhìn từ phía sau. Điều thú vị này đã khắc phục được tính đơn điệu của Default Battle System ngày trước II) Hướng dẫn sử dụng: - Plug-n-play - Xem kĩ phần chữ màu xanh (Giới thiệu và hướng dẫn) ở đầu đoạn mã trước khi dùng III) Screenshots & Example: IV) Code: Mã: #=============================================================================== # Behind-View Battle System # By Jet and efeberk #=============================================================================== # This script will allow you to have battle where all the actor's sprites are # display on the behind of the characters. # This script has: 10 customization options. #=============================================================================== # Overwritten Methods: # Scene_Battle: show_attack_animation # Spriteset_Battle: update_actors #------------------------------------------------------------------------------- # Aliased methods: # Spriteset_Battle: create_actors, create_enemies # Sprite_Character: initialize, update, dispose, start_new_effect # Scene_Battle: use_item, next_command, prior_command # Game_Character: screen_x, screen_y #=============================================================================== module Jet module Sideview #=========================================================================== # ENEMY OPTIONS #=========================================================================== # These are the attack animations for enemies when they use a regular attack. # It follows this format: enemy_id => animation_id ENEMY_ATK_ANIMS = { } # This is the default enemy attack animation, used when they do not have a # specific attack animation above. ENEMY_ATK_ANIMS.default = 1 # This is a list of enemies whose portraits should be flipped in battle. FLIPPED_ENEMIES = [2, 3, 4, 5, 8, 10, 12, 13, 14, 16, 17, 18, 19] #=========================================================================== # ACTOR OPTIONS #=========================================================================== # Should the player sprite have a shadow beneath them? PLAYER_SHADOW = true # These are sprite changes depending on state infliction. # It follows this format: state_id => "sprite_appention" # This means if the state is inflicted, the sprite will look for a graphic # that is the same name as the character's sprite, plus the appended option. # EX: Ralph's sprite's name is $ralph. Ralph gets knocked-out. This means # state 1 was inflicted, and my below config for 1 was: 1 => "_dead" # Now, his shown sprite will be $ralph_dead. If the sprite does not exist, # no change will be made. # The sprite index will be the same as the actor's. STATE_SPRITES = { 1 => "_dead", 2 => "_poison", 3 => "_blind" } #=========================================================================== # GENERAL_OPTIONS #=========================================================================== # This is the animation displayed when a skill is about to be used. SKILL_ANIMATION = 43 # This is the animation displayed when an item is about to be used. ITEM_ANIMATION = 43 # These are the animations played when a state is inflicted. # It follows this format: state_id => animation_id STATE_ANIMATIONS = { 1 => 56, 2 => 50, 3 => 51 } #=========================================================================== # FIELD OPTIONS #=========================================================================== # This is where the line-up begins. [x, y]. The higher the x, the further # right and the higher the y the further down. FIELD_POS = [275, 280] # This is how far down, and to the right each player is from the previous # actor. [x, y]. Same rules as above. FIELD_SPACING = [50, 0] end end #=============================================================================== # DON'T EDIT FURTHER UNLESS YOU KNOW WHAT TO DO. #=============================================================================== ($imported ||= {})[:jet] ||= {} $imported[:jet][:Sideview] = true class Game_Character attr_accessor :step_anime %w[screen_x screen_y].each {|a| aStr = %Q{ alias jet6372_#{a} #{a} def #{a}(*args, &block) $BTEST ? 0 : jet6372_#{a}(*args, &block) end } module_eval(aStr) } end class Game_Actor def animation_id=(t) self.battle_sprite.start_animation($data_animations[t]) rescue nil end end class Game_Battler def battle_sprite return nil unless SceneManager.scene_is?(Scene_Battle) SceneManager.scene.spriteset.battler_sprites.each {|a| return a if a.battler == self } return nil end end class Spriteset_Battle alias jet2847_create_enemies create_enemies def create_enemies(*args, &block) jet2847_create_enemies(*args, &block) @enemy_sprites.each {|a| a.mirror = Jet::Sideview::FLIPPED_ENEMIES.include?(a.battler.enemy.id) } end alias jet3835_create_actors create_actors def create_actors(*args, &block) jet3835_create_actors(*args, &block) @jet_party = $game_party.members @actor_sprites.each {|a| a.dispose } @actor_sprites = [] $game_party.members.each {|a| f = Game_Character.new f.set_graphic(a.character_name, a.character_index) f.step_anime = true f.set_direction(8) n = Sprite_Character.new(@viewport1, f) n.jet_x = Jet::Sideview::FIELD_POS[0] + a.index * Jet::Sideview::FIELD_SPACING[0] n.jet_y = Jet::Sideview::FIELD_POS[1] + a.index * Jet::Sideview::FIELD_SPACING[1] n.battler = a n.battle_sprite = true if Jet::Sideview::PLAYER_SHADOW v = Sprite.new(nil) v.bitmap = Cache.system("Shadow") n.shadow_sprite = v end @actor_sprites.push(n) } end def update_actors if @jet_party != $game_party.members @actor_sprites.each {|a| a.dispose } @actor_sprites = [] create_actors end @actor_sprites.each {|a| a.update } end end class Sprite_Character attr_accessor :battle_sprite, :jet_x, :jet_y, :shadow_sprite, :battler alias jet4646_initialize initialize def initialize(*args, &block) @battle_sprite = false jet4646_initialize(*args, &block) end alias jet3645_update update def update(*args, &block) jet3645_update(*args, &block) if @battle_sprite @character.step_anime = !@battler.dead? @character.update self.x = @jet_x self.y = @jet_y if !@battler.nil? f = @battler.states.dup f.sort! {|a, b| a.priority <=> b.priority }.reverse! for i in 0...f.size a = Jet::Sideview::STATE_SPRITES[f[i].id] next if a.nil? b = (Cache.character(@character.character_name + a) rescue false) next unless b index = @character.character_index @character.set_graphic(@character.character_name + a, index) break end end if !@shadow_sprite.nil? @shadow_sprite.x = self.x - @shadow_sprite.width / 2 @shadow_sprite.y = self.y - 28 @shadow_sprite.visible = self.visible @shadow_sprite.viewport = self.viewport @shadow_sprite.z = self.z - 1 end end end alias jet5484_dispose dispose def dispose(*args, &block) @shadow_sprite.dispose if !@shadow_sprite.nil? jet5484_dispose(*args, &block) end def move_x(times, amount) i = 0 until i == times self.jet_y += amount i += 1 [Graphics, SceneManager.scene.spriteset].each {|a| a.update } end end def effect? false end end class Game_Enemy def atk_animation_id1 return Jet::Sideview::ENEMY_ATK_ANIMS[@enemy_id] end def atk_animation_id2 return 0 end end class Scene_Battle attr_reader :spriteset alias jet2711_use_item use_item def use_item(*args, &block) if @subject.is_a?(Game_Actor) if !@subject.current_action.guard? @subject.battle_sprite.move_x(11, -4) end end if !@subject.current_action.guard? && !@subject.current_action.attack? if @subject.current_action.item.is_a?(RPG::Item) n = $data_animations[Jet::Sideview::ITEM_ANIMATION] else n = $data_animations[Jet::Sideview::SKILL_ANIMATION] end @subject.battle_sprite.start_animation(n) wait_for_animation end jet2711_use_item(*args, &block) if @subject.is_a?(Game_Actor) if !@subject.current_action.guard? @subject.battle_sprite.move_x(11, 4) end end end def show_attack_animation(targets) aid1 = @subject.atk_animation_id1 aid2 = @subject.atk_animation_id2 show_normal_animation(targets, aid1, false) show_normal_animation(targets, aid2, true) end %w[next prior].each {|a| aStr = %Q{ alias jet3734_#{a}_command #{a}_command def #{a}_command(*args, &block) f = BattleManager.actor f.battle_sprite.move_x(6, 4) if f.is_a?(Game_Actor) jet3734_#{a}_command(*args, &block) f = BattleManager.actor f.battle_sprite.move_x(6, -4) if f.is_a?(Game_Actor) end } module_eval(aStr) } end class Game_Action def guard? item == $data_skills[subject.guard_skill_id] end end if $imported[:jet][:BattlePopUps] class Sprite_Character attr_accessor :popups alias jet4758_initialize initialize def initialize(*args, &block) @popups = [] @updating_sprites = [] @popup_wait = 0 jet4758_initialize(*args, &block) end alias jet7467_update update def update(*args, &block) jet7467_update(*args, &block) if @popup_wait == 0 if !@popups.empty? @updating_sprites.push(@popups.pop) @popup_wait = 30 end else @popup_wait -= 1 end @updating_sprites.each {|a| a.visible = true if !a.visible a.update @updating_sprites.delete(a) if a.disposed? } end alias jet5483_dispose dispose def dispose(*args, &block) (@updating_sprites + @popups).each {|a| a.dispose } jet5483_dispose(*args, &block) end alias jet3745_setup_new_effect setup_new_effect def setup_new_effect(*args, &block) jet3745_setup_new_effect(*args, &block) do_sprite_popups end def make_popup(text, color) @popups.unshift(Sprite_JetPopup.new(text.to_s, color, self)) end def do_sprite_popups return if @battler.nil? if @battler_struct.nil? @battler_struct = Struct.new(:hp, :mp, :tp).new(0, 0, 0) @battler_struct.hp = @battler.hp @battler_struct.mp = @battler.mp @battler_struct.tp = @battler.tp end check_success_popup check_hp_popup check_mp_popup check_tp_popup end def check_success_popup if @battler.result.success if @battler.result.critical make_popup(Jet::BattlePopUps::CRITICAL_TEXT, Jet::BattlePopUps::CRITICAL_COLOR) elsif @battler.result.missed make_popup(Jet::BattlePopUps::MISSED_TEXT, Jet::BattlePopUps::MISS_COLOR) elsif @battler.result.evaded make_popup(Jet::BattlePopUps::EVADED_TEXT, Jet::BattlePopUps::EVADE_COLOR) end @battler.result.clear_hit_flags end end def check_hp_popup if @battler_struct.hp != @battler.hp f = @battler_struct.hp - @battler.hp if f > 0 make_popup(Jet::BattlePopUps::HURT_TEXT + f.to_s, Jet::BattlePopUps::HURT_COLOR) elsif f < 0 make_popup(Jet::BattlePopUps::HEAL_TEXT + f.abs.to_s, Jet::BattlePopUps::HEAL_COLOR) end @battler_struct.hp = @battler.hp end end def check_mp_popup if @battler_struct.mp != @battler.mp f = @battler_struct.mp - @battler.mp if f > 0 make_popup(Jet::BattlePopUps::HURT_TEXT_MP + f.to_s, Jet::BattlePopUps::HURT_COLOR_MP) elsif f < 0 make_popup(Jet::BattlePopUps::HEAL_TEXT_MP + f.abs.to_s, Jet::BattlePopUps::HEAL_COLOR_MP) end @battler_struct.mp = @battler.mp end end def check_tp_popup if @battler_struct.tp != @battler.tp f = (@battler_struct.tp - @battler.tp).round if f > 0 make_popup(Jet::BattlePopUps::HURT_TEXT_TP + f.to_s, Jet::BattlePopUps::HURT_COLOR_TP) elsif f < 0 make_popup(Jet::BattlePopUps::HEAL_TEXT_TP + f.abs.to_s, Jet::BattlePopUps::HEAL_COLOR_TP) end @battler_struct.tp = @battler.tp end end end end V) Credits: Jet Efeberk