TileMap mit Draw3D

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen

D2006

Administrator

BeitragMo, Jan 25, 2010 2:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich persönlich halte derlei Optimierungen auch für wahnsinnig übertrieben und die zu erwartenden Geschindigkeitsvorteile de facto nicht vorhanden. Mit sowas verwirrt man Beginner nur unnötig.
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard
Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium
Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jan 25, 2010 2:05
Antworten mit Zitat
Benutzer-Profile anzeigen
In Spalten ausgelesene Tilemap ist auf meinem Rechner etwa 8% langsamer. Das hängt sicherlich auch davon ab, welchen Prozessor man hat. Ich hab ein AMD Phenom und auf diesem ist der Speicherkontroller im Prozessor integriert. Daher ist es hier wichtig diesen möglichst gut zu programmieren. Bei einem Intel, wo dieser immer erst raus aus dem Prozessor nach Daten abfragen muß, macht es kaum einen Unterschied. Bei einem Intel-Prozessor macht es auch kaum einen Unterschied, wie schnell der eingebaute RAM ist.

- - -

Test Draw3D2 Button=0 vs. Button=Glow

Versuchsaufbau: Tilemap mit 40x40 (1600) Tiles, angeordnet frei in 3D-Raum gekippt (nicht quadratisch) positioniert:

310/311 FPS Ohne Button (Button=0)
310/311 FPS Mit Glow als Button (Button=Glow)

Auf meinem Rechner kein messbarer Unterschied.

- - -

Test Draw3D2 2D Array in Zeilen (Linear) vs. 2D Array in Spalten

Versuchsaufbau: Tilemap mit 40x30 (1200) Tiles

509/510 FPS in Zeilen (linear)
470/471 FPS in Spalten (nicht linear)

Auf meinem Rechner etwa 8% Unterschied.

- - -

Mein Rechner (AMD Phenom X4 3.0 GHz und OnBoard Grafik ATI HD 4200).

Also mein Fazit. Die Buttonfunktion der Draw3D2 kann man getrost benutzen. Lieber die vorhandene Programmierzeit dafür aufopfern, die beiden For/Next-Schleifen auszutauschen. Wink Außerdem erlauben sie es, frei positionierte Quads ohne Fehl- oder Doppelmarkierung genau zu bestimmen.


Edit1: Klar kann man das alles weg lassen. Aber hier handelt sich sich wirklich nur um einmal markieren, dann STRG+C, dann einmal CURSOR hoch/runter (je nachdem), dann STRG+V. Und schon hat man eine optimierte Tilemap die auf vielen Rechnern gleich sofort um 8.5% schneller ist. Und durcheinander ist Morgenstern wohl erst dadurch gekommen, weil der erste Vorschlag in Codeform nicht die korrigierte Fassung hatte. Bei einer ISO-Map ist es sogar zwingend es so zu machen.

Noobody

BeitragMo, Jan 25, 2010 11:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe bei mir mal gleiche Tests durchgeführt und kam dann auf folgendes Ergebnis:

Tilemap 40x40, DrawImage3D ohne Button: FPS ~249
Tilemap 40x40, DrawImage3D mit Button: FPS ~195

Tilemap 40x40, DrawImage3D ohne Button, nonlinear: FPS ~248
Tilemap 40x40, DrawImage3D ohne Button, linear: FPS ~251

Bei mir macht mit/ohne Button also gehörig etwas aus (22%), während lineares oder nicht-lineares Auslesen praktisch keinen Unterschied macht.

Und eine Koordinatenberechnung auf einer gescrollten Tilemap halte ich nun nich für so schwierig, als dass man auf Buttons ausweichen müsste Wink BlitzBasic: [AUSKLAPPEN]
Local TileX = Floor( ( MouseX() + ScrollX )/Float( TileSize ) )
Local TileY = Floor( ( MouseY() + ScrollY )/Float( TileSize ) )

hectic hat Folgendes geschrieben:
Klar kann man das alles weg lassen. Aber hier handelt sich sich wirklich nur um einmal markieren, dann STRG+C, dann einmal CURSOR hoch/runter (je nachdem), dann STRG+V. Und schon hat man eine optimierte Tilemap die auf vielen Rechnern gleich sofort um 8.5% schneller ist. Und durcheinander ist Morgenstern wohl erst dadurch gekommen, weil der erste Vorschlag in Codeform nicht die korrigierte Fassung hatte. Bei einer ISO-Map ist es sogar zwingend es so zu machen.

'Viele' Rechner sind wohl Ansichtssache (ich kenne niemanden aus meinem Bekanntenkreis, der einen AMD besitzt), aber es ist nicht viel Aufwand, die beiden Schleifen zu vertauschen, das stimmt. Mir gefiel einfach nicht, dass du während des Grossteils des Threads über drauf bestanden hast und schlussendlich Morgenstern angefahren hast, dass er es nicht auf die Reihe bringe, etwas 'falsches' zu korrigieren. Das hatte mit seinem eigentlichen Problem nur noch wenig zu tun und trug zu dessen Lösung wohl auch nichts bei.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jan 25, 2010 20:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry Noobody, aber einen Speicher nicht linear auszulesen, obwohl es mit nur einer winzigen Änderung im Code machbar wäre, ist nicht nur ein kleines Vergehen sondern absolut falsch. Auch wenn du es vielleicht nicht so sehen magst. Frag (neutral) von mir aus einen fähigen Assembler-Programmierer zu dieser Meinung.

Das bei dir die Buttons verhältnismässig so langsam sind, könnte auch daran liegen, dass du zu 95% Wahrscheinlichkeit eine Nvidia Grafikkarte hast. Diese sind schon seit Jahren nur noch auf hohe Benchmarkwerte ausgelegt, ohne wirkliche Triogemetrie-Leistungen zu erziehlen. Und diese Buttons benötigen diese 3D-triogemetrische Berechnungen. Das der Unterschied so groß wäre, hätte ich nicht gedacht.

ungeprüft: Dein Code dürfte bei negativen Werten nicht funktionieren.

