Oblivion:Eigenes Musiksystem

Aus Skript-Wiki
Version vom 23. März 2009, 12:50 Uhr von Keris (Diskussion | Beiträge) (Die Seite wurde neu angelegt: == Thema == Hier wird gezeigt, wie man z.B. für seinen eigenen Worldspace oder seine Zellen auch eigene Musik abspielen kann. Die Lieder sollen in Exterior und Interio...)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Thema

Hier wird gezeigt, wie man z.B. für seinen eigenen Worldspace oder seine Zellen auch eigene Musik abspielen kann. Die Lieder sollen in Exterior und Interior anders sein und in zufälliger Reihenfolge gespielt werden.

Anwendung

Aufgabenstellung

Wir werden mit Hilfe von StreamMusic ein Musik System erstellen, dass es dem Spieler ermöglicht, in seinen eigenen Zellen auch eigene Musik abzuspielen. Dazu kommt ein Zufallszähler, damit Lieder zufällig abgespielt werden, so dass es nicht eintönig wird. Außerdem werden wir zwischen Exterior und Interior Musik unterscheiden (theoretisch kann man dann natürlich auch für unterschiedliche Situationen unterschiedliche Musik abspielen, z.B. extra Musik, wenn der Spieler schwimmt oder schleicht). Auch hierfür wird es ein Beispiel geben.


Theorie

Wir werden unter anderem folgende Befehle verwenden:

Probleme

Es wird einige Probleme bei der Umsetzung geben. Beim Kampf wird die StreamMusic, die abgespielt wird, unterbrochen, d.h. es muss der StreamMusic Befehl nach einem Kampf wieder neu aufgerufen werden. Außerdem muss je nachdem, wo der Spieler sich befindet, nämlich ob er sich in einer Höhle befindet oder ob er draußen ist, die passende Musik gespielt werden. Dazu müssen wir aber auch wissen, wann genau der Spieler eine Zelle verlässt, also müssen wir Zellwechsel erkennen können. Es muss erkannt werden, wenn ein Lied zuende ist. Zuguterletzt kommt noch ein lange ungelöstes Problem dazu, und zwar wenn man zweimal hintereinander StreamMusic mit einem unterschiedlichen Lied aufruft, kommt trotzdem zweimal hintereinander das gleiche Lied. Das liegt daran, dass der Speicher für die aktuelle Musik nur bei bestimmten Ereignissen neu geflasht wird. Eines dieser Ereignisse ist der Beginn eines Kampfes, deswegen müssen wir immer kurz einen Kampf erzeugen, bevor wir das nächste Lied abspielen können. Also zusammenfassend:

  • Kampf
  • Interior oder Exterior
  • Zellwechsel
  • Lied-Ende
  • Kampf erzeugen

Realisierung

Für die Umsetzung erstellen wir uns erstmal eine neue Quest mit einem Quest Skript, das im Hintergrund abläuft.

Außerdem brauchen wir 10 Lieder, 5 für Drinnen (Interior) und 5 für Draußen (Exterior).Wir nennen sie der Einfachheit halber mal INTSong1-5 und EXTSong6-10

Es können auch mehr Lieder benutzt werden, dazu muss der Zufallszähler entsprechend verändert werden.



Wieso Gamemode UND Menumode?

Angenommen der Spieler öffnet sein Inventar und während er im Inventar ist, endet ein Lied. Die Folge ist, dass der Gamemode Block nicht mehr ausgeführt wird, weil sich das Spiel im Menumode befindet,- es wird ein normales Lied gespielt. Deswegen kommt der MenuMode-Block dazu, der fast identisch zum Gamemode-Block ist. Der einzige Unterscheid ist, dass die Kampferkennung und die Zellwechselerkennung nicht enthalten ist. Der Grund dafür? - Wenn das Spiel im Menumode ist, kann der Spieler die Zelle gar nicht wechseln und angegriffen wird er auch nicht.

Problem-Lösungen:

Zellwechsel:

Jetzt müssen wir den Zellwechsel vom Spieler erkennen. Wir erstellen uns ein kleines Item oder ein Objekt, dessen Größe wir im Render Window sehr sehr klein machen. Dazu stellen wir für das Item die Persistent Reference ID "ZellWechselFlyRef" ein.


