Rearranged and renamed Animation Editor-related script files

This commit is contained in:
Maruno17
2023-10-23 23:44:34 +01:00
parent 340983e765
commit 64890f3c9e
23 changed files with 136 additions and 91 deletions

View File

@@ -95,22 +95,22 @@ class UIControls::ControlsContainer
add_text_box(id, value, true)
end
def add_slider(id, min_value, max_value, value, has_label = false)
add_control(id, UIControls::Slider.new(*control_size(has_label), @viewport, min_value, max_value, value), has_label)
def add_number_slider(id, min_value, max_value, value, has_label = false)
add_control(id, UIControls::NumberSlider.new(*control_size(has_label), @viewport, min_value, max_value, value), has_label)
end
def add_labelled_slider(id, label, min_value, max_value, value)
def add_labelled_number_slider(id, label, min_value, max_value, value)
add_label(id, label)
add_slider(id, min_value, max_value, value, true)
add_number_slider(id, min_value, max_value, value, true)
end
def add_value_box(id, min_value, max_value, value, has_label = false)
add_control(id, UIControls::ValueBox.new(*control_size(has_label), @viewport, min_value, max_value, value), has_label)
def add_number_text_box(id, min_value, max_value, value, has_label = false)
add_control(id, UIControls::NumberTextBox.new(*control_size(has_label), @viewport, min_value, max_value, value), has_label)
end
def add_labelled_value_box(id, label, min_value, max_value, value)
def add_labelled_number_text_box(id, label, min_value, max_value, value)
add_label(id, label)
add_value_box(id, min_value, max_value, value, true)
add_number_text_box(id, min_value, max_value, value, true)
end
def add_button(id, button_text, has_label = false)

View File

@@ -1,7 +1,7 @@
#===============================================================================
#
#===============================================================================
class UIControls::Slider < UIControls::BaseControl
class UIControls::NumberSlider < UIControls::BaseControl
attr_reader :min_value
attr_reader :max_value

View File

@@ -1,7 +1,7 @@
#===============================================================================
#
#===============================================================================
class UIControls::ValueBox < UIControls::TextBox
class UIControls::NumberTextBox < UIControls::TextBox
attr_reader :min_value
attr_reader :max_value

View File