Außerdem bezweifle ich, dass du wirklich so viel deines Bekanntenkreises Prozessortyps Ahnung hast. Denn einem PC-Gehäuse sieht man es nicht an. Wenn es dir doch bekannt ist, dann bist du sicherlich einer der (in)direkten Kaufberater zu einem System geworden. Falls dieses noch vor einem bis zwei Jahren der Fall war, dann hättest du sie sogar komplett falsch beraten.

- - -

Aber gut, für mich ist das Thema abgeschlossen. Wer meint er müsse spaltenweise auslesen, kann es gerne machen.

Wink
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Noobody

BeitragMo, Jan 25, 2010 21:45
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Sorry Noobody, aber einen Speicher nicht linear auszulesen, obwohl es mit nur einer winzigen Änderung im Code machbar wäre, ist nicht nur ein kleines Vergehen sondern absolut falsch.

Als 'absolut falsch' bezeichne ich einen Code, der nicht mal im Ansatz funktioniert. Ein Code, der perfekt funktioniert und auf einigen Prozessoren eine handvoll FPS verschenkt, wäre dann ein leicht unoptimierter Code.

hectic hat Folgendes geschrieben:
Das bei dir die Buttons verhältnismässig so langsam sind, könnte auch daran liegen, dass du zu 95% Wahrscheinlichkeit eine Nvidia Grafikkarte hast. Diese sind schon seit Jahren nur noch auf hohe Benchmarkwerte ausgelegt, ohne wirkliche Triogemetrie-Leistungen zu erziehlen.

Ich habe eine ATI, und es würde mich SEHR verwundern, wenn Matheberechnungen in Blitz3D an die Grafikkarte ausgelagert werden.

hectic hat Folgendes geschrieben:
ungeprüft: Dein Code dürfte bei negativen Werten nicht funktionieren.

Das tut er nicht, aber da ein Array nur positive Indizes besitzt, wären negative Scrolling- bzw. TileX/TileY-Werte sowieso nicht sinnvoll Wink

hectic hat Folgendes geschrieben:
Außerdem bezweifle ich, dass du wirklich so viel deines Bekanntenkreises Prozessortyps Ahnung hast. Denn einem PC-Gehäuse sieht man es nicht an.

Da sich aus meiner Klasse die meisten männlichen Mitschüler den Computer selber zusammenbauten, ist mir das durchaus bekannt, da es sich die anderen doch nicht nehmen liessen, mit dem neuen System herumzuprahlen Razz Was meine Familie angeht, so kauften sich alle einen Serien-PC mit Intel Prozessor. Und ja, mir ist bewusst, dass man dem Gehäuse nicht ansieht, welcher Prozessor drinsteckt (ausser mit Röntgenblick, aber Superkräfte besitze ich leider nicht).

hectic hat Folgendes geschrieben:
Wenn es dir doch bekannt ist, dann bist du sicherlich einer der (in)direkten Kaufberater zu einem System geworden. Falls dieses noch vor einem bis zwei Jahren der Fall war, dann hättest du sie sogar komplett falsch beraten.

Ehh... was? Da fehlen einem doch glatt die Worte. Ich bin also der Grund dafür, dass sich in meinem Bekanntenkreis fast ausschliesslich Intel-CPUs befinden. Vermutlich, weil ich jeden Tag überall davon geschwärmt habe, wie toll dass doch meine Intel-CPU sei und dass es mir total wichtig sei, dass sich meine Freunde auch eine erwerben.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

M0rgenstern

BeitragMo, Jan 25, 2010 21:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, mal vorab:
Ich hab mir das ganze ein wenig genauer angeschaut.
Ich lese jetzt alles nach YWerten aus uns benutze zum Scrollen nicht mehr das Offset sondern ne andere Variable.
Vom Prinzip, also wie genau die Tilemap aufgebaut ist, hab ichs verstanden.
Das Scrollen hab ich soweit auch verstanden, von der Bewegung her.

Zwei Dinge sinds, die mir noch Probleme bereiten:

1. Die Map nur in dem Teil zu zeichnen den man auch wirklich sieht.
Da Blick ich durch die Zeile hier nicht durch:

BlitzBasic: [AUSKLAPPEN]
	;XRtv=Floor(XPos/(Tilesize))
;YRtv=Floor(YPos/(Tilesize))


Und 2.

Ich wollte einen Malbereich einprogrammieren, also ein Quadrat, das man mit + und - Zeichen vergrößern bzw verkleinern kann.

Das mach ich hiermit:

BlitzBasic: [AUSKLAPPEN]
KHPlus = KeyHit(27)
KHMinus = KeyHit(53)

If KHPlus Then
DrawSizeX = DrawSizeX + 1
DrawSizeY = DrawSizeY + 1
EndIf

If KHMinus And DrawSizeX > 1 And DrawSizeY > 1 Then
DrawSizeX = DrawSizeX - 1
DrawSizeY = DrawSizeY - 1
EndIf


Und hier wirds angezeigt und gesetzt:

BlitzBasic: [AUSKLAPPEN]
For i = -(DrawSizeX/2) To (DrawSizeX/2)
DrawImage3D(TileFrame, Mousex3d+(i*32), Mousey3d, 0, 0, 1, Gewaehlt)
Next

If MouseDown3D=1 Then

For i = -(DrawSizeX/2) To (DrawSizeX/2)
Map(x+i,y)=Gewaehlt
Next


Jetzt hab ich folgendes ProbleM. Wenn ich zuoft auf das + drücke dann bekomme ich irgendwann einen MAV Error, den der Debugger mir in dieser Zeile anzeigt:

Code: [AUSKLAPPEN]
   RenderWorld


Das gleiche passiert auch, wenn ich in hieraus:

BlitzBasic: [AUSKLAPPEN]
For i = -(DrawSizeX/2) To (DrawSizeX/2)
DrawImage3D(TileFrame, Mousex3d+(i*32), Mousey3d, 0, 0, 1, Gewaehlt)
Next


Das hier mache:
BlitzBasic: [AUSKLAPPEN]
			For i = -(DrawSizeX/2) To (DrawSizeX/2)
For i2 = -(DrawSizeY/2) To (DrawSizeY/2)
DrawImage3D(TileFrame, Mousex3d+(i*32), Mousey3d+(i2*32), 0, 0, 1, Gewaehlt)
Next
Next