Kampferkennung:

Beim Kampf wird das Lied, dass mit StreamMusic abgespielt wird, beendet. Um zu verhindern, dass nach einem Kampf wieder die Standart-Oblivion-Musik gestartet wird, muss man folgendes machen. Man muss erkennen, wann der Kampf vorbei ist und dann sofort wieder ein neues Lied starten.

So sieht der Algorithmus aus: <tesscript> if Kampf == 0 && player.IsInCombat == 1 ; Kampf hat angefangen set Kampf to 1; Spieler ist grade in einem Kampf elseif Kampf == 1 && player.IsInCombat == 0 ; Kampf hat aufgehört set Kampf to 0; Spieler ist nicht mehr im Kampf set Songtimer to 0 ; Lied kann von vorne anfangen endif </tesscript>

Auf diese Weise hat man eine einfache Variable, die 1 ist, wenn der Spieler kämpft und die 0 ist, wenn er NICHT kämpft.


Interior oder Exterior:


In Höhlen soll andere Musik kommen als auf der Blumenwiese, deswegen unterscheiden wir zwischen Interior- und Exterior-Liedern.

Das Prinzip ist dasselbe wie beim Kampf, es wird eine Variable geben, ob der Spieler drinnen oder draußen ist. <tesscript> if player.IsInInterior == 1 && drinnen == 0 ; Spieler betritt eine Interiorzelle set drinnen to 1 ; Spieler ist "drinnen" elseif player.IsInInterior == 0 && drinnen == 1; Spieler verlässt die Interiorzelle set drinnen to 0; Spieler ist "draußsen" endif </tesscript>

Je nachdem ob der Spieler drinnen oder draußen ist, wird ein anderes Lied gespielt, es muss aber trotzdem mehrere Lieder geben, die zufällig abgespielt werden. Das ganze wird also mit einem Zufallszähler verbunden.

<tesscript> if drinnen == 1  ; Für Interiorzellen set SongNR to 1 + 0.05 * GetRandompercent; Zufällige SongNummer von 1-5 else  ; Für Exterior set SongNR to 6 + 0.05 * GetRandomPercent; Zufällige SongNummer von 6-10 endif</tesscript>

Anschliessend wird jeder möglichen SongNummer (hier 10 verschiedene) ein Lied per StreamMusic zugeordnet.


Lied-Ende:

Wenn ein Lied zu ende ist, muss sofort das nächste abgespielt werden, deshalb muss man wissen, wie lang ein Lied ist.

Während das Lied dann spielt, läuft die Restdauer vom Lied ab (mit einem kategorie:Timer). Wenn der kategorie:Timer auf 0 ist, kann das nächste Lied gespielt werden.

Also jedem Lied die Dauer zuordnen: <tesscript> if SongNR == 1  ;Song 1 : Der songtimer wird auf die Lieddauer gesetzt set songtimer to 134 streammusic "Data\Music\sinHHHans\Wiki\SongWAV1.mp3" elseif SongNR == 2 (...) endif </tesscript>

Der Timer: <tesscript> (...) elseif Songtimer > 0 ; Wenn Lied grade abgespielt wird set songtimer to songtimer - getsecondspassed; Restdauer des Songs läuft ab endif</tesscript>

Wenn der Timer 0 ist, dann heißt das, der aktuelle Song ist zuende und es kann der nächste gestartet werden.

Kampferzeugung:

Also es muss ein kurzer Kampf erzeugt werden, damit ein neues Lied mit StreamMusic gestartet werden kann. Das machen wir ganz einfach, indem wir eine Ratte aus einer anderen Zelle zum Spieler bewegen, die dann den Spieler angreift. Nachdem dieser "Kampf" 3 Frames lang gelaufen ist, wird die Ratte wieder in ihre Startzelle gebracht und der Kampf wird beendet. Der Spieler selbst bekommt davon nichts mit aber der Speicher für ein neues Lied ist wieder frei.

So sieht der Algorithmus aus:

