Tile Engine- Bitte Helft mir =)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Fusselohr
Beiträge: 236
Registriert: 02.04.2007 10:43
Kontaktdaten:

Beitrag von Fusselohr »

Ich glaub ich habs so einigermaßen verstanden .....

Nochmal Sorry für die Umstände

EDIT: Werde demnächst dann mal meinen Code posten.
Mein Projekt besteht immernoch und wächst stündlich.

Du willst die Entwicklung mitverfolgen ?
Dann besuche jetzt den Entwicklungsblog unter
http://rpg-fire-games.blogspot.com/
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Ich was nicht warum, aber hier is ne kleine Demo... Bild

Code: Alles auswählen

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,640,480,"Tile Engine",#WS_SYSMENU | #WS_CAPTION | 1)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

CreateSprite(0,32,32)
StartDrawing(SpriteOutput(0))
For i=0 To 15 : Box(0,i,32,1,255 - (i * 100) / 15) : Next
For i=0 To 15 : Box(0,i+16,32,1,140 - (i * 70) / 15) : Next
DrawingMode(4)
Box(0,0,32,32,$303030)
Box(1,1,30,30,$656565)
StopDrawing()

CreateSprite(1,32,32)
StartDrawing(SpriteOutput(1))
For i=0 To 15 : Box(0,i,32,1,(255 - (i * 100) / 15) << 8) : Next
For i=0 To 15 : Box(0,i+16,32,1,(140 - (i * 70) / 15) << 8) : Next
DrawingMode(4)
Box(0,0,32,32,$303030)
Box(1,1,30,30,$656565)
StopDrawing()

CreateSprite(2,32,32)
StartDrawing(SpriteOutput(2))
For i=0 To 15 : Box(0,i,32,1,(255 - (i * 100) / 15) << 16) : Next
For i=0 To 15 : Box(0,i+16,32,1,(140 - (i * 70) / 15) << 16) : Next
DrawingMode(4)
Box(0,0,32,32,$303030)
Box(1,1,30,30,$656565)
StopDrawing()

; Demo Map
Dim MapData(19,44)

For X=0 To 19
	For Y=15 To 29			
		MapData(X,Y) = 1
	Next
Next

For X=0 To 19
	For Y=30 To 44			
		MapData(X,Y) = 2
	Next
Next

SetFrameRate(60)

Repeat
	EventID = WindowEvent()
	
	ClearScreen(0)
	
	ExamineKeyboard()
			
	MapY + 1	
		
	For X=0 To 19
		For Y=0 To 15	
			DisplaySprite(MapData(X,Y + TileOffset),X * 32,Y * 32 - MapY)
		Next
	Next

	If MapY = 32
		MapY = 0 : TileOffset + 1
		
		If TileOffset = 30
			MessageRequester("Info","Map end has been reached!",64) : CloseScreen() : End
		EndIf	
	EndIf
	
	FlipBuffers()
Until KeyboardPushed(1) Or EventID = 16
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
Fusselohr
Beiträge: 236
Registriert: 02.04.2007 10:43
Kontaktdaten:

Beitrag von Fusselohr »

@ Fluid Byte: Danke für die tolle Demo ^^.

Mir gings größtenteils nur darum das ich verstehe was die einzelnen Zeilen zu bedeuten haben. Deswegen habe ich mir mal einen kleinen Code von Kaeru geholt und bei dem soweit ich konnte Notizen hinzugefügt und klitzekleine Veränderungen hinzugefügt (hoffentlich bist du mir nicht böse <) )

Hier ist er:

Code: Alles auswählen

InitSprite()
InitKeyboard()

; Öffnet den Screen
OpenScreen(1024,768,32,".::Tile Engine::.")

; Der Sprite wird geladen : ID = 101,102,103 ... und Pfad = 001,002,003 ....
For n = 1 To 4
  LoadSprite( 100+n, Right("00"+Str(n),3)+".bmp")
Next

; Die größe der Map
Dim Map(100,100)

; Jeder einzelne Tile wird als 1 definiert und erhält den Sprite 1.
For n = 0 To 100
  For t = 0 To 100
    Map(n,t) = 1
  Next
Next

Repeat
; Keyboard und Screen werden aktualisiert
ExamineKeyboard()
ClearScreen(RGB(0,0,0))

; Und das hier kapier ich überhaupt nicht ^^.
  For SY=0 To 38
    For SX = 0 To 50
      DisplaySprite(100+Map(MapX+SX,MapY+SY), 16*SX - FineX , 16*SY - FineY )
    Next
  Next

;Bildschirme tauschen
FlipBuffers()