Und "zu oft" aufs + drücke.
Wobei "zu oft" in diesem Fall deutlich weniger ist als ohne die zweite if SChleife.

Ich kann mir bloß nicht erklären woran das liegt.


Also, ich hab mich jetzt ernsthaft damit auseinander gesetzt, wie gesagt, am Wochenende wars eigentlich ungünstig damit anzufangen, deshalb tuts mir auch leid, dass das ganze wohl so "halbherzig" rüberkam.

Aber es wäre echt nett, wenn sich jemand erbarmen würde mir das mit dem Scrolling genauer zu erklären und wenn vllt jemand den anderen Fehler finden würde, denn ich weiß nicht worans liegt, vor allem weil er "renderWorld" als Stelle anzeigt.

Achja, hier noch der "Hauptcode:"

BlitzBasic: [AUSKLAPPEN]
Repeat

KHPlus = KeyHit(27)
KHMinus = KeyHit(53)

If KHPlus Then
DrawSizeX = DrawSizeX + 1
DrawSizeY = DrawSizeY + 1
EndIf

If KHMinus And DrawSizeX > 1 And DrawSizeY > 1 Then
DrawSizeX = DrawSizeX - 1
DrawSizeY = DrawSizeY - 1
EndIf

MH = MouseHit(2)

If MH = 1 Then Gewaehlt = (Gewaehlt+1) Mod Tileanzahl

XScroll = XScroll+(KeyDown(205)-KeyDown(203))*3
YScroll = YScroll+(KeyDown(200)-KeyDown(208))*3

;If XPos<0 Then XPos=0
;If YPos<0 Then YPos=0
;If XPos>XWALL Then XPos=XWALL
;If YPos>YWALL Then YPos=YWALL

;XRtv=Floor(XPos/(Tilesize))
;YRtv=Floor(YPos/(Tilesize))

For y = 0 To YGroesse
For x = 0 To XGroesse
DrawImage3D(TileFrame, (x)*32+XOFFSET+XScroll, (y)*32+YOFFSET+YScroll, 1, 0, 1, Map(x,y))

For i = -(DrawSizeX/2) To (DrawSizeX/2)
For i2 = -(DrawSizeY/2) To (DrawSizeY/2)
DrawImage3D(TileFrame, Mousex3d+(i*32), Mousey3d+(i2*32), 0, 0, 1, Gewaehlt)
Next
Next

If MouseDown3D=1 Then

For i = -(DrawSizeX/2) To (DrawSizeX/2)
For i2 = -(DrawSizeY/2) To (DrawSizeY/2)
Map(x+i,y+i2)=Gewaehlt
Next
Next

EndIf
Next
Next

MH = 0
KHPlus = 0
KHMinus = 0


Nach dem Was da steht kommen nur noch die Lade und Speicherroutinen.


Lg, M0rgenstern.


BTW: Ich wollte hier übrigens nicht Auslöser eines Streits sein.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jan 25, 2010 22:59
Antworten mit Zitat
Benutzer-Profile anzeigen
M0rgenstern hat Folgendes geschrieben:
1. Die Map nur in dem Teil zu zeichnen den man auch wirklich sieht.
Da Blick ich durch die Zeile hier nicht durch:

BlitzBasic: [AUSKLAPPEN]
	;XRtv=Floor(XPos/(Tilesize))
;YRtv=Floor(YPos/(Tilesize))

Eine Map die Beispielsweise immer ganze Tiles scrollen kann, hat folgenden Aufbau: Sie scrollt Scrittweise zur Scrollposition mit. Und dieses wird so berechnet, dass immer die selben Stellen im Bildschirm von Tiles bedeckt werden. Lediglich die MapPosition ändert sich. Also am Ende bei DrawImage wird das entsprechende Frame nicht über map(X,Y) sondern map(X+XMap,Y+YMap) aus dem Array ausgelesen. Dadurch sieht es so aus, als würde sich die Map verschieben, obwohl immer nur der selbe Bereich gezeichnet wird.

Bei einem pixelgenauen Scrolling, kommt hinzu das zwsichen den Schritten eine Pixelverschiebung hinzu kommt. Also ab wann die nächste Tilereihe aus dem Array gelesen werden muß. So ist beispielsweise nun XMap die Summe aus Pixelposition/TILESIZE. Die Sprünge ab wann die nächste Array-Reihe gelesen werden muß ist wiederrum die Restsummer aus so einer Division Mod dieser Pixelposition. Da es sonst zu ''Rundungsfehlern'' kommen würde, müssen über Floor alle Nachkommastellen entfernt werden. Denn genau so handelt auch Mod mit seiner Restsumme.

Um besser zu sehen wie das funktioniert, kannst du mal folgende Schleifen etwas modifizieren:

Code: [AUSKLAPPEN]
   For y = 2 To YGroesse
      For x = 2 To XGroesse

Dann erkennst du die Sprünge, die die Map macht. Denn du kannst kein Array irgendwo zwischen zwei Zellen auslesen. Du benötigst eindeutige Werte. Und genau diese Abstände müssen mit den Sprüngen und den Rest übereinstimmen.

- - -

M0rgenstern hat Folgendes geschrieben:
Ich wollte einen Malbereich einprogrammieren, also ein Quadrat, das man mit + und - Zeichen vergrößern bzw verkleinern kann.

Dein Code ist leider nicht lauffähig. Und da ich heute nicht so viel Lust auf spekulation habe, hab ich mal meine Scrollmap auf deine Bedürfnisse erweitert.
Code: [AUSKLAPPEN]
Graphics3D 1024,768,0,2
SetBuffer BackBuffer()

Local Timer=CreateTimer(58)
Local Camera=CreateCamera()
CameraClsColor Camera,64,64,64

Include "..\Includes\Draw3D2.bb"
DrawInit3D(Camera)

;Konstantenzuweisungen
Const TILESIZE=64
Const XMAPSIZE=39
Const YMAPSIZE=29
Const XOFFSET=-480
Const YOFFSET=-352
Const XWALL=1535
Const YWALL=1151

;Fonttextur laden und Schreibfähig machen
Local Font=FontRange3D(LoadImage3D("..\Fonts\KarmaticArcade(3os4p).png",2,2,0,-100)):SetFont3D(Font,1,1,-4,0)

