I've been having an issue all day trying to figure out why I can't get my cursor to go left or right. So far it picks one direction and regardless of which button you click it will still go in that direction.
This is suppose to change it so the script would switch between windows depending on which button (:left or :right) you click. However all it does is jump to window #1 and then shift between window #1 and #2 without even going back to window #0
def on_status_change
last_index = @index
@index = (if @index < 3 then (@index + 1) % @item_max
elsif @index > 0 then (@index +) % @item_max
end)
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
This method shifts through all the windows but only in one direction regardless of which key I click (:left or :right)
def on_status_change
last_index = @index
@index = @index == (@item_max - 1) ? 0 : (@index + 1)
@index = @index == 0 ? (@item_max - 1) : (@index - 1)
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
If you need any additional information or clarification I'll add it.
Thanks
can you post the button.press? methods for R and L
class Window_TradeStatus < Window_Selectable
def process_handling
return unless open? && active
return process_change if Input.trigger?(:LEFT) || Input.trigger?(:RIGHT)
super
end
def process_change
Input.update
call_handler(:change)
end
end
class Scene_ActorTrade < Scene_Base
MAIN_CHAR.each_with_index do |a, b|
eval("#{b += 1}
def create_#{a}_status_window(*args)
@status_actor#{b} = Window_TradeStatus.new(*args)
@status_actor#{b}.set_handler(:cancel, method(:return_scene))
@status_actor#{b}.set_handler(:change, method(:on_status_change))
@status_actor#{b}.help_window = @help_window
end
def create_#{a}_trade_window(dx)
dy = @status_actor1.y + @status_actor1.height
dw = @status_actor1.width
dh = Graphics.height - dy
@trade_actor#{b} = Window_TradeItemList.new(dx, dy, dw, dh)
@trade_actor#{b}.help_window = @help_window
@status_actor#{b}.item_window = @trade_actor#{b}
end")
end
end
You really should put checks for what button was pressed in your 'on_status_change' method.
If button right is triggered
If @index is at last item, then @index = 0, else @index += 1
If button left is triggered
If @index is at first item, then @index = last_item, else @index -= 1
You can see for yourself why your logic is faulty if you get a piece of paper and a pencil, assume @index is 0, and run through your code a few times.
Repeat the process again except now @index is at the last item in the list.
Thanks, I tried something like that earlier but I accidentally used Input.trigger? instead of Input.press?. so it didn't work.
def on_status_change
last_index = @index
@index = (if Input.press?(:RIGHT) then @index == (@item_max - 1) ? 0 : (@index + 1)
else @index = @index == 0 ? (@item_max - 1) : (@index - 1)
end)
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
Can you use proper formatting?
def on_status_change
last_index = @index
if Input.press?(:RIGHT)
@index = @index == (@item_max - 1) ? 0 : (@index + 1)
elsif Input.press?(:LEFT)
@index = @index == 0 ? (@item_max - 1) : (@index - 1)
end
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
I take it that by "using trigger didn't work" means that you want the cursor to continually cycle through the items as long as the button is held (as opposed to stopping at the first/last item and not jumping to the beginning/end when the button is lifted and pressed again, like how the engine does by default).
Actually the button doesn't cycle through when held because in this class:
class Window_TradeStatus < Window_Selectable
def process_handling
return unless open? && active
return process_change if Input.trigger?(:LEFT) || Input.trigger?(:RIGHT)
super
end
def process_change
Input.update
call_handler(:change)
end
end
It is already telling the code to cycle through each window with each click.
However the method we both just posted:
def on_status_change
last_index = @index
if Input.press?(:RIGHT)
@index = @index == (@item_max - 1) ? 0 : (@index + 1)
elsif Input.press?(:LEFT)
@index = @index == 0 ? (@item_max - 1) : (@index - 1)
end
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
Also if I do:
def on_status_change
last_index = @index
if Input.trigger?(:RIGHT)
@index = @index == (@item_max - 1) ? 0 : (@index + 1)
elsif Input.trigger?(:LEFT)
@index = @index == 0 ? (@item_max - 1) : (@index - 1)
end
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
It doesn't switch windows at all and turning
elsif Input.trigger?(:LEFT)
into just
the code will just cycle RIGHT, but not Left.
...why would you even do that...
By calling Input.update again, you effectively destroy any buttons currently held down this frame to be removed from the triggered list. You REALLY should only call Input.update ONCE every frame.
Moving on, I'm going to assume that call_handler(:change) is essentially calling on_status_change.
Obviously, using Input.trigger? in your on_status_change isn't going to work since Input.update has just removed left or right from being considered triggered. It is, however, still considered as being pressed. That block of code I posted should clearly do the job.
Ya it does work, but for some reason it wasn't typed into that sentence I wrote in the last post so it looks like the code doesn't work. Well actually the code I posted before yours worked as well even if you didn't like the format. Also Input.update isn't being called twice according to VXACE.
Well it has to be called twice. How else would the Input.trigger? work for calling process_change, but then suddenly not work in on_status_change, assuming this is all occurring on the same frame?
Also, please do use proper, standard, and conventional formatting. Not only is it easier to see mistakes in code, but it also makes it easier for me and other programmers to read it, especially when you ask them to help you.
def on_status_change
last_index = @index
@index = (if Input.press?(:RIGHT) then @index == (@item_max - 1) ? 0 : (@index + 1)
else @index = @index == 0 ? (@item_max - 1) : (@index - 1) #<============ logic says: @index = @index = @index == 0 ...
end)
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
how about Input.repeat?
def on_status_change
last_index = @index
if Input.repeat?(:RIGHT)
@index = (@index + 1) % @item_max
elsif Input.repeat?(:LEFT)
@index = (@index - 1) % @item_max
end
if @index != last_index
@status_windows[last_index].deactivate.unselect
@status_windows[@index].activate.select(0)
end
end
Don't think that'd work either as Repeat has a weird interval/delay pattern going on. Someone posted the exact frame data but I forgot where it was.
Anyways, following bigace's "call Input.update again" code, #repeat? would always return false.
class Window_TradeStatus < Window_Selectable
def process_handling
return unless open? && active
return process_change if Input.trigger?(:LEFT) || Input.trigger?(:RIGHT)
# Assume LEFT button is down. At this point,
# TRIGGER = [LEFT]
# PRESS = [LEFT]
# REPEAT = [LEFT]
super
end
def process_change
Input.update
# At this point, assuming LEFT is still down,
# TRIGGER = []
# PRESS = [LEFT] #==> If LEFT was somehow released before the Input.update is called, this could actually be empty (but we're talking about 0.000000001 of a second or something in that realm)
# REPEAT = []
call_handler(:change) #===> Calls method on_status_change
end
end
There really is no reason to even call a second Input.update if the update method (on_status_change) is called only when the left or right button is triggered.