Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Player bleibt bei Menüaufruf nicht stehen



Marsellus
28.02.2012, 04:54
Hallo Leute, und schon wieder melde ich mit einem Problem.
Und zwar habe ich vor, ein Menü zu machen, mit Pictures und allem drum und dran.
Allerdings weiß ich zum Verrecken nicht, wie ich den Player "freezen" kann.
Im 2000/3er ging das, indem man einfach ein Move Event mit Wait gemacht hat, bei XP geht das nicht mehr.
Andere NPCs würden dann aber trotzdem noch rumlaufen. Und wenn man für das ganze ein Auto Event macht, kann man sich gar nicht mehr bewegen, das Menü muss also ein Paralleler Prozess sein.
Gibt es also eine Möglichkeit, alle Events inklusive Player zu freezen? Von mir aus auch mit Script.
Danke schonmal im Voraus! :)

Cornix
28.02.2012, 11:18
Wechsel die $scene zu einer eigenen neuen. Die Update-Methoden aller Kartenobjekte werden durch die $scene hervorgerufen.
Falls du die Karte selbst im Hintergrund sichtbar behalten möchtest müsstest du jedoch ein wenig weiter herumbasteln um das Spriteset der Scene_Map zu übernehmen.
Andernfalls könntest du auch einfach die Scene_Map Klasse so überarbeiten, dass du eine Pause-Funktion für Events und Player einbaust.

Marsellus
28.02.2012, 11:42
Leider habe ich keine Ahnung von Ruby, könntest du mir das vielleicht ein wenig simpler erklären?

Cornix
29.02.2012, 20:07
Wir haben in der Scene_Map folgende Update Methode:

def update
# Loop
loop do
# Update map, interpreter, and player order
# (this update order is important for when conditions are fulfilled
# to run any event, and the player isn't provided the opportunity to
# move in an instant)
$game_system.map_interpreter.update
$game_map.update
$game_player.update
# Update system (timer), screen
$game_system.update
$game_screen.update
# Abort loop if player isn't place moving
unless $game_temp.player_transferring
break
end
# Run place move
transfer_player
# Abort loop if transition processing
if $game_temp.transition_processing
break
end
end
# Update sprite set
@spriteset.update
# Update message window
@message_window.update
# If game over
if $game_temp.gameover
# Switch to game over screen
$scene = Scene_Gameover.new
return
end
# If returning to title screen
if $game_temp.to_title
# Change to title screen
$scene = Scene_Title.new
return
end
# If transition processing
if $game_temp.transition_processing
# Clear transition processing flag
$game_temp.transition_processing = false
# Execute transition
if $game_temp.transition_name == ""
Graphics.transition(20)
else
Graphics.transition(40, "Graphics/Transitions/" +
$game_temp.transition_name)
end
end
# If showing message window
if $game_temp.message_window_showing
return
end
# If encounter list isn't empty, and encounter count is 0
if $game_player.encounter_count == 0 and $game_map.encounter_list != []
# If event is running or encounter is not forbidden
unless $game_system.map_interpreter.running? or
$game_system.encounter_disabled
# Confirm troop
n = rand($game_map.encounter_list.size)
troop_id = $game_map.encounter_list[n]
# If troop is valid
if $data_troops[troop_id] != nil
# Set battle calling flag
$game_temp.battle_calling = true
$game_temp.battle_troop_id = troop_id
$game_temp.battle_can_escape = true
$game_temp.battle_can_lose = false
$game_temp.battle_proc = nil
end
end
end
# If B button was pressed
if Input.trigger?(Input::B)
# If event is running, or menu is not forbidden
unless $game_system.map_interpreter.running? or
$game_system.menu_disabled
# Set menu calling flag or beep flag
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
# If debug mode is ON and F9 key was pressed
if $DEBUG and Input.press?(Input::F9)
# Set debug calling flag
$game_temp.debug_calling = true
end
# If player is not moving
unless $game_player.moving?
# Run calling of each screen
if $game_temp.battle_calling
call_battle
elsif $game_temp.shop_calling
call_shop
elsif $game_temp.name_calling
call_name
elsif $game_temp.menu_calling
call_menu
elsif $game_temp.save_calling
call_save
elsif $game_temp.debug_calling
call_debug
end
end
end
Hintereinander werden hier die erforderlichen Update-Prozesse ausgeführt, damit wird Frame für Frame das Spiel fortgesetzt.
In dieser Methode können wir nun mithilfe einer Abfrage auf den Wert einer Variablen gewisse Bereiche abschalten wenn wir möchten.
Die Frage ist nur welche Bereiche wir herausfiltern wollen.