;Bilder laden und graben
Local LoadedImage=LoadImage3D("..\Data\tilemap.png",1,2,0,-10)
Local GrabedImage=GrabAnimImage3D(LoadedImage,TILESIZE,TILESIZE,1,4)
Local Glow=LoadImage3D("..\Data\Glow.png",2,2,0,-20)

;Variablendeklarationen
Local Xi,Yi,XPos=512,YPos=512,XRtv,YRtv

;Map-Array dimensionieren
Dim Map(XMAPSIZE,YMAPSIZE)

;Zufallsmap erstellen
For Yi=0 To YMAPSIZE
   For Xi=0 To XMAPSIZE
      Map(Xi,Yi)=Rand(1,3)
   Next
Next

Local MausRad,Xj,Yj




;Hauptschleife
While Not KeyHit(1)
   
   MausRad=MausRad-MouseZSpeed()
   If MausRad>9 Then MausRad=9
   If MausRad<0 Then MausRad=0
   
   ;Maus-Mapbewegung
   If MouseDown(3) Then
      XPos=XPos-MouseXSpeed3D
      YPos=YPos-MouseYSpeed3D
   End If
   
   ;Cursor-Mapbewegung
   XPos=XPos+(KeyDown(205)-KeyDown(203))*2
   YPos=YPos+(KeyDown(200)-KeyDown(208))*2
   
   ;Bewegungsgrenzen
   If XPos<0 Then XPos=0
   If YPos<0 Then YPos=0
   If XPos>XWALL Then XPos=XWALL
   If YPos>YWALL Then YPos=YWALL
   
   ;Array Schrittmacher
   XRtv=Floor(XPos/TILESIZE)
   YRtv=Floor(YPos/TILESIZE)
   
   ;Map zeichnen
   For Yi=0 To 12
      For Xi=0 To 16
         If Map(Xi+XRtv,Yi+YRtv)>0 Then DrawImage3D(GrabedImage,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,Glow,0,1,Map(Xi+XRtv,Yi+YRtv))
         If MouseOver3D Then
            Text3D(Font,MouseXOld3D+20,MouseYOld3D,(Xi+XRtv)+" "+(Yi+YRtv),0)
            Rect3D(Glow,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,TILESIZE/2+TILESIZE*MausRad,TILESIZE/2+TILESIZE*MausRad,0,2)
         End If
         
         If MouseDown3D=1 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=1
                     End If
                  End If
               Next
            Next
         End If
         
         If MouseDown3D=2 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=2
                     End If
                  End If
               Next
            Next
         End If
         
      Next
   Next
   
   ;Positionsinfo anzeigen
   Text3D(Font,-128,-192,"<#ff0>cursor</#> or <#f00>middle mouse</#> to move map",0)
   Text3D(Font,-128,-224,"XPos : "+XPos,0)
   Text3D(Font,-128,-256,"YPos : "+YPos,0)
   
   ;Draw3D2-Standardinfo anzeigen
   Text3D(Font,-460,+340,"Draw3D2 V.1.0",0)
   Text3D(Font,+460,+340,"Time: "+CurrentTime(),2)
   Text3D(Font,0,-340,"EXAMPLE · <#fc4>CREATE 2D TILEMAP</#> · EXAMPLE",1,0,Sin(MilliSecs()))
   
   ;Standardabschluss
   WaitTimer Timer
   RenderWorld
   Clear3D()
   Flip 0
Wend
End

Das Prinzip ist in etwa gleich mit deinem Lösungsweg. Ich kann dir aber nicht sagen, warum bei dir der Fehler kommt. Du könntest aber dein Code mit notwendigen Mediadateien zusammen packen und mir oder anderen zuschicken. Dann wird die Fehlersuche um ein vielfaches erleichtert.

Zur Funktionsweise, falls du es doch selbst erst einmal ausprobieren willst:

Grundlegend sind folgende Codezeilen:

Code: [AUSKLAPPEN]
         If MouseDown3D=1 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=1
                     End If
                  End If
               Next
            Next
         End If

Innerhalb der Mapzeichenschleifen werden zwei weitere doppelt verschachtelte Schleifen zum zeichnen des Sektors benötigt. Diese richten sich nach den Vorgaben, auf welches Tile sich dieser Sektor bezieht. Dann wird umrum diesen Sektors der Bereich ausgefüllt. Da aber direkt ins Array geschrieben wird, muß darauf geachtet werden, dass nicht aus dem Array-Speicherbereiches geschrieben wird. Das machen dann noch die zwei Sicherheitsabfragen.

- - -

Noobody, lass uns den Quatsch jetzt aufhören. Keiner von uns wird seinen Standpunkt verlassen wollen. Ich habe alles aus meiner Sicht gesagt und erklärt, und du die der deinen.

Eines noch, die Draw3D2 benutzt gegenüber der Draw3D V.3.2 tatsächlich mathematische Triogemetrieberechnungen zur ''Kollisionsabfrage'' eines Buttons. Denn nur so sind überhaupt die ganzen frei stehenden Flächen als Button zu deklarieren. Wie gesagt, auf meinem Rechner kann ich beim besten Willen kein FPS-Nachteil davon ableiten. Da es da wohl noch Unterschiede gibt, werde ich bei der Veröffentlichung darauf noch eingehen.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragDi, Jan 26, 2010 17:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, ich hab jetzt alles in dieser Datei: https://www.blitzforum.de/upload/file.php?id=7875

Da ist noch so ziemlich alles wie vorher beschrieben.
Mit + und - auf der Tastatur kann man den Zeichenbereich vergrößern und mit der rechten Maustaste kann man das Tile wechseln.
Mit den Pfeiltastetn bewegt man die Map.

@ Hectic: Deinen Code habe ich jetzt extra nicht kopiert, weil ich selbst hinter die Funktionen kommen will.
Es nervt mich nämlich gewaltig, dass ich das mit der Tilemap nicht ganze gepeilt bekomme.
Das mit dem Tile-By-Tile Scrolling hab ich noch nicht ganze hinbekommen.
Wenn ich einfach in dem Drawbefehlt bei Map(x,y) stattdessen Map(x+xpos,y+ypos) schreibe, bekomme ich "Array index ut of bounds".
Ich weiß im Prinzip auch, dass es falsch ist.
Aber ich weiß auch nicht genau wies richtig geht.

