Hallo.
Ich wollte dem Startbildschirm (Room 1) ein Event namens "After_fade_in()" hinzufügen, bekomme aber nur folgende Fehlermeldung:
Room room1.crm was saved, but there were warnings; details below
room1.asc: Function "room_AfterFadeIn" looks like an event handler, but is not linked on Room 1's Event pane
Was muss ich denn genau machen, um diesen Fehler zu beheben, denn ich möchte gerne ein After_Fade_In hinzufügen.
Danke schon mal im Voraus.
BG
der Volltanker
Mit dem Fade_in hat sich schon erledigt. ;)
Dafür habe ich ein anderes Problem.
Wie ist der richtige Syntax, wenn ich der Zeile...
aMoH_Main_Theme.Play();
...einen Loop hinzufügen möchte?
BG
der Volltanker
Quelle: https://adventuregamestudio.github.io/ags-manual/v3/AudioClip.html#audioclipplay (https://adventuregamestudio.github.io/ags-manual/v3/AudioClip.html#audioclipplay)
Ohne Gewähr, ich habe das alles noch nie gemacht:
AudioChannel* musicChannel = aMoH_Main_Theme.Play(eAudioPriorityNormal, eRepeat);
und zum Stoppen
musicChannel.Stop();
Besten Dank!
Ja, das hat geklappt. Super.
Der Syntax in 3.6.2. hat sich doch teilweise geändert. Andererseits bin ich auch schon etwas raus und muss mich da wieder reinfuchsen.
BG
der Volltanker
Beim Ausprobieren des Maniacweed-Starterpaks war mir aufgefallen, dass dieses Starterpak noch kein Licht-an--Licht-aus-Effekt beinhaltet.
Bernard schaltet den Lichtschalter im Keller nicht um, sondern sagt nur "Dann stehe ich hier im Dunkeln".
Wäre es bei diesem Starterpak schwer, diesen Effekt mit einzubauen, dass der Raum jeweils einmal hell und einmal dunkel dargestellt wird?
Wie wäre das denn machbar, einen Raum schlicht zu verdunkeln und bei Lichtquelle den Raum wieder hell zu machen?
Danke schon mal im Voraus.
BG
der Volltanker
Das ist noch nicht zu Ende gedacht, weil man noch Infos zum jeweiligen Raum braucht, ob das Licht beim Betreten des Raums ein- oder ausgeschaltet war PLUS natürlich beim Verlassen des Raums das GUI wieder zu deakivieren, aber das folgende hat in meinem Tutorial Script (Das Tutorial zu Foxy's Quest) funktioniert:
1. Ein neues GUI angelegen, in meinem Fall habe ich es gDarkness genannt, Background und BorderColor 8,8,8 (schwarz), Transparency 100, Height und Width auf die Größe des Bereichs, den man mit dem GUI verdecken bzw. abdunkeln möchte (Im Falle des Foxy's Quest Tutorials ist das Height=186, Top=14, Width=320) und wichtig: Clickable auf FALSE stellen.
2. Ein und Ausblenden des GUI's an der passenden Action festmachen, ich habe der Einfachheit halber die vorhandene Look Action genommen
Der Teil mit dem sanfteren Aus- und Einblenden ist natürlich optional und man kann stattdessen einfach das Visible Attribut hart auf den gewünschten Transparenzwert umschalten.
function hTree_Look(Hotspot *theHotspot, CursorMode mode)
{
Display("That's a big tree next to the pond.");
if (gDarkness.Visible == false)
{
int transparency=gDarkness.Transparency;
gDarkness.Visible=true;
while (transparency > 50)
{
transparency -= 10;
gDarkness.Transparency = transparency;
Wait(1);
}
}
else
{
int transparency=gDarkness.Transparency;
gDarkness.Visible=true;
while (transparency < 100)
{
transparency += 10;
gDarkness.Transparency = transparency;
Wait(1);
}
gDarkness.Visible=false;
}
}
Beim Verlassen des Raums dann nicht vergessen, das GUI wieder auf visible=false zu setzen.
Cool, danke!
Ich wäre nie auf die Idee gekommen, das mit einem GUI zu versuchen. ;)
Theoretisch könnte man das ja schon mit dem Bernard-Starterpak ausprobieren um das dann später in ein anderes Spiel zu portieren.
Prinzipiell ist das ja auch gar nicht so viel Code.
BG
der Volltanker
Es geht auch irgendwie mit einem zweiten Background, den man einfügt und dann je nach Situation setzt. Das hab ich aber noch nie gemacht.
So. Ich habe jetzt das Maniacweed-Starterpak so überarbeitet, dass man im Keller jetzt das Licht an und ausschalten kann.
Hier der Link:
Maniacweed Starterpak 2 (https://limewire.com/d/bCVCa#K60Nr07kux)
Funktioniert auch alles wunderbar.
Der Link hält allerdings auch nur 7 Tage an. Also ran, und fleißig downloaden. ;) Wenn möglich, vielleicht einen Upload machen, der dauerhaft ist. ;)
Fehlt eigentlich nur noch ein Flashlight-Code, sowie ingame noch eine Taschenlampe. Aber dafür fehlen mir noch die programmiertechnischen Fertigkeiten. Wer weiß. Vielleicht will das ja jemand machen.
;)
@alphawolf300 Ja, man kann pro Raum tatsächlich bis zu 5 Backgrounds anlegen. Aber der Effekt wäre wahrscheinlich, dass man das Bild nur schwarz machen könnte. Mit dem GUI kann man auch eine geringe Transparenz einstellen. Und ich weiß nicht, ob der zweite Background geeignet wäre, um ggf. noch einen Flashlight-Effekt einzubauen.
BG
der Volltanker
Ich versuche ja immer noch weiter zu lernen und habe mir das gerade angeschaut und ein wenig mit rumgespielt:
- gDarkness ist mir mit dem Transparency-Wert 1 für mich zu dunkel. Mir persönlich sagt 8 mehr zu. Das ist aber natürlich eine persönliche Präferenz und hängt auch davon ab, was man mit der Dunkelheit erreichen möchte.
- Height von gDarkness müsste 124 sein, ansonsten ragt das GUI in die Textzeile bei der klassischen Bedienung
- ZOrder von gDarkness auf -10, damit es sich nicht ÜBER das Speichermenü legt
Das mit einem zweiten Hintergrund bietet dann natürlich die komplette künstlerische Freiheit, man könnte dann auch helle und dunkle Stellen darstellen (ich kenn manche AGS-Spiele, da reagiert der Charakter dann auch auf die Helligkeit).
Ich hätte auch noch eine andere Idee im Kopf aber das ist einfach nur Spielerei und wird auch nicht ohne weiteres überall funktionieren, da die Grafiken dann nicht passen: Basierend auf der echten Uhrzeit die Helligkeit im Spiel anpassen. Wenn ich also um 22:00 Uhr Echtzeit spiele, dass das ganze Spiel oder bestimmte Spielszenen dann dunkler dargestellt werden. Könnte man in ein Rätsel einbauen, bei dem das Spiel die dritte Wand durchbricht oder so.
Stimmt. An die anderen GUIs habe ich gar nicht gedacht.
Habe lediglich das Action auf Z-Order 1 gesetzt.
Das müsste wohl noch korrigiert werden.
Nachdem ich zu dem Thema per PM gefragt wurde, hier gleich mal meine Ideen dazu, damit alle was davon haben: ;)
Flashlight-Effekt hab ich selbst auch noch nie gemacht, bei Epi53 hab ich da einfach einen zweiten Hintergrund im Raum gehabt und die Char-View auf den dunklen Eimer gesetzt, also die Lösung die ihr schon im Thread erörtert habt.
Ohne mich selbst näher damit beschäftigt zu haben hätte ich da aber schon eine Idee, wie das mit der GUI funktionieren könnte, je nachdem wie AGS das technisch implementiert hat:
Ein GUI Element machen, wo die Lichtfläche per Transparenz den eigentlichen hellen Hintergrund durchlässt und dieses per Script zyklisch an die aktuelle Mausposition schieben.
Falls AGS es zulässt müsste man das abdunkelnde GUI Element auf vierfache Raumgröße machen und die Lichtfläche zentral darin platziert.
Falls das nicht geht, müsste man mehrere GUI Elemente (abdunkelnde Rechtecke und eine Lichtfläche) machen und per Code die Rechtecke berechnen, die rund um die Lichtfläche gelegt und skaliert werden müssen, damit der restliche Raum abgedunkelt wird.
Sind eigentlich dann nur 5 Rechtecke/GUI Elemente
111
203
444
(0 ist die Lichtfläche, 1 ist oberhalb der Lichtfläche, 2 links, 3 rechts, 4 unterhalb)
Ist zwar etwas Tüftelarbeit, aber eigentlich recht simple Berechnungen.
Viel Spaß beim Tüfteln!
Danke Bòógieman!
Ja, meine Idee war evtl. auch, ob man das mit nem Cursor umsetzen könnte und die Fläche des Cursors entsprechend vergrößert, je nach dem, wie groß der Lichtstrahl werden soll.
Ich müsste mal gucken, wie das funktioniert, ein GUI an der Mausposition zu positionieren. Zur Zeit übe ich ja noch mit AGS.
Es gibt ja noch ein ein altes Flashlight-PlugIn für ich glaub 2.72. Aber das wird für das Maniacweed nicht kompatibel sein, nehme ich an.
Viele der alten Haudegen in Sachen AGS-Technik sind ja leider nicht mehr hier im Forum anzutreffen.
Drum liegt es jetzt an uns, es mit Bòógiemans Ansatz herauszufinden, wie es funktioniert.
@AmigaMaster Hast Du von den GUIs die Z-Order schon angepasst oder müsste ich das noch machen? Ansonsten kannst Du ja das geänderte Starterpak hier hochladen. ;)
BG
der Volltanker
Hier eine Version mit veränderten ZOrder zum Testen. Ich habe dabei auch die ZOrder für die gOptions usw. angepasst da der Text sich auch vor das Options-GUI gelegt hat.
maniacweed-master.7z (https://www.dropbox.com/scl/fi/z760gvmnqly4k6676id4h/maniacweed-master.7z?rlkey=k13u7x4qpvepro2f2vh8b4zir&st=xf4rdt2d&dl=0)
Ich habe hier eine Flashlight-Demo basierend auf dem gDarkness GUI-Ansatz. Ist bisher nur einfach an der BENUTZE Lichtschalter-Aktion festgemacht aber zeigt, dass es technisch mit Bordmitteln möglich ist.
Edit: Ich habe mich an der Implementierung einer Taschenlampe versucht und dazu die Scripte in den Räumen entsprechend angepasst. Wer testen möchte, der muss die Version vom 11.08.2026, 17:53 Uhr erneut herunterladen.
maniacweed-master-flashlight-demo.7z (https://www.dropbox.com/scl/fi/5pi73dqf8o9d025k1madb/maniacweed-master-flashlight-demo.7z?rlkey=w9vrpobin2hd2sfszyxb86fjy&st=9mnf8m79&dl=0)
Es sind folgende Änderungen notwendig:
1. Damit die Transparenz der Flashlight korrekt berechnet wird, muss gDarkness zwingend 0,0,0 als BackgroundColour und BorderColor haben! (DAS hat mich 45 Minuten gekostet, das herauszufinden).
2.Dem gDarkness GUI ist der Button bFlashlight hinzugefügt, welches ein mit GIMP erstelltes Alphachannel PNG Bild enthält. Das Bild inkl. Original GIMP-Format liegt im Verzeichnis sprites\flashlight.
3. Im GlobalScript in der Funktion repeatedly_execute_always():
// Check if the darkness GUI is active
if (gDarkness.Visible)
{
// Move the GUI button with the mouse cursor
bFlashlight.X = mouse.x - (bFlashlight.Width / 2);
bFlashlight.Y = mouse.y - (bFlashlight.Height / 2);
}
Coole Sache!
Ich werds gleich mal ausprobieren.
BG
der Volltanker
So.
Ich habs mir mal angeschaut.
Yeah! Es funktioniert!
Super Arbeit AmigaMaster! Besten Dank!
Das macht das Starterpak noch mal um einiges attraktiver. Vielleicht könnte man ja noch den kleinen Logikfehler korrigieren, dass Bernard bei eingeschalteter Taschenlampe NICHT den Kommentar abgibt "Ich kann im Dunkeln nichts erkennen.". ;) Mal sehen ob ich das noch angehe oder ob mir noch jemand zuvor kommt. Ich werds vielleicht nicht sofort erledigen, da ich parallel noch an meinem Projekt arbeite.
Bin mal gespannt, ob ich es schaffe, das lückenlos in mein derzeitiges Projekt implementiert zu bekommen. Denn das Flashlight-PlugIn muss ja schließlich an mehreren Scripten entsprechend gecoded werden.
BG
der Volltanker
Ist angepasst - Downloadlink bleibt identisch.
if (gDarkness.Visible == true)
ersetzt durch
if (gDarkness.Visible == true && bFlashlight.Visible == false)
zudem kurzerhand noch Soundeffekte beim Öffnen der Taschenlampe hinzugefügt.
Top!
Ich hätte wahrscheinlich einen komplizierteren Code gemacht.
So gefällts mir sogar besser! ;)
BG
der Volltanker
Ich konnte noch nicht die Finger davon lassen und habe mittels KI eine neue und konfigurierbare Scrollroutine eingebaut (das hätte meine Fähigkeiten überstiegen). Mich hat es schon immer genervt, dass der Charakter beim Scrolling hart in der Mitte bleibt und das Scrolling sofort und abrupt anfängt und stoppt.
Downloadlink ist weiterhin derselbe:
https://www.maniac-mansion-mania.de/forum/index.php?msg=58023 (https://www.maniac-mansion-mania.de/forum/index.php?msg=58023)
Anschauen kann man sich das in der Bibliothek, im garten oder im hinteren Kellerraum. Es wird erst gescrollt, wenn man sich dem Bildschirmrand nähert. Die "Dead Zones" (marginX / marginY) und die Geschwindigkeit des Scrollings lassen sich im globalen Script anpassen.
Super Arbeit, AmigaMaster!
Ich werds mir morgen mal anschauen.
Heute schaffe ich es nicht mehr.
BG
der Volltanker
So. Ich habs mir mal angeschaut.
Ich schätze, das Scrolling geht jetzt sanfter und der Scrolling-Point ist ein anderer.
Jetzt ist ja schon ziemlich vieles drin in dem Starterpak. Top!
Was jetzt noch offen sein könnte, wäre, dass man das Telefon auch benutzen könnte.
Dazu müsste man das Bild vom Ziffernblock aus einem anderen Starterpak implementieren und das Dial-Script erstellen.
Mal sehen, wann ich mir das noch vornehme.
BG
der Volltanker
Um die Änderungen besser hervorheben zu können, habe ich meine Erweiterungen und experimentellen Ergänzungen jetzt auf einen Fork des Starterpacks auf github hochgeladen. Somit kann jede gewünschte Version ausgewählt und heruntergeladen werden:
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
Noch eine kleine Anpassung, die ich gestern eingebaut habe:
- Mauspfeil wird bei der Hotspot-Anzeige ausgeblendet
Sehr gute Arbeit!
Ich finde, dieses Starterpak dürfte hier auf der MMM-Seite evtl. noch einmal einen Upload verdient haben. Leider sind die Admins fast alle nicht mehr da.
Würde die Versionen des Maniacweed-Starterpaks evtl. auch in den News erwähnen, damit die Leute, die auf diese Seite kommen, sehen, dass hier noch was passiert. ;)
BG
der Volltanker
Da bin ich etwas skeptischer. Mein Code sind Gehversuche, manches davon von Gemini (die Scrollroutine, von der ich noch nicht einmal das vertikale Scrolling getestet habe). Die Taschenlampe macht den Code komplizierter, da er standardmäßig aktiv ist, also muss jeder wissen, wie er die Aktion am Schalter im Keller deaktiviert, wenn er den Teil nicht haben möchte oder nicht benötigt.
Auf der anderen Seite wäre es aber natürlich schade um die Anpassungen.
Gehversuche hin oder her. Hauptsache das Ding funktioniert und ist lauffähig.
Wenn jemand das Flashlight-Modul nicht haben möchte, kann dieser ja auch das alte, ursprüngliche Starterpak noch runterladen.
Aber warum sollte jemand auf das Feature verzichten wollen?
Entweder man nutzt es, oder man nutzt es nicht.
BG
der Volltanker
Noch ein Update:
Die Hotspot-Anzeige ist jetzt dynamisch und pausiert das Spiel nicht mehr. Man kann mit angezeigten Hotspots weiterspielen. Auch hier hat mir KI die meiste Arbeit abgenommen.
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
Rein technisch wird jetzt kein Screenshot mehr erstellt, sondern ein transparentes Overlay (Sprite), welches dann jeden Frame aktualisiert wird und die Hotsports neu eingezeichnet.
Edit 14.08.: Es gab noch einen kleinen Fehler, dass nach Änderungen von Hotspots (z. B. dem Öffnen einer Schranktür oder Schublade) die alten Hotspots nicht entfernt wurden. Das wurde jetzt behoben.
Noch ein Experiment. Mal schauen, ob jemand den Unterschied findet ohne in den Commit-Text zu schauen.
Spoiler
Achtet mal auf das Scrolling
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
Toll, dass Du da jetzt richtig viel investierst in dieses Starterpak! ;)
Könntest Du die neue Version evtl. auch als Zip bereitstellen? Ich glaube über github wird es mühselig, die Dateiliste runterzuladen.
Bin mal gespannt, wie das aktualisierte Starterpak aussieht.
BG
der Volltanker
Man kann auf Github auf die grüne "Code" Schaltfläche klicken und dann das gesamte Projekt als ZIP herunterladen.
Vielleicht zu weiteren Erklärung:
Wenn man auf der Startseite des Projekts auf "Commits" klickt, sieht man den Änderungsverlauf und kann dann auch hier jeden einzelnen Commit auswählen und dann oben rechts auf "Browse files" und man schaltet auf diese eine, vorher ausgewählte Version um und kann dann auch diesen Zustand als ZIP runterladen.
Code.png
Weiß jemand, warum man die ganzen Wait() vor unzähligen Aktionen gemacht hat, auch bei den Dialogen? Die Verzögern doch nur minimal (125ms) die nächste Aktion und eigentlich braucht man sie die meiste Zeit doch nicht, außer man will bewusst eine Verzögerung haben. Oder hat das andere Hintergründe, weil dann etwas anderes nicht funktioniert hat?
Zum Beispiel hier ein Auszug aus Bernards Raum:
function hCertificate_AnyClick()
{
if (Verbs.AnyClickMove(175, 120, eDirectionUp))
{
if (Verbs.UsedAction(eGA_WalkTo))
{
// Wait(5);
}
else if (Verbs.UsedAction(eGA_LookAt))
{
Wait(5);
player.Say("'Gewinner des Eierkopfpreises.'");
}
else if (Verbs.UsedAction(eGA_PickUp))
{
Wait(5);
player.Say("Ich lass es, wo es ist.");
}
else if (Verbs.UsedAction(eGA_Use))
{
Wait(5);
player.Say("Ich will es nicht beschädigen.");
}
else if (Verbs.UsedAction(eGA_Open))
{
Wait(5);
player.Say("Ich kann es nicht öffnen.");
}
else if (Verbs.UsedAction(eGA_Close))
{
Wait(5);
player.Say("Ich kann es nicht schließen.");
}
else if (Verbs.UsedAction(eGA_Pull))
{
Wait(5);
player.Say("Ich lass es, wo es ist.");
}
Vermutlich als Stilmittel. Weil eine sofortige Reaktion nach dem Klick irgendwie überfordernd ist, wenn das wie aus der Pistole geschossen kommt. Eine minimale Verzögerung gibt dem Spieler da kurz Zeit um sich auf die Reaktion zu konzentrieren. :cl
Bzw. ist es auch schöner, wenn die Spielfigur das Objekt ansieht und erst dann zu reden beginnt, als wenn direkt bei der Drehung schon gesprochen wird.
Zitat von: AmigaMaster in 15. August 2026, 22:12:15Weiß jemand, warum man die ganzen Wait() vor unzähligen Aktionen gemacht hat, auch bei den Dialogen? Die Verzögern doch nur minimal (125ms) die nächste Aktion und eigentlich braucht man sie die meiste Zeit doch nicht, außer man will bewusst eine Verzögerung haben. Oder hat das andere Hintergründe, weil dann etwas anderes nicht funktioniert hat?
Zum Beispiel hier ein Auszug aus Bernards Raum:
function hCertificate_AnyClick()
{
if (Verbs.AnyClickMove(175, 120, eDirectionUp))
{
if (Verbs.UsedAction(eGA_WalkTo))
{
// Wait(5);
}
else if (Verbs.UsedAction(eGA_LookAt))
{
Wait(5);
player.Say("'Gewinner des Eierkopfpreises.'");
}
else if (Verbs.UsedAction(eGA_PickUp))
{
Wait(5);
player.Say("Ich lass es, wo es ist.");
}
else if (Verbs.UsedAction(eGA_Use))
{
Wait(5);
player.Say("Ich will es nicht beschädigen.");
}
else if (Verbs.UsedAction(eGA_Open))
{
Wait(5);
player.Say("Ich kann es nicht öffnen.");
}
else if (Verbs.UsedAction(eGA_Close))
{
Wait(5);
player.Say("Ich kann es nicht schließen.");
}
else if (Verbs.UsedAction(eGA_Pull))
{
Wait(5);
player.Say("Ich lass es, wo es ist.");
}
Die Entwickler von einst Lucasfilm Games hatten für das Wait-Event auch eine "Schnecke" als Cursor eingebettet.
Für Wait kann man in AGS sogar einen anderen Cursor dort hinterlegen. (Beispielsweise die Schnecke)
Dann hätten diese Wait-Zeilen auch den Zweck, dass für einen kurzen Augenblick die Schnecke auftaucht. ;)
Edit: Hab mir das Maniacweed-Bernard-Starterpak runtergeladen. Das Scrolling sieht jetzt richtig flüssig aus. ;)
BG
der Volltanker
Super, dass ihr das Starterpack erweitert!
Wie wäre es denn mit einem Thread, in dem jeder Zugang zu einem MMM-Projekt, basierend auf dem Tumbleweed-Starterpack hat, und jeder kann irgendwas für eine Episode einbauen, was ihm gerade in den Sinn kommt. Gegenstände, Kommentare, Dialoge, Rätsel, irgendwas. Irgendwann muss man dann alle Fäden irgendwie zusammenspinnen und hat eine Gemeinschaftsepisode.
Zitat von: 1mal_volltanken in 16. August 2026, 00:25:58Edit: Hab mir das Maniacweed-Bernard-Starterpak runtergeladen. Das Scrolling sieht jetzt richtig flüssig aus. ;)
Ich habe AGS auf 60 FPS gestellt. Was das im Einzelnen bedeutet (zumindest das, was ich mir erarbeiten konnte basierend auf Doku's):
- Alle statischen Wait() Werte durch eine Berechnung basierend auf dem GameSpeed() angepasst. Damit sind diese unabhängig von der Framerate (ca. 1000 Zeilen in den Quelltexten)
- Alle Animation Delays für Objekte und Charaktere angepasst, damit die bestehenden Animationen nicht 50% schneller laufen
- .Animate Delay (z. B. für die Telefon Klingelanimation) angepasst
- Movement Speed aller Charaktere angepasst
Eine Auswirkung davon ist, dass der Credits-Scroller, da er bereits pro Frame nur 1 Pixel scrollt, jetzt 50% schneller scrollt. Man könnte das noch mit einem Delay von 1 Frame verzögern aber dann hätte man 30 FPS anstatt vorher 40 FPS.
Fällt jemandem von Euch noch etwas ein, was jetzt schneller laufen könnte?
Ja, sicher kann man da noch justieren. Ich wüsste jetzt bspw. nicht, welche Auswirkungen es auf Timer-Funktionen haben könnte, falls jemand auch Timer mit einbauen möchte.
Was mir noch einfällt:
Bei damaligen Starterpaks gabs ja noch diese Problematik, dass die "Give to Charakter"-Funktion nur in Kombination mit "Use with Charakter" funktionierte. Ist das beim Maniacweed-Starterpak eigentlich immer noch so oder funktioniert "Give to" jetzt auch unabhängig?
BG
der Volltanker
Ja, Timerfunktionen laufen dann auch mit 60 Ticks pro Sekunde. Meine Frage zielte auch eher auf das Starterpack ab, da ich dort keine Timer gefunden hatte (SetTimer / IsTimerExpired).
Generell hilft bei allem, was mit den Ticks arbeitet die GetGameSpeed() Funktion:
Diese liefert die eingestellte Engine-Geschwindigkeit zurück, also bei 60 FPS 60 (das entpricht den Ticks) und das entspricht dann einer Sekunde (sofern AGS die Framerate halten kann, ansonsten verlängert sich diese Sekunde in der Echtzeit).
Jetzt kann man diesen Wert einfach multiplizieren (für mehr als 1 Sekunde) oder dividieren (für den Bruchteil einer Sekunde) und der Wert ist immer passend zur Framerate des Spiels.
Nach Tests funktioniert wait() damit auch mit Float-Werten, da wait() vermutlich einfach die Nachkommastellen ignoriert. Damit konnte ich auch die Achtelsekunden aus der 40FPS-Version (=5 Ticks) einfach in die 60 FPS-Version übernehmen (=7,5 Ticks). Ansonsten gibt es aber bestimmt auch eine Round()-Funktion in AGS, die auf Integer runden kann.
P.S:
Braucht jemand eine animierte (ein- und ausgeblendete) Hotspots? Zuerst dachte ich, es wäre eine gute Idee, als ich es dann im Spiel gesehen habe, gefiel es mir aber nicht wirklich. Ich habe es aber so implementieren können, dass man es faktisch auch ausschalten kann, indem man _max_transparency auf 0 setzt.
ShowHotspots3.1.asc
@@ -19,6 +19,16 @@ int g=70, b=70;
int islot=-1; // default icon: drawn circle
int ox, oy;
+// Fade effect
+// Initial start values
+int _fade_alpha = 0;
+int _fade_step = 1; // Transparency direction (1 = fade-out, -1 = fade-out)
+int _fade_timer = 0;
+
+// Fade settings
+int _max_transparency = 30; // 100 = fully transparent, 0 = not transparent
+int _fade_delay = 1; // Slow down effect by a delay: 1 = default speed, 2 = every second frame, 3 = every third frame, etc.
+
static function ShowHotspots::SetKey(eKeyCode keycode) {
_showhotspots_key = keycode;
}
@@ -204,11 +214,17 @@ function _Prepare() {
normalfont = Game.NormalFont;
Game.NormalFont = _showhotspots_font;
+ // Reset start values for transparency and timer
+ _fade_alpha = 0;
+ _fade_step = 1;
+ _fade_timer = 0;
+
// Create screen sized transparent sprite
hotspotSprite = DynamicSprite.Create(Screen.Width, Screen.Height, true);
// Create overlay
hotspotOverlay = Overlay.CreateGraphical(0, 0, hotspotSprite.Graphic, true);
+ hotspotOverlay.Transparency = _fade_alpha;
// Search and update hotspot condition
_SearchHotspots();
@@ -241,6 +257,28 @@ function repeatedly_execute_always() {
_Prepare();
}
+ // Start fade-in and fade-out
+ _fade_timer++;
+ if (_fade_timer >= _fade_delay) {
+ _fade_timer = 0;
+
+ _fade_alpha += _fade_step;
+
+ if (_fade_alpha >= _max_transparency) {
+ _fade_alpha = _max_transparency;
+ _fade_step = -1; // Switch to fade-in
+ }
+ else if (_fade_alpha <= 0) {
+ _fade_alpha = 0;
+ _fade_step = 1; // Switch to fade-out
+ }
+
+ if (hotspotOverlay != null && hotspotOverlay.Valid) {
+ hotspotOverlay.Transparency = _fade_alpha;
+ }
+ }
+ // ---------------------------------------------------
+
// Redraw Overlay for each frame
drs = hotspotSprite.GetDrawingSurface();
drs.Clear(COLOR_TRANSPARENT);
Das sieht dann mit _max_transparency = 30 und _fade_delay = 1 so aus:
ezgif-29e8ead8ef113ac4.gif
Hallo AmigaMaster!
Mit welcher Taste aktivierst Du denn die HotSpot-Anzeige?
Ich werde diese Funktion wahrscheinlich nicht mehr in mein Projekt implementieren, aber wer weiß?! - Vielleicht gibt es ja Entwickler, die dieses Feature behalten wollen. Kenne diese Hotspot-Anzeige vor allem auch nur aus Baphomets Fluch. Die LucasArts-Spiele hatten diese Funktion glaube ich nicht.
Dass man den Fade-In noch modifizieren kann, abseits der Main Settings, finde ich ne coole Sache. Bin aber auch mit dem Standard sonst ganz zufrieden. Ich nutze ja gerne diesen BlackBoxOut-Effekt bei Raumwechsel.
Von den Zeiteinheiten her kann man wahrscheinlich mit 60 FPS am einfachsten rechnen.
BG
der Volltanker
Zitat von: 1mal_volltanken in 17. August 2026, 20:50:57Mit welcher Taste aktivierst Du denn die HotSpot-Anzeige?
Taste h - ich habe schon vergessen, wo ich das gelesen habe. Vermutlich irgendwo im Sourcecode?
Meine Experimente von heute:
- Konfigurierbarer Ein- und Ausblendeffekt für Hotspots
- Umbenennung der Variables.* zu GameConfig.*. In der GameConfig.asc können jetzt einige Parameter eingestellt werden. Anfänglich dachte ich, es wäre praktisch in einer einzigen Datei unterschiedliche Einstellmöglichkeiten für das Starterpack zu haben. Mittlerweile kenne ich zumindest das ShowHotspots Script so gut, dass ich es nicht mehr bräuchte ;) - Einstellbar sind dort jetzt:
- Farbe der Hotspots
- Transparenzwert für den Fade-in/out Effekt
- Geschwindigkeit für den Fade-in/out Effekt
- Hotspot Key
- Hotspot FontType
- Ob die Hotspottexte in Großbuchstaben angezeigt werden sollen
- Maximale Hotspots für die Hotspotanzeige für AGS 3.6 angepasst (50)
- Umlautkonvertierung ist Dank UTF-Unterstützung für die Hotspot Textanzeige nicht mehr notwendig.
- Hotspot Textanzeige reaktiviert und über die GameConfig konfigurierbar gemacht. Standardmäßig sind die Texte für die Hotspots aber deaktiviert, da sie doch sehr stören können, vor allem in der Küche
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
So sieht es jetzt aus, wenn man die Hotspot-Textanzeige aktiviert und als Schriftart 3 bzw. eFontTumbleTiny einstellt:
Bernard - Maniacweed - Starterpack - 18.08.2026 , 23_38_41.png
Ja. Das hat doch schon was.
Richtig gute Arbeit. Schätze, der eine oder andere wird das gerne nutzen.
Die Schrift ist zwar klein aber trotzdem gut lesbar.
Bei einem 320x200 bzw. 320x180 -Bildschirm ist es schon schwieriger, das optimal hinzukriegen, denn entweder sieht es sonst verpixelt aus oder verschwommen.
Aber irgendwie sind wir ja immer diesem Screen-Format treu geblieben, auch wenn man da weniger detailiert arbeiten kann als mit größeren Auflösungen.
BG
der Volltanker
Nur um das klarzustellen und hervorzuheben:
Der Code für das Erzeugen und Auslesen der Namen für Objekte, Charaktere und Hotspots war schon in der Funktion enthalten, da hat KhrisMUC mit seinem ShowHotspots3.1 Script die ganze Arbeit gemacht. Es fehlte dann aber die Übergabe der Informationen in die Bildschirmausgabe. Das wird vermutlich bewusst deaktiviert gewesen sein aber von dem, was ich jetzt so getestet habe, scheint es zu funktionieren.
Ich habe heute die letzten Einstellungsmöglichkeiten des ShowHotspots Scripts (Iconauswahl, Icon X & Y Offsets sowie in das generelle Ein- und Ausschalten der Hotspotanzeige) mit in die GameConfig.asc übernommen. Alle bestehenden Funktionen der ShowHotspots sind weiterhin vorhanden, so dass auch vorhandener Code laufen müsste.
Die folgenden zwei Zeilen machen also effektiv dasselbe:
ShowHotspotsConfig.Enabled = true;
ShowHotspots.Enable();
Ich hatte noch die WalkTo Routine auf dem Plan, die mich in vielen anderen Adventures auch ein wenig nervt und an der ich mich versucht habe.
Änderungen:
- Code Cleanup und Namen vereinheitlicht (ShowHotspotsConfig anstatt ShowHotspotConfig)
- Kein versehentliches Rennen mehr bei einem Raumwechsel (Das konnte passieren, wenn man den Raum gewechselt hat und dann im richtigen Zeitfenster im neuen Raum den zweiten Mausklick gemacht hat)
- Der Charakter bewegt sich jetzt auch bei langsamer Gehgeschwindigkeit dauerhaft in Richtung Mauspfeil, so lange man die linke Maustaste gedrückt hält
- Koordinaten- und Distanzberechnung für die dauerhafte Bewegung (Gehen und Rennen) erfolgen jetzt nur noch mit AGS 3.6 Funktionen, da auch an anderen Stellen in den Scripten AGS 3.5 bzw. 3.6 vorausgesetzt wird.
- Charakter fängt nicht mehr an zu rennen, wenn man die Maustaste loslässt und kurz danach einmal klickt
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
Wow, mit diesen ganzen Verbesserungen werden zukünftige MMM-Episoden ja schon fast zu modernen Spielen. :cl
Ob noch ein weiteres Ronmaster der Ronmastered Collection notwendig ist? 8)
Zitat von: AmigaMaster in 15. August 2026, 22:12:15Weiß jemand, warum man die ganzen Wait() vor unzähligen Aktionen gemacht hat, auch bei den Dialogen? Die Verzögern doch nur minimal (125ms) die nächste Aktion und eigentlich braucht man sie die meiste Zeit doch nicht, außer man will bewusst eine Verzögerung haben. Oder hat das andere Hintergründe, weil dann etwas anderes nicht funktioniert hat?
Die leichte Verzögerung vor jeder Aktion halte ich auch für sinnvoll. Allerdings ist die damalige Umsetzung, die Pause vor jeder Aktion redundant zu setzen aus entwicklungstechnischer Sicht katastrophal. Die Pause hätte lieber am Ende der any_click_move-Funktion hinzugefügt werden müssen. Dann muss sie a) nur ein einziges Mal implementiert und werden und b) ist sie wirklich vor jeder Aktion vorhanden - man kann sie nicht vergessen.
Zitat von: Cmdr in 27. August 2026, 07:56:25Die leichte Verzögerung vor jeder Aktion halte ich auch für sinnvoll. Allerdings ist die damalige Umsetzung, die Pause vor jeder Aktion redundant zu setzen aus entwicklungstechnischer Sicht katastrophal. Die Pause hätte lieber am Ende der any_click_move-Funktion hinzugefügt werden müssen. Dann muss sie a) nur ein einziges Mal implementiert und werden und b) ist sie wirklich vor jeder Aktion vorhanden - man kann sie nicht vergessen.
Das Problem daran ist, dass die Verzögerung dann auch vor WalkTo ausgeführt wird. Deswegen wurde das nicht gemacht.
Zitat von: Cone Arex in 27. August 2026, 19:46:26Das Problem daran ist, dass die Verzögerung dann auch vor WalkTo ausgeführt wird. Deswegen wurde das nicht gemacht.
Ich behaupte einfach mal: das würde man nicht bemerken.
WalkTo kann man abfragen, aber was ist mit den ganzen anderen Funktionen wie Öffnen, Nim, usw, wenn kein Say() benutzt wird (z. B. Türen und Schubladen öffnen)? Dort wird auch eine Pause eingefügt. Klar könnte man eine eigene Say-Funktion schreiben aber das wäre eine grundlegende Änderung und damit für mich ein No-Go, da möchte ich gar nicht weiter drüber nachdenken, so sehr widerstrebt mir das.
Wer die Anpassung der AnyClickMove testen möchte, braucht nur in der VerbGui.asc die Verbs::AnyClickMove wie folgt um die Prüfung nach eGA_WalkTo ergänzen. Wenn man weiß, worauf man achten muss, merkt man schon den Unterschied zwischen vorher Türen oder Schubladen öffnen und schließen. Aber meine Wahrnehmung ist dadurch beeinträchtigt, da ich genau weiß, wann und wo die Pause kommt. Wer es genau merken möchte, der nimmt als Wert für Wait einfach nur GetGameSpeed(), was dann 1 Sekunde entspricht.
static int Verbs::AnyClickMove(int x, int y, CharacterDirection dir)
{
int result = Verbs.MovePlayer(x, y);
if (result) {
player.FaceDirection(dir, eBlock);
// Only add pause when WalkTo is NOT used
if (Verbs.UsedAction(eGA_WalkTo) == false) {
Wait(GetGameSpeed()/8);
}
}
return result;
}
Eine Sekunde ist natürlich zu lang. Aber die kurze Pause beim Öffnen von Schubladen und Türen finde ich auch nicht schlecht. Der Charakter muss schließlich erst ankommen und kann dann die Aktion ausführen.
Das Ausklammern der Pause bei WalkTo ist eine schöne Lösung.
Dann habe ich das mal genau so umgesetzt und alle Raumscripte angepasst. Bewusste Verzögerungen wie z. B. bei Britneys Unterwäsche sind unverändert vorhanden.
Effektiv fast 900 Zeilen eingespart.
- 125ms Wait() in die Verbs::AnyClickMove eingefügt (nicht gültig für eGA_WalkTo)
- In allen Räumen das Wait() entfernt, sofern diese zur Standardaktion Verbs.UsedAction gehört und keine gewollte Verzögerung war
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)
Klitzekleines Update:
Zwei kleine Änderungen bei der Behandlung der Taschenlampe, wenn man im dunklen steht oder sie im eingeschalteten Zustand öffnen möchte.
https://github.com/AmigaMaster/Maniacweed-Bernard (https://github.com/AmigaMaster/Maniacweed-Bernard)