[B3D] Planetenatmosphäre und Freelancer-Steuerung
Übersicht

KrischanBetreff: [B3D] Planetenatmosphäre und Freelancer-Steuerung |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hier eine komplett ohne Texturen lauffähige Demo eines Planeten mit Atmosphäre und einer Freelancer-ähnlichen Steuerung. Man kann dabei vom Weltraum nahtlos in die Atmosphäre eintauchen und auch wieder herausfliegen. Es werden dabei zwei Mesh-Ringe dynamisch zur Entfernung des Spielers zum Planeten skaliert und kegelförmig verbogen sowie berücksichtigt, ob man auf der der Sonne zu- oder abgewandten Seite fliegt.
Steuerung: Maus, Pfeiltasten Rotes Fadenkreuz: Flugrichtung Grüner Kasten: Zielrichtung SPACE = Wireframe an/aus Im Weltraum Eintritt in die Atmosphäre Flug über die Oberfläche Code: [AUSKLAPPEN] AppTitle "Planet Atmosphere Glow Demo"
; by Krischan webmaster(at)jaas.de ; Constants Const ScreenWidth% = 800 ; Screen width Const ScreenHeight% = 600 ; Screen height Const ColorDepth% = 32 ; Color depth Const ScreenMode% = 2 ; Screen Mode Const MouseSpeed# = 0.1 ; Mousespeed Const CameraSmoothness# = 10 ; Smoothness of movement Const Scale# = 12.756 ; Approx. the diameter of earth (1 unit = 1000km) Const GameTime% = 20 ; Game speed Const CursorSize% = 33 ; Size of cursor and crosshair image Const TurnSpeed# = 2.0 ; Turnspeed of player Const RollSpeed# = 1.0 ; Roll speed Const MaxRollAngle# = 20.0 ; Maximum roll angle Const RingDetail% = 60 ; Number of segments ; Glow Color scheme Const R1%=192,G1%=224,B1%=255 ; Surface near color Const R2%=128,G2%=160,B2%=255 ; Surface far color ; Variables Global CameraSpeed# = Scale/10.0 ; Movement speed Global TargetDistance# = 10.0*Scale ; Mousetarget distance to player Global FrameTime = MilliSecs() ; Initialize Frame Timer Global Period% = 1000/75.0 ; Calc frame period (here: 75FPS) ; help variables and objects Global MX%,MY% ; Mouse position Global Player%,MouseTarget%,Cam%,Ship% ; Player Global Cursor%,Cross% ; Images Global Planet%,Light%,Sun%,StarBox%,GlowPivot% ; Scene objects Global Glow1%,Glow2% ; Glow rings Global GlowScale# ; Glow scale indicator Global Tween# ; Frame tween ; Init 3D Graphics3D ScreenWidth,ScreenHeight,ColorDepth,ScreenMode ; Init Player and Scene InitPlayer() InitScene() ; Center mouse and hide pointer MoveMouse ScreenWidth/2,ScreenHeight/2 HidePointer ; Main loop While Not KeyHit(1) ; Frame tweening Tween#=Float(MilliSecs()-FrameTime)/Float(GameTime) : FrameTime=MilliSecs() ; SPACE = Wireframe If KeyHit(57) Then wf%=1-wf : WireFrame wf ; Get Distance player to planet Local distance#=EntityDistance(Cam,Planet) ; Update atmosphere glow UpdateAtmosphere(distance) ; Attach Starbox to camera PositionEntity StarBox,EntityX(Player),EntityY(Player),EntityZ(Player) ; Sun points to player PointEntity Sun,Player UpdateWorld RenderWorld ; Move player Movement(GlowScale,distance) ; Draw cursor and crosshair by chasing the mousetarget CameraProject Cam,EntityX(MouseTarget,1),EntityY(MouseTarget,1),EntityZ(MouseTarget,1) DrawImage Cursor,MX-(CursorSize/2),MY-(CursorSize/2) DrawImage Cross,ProjectedX()-(CursorSize/2),ProjectedY()-(CursorSize/2) ; Statistics Text 0, 0,"Triangles rendered....: "+TrisRendered() Text 0,15,"Distance To Surface...: "+Int((distance-Scale)*1000)+" km" Flip 0 Wend End ; The functions that creates the mesh and surface for a ring Function CreateRing(fx%=0,blend%=0) Local a1#,a2#,a3#,a4#,angle% Local v0%,v1%,v2%,v3% Local mesh=CreateMesh() Local surf=CreateSurface(mesh) ; Ring FX If fx>0 Then EntityFX mesh,fx If blend>0 Then EntityBlend mesh,blend Return mesh End Function ; Re-creates the ring vertices and triangles with different values Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0) Local a1#,a2#,a3#,a4#,angle% Local v0%,v1%,v2%,v3% ; Get and clear the surface Local surf=GetSurface(mesh,1) ClearSurface surf,1,1 ; Limit segments If segments>360 Then segments=360 ; Create ring For angle=1 To segments a1=angle*360.0/segments a2=angle*360.0/segments +360.0/segments a3=angle*360.0/segments +180.0/segments a4=angle*360.0/segments -180.0/segments ; Calc vertex points v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0) v1=AddVertex(surf,radius1*Cos(a2),radius1*Sin(a2),0,0,0) v2=AddVertex(surf,radius2*Cos(a3),radius2*Sin(a3),scale,1,1) v3=AddVertex(surf,radius2*Cos(a4),radius2*Sin(a4),scale,1,1) ; Color VertexColor surf,v0,r1,g1,b1,alpha1 VertexColor surf,v1,r1,g1,b1,alpha1 VertexColor surf,v2,r2,g2,b2,alpha2 VertexColor surf,v3,r2,g2,b2,alpha2 ; Create Triangles AddTriangle surf,v2,v1,v0 AddTriangle surf,v0,v3,v2 Next Return mesh End Function ; Initialize player, camera Function InitPlayer() Local i% ; Player pivot Player=CreatePivot() PositionEntity Player,-Scale*2,0,Scale*2 ; Ship mesh Ship=CreateCube(Player) EntityFX Ship,1 ScaleEntity Ship,0.2,0.05,0.2 PositionEntity Ship,0,-0.5,1.5 EntityOrder Ship,-1000 ; Mousetarget in space MouseTarget=CreatePivot(Ship) MoveEntity MouseTarget,0,0,TargetDistance ; Camera Cam=CreateCamera(Player) PositionEntity Cam,0,0,0 CameraRange Cam,0.01,1000*Scale ; Create cursor image Cursor=CreateImage(CursorSize,CursorSize) SetBuffer ImageBuffer(Cursor) For i=0 To 2 Color 0,Int(255.0/(1+i)),0 Rect i,i,CursorSize-(2*i),CursorSize-(2*i),0 Next ; Create crosshair image Cross=CreateImage(CursorSize,CursorSize) SetBuffer ImageBuffer(Cross) Color 255,0,0 Line (CursorSize-1)/2.0,0,(CursorSize-1)/2.0,CursorSize Line 0,(CursorSize-1)/2.0,CursorSize,(CursorSize-1)/2.0 ; reset buffer and color SetBuffer BackBuffer() Color 255,255,255 End Function ; Initialize scene Function InitScene() Local startex%,i%,col%,rgb% ; Planet Planet=CreateSphere(60) ScaleEntity Planet,Scale,Scale,Scale EntityColor Planet,32,192,64 ; Directional Sunlight Light=CreateLight(1) PositionEntity Light,0,0,-Scale*200 LightRange Light,200*Scale AmbientLight 16,16,16 ; Sun Sun=CreateQuad() ScaleEntity Sun,Scale*10,Scale*10,Scale*10 EntityFX Sun,1 EntityColor Sun,255,255,192 EntityParent Sun,Light PositionEntity Sun,0,0,0 EntityBlend Sun,3 EntityTexture Sun,CreateSunTexture() ; Simple Starbox StarBox=CreateCube() startex=CreateTexture(1024,1024) LockBuffer TextureBuffer(startex) For i=1 To 1000 col=Rand(0,255) rgb=col*$10000+col*$100+col WritePixelFast Rand(0,1023),Rand(0,1023),rgb,TextureBuffer(startex) Next UnlockBuffer TextureBuffer(startex) EntityTexture StarBox,startex ScaleEntity StarBox,10,10,10 EntityOrder StarBox,1 EntityFX StarBox,1 FlipMesh StarBox ; Glow GlowPivot=CreatePivot() Glow1=CreateRing(1+2+16+32,1) Glow2=CreateRing(1+2+16+32,3) EntityParent Glow1,GlowPivot EntityParent Glow2,GlowPivot EntityOrder Glow1,1 EntityOrder Glow2,1 ; Player points to planet first PointEntity Player,Planet TurnEntity Player,0,-20,-90 End Function ; Update atmosphere glow and background color Function UpdateAtmosphere(distance#) Local s2#,s2d#,aa#,bb#,cc# Local angle#,intensity#,clscol#,horizon# ; Calculate ring scale with the help of two right-angled triangles and trigonometry s2#=Scale^2 s2d#=s2/distance GlowScale#=(Sqr(s2+(Scale/Tan(90-(90-(90-ATan(Sqr((distance-(s2d))*(s2d))/(distance-(s2d)))))))^2))/Scale ; Calculcate the sun light angle (1 = exactly between sun and planet, 0 = exactly behind the planet) aa#=EntityDistance(Cam,Planet) bb#=EntityDistance(Planet,Light) cc#=EntityDistance(Cam,Light) angle#=ACos((aa^2+cc^2-bb^2)/(2*aa*cc))/180.0 If angle>1 Then angle=1 If angle<0 Then angle=0 ; Calculate the glow intensity according to sun light angle and distance to planet intensity#=1-(1.0/Exp(GlowScale*angle)) If intensity<0 Then intensity=0 If intensity>1 Then intensity=1 ; Calculate the horizon glow scale multiplicator horizon#=1-(1.2/Exp(GlowScale*angle/2.0)) If horizon<0 Then horizon=0 If horizon>1 Then horizon=1 ; Update ring intensity according to sun light angle and distance to planet UpdateRing(Glow1,0.6*Scale,0.01*Scale,RingDetail,R1*intensity,G1*intensity,B1*intensity,angle,R2*(angle-intensity),G2*(angle-intensity),B2*(angle-intensity), 0,Scale/3.0) UpdateRing(Glow2,(1.0-(horizon/10.0))*Scale,(1.05+(horizon/10.0))*Scale,RingDetail,R1*intensity,G1*intensity,B1*intensity,1.0-horizon,R2*angle,G2*angle,B2*angle,0,horizon*2) ; Scale the rings and always point to player ScaleEntity GlowPivot,GlowScale,GlowScale,GlowScale PointEntity GlowPivot,Player ; Calculate the background color to simulate atmosphere penetration clscol#=(1-(5.0/Exp(GlowScale*angle/2.0)))*intensity If clscol<0 Then clscol=0 If clscol>1 Then clscol=1 CameraClsColor Cam,R2*clscol,G2*clscol,B2*clscol ; Change Starbox alpha EntityAlpha StarBox,1-clscol End Function ; Player movement Function Movement(scale#,distance#) Local roll#,mox#,moz#,cx#,cz# Local t1#,t2# ; get mouse position MX=MouseX() MY=MouseY() ; Movement with speed limit cx=(KeyDown(205)-KeyDown(203))*CameraSpeed cz=(KeyDown(200)-KeyDown(208))*CameraSpeed ; Arrow left/right = roll If KeyDown(203) Then roll=RollSpeed If KeyDown(205) Then roll=-RollSpeed ; Normalize Mouse position (-1 to +1) t1=Normalize(MY,0,ScreenHeight,-1,1) t2=Normalize(MX,0,ScreenWidth,1,-1) ; Slower cursor movement in the center of the screen If t1<0 Then t1=(Abs(t1)^2.0)*-1 Else t1=t1^2.0 If t2<0 Then t2=(Abs(t2)^2.0)*-1 Else t2=t2^2.0 ; Rotate ship mesh and turn player pivot RotateEntity Ship,t1*MaxRollAngle,t2*MaxRollAngle,t2*MaxRollAngle*2 TurnEntity Player,t1*TurnSpeed*Tween,t2*TurnSpeed*Tween,roll*TurnSpeed*Tween ; Move the player forward/backward MoveEntity Player,0,0,(cz*1.0/(scale)^3)*Tween End Function ; Normalize a value Function Normalize#(value#=128.0,value_min#=0.0,value_max#=255.0,norm_min#=0.0,norm_max#=1.0) Return ((value-value_min)/(value_max-value_min))*(norm_max-norm_min)+norm_min End Function Function CreateQuad() ; Create mesh and surface Local mesh%=CreateMesh() Local surf%=CreateSurface(mesh) ; Add vertices Local v0%=AddVertex(surf, 1.0, 1.0, 0.0, 0.0, 0.0 ) ; upper left Local v1%=AddVertex(surf, -1.0, 1.0, 0.0, 1.0, 0.0 ) ; upper right Local v2%=AddVertex(surf, -1.0, -1.0, 0.0, 1.0, 1.0 ) ; lower right Local v3%=AddVertex(surf, 1.0, -1.0, 0.0, 0.0, 1.0 ) ; lower left ; Connect vertices AddTriangle surf,v0,v1,v2 AddTriangle surf,v0,v2,v3 Return mesh End Function ; Create a simple sun texture Function CreateSunTexture() Local tex%=CreateTexture(512,512,2) Local tb%=TextureBuffer(tex) Local i#,j%,col%,rgb% SetBuffer tb LockBuffer tb ; Intensity steps For j=0 To 255 ; Exponential falloff col=Int((1.0/Exp(j*0.075))*100000000) If col>255 Then col=255 rgb=col*$1000000+col*$10000+col*$100+col ; Draw circles For i=0 To 360 Step 0.1 WritePixelFast 256+(Sin(i)*j),256+(Cos(i)*j),rgb,tb Next Next UnlockBuffer tb SetBuffer BackBuffer() Return tex End Function |
||
- Zuletzt bearbeitet von Krischan am So, Nov 16, 2008 19:49, insgesamt einmal bearbeitet
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ups da bin ich im Blitzmax Codearchiv gelandet, kann das mal einer nach B3D verschieben? Danke! | ||
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Super Ding muss ich da sagen. Vielleicht sollte das Raumschiff in Planetennähe nicht ganz sooo langsam fliegen - Eine Speedanzeige wäre da auch praktisch...
Wann kommt da eine Stadt hin in die man eintauchen kann? ![]() |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Kannst ja mal an der Zeile
MoveEntity Player,0,0,(cz*1.0/(scale)^3)*Tween herumspielen, z.B. aus dem ^3 ein ^2 machen, dann gehts fixer (allerdings bekommt man dann auch schneller Probleme mit der Cameraviewrange). Die Geschwindigkeit wäre so auszurechnen: movespeed#=(cz*1.0/(scale)^3)*3600000 Und zwar in km/h - bei 300km Höhe hätte ich so noch 45.000km/h und bei 10km Höhe etwa 300km/h drauf. Bisschen wenig bei 10km und ein bisschen zu viel bei 300km, naja. Ausserdem ist mir noch aufgefallen, dass die Maus-Speedlimitierung nicht so doll funktioniert, die Steuerung flutscht besser, wenn man diese beiden Zeilen auskommentiert: If t1<0 Then t1=(Abs(t1)^2.0)*-1 Else t1=t1^2.0 If t2<0 Then t2=(Abs(t2)^2.0)*-1 Else t2=t2^2.0 Das mit der Stadt wird mit diesem Planeten ein wenig schwierig. Ich selbst könnte das nur mit tarnen, täuschen, tricksen realisieren. Mir schwebt da vor, beim Eintritt zwischen 100km und 10km Höhe Wolken auf die Camera zufliegen zu lassen, die immer dichter werden und sobald das ganze Fenster zugeklebt ist, die Szene zu wechseln und durch eine 3D-Landschaft mit Sky auszuwechseln. Die Alternative wäre wie schon einmal im Forum angesprochen ein Superikosaeder, Perlin-Noise und dynamic LOD, alles ist aber weit ausserhalb meiner jetzigen Programmierkenntnisse. Wobei mir wenn überhaupt eher ein Starflight-Clone vorschwebt, da gabs eher Raumstationen als Städte, konnte aber auch auf Planeten landen (das war aber in Forth geschrieben und grottenlangsam). |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nachtrag: ich habe festgestellt, dass es auch mit weniger Vertices geht, wenn man die Funktion ein wenig umbaut, dabei werden nun 50% weniger Vertices benötigt. Und ich kann die Atmosphäre jetzt mit optisch gleichem Resultat mit 42 Vertices/40 Triangles anstatt 240 Vertices/120 Triangles darstellen (Variable Ringdetail 20 anstatt 60):
Code: [AUSKLAPPEN] ; Re-creates the ring vertices and triangles with different values
Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0) Local a1#,a2#,angle% Local v0%,v1%,v2%,v3%,v% ; get and clear the surface Local surf=GetSurface(mesh,1) ClearSurface surf,1,1 ; Limit segments If segments>360 Then segments=360 ; Create ring For angle=0 To segments a1=angle*360.0/segments a2=angle*360.0/segments+180.0/segments ; Calc vertex points v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0) v1=AddVertex(surf,radius2*Cos(a2),radius2*Sin(a2),scale,1,1) ; Color VertexColor surf,v0,r1,g1,b1,alpha1 VertexColor surf,v1,r2,g2,b2,alpha2 Next ; Create Triangles For v=0 To CountVertices(surf)-3 AddTriangle(surf,v,v+1,v+2) Next Return mesh End Function |
||
Shaggy82Betreff: problem mit planetengrößen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
hallo Krischan,
habe ein problem mit deinem code. habe es zwar geschaft mehrer planeten zu erzeugen. doch kann ich durch alle hindurchfliegen bis auf den zuletzt erstellten. und soblad ich die größe verändere passt der Atmosphere effekt nicht mehr. hier mein versuch: BlitzBasic: [AUSKLAPPEN]
kannst du mir vieleicht weiterhelfen. die formeln in deinem code sind mir leider ein pissel zu hoch. mfg shaggy |
||
![]() |
LINKed |
![]() Antworten mit Zitat ![]() |
---|---|---|
sieht gut aus, aber man sollte vielleicht die atmosphäre die von der Sonne abgewendet ist dunkler machen.
Es sieht komisch aus wenn der Boden dunkel ist, aber der Himmel leuchtend blau. |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also ich blicke da bei Deinem Code nicht so ganz durch. Beschäftige Dich am Besten erst einmal mit dem zugrunde liegenden Prinzip wie ich den Ring / die Atmosphäre ursprünglich erstellt habe, das steht in diesem Post (der ganze Thread drumherum ist auch interessant):
https://www.blitzforum.de/foru...822#312051 |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jetzt habe ich noch einmal selbst an meinem Beispiel herumgebastelt und - nachdem ich alles komplett umschreiben musste habe ich gleich ein ganzes Sonnensystem daraus gebastelt. Es ist unglaublich schwierig die Distanzen einigermassen unter einen Hut zu bringen, so dass der Eindruck entsteht dass man wirklich durch ein Sonnensystem fliegt, aber trotzdem noch in Atmosphären von Planeten eintauchen kann. Geht bestimmt noch eleganter aber so läuft es erstmal und taugt als Beispiel.
Die Steuerung ist wieder ganz einfach gehalten: Maus = Zielrichtung Pfeiltasten = vor/zurück sowie Rollen Linke Maustaste = 10x Zoom Rechte Maustaste = 10x schneller SPACE = Wireframe So sieht die Demo aus ![]() Und hier ein gepimpter Screenshot mit Milchstrasse und Raumschiff, 99% gleiche Codebasis ![]() Und hier der Code Code: [AUSKLAPPEN] Graphics3D 800,600,32,2
;Include "milkyway.bb" ; the answer to all questions SeedRnd 42 ; Frametween stuff Global GameSpeed%=60 Global Screenwidth%=GraphicsWidth() Global Screenheight%=GraphicsHeight() Global FramePeriod%=1000/GameSpeed Global FrameTime%=MilliSecs()-FramePeriod ; variables Global RingDetail% = 120 Global TargetDist# = 10000 Global RollSpeed# = 1.0 Global TurnSpeed# = 2.0 Global MaxRoll# = 20.0 Global Speed# = 500 Global CursorSize% = 33 ; Glow Color scheme Const R1%=192,G1%=224,B1%=255 Const R2%=128,G2%=160,B2%=255 ; player / movement Global MX%,MY%,Player%,MouseTarget%,Cam%,Ship%,Cursor%,Cross%,movedistance#,speedtimer%,mm#,wf% ; nearest object Global nearestdist#,nearestscale#,nearestname%,nearestglowscale# ; scene objects Global Light%,Sun0%,Sun1%,Sun2%,Sun3%;,MilkyWay% Global masterpivot%,solidpivot%,wiredpivot% ; homekeeping Global localx#,localy#,localz# Global globalx#,globaly#,globalz# Global simx#,simy#,simz# Global newx#,newy#,newz# Global oldx#,oldy#,oldz# ; planet type Type planet Field id% Field Planet% Field GlowPivot% Field Glow1% Field Glow2% Field Scale# Field glowscale# Field d# Field angle# Field intensity# Field horizon# Field clscol# Field orbit% Field radius# Field atmofactor# End Type ; Init Player and Scene InitPlayer() InitScene() ; initiate homekeeping and movespeed calculation HomeKeeping(Player,masterpivot,1000) oldx=simx oldy=simy oldz=simz ; Center mouse and hide pointer MoveMouse Screenwidth/2,Screenheight/2 HidePointer ; Main loop While Not KeyHit(1) Cls Local FrameElapsed%,FrameTicks%,FrameTween#,t% Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed FrameTicks=FrameElapsed/FramePeriod FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod) ; main tweened loop For t=1 To FrameTicks FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld ; SPACE = Wireframe If KeyHit(57) Then wf%=1-wf : WireFrame wf ; updates scene UpdateScene(p.planet) ; moves player Movement() ; keeps the player in its "home area" HomeKeeping(Player,masterpivot,1000) ; calcs the speed/sec CalcSpeed() ; sorts the planets SortPlanets() ; updates the planets atmospheres UpdatePlanets(p.planet) ; attaches galaxy to player ;PositionEntity MilkyWay,localx,localy,localz UpdateWorld Next ; tweened render Wireframe WireFrame 1 ShowEntity wiredpivot HideEntity solidpivot ;HideEntity MilkyWay CameraClsMode Cam,1,1 RenderWorld FrameTween ; tweened render solid objects WireFrame wf HideEntity wiredpivot ShowEntity solidpivot ;ShowEntity MilkyWay CameraClsMode Cam,0,0 RenderWorld FrameTween ; draw planet names DrawPlanetNames(p) ; Draw cursor and crosshair by chasing the mousetarget CameraProject Cam,EntityX(MouseTarget,1),EntityY(MouseTarget,1),EntityZ(MouseTarget,1) DrawImage Cursor,MX-(CursorSize/2),MY-(CursorSize/2) DrawImage Cross,ProjectedX()-(CursorSize/2),ProjectedY()-(CursorSize/2) ; Statistics Text 0, 0,"Triangles rendered....: "+TrisRendered() Text 0,15,"Distance To Sun.......: "+(EntityDistance(Player,Sun0)/100)+" Mio. km" Text 0,30,"Nearest Planet........: "+Int((nearestdist-nearestscale)*100)+"km [Planet "+nearestname+"]" Text 0,45,"Movespeed.............: "+(movedistance*100)+"km/s ["+((movedistance*100)/299792)+"c]" Text 0,60,"Player Position X/Y/Z.: "+simx+" / "+simy+" / "+simz Flip 0 Wend End ; updates the planets distances, the speed multiplicator, the camerarange, the lightrange and the sunscale Function UpdateScene(p.planet) Local cr#,sunscale# For p.planet = Each planet p\d=EntityDistance(Player,p\Planet) ; Update atmosphere glow UpdateAtmosphere(p) Next ; calculate speed multiplicator If (nearestdist-nearestscale)<50000 Then mm#=(nearestdist-nearestscale)/50000 Else mm=1 ; adjust camerarange cr=Abs(mm):If cr<0.1 Then cr=0.1 CameraRange Cam,cr,5000000 ; adjust lightrange LightRange Light,EntityDistance(Player,Sun0)*2 ; sun quads point to player PointEntity Sun0,Player PointEntity Sun1,Player PointEntity Sun2,Player PointEntity Sun3,Player ; adjust sunscale sunscale=((1-(1.0/Exp(EntityDistance(Player,Sun0)*0.0000001)))*500000) ScaleEntity Sun0,sunscale,sunscale,sunscale End Function ; updates the planets atmospheres Function UpdatePlanets(p.planet) Local flag%=0 For p.planet = Each planet ; first planet = nearest planet If p\d>0 And flag=0 Then flag=1 ; set nearest variables nearestdist#=p\d nearestscale#=p\Scale*1.005 nearestname%=p\id nearestglowscale#=p\glowscale ; update background color ("sky") CameraClsColor Cam,R2*p\clscol,G2*p\clscol,B2*p\clscol ; fade galaxy and stars ;UpdatePatch(Starbox,255,255,255,1-(p\clscol*1.1),False,True) ;UpdatePatch(Fogpanorama,255,255,255,1-(p\clscol*1.1),False,True) ;UpdatePatch(Starsphere,255,255,255,1-(p\clscol*1.1),False,True) ; switch blend mode EntityBlend p\Planet,1 ShowEntity p\GlowPivot ; Update ring intensity according to sun light angle and distance to planet UpdateRing(p\Glow1,0.6*p\Scale,0.01*p\Scale,RingDetail,R1*p\intensity,G1*p\intensity,B1*p\intensity,p\angle,R2*(p\angle-p\intensity),G2*(p\angle-p\intensity),B2*(p\angle-p\intensity), 0,p\atmofactor*p\Scale/3.0) UpdateRing(p\Glow2,(1.0-(p\horizon/10.0))*p\Scale,(1.05+(p\horizon/10.0))*p\Scale,RingDetail,R1*p\intensity,G1*p\intensity,B1*p\intensity,1.0-p\horizon,R2*p\angle,G2*p\angle,B2*p\angle,0,p\atmofactor*p\horizon*2) ; Scale the rings and always point to player ScaleEntity p\GlowPivot,p\glowscale,p\glowscale,p\glowscale PointEntity p\GlowPivot,Player Else ; switch blend mode and hide glow EntityBlend p\Planet,3 HideEntity p\GlowPivot EndIf ; fade orbit UpdatePatch(p\orbit,64,64,64,0.5/Exp(nearestglowscale),False) Next End Function ; draws the planet name above the current position, visible only Function DrawPlanetNames(p.planet) ; draw planet names For p.planet = Each planet If EntityInView(p\Planet,Cam) Then CameraProject Cam,EntityX(p\Planet)-globalx,EntityY(p\Planet)-globaly,EntityZ(p\Planet)-globalz Text ProjectedX()-4,ProjectedY()-20,p\id EndIf Next End Function ; keeps the player in a given distance while the world can move far away Function HomeKeeping(player%,world%,homesize%=100) ; store local player position localx=EntityX(player) localy=EntityY(player) localz=EntityZ(player) ; check X axis While localx>homesize globalx=globalx+homesize localx=localx-homesize PositionEntity player,localx,localy,localz MoveEntity world,-homesize,0,0 Wend While localx<-homesize globalx=globalx-homesize localx=localx+homesize PositionEntity player,localx,localy,localz MoveEntity world,homesize,0,0 Wend ; check Y axis While localy>homesize globaly=globaly+homesize localy=localy-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,-homesize,0 Wend While localy<-homesize globaly=globaly-homesize localy=localy+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,homesize,0 Wend ; check Z axis While localz>homesize globalz=globalz+homesize localz=localz-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,-homesize Wend While localz<-homesize globalz=globalz-homesize localz=localz+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,homesize Wend ; store simulated player position simx=localx+globalx simy=localy+globaly simz=localz+globalz End Function ; sorts planets by distance to player Function SortPlanets() Local o.planet,no.planet,o1.planet,o2.planet,t% no=After First planet While no<>Null o=no no=After o o1=o:t=o\d Repeat o2=Before o1 If o2=Null Then Exit If t>=o2\d Then Exit o1=o2 Forever o2=o Insert o2 Before o1 Wend End Function ; The functions that creates the mesh and surface for a ring Function CreateRing(fx%=0,blend%=0,parent%=False,x#=0.0,y#=0.0,z#=0.0,order%=False) Local mesh=CreateMesh(),surf% surf=CreateSurface(mesh) ; Ring fx If fx Then EntityFX mesh,fx If blend Then EntityBlend mesh,blend If parent Then EntityParent mesh,parent If order Then EntityOrder mesh,order PositionEntity mesh,x,y,z Return mesh End Function ; Re-creates the ring vertices and triangles with different values Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0) Local a1#,a2#,angle% Local v0%,v1%,v% ; get and clear the surface Local surf=GetSurface(mesh,1) ClearSurface surf,1,1 ; Limit segments If segments>360 Then segments=360 ; Create ring For angle=0 To segments a1=angle*360.0/segments a2=angle*360.0/segments+180.0/segments ; Calc vertex points v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0) v1=AddVertex(surf,radius2*Cos(a2),radius2*Sin(a2),scale,1,1) ; Color VertexColor surf,v0,r1,g1,b1,alpha1 VertexColor surf,v1,r2,g2,b2,alpha2 Next ; Create Triangles For v=0 To CountVertices(surf)-3 AddTriangle(surf,v,v+1,v+2) Next Return mesh End Function ; Initialize player, camera Function InitPlayer() Local i% ; Player pivot Player=CreatePivot() PositionEntity Player,-7280,25,-6961 ; Ship mesh Ship=CreateCube(Player) EntityFX Ship,1 ScaleEntity Ship,0.2,0.05,0.2 PositionEntity Ship,0,-0.5,1.5 EntityOrder Ship,-1000 ; Mousetarget in space MouseTarget=CreatePivot(Ship) PositionEntity MouseTarget,0,0,TargetDist ; Camera Cam=CreateCamera(Player) PositionEntity Cam,0,0,0 CameraRange Cam,1,5000000 CameraFogMode Cam,True CameraFogRange Cam,500000,1000000 ; Create cursor image Cursor=CreateImage(CursorSize,CursorSize) SetBuffer ImageBuffer(Cursor) For i=0 To 2 Color 0,Int(255.0/(1+i)),0 Rect i,i,CursorSize-(2*i),CursorSize-(2*i),0 Next ; Create crosshair image Cross=CreateImage(CursorSize,CursorSize) SetBuffer ImageBuffer(Cross) Color 255,0,0 Line (CursorSize-1)/2.0,0,(CursorSize-1)/2.0,CursorSize Line 0,(CursorSize-1)/2.0,CursorSize,(CursorSize-1)/2.0 ; reset buffer and color SetBuffer BackBuffer() Color 255,255,255 End Function ; Initialize scene Function InitScene() Local i%,suntex% masterpivot=CreatePivot() solidpivot=CreatePivot(masterpivot) wiredpivot=CreatePivot(masterpivot) ; Sunlight Light=CreateLight(2,solidpivot) PositionEntity Light,0,0,0 AmbientLight 0,0,0 LightRange Light,100 ; Create Sun Texture suntex=CreateSunTexture() ; Sun Quads Sun0=CreateQuad(Light,1000,suntex,3,1+8,255,255,255,1.00) Sun1=CreateQuad(Light,1500,suntex,3,1+8,255,192,128,1.00) Sun2=CreateQuad(Light,3000,suntex,3,1+8,255,255,224,0.75) Sun3=CreateQuad(Light,6000,suntex,3,1+8,255,255,224,0.50) ; Milkyway background ;MilkyWay=InitMilkyway(1000,0.5,10,40,Sun0,10,0,0,0,1,128,96,64,1,0,0,0,1) For i=1 To 9 p.planet = New planet p\planet=CreateSphere(64,solidpivot) p\scale=50+Rnd(i*10,i*2*10) p\atmofactor=Sqr(p\scale^4.2)/10000.0 p\radius=(4+3*2^(i-1))*1000 p\id=i RotateEntity p\planet,0,Rnd(0,360),0 MoveEntity p\planet,0,0,p\radius ScaleEntity p\planet,p\scale,p\scale,p\scale EntityColor p\planet,32,128,64 p\glowpivot=CreatePivot(solidpivot) PositionEntity p\glowpivot,EntityX(p\planet),EntityY(p\planet),EntityZ(p\planet) p\glow1=CreateRing(1+2+16+32,1,p\glowpivot,0,0,0,1) p\glow2=CreateRing(1+2+16+32,3,p\glowpivot,0,0,0,1) p\orbit=CreateOrbit(360,0,p\radius,p\radius,128,255,128,0.0) EntityParent p\orbit,wiredpivot Next ; Player points to planet first PointEntity Player,Sun0 End Function ; updates a patch Function UpdatePatch(mesh%,r%,g%,b%,a#,usealpha%=False,usevertexcolors%=False) Local surf%=GetSurface(mesh,1),v% For v=0 To CountVertices(surf)-1 If usealpha Then a=VertexAlpha(surf,v) If usevertexcolors Then r=VertexRed(surf,v) g=VertexGreen(surf,v) b=VertexBlue(surf,v) EndIf VertexColor surf,v,r,g,b,a Next End Function ; Update atmosphere glow and background color Function UpdateAtmosphere#(p.planet) Local s2#,s2d#,aa#,bb#,cc# ; calculate ring scale with the help of two right-angled triangles and trigonometry s2#=p\Scale^2 s2d#=s2/p\d p\glowscale#=(Sqr(s2+(p\Scale/Tan(90-(90-(90-ATan(Sqr((p\d-(s2d))*(s2d))/(p\d-(s2d)))))))^2))/p\Scale ; calculcate the sun light angle (1 = exactly between sun and planet, 0 = exactly behind the planet) aa#=EntityDistance(Cam,p\Planet) bb#=EntityDistance(p\Planet,Light) cc#=EntityDistance(Cam,Light) p\angle=ACos((aa^2+cc^2-bb^2)/(2*aa*cc))/180.0 If p\angle>1 Then p\angle=1 If p\angle<0 Then p\angle=0 ; calculate the glow intensity according to sun light angle and distance to planet p\intensity=1-(1.0/Exp(p\glowscale*p\angle)) If p\intensity<0 Then p\intensity=0 If p\intensity>1 Then p\intensity=1 ; calculate the horizon glow scale multiplicator p\horizon=1-(1.2/Exp(p\glowscale*p\angle/2.0)) If p\horizon<0 Then p\horizon=0 If p\horizon>1 Then p\horizon=1 ; calculate the background color to simulate atmosphere penetration p\clscol=(1-(5.0/Exp(p\glowscale*p\angle/2.0)))*p\intensity If p\clscol<0 Then p\clscol=0 If p\clscol>1 Then p\clscol=1 End Function ; Player movement Function Movement() Local roll#,cx#,cz#,multi%,limit# Local t1#,t2# ; get mouse position MX=MouseX() MY=MouseY() ; Movement with speed limit cx=(KeyDown(205)-KeyDown(203))*Speed cz=(KeyDown(200)-KeyDown(208))*Speed ; LMB = adjust Camerazoom If MouseDown(1) Then CameraZoom Cam,10 Else CameraZoom Cam,1 ; RMB or RSHIFT = speedup 10x If MouseDown(2) Or KeyDown(54) Then multi=10 Else multi=1 ; Arrow left/right = roll If KeyDown(203) Then roll=RollSpeed If KeyDown(205) Then roll=-RollSpeed ; Normalize Mouse position (-1 to +1) t1=Normalize(MY,0,Screenheight,-1,1) t2=Normalize(MX,0,Screenwidth,1,-1) ; Rotate ship mesh and turn player pivot RotateEntity Ship,t1*MaxRoll,t2*MaxRoll,t2*MaxRoll*2 TurnEntity Player,t1*TurnSpeed,t2*TurnSpeed,roll*TurnSpeed ; Move the player forward/backward MoveEntity Player,0,0,cz*Abs(mm)*multi End Function ; quick distance calculation between two 3D points Function Distance#(x1#,y1#,z1#,x2#,y2#,z2#) Return Sqr((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)) End Function ; calculates moved units per second Function CalcSpeed#(interval%=1000) Local ms%=MilliSecs() ; check each second If ms>speedtimer+interval Then ; store current position newx=simx newy=simy newz=simz ; calculate Distance between current and old position movedistance=Distance(oldx,oldy,oldz,newx,newy,newz) ; store old position oldx=simx oldy=simy oldz=simz ; reset timer speedtimer=ms EndIf End Function ; Normalize a value Function Normalize#(value#=128.0,value_min#=0.0,value_max#=255.0,norm_min#=0.0,norm_max#=1.0) Return ((value-value_min)/(value_max-value_min))*(norm_max-norm_min)+norm_min End Function ; creates a 3D wireframe orbit line Function CreateOrbit(segments%,mesh=0,r1#=1,r2#=1.5,r%=255,g%=255,b%=255,a#=1.0) Local la#,na#,i% For i = 1 To segments na=la+(360.0/segments) mesh=CreateLine(mesh,Cos(la)*r1,0,Sin(la)*r2,Cos(na)*r1,0,Sin(na)*r2,r,g,b,a) la=na Next Return mesh End Function ; creates a 3D line (for orbit) Function CreateLine(mesh,x0#,y0#,z0#,x1#,y1#,z1#,r%=255,g%=255,b%=255,a#=1.0) Local surf%,v1%,v2% If mesh Then surf=GetSurface(mesh,1) Else mesh = CreateMesh() surf = CreateSurface(mesh) EntityFX mesh,1+2+16+32 End If v1=AddVertex(surf,x1,y1,z1) v2=AddVertex(surf,x0,y0,z0) AddTriangle surf,v1,v1,v2 VertexColor surf,v1,r,g,b,a VertexColor surf,v2,r,g,b,a Return mesh End Function ; advanced quad creation Function CreateQuad(parent%=False,scale#=1.0,tex%=False,blend%=False,fx%=False,r%=255,g%=255,b%=255,a#=1.0) ; create mesh and surface Local mesh%=CreateMesh() Local surf%=CreateSurface(mesh) ; add vertices Local v0%=AddVertex(surf, 1, 1,0,0,0) ; upper left Local v1%=AddVertex(surf,-1, 1,0,1,0) ; upper right Local v2%=AddVertex(surf,-1,-1,0,1,1) ; lower right Local v3%=AddVertex(surf, 1,-1,0,0,1) ; lower left ; connect vertices AddTriangle surf,v0,v1,v2 AddTriangle surf,v0,v2,v3 ; parent, fx, texcture and blending If parent Then EntityParent mesh,parent If fx Then EntityFX mesh,fx If tex Then EntityTexture mesh,tex If blend Then EntityBlend mesh,blend ; color and alpha EntityColor mesh,r,g,b EntityAlpha mesh,a ; vertexcolor and vertexalpha VertexColor surf,v0,r,g,b,a VertexColor surf,v1,r,g,b,a VertexColor surf,v2,r,g,b,a VertexColor surf,v3,r,g,b,a ; scale ScaleEntity mesh,scale,scale,scale Return mesh End Function ; Create a simple but impressive sun texture Function CreateSunTexture() Local tex%=CreateTexture(512,512,3) Local tb%=TextureBuffer(tex) Local i#,j%,col%,rgb% SetBuffer tb LockBuffer tb ; Intensity steps For j=0 To 255 col=255-j If col>255 Then col=255 rgb=col*$1000000+col*$10000+col*$100+col ; Draw circles For i=0 To 360 Step 0.1 WritePixelFast 256+(Sin(i)*j),256+(Cos(i)*j),rgb,tb Next Next UnlockBuffer tb SetBuffer BackBuffer() Return tex End Function |
||
![]() |
AlkanBetreff: Hmmm?? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich find das sehr gut was du da programmiert hast,doch irgendwie klappt das bei mir nicht!
Ich hab blitz3d und da steht im debugger immer : Zitat: Function Not Found kanns du mir vieleicht sagen wieso das passiert?
Ich hab den neusten Code von dir Kopiert und Eingefügt. MfG Alkan |
||
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD Worklog: Planetensimulation Homepage(Under Construction): alkan96.dyndns.org Wenn schon falsch, dann richtig falsch. |
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Welche Zeile ist markiert? Welche Blitz3D-Version hast du? (Version findest du unter "Help->About Blitz3D!") | ||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
![]() |
AlkanBetreff: nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da ist ja eben überhaupt keine zeile markiert.
Und die Version: Alos da steht: Zitat: IDE V1.66 - Linker V1.64 - Runtime V1.66
|
||
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD Worklog: Planetensimulation Homepage(Under Construction): alkan96.dyndns.org Wenn schon falsch, dann richtig falsch. |
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Geh auf www.blitzbasic.com , meld dich an und lad im "Account"-Bereich das neuste Update herunter. | ||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
![]() |
ChriseBetreff: Re: nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie übel genial ist das denn?? Du bekommst meine Bewunderung, Krischan!
Sehr realistisch! Einziges Problem. Aber ner bestimmten Nähe zum Planeten will das Raumschiff irgendwie nimmer weiterfliegen ![]() |
||
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet. |
KrischanBetreff: Re: nicdel |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Chrise hat Folgendes geschrieben: Einziges Problem. Aber ner bestimmten Nähe zum Planeten will das Raumschiff irgendwie nimmer weiterfliegen
![]() Das liegt an viel zu kleinen Werten, die bei meinen Funktionen irgendwann herauskommen müssen. Du musst eigentlich nur in der Movement-Funktion abfragen, dass der Bewegungswert (cz*Abs(mm)*multi) nicht zu klein wird. Falls ja: das Schiff stoppen oder in einen Autopilot-Orbit einschwenken lassen. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group