Maniac Mansion Mania Forum

MMM-Werkzeugkiste => Technik => Thema gestartet von: Private am 12. Mai 2012, 19:06:50

Titel: Privates Fragethread
Beitrag von: Private am 12. Mai 2012, 19:06:50
Hallo, bin neu hier und habe beim Durchsuchen der bisherigen Beiträge keine Lösung für mein Problem gefunden.

Genutzt wird das aktuelle Starterpack Bernard für das aktuelle AGS 3.2?

Ich möchte, dass mein Spielercharakter im Bett liegt und im Schlaf redet. Die Bilder dazu habe ich bereits erstellt und ins Spiel geladen.

Wie kann ich bei
player.Say("...");

die Sprachanimation starten, die ich als Loop 4 in den BernardT-Ordner eingefügt habe? Das wäre die Animation, die er machen soll, wenn er in dieser Liegeposition ist.

im Global Skript muss es doch irgendwo definiert sein, dass beim Sprechen diese oder jene Sprachanimation abhängig von der jeweiligen Befindlichkeit des Charakters abgespielt werden soll. Meinetwegen schaut der Charakter nach rechts, also soll beim Sprechen der entsprechende Loop abgespielt werden.

Hoffentlich könnt Ihr mir helfen.

EDIT: Zu Beginn von Episode MMM04 liegt Hoagie auf Bernards Bett und spricht. Es muss also wenigstens ein Person wissen, wie das geht, was ich machen möchte.

EDIT: so, einen befehl habe ich schon mal gefunden:
player.LockViewFrame(9, 6, 0);
Damit bekomme ich schon mal den Charakter zum liegen, ohne dass ich das über den Animationsbefehl mache, wie ich es vorher hatte.

Jetzt fehlt nur noch das mit dem Loop für das Sprechen im Liegen.

EDIT: ok, habe es selbst herausgefunden. offenbar reichte es, dass ich den loop fürs quatschen auf die selbe zahl lege wie den loop im bewegungsbereich des charakters.
Titel: Re: Privates Fragethread
Beitrag von: Private am 13. Mai 2012, 14:50:32
Nächstes Problem: In einer Cutscene stoppt bei mir plötzlich die Hintergrund-Musik. Ich weiß nicht, warum das geschieht, und auch nicht, wie ich das Problem beheben kann.

Hier das Skript:
function room_Load()
{
  SetBackgroundFrame(2);
  aMusic5.Play();
  Door[eTuerBernardsZimmer].Init(oTuer01, hTuer01);
  oPerpetuumMobile.SetView(56, 0, 0);
  oPerpetuumMobile.Animate(0, 7, eRepeat, eNoBlock);
  oComputer.SetView(57, 0, 0);
  oComputer.Animate(0, 9, eRepeat, eNoBlock);
}

function room_FirstLoad()
{
StartCutscene (eSkipESCOrRightButton);
StopMusic();
aMusic10.Play(eAudioPriorityVeryHigh);
SetBackgroundFrame(1);
object[7].Visible = true;
object[6].Visible = true;
object[1].Visible = true;
player.PlaceCharacter(210, 112, eDirUp);
player.LockViewFrame(9, 6, 0);
player.Transparency = 0;
Wait(100);
player.Say("Tun Sie es nicht, Herr Koslowski. Das dürfen Sie nicht.");
player.Say("Sie können mich der Schule nicht verweisen.");
player.Say("Nicht wegen Sport.");

object[8].Visible = true;
aSound2.Play();
Wait(30);
cBerno.EnterRoom(5, -30, 135, eDirRight);
cBerno.Walk(30, 135, eBlock, eAnywhere);
Wait(50);
cBerno.Say("Endlich.");
cBerno.Say("Bernard, da musst du jetzt durch.");
cBerno.Walk(190, 135, eBlock, eWalkableAreas);

object[8].Visible = false;
object[7].Visible = false;
object[6].Visible = false;
object[1].Visible = false;
EndCutscene();
player.PlaceCharacter(230, 140, eDirLeft);
}
Beim ersten Satz, den Bernard spricht, ist die Hintergrundmusik bereits nicht mehr zu hören.

