3D-Kegel (transparent) auf 2D abbilden

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

3D-Kegel (transparent) auf 2D abbilden

Beitrag von TomS »

Hallo.

Ich versuche gerade einen Showlaser zu simulieren (optisch auf Screen). Dieser strahlt von unten Kegelförmig nach oben.
Die einzelnen Strahlen gehen jetzt einfach von links nach rechts und in die andere Richtung, wenn sie an den Rand stoßen. Das sieht nicht sehr realistisch aus.

Hat vielleicht jemand eine Idee, wie man das besser lösen kann?

Code:
Bin auf eure Antworten gespannt.

MfG, Thomas
Zuletzt geändert von TomS am 27.03.2008 02:32, insgesamt 1-mal geändert.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Poste doch bitte den Code hier im Forum (so lang ist er ja nun nicht),
dann bleibt er erhalten und es kommen keine Codeanfragen.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Der bleibt auch so erhalten^^

Aber hier bitte:

Code: Alles auswählen

#SCREEN_WIDTH=400

OpenWindow(1,0,0,210,135,"LASER - Settings",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(1))
  TextGadget(101,5,8,100,14,"Anzahl der Laser:")
  SpinGadget(1,105,5,30,20,1,2, #PB_Spin_Numeric| #PB_Spin_ReadOnly)
  SetGadgetText(1,"1")
  
  TextGadget(102,5,33,100,14,"Anzahl der Beams:")
  SpinGadget(2,105,30,30,20,1,50, #PB_Spin_Numeric| #PB_Spin_ReadOnly)
  SetGadgetText(2,"10")
  
  TextGadget(103,5,58,100,14,"Farbe für Laser 1:")
  ComboBoxGadget(3,105,55,100,20)
  	AddGadgetItem(3,0,"Rot")  	
  	AddGadgetItem(3,0,"Grün")  	
  	AddGadgetItem(3,0,"Blau")  	
  	AddGadgetItem(3,0,"Weiß")
  	AddGadgetItem(3,0,"Zufällig")
 SetGadgetState(3,0)
  
  TextGadget(104,5,83,100,14,"Farbe für Laser 2:")
  ComboBoxGadget(4,105,80,100,20)
  	AddGadgetItem(4,0,"Rot")  	
  	AddGadgetItem(4,0,"Grün")  	
  	AddGadgetItem(4,0,"Blau")  	
  	AddGadgetItem(4,0,"Weiß")
  	AddGadgetItem(4,0,"Zufällig")
 SetGadgetState(4,0)
 
 ButtonGadget(5,5,110,200,20,"O K")  
  
  Repeat
  event=WaitWindowEvent()
  If event=#PB_Event_Gadget
  Select EventGadget()
  
	Case 5	
	laser_color1.s=GetGadgetText(3)
	laser_color2.s=GetGadgetText(4)
	laser=Val(GetGadgetText(1))
	NUMBER_OF_BEAMS=Val(GetGadgetText(2))	
	CloseWindow(1)
	weiter=1  
  EndSelect
  EndIf 
  
  If event=#PB_Event_CloseWindow
  End 
  EndIf 
  
  Until weiter=1  

abstand=(#SCREEN_WIDTH/NUMBER_OF_BEAMS)*2

Structure beam
    xpos.l
    direction.l    
    rgb.l
EndStructure

 NewList laser.beam()

For var=1 To NUMBER_OF_BEAMS
	AddElement(laser())
		laser()\xpos=var*abstand/laser
		If laser()\xpos<=#SCREEN_WIDTH/laser
			laser()\direction=1
			
		ElseIf laser()\xpos>=#SCREEN_WIDTH/laser
			laser()\direction=-1
			laser()\xpos=(NUMBER_OF_BEAMS-var)*abstand/laser				EndIf 		
		
		Select laser_color1
		Case "Zufällig"
			laser()\rgb=RGB(Random(150)+100,Random(150)+100,Random(150)+100)
		Case "Grün"
			laser()\rgb=RGB(0,255,0)
		Case "Rot"
			laser()\rgb=RGB(255,0,0)
		Case "Blau"
			laser()\rgb=RGB(0,0,255)
		Case "Weiß"
			laser()\rgb=RGB(255,255,255)
		EndSelect 		
Next  

NewList laser2.beam()

For var=1 To NUMBER_OF_BEAMS
	AddElement(laser2())
		laser2()\xpos=var*abstand/laser+200
		
		If laser2()\xpos<=#SCREEN_WIDTH/laser+200
			laser2()\direction=1
			
		ElseIf laser2()\xpos>=#SCREEN_WIDTH
			laser2()\direction=-1
			laser2()\xpos=(NUMBER_OF_BEAMS-var)*abstand/laser+200
		
		EndIf 
				
		Select laser_color2
		Case "Zufällig"
				laser2()\rgb=RGB(Random(150)+100,Random(150)+100,Random(150)+100)
		Case "Grün"
			laser2()\rgb=RGB(0,255,0)
		Case "Rot"
			laser2()\rgb=RGB(255,0,0)
		Case "Blau"
			laser2()\rgb=RGB(0,0,255)
		Case "Weiß"
			laser2()\rgb=RGB(255,255,255)
		EndSelect 		
Next 

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

If OpenWindow(0,0,0,400,400,"LASER",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(0))
  TextGadget(1,5,305,30,14,"blab")
  
  If OpenWindowedScreen(WindowID(0),0,0,400,300,0,0,0)
    
  Else
    MessageRequester("Error", "Can't open windowed screen!", 0)
    End
  EndIf

EndIf

Repeat
  Event.l = WindowEvent()    
  
  If Event = #PB_Event_Gadget
    ; do the normal application stuff here...
    Gadget  = EventGadget()  

    Select Gadget
      Case 1, 2, 3
        SetGadgetText(4,"Button "+Str(Gadget)+" pressed.")
    EndSelect
  Else
  
  If IsScreenActive()
    ; do the sprite & screen stuff here...
    FlipBuffers()       ; Inverse the buffers (the back become the front (visible)... and we can do the rendering on the back
    ExamineKeyboard()
   
    ; Clear the screen and draw our sprites
    ClearScreen(RGB(0,0,0))

If laser=2
ResetList(laser())
While NextElement(laser())
If laser()\xpos=0  
	laser()\direction=1
EndIf 
If laser()\xpos=200
	laser()\direction=-1
EndIf 

laser()\xpos+laser()\direction

Wend 

ResetList(laser2())
While NextElement(laser2())
If laser2()\xpos=200  
	laser2()\direction=1
EndIf 
If laser2()\xpos=400
	laser2()\direction=-1
EndIf 

laser2()\xpos+laser2()\direction

Wend 
EndIf 

If laser=1
ResetList(laser())
While NextElement(laser())
If laser()\xpos=0  
	laser()\direction=1
EndIf 
If laser()\xpos=400
	laser()\direction=-1
EndIf 

laser()\xpos+laser()\direction

Wend 
EndIf 

If laser=1
  StartDrawing(ScreenOutput())
  
  ResetList(laser())
  While NextElement(laser())
  
  If laser()\rgb=0
  rgb=RGB(0,laser()\xpos/2,255-laser()\xpos/2)
  Else 
  rgb=laser()\rgb
  EndIf 
  LineXY(200,300,laser()\xpos,0,rgb)
  Wend 
   
  StopDrawing()
  
  EndIf   
  
  If laser=2
  StartDrawing(ScreenOutput())
  
  ResetList(laser())
  While NextElement(laser())
  
  If laser()\rgb=0
  rgb=RGB(0,laser()\xpos/2,255-laser()\xpos/2)
  Else 
  rgb=laser()\rgb
  EndIf 
  LineXY(100,300,laser()\xpos,0,rgb)
  Wend   
   
     ResetList(laser2())
  While NextElement(laser2())
  
  If laser2()\rgb=0
  rgb=RGB(0,laser2()\xpos/2,255-laser2()\xpos/2)
  Else 
  rgb=laser2()\rgb
  EndIf 
  LineXY(300,300,laser2()\xpos,0,rgb)
  Wend  
   
  StopDrawing()
  
  EndIf 
    EndIf  
    
     Delay(20)
  EndIf

Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
End   
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

@TomS:

Du gehst da meiner Meinung nach etwas falsch ran.
Anstatt eine Richtung zu bestimmen und dann einfach die X-Position des oberen Laserpunktes zu verändern solltest Du diese Position mit Hilfe der Kreisfunktionen Sin() bzw. Cos() berechnen.

Erhöhe also bei jedem Frame einfach den "Winkel" des Beams etwas und errechne Dir dann per "Sin(Winkel(BeamNr)) * Multiplier" die obere X-Position (wobei "Multiplier" in etwa die Hälfte Deiner Fensterbreite sein sollte).
Dann wird das wohl schon eher so aussehen wie Du es haben wolltest.

Gruß, PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Ok. Danke.

Ich hab das jetzt mit cosinus gemacht.

Nur leider ist das Bild jetzt alles andere als symmetrisch abhängig von der eingestellten Anzahl der Beams. Stell z.B mal 4 Beams ein :freak:
Hab das jetzt nur mal für einen Laser gemacht.

Code: Alles auswählen

#SCREEN_WIDTH=400


OpenWindow(1,0,0,210,135,"LASER - Settings",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(1))
  TextGadget(101,5,8,100,14,"Anzahl der Laser:")
  SpinGadget(1,105,5,30,20,1,2, #PB_Spin_Numeric| #PB_Spin_ReadOnly)
  SetGadgetText(1,"1")
  
  TextGadget(102,5,33,100,14,"Anzahl der Beams:")
  SpinGadget(2,105,30,30,20,1,50, #PB_Spin_Numeric| #PB_Spin_ReadOnly)
  SetGadgetText(2,"10")
  
  TextGadget(103,5,58,100,14,"Farbe für Laser 1:")
  ComboBoxGadget(3,105,55,100,20)
  	AddGadgetItem(3,0,"Rot")  	
  	AddGadgetItem(3,0,"Grün")  	
  	AddGadgetItem(3,0,"Blau")  	
  	AddGadgetItem(3,0,"Weiß")
  	AddGadgetItem(3,0,"Zufällig")
 SetGadgetState(3,0)
  
  TextGadget(104,5,83,100,14,"Farbe für Laser 2:")
  ComboBoxGadget(4,105,80,100,20)
  	AddGadgetItem(4,0,"Rot")  	
  	AddGadgetItem(4,0,"Grün")  	
  	AddGadgetItem(4,0,"Blau")  	
  	AddGadgetItem(4,0,"Weiß")
  	AddGadgetItem(4,0,"Zufällig")
 SetGadgetState(4,0)
 
 ButtonGadget(5,5,110,200,20,"O K")
  
  
  
  Repeat
  event=WaitWindowEvent()
  If event=#PB_Event_Gadget
  Select EventGadget()
  
	Case 5
	
	laser_color1.s=GetGadgetText(3)
	laser_color2.s=GetGadgetText(4)
	laser=Val(GetGadgetText(1))
	NUMBER_OF_BEAMS=Val(GetGadgetText(2))
	
	
	
	
	CloseWindow(1)
	weiter=1
  
  
  EndSelect
  EndIf 
  
  If event=#PB_Event_CloseWindow
  End 
  EndIf 
  
  Until weiter=1
  
  

abstand=(#SCREEN_WIDTH/NUMBER_OF_BEAMS)*2

Structure beam

	index.l
	xpos.l
	xposold.l
    direction.l    
    rgb.l
EndStructure

 NewList laser.beam()

For var=1 To NUMBER_OF_BEAMS
	AddElement(laser())
		laser()\index=var
		laser()\xposold=var*abstand/laser
		If laser()\xposold<=#SCREEN_WIDTH/laser
			laser()\direction=1
			
		ElseIf laser()\xposold>=#SCREEN_WIDTH/laser
			laser()\direction=-1
			laser()\xposold=(NUMBER_OF_BEAMS-var)*abstand/laser
		
		EndIf 
		
		
		Select laser_color1
		Case "Zufällig"
			laser()\rgb=RGB(Random(150)+100,Random(150)+100,Random(150)+100)
		Case "Grün"
			laser()\rgb=RGB(0,255,0)
		Case "Rot"
			laser()\rgb=RGB(255,0,0)
		Case "Blau"
			laser()\rgb=RGB(0,0,255)
		Case "Weiß"
			laser()\rgb=RGB(255,255,255)
		EndSelect 
		
Next  

NewList laser2.beam()

For var=1 To NUMBER_OF_BEAMS
	AddElement(laser2())
		laser2()\xpos=var*abstand/laser+200
		
		If laser2()\xpos<=#SCREEN_WIDTH/laser+200
			laser2()\direction=1
			
		ElseIf laser2()\xpos>=#SCREEN_WIDTH
			laser2()\direction=-1
			laser2()\xpos=(NUMBER_OF_BEAMS-var)*abstand/laser+200
		
		EndIf 
		
		
				
		Select laser_color2
		Case "Zufällig"
				laser2()\rgb=RGB(Random(150)+100,Random(150)+100,Random(150)+100)
		Case "Grün"
			laser2()\rgb=RGB(0,255,0)
		Case "Rot"
			laser2()\rgb=RGB(255,0,0)
		Case "Blau"
			laser2()\rgb=RGB(0,0,255)
		Case "Weiß"
			laser2()\rgb=RGB(255,255,255)
		EndSelect 
	
		
Next 




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

If OpenWindow(0,0,0,400,400,"LASER",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(0))


  If OpenWindowedScreen(WindowID(0),0,0,400,300,0,0,0)
  
  

    
    
    
    
  Else
    MessageRequester("Error", "Can't open windowed screen!", 0)
    End
  EndIf

EndIf







winkel_add.f=0.01



; If laser=1
; ResetList(laser())
; While NextElement(laser())
; If laser()\xpos=0  
; 	laser()\direction=1
; EndIf 
; If laser()\xpos=400
; 	laser()\direction=-1
; EndIf 
; 
; laser()\xpos+laser()\direction
; 
; Wend 
; EndIf 


Repeat

  alpha.f+winkel_add
  Event.l = WindowEvent()    
  
  If Event = #PB_Event_Gadget
    ; do the normal application stuff here...
    Gadget  = EventGadget()  


	
    Select Gadget
    	Case 1
    		
    	Case 2
    		
    		
     
     
     
    EndSelect
  Else
  
  If IsScreenActive()
    ; do the sprite & screen stuff here...
    FlipBuffers()       ; Inverse the buffers (the back become the front (visible)... and we can do the rendering on the back
    ExamineKeyboard()
   
    ; Clear the screen and draw our sprites
    ClearScreen(RGB(0,0,0))


If laser=2
ResetList(laser())
While NextElement(laser())
If laser()\xpos=0  
	laser()\direction=1
EndIf 
If laser()\xpos=200
	laser()\direction=-1
EndIf 

laser()\xpos+laser()\direction

Wend 


ResetList(laser2())
While NextElement(laser2())
If laser2()\xpos=200  
	laser2()\direction=1
EndIf 
If laser2()\xpos=400
	laser2()\direction=-1
EndIf 

laser2()\xpos+laser2()\direction

Wend 
EndIf 

; 
; If laser=1
; ResetList(laser())
; While NextElement(laser())
; If laser()\xpos=0  
; 	laser()\direction=1
; EndIf 
; If laser()\xpos=400
; 	laser()\direction=-1
; EndIf 
; 
; laser()\xpos+laser()\direction
; 
; Wend 
; EndIf 




If laser=1
ResetList(laser())
While NextElement(laser())

laser()\xpos=200+Cos(alpha+laser()\xposold)*200

Wend 
EndIf 




If laser=1
  StartDrawing(ScreenOutput())
  
  ResetList(laser())
  While NextElement(laser())
  
  If laser()\rgb=0
  rgb=RGB(0,laser()\xpos/2,255-laser()\xpos/2)
  Else 
  rgb=laser()\rgb
  EndIf 
  LineXY(200,300,laser()\xpos,0,rgb)
  Wend 
   
  StopDrawing()
  
  EndIf 
  
  
  
  
  If laser=2
  StartDrawing(ScreenOutput())
  
  ResetList(laser())
  While NextElement(laser())
  
  If laser()\rgb=0
  rgb=RGB(0,laser()\xpos/2,255-laser()\xpos/2)
  Else 
  rgb=laser()\rgb
  EndIf 
  LineXY(100,300,laser()\xpos,0,rgb)
  Wend 
   
   
     ResetList(laser2())
  While NextElement(laser2())
  
  If laser2()\rgb=0
  rgb=RGB(0,laser2()\xpos/2,255-laser2()\xpos/2)
  Else 
  rgb=laser2()\rgb
  EndIf 
  LineXY(300,300,laser2()\xpos,0,rgb)
  Wend 
   
   
   
   
   
  StopDrawing()
  
  EndIf 
      
    EndIf  
    
     Delay(20)
  EndIf

Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

End   

Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

TomS hat geschrieben:Nur leider ist das Bild jetzt alles andere als symmetrisch abhängig von der eingestellten Anzahl der Beams. Stell z.B mal 4 Beams ein :freak:
Dein Hauptproblem ist eine falsche Formel sowie ein falscher Datentyp für Deine Variable "abstand" in Zeile 66:

Statt: abstand=(#SCREEN_WIDTH/NUMBER_OF_BEAMS)*2
muss Zeile 66 lauten: abstand.f=(#PI/NUMBER_OF_BEAMS)*2

Weiterhin musst Du auch noch in Zeile 72 die Variable xposold als Fließkommazahl definieren: xposold.f
Dann klappts auch mit der Nachbarin. <)

Gruß und weiterhin viel Erfolg,
PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Jaja. Wenn einem das logische Denkvermögen als Programmierer fehlt, geht's meistens in die Hose :oops:

Vielendank für deine Hilfe, klappt nun Wunderbar :allright:
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

TomS hat geschrieben:Vielendank für deine Hilfe, klappt nun Wunderbar :allright:
You are welcome. Bild
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Antworten