Geänderte Version von TransformSprite3D

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Drago
Beiträge: 148
Registriert: 02.02.2010 18:22
Computerausstattung: Win XP SP3, AMD Sempron (MMX) 1.2 GHz, 512 MB, Nvidia GeForce FX 5200, 128 MB, DirectX 9.0c
Wohnort: Westerwald

Geänderte Version von TransformSprite3D

Beitrag von Drago »

Guten Abend Leute....

Ich weis nicht genau ob es euch etwas bringt, oder ob es sowas schon gibt,
aber ich habe mit dem Code von Stargate etwas experimentiert.
Dabei ist mir aufgefallen, das meine Sprites verkehrt herum waren.
Ansonsten habe ich nur eine Kleinigkeit geändert.
Das Rotationscentrum wird nun innerhalb des Sprites verschoben und das
Sprite auch um das Centrum rotiert.
Ich habe ein Beispiel programmiert, damit könnt ihr ein wenig spielen...
Ich denke dann seht ihr selber wie es funktioniert.

Drago

Hier der Code:

Code: Alles auswählen

;****************************************************************************************
;                                 Verändertes TransformSprite3D
; Ursprungsautor    : Stargate
; Dieb/Bastler        : Drago 
; Sternenzeit         : 31. Juli 2011 / 23.59 Uhr
;****************************************************************************************

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitSprite3D()=0 Or InitSound()=0 Or InitMouse()=0
  MessageRequester("Error", "Can't open DirectX 7 or later", 0)
  End
EndIf

If OpenScreen(1024,768,32,"Test")=0
  MessageRequester("Error", "Can't open Screen", 0)
  End
EndIf

SetFrameRate(30)

; Zoom und Rotate und Display von einem Sprite3D
; ----------------------------------------------
; Sprite - Nummer des Anzuzeigenen Sprite
; x      - X-Positon des Mittelpunks bzw. Rotationspunkts vom Sprite
; y      - Y-Positon des Mittelpunks bzw. Rotationspunkts vom Sprite
; xx     - Breite des Sprite
; yy     - Höhe des Sprite
; w      - Rotationswinkel des Sprite (in Grad, wobei 0° Richtung Osten ist)
; dx     - Verschiebt den Mittelpunkt und damit auch den Rotationspunkt
;          auf dem Sprite in X-Richtung
; dy     - Verschiebt den Mittelpunkt und damit auch den Rotationspunkt
;          auf dem Sprite in Y-Richtung
; h      - Transparenz des Sprite (0 Transparent, 255 voll sichtbar)