Sorry, wenn ich begriffsstutzig erscheine, aber irgendwie fällt mir das Thema da schwer, weiß auch nicht warum.

Lg, M0rgenstern


EDIT:

@ Hectic:
Ich hab mir mal deinen Code angeguckt.
Wenn ich nach oben Scrolle, dann bekomme ich immer etwa bei Y = 574 einen MAV der im Debugger auf diese Zeile zurückgeführt wird: Code: [AUSKLAPPEN]
If Map(Xi+XRtv,Yi+YRtv)>0 Then DrawImage3D(GrabedImage,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,Glow,0,1,Map(Xi+XRtv,Yi+YRtv))


Wie gesagt, hab ihn mir angeguckt, bastle aber trotzdem an meinem eigenen rum.

Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Jan 26, 2010 21:07
Antworten mit Zitat
Benutzer-Profile anzeigen
M0rgenstern hat Folgendes geschrieben:
...Wenn ich einfach in dem Drawbefehlt bei Map(x,y) stattdessen Map(x+xpos,y+ypos) schreibe, bekomme ich "Array index ut of bounds".

Du musst natürlich die Eingrenzung noch vorher ausrechnen. Ich hab es in meinem Code über die beiden Konstanten XWALL und YWALL gemacht. Per Laufzeit wird es dann einfach über: Code: [AUSKLAPPEN]
   If XPos>XWALL Then XPos=XWALL
   If YPos>YWALL Then YPos=YWALL

Eingegrenzt. Das hat einfach den Vorteil, dass nicht jedes Frame alles neu berechnet werden muß und es so auch übersichtlicher ist. Blöd nur von mir, dass ich dieses als Fixwert eingetragen hab. Wird nun nachgebessert.


M0rgenstern hat Folgendes geschrieben:
Sorry, wenn ich begriffsstutzig erscheine, aber irgendwie fällt mir das Thema da schwer, weiß auch nicht warum.

Das ist kein Problem, da ich schon das Gefühl habe, dass du dich darum kümmerst. Im übrigen hat jeder irgend etwas womit er nicht klar kommt. Bei mir waren es in Anbetracht der Komplexität sehr einfache Dinge, die ich einfach nicht berechnen konnte. Heute kann ich zumindest die Sachen die für mich wichtig sind, auch meistens selbst lösen.


M0rgenstern hat Folgendes geschrieben:
Ich hab mir mal deinen Code angeguckt. Wenn ich nach oben Scrolle, dann bekomme ich immer etwa bei Y = 574 einen MAV...

Das ist so nicht richtig. Denn der von mir gepostete Code verursacht da kein MAV, auch beim debugen nicht. Der Grund warum du Probleme damit hast ist, dass du TILESIZE mal eben auf 32 umgestellt hast, wo es vorher 64 war. Dadurch ist die Map tatsächlich um die hälfte der Pixeln kleiner geworden. Sowohl in X als auch in Y. Da aber zumindest in diesem Beispiel über Pixelposition eingegrenzt wird, liegt nun die Grenze außerhalb der vorgegebenen Dimensionen, was zum Überlauf des Array führt. Denn der Code erwartet weitere Tiles, wo aber keine mehr da sind.

Aus diesem Grund hab ich mal mein Code so abgeöndert, dass wirklich alles über die Konstanten geregelt werden kann:

Code: [AUSKLAPPEN]
Const GX=1024
Const GY=768

Graphics3D GX,GY,0,2
SetBuffer BackBuffer()

Local Timer=CreateTimer(58)
Local Camera=CreateCamera()
CameraClsColor Camera,64,64,64

Include "..\Includes\Draw3D2.bb"
DrawInit3D(Camera)

;Konstantenzuweisungen
Const TILESIZE=64
Const XMAPSIZE=39
Const YMAPSIZE=29
Const XDRAWTILES=16
Const YDRAWTILES=12
Const XOFFSET=(TILESIZE-GX)/2
Const YOFFSET=(TILESIZE-GY)/2
Const XWALL=(XMAPSIZE-XDRAWTILES)*TILESIZE+TILESIZE-1
Const YWALL=(YMAPSIZE-YDRAWTILES)*TILESIZE+TILESIZE-1

;Fonttextur laden und Schreibfähig machen
Local Font=FontRange3D(LoadImage3D("..\Fonts\KarmaticArcade(3os4p).png",2,2,0,-100)):SetFont3D(Font,1,1,-4,0)

;Bilder laden und graben
Local LoadedImage=LoadImage3D("..\Data\tilemap.png",1,2,0,-10)
Local GrabedImage=GrabAnimImage3D(LoadedImage,TILESIZE,TILESIZE,1,4)
Local Glow=LoadImage3D("..\Data\Glow.png",2,2,0,-20)

;Variablendeklarationen
Local Xi,Yi,XPos=512,YPos=512,XRtv,YRtv

;Map-Array dimensionieren
Dim Map(XMAPSIZE,YMAPSIZE)

;Zufallsmap erstellen
For Yi=0 To YMAPSIZE
   For Xi=0 To XMAPSIZE
      Map(Xi,Yi)=Rand(1,3)
   Next
Next

Local MausRad,Xj,Yj