Wenn du willst, dass das derzeitige Event weiterausgeführt werden kann aber weder der Spieler noch übrige Events wie NPC's Aktionen ausführen können so müssen wir unseren Fokus auf diese drei Zeilen am Anfang des Updates richten:


$game_system.map_interpreter.update
$game_map.update
$game_player.update
Hier wird der Interpreter (Dein Event-Code) die Map (Mit allen übrigen Events) und der Spielercharakter (Mit Bewegungen und allen übrigen Aktionen) geupdated.

Wir können hier nun beispielsweise eine Abfrage wie folgt einbauen:


$game_system.map_interpreter.update
if $game_switches[1]
$game_map.update
$game_player.update
end
Das würde dazu führen, dass alle Events (außer dem derzeit laufenden) und der Spieler nichtmehr geupdated werden würden falls der Switch (Nicht self-switch!) mit der ID 1 auf false stehen würde.

Du kannst die Bedingung natürlich auch auf alles andere Stellen was dir beliebt.
Ich hoffe das hilft dir ersteinmal weiter.

Das Script findest du deklariert als "Scene_Map" im unteren Bereich des Scripteditors, die Update Methode beginnt ab Zeile 56, das eingefügte "if" würde an Zeile 64 liegen. Alles natürlich angenommen du hast keines der Scripte derzeit verändert und benutzt die Bedingung wie ich sie oben beschrieben habe.

Falls du noch Fragen oder Probleme haben solltest stell sie ruhig, ich bin sicher, selbst wenn ich gerade keine Zeit finde wird sich jemand finden lassen der dir dabei helfen kann.

Marsellus
02.03.2012, 14:24
Okay, das macht soweit Sinn. Dankeschön dafür! Allerdings bleibt dann das ganze Spiel stehen, weil der Switch ja nicht an ist. Und selbst wenn ich den in einem Event auf der Startmap und Autostart an schalte, funktioniert das ganze nicht. Ich denke mal, dass es sinnvoll wäre, den Switch im Titelbildschirm auf true zu setzen (wenn das überhaupt geht).
Wie kriege ich das hin?

Cornix
02.03.2012, 15:48
Ist alles möglich, einfacher wäre es natürlich aber die Condition lediglich umzudrehen und darauf zu prüfen, dass der Switch aus ist.
Eine Bedingung kann man auf verschiedenem Wege umdrehen:

if not $game_switches[1]
oder aber:

if !$game_switches[1]
Hat den gleichen Effekt, meiner Meinung ist die erste Variation allerdings leichter zu lesen und zu verstehen.

Marsellus
02.03.2012, 17:23
Dankesehr. Nur gibt's nun wieder ein Problem: Wenn das Menü geschlossen wird, soll der Switch wieder an gemacht werden, d.h. dass alles wieder läuft. Nur leider bleibt dann immernoch alles stehen.
Entschuldige, wenn ich dich mit der ganzen Fragerei nerve.

Cornix
03.03.2012, 09:58
Ich sehe, das funktioniert nicht mit wait-, loop- und label-Befehlen.

Hier ist eine zweite, ein klein wenig aufwändigere Variante welche es dir erlauben wird parallel und auto-start common events weiterhin zu benutzen allerdings alle normalen Events, den Player und alle Common-Events mit Call-Aufruf pausiert.

In der Klasse "Game_Map" müssen in Zeile 392 die folgenden Zeilen ersetzt werden:

for event in @events.values
event.update
end
werden ersetzt durch:

if not $game_switches[1]
for event in @events.values
event.update
end
end

Und in der Klasse "Scene_Map" werden in Zeile 54 die folgenden Zeilen Code ersetzt werden:

$game_system.map_interpreter.update
$game_map.update
$game_player.update
wird ersetzt durch:

$game_system.map_interpreter.update
$game_map.update
if not $game_switches[1]
$game_player.update
end

Nun sollten parallele common events und autostart common events weiterhin funktionieren.