@@ -17,10 +17,10 @@ class UIControls::List < UIControls::BaseControl
def initialize(width, height, viewport, values = [])
super(width, height, viewport)
@slider = UIControls::Scrollbar.new(LIST_X + width - UIControls::Scrollbar::SLIDER_WIDTH, LIST_Y, height, viewport)
@slider.set_interactive_rects
@slider.range = ROW_HEIGHT
@slider.z = self.z + 1
@scrollbar = UIControls::Scrollbar.new(LIST_X + width - UIControls::Scrollbar::SLIDER_WIDTH, LIST_Y, height, viewport)
@scrollbar.set_interactive_rects
@scrollbar.range = ROW_HEIGHT
@scrollbar.z = self.z + 1
@rows_count = (height / ROW_HEIGHT).floor # Number of rows visible at once
@top_row = 0
@selected = -1
@@ -28,28 +28,28 @@ class UIControls::List < UIControls::BaseControl
end
def dispose
@slider.dispose
@slider = nil
@scrollbar.dispose
@scrollbar = nil
super
end
def x=(new_val)
super(new_val)
@slider.x = new_val + LIST_X + width - UIControls::Scrollbar::SLIDER_WIDTH
@scrollbar.x = new_val + LIST_X + width - UIControls::Scrollbar::SLIDER_WIDTH
end
def y=(new_val)
super(new_val)
@slider.y = new_val + LIST_Y
@scrollbar.y = new_val + LIST_Y
end
# Each value in @values is an array: [id, text].
def values=(new_vals)
@values = new_vals
set_interactive_rects
@slider.range = @values.length * ROW_HEIGHT
if @slider.visible
self.top_row = (@slider.position.to_f / ROW_HEIGHT).round
@scrollbar.range = @values.length * ROW_HEIGHT
if @scrollbar.visible
self.top_row = (@scrollbar.position.to_f / ROW_HEIGHT).round
else
self.top_row = 0
end
@@ -60,7 +60,7 @@ class UIControls::List < UIControls::BaseControl
def top_row=(val)
old_val = @top_row
@top_row = val
if @slider.visible
if @scrollbar.visible
@top_row = @top_row.clamp(0, @values.length - @rows_count)
else
@top_row = 0
@@ -110,7 +110,7 @@ class UIControls::List < UIControls::BaseControl
end
def repaint
@slider.repaint if @slider.invalid?
@scrollbar.repaint if @scrollbar.invalid?
super if invalid?
end
@@ -140,7 +140,7 @@ class UIControls::List < UIControls::BaseControl
@captured_area = nil
mouse_x, mouse_y = mouse_pos
return if !mouse_x || !mouse_y
return if @slider.visible && (@slider.busy? || mouse_x >= @slider.x - self.x)
return if @scrollbar.visible && (@scrollbar.busy? || mouse_x >= @scrollbar.x - self.x)
# Check for mouse presses on rows
mouse_y += @top_row * ROW_HEIGHT
@interactions.each_pair do |area, rect|
@@ -168,7 +168,7 @@ class UIControls::List < UIControls::BaseControl
return
end
# Don't update the highlight if the mouse is using the scrollbar
if @slider.visible && (@slider.busy? || mouse_x >= @slider.x - self.x)
if @scrollbar.visible && (@scrollbar.busy? || mouse_x >= @scrollbar.x - self.x)
invalidate if @hover_area
@hover_area = nil
return
@@ -193,12 +193,12 @@ class UIControls::List < UIControls::BaseControl
def update
return if !self.visible
@slider.update
@scrollbar.update
super
# TODO: Disabled control stuff.
# return if self.disabled
# Refresh the list's position if changed by moving the slider
self.top_row = (@slider.position.to_f / ROW_HEIGHT).round
# Refresh the list's position if changed by moving the scrollbar
self.top_row = (@scrollbar.position.to_f / ROW_HEIGHT).round
# Set the selected row to the row the mouse is over, if clicked on
if @captured_area
@selected = @hover_area if @hover_area.is_a?(Integer)

View File

@@ -1,8 +0,0 @@
MenuHandlers.add(:debug_menu, :create_animation_pbs_files, {
"name" => _INTL("Write all animation PBS files"),
"parent" => :files_menu,
"description" => _INTL("Write all animation PBS files."),
"effect" => proc {
Compiler.write_all_battle_animations
}
})

View File

@@ -120,3 +120,16 @@ module Compiler
Console.echo_h2(_INTL("Successfully rewrote all animation PBS files"), text: :green)
end
end
#===============================================================================
# Debug menu function for writing all animation PBS files. Shouldn't need to be
# used, but it's here if you want it.
#===============================================================================
MenuHandlers.add(:debug_menu, :create_animation_pbs_files, {
"name" => _INTL("Write all animation PBS files"),
"parent" => :files_menu,
"description" => _INTL("Write all animation PBS files."),
"effect" => proc {
Compiler.write_all_battle_animations
}
})

View File

