2d Karte, skalierung....

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ich hab vor die Hauptschleife mal

Code: Alles auswählen

For t=0 To #MapY
  For n=0 To #MapX
    Map(n,t)\typ = Random(1)
  Next
Next
hinzugefügt, damit man überhaupt was sieht.
dein setzen/löschen ist übrigens nicht richtig, dabei beachtest du die rotation nicht.
...und das debugger-fenster sollte man im fullscreen modus nicht unbedingt verwenden... xD

und naja, das ist nur ne 90° rotation, natürlich ist die einfach...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
kswb73
Beiträge: 319
Registriert: 04.02.2008 16:51
Kontaktdaten:

Beitrag von kswb73 »

Ups, danke. Werd ich gleich mal änder.

/Edit
so hier in überarbieteter Form. Die Felder werden jetzt auch noch selber rotiert (sieht man aber nichts von). Ein Zufälliges Feld wird erstellt und die MouseMapX und MouseMapY Kordinate stimmt jetzt, womit die Maus wieder richtig auf dem Feld liegt.


Code: Alles auswählen

#MapX=50
#MapY=50

InitSprite()
InitSprite3D()
InitMouse()
InitKeyboard()

Structure Map
typ.b
EndStructure

Dim Map.Map(#MapX,#MapY)

OpenScreen(1024,768,32,"Map-Test")

CreateSprite(1,50,50,#PB_Sprite_Texture)
  StartDrawing(SpriteOutput(1))
  Box(0,0,50,50,0)
  Box(1,1,48,48,$00FF00)
  StopDrawing()
CreateSprite3D(1,1)

CreateSprite(2,50,50,#PB_Sprite_Texture)
  StartDrawing(SpriteOutput(2))
  Box(0,0,50,50,0)
  Box(1,1,48,48,$0000FF)
  StopDrawing()
CreateSprite3D(2,2)

CreateSprite(3,10,20)
  StartDrawing(SpriteOutput(3))
  Line(0,0,0,20,$FF0000)
  Line(0,0,10,20,$FF0000)
  StopDrawing()

viewX=-100
viewY=-100
Zoom.f=1


For a=0 To #MapX
  For b=0 To #MapX
  Map(a,b)\Typ=Random(1)
  Next b
Next a

Repeat
  If IsScreenActive()
  ClearScreen(0):ExamineKeyboard():ExamineMouse()
  
  
    If KeyboardReleased(#PB_Key_Escape)
    End
    EndIf
    
    If KeyboardPushed(#PB_Key_Left)
    viewX-5*Zoom
    EndIf
    
    If KeyboardPushed(#PB_Key_Right)
    viewX+5*Zoom
    EndIf
    
    If KeyboardPushed(#PB_Key_Up)
    viewY-5*Zoom
    EndIf
    
    If KeyboardPushed(#PB_Key_Down)
    viewY+5*Zoom
    EndIf
    
    Start3D()
    If KeyboardReleased(#PB_Key_Y)
    rotate-1
    RotateSprite3D(1,-90,1)
      If rotate<0
      rotate+4
      EndIf
    EndIf
    
    If KeyboardReleased(#PB_Key_X)
    rotate+1
    RotateSprite3D(1,90,1)
      If rotate>3
      rotate-4
      EndIf
    EndIf
  
    
      If MouseWheel()
        If MouseWheel()<0
        Zoom*2
        Else
        Zoom/2
        EndIf
        If Zoom<1
        Zoom=1
        ElseIf Zoom>16
        Zoom=16
        EndIf
      ZoomSprite3D(1,50/Zoom,50/Zoom)
      ZoomSprite3D(2,50/Zoom,50/Zoom)
        
      EndIf
      
    MouseMapX=MouseX()*Zoom+viewX
    MouseMapY=MouseY()*Zoom+viewY
       If rotate=1
       MouseMapX=(#MapX+1)*50-MouseMapX
       ElseIf rotate=2
       MouseMapX=(#MapX+1)*50-MouseMapX
       MouseMapY=(#MapY+1)*50-MouseMapY
       ElseIf rotate=3
       MouseMapY=(#MapY+1)*50-MouseMapY
       EndIf
      
    If MouseMapX>0 And MouseMapX<#MapX*50+49 And MouseMapY>0 And MouseMapY<#MapY*50+49
      If MouseButton(2)
      Map(MouseMapX/50,MouseMapY/50)\Typ=1
      ElseIf MouseButton(1)
      Map(MouseMapX/50,MouseMapY/50)\Typ=0
      EndIf
    EndIf
      
    For a=0 To #MapX
      For b=0 To #MapY
      
        If rotate=0
        c=Map(a,b)\Typ
        ElseIf rotate=1
        c=Map(#MapX-a,b)\Typ
        ElseIf rotate=2
        c=Map(#MapX-a,#MapY-b)\Typ
        ElseIf rotate=3
        c=Map(a,#MapX-b)\Typ
        EndIf
        
        Select c
          Case 0
          DisplaySprite3D(1,(a*50-viewX)/Zoom,(b*50-viewY)/Zoom)
          Case 1
          DisplaySprite3D(2,(a*50-viewX)/Zoom,(b*50-viewY)/Zoom)
        EndSelect 
        
      Next b
    Next a
    Stop3D()
  
  StartDrawing(ScreenOutput())
  DrawText(10,10,Str(mouseMapX)+"|"+Str(MouseMapY))
  StopDrawing()
  
  DisplayTransparentSprite(3,MouseX(),MouseY())
  EndIf
FlipBuffers()
ForEver
Zuletzt geändert von kswb73 am 03.09.2008 16:13, insgesamt 1-mal geändert.
Windows XP: PB 4.31, PB 4.4, PB 4.51
Open Suse 11.2: PB 4.4
Benutzeravatar
Bisonte
Beiträge: 2471
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Sollte man das ganze auf minimale größe zoomen (zoomOut) wird nicht mehr überprüft,
ob der Mauszeiger überhaupt im Feld ist. Gibt beim rechten Rand einen unschönen Error. (Array Index out of bounds)

da solltest du dann noch eine Kontrolle einbauen das das nicht passiert.
Grob gesagt:

Wenn Mausknopf=1 und X-Achse größer als MapGrößeX dann Mauskoord=MapgrößeX

Aber by the way, bei einfarbigen Feldern sieht das ja noch ansehnlich aus beim zoomen. Sollte aber ein richtiges Bild zu sehen sein (zB ein Baum)
dann ist das weit entfernt von Erkennbarkeit.
Dagegen könnte man TileSizeGroessenSchritte einbauen.
zB 32,48,64 usw. ist dann aber wohl Bildabhängig.

Aber was Toshy wohl meinte (wenn Travian immer noch in seinem Projekt steckt ;) ) ist dann ein Iso-Ansicht der Karte.
Und dazu ist Toshys Aussage:
dann will ich nicht auf einmal erleben das ich dafür komplett alles hätte anders machen müssen.
wohl leider richtig. das ist dann ein anderes Prinzip, zumindest was koordinatenberechnungen angeht...

Edit: Also Jungs, ich muss schon sagen, das Forum hier ist bis jetzt im Bereich PB-Programmierung das lehrreichste was ich je erlebt habe. :allright:
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
kswb73
Beiträge: 319
Registriert: 04.02.2008 16:51
Kontaktdaten:

Beitrag von kswb73 »

ändere Zeile 113 mal in
If MouseMapX>0 And MouseMapX<#MapX*50+49 And MouseMapY>0 And MouseMapY<#MapY*50+49
dann klaps. War ein Tippfehler.
Windows XP: PB 4.31, PB 4.4, PB 4.51
Open Suse 11.2: PB 4.4
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Kaeru Gaman hat geschrieben: > einfach eine Hintergrundgrafik die ich jeden Aufruf (z.b. einige male in der Sekunde) die ich neu kopieren muß und daruaf dann die Elemente?
wenn du eine hintergrundgrafik brauchst?
aber oft wählt man den kartenausschnitt so groß, dass er den Screen komplett ausfüllt,
man braucht also keinen Hintergrund dahinter eigentlich nichtmal ein Clear.
oder man wählt eine feste farbe für den hintersten Hintergrund, die man dann direkt bei ClearScreen angibt.
Mit Hintergrundkrafik meine ich ja im Grunde die unterste Ebene der KArte.
Wollte halt eine einzige durchgehende Grafik verwenden (eventuell mit kopieren einer kleinen Grafik eine große Grafik erstellen)
> Aber wenn ich dir Karte z.B. um 45% drehen will damit sie auf der Kante steht, wie könnte ich dann die Positionen usw. in erfahrung bringen?
ja, da wird die Mathematik dahinter um einiges komplizierter, aber machbar ist es.
am praktischsten wäre es, die koordinaten direkt im moment der darstellung zu vergleichen,
da man ja für die darstellung ausrechnen muss, wo man momentan grad das tile und das objekt hin Displayt,
da kann man auch mit den Mauskoordinaten vergleichen und die schleifenposition rückpuffern.
Das habe ich "befürchtet". Alles "handarbeit" und keine Routine die einem das abnimmt. Na ich fang dann erstmal klein an ohne zu drehen und später... eins nach dem anderen. Wir für den ersten Versuch ja nur wenig Code da ist es egal den komplett neu zu machen wenn es notwendig wird.

Mit 90% drehen hat vermutlich damit zu tun, weil man dann ja nur die x und y - Werte "tauschen" muß. Aber bei der MAP mit der ich starte geht das nicht. Der sinn wäre gewesen, weil in dem Originalbrowserspiel die Welt auch in einem 45% Winkel steht. Ich wollte die Ansicht so besser vergleichbar machen.

@kswb73
Danke, ich werde mich mal die Tage an eine KArte machen und deinen Teil dann genau testen und druchschauen.
1. Win10
PB6.1
Benutzeravatar
Bisonte
Beiträge: 2471
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Toshy hat geschrieben:Der sinn wäre gewesen, weil in dem Originalbrowserspiel die Welt auch in einem 45% Winkel steht. Ich wollte die Ansicht so besser vergleichbar machen.
Sag ich doch. Diese Ansicht nennt man ISO-Ansicht oder Isometrische welche... Die ist ein wenig aufwendiger zu programmieren als die klassische
2D Draufsicht...

Aber auch kein Problem ... einfach mal die Boardsuche bemühen und nachfragen. Kaeru war da glaub ich auch ganz versiert drin ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ob ISO oder 45° Draufsicht ist nicht mehr der SO große unterschied.

ein grundsätzlicher Unterschied bei 2.5D-Perspektive im Gegensatz zu Draufsicht ist,
dass man immer hinten oben mit dem draufzeichnen anfangen muss,
weilobjekte von "vorne" liegenden positionen nach "oben" überstehen können,
sie müssen also später als "hintere" Tiles gezeichnet werden.

bei 45° zeichnen ist die eigentliche darstellung recht einfach:
wir drehen die matrix um 45° nach rechts, also eine zeile läuft nach rechts abwärts.
die spalten zählen wir mit n, die zeilen mit t.
mit jedem n gehst du 1/2 tile nach rechts und 1/2 tile nach unten,
mit jedem t 1/2 nach links und 1/2 tile nach unten.

also:
TileX = HalbTile * n - HalbTile * t : TileY = HalbTile * n + HalbTile * t
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten