Autotiles für RPGs

Übersicht BlitzBasic FAQ und Tutorials

Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.

Jean

Betreff: Autotiles für RPGs

BeitragSo, Aug 03, 2008 0:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Willkommen zu meinem ersten Tutorial in diesem Forum!
Ich möchte zeigen, wie man die Autotiles vom Rpg Maker XP in Blitz Basic verwenden kann.

Was sind Autotiles?
Autotiles sind Tiles, welche sich automatisch „abrunden“. Das heisst, sie bilden nie eckige Kanten, sondern bilden schöne „natürliche“ Übergänge zwischen zwei unterschiedlichen Untergründen.

Wie ist ein Autotile aufgebaut?
Die Autotiles aus dem Rpg Maker XP sind insgesamt 96 Pixel x 128 Pixel gross. Ein einzelnes Tile ist 32 Pixel x 32 Pixel gross. Also sind in einem Autotile genau 12 Tiles enthalten.
Hier einige Beispiele:
user posted image
user posted image
user posted image
user posted image

Und hier kurz eine Übersicht:
user posted image
0: Dieses Tile wird nie in der Map verwendet.
1: Der zum Autotile passende Untergrund.
2: Tile mit 4 "inneren Ecken"
3,5,9,11: Tiles mit "äusserer Ecke"
4,6,8,10: Tiles mit Kante
7: Dieses Tile wird verwendet, wenn ein Autotile komplett von gleichen Autotiles umgeben ist.

Wie funktioniert das?
Wenn der User im Mapeditor ein Autotile setzt, werden alle 8 umliegenden Tiles überprüft. Daraus wird ein Code generiert und bei der Position des soeben erstellten Autotiles im Array gespeichert. Die Codes der umliegenden Autotiles müssen natürlich angepasst werden.
Wenn die Map gezeichnet werden soll, liest eine Funktion den Code des Autotiles aus und baut das Autotile dann dem Code entsprechend zusammen.

Was ist hier überhaupt die Schwierigkeit?
Wir haben 12 Tiles. Auf den ersten Blick genügt dies völlig. Wenn man das ganze jedoch genau analysiert, wird man schnell merken, dass 12 Tiles bei weitem nicht genügen, um jede mögliche Situation darzustellen. Wird müssen also unsere Tiles selber zusammenschneiden. Genauer gesagt, wird jedes Tile in 4 weitere Teile unterteilt.
Um die Performance zu steigern, wird der passende Untergrund und das gefüllte Autotile als ganzes Tile seperat geladen.

Wie ist der Autotile-Code aufgebaut?
0 = zum Autotile passender Untergrund
1 = Autotile voll
+2 = Äussere Ecke oben links
+4 = Innere Ecke oben links
+8 = Äussere Ecke oben rechts
+16 = Innere Ecke oben rechts
+32 = Äussere Ecke unten links
+64 = Innere Ecke unten links
+128 = Äussere Ecke unten rechts
+256 = Innere Ecke unten rechts
+512 = Kante oben
+1024 = Kante links
+2048 = Kante rechts
+4096 = Kante unten

