als ich endlich mal wieder etwas Zeit gefunden habe und FreeOrion spielte, kam mir die Idee, ob man so eine Galaxiekarte nicht auch in 3D erstellen könnte. Also Purebasic gestartet und direkt mal was ausprobiert. Direkt nach dem Start bin ich auf zwei Probleme gestoßen. Doch hier zunächst der Beispielcode:
Code: Alles auswählen
#APPNAME = "SpaceTest"
#FRONTCAM = 0
#COLOR_LINE = $202020
UsePNGImageDecoder()
Structure CameraPositionOuter
x.i
y.i
z.i
deg.f
rad.i
spd.f
EndStructure
Structure PlanetPositionOuter
name.s
x.i
y.i
z.i
size.i
material.i
mesh.i
entity.i
text3d.i
EndStructure
Procedure CalculateCameraPosHor(*pos.CameraPositionOuter, right.i=#False)
If right
*pos\deg - *pos\spd
Else
*pos\deg + *pos\spd
EndIf
If *pos\deg < 0
*pos\deg = 359 + (1-*pos\deg)
ElseIf *pos\deg > 360
*pos\deg = *pos\deg - 360
EndIf : Debug *pos\deg
*pos\x = *pos\rad * Cos(*pos\deg) + 2500
*pos\z = *pos\rad * Sin(*pos\deg) + 2500
EndProcedure
; init
If InitEngine3D()
CurrentDir.s = GetCurrentDirectory()
If Right(CurrentDir, 1) <> "\"
CurrentDir = CurrentDir + "\"
EndIf
Add3DArchive(CurrentDir, #PB_3DArchive_FileSystem)
Else
Debug "Can not init 3D Engine"
End
EndIf
If InitSprite()
If InitMouse()
If InitKeyboard()
If OpenWindow(0, 0, 0, 1600, 900, #APPNAME, #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0, #PB_Screen_NoSynchronization)
Debug "init done"
Else
Debug "Can not open screen"
EndIf
Else
Debug "Can not open window"
EndIf
Else
Debug "Can not init keyboard"
EndIf
Else
Debug "Can not init mouse"
EndIf
Else
Debug "Can not init sprite"
EndIf
Dim SolarSystem.PlanetPositionOuter(51)
Define FrontCam.CameraPositionOuter
; textures & materials
tex1 = CreateTexture(#PB_Any, 256, 256)
StartDrawing(TextureOutput(tex1))
Box(0, 0, 256, 256, RGB(192, 192, 192))
StopDrawing()
mat1 = CreateMaterial(#PB_Any, TextureID(tex1))
mesh8 = CreateSphere(#PB_Any, 80, 16, 16)
mesh9 = CreateSphere(#PB_Any, 90, 16, 16)
mesh10 = CreateSphere(#PB_Any, 100, 16, 16)
mesh11 = CreateSphere(#PB_Any, 110, 16, 16)
mesh12 = CreateSphere(#PB_Any, 120, 16, 16)
; starfield
For n = 1 To 50
With SolarSystem(n)
\name = "Star " + Str(n)
\x = Random(5000,0)
\y = Random(5000,0)
\z = Random(5000,0)
\material = mat1
\mesh = Random(12,8)
If \mesh = 8
\mesh = mesh8
ElseIf \mesh = 9
\mesh = mesh9
ElseIf \mesh = 10
\mesh = mesh10
ElseIf \mesh = 11
\mesh = mesh11
ElseIf \mesh = 12
\mesh = mesh12
EndIf
\entity = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\material), \x, \y, \z)
\text3d = CreateText3D(#PB_Any, \name, "Arial", 1.0, RGBA(0,0,255,255))
Text3DAlignment(\text3d, #PB_Text3D_HorizontallyCentered)
;AttachEntityObject(\entity, "", \text3d)
MoveText3D(\text3d, 0, 0, 80)
EndWith
Next
; space cube
CreateLine3D(#PB_Any, 0, 0, 0, #COLOR_LINE, 5000, 0, 0, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 5000, 0, #COLOR_LINE, 5000, 5000, 0, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 0, 5000, #COLOR_LINE, 5000, 0, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 5000, 5000, #COLOR_LINE, 5000, 5000, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 0, 0, #COLOR_LINE, 0, 5000, 0, #COLOR_LINE)
CreateLine3D(#PB_Any, 5000, 0, 0, #COLOR_LINE, 5000, 5000, 0, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 0, 5000, #COLOR_LINE, 0, 5000, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 5000, 0, 5000, #COLOR_LINE, 5000, 5000, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 0, 0, #COLOR_LINE, 0, 0, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 0, 5000, 0, #COLOR_LINE, 0, 5000, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 5000, 0, 0, #COLOR_LINE, 5000, 0, 5000, #COLOR_LINE)
CreateLine3D(#PB_Any, 5000, 5000, 0, #COLOR_LINE, 5000, 5000, 5000, #COLOR_LINE)
; space cube end
; light
looklight = CreateLight(#PB_Any, RGB(255, 255, 128), 0, 0, 0, #PB_Light_Spot)
MoveLight(looklight, 2500, 2500, 10000)
; camera
FrontCam\x = 2500
FrontCam\y = 2500
FrontCam\z = 10000
FrontCam\spd = 0.005
FrontCam\rad = 10000
FrontCam\deg = 0
CreateCamera(#FRONTCAM, 0, 0, 100, 100)
CalculateCameraPosHor(FrontCam)
MoveCamera(#FRONTCAM, FrontCam\x, FrontCam\y, FrontCam\z)
; loop
Repeat
; catch all window events
Repeat
WindowEventId = WindowEvent()
If WindowEventId = #PB_Event_CloseWindow
ExitLoop = #True
EndIf
Delay (1)
Until WindowEventId = 0
; get keyboard
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
CalculateCameraPosHor(@FrontCam)
ElseIf KeyboardPushed(#PB_Key_Right)
CalculateCameraPosHor(@FrontCam, #True)
EndIf
MoveLight(looklight, FrontCam\x, FrontCam\y, FrontCam\z, #PB_Absolute)
MoveCamera(#FRONTCAM, FrontCam\x, FrontCam\y, FrontCam\z, #PB_Absolute)
CameraLookAt(#FRONTCAM, 2500, 2500, 2500) ; the center
EndIf
; get mouse
If ExamineMouse()
; wheel ?!
EndIf
RenderWorld()
FlipBuffers()
SetWindowTitle(0, #APPNAME + " - " + Str(Engine3DFrameRate(#PB_Engine3D_Current)) + " fps")
Until KeyboardPushed(#PB_Key_Escape) Or ExitLoop = #True
End
Wenn ich den Code so starte, bekomme ich die Fehlermeldung: Ungültiger Speicherzugriff die Zeile 115:
Code: Alles auswählen
AttachEntityObject(\entity, "", \text3d)
Problem 2:
Wenn man den Text3D Block auskommentiert, funktioniert die Anzeige, wenn ich die Pfeiltasten (Rechts/Links) drücke, rotiert die Kamera auch um das Zentrum des Sternenfelds, aber, sobald der Umbruch von 0 auf 360 Grad oder umgekehrt kommt, sieht man einen "Sprung" in der Anzeige, die Galaxie macht auf einmal einen Sprung um ca. 270°.
Ich danke schonmal im voraus für Eure Tips und Hilfestellungen.
Edit: PureBasic 5.10 x86; Windows 7-64bit
Edit2: Problem 2 gelöst:
Code: Alles auswählen
*pos\x = *pos\rad * Cos(Radian(*pos\deg)) + 2500
*pos\z = *pos\rad * Sin(Radian(*pos\deg)) + 2500