Until  KeyboardPushed(#PB_Key_Escape)
; Fertig
Ich wollte fragen ob meine Interpretierungen richtig sind und was es damit ...

Code: Alles auswählen

; Und das hier kapier ich überhaupt nicht ^^.
  For SY=0 To 38
    For SX = 0 To 50
      DisplaySprite(100+Map(MapX+SX,MapY+SY), 16*SX - FineX , 16*SY - FineY )
    Next
  Next
... auf sich hat.

Gruß Fusselohr

PS: SCHÖNE FERIEN ^^
Mein Projekt besteht immernoch und wächst stündlich.

Du willst die Entwicklung mitverfolgen ?
Dann besuche jetzt den Entwicklungsblog unter
http://rpg-fire-games.blogspot.com/
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> was es damit ... ... auf sich hat.

das ist die eigentliche Map-"engine", die schleife, die die Map anzeigt.

vielleicht wirds etwas klara, wenn ich die Variablen ausführlicher benenne:

Code: Alles auswählen

  For Line = 0 To #TilesPerScreenY
    For Row = 0 To #TilesPerScreenX
      TileToShow = #TileSetStart + Map( PositionOnMapX + Row , PositionOnMapY + Line)
      ActualDisplayX = #TileWidth * Row - FineScrollX
      ActualDisplayY = #TileHeight * Line - FineScrollY
      DisplaySprite( TileToShow , ActualDisplayX , ActualDisplayY )
    Next
  Next
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Fusselohr
Beiträge: 236
Registriert: 02.04.2007 10:43
Kontaktdaten:

Beitrag von Fusselohr »

Ahh jetzt check ich es <) .
Und nun muss ich dafür sorgen, dass dieser Code

Code: Alles auswählen

; Jeder einzelne Tile wird als 1 definiert und erhält den Sprite 1.
For n = 0 To 100
  For t = 0 To 100
    Map(n,t) = 1
  Next
Next 
etwas anders aussieht, damit ich nicht nur ein Tile zuordnen kann. Das heißt ich brauch ne externe Datei (.map) in der ich dann die einzelnen Tiles zuordnen kann, oder ?
Mein Projekt besteht immernoch und wächst stündlich.

Du willst die Entwicklung mitverfolgen ?
Dann besuche jetzt den Entwicklungsblog unter
http://rpg-fire-games.blogspot.com/
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

Code: Alles auswählen

For SY=0 To 38
    For SX = 0 To 50
      DisplaySprite(100+Map(MapX+SX,MapY+SY), 16*SX - FineX , 16*SY - FineY )
    Next
  Next
Das ist ganz einfach, das zeichnet den Ausschnitt der Map der auf dem Bildschirm sichtbar ist.

Code: Alles auswählen

For SY=0 To 38
    For SX = 0 To 50
Einfach nur zwei for-schleifen. SY zählt die Zeilen von oben nach unten.
SX Zählt die Spalten von links nach rechts. 38 ist in diesem Fall optimalerweise ein Wert, der die Anzahl der Tiles beschreibt die untereinander auf den Bildschirm passen, also Bildschirmhöhe geteilt durch Tilehöhe.
50 ist in dem Fall entsprechend die ANzahl der Tiles die nebeneinander auf den Screen passen.
Diese Einschränkung brauchst du, weil du selbstverständlich nicht die ganze Map zeichnen willst, da ja nur ein bruchteil der Map gleichzeitig auf den Bildschirm passt.

Betrachten wir also den teil der schleife, der das Zeichnen realisiert.

Code: Alles auswählen

DisplaySprite(100+Map(MapX+SX,MapY+SY), 16*SX - FineX , 16*SY - FineY )
Map(MapX+SX,MapY+SY) liefert die Identifikation des Tiles das dargestellt werden soll an der stelle SX,SY auf deinem Bildschirm, also des segments der Karte das du grade darstellen willst. Da du ja vermutlich nicht immer nur die Linke obere Ecke der Map darstellen willst, brauchst du eine Methode den Teil der Karte zu identifizieren, der dargestellt werden soll.
Das ist zum Glück banal einfach, denn du brauchst ja nur die Koordinaten relativ nach rechts und nach untern zu verschieben um einen anderen Teil deiner Map darzustellen. Das passiert mit MapX,MapY. MapX bezeichnet also, wieweit dein darzustellender bereich vom linken Rand der Map entfernt ist, MapY dementsprechend den Abstand vom oberen Rand der Map.

Das 100+ ist nur eine Verschiebung der Sprite id relativ zur id eines Feldes deiner Map. Also bedeutet das nur, dass das Feld mit das den Wert 15 enthält mit dem Sprite 100+15=115 darzustellen ist. Das ist praktisch wenn du ein paar andere Feste Sprites Laden willst die du nachher brauchst, also hast du die Sprite IDs 0-99 Frei für dinge wie Mauszeiger und der gleichen.

