Dieses Tutorial unterscheidet sich von meinen früheren Tutorials, da es sich auf Game Jam und Game Prototyping, insbesondere Kartenspiele, konzentriert. Wir werden in Unity ein 2D-Kartenspiel ohne Code erstellen.
Ein Spielkartendeck hat insgesamt 52 Karten mit 13 Karten mit jeweils 4 verschiedenen Symbolen. Um eines mit Code zu erstellen, müssen wir diese 4 Symbole, die abgerundete rechteckige Basis für die Karte und das Design auf der Rückseite der Karte erstellen.
Das Design auf der Rückseite der Karte kann ein beliebiges abstraktes Muster sein, und es gibt zahlreiche Möglichkeiten, eines zu erstellen. Wir erstellen ein einfaches kachelförmiges Muster, das dann gekachelt wird, um das Design zu erstellen. Wir haben kein spezielles Design für die A-, K-, Q- und J-Karten.
Bevor wir beginnen, muss ich erwähnen, dass es einfachere Lösungen gibt, mit denen wir ein Kartendeck erstellen können. Einige davon sind unten aufgeführt.
Die font-basierte Lösung ist die schnellste und einfachste Lösung, wenn Sie schnelle Prototypen erstellen möchten.
Der erste Schritt besteht darin, zu lernen, wie man eine erstellt Textur2D
mit Code, der dann verwendet werden kann, um eine Sprite
in der Einheit. Der folgende Code zeigt die Erstellung einer leeren Textur von 256x256.
Texture2D-Textur = new Texture2D (256, 256, TextureFormat.ARGB4444, false); texture.filterMode = FilterMode.Trilinear; texture.wrapMode = TextureWrapMode.Clamp; Textur.Apply ();
Die Idee ist, alle Designs auf die Textur zu zeichnen, bevor wir das verwenden Sich bewerben
Methode. Wir können Designs mit der Pixel Pixel für Pixel auf die Textur zeichnen SetPixel
wie unten gezeigt.
texture.SetPixel (x, y, Color.white);
Wenn wir zum Beispiel die gesamte Textur mit einer Farbe ausfüllen möchten, können wir eine Methode wie diese verwenden.
private void PaintRectangle (Texture2D-Textur, Rect rectBounds, Color-Farbe) für (int i = (int) rectBounds.x; iSobald wir eine haben
Textur2D
erstellt, können wir damit eine erstellenSprite
auf dem Bildschirm angezeigt werden.Sprite Sprite = Sprite.Create (Textur, neues Rect (0.0f, 0.0f, Texturbreite, Texturhöhe), neuer Vector2 (0.5f, 0.5f), 1);Der komplizierte Teil bei all dem ist das Erstellen der notwendigen Designs für die Textur.
4. Erstellen der Herzform
Bei der Erstellung der Herzform gibt es viele verschiedene Ansätze, darunter einige komplizierte Gleichungen sowie einfaches Mischen von Formen. Wir verwenden die Methode der Mischung von Formen wie unten gezeigt, insbesondere die mit dem Dreieck.
Wie Sie beobachtet haben, können wir zwei Kreise und ein Quadrat oder ein Dreieck verwenden, um die grundlegende Herzform zu erstellen. Dies bedeutet, dass diese besonders schönen Kurven fehlen würden, aber genau zu unserem Zweck passen würden.
Einen Kreis malen
Lassen Sie uns einige Gleichungen auffrischen, um einen Kreis zu zeichnen. Für einen Kreis mit Mittelpunkt am Ursprung und Radius
r
, die Gleichung für den Punkt(x, y)
auf dem Kreis istx
2
+ y
2
= r
2
. Nun, wenn der Mittelpunkt des Kreises liegt(h, k)
dann wird die Gleichung(x-h)
2
+ (y-k)
2
= r
2
. Wenn wir also ein quadratisches Begrenzungsrahmenrechteck haben, können wir alle Punkte innerhalb dieses Rechtecks durchlaufen und bestimmen, welche Punkte in den Kreis fallen und welche nicht. Wir können leicht unsere erstellenPaintCircle
Methode basierend auf diesem Verständnis, wie unten gezeigt.private void PaintCircle (Textur2D-Textur, Float-Radius, Vector2 midPoint, Farbe) Rect circleBounds = new Rect (); circleBounds.x = Mathf.Clamp (midPoint.x- (radius), 0, Auflösung); circleBounds.y = Mathf.Clamp (midPoint.y- (radius), 0, Auflösung); circleBounds.width = Mathf.Clamp (2 * Radius, 0, Auflösung); circleBounds.height = Mathf.Clamp (2 * Radius, 0, Auflösung); Float iValue; für (int i = (int) circleBounds.x; imidPoint.x-iValue && i Sobald wir die haben
PaintCircle
Auf diese Weise können wir unsere Herzform wie unten gezeigt erstellen.void PaintHearts (Texture2D-Textur) // 2 Kreise auf dem oberen Float-Radius = Auflösung * 0.26f; Vector2 mid = new Vector2 (Radius, Auflösungsradius); PaintCircle (Textur, Radius, Mitte, Color.red); mid = new Vector2 (Auflösungsradius, Auflösungsradius); PaintCircle (Textur, Radius, Mitte, Color.red); // Dreieck am unteren Rand des Gleitkommas Breite = Auflösung * 0.58f; int endJ = (int) (Auflösung * 0,65f); int startJ = (int) (Auflösung * 0,1f); Float Delta = (Breite / EndeJ); Float MidI = Auflösung * 0.5f; für (int i = 0; i(midI- (delta * (j-startJ))) && i<(midI+(delta*(j-startJ)))) texture.SetPixel(i, j, Color.red); Die Variable
Auflösung
ist die Breite und Höhe der Textur.5. Erstellen der Rautenform
Wir werden zwei Möglichkeiten diskutieren, um die Rautenform zu zeichnen.
Einen einfachen Diamanten malen
Am einfachsten ist es, den für das Dreieck verwendeten Code zu erweitern und oben ein umgekehrtes Dreieck hinzuzufügen, um die erforderliche Form zu erzeugen (siehe unten).
void PaintDiamond (Texture2D-Textur) Floatbreite = Auflösung * 0,35f; für (int i = 0; imidJ) j = Auflösung-j; if (i> (midI- (delta * j)) && i<(midI+(delta*j))) isValid=true; else if(i>(midI- (delta * j)) && i<(midI+(delta*j))) isValid=true; return isValid; PaintDiamond(texture); Einen kurvigen Diamanten malen
Die zweite besteht darin, eine andere Gleichung zu verwenden, um eine bessere, kurvigere Version unserer Diamantform zu erstellen. Wir werden dieses verwenden, um das Kacheldesign für die Rückseite unserer Karte zu erstellen. Die Gleichung für einen Kreis leitet sich von der ursprünglichen Gleichung einer Ellipse ab
(x / a)
2
+ (j / b)
2
= r
2
.Diese Gleichung ist die gleiche wie die des Kreises bei den Variablen
ein
undb
sind beide1
. Die Ellipsengleichung kann dann für ähnliche Formen zu einer Superellipsengleichung erweitert werden, indem einfach die Potenz verändert wird,(x / a)
n
+ (j / b)
n
= r
n
. Also wannn
ist2
Wir haben die Ellipse und für andere Werte vonn
Wir werden verschiedene Formen haben, eine davon ist unser Diamant. Wir können den Ansatz verwenden, um zum zu gelangenPaintCircle
Methode, um zu unserem neuen zu gelangenPaintDiamond
Methode.private void PaintDiamond (Textur2D-Textur, Rect rectBounds, Vector2 midPoint, Farbe, Float n = 0.8f) Float iValue; int a = (int) (rectBounds.width / 2); int b = (int) (rectBounds.height / 2); Float nRoot = 1 / n; Float Delta; Schwimmer partiell ein; rectBounds.width = Mathf.Clamp (rectBounds.x + rectBounds.width, 0, Auflösung); rectBounds.height = Mathf.Clamp (rectBounds.y + rectBounds.height, 0, Auflösung); rectBounds.x = Mathf.Clamp (rectBounds.x, 0, Auflösung); rectBounds.y = Mathf.Clamp (rectBounds.y, 0, Auflösung); für (int i = (int) rectBounds.x; imidPoint.x-iValue && i Malen eines abgerundeten Rechtecks
Dieselbe Gleichung kann verwendet werden, um die Basisform für abgerundete Rechteckkarten zu erstellen, indem der Wert von geändert wird
n
.private void PaintRoundedRectangle (Textur2D-Textur) für (int i = 0; imid.x-iValue && i Kacheln eines Designs bemalen
Verwenden Sie dies
PaintDiamond
Auf diese Weise können wir fünf Diamanten zeichnen, um die Kacheltextur für das Design auf der Rückseite unserer Karte zu erstellen.Der Code zum Zeichnen des Kacheldesigns ist wie folgt.
private void PaintTilingDesign (Texture2D-Textur, int tileResolution) Vector2 mid = new Vector2 (tileResolution / 2, tileResolution / 2); Floatgröße = 0,6f * tileResolution; PaintDiamond (Textur, neues Rect (mid.x-size / 2, mid.y-size / 2, Größe, Größe), mid, Color.red); mid = new Vector2 (0,0); PaintDiamond (Textur, neues Rect (mid.x-size / 2, mid.y-size / 2, Größe, Größe), mid, Color.red); mid = new Vector2 (tileResolution, 0); PaintDiamond (Textur, neues Rect (mid.x-size / 2, mid.y-size / 2, Größe, Größe), mid, Color.red); mid = new Vector2 (tileResolution, tileResolution); PaintDiamond (Textur, neues Rect (mid.x-size / 2, mid.y-size / 2, Größe, Größe), mid, Color.red); mid = new Vector2 (0, tileResolution); PaintDiamond (Textur, neues Rect (mid.x-size / 2, mid.y-size / 2, Größe, Größe), mid, Color.red);6. Erstellen der Pik-Form
Die Spatenform ist nur die vertikale Drehung unserer Herzform zusammen mit einer Basisform. Diese Basisform wird auch für die Keulenform gleich sein. Die folgende Abbildung zeigt, wie wir diese Basisform mit zwei Kreisen erstellen können.
Das
PaintSpades
Methode wird wie unten gezeigt sein.void PaintSpades (Textur2D-Textur) // 2 Kreise auf mittlerem Fließradius = Auflösung * 0.26f; Vector2 mid = new Vector2 (Radius, Auflösung-2,2f * Radius); PaintCircle (Textur, Radius, Mitte, Color.black); mid = new Vector2 (Auflösungsradius, Auflösung-2.2f * Radius); PaintCircle (Textur, Radius, Mitte, Color.black); // Dreieck im oberen Bereich Breite Breite = Auflösung * 0.49f; int startJ = (int) (Auflösung * 0,52f); Float Delta = (Breite / (Auflösung-StartJ)); Float MidI = Auflösung * 0.5f; int verändertJ; Radius = Auflösung * 0,5f; Float MidJ = Auflösung * 0.42f; Float iValue; für (int i = 0; i(midI- (delta * modifiedJ)) && i<(midI+(delta*alteredJ))) texture.SetPixel(i, j, Color.black); //bottom stalk for (int k=0;k mid.x + iValue) mid = new Vector2 (Auflösung, midJ); iValue = (Mathf.Sqrt (Radius * Radius - ((k-mid.y) * (k-mid.y)))) // // mid.x; wenn ich 7. Erstellen der Keulenform
An diesem Punkt bin ich sicher, dass Sie herausfinden können, wie einfach es geworden ist, die Form eines Clubs zu erstellen. Alles, was wir brauchen, sind zwei Kreise und die Basisform, die wir für die Pikform erstellt haben.
Das
PaintClubs
Methode wird wie unten gezeigt sein.void PaintClubs (Textur2D-Textur) int radius = (int) (Auflösung * 0,24f); // 3 Kreise Vector2 mid = new Vector2 (Auflösung * 0.5f, Auflösungsradius); PaintCircle (Textur, Radius, Mitte, Color.black); mid = new Vector2 (Auflösung * 0,25f, Auflösung- (2,5f * Radius)); PaintCircle (Textur, Radius, Mitte, Color.black); mid = new Vector2 (Auflösung * 0,75f, Auflösung- (2,5f * Radius)); PaintCircle (Textur, Radius, Mitte, Color.black); // Basisstielradius = (int) (Auflösung * 0.5f); Float MidY = Auflösung * 0.42f; int stalkHeightJ = (int) (Auflösung * 0,65f); Float iValue; für (int i = 0; imid.x + iValue) mid = new Vector2 (Auflösung * 1,035f, midY); iValue = (Mathf.Sqrt (Radius * Radius - ((j-mid.y) * (j-mid.y)))) // // mid.x; wenn ich 8. Texturen verpacken
Wenn Sie die Unity-Quelldateien für dieses Projekt untersuchen, finden Sie eine
TextureManager
Klasse, die all das schwere Heben macht. Nachdem wir alle notwendigen Texturen erstellt haben, wird derTextureManager
Klasse verwendet diePackTextures
Diese Methode kombiniert sie in einer einzigen Textur, wodurch die Anzahl der erforderlichen Draw-Aufrufe reduziert wird, wenn wir diese Formen verwenden.Rect []packAssets = PackTexture.PackTextures (allGraphics, 1);Verwendung der
GepackteAssets
Array können wir die Begrenzungsrahmen einzelner Texturen aus der genannten Mastertextur abrufenGepackteTextur
.public Rect GetTextureRectByName (String TexturName) TexturName = TexturName.ToLower (); int textureIndex; Rect textureRect = new Rect (0,0,0,0); if (textureDict.TryGetValue (textureName, out textureIndex)) textureRect = ConvertUVToTextureCoordinates (loadedAssets [textureIndex]); else Debug.Log ("keine solche Textur" + TexturName); return textureRect; private Rect ConvertUVToTextureCoordinates (Rect rect) return new Rect (rect.x * gepackteTexture.width, rect.y * gepackteTexture.height, rect.width * gepackteTexture.width, rect.height * gepackteTexture.height);Fazit
Nachdem alle erforderlichen Komponenten erstellt wurden, können wir mit der Erstellung unseres Kartensets fortfahren, da es nur eine Frage der richtigen Anordnung der Formen ist. Wir können entweder die Unity-Benutzeroberfläche verwenden, um Karten zusammenzusetzen, oder wir können die Karten als individuelle Texturen erstellen. Sie können den Beispielcode untersuchen, um zu verstehen, wie ich die erste Methode zum Erstellen von Kartenlayouts verwendet habe.
Wir können dieselbe Methode zum Erstellen beliebiger dynamischer Grafiken zur Laufzeit in Unity verwenden. Das Erstellen von Grafiken zur Laufzeit ist ein leistungshungriger Vorgang, der jedoch nur einmal durchgeführt werden muss, wenn diese Texturen effizient gespeichert und wiederverwendet werden. Durch das Packen der dynamisch erstellten Objekte in eine einzige Textur erhalten wir auch die Vorteile eines Texturatlas.
Jetzt, da wir unser Spielkartendeck haben, lassen Sie mich wissen, welche Spiele Sie damit erstellen möchten.