;Hauptschleife
While Not KeyHit(1)
   
   MausRad=MausRad-MouseZSpeed()
   If MausRad>9 Then MausRad=9
   If MausRad<0 Then MausRad=0
   
   ;Maus-Mapbewegung
   If MouseDown(3) Then
      XPos=XPos-MouseXSpeed3D
      YPos=YPos-MouseYSpeed3D
   End If
   
   ;Cursor-Mapbewegung
   XPos=XPos+(KeyDown(205)-KeyDown(203))*2
   YPos=YPos+(KeyDown(200)-KeyDown(208))*2
   
   ;Bewegungsgrenzen
   If XPos<0 Then XPos=0
   If YPos<0 Then YPos=0
   If XPos>XWALL Then XPos=XWALL
   If YPos>YWALL Then YPos=YWALL
   
   ;Array Schrittmacher
   XRtv=Floor(XPos/TILESIZE)
   YRtv=Floor(YPos/TILESIZE)
   
   ;Map zeichnen
   For Yi=0 To YDRAWTILES
      For Xi=0 To XDRAWTILES
         If Map(Xi+XRtv,Yi+YRtv)>0 Then DrawImage3D(GrabedImage,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,Glow,0,1,Map(Xi+XRtv,Yi+YRtv))
         If MouseOver3D Then
            Text3D(Font,MouseXOld3D+20,MouseYOld3D,(Xi+XRtv)+" "+(Yi+YRtv),0)
            Rect3D(Glow,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,TILESIZE/2+TILESIZE*MausRad,TILESIZE/2+TILESIZE*MausRad,0,2)
         End If
         
         If MouseDown3D=1 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=1
                     End If
                  End If
               Next
            Next
         End If
         
         If MouseDown3D=2 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=2
                     End If
                  End If
               Next
            Next
         End If
         
      Next
   Next
   
   ;Positionsinfo anzeigen
   Text3D(Font,-128,-192,"<#ff0>cursor</#> or <#f00>middle mouse</#> to move map",0)
   Text3D(Font,-128,-224,"XPos : "+XPos,0)
   Text3D(Font,-128,-256,"YPos : "+YPos,0)
   
   ;Draw3D2-Standardinfo anzeigen
   Text3D(Font,-460,+340,"Draw3D2 V.1.0",0)
   Text3D(Font,+460,+340,"Time: "+CurrentTime(),2)
   Text3D(Font,0,-340,"EXAMPLE · <#fc4>CREATE 2D TILEMAP</#> · EXAMPLE",1,0,Sin(MilliSecs()))
   
   ;Standardabschluss
   WaitTimer Timer
   RenderWorld
   Clear3D()
   Flip 0
Wend
End

In diesem Code wird nun leider auch die Bildschirmauflösung benötigt.

Const GX=1024
Const GY=768

Folgendes sollte klar sein. Die TILESIZE bestimmt die Dimension (Breite/Höhe) einzelner Tiles.

Const TILESIZE=64

Folgendes dimensioniert das zu benutzende 2D-Array. Wird 1:1 auf Dim Map(XMAPSIZE,YMAPSIZE) angewandt

Const XMAPSIZE=39
Const YMAPSIZE=29

Mit folgenden Konstanten kann man bestimmen, wie viele Tiles auf dem Bildschirm in X und Y (ab 0) gezeichnet werden.

Const XDRAWTILES=16
Const YDRAWTILES=12

In folgenden Konstanten wird die Map-Verschiebung so berechnet, dass unten/links gerade so mindestens ein Tile sichtbar ist.

Const XOFFSET=(TILESIZE-GX)/2
Const YOFFSET=(TILESIZE-GY)/2

In folgenden Konstanten wird berechnet, das zusammen mit X/YDRAWTILES die Eingrenzung so berechnet wird, dass nie nach Rechts/Außen das Array überlesen werden kann. Also kein ''Array out of Bounds''.

Const XWALL=(XMAPSIZE-XDRAWTILES)*TILESIZE+TILESIZE-1
Const YWALL=(YMAPSIZE-YDRAWTILES)*TILESIZE+TILESIZE-1

- - -

Ich hoffe das hilft erstmal. Wenn nicht, dann frag.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragMi, Jan 27, 2010 19:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, ich hab jetzt mal versucht das was du mir erklärt bzw gezeigt hast auf die Draw3D umzusetzen, also auf den alten Code den ich schon geschrieben hatte umzuschreiben, aber das funktioniert nicht.

Ich bekomm nen MAV bzw Array Indey out of Bounds.

Den bekomm ich schon hier angezeigt:

Code: [AUSKLAPPEN]
;Zufallsmap erstellen
For Yi=0 To YMAPSIZE
   For Xi=0 To XMAPSIZE
      Map(Xi,Yi)=2
   Next
Next


Der Code für die Draw3D2 funktioniert super. Das Problem ist nur, dass ichs umschreiben MUSS auf die Draw3D weil das Projekt, für das ich den MapEditor brauche komplett mit der Draw3D läuft.
Ansonsten würd ich die Draw3D2 nutzen.

Hier ist der ganze Code:
Wenn ich oben genanntes auskommentiere, dann zeigt er mir den Fehler in der ersten Zeichenreihe an.

Ich hab das gesamte jetzt im Prinzip verstanden, vielen Dank für eure Erklärungen, aber ich versteh das Problem nicht, dass er genau die gleiche Schleife nicht übernimmt. Das hat ja alles erstmal nichts mit Zeichenbefehlen zu tun.

Ich hoffe, mir kann jemand helfen.

Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jan 27, 2010 20:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Der mir einzig erkennbare Grund wie dieser Fehler zustande kommen kann ist, du hast nicht Dim Map(XMAPSIZE,YMAPSIZE) gemacht, sondern eigene oder andere Werte da eingetragen.

P.S.

Selbst das ''Umschreiben'' des Code von Draw3D V.3.2 auf Draw3D2 ist im grunde nicht gegeben. Einzig, folgendes:

- In der Draw3D2 wird kein automatisches DrawOrder3D mehr durchgeführt. Das überlasse ich nun den verantwortungsvollen Programmierer. Das geht ganz einfach über den letzten Parameter bei LoadImage3D, oder eben auch nachträglich über DrawOrder3D.

- Ansonsten wird auch kein Pixel umrum bei Bildern mehr automatisch abgeschnitten (bei einer Tilemap eh nicht Sinnvoll). Dieses Verhalten kann man aber über die Konstanten wieder nachtragen (Const DRAWOFFSET%=1).

- Man kann sich viele GrabImage3D-Ketten sparen, indem man einmal GrabAnimImage3D durchführt, und den Rest dann über Frames erledigt. Bei einer Tilemap wird sinnvoller Weise eh über Frames gearbeitet.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragMi, Jan 27, 2010 20:52
Antworten mit Zitat
Benutzer-Profile anzeigen
*hust*
Dummer Fehler, war genau das besagte, sorry.

Aber irgendwas in der Berechnung stimmt trotzdem nicht.

