PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Ace] Window.ok_handler funktioniert nicht



MindXperience
07.03.2014, 19:47
Hey Guys,
ich experimentiere wieder etwas mit den Window Klassen, damit ich diese endlich mal erlerne und auch verstehen ^^
So versuche ich grad eine Liste zu machen, die jeden Status anzeigt und dabei angibt, ob der Actor mit diesem Status betroffen ist oder nicht. Wenn man Enter drückt, so soll der Status on/off triggern. Aber der ok-Handler scheint einfach nicht zu funktionieren?


class Window_DebugStates < Window_SkillList
def col_max
return 1
end
def enable?(item)
return true
end
def include?(item)
return true
end
def make_item_list
@data = $data_states
end
def draw_item(index)
state = @data[index]
if state
rect = item_rect(index)
rect.width -= 4
draw_item_name(state, rect.x, rect.y, enable?(state))
infl = inflicted?(state) ? "[ON]" : "[OFF]"
draw_text(item_rect_for_text(index), infl, 2)
end
end
def inflicted?(state)
return @actor.state?(state)
end
end


def command_edit_states
@states_window = Window_DebugStates.new(100, 120, 250, 250)
@states_window.actor = @actor
@states_window.set_handler(:ok, method(:on_state_ok))
@states_window.set_handler(:cancel, method(:on_state_cancel))
@states_window.activate
@states_window.refresh
@states_window.select(1)
end


def on_state_ok
state_id = @states_window.index
if actor.state?(state_id)
@actor.remove_state(state_id)
else
@actor.add_state(state_id)
end
@states_window.select(@states_window.index)
@status_window.refresh
@states_window.activate
end

Cornix
07.03.2014, 19:50
Es wäre ganz nützlich falls du dazu sagen kannst, um welchen Maker es sich handelt.

MindXperience
07.03.2014, 19:51
VX Ace
steht aber auch in meiner Signatur ;)

-KD-
07.03.2014, 20:16
Das ist alles weitestgehend richtig. Zwei Fehler sind mir aufgefallen:

def inflicted?(state)
return @actor.state?(state)
end
Die Methode state? erwartet die ID des States, nicht das State Objekt selbst. Und die RGSS ist an der Stelle leider sehr sparsam mit Fehlermeldungen. Also einfach state.id hinschreiben.


@status_window.refresh
Das soll vermutlich @state_window.refresh heißen.

Solche blöden Fehler findet man nur durch exzessives Einfügen von print Befehlen.

MindXperience
07.03.2014, 20:21
Vielen Dank für den Hinweis.

Es heißt tatsächlich status_window, da ich noch weitere Fenster habe.
Außerdem habe ich schon eindeutige Befehle in "def on_state_ok" eingefügt (zB prints), aber die Methode wird einfach nicht gestartet

-KD-
07.03.2014, 20:32
Ich hab deinen Code so in Scene_Map reingepresst und die zwei Stellen korrigiert. Damit funktioniert es.

class Window_DebugStates < Window_SkillList
def col_max
return 1
end
def enable?(item)
return true
end
def include?(item)
return true
end
def make_item_list
@data = $data_states
end
def draw_item(index)
state = @data[index]
if state
rect = item_rect(index)
rect.width -= 4
draw_item_name(state, rect.x, rect.y, enable?(state))
infl = inflicted?(state) ? "[ON]" : "[OFF]"
draw_text(item_rect_for_text(index), infl, 2)
end
end
def inflicted?(state)
return @actor.state?(state.id)
end
end

class Scene_Map < Scene_Base

alias start_debugstates start
def start
start_debugstates
@actor = $game_party.members.first
command_edit_states
end

def command_edit_states
@states_window = Window_DebugStates.new(100, 120, 250, 250)
@states_window.actor = @actor
@states_window.set_handler(:ok, method(:on_state_ok))
@states_window.set_handler(:cancel, method(:on_state_cancel))
@states_window.activate
@states_window.refresh
@states_window.select(1)
@states_window.actor = @actor
end

def on_state_cancel

end

def on_state_ok
state_id = @states_window.index
if @actor.state?(state_id)
@actor.remove_state(state_id)
@actor.result.removed_states.clear
else
@actor.add_state(state_id)
end
#@states_window.select(@states_window.index)
@states_window.refresh
@states_window.activate
end

end

Eine Zeile hab ich noch eingefügt:

@actor.result.removed_states.clear
muss nach @actor.remove_state aufgerufen werden, da ein Zustand der beseitigt wurde in der selben "Kampfrunde" nicht noch einmal gesetzt werden darf.

Kannst du mal deinen kompletten Code zeigen?

MindXperience
07.03.2014, 20:39
Nun, das komplette Skript umfasst einige mehr Funktionieren, aber schau es dir mal an


class Window_CharacterCommand < Window_MenuCommand
def make_command_list
add_command("Name ändern", :name)
add_command("Klasse bearbeiten", :class)
add_command("Level ändern", :level)
add_command("Skills bearbeiten", :skills)
add_command("heilen", :heal)
add_command("Status hinzufügen/entfernen", :stats)
end
end

class Window_DebugClass < Window_Command
def make_command_list
for i in 1...$data_actors.size
name = $data_classes[i].name
text = sprintf("%s", name)
add_command(text, :switch, true, i)
end
end
end

class Window_Level < Window_Command
def make_command_list
add_command("< >", :switch)
end
def update
super
update_tone
update_open if @opening
update_close if @closing
if Input.repeat?(:RIGHT)
call_handler(:right)
end
if Input.repeat?(:LEFT)
call_handler(:left)
end
end
end