Procedure DisplayZoomRotateSprite3D(Sprite, x, y, xx, yy, w.f, dx, dy, h)
  
  Protected r.f, t.f, w1.f, w2.f, w3.f, w4.f
  x - xx/2
  y - yy/2
  w - 90

  If w < 0: w+360: EndIf
  
  w = w * (#PI/180)
  r.f = Sqr(Pow(xx,2)+Pow(yy,2))/2
  t.f = ATan(xx/yy)
  w1.f = w       - t : w2.f = w       + t : w3.f = w + #PI - t : w4.f = w + #PI + t
  TransformSprite3D(Sprite, Cos(w1)*r, Sin(w1)*r, Cos(w2)*r, Sin(w2)*r, Cos(w3)*r, Sin(w3)*r, Cos(w4)*r, Sin(w4)*r)
  
  DisplaySprite3D(Sprite, x +Cos(w)*dy+Sin(w)*dx+dx, y+Sin(w)*dy-Cos(w)*dx+dy, h)
 
EndProcedure

Global Sprite1_GL.l = CreateSprite( #PB_Any, 128, 128, #PB_Sprite_Texture )

StartDrawing( SpriteOutput(Sprite1_GL) )

DrawingMode( #PB_2DDrawing_Outlined )
Box( 0, 0, 128, 128, RGB( 255, 255, 0 ) )
For I = 1 To 8
  LineXY( 0, 59 + I, 128, 59 + I, RGB( 20*I, 20*I, 255 ))
Next

StopDrawing()

Sprite1_GL = CreateSprite3D( #PB_Any, Sprite1_GL)

x   = 512
y   = 384
xx = 128
yy = 128
dx = 0
dy = 0
w  = 135

Repeat
  
  ClearScreen(0) 
  
  Start3D()
  
  Sprite3DQuality(0)
  DisplayZoomRotateSprite3D(Sprite1_GL, x, y, xx, yy, 0, 0, 0, 80 )
  DisplayZoomRotateSprite3D(Sprite1_GL, x, y, xx, yy, w, dx, dy, 255)
  
  Stop3D()
  
  StartDrawing(ScreenOutput())
  
  DrawingMode( #PB_2DDrawing_Outlined | #PB_2DDrawing_Transparent )
  Circle( 380, 40, 4, RGB( 255, 0, 0 ) )
  Plot  ( 380, 40, RGB( Random(255), Random(255),255 ) ) 
  
  Circle( x + dx - xx / 2, y+dy - yy / 2, 4, RGB( 255, 0, 0 ) )
  Plot( x + dx - xx / 2, y + dy - yy / 2, RGB( Random(255), Random(255),255 ) ) 
  
  DrawText( 410, 30, "= RotationsCentrum", RGB( 255, 255, 255 ) )
  DrawText( 250, 600," Corsor links/rechts verschiebt das Rotationsxentrum auf der x - Achse", RGB( 255, 255, 255 ) )
  DrawText( 250, 620," Corsor hoch/runter verschiebt das Rotationsxentrum auf der y - Achse", RGB( 255, 255, 255 ) )
  DrawText( 250, 640,"                   + = erhöht den Rotationswinkel", RGB( 255, 255, 255 ) )
  DrawText( 250, 660,"                    - = erniedrigt den Rotationswinkel", RGB( 255, 255, 255 ) )
  
  StopDrawing()
  
  FlipBuffers()
  
  Delay(1)
  
  ExamineKeyboard()
  
  If KeyboardPushed( #PB_Key_Left )
    dx - 1
  EndIf
  
  If KeyboardPushed( #PB_Key_Right )
    dx + 1
  EndIf
  
  If KeyboardPushed( #PB_Key_Up )
    dy - 1
  EndIf
  
  If KeyboardPushed( #PB_Key_Down )
    dy + 1
  EndIf
  
  If KeyboardPushed( #PB_Key_Add )
    w + 1
    If w > 360: w - 360: EndIf
  EndIf
  
  If KeyboardPushed( #PB_Key_Subtract )
    w - 1
    If w < 0: w + 360: EndIf
  EndIf
  
Until KeyboardPushed( #PB_Key_Escape)
Zuletzt geändert von Drago am 31.07.2011 08:00, insgesamt 2-mal geändert.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Geänderte Version von TransformSprite3D

Beitrag von STARGÅTE »

Das mein alter Code noch hier rum schwebt ist mir echt peinlich ^^
weil er mit dem ganzen sin/cos/tan extral langsam ist.

Das mit dem "verkehrt herum" ist 'n Definitionssache, nämlich wolang 0° sind, und wo 0° beim original waren.
(das nur am Rande)

Hier mal 'n neuere Version die vielleicht "komplexer" aussieht, aber für den PC einfacher ist:

Code: Alles auswählen

; Verformt ein Sprite3D und zeigt es an.
;   (X,Y) ist dabei die Position des Mittelpunkts,
;   (CenterX,CenterY) die Verschiebung des Rotationspunkt vom Mittelpunkt.
Procedure DisplayTransformSprite3D(Sprite3D, X.f, Y.f, Width.f, Height.f, Angle.f, CenterX.f=0, CenterY.f=0, Transparency=255) 
	Protected Sin.f = Sin(Radian(Angle)), Cos.f = Cos(Radian(Angle))
	TransformSprite3D(Sprite3D, Cos*(-Width*0.5-CenterX) - Sin*(-Height*0.5-CenterY), Sin*(-Width*0.5-CenterX) + Cos*(-Height*0.5-CenterY), Cos*( Width*0.5-CenterX) - Sin*(-Height*0.5-CenterY), Sin*( Width*0.5-CenterX) + Cos*(-Height*0.5-CenterY), Cos*( Width*0.5-CenterX) - Sin*( Height*0.5-CenterY), Sin*( Width*0.5-CenterX) + Cos*( Height*0.5-CenterY), Cos*(-Width*0.5-CenterX) - Sin*( Height*0.5-CenterY), Sin*(-Width*0.5-CenterX) + Cos*( Height*0.5-CenterY))
	DisplaySprite3D(Sprite3D, X, Y, Transparency) 
EndProcedure 

InitSprite()
InitSprite3D()

OpenWindow(1, 0, 0, 800, 600, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(1), 0, 0, WindowWidth(1), WindowHeight(1), 0, 0, 0)

CreateSprite(1, 128, 32, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
	FillArea(0, 0, #PB_Any, $FFFF00)
	DrawText(10, 10, "Hallo Welt!", $FFFFFF, $0000FF)
StopDrawing()
CreateSprite3D(1, 1)

Repeat
	
	Repeat
		
		Select WindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #Null
				Break
		EndSelect
		
	ForEver
	
	Time.f = ElapsedMilliseconds()/10
	
	ClearScreen(0)
	
	If Start3D()
		
		DisplayTransformSprite3D(1, 400, 300, 600, 150, 0, 0, 0, 64) 
		DisplayTransformSprite3D(1, 400, 300, 600, 150, Time, WindowMouseX(1)-400, WindowMouseY(1)-300) 
		
		Stop3D()
	EndIf
	
	FlipBuffers()
	
Until WindowEvent() = #PB_Event_CloseWindow
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Drago
Beiträge: 148
Registriert: 02.02.2010 18:22
Computerausstattung: Win XP SP3, AMD Sempron (MMX) 1.2 GHz, 512 MB, Nvidia GeForce FX 5200, 128 MB, DirectX 9.0c
Wohnort: Westerwald

Re: Geänderte Version von TransformSprite3D

Beitrag von Drago »

@Stargate:

Das mit dem verkehrt rum meinte ich so:

Wenn ich ein Sprite zeichne, so ist es einfacher wenn es bei
0 Grad so angezeigt wird, wie ich es gezeichnet habe.
So muß ich beim arbeiten nicht immer wieder "umdenken",
wenn ich zeichne und wenn ich programmiere....

Raumschiff wird mit der Spitze nach oben gezeichnet und auch
so imm Programm angezeigt!!!

Nun, was das betrifft, da hatte ich doch noch einen kleinen Bug
in meinem Programm,
habe ich aber im Code oben behoben.... :mrgreen:
Antworten