Anim Editor: improved NumberTextBox entry, added "FoeInvertX/Y" particle properties, tidied up

This commit is contained in:
Maruno17
2024-04-15 22:42:46 +01:00
parent a548a1ae9d
commit 15033d6114
18 changed files with 271 additions and 279 deletions

View File

@@ -209,14 +209,11 @@ class AnimationEditor
end
def load_settings
# TODO: Load these from a saved file.
@settings = {
:side_sizes => [1, 1],
:user_index => 0,
:target_indices => [1],
:side_sizes => [1, 1], # Player's side, opposing side
:user_index => 0, # 0, 2, 4
:target_indices => [1], # There must be at least one valid target
:user_opposes => false,
# TODO: Ideally be able to independently choose base graphics, which will
# be a separate setting here.
:canvas_bg => "indoor1",
# NOTE: These sprite names are also used in Pokemon.play_cry and so should
# be a species ID (being a string is fine).
@@ -277,11 +274,9 @@ class AnimationEditor
def add_side_pane_tab_buttons(component, pane)
next_pos_x, next_pos_y = pane.next_control_position
# TODO: Add masking tab and properties.
[
[:commands_pane, :general_tab, _INTL("General")],
[:color_tone_pane, :color_tone_tab, _INTL("Color/Tone")],
# [:masking_pane, :masking_tab, _INTL("Masking")]
[:color_tone_pane, :color_tone_tab, _INTL("Color/Tone")]
].each_with_index do |tab, i|
btn = UIControls::Button.new(100, 28, pane.viewport, tab[2])
btn.set_fixed_size
@@ -334,7 +329,6 @@ class AnimationEditor
anim_properties.add_labelled_text_box(:pbs_path, _INTL("PBS filepath"), "")
anim_properties.add_labelled_checkbox(:has_user, _INTL("Involves a user?"), true)
anim_properties.add_labelled_checkbox(:has_target, _INTL("Involves a target?"), true)
# TODO: Flags control. Includes a List, TextBox and some add/delete Buttons.
anim_properties.add_button(:close, _INTL("Close"))
anim_properties.visible = false
end
@@ -421,7 +415,6 @@ class AnimationEditor
#-----------------------------------------------------------------------------
def play_animation
# TODO: Grey out the rest of the screen.
play_controls = @components[:play_controls]
# Set up canvas as a pseudo-battle screen
@components[:canvas].prepare_to_play_animation
@@ -457,8 +450,6 @@ class AnimationEditor
Graphics.update
Input.update
anim_player.update
# TODO: Maybe get elapsed time from anim_player and pass it to
# play_controls to be drawn?
play_controls.update
if play_controls.changed?
if play_controls.values.keys.include?(:stop)
@@ -487,7 +478,6 @@ class AnimationEditor
ctrl = @components[:animation_properties].get_control(:move)
case @anim[:type]
when :move, :opp_move
# TODO: Cache this list?
move_list = []
GameData::Move.each { |m| move_list.push([m.id.to_s, m.name]) }
move_list.push(["STRUGGLE", _INTL("Struggle")]) if move_list.none? { |val| val[0] == "STRUGGLE" }
@@ -527,7 +517,6 @@ class AnimationEditor
when :common, :opp_common
component.get_control(:move_label).text = _INTL("Common animation")
end
# TODO: Maybe other things as well?
else
# Side panes
if AnimationEditor::SidePanes.is_side_pane?(component_sym)
@@ -543,8 +532,6 @@ class AnimationEditor
component.controls.each do |ctrl|
next if !new_vals.include?(ctrl[0])
ctrl[1].value = new_vals[ctrl[0]][0] if ctrl[1].respond_to?("value=")
# TODO: new_vals[ctrl[0]][1] is whether the value is being interpolated,
# which should be indicated somehow in ctrl[1].
end
end
# Additional refreshing of controls
@@ -591,7 +578,6 @@ class AnimationEditor
when :name
edit_animation_properties
@components[:menu_bar].anim_name = get_animation_display_name
# TODO: May need to refresh other things.
refresh_component(:particle_list)
end
when :canvas
@@ -663,8 +649,6 @@ class AnimationEditor
refresh_component(:canvas)
end
when :animation_properties
# TODO: Will changes here need to refresh any other components (e.g. side
# panes)? Probably.
case property
when :type, :opp_variant
type = @components[component_sym].get_control(:type).value
@@ -770,7 +754,6 @@ class AnimationEditor
refresh if keyframe != old_keyframe || particle_index != old_particle_index
end
if component.respond_to?("values")
# TODO: Make undo/redo snapshot.
values = component.values
if values
values.each_pair do |property, value|

View File

@@ -80,9 +80,6 @@ class AnimationEditor
# Show pop-up window
@pop_up_bg_bitmap.visible = true
bg_bitmap = create_pop_up_window(ANIM_PROPERTIES_WIDTH, ANIM_PROPERTIES_HEIGHT)
# TODO: Draw box around list control(s), i.e. flags. Note that an extra +4
# should be added to its x coordinate because of padding created when
# defining @components[:animation_properties].
anim_properties = @components[:animation_properties]
anim_properties.visible = true
# Set control values
@@ -99,7 +96,6 @@ class AnimationEditor
anim_properties.get_control(:has_user).value = !@anim[:no_user]
anim_properties.get_control(:has_target).value = !@anim[:no_target]
anim_properties.get_control(:usable).value = !(@anim[:ignore] || false)
# TODO: Populate flags.
refresh_component(:animation_properties) # This sets the :move control's value
# Interaction loop
ret = nil
@@ -200,8 +196,6 @@ class AnimationEditor
fname = (chunks[0] == "USER") ? @settings[:user_sprite_name].to_s : @settings[:target_sprite_name].to_s
case chunks[1] || ""
when "", "OPP"
# TODO: "TARGET" and "TARGET_OPP" will not be accurate in cases where
# the target is on the same side as the user.
if (chunks[0] == "USER") ^ (chunks[1] == "OPP") # xor
folder = (@settings[:user_opposes]) ? "Graphics/Pokemon/Front/" : "Graphics/Pokemon/Back/"
else

View File

@@ -132,12 +132,6 @@ AnimationEditor::SidePanes.add_pane(:particle_pane, {
}
})
# AnimationEditor::SidePanes.add_pane(:keyframe_pane, {
# :set_visible => proc { |editor, anim, keyframe, particle_index|
# next keyframe >= 0 && particle_index < 0
# }
# })
#===============================================================================
#
#===============================================================================
@@ -183,12 +177,6 @@ AnimationEditor::SidePanes.add_property(:commands_pane, :z, {
}
})
# TODO: If the graphic is user's sprite/target's sprite, make :frame instead
# a choice of front/back/same as the main sprite/opposite of the main
# sprite. Will need two controls in the same space, which is doable.
# Will also need to change the graphic chooser to only have "user"/
# "target" options rather than all the variants that this control
# would manage.
AnimationEditor::SidePanes.add_property(:commands_pane, :frame, {
:new => proc { |pane, editor|
pane.add_labelled_number_text_box(:frame, _INTL("Frame"), 0, 99, 0)
@@ -196,7 +184,6 @@ AnimationEditor::SidePanes.add_property(:commands_pane, :frame, {
:refresh_value => proc { |control, editor|
# Disable the "Frame" control if the particle's graphic is predefined to be
# the user's or target's sprite
# TODO: Also disable it if the particle's graphic isn't a spritesheet.
graphic = editor.anim[:particles][editor.particle_index][:graphic]
if ["USER", "USER_OPP", "USER_FRONT", "USER_BACK",
"TARGET", "TARGET_OPP", "TARGET_FRONT", "TARGET_BACK"].include?(graphic)
@@ -253,9 +240,6 @@ AnimationEditor::SidePanes.add_property(:commands_pane, :blending, {
}
})
# TODO: Add buttons that shift all commands from the current keyframe and later
# forwards/backwards in time?
#===============================================================================
#
#===============================================================================
@@ -534,8 +518,39 @@ AnimationEditor::SidePanes.add_property(:particle_pane, :focus, {
}
})
# TODO: FlipIfFoe.
# TODO: RotateIfFoe.
AnimationEditor::SidePanes.add_property(:particle_pane, :opposing_label, {
:new => proc { |pane, editor|
pane.add_label(:opposing_label, _INTL("If on opposing side..."))
}
})
AnimationEditor::SidePanes.add_property(:particle_pane, :foe_invert_x, {
:new => proc { |pane, editor|
pane.add_labelled_checkbox(:foe_invert_x, _INTL("Invert X"), false)
},
:refresh_value => proc { |control, editor|
focus = editor.anim[:particles][editor.particle_index][:focus]
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(focus) == GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(focus)
control.disable
else
control.enable
end
}
})
AnimationEditor::SidePanes.add_property(:particle_pane, :foe_invert_y, {
:new => proc { |pane, editor|
pane.add_labelled_checkbox(:foe_invert_y, _INTL("Invert Y"), false)
},
:refresh_value => proc { |control, editor|
focus = editor.anim[:particles][editor.particle_index][:focus]
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(focus) == GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(focus)
control.disable
else
control.enable
end
}
})
AnimationEditor::SidePanes.add_property(:particle_pane, :duplicate, {
:new => proc { |pane, editor|
@@ -580,18 +595,3 @@ AnimationEditor::SidePanes.add_property(:particle_pane, :delete, {
end
}
})
# TODO: Various ways to bulk shift this particle's commands earlier/later.
#===============================================================================
# NOTE: keyframe_pane is currently inaccessible (intentionally). If it will have
# its own commands and should be accessible again, change def
# on_mouse_release in ParticleList.
#===============================================================================
# AnimationEditor::SidePanes.add_property(:keyframe_pane, :header, {
# :new => proc { |pane, editor|
# pane.add_header_label(:header, _INTL("Edit keyframe"))
# }
# })
# TODO: Various command-shifting options (insert/delete keyframe).

View File

@@ -63,7 +63,8 @@ module AnimationEditor::ParticleDataHelper
return ret
end
# TODO: Generalise this to any property?
# Used to determine which keyframes the particle is visible in, which is
# indicated in the timeline by a coloured bar.
# NOTE: Particles are assumed to be not visible at the start of the
# animation, and automatically become visible when the particle has
# its first command. This does not apply to the "User" and "Target"
@@ -460,11 +461,8 @@ module AnimationEditor::ParticleDataHelper
# the new one, the new particle will inherit its focus; otherwise it gets a
# default focus of :foreground.
def add_particle(particles, index)
new_particle = {
:name => _INTL("New particle"),
:graphic => GameData::Animation::PARTICLE_DEFAULT_VALUES[:graphic],
:focus => GameData::Animation::PARTICLE_DEFAULT_VALUES[:focus]
}
new_particle = GameData::Animation::PARTICLE_DEFAULT_VALUES.clone
new_particle[:name] = _INTL("New particle")
if index > 0 && index <= particles.length && particles[index - 1][:name] != "SE"
new_particle[:focus] = particles[index - 1][:focus]
end

View File

@@ -39,7 +39,6 @@ class AnimationEditor::Canvas < Sprite
def initialize_background
self.z = -200
# NOTE: The background graphic is self.bitmap.
# TODO: Add second (flipped) background graphic, for screen shake commands.
player_base_pos = Battle::Scene.pbBattlerPosition(0)
@player_base = IconSprite.new(*player_base_pos, viewport)
@player_base.z = -199
@@ -231,7 +230,6 @@ class AnimationEditor::Canvas < Sprite
AnimationPlayer::Helper.apply_z_focus_to_sprite(@battler_sprites[idx], 0, focus_z)
end
end
# TODO: Also add background/bases and so on.
hide_all_sprites
@sel_frame_sprite.visible = false
@playing = true
@@ -249,9 +247,6 @@ class AnimationEditor::Canvas < Sprite
def refresh_bg_graphics
return if @bg_name && @bg_name == @settings[:canvas_bg]
@bg_name = @settings[:canvas_bg]
# TODO: Make the choice of background graphics match the in-battle one in
# def pbCreateBackdropSprites. Ideally make that method a class method
# so the canvas can use it rather than duplicate it.
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
@@ -292,12 +287,11 @@ class AnimationEditor::Canvas < Sprite
end
end
# TODO: Create shadow sprites?
# TODO: Make this also refresh if the layout of the battle changes (i.e. which
# battlers are the user/target).
def ensure_battler_sprites
if @sides_swapped.nil? || @sides_swapped != sides_swapped? ||
!@side_size0 || @side_size0 != side_size(0)
should_ensure = @sides_swapped.nil? || @sides_swapped != sides_swapped? ||
@settings_user_index.nil? || @settings_user_index != @settings[:user_index] ||
@settings_target_indices.nil? || @settings_target_indices != @settings[:target_indices]
if should_ensure || !@side_size0 || @side_size0 != side_size(0)
@battler_sprites.each_with_index { |s, i| s.dispose if i.even? && s && !s.disposed? }
@battler_frame_sprites.each_with_index { |s, i| s.dispose if i.even? && s && !s.disposed? }
@side_size0 = side_size(0)
@@ -312,8 +306,7 @@ class AnimationEditor::Canvas < Sprite
@battler_frame_sprites[i * 2] = frame_sprite
end
end
if @sides_swapped.nil? || @sides_swapped != sides_swapped? ||
!@side_size1 || @side_size1 != side_size(1)
if should_ensure || !@side_size1 || @side_size1 != side_size(1)
@battler_sprites.each_with_index { |s, i| s.dispose if i.odd? && s && !s.disposed? }
@battler_frame_sprites.each_with_index { |s, i| s.dispose if i.odd? && s && !s.disposed? }
@side_size1 = side_size(1)
@@ -328,7 +321,11 @@ class AnimationEditor::Canvas < Sprite
@battler_frame_sprites[(i * 2) + 1] = frame_sprite
end
end
@sides_swapped = sides_swapped?
if should_ensure
@sides_swapped = sides_swapped?
@settings_user_index = @settings[:user_index]
@settings_target_indices = @settings[:target_indices].clone
end
end
def refresh_battler_graphics
@@ -429,6 +426,14 @@ class AnimationEditor::Canvas < Sprite
def refresh_sprite(index, target_idx = -1)
particle = @anim[:particles][index]
return if !particle || particle[:name] == "SE"
relative_to_index = -1
if particle[:focus] != :user_and_target
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
relative_to_index = user_index
elsif GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
relative_to_index = target_idx
end
end
# Get sprite
spr, frame = get_sprite_and_frame(index, target_idx)
# Calculate all values of particle at the current keyframe
@@ -443,10 +448,16 @@ class AnimationEditor::Canvas < Sprite
# Set opacity
spr.opacity = values[:opacity]
# Set coordinates
base_x = values[:x]
base_y = values[:y]
if relative_to_index >= 0 && relative_to_index.odd?
base_x *= -1 if particle[:foe_invert_x]
base_y *= -1 if particle[:foe_invert_y]
end
focus_xy = AnimationPlayer::Helper.get_xy_focus(particle, user_index, target_idx,
@user_coords, @target_coords[target_idx])
AnimationPlayer::Helper.apply_xy_focus_to_sprite(spr, :x, values[:x], focus_xy)
AnimationPlayer::Helper.apply_xy_focus_to_sprite(spr, :y, values[:y], focus_xy)
AnimationPlayer::Helper.apply_xy_focus_to_sprite(spr, :x, base_x, focus_xy)
AnimationPlayer::Helper.apply_xy_focus_to_sprite(spr, :y, base_y, focus_xy)
# Set graphic and ox/oy (may also alter y coordinate)
AnimationPlayer::Helper.set_bitmap_and_origin(particle, spr, user_index, target_idx,
[@user_bitmap_front_name, @user_bitmap_back_name],
@@ -455,8 +466,6 @@ class AnimationEditor::Canvas < Sprite
spr.x += offset_xy[0]
spr.y += offset_xy[1]
# Set frame
# TODO: Should this always happens or only if the graphic is a spritesheet?
# I don't think there's harm in it always being set.
spr.src_rect.x = values[:frame].floor * spr.src_rect.width
# Set z (priority)
focus_z = AnimationPlayer::Helper.get_z_focus(particle, user_index, target_idx)
@@ -627,6 +636,15 @@ class AnimationEditor::Canvas < Sprite
base_coords = Battle::Scene.pbBattlerPosition(first_target_index)
new_pos -= base_coords[0]
end
relative_to_index = -1
if particle[:focus] != :user_and_target
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
relative_to_index = user_index
elsif GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
relative_to_index = target_idx
end
end
new_pos *= -1 if relative_to_index >= 0 && relative_to_index.odd? && particle[:foe_invert_x]
@values ||= {}
@values[:x] = new_pos
@captured[0] = new_canvas_x
@@ -655,6 +673,15 @@ class AnimationEditor::Canvas < Sprite
base_coords = Battle::Scene.pbBattlerPosition(first_target_index)
new_pos -= base_coords[1]
end
relative_to_index = -1
if particle[:focus] != :user_and_target
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
relative_to_index = user_index
elsif GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
relative_to_index = target_idx
end
end
new_pos *= -1 if relative_to_index >= 0 && relative_to_index.odd? && particle[:foe_invert_y]
@values ||= {}
@values[:y] = new_pos
@captured[1] = new_canvas_y

View File

@@ -33,25 +33,68 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
@looping = false
end
def dispose
@bitmaps.each { |b| b&.dispose }
super
end
#-----------------------------------------------------------------------------
def generate_button_bitmaps
@bitmaps = {}
play_button = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
(PLAY_BUTTON_SIZE - 2).times do |j|
play_button.fill_rect(PLAY_BUTTON_SIZE / 4, j + 1, (j >= (PLAY_BUTTON_SIZE - 2) / 2) ? PLAY_BUTTON_SIZE - j : j + 3, 1, ICON_COLOR)
end
@bitmaps[:play_button] = play_button
stop_button = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
stop_button.fill_rect(4, 4, PLAY_BUTTON_SIZE - 8, PLAY_BUTTON_SIZE - 8, ICON_COLOR)
@bitmaps[:stop_button] = stop_button
# Loop button
play_once_button = Bitmap.new(LOOP_BUTTON_SIZE, LOOP_BUTTON_SIZE)
play_once_button.fill_rect(1, 7, 11, 2, ICON_COLOR)
play_once_button.fill_rect(8, 5, 2, 6, ICON_COLOR)
play_once_button.fill_rect(10, 6, 1, 4, ICON_COLOR)
play_once_button.fill_rect(13, 1, 2, 14, ICON_COLOR)
@bitmaps[:play_once_button] = play_once_button
looping_button = Bitmap.new(LOOP_BUTTON_SIZE, LOOP_BUTTON_SIZE)
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0].each_with_index do |val, i|
next if val == 0
looping_button.fill_rect(1 + (i % 14), 1 + (i / 14), 1, 1, ICON_COLOR)
end
@bitmaps[:looping_button] = looping_button
end
def add_play_controls
# Play button
play_button = UIControls::BitmapButton.new(PLAY_BUTTON_X, PLAY_BUTTON_Y, self.viewport, @play_button_bitmap)
play_button = UIControls::BitmapButton.new(PLAY_BUTTON_X, PLAY_BUTTON_Y, self.viewport, @bitmaps[:play_button])
play_button.set_interactive_rects
play_button.disable
@controls.push([:play, play_button])
# Stop button
stop_button = UIControls::BitmapButton.new(PLAY_BUTTON_X, PLAY_BUTTON_Y, self.viewport, @stop_button_bitmap)
stop_button = UIControls::BitmapButton.new(PLAY_BUTTON_X, PLAY_BUTTON_Y, self.viewport, @bitmaps[:stop_button])
stop_button.set_interactive_rects
stop_button.visible = false
@controls.push([:stop, stop_button])
# Loop buttons
loop_button = UIControls::BitmapButton.new(LOOP_BUTTON_X, LOOP_BUTTON_Y, self.viewport, @play_once_button_bitmap)
loop_button = UIControls::BitmapButton.new(LOOP_BUTTON_X, LOOP_BUTTON_Y, self.viewport, @bitmaps[:play_once_button])
loop_button.set_interactive_rects
loop_button.visible = false if @looping
@controls.push([:loop, loop_button])
unloop_button = UIControls::BitmapButton.new(LOOP_BUTTON_X, LOOP_BUTTON_Y, self.viewport, @looping_button_bitmap)
unloop_button = UIControls::BitmapButton.new(LOOP_BUTTON_X, LOOP_BUTTON_Y, self.viewport, @bitmaps[:looping_button])
unloop_button.set_interactive_rects
unloop_button.visible = false if !@looping
@controls.push([:unloop, unloop_button])
@@ -83,47 +126,6 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
@controls.push([:duration_value, duration_value])
end
def generate_button_bitmaps
@play_button_bitmap = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
(PLAY_BUTTON_SIZE - 2).times do |j|
@play_button_bitmap.fill_rect(PLAY_BUTTON_SIZE / 4, j + 1, (j >= (PLAY_BUTTON_SIZE - 2) / 2) ? PLAY_BUTTON_SIZE - j : j + 3, 1, ICON_COLOR)
end
@stop_button_bitmap = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
@stop_button_bitmap.fill_rect(4, 4, PLAY_BUTTON_SIZE - 8, PLAY_BUTTON_SIZE - 8, ICON_COLOR)
# Loop button
@play_once_button_bitmap = Bitmap.new(LOOP_BUTTON_SIZE, LOOP_BUTTON_SIZE)
@play_once_button_bitmap.fill_rect(1, 7, 11, 2, ICON_COLOR)
@play_once_button_bitmap.fill_rect(8, 5, 2, 6, ICON_COLOR)
@play_once_button_bitmap.fill_rect(10, 6, 1, 4, ICON_COLOR)
@play_once_button_bitmap.fill_rect(13, 1, 2, 14, ICON_COLOR)
@looping_button_bitmap = Bitmap.new(LOOP_BUTTON_SIZE, LOOP_BUTTON_SIZE)
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0].each_with_index do |val, i|
next if val == 0
@looping_button_bitmap.fill_rect(1 + (i % 14), 1 + (i / 14), 1, 1, ICON_COLOR)
end
end
def dispose
@play_button_bitmap.dispose
@stop_button_bitmap.dispose
@play_once_button_bitmap.dispose
@looping_button_bitmap.dispose
super
end
#-----------------------------------------------------------------------------
def duration=(new_val)

View File

@@ -135,31 +135,35 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
def initialize_controls
generate_button_bitmaps
@controls = []
add_particle_button = UIControls::BitmapButton.new(x + 1, y + 1, viewport, @add_button_bitmap)
add_particle_button = UIControls::BitmapButton.new(x + 1, y + 1, viewport, @bitmaps[:add_button])
add_particle_button.set_interactive_rects
@controls.push([:add_particle, add_particle_button])
up_particle_button = UIControls::BitmapButton.new(x + 22, y + 1, viewport, @up_button_bitmap)
up_particle_button = UIControls::BitmapButton.new(x + 22, y + 1, viewport, @bitmaps[:up_button])
up_particle_button.set_interactive_rects
@controls.push([:move_particle_up, up_particle_button])
down_particle_button = UIControls::BitmapButton.new(x + 43, y + 1, viewport, @down_button_bitmap)
down_particle_button = UIControls::BitmapButton.new(x + 43, y + 1, viewport, @bitmaps[:down_button])
down_particle_button.set_interactive_rects
@controls.push([:move_particle_down, down_particle_button])
end
def generate_button_bitmaps
@add_button_bitmap = Bitmap.new(12, 12)
@add_button_bitmap.fill_rect(1, 5, 10, 2, TEXT_COLOR)
@add_button_bitmap.fill_rect(5, 1, 2, 10, TEXT_COLOR)
@up_button_bitmap = Bitmap.new(12, 12)
@bitmaps = {}
add_button = Bitmap.new(12, 12)
add_button.fill_rect(1, 5, 10, 2, TEXT_COLOR)
add_button.fill_rect(5, 1, 2, 10, TEXT_COLOR)
@bitmaps[:add_button] = add_button
up_button = Bitmap.new(12, 12)
5.times do |i|
@up_button_bitmap.fill_rect(1 + i, 7 - i, 1, (i == 0) ? 2 : 3, TEXT_COLOR)
@up_button_bitmap.fill_rect(10 - i, 7 - i, 1, (i == 0) ? 2 : 3, TEXT_COLOR)
up_button.fill_rect(1 + i, 7 - i, 1, (i == 0) ? 2 : 3, TEXT_COLOR)
up_button.fill_rect(10 - i, 7 - i, 1, (i == 0) ? 2 : 3, TEXT_COLOR)
end
@down_button_bitmap = Bitmap.new(12, 12)
@bitmaps[:up_button] = up_button
down_button = Bitmap.new(12, 12)
5.times do |i|
@down_button_bitmap.fill_rect(1 + i, 2 + i + (i == 0 ? 1 : 0), 1, (i == 0) ? 2 : 3, TEXT_COLOR)
@down_button_bitmap.fill_rect(10 - i, 2 + i + (i == 0 ? 1 : 0), 1, (i == 0) ? 2 : 3, TEXT_COLOR)
down_button.fill_rect(1 + i, 2 + i + (i == 0 ? 1 : 0), 1, (i == 0) ? 2 : 3, TEXT_COLOR)
down_button.fill_rect(10 - i, 2 + i + (i == 0 ? 1 : 0), 1, (i == 0) ? 2 : 3, TEXT_COLOR)
end
@bitmaps[:down_button] = down_button
end
def dispose
@@ -171,9 +175,7 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
@particle_line_sprite.dispose
@controls.each { |c| c[1].dispose }
@controls.clear
@add_button_bitmap.dispose
@up_button_bitmap.dispose
@down_button_bitmap.dispose
@bitmaps.each { |b| b&.dispose }
dispose_listed_sprites
@list_viewport.dispose
@commands_bg_viewport.dispose
@@ -436,9 +438,6 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
@duration += DURATION_BUFFER
end
# TODO: Call this only from set_particles and when changes are made to
# @particles by the main editor scene. If we can be specific about which
# particle was changed, recalculate only that particle's commands.
def calculate_all_commands_and_durations
calculate_duration
calculate_all_commands
@@ -956,8 +955,6 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
end
set_changed if @keyframe != @captured_keyframe || @row_index != @captured_row
@keyframe = @captured_keyframe || -1
# TODO: If :keyframe_pane should be accessible by clicking on the
# timeline, change the below line to = @captured_row || -1.
@row_index = @captured_row if @captured_row
end
end