Maniac Mansion Mania Forum
MMM-Werkzeugkiste => Technik => Thema gestartet von: Mulle The Maniac am 21. August 2007, 16:58:55
-
Hi Leute!
Heute möchte ich folgendes wissen: Wie kann ich ein Gespräch von zwei Personen im Hintergrund laufen lassen.
Ein Beispiel: Man steuert gerade Bernard und läuft an ein paar Passanten vorbei, die gerade über Gott und die Welt sprechen.
Mit welchem Skript-Befehl funktioniert das?
-
ich hatte das für epi53 so gelöst
Overlay* sayNoBlockOverlay1;
Overlay* sayNoBlockOverlay2;
Overlay* sayNoBlockOverlay3;
int sayNoBlockCharID1 = -1;
int sayNoBlockCharID2 = -1;
int sayNoBlockCharID3 = -1;
int sayNoBlockCounter1 = 0;
int sayNoBlockCounter2 = 0;
int sayNoBlockCounter3 = 0;
int sayNoBlockCounter4 = 0;
int sayNoBlockCounter5 = 0;
int sayNoBlockCounter6 = 0;
int iPause = 300;
function sayNoBlock(int CharID, const string message, int number)
{
if(number == 1)
{
sayNoBlockOverlay1 = character[CharID].SayBackground(message);
sayNoBlockCharID1 = CharID;
}
else if(number == 2)
{
sayNoBlockOverlay2 = character[CharID].SayBackground(message);
sayNoBlockCharID2 = CharID;
}
else if(number == 3)
{
sayNoBlockOverlay3 = character[CharID].SayBackground(message);
sayNoBlockCharID3 = CharID;
}
character[CharID].LockView(character[CharID].SpeechView);
character[CharID].Animate(character[CharID].Loop, 5, eRepeat, eNoBlock, eForwards);
}
// =======================================================================================
function removeAllSayNoBlock()
{
if(sayNoBlockCharID1 != -1)
{
character[sayNoBlockCharID1].UnlockView();
sayNoBlockCharID1 = -1;
}
if(sayNoBlockCharID2 != -1)
{
character[sayNoBlockCharID2].UnlockView();
sayNoBlockCharID2 = -1;
}
if(sayNoBlockCharID3 != -1)
{
character[sayNoBlockCharID3].UnlockView();
sayNoBlockCharID3 = -1;
}
if(sayNoBlockOverlay1 != null && sayNoBlockOverlay1.Valid == 1)
{
sayNoBlockOverlay1.Remove();
}
if(sayNoBlockOverlay2 != null && sayNoBlockOverlay2.Valid == 1)
{
sayNoBlockOverlay2.Remove();
}
if(sayNoBlockOverlay3 != null && sayNoBlockOverlay3.Valid == 1)
{
sayNoBlockOverlay3.Remove();
}
}
// =======================================================================================
function EmiliaAndWendyDialog()
{
int iStart1 = 100;
int iStart2 = iStart1+125+iPause;
int iStart3 = iStart2+150+iPause;
int iStart4 = iStart3+150+iPause;
int iStart5 = iStart4+199+iPause;
if (IsGamePaused() == 0)
{
if(sayNoBlockCounter6 == iStart1)
sayNoBlock(cEmilia.ID, "Nun mach schon.", 1);
else if(sayNoBlockCounter6 == iStart1+125)
sayNoBlock(cWendy.ID, "Alles zu seiner Zeit.", 2);
else if(sayNoBlockCounter6 == iStart2)
sayNoBlock(cEmilia.ID, "Es ist wirklich dringend.", 1);
else if(sayNoBlockCounter6 == iStart2+150)
sayNoBlock(cWendy.ID, "Siehst du nicht, dass ich gerade beschäftigt bin?", 2);
else if(sayNoBlockCounter6 == iStart3)
sayNoBlock(cEmilia.ID, "Bist du dann mal fertig?", 1);
else if(sayNoBlockCounter6 == iStart3+150)
sayNoBlock(cWendy.ID, "Ich bin fertig, wenn ich fertig bin.", 2);
else if(sayNoBlockCounter6 == iStart4)
sayNoBlock(cEmilia.ID, "Ich muss diesen Aufsatz morgen abgeben.", 1);
else if(sayNoBlockCounter6 == iStart4+200)
sayNoBlock(cWendy.ID, "Das ist dein Problem, nicht meines.", 2);
else if(sayNoBlockCounter6 == iStart5)
sayNoBlockCounter6 = iStart1-1;
sayNoBlockCounter6++;
}
}
function repeatedly_execute (){
...
// sayNoBlock global checks
if(sayNoBlockCharID1 != -1 && sayNoBlockOverlay1.Valid == 0)
{
character[sayNoBlockCharID1].UnlockView();
sayNoBlockCharID1 = -1;
}
else if(sayNoBlockCharID2 != -1 && sayNoBlockOverlay2.Valid == 0)
{
character[sayNoBlockCharID2].UnlockView();
sayNoBlockCharID2 = -1;
}
else if(sayNoBlockCharID3 != -1 && sayNoBlockOverlay3.Valid == 0)
{
character[sayNoBlockCharID3].UnlockView();
sayNoBlockCharID3 = -1;
}
// sayNoBlock room checks
if(player.room == 3)
{
if(cWendy.x > 0)
{
EmiliaAndWendyDialog();
}
}
}
}
geht sicher einfacher und dieser code ist auch nicht optimiert, aber er hat gefunkt ;D
die einzelnen sayNoBlockCounter sind jeweils für einen hintergrunddialog
der code ist für 3 sprecher ausgelegt, aber jederzeit erweiterbar
die einzelnen dialoge bleiben bei einem bildwechsel genau da stehen und werden beim erneuten betreten des raumes wieder genau da fortgesetzt
-
Jessas! :D
Das ist doch bereits alles eingebaut...
qDisplaySpeech(int CharID, string message);
Also bspw.
// player enters room (after fadein)
qDisplaySpeech(cPassant1.ID, "Na, alles klar?);
qDisplaySpeech(cPassant2.ID, "Freilich. Bei Dir?");
...
(Nicht getestet!)
@Bòógieman:
Verwende das nächste Mal lieber arrays ;)
Overlay*sayNoBlockOverlay[4];
int sayNoBlockCharID[4];
...
sayNoBlockOverlay[number] = character[CharID].SayBackground(message);
sayNoBlockCharID[number] = CharID;
-
wie gesagt, der code ist nicht optimiert sondern war eigentlich nur zur einmaligen verwendung in meiner episode gedacht ;D
solche sachen programmiere ich immer quick&dirty ;)
wäre halt praktisch gewesen, wenn ich vorher kenntnis von der existenz von qDisplaySpeech gehabt hätte, in der AGS hilfe hab ich nix gefunden und das gesamte starterpack wollte ich nicht von a bis o durchackern ;)
ich sollte evtl. vielleicht doch mal einen blick in die tutorials werfen :P
wo sind denn die ganzen spannenden starterpack-funktionen beschrieben?
-
Richtig entdeckt hab ich das erst beim Ummodeln auf OO.
Aber das komplette global script mal zu überfliegen kann nicht schaden, sollte jeder Entwickler mal machen :)
Ansonsten:
http://www.adventure-treff.de/forum/viewtopic.php?t=7529
-
Werde ich umsetzen!
Danke Ihr Beiden! ;)
-
gibt es eigentlich eine funktion wie SayBackgroundAt?
also eine kombination von SayBackground und SayAt, die einen text an einer bestimmten position aber ohne zu blockieren anzeigt
oder muss man dafür extra overlays verwenden?
(für diese frage wollte ich nicht extra einen eigenen thread aufmachen und außerdem passt sie hier ganz gut rein ;) )
-
ok, hab mir ein eigenes SayBackgroundAt gebastelt ;)
gibt es für qDisplaySpeech eigentlich auch eine Verzögerungsfunktion?
qDisplaySpeech zeigt ja die texte ohne pausen am stück an
ich hätte aber gerne nach jedem satz eine kleine pause :-\
EDIT: ok auch das ist gelöst
mit
string Delay(int time)
kann man einen passenden leerstring erzeugen :)
-
kann man eigentlich eine cutscene machen, die vom global script gestartet und später beendet wird?
ich würde gerne, wenn der hintergrunddialog einen bestimmten punkt erreicht hat, eine kurze cutscene machen
es wird zwar weiterhin nur der hintergrunddialog ausgeführt, aber die benutzereingaben sollen unterdrückt werden
oder anders gefragt, gibt es eine möglichkeit um benutzereingaben zu unterbinden und später wieder zu aktivieren?
ich stelle mir da sowas vor wie
Mouse.Enabled = false
nur leider habe ich da nix passendes gefunden :(
Mouse.Visible versteckt zwar den cursor, aber klicken kann man trotzdem noch
-
DisableInterface() / EnableInterface()
-
aah, sehr schön :D
-
so, zurück zum alten thema ;D
ich verwende qDisplaySpeech und das wiederum verwendet DisplaySpeechBackground
dummerweise ignoriert das das schwarze streifen GUI am oberen rand gänzlich und somit ist der text bei einem character der bei Y 100 steht, nicht mehr sichtbar
ich hab das jetzt soweit umgeschrieben, dass Character.SayBackground verwendet wird, damit ich auch an das Overlay des textes ran komme
nur wenn ich jetzt bei diesem Overlay die Y koordinate neu setzen will, wird der text plötzlich X/Y zentriert am bildschirm dargestellt
das ist unabhängig vom wert, sobald ich Y umsetze ist der text mittig :'(
olqDisplaySpeech = character[CharID].SayBackground(buf);
if(olqDisplaySpeech.Y < gBorder.Height)
olqDisplaySpeech.Y = gBorder.Height;
hat jemand eine idee wie ich ein hintergrundgespräch machen kann, dass auch immer sichtbar ist?
-
Der schwarze Rand wird durch ein GUI namens "border" oder so ähnlich erzeugt; schalt es doch mal versuchsweise ab, während der Overlay sichtbar ist.
-
hat sich erledigt :D
der character der spricht, ist immer an der selben position und leerzeichen am anfang des sprachtextes werden ebenfalls dargestellt :)
ich hab jetzt einfach statt
"Nein danke."
" Nein danke."
geschrieben
jetzt sind die leerzeichen im nicht sichtbaren bereich, der automatische zeilenumbruch erledigt den rest ;)
-
ich mal wieder zum alten thema ;D
hab ich eigentlich irgendwie die möglichkeit auf die tatsächlichen delay-werte des characters zu kommen, die bei der speechview verwendet werden?
qDisplaySpeech verwendet ja bei AnimateCharacterEx character[CharID].animspeed als delay, was aber nix mit der speechview zu tun hat :o
character[CharID].animspeed ist bei fast allen chars nämlich 2, was viel zu schnell für die speechview ist und scheinbar auch nur beim laufen verwendet wird
bei einem normalen char.say wird ungefähr 5 verwendet, ich weiß aber nicht woher dieser wert kommt ???
-
qDisplaySpeech verwendet den normalen Anim-Speed, weil der Charater einfach animiert wird und daher seinen alten Delay behält. Der Delay 5 beim Speechview ist Standart(und ehrlich gesagt hab ich keine Ahnung wie mans ändern könnte)
-
naja, ich hab das jetzt mal auf fix 5 geändert und gut ist
qDisplaySpeech ist sowieso nur bedingt einsetzbar, denn sobald man zb unterschiedliche chars in unterschiedlichen räumen reden lassen will, klappt das nicht mehr so ganz ::)
war schon einiges an arbeit, das richtig zum laufen zu bringen
-
5 ist die Grundeinstellung, da game.talkanim_speed diesen Wert hat.
qDisplaySpeech ist dafür gedacht, im Hintergrund ein Gespräch laufen zu lassen; dass das in verschiedenen Räumen nicht automatisch perfekt klappt, wundert mich nicht.
-
Jessas! :D
Das ist doch bereits alles eingebaut...
qDisplaySpeech(int CharID, string message);
Also bspw.
// player enters room (after fadein)
qDisplaySpeech(cPassant1.ID, "Na, alles klar?);
qDisplaySpeech(cPassant2.ID, "Freilich. Bei Dir?");
...
(Nicht getestet!)
Kann man in so einen Hintergrund-Dialog auch Sounds integrieren? Gibts dafür nen Code?
-
Du köntest ja die qDisplaySpeech-Funktionen entsprechendend ändern.
-
Gibt es eine Möglichkeit, eine bereits angefangene Unterhaltung abzubrechen? Z.B. wenn sie aufgrund einer Aktion auf einmal anders verlaufen muss oder man die Charaktere anspricht?