Beiträge von agenty

    Dein Fall besteht aus zwei Teilen:

    1. Zu einem Item speichern, welcher Actor/welche Actors es nutzen dürfen.

    2. Die Sache mit dem "nur auswählen wenn"


    Der erste Teil ist per Script relativ trivial. Der zweite nicht. Es gibt tausende Kampf-/Menü-Systeme und du müsstest das "nicht wählen können" genau in die integrieren, die du nutzt.

    Also ich hab mich jetzt mal 2 Std hingesetzt und was runter gecoded dazu


    Das Script

    Wie mans benutzt steht im Kopf-Kommentar


    Beispiel Sprachdatei:

    Ich hab nicht alles eingetragen, was Maru gefunden hatte, das kann jeder für sich, oder jemand ist mal fleißig und machts für alle ^^'


    LG

    Agy

    Also nur mit Events ist das relativ schwer umzusetzen. Daher würde ich dir eher raten, ein wenig Script Unterstützung zu verwenden. Aber ein denkbares Szenario mit Events wäre:


    1. Du hast irgendwo auf der Map ein Event. Die erste Seite hat kein Bild, die zweite Seite deinen Pfeil. Die Bedingung der zweiten Seite ist ein lokaler Schalter. Wichtig: Das Event ist so eingestellt, dass es durch andere Events durch moven kann.

    2. Wenn der Spieler die Aktion auslöst:

    2.1. Ermitteln der Spieler Koordinaten und Blickrichtung

    2.2. Verschiebe das Pfeil Event auf den Spieler plus ein Feld in seine Blickrichtung (ggf. zwei bis drei Schritte nötig (set to player, turn, move))

    2.3. Lege den lokalen Schalter um. (damit dein Event sichtbar wird)

    3. Bewege den Pfeil in Blickrichtung

    3.1. Bewege den Pfeil um ein Feld

    3.2. Prüfe auf Kollision mit dem Ziel (Map-Koordinaten vergleichen)

    3.3. Wenn Treffer => Ende + Erfolg

    3.4. Solange Reichweite nicht ausgeschöpft => gehe zurück zu Schritt 3.1.


    Die Schwachstelle des Ganzen ist in erster Linie, dass du mit Events nie so generisch werden kannst, wie dus für deinen Anwendungsfall gerne hättest. Zum Beispiel wirds ohne Script echt eng, wenn du willst, dass du die Ziel Events irgendwie "markieren" kannst, so dass du bei der Kollisions-Erkennung auf eine Untermenge der Events (Ziele) prüfen kannst, ob eine Koordinaten-Überschneidung stattgefunden hat.

    Also erstmal:


    Dein Bitmap hat eine eingestellte Breite, in deinem Fall "width". Die entspricht der Bildbreite plus der berechneten Textbreite. Sowie eine Höhe (der max Wert). Stell dir das wie deinen Zeichenblock vor. Wenn du da zu weit links malst, dann malst du auch deinen Tisch an, aber in deinem Bild wird das nicht zu sehen sein. So verhält sich das auch mit deinem Bitmap. Du malst der Reihe nach Farbpunkte rein. Wenn du an eine Stelle, an der schon was ist, einen neuen Farbwert setzt, hast dus überschriebn.


    Zu Bitmap#blt


    blt malt ein bild in ein anderes rein, oder noch genauer:


    Die Farbwerte des angegebenen ausschnitts (x,y,witdht,height) (in deinem Fall icon.rect) des einzuzeichnenden Bitmaps (in deinem Fall icon) werden beginnend an der stelle (x, y) (in deinem Fall (0,0)) in die Zielbitmap übernommen.


    Jetzt haben wir aber die ganzen dimensionen so berechnet, dass es ein genauer match ist, wir wollen also garnicht die einzelnen Teile rumschieben, sondern das ganze.

    Selbe Analogie zum Zeichenblock: Du hast ein Bild gemalt, da ist ein Baum und eine Katze drauf. Das Bild ist ganz toll geworden und du hast es aufgehängt. Du trittst einen Schritt zurück und schaust es dir an und entscheidest "das Bild hängt zuweit Oben". Würdest du die Katze und den Baum aus dem Bild ausschneiden und tiefer wieder ankleben, oder würdest du den Nagel rausziehn und tiefer erneut einschlagen?


    Kurz um: Willst du das ganze Ding verschieben, packste die Koordinaten von sprite an, da gibts auch n x und n y.


    Zum mystischen Verschwinden


    Der Maker berechnet zyklisch die auf den Bildschirm zu übertragenden Bilder. Wenn jetzt dein Sprite nicht regelmäßig sagt "hallo, ich bin auch noch da!" dann wirds weggeräumt. Darum hat das Ding ne update methode.

    Und genau desswegen habe ich dir am 17.03.2018 den Rendering zyklus nahegelegt ^^.


    LG

    agy

    Sehr löblich von dir, dass du selbst lernen willst wies geht, ich geb dir gerne eine kleine Starthilfe für dein erstes Script =)


    Also als erstes solltest du dir das mal durchlesen:

    https://www.ruby-lang.org/de/documentation/quickstart/

    Das ist zwar für eine erheblich neuere Ruby Version als im maker, aber das feeling bei der Syntax bleibt das selbe.


    Dann: Der Maker hat ein Hilfe File, i.d.R. kannste das mit F1 aufrufen. Da haste dann ein Suchfeld, da kannste die Namen der Klassen eintippen, für die du Methoden suchst.

    Bei dir sind das:


    • RPG::Cache
    • Sprite
    • Bitmap

    Für deine ersten Schritte:


    Sagen wir mal du hast ein Icon in dem Icon-Ordner deines Spiels, oder nimmst eines aus dem RTP. Dann ist RPG::Cache.icon dein Freund. Lass und mal eines aus dem RTP nehmen. Zunächst speichern wir das in einer variablen und erhalten dafür eine Instanz der Bitmap Klasse. Das brauchen wir, weil wir ja mit der Höhe und der Breite weiter rechnen wollen.

    icon = RPG::Cache.icon("028-Herb04")


    Als nächstes machen wir das selbe mit dem Text, erstmal als einfacher String. text = "12x Herb". So nun wollen wir auch dafür den Platzbedarf bestimmen. Jetzt könnten wir natürlich hergehen, die Zeichen zählen und anhand der Font-Größe das ganze ausrechnen. Gut nur, dass die Klasse Bitmap bereits eine Methode genau dafür hat. Aber wo bekommen wir jetzt ein Bitmap Objekt her? Ah, wir haben doch das Icon als Bitmap vorliegen.

    Nutzen wir doch das, um ein sog. Rect zu erhalten, in dem unter anderem die Breite und die Höhe des Platzbedarfs drin stehen. text_rect = icon.text_size(text)


    So, jetzt haben wir den Platzbedarf für das Icon und für den Text. Jetzt gehts daran, den gesamten Platzbedarf zu bestimmen. In unserem Fall soll der Text rechts neben dem Icon stehen. Das bedeutet, dass wir als Gesamtbreite die Summe beider Breitenangaben brauchen. Die Höhe dagegen ist was anderes. Wir haben nur eine "Zeile". Da jetzt aber Icon und Text unterschiedlich groß sein können, müssen wir hier das Maximum der beiden Höhen nehmen.

    Code
    1. width = icon.width + text_rect.width
    2. height = [icon.height, text_rect.height].max

    Jetzt haben wir endlich den gesamten Platzbedarf dessen, was wir zeichnen möchten. Daher können wir uns nun daran machen, das Sprite zu erstellen. sprite = Sprite.newDieses Sprite braucht als erstes ein Bitmap, auf dem wir malen können. Wie groß unsere Zeichenfläche ist, haben wir ja bereits berechnet. sprite.bitmap = Bitmap.new(width,height)

    Zwischenstand: Wir haben ein Sprite mit einer Zeichenfläche, die so groß ist, wie unser Platzbedarf. Was fehlt noch? Das Einzeichnen des Icons und des Textes. Fangen wir mal mit dem Icon an. Dazu nutzen wir die Methode "blt" aus der Bitmap Klasse. Das Icon steht ganz links (x = 0, y = 0) und benötigt ein Rechteck, das so Groß ist, wie der eigene Platzbedarf. Nur gut, dass wir das Icon als Bitmap haben, da können wir das Rechteck einfach anfordern.sprite.bitmap.blt(0,0,icon,icon.rect)Jetzt nur noch den text malen und wir sind durch! Aber auch dazu hat Bitmap eine eigene Methode, nämlich "draw_text". Beim Icon war die Positionierung ganz einfach, da wir das ganz links oben einzeichnen. Wo kommt jetzt der Text hin? In X-Richtung an die Stelle, wo das Icon aufhört, in Y-Richtung an die Stelle 0. Dadurch erscheint der Text rechts neben dem Icon. Aber wieviel Platz reservieren wir dafür? In der Breite ist das klar, so viel wie unser Text halt braucht, in der Höhe nehmen wir einfach die Gesamt-Höhe unserer Zeile. Wir wollen nämlich den Text noch so ausrichten, dass er vertikal und horizontal zentriert wird. Horizontal passiert ja schon dadurch, dass wir nicht mehr Breite als Platzbedarf zur Verfügung stellen, vertikal ergibt sich das daraus, dass wir dem Zeichenbefehl mitgeben "Text bitte zentrieren". Das ist einfach eine 1 als letzter Parameter. So viel zu den Überlegungen. Jetzt wissen wir, was wir machen wollen, lass es uns noch umsetzen. sprite.bitmap.draw_text(icon.width,0,text_rect.width,height,text,1)


    Und schon haben wir das Dingens gemalt. Jetzt schauen wir uns doch nochmal den ganzen Code an. Das war sehr viel Geschwafel von mir, für sehr wenig Code. Daran sehen wir dann auch, dass das Ganze eigentlich nach den reichlichen Überlegungen recht simpel ist.

    Code
    1. icon = RPG::Cache.icon("028-Herb04")
    2. text = "12x Herb"
    3. text_rect = icon.text_size(text)
    4. width = icon.width + text_rect.width
    5. height = [icon.height, text_rect.height].max
    6. sprite = Sprite.new
    7. sprite.bitmap = Bitmap.new(width,height)
    8. sprite.bitmap.blt(0,0,icon,icon.rect)
    9. sprite.bitmap.draw_text(icon.width,0,text_rect.width,height,text,1)

    Ich hoffe die Anleitung war verständlich genug, wenn nicht, frag ruhig nach.


    LG

    Agy


    P.S.: Nachtrag


    Ich hab mal zum Spaß kurz deine ganze Anforderung in ein Script "gehackt". Das ist aus vieler lei Sicht nicht schön, aber vor allem, weils an dem Maker Konzept mit den Szenen und synchronen update Zyklen vorbei schifft. Dafür braucht man aber Scene_Map nicht anfassen. Ich empfehle, dass dus erstmal zu lernzwecken selber versuchst, aber wenn du garnicht weiter kommst, dann hast du was zum spicken.


    Hallo Leute,


    ich hab früher viel mit dem RMXP gemacht. Hauptsächlich Scripts. Unter anderem auch ein eigenes Framework mit dem Ziel, den Einschränkungen des RMXP Herr zu werden. Eigentlich ist es schade, dass viel von dem Zeug jetzt auf irgendeiner Harddisk vor sich hin gammelt. Also möchte ich versuchen, wann immer ich Zeit habe, einzelne Teile daraus zu extrahieren und hier als Stand Alone Open Source Scripts anzubieten.


    Das Lizenz Modell


    Das nachfolgende Lizenzmodell soll für alle meine Publikationen im Rahmen dieses Posts gelten:


    Credits


    Früher war es üblich, die Macher von Scripts in den Credits des Spiels zu erwähnen. Ich habe schon immer davon abgesehen, die Nutzer meiner Scripts dazu zu zwingen. (Maßanfertigungen wären ggf. nochmal eine andere Sache) Daher besteht keine Pflicht, mich zu erwähnen. Im Gegenteil, wenn mich jemand namentlich erwähnen möchte, dann bitte nur mit Absprache.


    Scripts


    Hier werden nach und nach, immer wenn ich Zeit habe, die Scripts angehängt werden.

    Der Post ist zwar schon etwas älter, aber da ich neu hier bin, ich aber in grauer vorzeit mal mein eigenes UI Framework für den RMXP gebaut hatte, kann ich einige Erkenntnisse zum Thema "Animation" beisteuern.


    Also zunächst mal: Was ist aus Sicht eines potentiellen Scripts eine "Animation"?


    Im Endeffeckt zeichnet das Programm Frame für Frame das zu rendernde Bild auf deinen Bildschirm. Der Maker geht dabei zyklisch vor. Das bedeutet, dass ein Animations-Script pro Rechenzyklus des Makers die Informationen zum Zeichnen deiner Erweiterung berechnen muss. Du programmierst also nicht die Animation selbst, sondern die zyklische Abweichung der Position und Sichtbarkeit deines Objektes. Der Maker selbst nennt die Steuerung dieser Zyklen "Scene". Die Scene wiederum enthält unter anderem sog. Sprites. Das sind komplexe Zeichenanweisungen, wenn du so willst. Aus Computergrafik Sicht würde man sagen, es handelt sich dabei um die Geometrie Daten deines Programms. Die Bitmap ist dann als Teil dieser Datenstruktur dein Zeichenblock. Sie enthällt also die Information der einzelnen Farbpunkte der zu zeichnenden Grafik.


    Warum erklärst du diesen Käse?


    Für das Erstellen einer Animantion ist es absolut kriegsentscheidend das Rendering Verhalten der gewünschten Zielplattform zu kennen, da gerade bei bewegten Bildern das Timing extrem wichtig ist.


    Wie sollte ich mein Animations-Script aufbaun?


    Zunächst musst du dir klar werden, welche Szene deine Animation bedienen soll, also, wenn du so willst, in welchen update Zyklus du dich reinhängen musst. In deinem Fall ist das trivial: Dein Spieler sammelt auf der Map ein Item. Also ist deine Scene "Scene_Map". Jetzt musst du deine Scene so erweitern, dass sie über Animationswünsche informierbar ist, sprich irgendeine schnittstelle erhällt, die die Objekte (Icon, Name, Anzahl) und ein von bis erhält, in etwa (in form von psoido code)#animate("Potion.png","Trank",1,{:y => 255, :opacity => 255},{:y => 0, :opacity => 0})

    Deine Scene sollte dann aus diesen Informationen ein Sprite erstellen und sich merken. (Es reicht ein Sprite, du kannst alle Bildpunkte in das eine Bitmap zeichen und so kannst du auch alles als ein Bild verschieben und/oder ausblenden)


    Hat sich deine Scene deinen Antrag gemerkt soll diese nun im update Zyklus den gewünschten Unterschied der Werte berechnen und an das erstellte Sprite übergeben. (Den Sprite#update Aufruf nach der Werteübergabe nicht vergessen). Wenn du das genau so machst, kommst du schnell an den Punkt, an dem dein Bild viel zu schnell verschwindet. Was macht man dagegen? Man verzögert. Sagen wir mal, du machst dir einen Timer, der nur alle n Zyklen die Werte inkrementiert/dekrementiert. Dann wäre "n" dein Stellrad für die Animationsgeschwindigkeit. Ich beforzuge im Maker jedoch eine Lösung, die mich eher das Zeitverhalten steuern lässt. Das geschieht mit Hilfe von in etwa Graphics.frame_count / Graphics.frame_rate Dies gibt dir die ungefähre Anzahl an Sekunden, die dein Spiel seit dem Start gelaufen ist. Wenn dir die Einheit "Sekunden" zu groß ist, kammst du beispielsweise auch durch die halbe Frame-Rate teilen, u.s.w. Wie dem auch sei, deine Scene Updated jetzt nicht mehr das Sprite direkt, sondern einen Timer und wenn der entscheiden "Jetzt ist es an der Zeit", dann ändert dieser das Sprite. Sobald dein Sprite die gewünschten werte hat, kannst dus löschen (Sprite#dispose) und deiner Scene mitteilen "Das gibts nicht mehr".


    "Kleiner" Ausschnitt


    Zur kleinen Hilfestellung häng ich mal den Kern der Animationen aus meinem alten Framework an. ACHTUNG! Das ist kein vollständiges Copy/Paste Script, sondern nur ein Ausschnitt eines sehr viel komplexeren Scripts und soll lediglich der Orientierung dienen. (Btw. ist das wirklch alt. Kann also sein, dass der Code nicht der schönste ist)


    LG

    Agy

    Hallo Leute,


    ich bin agenty. Ich hab früher viel mit dem RMXP gemacht, makere aber schon geraume Zeit nicht mehr wirklich. Angemeldet hatte ich mich, weil ich zufällig beim googeln auf diese Seite gestoßen bin und ein paar bekannte Gesichter sah.


    Zu meiner Person:


    Ich bin 29 Jahre jung und studierter Informatiker (B.Sc.). Derzeit setze ich noch ein Folgestudium zum Master Informatik an. Des Weiteren arbeite ich als Entwickler in einem mittelständischen Software Unternehmen in München. Meine damaligen stärken beim makern lagen im scripten und komponieren, besonders mies war ich schon immer im Grafik bereich =)


    Wenn noch jemand Fragen hat, seid ihr herzlichst eingeladen mich zu löchern.


    LG

    Agy