Ich bekomme jetzt in der Reihe hier nen "Array INdex out of Bounds":

Code: [AUSKLAPPEN]
If (Map(Xi+XRtv,Yi+YRtv)>0) Then DrawImage3D(TileFrame, XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE, 1, 0, 1, Map(Xi+XRtv,Yi+YRtv))


Ich weiß auch woran das liegt:
Xi ist ab einer bestimmten Stelle so groß, dass Xi + Xrtv bzw Yi + Yrtv größer als XMapsize bzw YMapzise ist, also größer als das Array selbst.

Warum funktioniert das in dem anderen Teil mit genau der gleichen Berechnung, aber hier nicht?
Ich hab den ganzen Code durchgeguckt.

Also, entweder ich hab was übersehen oder... KP...

Der ganze Code würde so aussehen (Speicherroutinen ausgelassen, und bitte nicht beachten, dass mein "Zeichenbereich" noch nicht angepasst ist):

Code: [AUSKLAPPEN]
Const GX=1024
Const GY=768

Graphics3D GX,GY,0,2
SetBuffer BackBuffer()

Local Timer=CreateTimer(58)
Local Camera=CreateCamera()
CameraClsColor Camera,64,64,64

Include "Includes\Draw3D2.bb"
DrawInit3D(Camera)

;Konstantenzuweisungen
Const TILESIZE=32
Const XMAPSIZE=39
Const YMAPSIZE=29
Const XDRAWTILES=20
Const YDRAWTILES=20
Const XOFFSET=(TILESIZE-GX)/2.1
Const YOFFSET=(TILESIZE-GY)/2.4
Const XWALL=(XMAPSIZE-XDRAWTILES)*TILESIZE+TILESIZE-1
Const YWALL=(YMAPSIZE-YDRAWTILES)*TILESIZE+TILESIZE-1

;Fonttextur laden und Schreibfähig machen
Local Font=FontRange3D(LoadImage3D("Fonts\KarmaticArcade(3os4p).png",2,2,0,-100)):SetFont3D(Font,1,1,-4,0)

;Bilder laden und graben
Local LoadedImage=LoadImage3D("Data\tilemap.png",1,2,0,-10)
Local GrabedImage=GrabAnimImage3D(LoadedImage,TILESIZE,TILESIZE,1,4)
Local Glow=LoadImage3D("Data\Glow.png",2,2,0,-20)

;Variablendeklarationen
Local Xi,Yi,XPos=512,YPos=512,XRtv,YRtv

;Map-Array dimensionieren
Dim Map(XMAPSIZE,YMAPSIZE)

;Zufallsmap erstellen
For Yi=0 To YMAPSIZE
   For Xi=0 To XMAPSIZE
      Map(Xi,Yi)=3
   Next
Next

Local MausRad,Xj,Yj
Local Gewaehlt = 1
Local MH




;Hauptschleife
While Not KeyHit(1)
   
   MH = MouseHit(2)
   
   MausRad=MausRad-MouseZSpeed()
   If MausRad>9 Then MausRad=9
   If MausRad<0 Then MausRad=0
   
   ;Maus-Mapbewegung
   If MouseDown(3) Then
      XPos=XPos-MouseXSpeed3D
      YPos=YPos-MouseYSpeed3D
   End If
   
   If MH Then Gewaehlt = (Gewaehlt + 1) Mod 4
   
   ;Cursor-Mapbewegung
   XPos=XPos+(KeyDown(205)-KeyDown(203))*2
   YPos=YPos+(KeyDown(200)-KeyDown(208))*2
   
   ;Bewegungsgrenzen
   If XPos<0 Then XPos=0
   If YPos<0 Then YPos=0
   If XPos>XWALL Then XPos=XWALL
   If YPos>YWALL Then YPos=YWALL
   
   ;Array Schrittmacher
   XRtv=Floor(XPos/TILESIZE)
   YRtv=Floor(YPos/TILESIZE)
   
   ;Map zeichnen
   For Yi=0 To YDRAWTILES
      For Xi=0 To XDRAWTILES
         If Map(Xi+XRtv,Yi+YRtv)>0 Then DrawImage3D(GrabedImage,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,Glow,0,1,Map(Xi+XRtv,Yi+YRtv))
         If MouseOver3D Then
            Text3D(Font,MouseXOld3D+20,MouseYOld3D,(Xi+XRtv)+" "+(Yi+YRtv),0)
            Rect3D(Glow,XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE,TILESIZE/2+TILESIZE*MausRad,TILESIZE/2+TILESIZE*MausRad,0,2)
         End If
         
         If MouseDown3D=1 Then
            For Yj=-MausRad To MausRad
               For Xj=-MausRad To MausRad
                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=Gewaehlt
                     End If
                  End If
               Next
            Next
         End If
         
;         If MouseDown3D=2 Then
;            For Yj=-MausRad To MausRad
;               For Xj=-MausRad To MausRad
;                  If (Xi+Xj+XRtv)=>0 And (Xi+Xj+XRtv)<=XMAPSIZE Then
;                     If (Yi+Yj+YRtv)=>0 And (Yi+Yj+YRtv)<=YMAPSIZE Then
;                        Map(Xi+Xj+XRtv,Yi+Yj+YRtv)=2
;                     End If
;                  End If
;               Next
;            Next
;         End If
         
      Next
   Next



Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jan 27, 2010 21:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Der von dir beschriebene Fehler kann nur dann zustande kommen, wenn jeweils X/YDRAWTILES größer als X/YMAPSIZE eingestellt ist.

Ansonsten kann ich nur wenige dazu sagen, weil die von dir beschriebene Fehlerzeile aus einem anderem Code zu sein scheint, als der Komplettcode weiter unten. Ein vernünftiger Vergleich geht so schon mal gar nicht.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragMi, Jan 27, 2010 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
OH VERDAMMT.

Sorry, ich war im falschen Fenster von IDEAL.

Der richtige Code wäre der hier:

Code: [AUSKLAPPEN]
AppTitle "StrategieGame"

Global XGroesseString$ = "29"
Global YGroesseString$ = "29"
Global XGroesse
Global YGroesse


