Homekeeping
Übersicht

KrischanBetreff: Homekeeping |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Homekeeping bedeutet, dass man die Welt um den Spieler herum bewegt, während sich der Spieler nur in einem begrenzten Gebiet um 0,0,0 herum bewegt. Damit kann man das "wabern" von Meshes bei grossen Distanzen, z.B. in Weltraumumgebungen verhindern und sehr grosse Cameraranges verwenden, z.B. 1,1000000. Die Idee dazu kam mir, nachdem ich erfolglos versuchte ein Sonnensystem mit halbwegs realistischen Grössenverhältnissen in Relation zum Spieler zu basteln und immer an der Camerarange gescheitert bin bzw. dynamisches Skalieren irgendwie seltsam aussah.
Das Prinzip ist ganz einfach: man hängt einfach alles, was mit der Welt zu tun hat (z.B. Sonne, Planeten, Asteroiden) an ein "masterpivot" - alles, bis auf den Spieler! Die Funktion überprüft nun, ob sich der Spieler ausserhalb seines "home bereiches", der homesize% befindet. Falls dies der Fall ist, wird die Spielerposition rückgesetzt und die Welt bzw. das masterpivot um die homesize% der entsprechenden Achse verschoben. In den Variablen localx/y/z ist dabei die "echte" Position des Spielers innerhalb der homesize gespeichert, in den Variablen globalx/y/z die simulierte Differenz und beide Werte addiert ergibt die simulierte Spielerposition. Homekeeping Funktion: Code: [AUSKLAPPEN] Function HomeKeeping(player%,world%,homesize%=100)
localx=EntityX(player) localy=EntityY(player) localz=EntityZ(player) If localx>homesize Then globalx=globalx+homesize localx=localx-homesize PositionEntity player,localx,localy,localz MoveEntity world,-homesize,0,0 EndIf If localx<-homesize Then globalx=globalx-homesize localx=localx+homesize PositionEntity player,localx,localy,localz MoveEntity world,homesize,0,0 EndIf If localy>homesize Then globaly=globaly+homesize localy=localy-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,-homesize,0 EndIf If localy<-homesize Then globaly=globaly-homesize localy=localy+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,homesize,0 EndIf If localz>homesize Then globalz=globalz+homesize localz=localz-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,-homesize EndIf If localz<-homesize Then globalz=globalz-homesize localz=localz+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,homesize EndIf End Function Hier mal ein Beispiel einer Sonne mit 25.000 umliegenden Objekten im Bereich von 10.000 bis 100.000 und einer Camerarange von 1.000.000. Kommentiert man in der Hauptschleife die Homekeeping-Funktion aus, fängt das Spielermesh bei ca. 32.000 Entfernung zur Sonne an böse zu wabern, mit der Funktion bleibt es bis zum INT/Float-Limit stabil. ACHTUNG: in diesem Code ist die Funktion bereits entkommentiert damit man zuerst den Wabereffekt sieht. Steuerung mit Maus/Pfeiltasten, RSHIFT=10x schneller fliegen und LMB=Zoom 10x: Code: [AUSKLAPPEN] Graphics3D 800,600,32,2
Global GameSpeed%=60 Global Screenwidth%=GraphicsWidth() Global Screenheight%=GraphicsHeight() Global FramePeriod%=1000/GameSpeed Global FrameTime%=MilliSecs()-FramePeriod Global movetarget%,masterpivot% Global player%,cam%,ship%,sun%,light% Global iwc%,ihc%,iwk%,ihk% Global kreuz%,cursor% Global localx#,localy#,localz# Global globalx#,globaly#,globalz# Global reichweite# = 9000.0 Global rollspeed# = 1.0 Global turnspeed# = 2.0 Global maxroll# = 20.0 Global speed# = 100.0 Global wf%,mx%,my%,t1#,t2#,roll#,currentspeed# InitWorld() MoveMouse Screenwidth/2,Screenheight/2 While Not KeyHit(1) Local FrameElapsed%,FrameTicks%,FrameTween#,t% Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed FrameTicks=FrameElapsed/FramePeriod FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod) For t=1 To FrameTicks FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld Movement() localx=EntityX(player) localy=EntityY(player) localz=EntityZ(player) ;HomeKeeping(player,masterpivot,1000) UpdateWorld Next RenderWorld FrameTween CameraProject cam,EntityX(movetarget,1),EntityY(movetarget,1),EntityZ(movetarget,1) DrawImage kreuz,ProjectedX()-iwk,ProjectedY()-ihk DrawImage cursor,mx-iwc,my-ihc Text 0, 0,"Local Position....: "+localx+" | "+localy+" | "+localz Text 0,15,"Global Position...: "+globalx+" | "+globaly+" | "+globalz Text 0,30,"Simulated Position: "+(globalx+localx)+" | "+(globaly+localy)+" | "+(globalz+localz) Text 0,45,"Distance to Sun...: "+EntityDistance(player,sun) Flip 0 Wend End Function HomeKeeping(player%,world%,homesize%=100) If localx>homesize Then globalx=globalx+homesize localx=localx-homesize PositionEntity player,localx,localy,localz MoveEntity world,-homesize,0,0 EndIf If localx<-homesize Then globalx=globalx-homesize localx=localx+homesize PositionEntity player,localx,localy,localz MoveEntity world,homesize,0,0 EndIf If localy>homesize Then globaly=globaly+homesize localy=localy-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,-homesize,0 EndIf If localy<-homesize Then globaly=globaly-homesize localy=localy+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,homesize,0 EndIf If localz>homesize Then globalz=globalz+homesize localz=localz-homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,-homesize EndIf If localz<-homesize Then globalz=globalz-homesize localz=localz+homesize PositionEntity player,localx,localy,localz MoveEntity world,0,0,homesize EndIf End Function Function InitWorld() Local mesh%,surf%,cube%,i%,s#,d# masterpivot=CreatePivot() player=CreatePivot() PositionEntity player,0,1000,-10000 ship=CreateCube(player) EntityFX ship,1 EntityColor ship,0,128,255 ScaleEntity ship,1,0.05,1 PositionEntity ship,0,-0.5,1.5 EntityOrder ship,-1000 movetarget=CreatePivot(player) MoveEntity movetarget,0,0,reichweite cam=CreateCamera(player) PositionEntity cam,0,0.5,-1.5 CameraFogMode cam,True CameraRange cam,1,1000000 CameraFogRange cam,500000,1000000 CameraZoom cam,1 CameraClsColor cam,0,0,0 CameraFogColor cam,0,0,0 cursor=CreateImage(33,33) Color 255,0,0 SetBuffer ImageBuffer(cursor) Rect 0,0,33,33,0 iwc=ImageWidth(cursor)/2 ihc=ImageHeight(cursor)/2 kreuz=CreateImage(33,33) Color 0,255,0 SetBuffer ImageBuffer(kreuz) Line 16,0,16,33 Line 0,16,33,16 iwk=ImageWidth(kreuz)/2 ihk=ImageHeight(kreuz)/2 SetBuffer BackBuffer() mesh=CreateMesh(masterpivot) surf=CreateSurface(mesh) EntityFX mesh,2 sun=CreateSphere(32,masterpivot) EntityFX sun,1+8 EntityColor sun,255,255,224 ScaleMesh sun,6000,6000,6000 light=CreateLight(2,masterpivot) LightRange light,50000 AmbientLight 32,32,32 cube=CreateCube() For i=1 To 25000 s#=Rnd(10,100) If Rnd(1)>0.999 Then s=Rnd(100,1000) d#=Rnd(10000,100000) ScaleEntity cube,s,s,s PositionEntity cube,0,0,0 RotateEntity cube,0,0,0 TurnEntity cube,Rnd(-Rnd(0,90),Rnd(0,90)),Rnd(0,360),0 MoveEntity cube,0,0,d PointEntity cube,sun AddToMesh(cube,mesh,128,128,128,1) Next FreeEntity cube UpdateNormals mesh PointEntity player,sun End Function Function Normalisieren#(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 Movement() Local multi#,limit# roll=0 If KeyDown(203) Then roll=rollspeed If KeyDown(205) Then roll=-rollspeed If KeyHit(57) Then wf=1-wf : WireFrame wf If KeyDown(54) Then multi=10 Else multi=1 If MouseDown(1) Then CameraZoom cam,10 : limit=0.1 Else CameraZoom cam,1 : limit=1.0 currentspeed=(KeyDown(200)-KeyDown(208))*speed*multi MoveEntity player,0,0,currentspeed mx=MouseX() my=MouseY() t1=Normalisieren(my,0,Screenheight,-1,1) t2=Normalisieren(mx,0,Screenwidth,1,-1) RotateEntity ship,t1*maxroll,t2*maxroll,t2*maxroll*2 TurnEntity player,t1*turnspeed*limit,t2*turnspeed*limit,roll*turnspeed End Function Function AddToMesh(source%,target%,r%,g%,b%,a#) Local vert%[2],vr%[2],vg%[2],vb%[2],va#[2] Local oldvert%,i1%,i2%,v1%,v2% Local surf%,surf1%=GetSurface(source,1),surf2% v1=CountVertices(surf1) For v2=1 To CountSurfaces(target) surf=GetSurface(target,v2) If CountVertices(surf)+v1<64000 Then surf2=surf : Goto skip Next surf2=CreateSurface(target) .skip For i1=0 To CountTriangles(surf1)-1 For i2=0 To 2 oldvert = TriangleVertex(surf1,i1,i2) vr[i2]=r vg[i2]=g vb[i2]=b va[i2]=a TFormPoint VertexX(surf1,oldvert),VertexY(surf1,oldvert),VertexZ(surf1,oldvert),source,target vert[i2]=AddVertex(surf2,TFormedX(),TFormedY(),TFormedZ(),VertexU(surf1,oldvert),VertexV(surf1,oldvert)) VertexColor surf2,vert[i2],r,g,b,a VertexNormal surf2,vert[i2],VertexNX(surf1,oldvert),VertexNY(surf1,oldvert),VertexNZ(surf1,oldvert) Next AddTriangle(surf2,vert[0],vert[1],vert[2]) Next End Function |
||
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr schön das ganze, aber was ist bei Kollisionserkennung ? weil die kann man in Blitz jetzt komplett in die Pfanne hauen, da beide Mesches sich bewegen.
mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
Silver_Knee |
![]() Antworten mit Zitat ![]() |
---|---|---|
ne kolli kommt immer vor dem rücksetzten
was vorher nicht kollidiert ist kollidiert auch nacher nicht, da die relativen positionen immer gleich bleiben. Ich kenne das ganze als Systemcubes und habs von Evo in cnRS benutzt. Eine Erkenntnis will ich euch nicht vorenthalten: Nimm while anstatt if. Dann kannst du auch mit geschwindigkeiten > 2* homezone ohne ein Nachziehen (da pro frame sonst max. 1 homezone gsprungen wird) arbeiten. |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hast Recht, Silver_Knee, hatte später das Problem beim Positionieren des Spielers weit ausserhalb der Homezone (z.B. 0,0,-1000000). Hat das gedauert, bis sich die Welt repositioniert hatte ![]() Code: [AUSKLAPPEN] Function HomeKeeping(player%,world%,homesize%=100)
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 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 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 End Function |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group