So, jetzt weißt du also an welcher stelle des Bildschirms du welches Sprite darstellen musst, aber jetzt weißt du nicht genau wohin das Sprite gezeichnet werden soll.

Schauen wir uns das mal genauer anhand der ersten zu zeichnenden Zeile an...
Ok das nullte Tile auf der nullten Zeile... ok das ist leicht, das kommt natürlich an die genauen Pixelkoordinaten 0,0.

Code: Alles auswählen

#  <---Plopp... das haben wir gezeichnet... aber klopfen wir uns noch nicht auf die schulter
Fickpisse, wie finden wir jetzt heraus, wo das sprite daneben genau hinkommt.... aber ja! Wir wissen ja wie breit ein Tile ist... und das erste Tile kam an die x position 0, also war das 0*Tilebreite=0 richtig?
Könnte es dann sein, dass die x Position des Tiles daneben SX*Tilebreite ist? Probieren wir das mal: 1*Tilebreite (in dem Fall 16)=16 Wow... das hat ja funktioniert, gleich weiter
2*Tilebreite=32 Klasse, das haben wir jetzt also verstanden... Spulen wir also mal vor bis SX=50

Code: Alles auswählen

##################################################
Tja, was nun, jetzt kommt die nächste Zeile drann... aber moment... ist das nicht das exakt gleiche Problem?
Die x schleife ist jetzt in einem neuen Durchlauf, fängt also wieder bei 0 an.
SY ist jetzt aber 1.... hm, probieren wir das aus
1*16=16

Code: Alles auswählen

##################################################
#
Heureka! Das klappt mit SX=0,SY=1... probieren wir mal SX=1,SY=1

Code: Alles auswählen

##################################################
##
Ok, also scheinbar haben wir jetzt das Koordinaten Problem ebenfalls gelöst.
Damit können wir jetzt also ein Spiel machen. Was aber wenn wir nicht Tile-weise scrollen wollen, sondern weich? Naja, das bedeutet ja nur, dass wir unser grobes kästchending auchnoch Pixelweise verschieben müssen, richtig? Gucken wir mal wie der gute Kaeru das macht.

Code: Alles auswählen

16*SX - FineX , 16*SY - FineY
Der gute Kaeru scheint dafür von der Exakten Pixelweisen position der Sprites einen gewissen wert abzuziehen... das muss dann natürlich für jedes Tile der selbe wert sein (sonst machen wirs kaputt).
Kleines Quiz dazu: wie groß darf die Scrollverschiebung Maximal sein?

Klar, maximal Tilebreite, dann haben wir ja schon um eine ganze Zeile/Spalte verschoben.
Benutzeravatar
Fusselohr
Beiträge: 236
Registriert: 02.04.2007 10:43
Kontaktdaten:

Beitrag von Fusselohr »

@ Zaphod: Danke für die Saucoole Erklärung ^^.
Mein Projekt besteht immernoch und wächst stündlich.

Du willst die Entwicklung mitverfolgen ?
Dann besuche jetzt den Entwicklungsblog unter
http://rpg-fire-games.blogspot.com/
Benutzeravatar
Fusselohr
Beiträge: 236
Registriert: 02.04.2007 10:43
Kontaktdaten:

Beitrag von Fusselohr »

Also ich hab am Map-Editor weiter gemacht... habe aber das Problem das ich nur die Tilemap in einem bestimmten Bereich und nicht auf dem ganzen Screen zeichnen lassen möchte. Hat da jemand Tipps <) .

Mit freundlichen Grüßen,
Fusselohr
Mein Projekt besteht immernoch und wächst stündlich.

Du willst die Entwicklung mitverfolgen ?
Dann besuche jetzt den Entwicklungsblog unter
http://rpg-fire-games.blogspot.com/
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ist doch ganz einfach... du displayst eben nur z.b. 10x10 tiles...

damit der rand dann nicht rumhüpft, musst du halt was drüberzeichnen... ;)


PS: hast du den link zu dem thread wo du mein altes beispiel her geholt hattest?
..ich find den nich...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

Wenn du dir den Code ansiehst, dann siehst du doch die beiden Konstanten zahlen, die die Schleifendurchläufe begrenzen, in unserem Beispiel 38 für die Y Werte und 50 für die X Werte.
Wir sehen außerdem das ein Tile 16*16 Pixel groß ist.

Also, wie groß ist der Ausschnitt den wir grade Zeichnen?

50*16=800 Pixel Breite und 38*16=608 Pixel höhe.

Preisfrage: welche Werte musst du Ändern um einen kleineren Ausschnitt zu zeichnen? Die Breite der Tiles oder die Anzahl der zu zeichnenden Tiles?
Antworten