;XGroesseString$ = Input$("Bitte gib die XGroesse der Map ein: ")
;YGroesseString$ = Input$("Bitte gib die YGroesse der Map ein: ")

Const XMAPSIZE=30
Const YMAPSIZE=30

Const GX=1024
Const GY=768

Include "Includes\Draw3D.bb"

Graphics3D GX,GY,0,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Local Timer=CreateTimer(58)
Global Camera=CreateCamera()
CameraClsColor Camera,5,5,5
DrawInit3D(Camera)
Origin3D(1024,768)


Dim Map(XMAPSIZE,YMAPSIZE)

Const TILESIZE=32

Const XDRAWTILES=20
Const YDRAWTILES=20
Const XOFFSET=(TILESIZE-GX)/2.1
Const YOFFSET=(TILESIZE-GY)/2.4
Const XWALL=(XMAPSIZE-XDRAWTILES)*TILESIZE+TILESIZE-1
Const YWALL=(YMAPSIZE-YDRAWTILES)*TILESIZE+TILESIZE-1

Local Xi,Yi,XPos=512,YPos=512,XRtv,YRtv



Global Tileanzahl = 0
Global Tiles = LoadImage3D("gfx\Tiles\TileSet1.png", 1)

Global TileFrame = GrabImage3D(Tiles, 0, 0, 32, 32) : Tileanzahl = Tileanzahl+1
For i = 1 To 3
   GrabImage3D(Tiles, i*32, 0, 32, 32)
   Tileanzahl = Tileanzahl + 1
Next

;Zufallsmap erstellen
For Yi=0 To YMAPSIZE
   For Xi=0 To XMAPSIZE
      Map(Xi,Yi)=2
   Next
Next

Local DrawSizeX = 1
Local DrawSizeY = 1
Local KHPlus, KHMinus

Global Gewaehlt = 1
Local MH

Repeat
   
   KHPlus = KeyHit(27)
   KHMinus = KeyHit(53)
   
   If KHPlus Then
      DrawSizeX = DrawSizeX + 1
      DrawSizeY = DrawSizeY + 1
   EndIf
   
   If KHMinus And DrawSizeX > 1 And DrawSizeY > 1 Then
      DrawSizeX = DrawSizeX - 1
      DrawSizeY = DrawSizeY - 1
   EndIf
   
   MH = MouseHit(2)
   
   If MH = 1 Then Gewaehlt = (Gewaehlt+1) Mod Tileanzahl
   
   XPos = XPos+(KeyDown(205)-KeyDown(203))*2
   YPos = YPos+(KeyDown(200)-KeyDown(208))*2
   
   If XPos<0 Then XPos=0
   If YPos<0 Then YPos=0
   If XPos>XWALL Then XPos=XWALL
   If YPos>YWALL Then YPos=YWALL
   
   XRtv=Floor(XPos/(TILESIZE))
   YRtv=Floor(YPos/(TILESIZE))
   
   For Yi = 0 To YMAPSIZE
      For Xi = 0 To XMAPSIZE
         If (Map(Xi+XRtv,Yi+YRtv)>0) Then DrawImage3D(TileFrame, XOFFSET-(XPos Mod TILESIZE)+Xi*TILESIZE,YOFFSET-(YPos Mod TILESIZE)+Yi*TILESIZE, 1, 0, 1, Map(Xi+XRtv,Yi+YRtv))
         
         For i = -(DrawSizeX/2) To (DrawSizeX/2)
            For i2 = -(DrawSizeY/2) To (DrawSizeY/2)
               DrawImage3D(TileFrame, Mousex3d+(i*32), Mousey3d+(i2*32), 0, 0, 1, Gewaehlt)
            Next
         Next
         
         If MouseDown3D=1 Then
            
            For i = -(DrawSizeX/2) To (DrawSizeX/2)
               For i2 = -(DrawSizeY/2) To (DrawSizeY/2)
                  Map(Xi+i,Yi+i2)=Gewaehlt
            Next
         Next
            
         EndIf
      Next
   Next
   
   MH = 0
   KHPlus = 0
   KHMinus = 0
   


Tut mir echt leid.

Lg, M0rgenstern


EDIT:

Hab den Fehler gefunden:

Ich hatte bei den Forschleifen zum Zeichnen die komplette XMapsize/YMapsize drin und hätte da eigentlich mit der Drawsize arbeiten müssen.

Lg, M0rgenstern.

Vielen Dank für eure Hilfe. Ich habs jetzt verstanden und werde den Rest bestimmt allein hinbekommen, wenn nicht frag ich einfach nochmal^^.

Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jan 27, 2010 23:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Du hast geändert:

Code: [AUSKLAPPEN]
   For Yi=0 To YDRAWTILES
      For Xi=0 To XDRAWTILES

zu

Code: [AUSKLAPPEN]
   For Yi = 0 To YMAPSIZE
      For Xi = 0 To XMAPSIZE


Du nimmst X/YDRAWTILES (eine Konstante die einzig nur daür da ist genau das zu bestimmen) da einfach weg, ersetzt es durch das Maximum eines Arrays, nämlich X/YMAPSIZE (wird auf Dim Map(XMAPSIZE,YMAPSIZE) angesetzt) und addierst später noch Werte hinzu, so muß es zwangsläufig zu einem Überlauf kommen.

Tipp: Wenn du was änderst, wovon du dir nicht Sicher bist, dann teste das geänderte nach. Und zwar so, dass du die Map an alle Grenzen links/rechts/oben/unten bis zum Anschlag bewegst, und darauf achtest was passiert und daraif achtest, ob tatsächlich auch die letzten Tiles noch angezeigt werden. Soll heissen, zu jeder Änderung machst du ein KOMPLETT-FEHLERTEST. Auch wenn viele es nicht glauben mögen, aber ich teste auch alles mögliche, wenn ich mal was an der Draw3D2 ändere. Solche Tests können bei der Draw3D2 dann auch schon mal ein paar Stunden dauern. Nimm dir Zeit, und ändern nicht 20 Sachen auf einmal.

Edit1:

Tipp:

Code: [AUSKLAPPEN]
Local VarString$="12"
Local VarInteger%=Int(VarString)

Print VarString
Print VarInteger
VarInteger=VarInteger+1
Print VarInteger

WaitKey

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group