EDIT: Problem solved. Ich hatte in einer vorigen Cutscene ein Musikstück laufen, und dadurch, dass es nicht gestoppt wurde, hat sich vermutlich irgendwas verhakt. So langsam lässt sich in das System einfinden, obwohl es mir nicht benutzerfreundlich genug ist für Laien wie mich, die nicht viel mit der Programmiersprache am Hut haben.
Titel: Re: Privates Fragethread
Beitrag von: Private am 13. Mai 2012, 20:37:18
Auch in der Gefahr, es wieder selbst irgendwo herauszufinden, gebe ich bei der Suche nach Hilfe in diesem Forum noch nicht auf:

Ich möchte bei diesem Befehl
DisplayTopBar(1, 8, 7, "Erzaehler", "Bernards Haus");einen Sound abspielen.

Lieber hätte ich zwar, dass die Buchstaben nach und nach einzeln auftauchen, aber erstmal gebe ich mich damit zufrieden.

Bisher gelingt es mir nur, den Sound vorher oder nachher abzuspielen.

EDIT: Als gelernter Autodidakt (den Witz versteht nicht jeder) habe ich es jetzt nicht sehr elegant hierüber gelöst.

if (aSound23.Play()) {
  DisplayTopBar(180, 8, 8, "Erzaehler", "Bernards Haus");
  }
Zuvor habe ich aber die Textgeschwindigkeit ändern müssen.
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 13. Mai 2012, 21:56:26
Hast Du es denn mal so versucht:
[ags]  aSound23.Play();
  DisplayTopBar(180, 8, 8, "Erzaehler", "Bernards Haus");[/ags]

Sounds sind nicht blocking, das sollte eigentlich so klappen (und Dein Code macht unterm Strich nichts anderes).

Und AGS skripten ist Dir nicht benutzerfreundlich genug...? Sorry, einfacher wird es nicht (und geht es auch kaum).
Titel: Re: Privates Fragethread
Beitrag von: Private am 13. Mai 2012, 23:07:19
danke für die rückmeldung, ja das habe ich versucht, aber das stimmte nicht ganz überein, mittlerweile bin ich mit dem ergebnis zufrieden, ärgere mich aber, dass ich zu wenig ahnung von dem ganzen habe. ich kann ja ende der nächsten woche eine art demo meiner idee posten, falls das jemanden interessiert. zunächst einmal mache ich das ganze, weil ich lust drauf habe und es für mich machen möchte. am ende kann ich es aber zur freien verfügung stellen. die story, oder besser: der rahmen für den plot, steht ja noch nicht mal zu 100%, es wird wie alles bei mir im prozess entwickelt.

spätestens bei den rätseln werde ich vermutlich einige hürden nehmen müssen.
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 13. Mai 2012, 23:35:11
Hier ist noch keiner in ein paar Tagen vom Anfänger zum Supercoder geworden. Wenn Du Dich jetzt schon ärgerst...

Und gib dem Forum hier ruhig etwas mehr Zeit; wenn Du die Antwort auf Deine Fragen immer selbst parat hast, heißt das nicht, dass wir anderen langsam oder schreibfaul sind, sondern eigentlich nur, dass Du hier voreilig postest... ;)
Neue Spielemacher sind hier aber immer herzlich willkommen; wenn Du Dein Projekt durchziehst und einen Betatest machen lässt, kann eigentlich nicht viel schief gehen.

Falls Du Rückmeldungen zu Deiner Story, Deinen Grafiken o.Ä. willst und schon was entsprechendes vorzuweisen hast, mach Doch hier einen Thread auf: http://www.maniac-mansion-mania.de/forum/index.php?board=9.0

Wegen dem Schreibmaschinen-Stil für Bildschirmtext: solche Sachen muss man i.d.R. selbst coden oder ein entsprechendes Modul nutzen.
Titel: Re: Privates Fragethread
Beitrag von: Private am 14. Mai 2012, 13:37:34
Nächste Frage:
Wie kann ich Folgendes richtig skripten?

Ich möchte, dass in einem Raum je nach Charakter ein anderer Inhalt des "function room_AfterFadeIn()" abgerufen wird.

Versucht habe ich
if (player = cBerno) {
else (player = cBernard) {}
}
Aber das hat es nicht gebracht.

Alternativ kann ich natürlich einfach einen neuen Raum erstellen, was ich aber eigentlich nicht will. Bislang habe ich die Räume des Starterpacks um ein Nachtframe als Background erweitert.
Titel: Re: Privates Fragethread
Beitrag von: Bòógieman am 14. Mai 2012, 13:47:14
zum vergleichen musst du == statt = machen