@@ -22,8 +22,8 @@
# while it's playing.
#===============================================================================
class AnimationEditor
WINDOW_WIDTH = AnimationEditorLoadScreen::WINDOW_WIDTH
WINDOW_HEIGHT = AnimationEditorLoadScreen::WINDOW_HEIGHT
WINDOW_WIDTH = Settings::SCREEN_WIDTH + (32 * 10)
WINDOW_HEIGHT = Settings::SCREEN_HEIGHT + (32 * 10)
TOP_BAR_HEIGHT = 30
@@ -51,42 +51,39 @@ class AnimationEditor
def initialize(anim_id, anim)
@anim_id = anim_id
@anim = anim
# Viewports
@viewport = Viewport.new(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
@viewport.z = 99999
@canvas_viewport = Viewport.new(CANVAS_X, CANVAS_Y, CANVAS_WIDTH, CANVAS_HEIGHT)
@canvas_viewport.z = @viewport.z
# Background sprite
@screen_bitmap = BitmapSprite.new(WINDOW_WIDTH, WINDOW_HEIGHT, @viewport)
draw_editor_background
# Canvas
@canvas = Sprite.new(@viewport)
@canvas.x = CANVAS_X
@canvas.y = CANVAS_Y
@canvas.bitmap = RPG::Cache.load_bitmap("Graphics/Battlebacks/", "field_bg")
@canvas = AnimationEditor::Canvas.new(@canvas_viewport)
# Play controls
@play_controls = AnimationEditor::PlayControls.new(
PLAY_CONTROLS_X, PLAY_CONTROLS_Y, PLAY_CONTROLS_WIDTH, PLAY_CONTROLS_HEIGHT, @viewport
)
# Side panes
@commands_pane = UIControls::ControlsContainer.new(SIDE_PANE_X, SIDE_PANE_Y, SIDE_PANE_WIDTH, SIDE_PANE_HEIGHT)
@se_pane = UIControls::ControlsContainer.new(SIDE_PANE_X, SIDE_PANE_Y, SIDE_PANE_WIDTH, SIDE_PANE_HEIGHT)
@se_pane = UIControls::ControlsContainer.new(SIDE_PANE_X, SIDE_PANE_Y, SIDE_PANE_WIDTH, SIDE_PANE_HEIGHT)
@particle_pane = UIControls::ControlsContainer.new(SIDE_PANE_X, SIDE_PANE_Y, SIDE_PANE_WIDTH, SIDE_PANE_HEIGHT)
@keyframe_pane = UIControls::ControlsContainer.new(SIDE_PANE_X, SIDE_PANE_Y, SIDE_PANE_WIDTH, SIDE_PANE_HEIGHT)
# TODO: Make more side panes for:
# - colour/tone editor (accessed from commands_pane via a
# - colour/tone editor (accessed from @commands_pane via a
# button; has Apply/Cancel buttons to only apply all its values at
# the end of editing them, although canvas will be updated in real
# time to show the changes)
# - particle properties (that don't change during the animation; name,
# focus...)
# - SE particle properties (depends on keyframe)
# - effects particle properties (depends on keyframe; for screen
# shake, etc.)
# - keyframe properties (shift all later particle commands forward/
# backward).
# Play controls
@play_controls = UIControls::AnimationPlayControls.new(
PLAY_CONTROLS_X, PLAY_CONTROLS_Y, PLAY_CONTROLS_WIDTH, PLAY_CONTROLS_HEIGHT, @viewport
)
# Timeline/particle list
@particle_list = UIControls::AnimationParticleList.new(
@particle_list = AnimationEditor::ParticleList.new(
PARTICLE_LIST_X, PARTICLE_LIST_Y, PARTICLE_LIST_WIDTH, PARTICLE_LIST_HEIGHT, @viewport
)
@particle_list.set_interactive_rects
@captured = nil
set_canvas_contents
set_side_panes_contents
set_particle_list_contents
set_play_controls_contents
@@ -103,6 +100,7 @@ class AnimationEditor
@play_controls.dispose
@particle_list.dispose
@viewport.dispose
@canvas_viewport.dispose
end
def keyframe
@@ -115,18 +113,22 @@ class AnimationEditor
#-----------------------------------------------------------------------------
def set_canvas_contents
@canvas.bg_name = "indoor1"
end
def set_commands_pane_contents
# :frame (related to graphic) - If the graphic is user's sprite/target's
# sprite, make this instead a choice of front/back/same as the main sprite/
# opposite of the main sprite. Probably need two controls in the same space
# and refresh_commands_pane makes the appropriate one visible.
@commands_pane.add_labelled_value_box(:x, _INTL("X"), -128, CANVAS_WIDTH + 128, 64)
@commands_pane.add_labelled_value_box(:y, _INTL("Y"), -128, CANVAS_HEIGHT + 128, 96)
@commands_pane.add_labelled_number_text_box(:x, _INTL("X"), -128, CANVAS_WIDTH + 128, 64)
@commands_pane.add_labelled_number_text_box(:y, _INTL("Y"), -128, CANVAS_HEIGHT + 128, 96)
@commands_pane.add_labelled_checkbox(:visible, _INTL("Visible"), true)
@commands_pane.add_labelled_slider(:opacity, _INTL("Opacity"), 0, 255, 255)
@commands_pane.add_labelled_value_box(:zoom_x, _INTL("Zoom X"), 0, 1000, 100)
@commands_pane.add_labelled_value_box(:zoom_y, _INTL("Zoom Y"), 0, 1000, 100)
@commands_pane.add_labelled_value_box(:angle, _INTL("Angle"), -1080, 1080, 0)
@commands_pane.add_labelled_number_slider(:opacity, _INTL("Opacity"), 0, 255, 255)
@commands_pane.add_labelled_number_text_box(:zoom_x, _INTL("Zoom X"), 0, 1000, 100)
@commands_pane.add_labelled_number_text_box(:zoom_y, _INTL("Zoom Y"), 0, 1000, 100)
@commands_pane.add_labelled_number_text_box(:angle, _INTL("Angle"), -1080, 1080, 0)
@commands_pane.add_labelled_checkbox(:flip, _INTL("Flip"), false)
@commands_pane.add_labelled_dropdown_list(:blending, _INTL("Blending"), {
0 => _INTL("None"),

View File

@@ -1,13 +1,11 @@
# TODO: Come up with a better name for this class. I'm not sure I want to merge
# this class with the editor class.
class AnimationEditorLoadScreen
WINDOW_WIDTH = Settings::SCREEN_WIDTH + (32 * 10)
WINDOW_HEIGHT = Settings::SCREEN_HEIGHT + (32 * 10)
#===============================================================================
#
#===============================================================================
class AnimationEditor::AnimationSelector
ANIMATIONS_LIST_X = 4
ANIMATIONS_LIST_Y = 4
ANIMATIONS_LIST_WIDTH = 300
ANIMATIONS_LIST_HEIGHT = WINDOW_HEIGHT - (ANIMATIONS_LIST_Y * 2)
ANIMATIONS_LIST_HEIGHT = AnimationEditor::WINDOW_HEIGHT - (ANIMATIONS_LIST_Y * 2)
LOAD_BUTTON_WIDTH = 200
LOAD_BUTTON_HEIGHT = 48
@@ -16,9 +14,9 @@ class AnimationEditorLoadScreen
def initialize
generate_list
@viewport = Viewport.new(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
@viewport = Viewport.new(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
@viewport.z = 99999
@screen_bitmap = BitmapSprite.new(WINDOW_WIDTH, WINDOW_HEIGHT, @viewport)
@screen_bitmap = BitmapSprite.new(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, @viewport)
draw_editor_background
@load_animation_id = nil
create_controls
@@ -45,7 +43,7 @@ class AnimationEditorLoadScreen
end
@animations.push([id, name])
end
# TODO: For slider testing purposes.
# TODO: For scrollbar testing purposes.
rand(400).times do |i|
@animations.push([42 + i, "Extra animation #{i + 1}"])
end
@@ -53,7 +51,7 @@ class AnimationEditorLoadScreen
def draw_editor_background
# Fill the whole screen with white
@screen_bitmap.bitmap.fill_rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Color.black)
@screen_bitmap.bitmap.fill_rect(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, Color.black)
# Outline around animations list
areas = [
[ANIMATIONS_LIST_X, ANIMATIONS_LIST_Y, ANIMATIONS_LIST_WIDTH, ANIMATIONS_LIST_HEIGHT],
@@ -138,6 +136,7 @@ class AnimationEditorLoadScreen
screen = AnimationEditor.new(@load_animation_id, GameData::Animation.get(@load_animation_id).clone_as_hash)
screen.run
@load_animation_id = nil
break # TODO: For quickstart testing purposes.
# Refresh list of animations, in case the edited one changed its type,
# move, version or name
generate_list
@@ -155,26 +154,19 @@ class AnimationEditorLoadScreen
end
#===============================================================================
# Start
#===============================================================================
def test_anim_editor
Graphics.resize_screen(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
pbSetResizeFactor(1)
screen = AnimationEditorLoadScreen.new
screen.run
Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT)
pbSetResizeFactor($PokemonSystem.screensize)
$game_map&.autoplay
end
#===============================================================================
# Add to Debug menu
# Add to Debug menu.
#===============================================================================
MenuHandlers.add(:debug_menu, :use_pc, {
"name" => "Test new animation editor",
"name" => _INTL("New Animation Editor"),
"parent" => :main,
"description" => "Test new animation editor",
"description" => _INTL("Open the new animation editor."),
"effect" => proc {
test_anim_editor
Graphics.resize_screen(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
pbSetResizeFactor(1)
screen = AnimationEditor::AnimationSelector.new
screen.run
Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT)
pbSetResizeFactor($PokemonSystem.screensize)
$game_map&.autoplay
}
})

View File

@@ -1,3 +1,6 @@
#===============================================================================
#
#===============================================================================
module AnimationEditor::ParticleDataHelper
module_function
@@ -97,7 +100,7 @@ module AnimationEditor::ParticleDataHelper
#-----------------------------------------------------------------------------
# Returns an array indicating where command diamonds and duration lines should
# be drawn in the AnimationParticleList.
# be drawn in the AnimationEditor::ParticleList.
def get_particle_commands_timeline(particle)
ret = []
durations = []

View File

@@ -0,0 +1,43 @@
#===============================================================================
# TODO
#===============================================================================
class AnimationEditor::Canvas < Sprite
attr_reader :bg_name
def initialize(viewport)
super
@bg_val = ""
# TODO: Add a second bg sprite for screen shake purposes.
player_base_pos = Battle::Scene.pbBattlerPosition(0)
@player_base = IconSprite.new(*player_base_pos, viewport)
@player_base.z = 1
foe_base_pos = Battle::Scene.pbBattlerPosition(1)
@foe_base = IconSprite.new(*foe_base_pos, viewport)
@foe_base.z = 1
@message_bar_sprite = Sprite.new(viewport)
@message_bar_sprite.z = 999
end
def dispose
@message_bar_sprite.dispose
@player_base.dispose
@foe_base.dispose
super
end
def bg_name=(val)
return if @bg_name == val
@bg_name = val
# TODO: Come up with a better way to define the base filenames, based on
# which files actually exist.
self.bitmap = RPG::Cache.load_bitmap("Graphics/Battlebacks/", @bg_name + "_bg")
@player_base.setBitmap("Graphics/Battlebacks/" + @bg_name + "_base0")
@player_base.ox = @player_base.bitmap.width / 2
@player_base.oy = @player_base.bitmap.height
@foe_base.setBitmap("Graphics/Battlebacks/" + @bg_name + "_base1")
@foe_base.ox = @foe_base.bitmap.width / 2
@foe_base.oy = @foe_base.bitmap.height / 2
@message_bar_sprite.bitmap = RPG::Cache.load_bitmap("Graphics/Battlebacks/", @bg_name + "_message")
@message_bar_sprite.y = Settings::SCREEN_HEIGHT - @message_bar_sprite.height
end
end

View File

@@ -1,7 +1,7 @@
#===============================================================================
# TODO
#===============================================================================
class UIControls::AnimationPlayControls < UIControls::BaseControl
class AnimationEditor::PlayControls < UIControls::BaseControl
TEXT_OFFSET_Y = 5
def initialize(x, y, width, height, viewport)

View File

@@ -4,7 +4,7 @@
# scrollbar works, i.e. every visible @commands_sprites isn't redrawn each
# time the horizontal scrollbar changes.
#===============================================================================
class UIControls::AnimationParticleList < UIControls::BaseControl
class AnimationEditor::ParticleList < UIControls::BaseControl
VIEWPORT_SPACING = 1
TIMELINE_HEIGHT = 24 - VIEWPORT_SPACING
LIST_X = 0