<tesscript> if FakeFightDone < 3 ; 3 Frames lang den Kampf laufen lassen if FakeFightDone == 0 MusikKampfDummyREF.moveto player ;Ratte zum Spieler holen MusikKampfDummyREF.StartCombat player ;Ratte greift an set FakeFightDone to 1 return endif set FakeFightDone to FakeFightDone + 1 ; wird bis 3 zählen return elseif FakeFightDone == 3 ; nach 3 Frames Kampf MusikKampfDummyREF.poscell 0,0,0, 0, KampfDummyZelle ;Ratte zurück in ihre Zelle MusikKampfDummyREF.StopCombat player; Kampf beenden set FakeFightDone to 4; "Kampferzeugen" schließen return endif</tesscript>

Es müssen eine Ratte und eine neue Zelle erstellt werden (siehe unten die Bilder)

Umgebung

Die Ratte:

MusikKampfDummy.jpg MusikKampfDummyRef.jpg

Für den Zellwechsel:

CellDetect.jpg CellDetectRef2.jpg

Script

Das ist das gesamte Skript: <tesscript>scn GanzesMusikSystem

float songtimer float fQuestDelayTime

short songNR short ZellWechsel short Drinnen short Kampf short FakeFightDone

Written by sinHHHans
21.08.08


Begin Gamemode

if player.GetInWorldspace DeinWorldSpace == 1 || player.GetInCell DeineZelle == 1

Wenn der Spieler in einer Zelle oder einem Worldspace von dir ist.

if fQuestDelayTime != 0.1  ; Durchlauf Häufigkeit set fQuestDelayTime to 0.1 endif


ZELLWECHSEL ( Ist in eigenem Artikel genauer beschrieben )

if player.IsInInterior == 1 && drinnen == 0 set drinnen to 1 elseif player.IsInInterior == 0 && drinnen == 1 set drinnen to 0; endif


if player.GetInSameCell ZellWechselFlyRef == 0 && drinnen == 1 set ZellWechsel to 1 set songtimer to 0 ZellWechselFlyRef.moveto player elseif player.GetInSameCell ZellWechselFlyRef == 0 && drinnen == 0 if ZellWechselFlyRef.IsInInterior == 1 ZellWechselFlyRef.moveto player set ZellWechsel to 1 set songtimer to 0 Elseif ZellWechselFlyRef.IsInInterior == 0 ZellWechselFlyRef.moveto player endif endif


KAMPF-ERKENNUNG

if Kampf == 0 && player.IsInCombat == 1 set Kampf to 1; Spieler ist grade in einem Kampf elseif Kampf == 1 && player.IsInCombat == 0 set Kampf to 0; Spieler ist nicht mehr im Kampf set Songtimer to 0 ; Lied kann von vorne anfangen endif



if songtimer <= 0  ; Wenn der Songtimer auf 0 ist wird ein neues Lied gespielt


KAMPF-ERZEUGEN

if FakeFightDone < 3 ; 3 Frames lang den Kampf laufen lassen if FakeFightDone == 0 MusikKampfDummyREF.moveto player ;Ratte zum Spieler MusikKampfDummyREF.StartCombat player ;Ratte greift an set FakeFightDone to 1 return endif set FakeFightDone to FakeFightDone + 1 ; wird bis 3 zählen return elseif FakeFightDone == 3 ; nach 3 Frames Kampf MusikKampfDummyREF.poscell 0,0,0, 0, KampfDummyZelle ;Ratte kommt weg MusikKampfDummyREF.StopCombat player;Kampf beenden set FakeFightDone to 4; Kampferzeugen schließen return endif


if Kampf == 0 ; Wenn der Spieler nicht im Kampf ist

ZUFÄLLIGES LIED

if drinnen == 1  ; Für Interior set SongNR to 1 + 0.05 * GetRandompercent; 5 für Interior else  ; Für Exterior set SongNR to 6 + 0.05 * GetRandomPercent; 5 für Exterior endif



set FakeFightDone to 0; Kampferzeugung wieder möglich machen