Let`s go!
Zuerst brauchen wird ein Map Array und wir müssen ein Autotile Bild laden:
Code: [AUSKLAPPEN]
Dim map(24,19) ;Map Array
Global map_w = 25 ;Map Breite
Global map_h = 20 ;Map Höhe

Global autotile=LoadAnimImage ("autotile.png", 16, 16, 0, 48) ;Die Tiles werden je in 4 kleinere Tiles unterteilt

Global autotile_terrain = CreateImage (32, 32) ;Um die Map schneller darzustellen wird der passende Untergrund und das "gefüllte" Autotile seperat in einem 32 Pixel x 32 Pixel Tile geladen
CopyRect 0, 0, 16, 16, 0, 0,ImageBuffer (autotile,2),ImageBuffer (autotile_terrain)
CopyRect 0, 0, 16, 16, 16, 0,ImageBuffer (autotile,3),ImageBuffer (autotile_terrain)
CopyRect 0, 0, 16, 16, 0, 16,ImageBuffer (autotile,8),ImageBuffer (autotile_terrain)
CopyRect 0, 0, 16, 16, 16, 16,ImageBuffer (autotile,9),ImageBuffer (autotile_terrain)

Global autotile_full = CreateImage (32, 32)
CopyRect 0, 0, 16, 16, 0, 0,ImageBuffer (autotile,26),ImageBuffer (autotile_full)
CopyRect 0, 0, 16, 16, 16, 0,ImageBuffer (autotile,27),ImageBuffer (autotile_full)
CopyRect 0, 0, 16, 16, 0, 16,ImageBuffer (autotile,32),ImageBuffer (autotile_full)
CopyRect 0, 0, 16, 16, 16, 16,ImageBuffer (autotile,33),ImageBuffer (autotile_full)


Danach brauchen wir eine Funktion, welche den Autotile-Code generieren kann:
Code: [AUSKLAPPEN]
Function create_tile(x,y) ;Der Autotile-Code wird generiert
   If  x > 0 And y > 0 And map(x-1,y) = 0 And map(x,y-1) = 0 Then ;Überprüfen ob das Tile alleine steht
      If x < map_w-1 And map(x+1,y) = 0 And y < map_h-1 And map(x,y+1) = 0 Then
         Return 15360
      EndIf
   EndIf
   
   If x > 0 And map(x-1,y) = 0 And y > 0 And map(x,y-1) = 0 Then ;Ecke oben links
      code = 2
      If x < map_w-1 And map(x+1,y) = 0 Then ;Ecken oben rechts
         code = code + 8
      Else If y < map_h-1 And map(x,y+1) = 0 Then ;Ecke unten links
         code = code + 32
      Else If x < map_w-1 And map(x+1,y) > 0 And y < map_h-1 And map(x,y+1) > 0 And map(x+1,y+1) = 0 Then ;Innere Ecke unten rechts
         code = code + 256
      EndIf
      Return code
   EndIf
   
   If x < map_w-1 And map(x+1,y) = 0 And y > 0 And map(x,y-1) = 0 Then ;Ecke oben rechts
      code = 8
      If x > 0 And map(x-1,y) > 0 And y < map_h-1 And map(x,y+1) > 0 And map(x-1,y+1) = 0 Then ;Innere Ecke unten links
         code = code + 64
      ElseIf y < map_h-1 And map(x,y+1) = 0 Then ;Ecke unten rechts
         code = code + 128
      EndIf
      Return code
   EndIf
   
   If x < map_w-1 And map(x+1,y) = 0 And y < map_h-1 And map(x,y+1) = 0 Then ;Ecke unten rechts
      code = 128
      If x > 0 And map(x-1,y) = 0 Then ;Ecke unten links
         code = code + 32
      Else If x > 0 And map(x-1,y) > 0 And y > 0 And map(x,y-1) > 0 And map(x-1,y-1) = 0 Then ;Innere Ecke oben links
         code = code + 4
      EndIf
      Return code
   End If
   
   If x > 0 And map(x-1,y) = 0 And y < map_h-1 And map(x,y+1) = 0 Then ;Ecke unten links
      code = 32
      If x < map_w-1 And map(x+1,y) > 0 And y > 0 And map(x,y-1) > 0 And map(x+1,y-1) = 0 Then ;Innere Ecke oben rechts
         code = code + 16
      EndIf
      Return code
   EndIf

   
   If x < map_w-1 And map(x+1,y) > 0 And y < map_h-1 And map(x,y+1) > 0 And map(x+1,y+1) = 0 Then code = code + 256 ;Innere Ecke unten rechts
   If x > 0 And map(x-1,y) > 0 And y < map_h-1 And map(x,y+1) > 0 And map(x-1,y+1) = 0 Then code = code + 64 ;Innere Ecke unten links
   If x > 0 And map(x-1,y) > 0 And y > 0 And map(x,y-1) > 0 And map(x-1,y-1) = 0 Then code = code + 4;Innere Ecke oben links
   If x < map_w-1 And map(x+1,y) > 0 And y > 0 And map(x,y-1) > 0 And map(x+1,y-1) = 0 Then code = code + 16 ;Innere Ecke oben rechts
   
   If x > 0 And map(x-1,y) = 0 Then code = code + 1024 ;Kante links
   If x < map_w-1 And map(x+1,y) = 0 Then code = code + 2048 ;Kante rechts
   If y > 0 And map(x,y-1) = 0 Then code = code + 512 ;Kante oben
   If y < map_h-1 And map(x,y+1) = 0 Then code = code + 4096 ;Kante unten
   
   If code = 0 Then Return 1 ;Wenn nichts eintrifft, ist das Autotile "gefüllt"
   
   Return code
End Function


Zudem wird eine Funktion benötigt, welche die 8 umliegenden Felder aktualisiert:
Code: [AUSKLAPPEN]
Function update_tile(x,y,k) ;erstellt, aktualisiert & löscht Autotiles
   If k = 1 Then
      map(x,y) = create_tile(x,y) ;Ein neues Autotile wird eingesetzt
   ElseIf k = 0
      map(x,y) = 0 ;Ein Autotile wird entfernt
   EndIf
   
   
   If x > 0 And y > 0 And map(x-1,y-1) > 0 Then map(x-1,y-1) = create_tile(x-1,y-1) ;Die 8 umliegenden Tiles müssen aktualisiert werden
   If y > 0 And map(x,y-1) > 0 Then map(x,y-1) = create_tile(x,y-1)
   If x < 24 And y > 0 And map(x+1,y-1) > 0 Then map(x+1,y-1) = create_tile(x+1,y-1)
   
   If x > 0 And map(x-1,y) > 0 Then map(x-1,y) = create_tile(x-1,y)
   If x < 24 And map(x+1,y) > 0 Then map(x+1,y) = create_tile(x+1,y)
   
   If x > 0 And y < 19 And map(x-1,y+1) > 0 Then map(x-1,y+1) = create_tile(x-1,y+1)
   If y < 19 And map(x,y+1) > 0 Then map(x,y+1) = create_tile(x,y+1)
   If x < 24 And y < 19 And map(x+1,y+1) > 0 Then map(x+1,y+1) = create_tile(x+1,y+1)
End Function


So, jetzt noch eine Funktion, welche die Tiles zusammenbaut und dann hätten wird das Wichtigste zusammen.
Code: [AUSKLAPPEN]
Function draw_tile(x,y) ;Zeichnet die Tiles
   tmp = map(x,y)
   
   If tmp = 0 Then ;Der passende Untergrund wird direkt gezeichnet
      DrawImage autotile_terrain, x*32, y*32
   ElseIf tmp = 1 Then ;ebenso das "gefüllte" Autotile
      DrawImage autotile_full, x*32, y*32
   Else ;ansonsten wird das Autotile eben zusammengesbaut
      For n=12 To 1 Step -1
         If 2^n <= tmp Then
            tmp = tmp - 2^n
            
            Select 2^n
            Case 2
               l = 12
               If r = 0 Then r = 13
               If ul = 0 Then ul = 18
            Case 4
               l = 4
            Case 8
               r = 17
               If l = 0 Then l = 16
               If ur = 0 Then ur = 23
            Case 16
               r = 5
            Case 32
               ul = 42
               If l = 0 Then l = 36
               If ur = o Then ur = 43
            Case 64
               ul = 10
            Case 128
               ur = 47
               If r = 0 Then r = 41
               If ul = 0 Then ul = 46
            Case 256
               ur = 11
            Case 512
               l = 14
               r = 15
            Case 1024
               l = 24
               ul = 30
            Case 2048
               r = 29
               ur = 35
            Case 4096
               ul = 44
               ur = 45
            End Select
         EndIf
      Next
      
      If l = 0 Then l = 26
      If r = 0 Then r = 27
      If ul = 0 Then ul = 32
      If ur = 0 Then ur = 33
      
      DrawImage autotile, x*32, y*32, l
      DrawImage autotile, x*32+16, y*32, r
      DrawImage autotile, x*32, y*32+16, ul
      DrawImage autotile, x*32+16, y*32+16, ur
   EndIf
End Function


Ich habe mit diesen Funktionen einen simplen Editor gebastelt, damit man das ganze testen kann.
Download (6kb)
user posted image

Ich hoffe euch hat mein Tutorial gefallen und freue mich über Kritik und Verbesserungen!
THX fürs Lesen!
  • Zuletzt bearbeitet von Jean am So, Sep 21, 2008 15:31, insgesamt einmal bearbeitet

BladeRunner

Moderator

BeitragSo, Aug 03, 2008 14:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
0: Dieses Tile wird nie in der Map verwendet.

Das stimmt schlicht und einfach nicht.
Dieses Tile wird verwendet wenn in der Map nur ein einziges mal das Zentrale Tile des unteren Neunerblocks verwendet wird- es gibt einen kleinen Fleck des einen Untergrundes im andern.

Wenn das Tile nie genutzt würde hätten sich die Gfxler nicht die Arbeit machen müssen es auszuarbeiten Wink
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Jean

BeitragSo, Aug 03, 2008 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
@BladeRunner: Ja, logisch ist es nicht. Jedoch habe ich die Funktionsweise des RPG Maker Xp sehr genau analysiert und festgestellt, dass dieser das Tile wirklich nie in einer Map verwendet, sondern das Tile immer aus den 4 Ecken zusammenbaut.
Ausserdem wäre es eine Verschwendung des Grafikspeichers, dieses Tile direkt in ein 32 x 32 Tile zu laden, das es nicht häufiger als andere Tiles vorkommt.

Corvulus

BeitragSo, Aug 03, 2008 15:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Aber im Normalfall würde man das doch so machen, oder? Denke gerade bisle an den Warcraft 3 Editor zurück, mit dem ich mich lange beschäftigt habe.

Gruß Corvulus
Was wäre eine Welt ohne Schokolade und Coffein?

The Shark

BeitragSo, Aug 03, 2008 20:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Nach der offiziellen RPG-Maker Hilfe ist das tile links oben das vorschautile

Shinkiro1

ehemals "Espada"

BeitragMo, Aug 04, 2008 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Nach der offiziellen RPG-Maker Hilfe ist das tile links oben das vorschautile

Richtig. Es dient zur Ansicht im Editor.
Das oberste, 2te Tile von links dient übrigens dazu um festzustellen ob ein anderes Tile dazu passt.
(Wenn 2 Autotiles jetzt dieses Gras an dieser Stelle hätten würden sie einen Übergang zueinander bilden,
hoffe das war verständlich. Hab in den letzten Jahren mit dem RPG Maker gearbeitet ^^).

Der Editor schaut aber nicht schlecht aus.

Jean

BeitragMo, Aug 04, 2008 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
Richtig. Es dient zur Ansicht im Editor.

Eben. Dann habe ich also doch recht, wenn ich behaupte, dass das erste Tile nie in der Map vorkommt.

coolo

BeitragFr, Jul 24, 2009 20:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Gibt es denn noch das Komplettpaket?
http://programming-with-design.at/ <-- Der Preis ist heiß!
That's no bug, that's my project!
"Eigenzitate sind nur was für Deppen" -Eigenzitat

Kryan

BeitragFr, Aug 14, 2009 10:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Und BladeRunner hat doch Recht:

user posted image

Oder kommt euch das nicht bekannt vor?
Webspaceanbieter?
Klick hier!
Kultige Spieleschmiede?
Klick hier!

The Shark

BeitragFr, Aug 14, 2009 13:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Bladerunner hat leider nicht recht:
user posted image
aber das war schon geklärt.

BladeRunner

Moderator

BeitragMo, Aug 17, 2009 17:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Lasst die Leiche ruhen, ich hatte nicht recht, es ist das Vorschautile, auch wenn ich das anders interpretiert hatte.
~GESCHLOSSEN~
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group