if (player == cBerno) {
else (player == cBernard) {}
}
Titel: Re: Privates Fragethread
Beitrag von: Fatal B am 14. Mai 2012, 13:56:12
Oder du benutzt Variablen .

zB:

[ags]if (GetGlobalInt(326)==0)  {  //Hier wird die Variable gesetzt

cBernard.Say("Das Zimmer ist dunkel.");

SetGlobalInt(326,1);  }  // Hier wird die Variable von 0 auf 1 gesetzt

else if (GetGlobalInt(326)==1)  {  // Hier wird jetzt beim zweiten Raumbetreten diese Variable abgespielt

cBernard.Say("Das Zimmer jetzt hell.");

SetGlobalInt(326,2);  }  // Und hier wird wieder die Variable um 1 erhöht usw...[/ags]

Hoffe du versteht es wie ich es meine, bin kein guter Erklärer. :o
Titel: Re: Privates Fragethread
Beitrag von: Private am 14. Mai 2012, 14:09:29
ha! danke euch beiden, die doppelten gleichheitszeichen haben es gebracht, und den anderen code werde ich für später im hinterkopf behalten.
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 15. Mai 2012, 01:40:25
Der Code muss so aussehen:
[ags]  if (player == cBerno) {
    ...
  }
  else if (player == cBernard) {
    ...
  }
  else {
    ...
  }[/ags]