class Window_DebugSkill < Window_SkillList
def col_max
return 1
end
def enable?(item)
return true
end
def include?(item)
return true
end
def make_item_list
@data = $data_skills
end
end

class Window_DebugStates < Window_SkillList
def col_max
return 1
end
def enable?(item)
return true
end
def include?(item)
return true
end
def make_item_list
@data = $data_states
end
def draw_item(index)
state = @data[index]
if state
rect = item_rect(index)
rect.width -= 4
draw_item_name(state, rect.x, rect.y, enable?(state))
infl = inflicted?(state) ? "[ON]" : "[OFF]"
draw_text(item_rect_for_text(index), infl, 2)
end
end
def inflicted?(state)
return @actor.state?(state)
end
end

class Scene_Character < Scene_Status

def start
super
@status_window = Window_Status.new(@actor)
@status_window.set_handler(:pagedown, method(:next_actor))
@status_window.set_handler(:pageup, method(:prev_actor))
@status_window.refresh

@command_window = Window_CharacterCommand.new
@command_window.x = 350
@command_window.y = 200
@command_window.width = 290
@command_window.set_handler(:name, method(:command_change_name))
@command_window.set_handler(:class, method(:command_change_class))
@command_window.set_handler(:level, method(:command_change_level))
@command_window.set_handler(:skills, method(:command_edit_skills))
@command_window.set_handler(:heal, method(:command_heal))
@command_window.set_handler(:stats, method(:command_edit_states))
@command_window.set_handler(:cancel, method(:return_scene))
@command_window.refresh

@class_window = Window_DebugClass.new(100, 100)
@class_window.hide

@level_window = Window_Level.new(300, 200)
@level_window.hide

@skill_window = Window_DebugSkill.new(100, 100, 400, 480)
@skill_window.hide

@states_window = Window_DebugStates.new(100, 300, 250, 250)
@states_window.hide
@states_window.set_handler(:ok, method(:on_state_ok))
@states_window.set_handler(:cancel, method(:on_state_cancel))
end

def command_change_name
SceneManager.call(Scene_Name)
SceneManager.scene.prepare(@actor, 10)
end

def command_change_class
@class_window = Window_DebugClass.new(100, 40)
@class_window.width = 250
@class_window.set_handler(:ok, method(:on_class_ok))
@class_window.set_handler(:cancel, method(:on_class_cancel))
@class_window.activate
@class_window.refresh
end

def command_change_level
@level_window = Window_Level.new(100, 100)
@level_window.set_handler(:ok, method(:on_level_cancel))
@level_window.set_handler(:cancel, method(:on_level_cancel))
@level_window.set_handler(:left, method(:decrease_level))
@level_window.set_handler(:right, method(:increase_level))
@level_window.activate
@level_window.refresh
end

def command_edit_skills
@skill_window = Window_DebugSkill.new(100, 0, 400, 400)
@skill_window.actor = @actor
@skill_window.set_handler(:ok, method(:on_skill_ok))
@skill_window.set_handler(:cancel, method(:on_skill_cancel))
@skill_window.activate
@skill_window.refresh
@skill_window.select(1)
end

def command_change_equip
end

def command_heal
@actor.recover_all
@command_window.refresh
@command_window.activate
@status_window.refresh
end

def command_edit_states
@states_window = Window_DebugStates.new(100, 120, 250, 250)
@states_window.actor = @actor
@states_window.set_handler(:ok, method(:on_state_ok))
@states_window.set_handler(:cancel, method(:on_state_cancel))
@states_window.activate
@states_window.refresh
@states_window.select(1)
end

def on_class_ok
cl = @class_window.index + 1
@actor.change_class(cl)
@class_window.hide
@command_window.activate
@status_window.refresh
end

def on_class_cancel
@command_window.activate
@class_window.hide
end

def on_level_cancel
@level_window.hide
@command_window.activate
@status_window.refresh
end

def decrease_level
@actor.level_down
@status_window.refresh
end

def increase_level
@actor.level_up
@status_window.refresh
end

def on_skill_ok
@actor.learn_skill(@skill_window.index)
@skill_window.refresh
@skill_window.activate
@status_window.refresh
end

def on_skill_cancel
@skill_window.hide
@command_window.activate
@status_window.refresh
end

def on_state_ok
state_id = @states_window.index
if (4 < 2)
@actor.remove_state(state_id)
else
@actor.add_state(state_id)
end
#@states_window.select(@states_window.index)
@states_window.refresh
#@status_window.refresh
@states_window.activate
end

def on_state_cancel
@states_window.hide
@command_window.activate
@status_window.refresh
end
end

-KD-
07.03.2014, 21:26
Okay, Fehler gefunden. Das Problem liegt darin, dass (bezogen auf die OK und CANCEL Handler) immer nur ein Fenster aktiv sein darf (also sozusagen im Fokus liegen kann). Bei dir fängt ein anderes Window den Tastendruck Enter ab, daher kommt der in Window_DebugState nicht mehr an. Klassen die von Window_Selectable erben, sind automatisch erstmal inaktiv. Klassen die von Window_Command erben, sind automatisch aktiv. Du musst also deine Klassen, Window_DebugClass und Window_Level direkt nach der Initialisierung deaktivieren, sonst liegen die im Fokus und fangen die OK und CANCEL Handler ab. Ob ein Fenster aktiv ist, ist komplett unabhängig davon ob ein Fenster angezeigt wird. hide() allein reicht also nicht aus, du musst auch deactivate() aufrufen.

MindXperience
07.03.2014, 22:05
Ahhh so läuft das also ^^

Vielen Dank fr diese ausführliche Erklärung :)