if SongNR == 1  ;Alle Lieder mit Dauer,songtimer ist Lied-Dauer set songtimer to 134 streammusic "Data\Music\INTSong1.mp3" elseif SongNR == 2 set songtimer to 100 streammusic "Data\Music\INTSong2.mp3" elseif SongNR == 3 set songtimer to 130 streammusic "Data\Music\INTSong3.mp3" elseif SongNR == 4 set songtimer to 148 streammusic "Data\Music\INTSong4.mp3" elseif SongNR == 5 set songtimer to 212 streammusic "Data\Music\INTSong5.mp3" elseif SongNR == 6 set songtimer to 266 streammusic "Data\Music\EXTSong1.mp3" elseif SongNR == 7 set songtimer to 214 streammusic "Data\Music\EXTSong2.mp3" elseif SongNR == 8 set songtimer to 217 streammusic "Data\Music\EXTSong3.mp3" elseif SongNR == 9 set songtimer to 275 streammusic "Data\Music\EXTSong4.mp3" elseif SongNR == 10 set songtimer to 269 streammusic "Data\Music\EXTSong5.mp3" endif endif elseif Songtimer > 0 ; Wenn Lied grade abgespielt wird set songtimer to songtimer - getsecondspassed; Restdauer des Songs endif endif

End

Begin Menumode  ;DAS GLEICHE OHNE KAMPF ERKENNUNG UND ZELLWECHSEL (Erklärung oben)


if player.GetInWorldspace DeinWorldSpace == 1 || player.GetInCell DeineZelle == 1

Wenn der Spieler in einer Zelle oder einem Worldspace von dir ist

if songtimer <= 0

KAMPF-ERZEUGEN

if FakeFightDone < 3 ; 3 Frames lang den Kampf laufen lassen if FakeFightDone == 0 MusikKampfDummyREF.moveto player ;Ratte zum Spieler MusikKampfDummyREF.StartCombat player ;Ratte greift an set FakeFightDone to 1 return endif set FakeFightDone to FakeFightDone + 1 ; wird bis 3 zählen return elseif FakeFightDone == 3 ; nach 3 Frames Kampf MusikKampfDummyREF.poscell 0,0,0, 0, KampfDummyZelle ;Ratte kommt weg MusikKampfDummyREF.StopCombat player;Kampf beenden set FakeFightDone to 4; Kampferzeugen schließen return endif


if Kampf == 0

ZUFÄLLIGES LIED

if drinnen == 1 set SongNR to 1 + 0.05 * GetRandompercent else set SongNR to 6 + 0.05 * GetRandomPercent endif


set FakeFightDone to 0 if SongNR == 1  ;Alle Lieder mit Dauer,songtimer ist Lied-Dauer set songtimer to 134 streammusic "Data\Music\INTSong1.mp3" elseif SongNR == 2 set songtimer to 100 streammusic "Data\Music\INTSong2.mp3" elseif SongNR == 3 set songtimer to 130 streammusic "Data\Music\INTSong3.mp3" elseif SongNR == 4 set songtimer to 148 streammusic "Data\Music\INTSong4.mp3" elseif SongNR == 5 set songtimer to 212 streammusic "Data\Music\INTSong5.mp3" elseif SongNR == 6 set songtimer to 266 streammusic "Data\Music\EXTSong1.mp3" elseif SongNR == 7 set songtimer to 214 streammusic "Data\Music\EXTSong2.mp3" elseif SongNR == 8 set songtimer to 217 streammusic "Data\Music\EXTSong3.mp3" elseif SongNR == 9 set songtimer to 275 streammusic "Data\Music\EXTSong4.mp3" elseif SongNR == 10 set songtimer to 269 streammusic "Data\Music\EXTSong5.mp3" endif endif elseif Songtimer > 0 set songtimer to songtimer - getsecondspassed endif endif End

</tesscript>

Handhabung

Das Skript muss als Questskript eingestellt sein. DeinWorldSpace oder DeineZelle sind Namen für den Worldspace oder die Zelle, in der das Musiksystem laufen soll (die Namen sind Platzhalter, du kannst eigene wählen).

Man kann natürlich so viele Lieder wie man will benutzten, solange man den Zufallszähler entsprechend einstellt. Die Songtimer bei den Liedern sind bei mir nur Beispiele, es müssen für andere Lieder auch andere Timer eingestellt werden!

Weiterführende Hinweise



Weitere Scripts aus dieser Kategorie

Level 1

 

Level 3

Level 4

 



{{#if: Musik | }} {{#if: Level 4 Scripts | }}