Und die Verwendung von GetGlobalInt und SetGlobalInt wird mit nicht unter fünf Gnackwatschn bestraft... ;)
Ernsthaft, wir haben nicht mehr 2004.
Titel: Re: Privates Fragethread
Beitrag von: Fatal B am 15. Mai 2012, 23:51:03
(http://img716.imageshack.us/img716/4986/einherz12.png) (http://imageshack.us/photo/my-images/716/einherz12.png/)
 ;D

Titel: Re: Privates Fragethread
Beitrag von: Private am 16. Mai 2012, 18:16:12
Irgendwie klappt es heute nicht so gut:
Ich möchte, dass die Spielerfigur in den geöffneten Briefkasten schaut und daraus einen Umschlag (addinventory) erhält.

Beim zweiten Anschauen soll die Figur einfach nur sagen, dass da nichts weiter drin ist.

Mein fehlgeschlagener Versuch:
else if (UsedAction(eActLookAt) == 1)
{
Wait(5);
player.Say("Oh, ein Briefumschlag.");
        player.AddInventory(iBriefumschlag);
}
    else if (UsedAction(eActLookAt) == 2)
    {
      Wait(5);
      player.Say("Leer.");
    }    

EDIT: Ich glaube, ich habe hier was Nützliches gefunden:
http://www.adventuregamestudio.co.uk/wiki/?title=MultiResponse

Werde es gleich mal ausprobieren.

EDIT2:Ok, ich bin zu blöd. Wie bekomme ich die
MultiResponse.scm
Datei ins Spiel integriert?

EDIT3:
Gut, ich habe es dann doch geschafft. Für alle Dummies wie mich:
Eine scm-Datei wird in AGS integriert, indem man im Baumdiagramm auf der rechten Seite bei den Scripts die rechte Maustaste drückt und dann "Import Script" anklickt. Wo man die Datei gespeichert hat, sollte man eigentlich wissen.
Titel: Re: Privates Fragethread
Beitrag von: Endres am 16. Mai 2012, 18:59:32
Nein, MultiResponse brauchst du für sowas nicht. Dein Ansatz mit ifs ist schon gar nicht so schlecht.
Weil sonst kriegst du das mit dem Inventar nicht mehr so richtig da rein. Auch falls du mal was anderes machen willst.

allerdings musst du auch dies mit Variablen / GlobalInts machen.

[ags]    else if (UsedAction(eActLookAt))
    {
        Wait(5);
        if (iUmschlagWeg == 0)
        {
            iUmschlagWeg = 1;
       player.Say("Oh, ein Briefumschlag.");
            player.AddInventory(iBriefumschlag);
        }
        else
        {
            player.Say("Leer.");
        }
    }[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Private am 16. Mai 2012, 19:08:24
Danke Dir. Ich habe es jetzt so gelöst, und es klappt. Ich wollte nicht extra mit Global Ints arbeiten müssen, aber irgendwann werde ich das wohl nicht mehr vermeiden können:

else if (UsedAction(eActLookAt))
{
Wait(5);
int state=Multi.Say("Oh, ein Briefumschlag.>Leer.>Immer noch leer.");
      if (state==1) player.Animate(14, 3, eOnce, eBlock, eForwards);
      if (state==1) aSound25.Play();
      if (state==1) player.AddInventory(iBriefumschlag);
}

Mit dem Multi-Response-Script läuft das einwandfrei.
Titel: Re: Privates Fragethread
Beitrag von: Endres am 17. Mai 2012, 00:32:04
Hehe, ob du es glaubst oder nicht, aber mit dem Multi-Response hast du dann statt einer sogar zwei Variablen. ;)
Titel: Re: Privates Fragethread
Beitrag von: Private am 17. Mai 2012, 00:56:09
@Endres
Keine Sorge, ich bin gutgläubig, ich glaube Dir das schon.

so, feierabend für heute. komme mir vor, wie im studium der theoretischen philosophie. der erste beweis, der gelingt, verschafft unheimliche glücksgefühle. und dann, wenn man nicht weiter kommt, stellt sich ein vollkommen gegensätzliches gefühl ein.

nun stehe ich vor dem problem, dass mir einfach nicht einleuchten will, warum das mit dem inventar nicht klappt, wie ich es will.

1. ich möchte inventar a mit inventar b benutzen, und zwar wechselseitig.
das klappt auch, aber nur, wenn ich mit der linken maustaste zuerst jeweils den einen inventargegenstand anklicke und dann den anderen.
sobald ich aber den "benutze" butten anklicke und dann auf den inventargegenstand klicke, egal ob a oder b, so will das programm plötzlich nur noch einen "benutze"- und keinen "benutze-mit" befehl ausführen.

Beispiel: Ich habe einen Briefumschlag und möchte ihn mit einem Skalpell öffnen.
Sobald ich aber den Event "Use Inventory on this Item" verwende und dort mit "player.ActiveInventory = iItemxy" auswähle, was auf den jeweiligen gegenstand angewendet werden kann, erzeuge ich obiges Problem. Ich kann mit der linken Maustaste im Inventar die Gegenstände miteinander kombinieren, aber eben nicht durch "Benutze" + "Skalpell" mit "Briefumschlag", weil er ja nur "Benutze" versucht und kein "Benutze-mit", warum auch immer das versperrt ist, kann ich mir nicht erklären. jedenfalls wäre das spiel so aus meiner sicht nicht spielbar.

Mit dem Event "Other click on inventory item" habe ich es leider auch nicht hinbekommen.

2. dann suche ich verzweifelt ein tutorial, das gerade diese dinge klärt:
Benutze Inventar mit Inventar
Benutze Inventar mit Hotspot
Benutze Inventar mit Objekt
(in diesem Forum findet man wenigstens in einem Tutorial eine Formel, mit der man Gegenstände an andere Charaktere geben kann.)

3. Habe mir nochmal das Tutorial angeschaut und dort das gefunden:
if(UsedAction(eActUse)) {
Wait(5);
player.Say("Vielleicht woanders.");
}
else if(player.ActiveInventory==iUSBStick) {
Wait(5);
player.Say("Ich stecke den Stick mal rein...");
}
else Unhandled_Inventory();
Das, was hier mit dem USB-Stick angedacht ist, funktioniert einfach nicht. Das kann man knicken und es sollte vlt. das Tutorial dahingehend geändert werden.
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 17. Mai 2012, 14:06:37
Nochmal bzgl. des Briefumschlags:
else if (UsedAction(eActLookAt))
{
Wait(5);
int state=Multi.Say("Oh, ein Briefumschlag.>Leer.>Immer noch leer.");
      if (state==1) player.Animate(14, 3, eOnce, eBlock, eForwards);
      if (state==1) aSound25.Play();
      if (state==1) player.AddInventory(iBriefumschlag);
}
Die drei Zeilen mit if (state == 1) kann man zu einem Block zusammenfassen:
[ags]      if (state==1) {
        player.Animate(14, 3, eOnce, eBlock, eForwards);
        aSound25.Play();
        player.AddInventory(iBriefumschlag);
      }[/ags]

Das Multiresponse-Modul ist ne feine Sache, es gibt aber eine eingebaute Funktion in AGS, die zumindest zwei states zulässt:
[ags]      if (Game.DoOnceOnly("Briefkasten-Check")) {
        player.Say("Oh, ein Briefumschlag!");
        player.Animate(14, 3, eOnce, eBlock, eForwards);
        aSound25.Play();
        player.AddInventory(iBriefumschlag);
      }
      else player.Say("Er ist leer.");[/ags]
Den Text, der als Parameter übergeben wird, kannst Du beliebig wählen, er muss nur jeweils eindeutig sein. Damit kann man praktischerweise auch den gleichen Check an zwei verschiedenen Stellen im Code durchführen, indem man einfach bei beiden den selben Text verwendet.

So kann man zumindest vermeiden, wegen jedem Pups ne Raum- oder globale Variable einzuführen.

Wegen des Benutzens zweier Inventargegenstände:
Eigentlich sollte ein Inventargegenstand bei angewähltem "Benutze" nur sofort allein benutzt werden, wenn am Ende ein ">u" hängt.
Ich hab das mal mit dem ManiacMansion-Starterpack getestet.
Damit ein Inventargegenstand nicht auswählbar ist, sondern sofort benutzt wird, muss erstens ein ">u" am Namen hängen, zweitens muss eine Funktion bei "Interact with item" verlinkt sein, und drittens muss "Gehe zu" oder "Nimm" das aktive Verb sein.
Die ersten beiden Kriterien kannst Du ganz leicht ändern.

Als nächstes solltest Du bei "Use inventory on item" Folgendes eintragen:
[ags]function iBriefumschlag_UseInv()
{
  if (player.ActiveInventory == iSkalpell) brief_oeffnen();
  else Unhandled_Inventory();
}

function iSkalpell_UseInv()
{
  if (player.ActiveInventory == iBriefumschlag) brief_oeffnen();
  else Unhandled_Inventory();
}[/ags]

Über(!) diese beiden Funktionen setzt Du nun:
[ags]function brief_oeffnen() {
  ...
}[/ags]
Und schreibst dort rein, was passiert, wenn man das Skalpell mit dem Umschlag oder umgekehrt benutzt.

Einen Inventargegenstand mit einem Objekt oder Hotspot zu benutzen, funktioniert so:
Du legst für den Hotspot die "Any click on" funktion an, und dann setzt Du Folgendes rein:
[ags]function hBaum_AnyClick()
{
  if (UsedAction(eActLookAt)) {
    player.FaceLocation(176, 130);
    Wait(5);
    player.Say("Nur ein Baum.");
    return; // jetzt aussteigen
  }
  if (MovePlayer(176, 155) == 2) {
    player.FaceDirection(eDirUp);
    Wait(5);
    if (UsedAction(eActUseInventory)) {
      if (player.ActiveInventory == iTaschenlampeOn) {
        player.Say("Ich leuchte mal in den Baum.");
      }
      // else if (UsedAction()) { }   // hier andere Verben
      else Unhandled();
    }
    else Unhandled();
  }
  else player.Say("Ich komme nicht ran.");
}[/ags]

Hier lasse ich bei "Schau an" den Charakter nicht hinlaufen, d.h. er kann sich den Baum auch von der Ferne ansehen, falls er z.B. gerade nicht erreichbar ist. Soll er statt dessen genauer untersucht werden, setze ich den if (UsedAction(eActLookAt))-Block mit rein zu den anderen Verben.

MovePlayer liefert nur 2 zurück, wenn der Charakter auch tatsächlich bei den Koordinaten angekommen ist. Deswegen sollte man immer diesen == 2 Check machen.
Als nächstes lässt man den Charakter in die richtige Richtung schauen, dann überprüft man die Aktion, in diesem Fall muss also eActUseInventory verwendet werden. Am Ende überprüft man das verwendete Item.
Die Unhandled()s sind wichtig, damit das Spiel korrekt reagiert, falls eine andere Aktion oder ein anderes Item verwendet wurde.

Übrigens wirst Du auf Dauer nicht um globale oder zumindest Raumvariablen herumkommen; wie anders soll Dein Spiel wissen, wann der Spieler Fortschritte bei den Rätseln gemacht hat?
Ein paar Schlauköpfe haben das teilweise mit unsichtbaren Inventory Items und ähnlichen Späßen versucht, aber bitte begib Dich nicht auf derartige Irrwege.
Titel: Re: Privates Fragethread
Beitrag von: Private am 17. Mai 2012, 14:30:45
zum letzten Punkt. oha, nicht dass ich da schon auf den irrweg geraten bin. vielen dank für die einführenden hinweise.

habe das problem mit dem benutzen auch hier im forum gefunden:
http://www.maniac-mansion-mania.de/forum/index.php?topic=1994.0

den tipps dort bin ich gefolgt und es funktionierte, aber nicht für lange ... denn sobald ich dann den inventargegenstand nochmals benutzt habe, ging danach die "Benutze mit"-Funktion nicht mehr.

Meine vorläufige Lösung:
function iGummiballRepLeer_UseInv() {
if (player.ActiveInventory==iSkalpell) {
  int state=Multi.Say("Nein.>Niemals!");
  if (state==1) {
  player.Say("Zuerst biete ich all meine psychische und physische Kraft auf, um den Ball in einen intakten Zustand zu versetzen.");
  player.Say("Und jetzt soll ich mein legendäres Tagwerk wieder vernichten?");
  }
  player.ActiveInventory = null;
  }
else Unhandled_Inventory();
}
Also, ich habe bei jedem "UseInv" die Zeile "player.ActiveInventory = null;" eingefügt. Es funktionierte, ich war froh, aber stieß dann sogleich auf das nächste problem in diesem zusammenhang:
Ich verwendete das Skalpell mit dem Garagentor, worauf der "Benutze-mit"-Befehl wieder blockiert oder weg war, so dass nur noch ein "Benutze" ging.
Als nächstes probiere ich aus, ob ich nicht bei den Hotspots und Objekten auch noch
"player.ActiveInventory = null;" einfügen muss, um das Problem zu vermeiden.

EDIT: Ha, es war erfolgreich. Dank Deines Hinweises wusste ich nun auch, wo genau ich das bei den Hotspots einzutragen habe. Es ist zwar etwas umständlich, aber solange die Funktionalität gewährleistet wird, ist es in Ordnung.
Titel: Re: Privates Fragethread
Beitrag von: Private am 17. Mai 2012, 16:47:33
Jetzt habe ich den Salat.

Ich wollte einen Inventargegenstand erstellen, den man direkt mit "Benutze" verwenden kann. Und nun geht das nicht mehr.

Habe extra bei Description ">u" dahinter geschrieben.

EDIT: Ich werde jetzt erstmal alles rückgängig machen, was ich im Global Script geändert habe. Mal sehen, ob dann was geht.

Welches neuere Starterpack funktioniert denn einwandfrei? Vielleicht könnte ich einfach die Definitionen übernehmen. Dann müsste doch das mit dem "Benutze" und "Benutze-mit" auch wieder richtig gehen.

EDIT2:
nächste Frage:
Ich möchte eine Tür mit einem Schlüssel aufschließen und dann verwenden.

Was muss ich dazu im Door-Skript ändern?

EDIT3:Problem solved. Im Door-Skript habe ich die Tür in der Garage entdeckt, dort stand Global Int = 2.
Habe ich gleich auf meine Tür übertragen und im Room-Skript der Garage auch den entsprechenden Befehl
if(Door[eTuerGarage].ClickSpecial(2, 3, iSchluessel, 0) == 0 ) Unhandled();gefunden.
Jetzt klappt es, aber irgendwie wollte ich eigentlich noch ein Türrüttelsound einbauen, wenn jemand versucht die Tür zu öffnen, zu drücken oder zu ziehen, obwohl Sie geschlossen ist. Das müsste ich ja eigentlich dann auch in das Türenskript schreiben können.
Titel: Re: Privates Fragethread
Beitrag von: Private am 18. Mai 2012, 19:14:33
Wie kann ich die Musiklautstärke ändern?
SetMusicVolume(-3);oder
SetMusicMasterVolume(0);hat beides keinen Effekt.
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 19. Mai 2012, 10:30:50
Probier es mal so:

[ags]  AudioChannel*ac = aMusik.Play();
  ac.Volume = 50;  // 0 - 100[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Rocco am 19. Mai 2012, 13:18:35
Wie kann ich die Musiklautstärke ändern?
SetMusicVolume(-3);oder
SetMusicMasterVolume(0);hat beides keinen Effekt.

Diese Befehle sind veraltet.
Für die Slider im OptionsGui:
[ags]function sldMusic_OnChange(GUIControl *control)
{
  //System.Volume = sldMusic.Value;
  Game.SetAudioTypeVolume(eAudioTypeMusic, sldMusic.Value, eVolExistingAndFuture);

}

function sldSound_OnChange(GUIControl *control)
{
  // This sets the sound volume. Note it'll also affect MOD and XM music - read the manual
  Game.SetAudioTypeVolume(eAudioTypeSound, sldSound.Value, eVolExistingAndFuture);
}[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Private am 19. Mai 2012, 14:56:23
offenbar kann ich das nicht im roomskript eingeben. jedenfalls führte das zu keiner änderung.
Titel: Re: Privates Fragethread
Beitrag von: Rocco am 19. Mai 2012, 14:59:34

Der Wert in der Mitte ist die Lautstärke.
Das ist der Befehl auf den es ankommt.

[ags]  Game.SetAudioTypeVolume(eAudioTypeMusic,50, eVolExistingAndFuture);[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Private am 19. Mai 2012, 17:45:33
habs versucht, hat nicht geklappt, die musik ist immer noch viel zu laut und lässt sich durch den befehl nicht regeln.

es ist das stück

aMusic26

im neuesten Bernard-Starterpack.

oder liegt es daran, dass ich windows 7 64bit verwende?
Titel: Re: Privates Fragethread
Beitrag von: Rocco am 20. Mai 2012, 10:09:45
seltsam, also an win7 64bit liegts nicht.
wäre ja abstrus wenn sich die lautstärke auf einem win7 32 bit ändern liesse,
aber auf einem 64bit system nicht.

wenn es nur um das eine Musikstück geht,
dann such dir das file unter audio -> music und stell die DefaultVolume ein.
Vielleicht klappts so.  :cl
   
Titel: Re: Privates Fragethread
Beitrag von: Private am 20. Mai 2012, 13:17:40
aber klar, dabei hatte ich die funktion doch schon vorher bemerkt, danke rocco.
Titel: Re: Privates Fragethread
Beitrag von: Private am 20. Mai 2012, 19:01:53
nächste Frage:
Ich habe einen Dialog geschrieben und wollte, dass im Anschluss daran einige Dinge geschehen.

Nun zieht das Programm diese Handlungen vor und spielt anschließend den Dialog ab.

Gibt es eine Möglichkeit, dass ich erst den Dialog abspielen kann und danach die anderen Sachen beginnen?

Ich könnte mir sowas mit einem Blockingbefehl vorstellen.

EDIT: Das Problem zerstört mir jetzt irgendwie alles.

Wenn ich im Dialog einen Charakter ausblende, den Raum ausblende und dann den Charakter einen anderen Raum betreten lasse, kann ich dort in dem anderen Raum den Charakter nicht wieder einblenden. Das ist nervig.
Wenn ich versuche, es nach dem Dialog zu machen, dann werden Handlungen vor dem Dialog vollzogen und nicht danach, wie es sein sollte. Und das Spiel stürzt anschließend ab.

im Dialog:
Wait(40);
cBerno.Animate(27, 5, eOnce, eBlock, eForwards);
int trans;
while (trans < 100) {
   trans++;
   player.Transparency = trans;
   Wait(1);
   aSound28.Play();
 }
Wait(40);
cBerno.FaceDirection(eDirDown);
cBerno.Say("Ich hätte ihn wirklich umbringen sollen.");
StopMusic();
FadeOut(1);
player.EnterRoom(23, 140, 110, eDirLeft);
Wait(50);
stop
}

Und dann im neuen Raum:
function room_FirstLoad()
{
aMusic11.Play();
Wait(60);
 int trans;
 while (trans > 0) {
    trans--;
    player.Transparency = trans;
    aSound28.Play();
    Wait(1);
  }
player.Say("Was zum ...");
}

Aber die Figur wird leider nicht eingeblendet, wie ich es will. Ich weiß nicht, woran es liegt, aber wenn ich das so nicht hinbekomme, weiß ich nicht, wie ich die Handlung des Spiels sinnvoll umschreiben soll. Lasse ich den Dialog weg, ist die Unterredung zwischen zwei Figuren zu langatmig und schließt den Spieler hinter dem Bildschirm aus. Behalte ich ihn, habe ich im neuen Raum eine unsichtbare Figur.
Titel: Re: Privates Fragethread
Beitrag von: Private am 20. Mai 2012, 23:59:19
habe es jetzt etwas unschön gelöst bekommen
function room_FirstLoad()
{
aMusic11.Play();
Wait(60);
 int transo;
 while (transo < 100) {
    transo++;
    player.Transparency = transo;
  }
 while (transo > 0) {
    transo--;
    player.Transparency = transo;
    Wait(1);
    aSound28.Play();
  }
player.Say("Was zum ...?");
Wait(30);

Wait(30);
}

warum nur funktioniert das jetzt, indem ich den charakter nach einem ausblendeprozess nochmal im neuen raum ausblende?
Titel: Re: Privates Fragethread
Beitrag von: Endres am 21. Mai 2012, 00:21:49
Nun, weil durch int transo; die Variable transo den Wert 0 zugewiesen bekommt. Du willst aber von 100 auf 0 herunterzählen, darum musst du der Variable auch erstmal wieder 100 zuweisen. Also:
[ags]int transo = 100;
while (transo > 0) { ... }[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Private am 21. Mai 2012, 00:34:25
sauber, hat geklappt. jetzt kann ich den prolog fertig stellen und irgendwo hochladen und hier im forum posten und dann erstmal pausieren. habe noch andere dinge zu erledigen, die mir nicht als sinnlose zeitverschwendung vorgeworfen werden. in etwa einem monat mache ich dann weiter und habe bestimmt weitere fragen.
Titel: Re: Privates Fragethread
Beitrag von: Rocco am 21. Mai 2012, 09:28:33
weil du die variable transo nicht definiert hast.

du kannst nicht schreiben:
[ags]
int transo;   // transo hat keinen wert und ist somit null
 while (transo > 0) {   // Bedingung ist nie erfüllt, deswegen wird die Schleife nie durchlaufen
    transo--;
    player.Transparency = transo;
    Wait(1);
    aSound28.Play();     // das hier ist auch nicht ratsam, damit startest du den Sound, wenn die Schleife läuft alle paar millisekunden neu.
  }
[/ags]

So hätte es wahrscheinlich funktioniert:
[ags]
int transo = 100;

while (transo > 0) {  
    transo--;
    player.Transparency = transo;
    Wait(1);

    if(!Game.IsAudioPlaying(eAudioTypeSound))
       aSound28.Play();
  }

[/ags]


oha, hat endres schon lange beantwortet, egal doppelt hält besser....
Titel: Re: Privates Fragethread
Beitrag von: KhrisMUC am 21. Mai 2012, 11:51:26
Bezüglich erst Dialog, dann andere Befehle:

Dialog.Start() wird, wie auch in der Hilfedatei beschrieben, nicht sofort ausgeführt, sondern erst am Ende der Funktion.
Wenn Du also nach Ende des Dialoges Befehle ausführen willst, schreib sie direkt ins Dialogskript, vor den "stop"-Befehl. Man kann nämlich in Dialogen auch herkömmliche Skriptbefehle verwenden, man muss nur mindestens ein Leerzeichen an den Anfang der Zeile setzen.

Falls die Befehle an mehreren Stellen ausgeführt werden sollen, schreib sie in eine Funktion im GlobalScript und ruf die vom Dialog aus auf:

[ags]// in GlobalScript.asc

function Dialog1_Ende() {
  player.Walk(240, 176);
  player.Say("bla");
  object[3].Visible = false;
}


// Dialogskript

...
@2
player: Alles klar.
 Dialog1_Ende();
stop
@3
player: Na gut, dann werd ich das tun.
 Dialog1_Ende();
stop[/ags]
Titel: Re: Privates Fragethread
Beitrag von: Private am 15. Dezember 2012, 17:29:58
Hallo,

ist es möglich, ein kompiliertes Spiel wieder zu dekompilieren? Wenn das nicht möglich ist, dürfte mein Projekt gestorben sein. Mein Computer ist vor einigen Monaten abgeraucht und meine Sicherungskopie von AGS war ziemlich alt.

Gruß
Priv
Titel: Re: Privates Fragethread
Beitrag von: Cone Arex am 15. Dezember 2012, 18:10:25
Nein, das ist leider nicht möglich.