Maussteuerung flüssig und schön?

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

Megamag

Betreff: Maussteuerung flüssig und schön?

BeitragMo, Jun 22, 2009 20:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Tag mal wieder Smile
Ich mache gerade ein Spiel mit einer GTA-artigen Maussteuerung (in 3D), wobei
die Kamera immer hinter dem Paly ist und sich um diesen dreht. Ich habe das auch
schon ganz gut hinbekommen, bis jetzt.

Es gibt vielerlei Probleme.

1.- Ich habe es schon so gemacht, dass man mit der Kamera nicht durch den Boden kommt.
Doch das Problem ist, dass die Kamera etwas stockt, wenn ich sie zurück nach oben hole. Wie
kann ich das hinkirgen, dass es schön flüssig funktioniert? Ich habe mit schon fast den Kopf
zwerbrochen, aber ich komme nicht drauf, wie man sowas anstellen sollte.

2.- Ihr werdet vielleicht lachen, aber irgendwie klappt eine Begrenzung nicht, dass man nicht weiter gehen
kann, als Kamera-Pitch 90 und nicht tiefer gehen kann als Kamera-Pitch -40. Könnt ihr mir da auch helfen?

3.- Hm, ja...
Das war's eigentlich. Wenn mir noch Fragen zur Kameraführung kommen, die ich nicht lösen kann, dann
sage ich bescheid. Aber das waren die Hauptprobleme. Ich hoffe, ihr helft mir. Very Happy

,-Megamag


Hey, ich habe mir nach viel Kopfzerbrechen einen neuen Code gebaut:
Code: [AUSKLAPPEN]
Graphics3D 1024, 768, 32, 1
SetBuffer BackBuffer()

Const links = 30
Const rechts = 32
Const hoch = 17
Const runter = 31

Global player=CreateCube()
EntityRadius player,1.8
EntityType player,1
Global playerpiv=CreateSphere(16,player)
ScaleEntity playerpiv,.3,.3,.3
PositionEntity playerpiv,0,3,0
EntityAlpha playerpiv,0

Global cam=CreateCamera()

light = CreateLight(2)
PositionEntity light, 0, 20, 0
LightRange light,35

scene = CreatePlane();LoadMesh("data\Models\Test.b3d")
PositionEntity scene, 0, -2, 0
EntityColor scene,0,80,0

tree=CreateCube()
PositionEntity tree,0,0,20

Global XXX#=20
Global YYY#=20
Global ZZZ#=20
Global c#=0

;----------------------------------------------------------------------------;

While Not KeyHit(1)

winkel=winkel-MouseXSpeed()/2
winkel2=winkel2+MouseYSpeed()/1.8
X# = XXX * Cos( winkel ) * Cos( winkel2 )
Y# = XXX * Sin( winkel2 )
Z# = XXX * Sin( winkel ) * Cos( winkel2 )
PositionEntity cam,EntityX(player)+x,EntityY(player)+y,EntityZ(player)+z
RotateEntity player,EntityPitch(player),winkel+90,EntityRoll(player)

If EntityY(cam)<EntityY(player) Then ;PositionEntity cam,EntityX(cam),EntityY(player),EntityZ(cam)
XXX=c#
EndIf

PointEntity cam,playerpiv

MoveMouse 512,384

If Not EntityPitch(cam)>-40 Then
If Not EntityPitch(cam)<90 Then
PositionEntity cam,EntityX(player),EntityY(cam),EntityZ(player)
EndIf
EndIf


If KeyDown(hoch) MoveEntity player,0,0,0.3


UpdateWorld
RenderWorld
a#=EntityPitch(cam)*EntityPitch(cam)
b#=EntityPitch(cam)/a
c#=b*-200
Text 0,0,"X: "+c
Flip
Wend
End

;----------------------------------------------------------------------------;

Irgendwie wackelt es immer noch ein wenig, und vor allem, wenn ich die Kamera zurückziehe, geht sie
nicht wieder ganz zurück. Warum? Was habe ich falsch gemacht?

ToeB

BeitragDi, Jun 23, 2009 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Gehen wir mal rein mathematisch vor. Du willst ja das die Camera sich immer hinten dem an einer Position zu sehen ist. Das allein ist nicht schwer. Dazu erstelltst du einen Pivot :
Code: [AUSKLAPPEN]
global cam_piv = CreatePivot(Player)
PositionEntity cam_piv,0,5,-5,0  ;Pivot an der Stelle positionieren, wo die camera hinsoll...


Jetzt muss man nur noch die camera dorthin setzten :
Code: [AUSKLAPPEN]
cam_x# = EntityX(cam_piv,1)
cam_y# = EntityY(cam_piv,1)
cam_z# = EntityZ(cam_piv,1)
PositionEntity Camera,cam_x#,cam_y#,cam_z#


Dann würde die camera immer an der gleichen stelle stehen, sieht gar nicht gut aus und ich glaub das willst du auch nicht. Dazu ersetzten wir die Koordinaten durch eine differenz zwischen der Camera und dem Pivot (also Pivot_pos - Camera_pos), sodasss wir x/y/z abstand zum Pivot haben, und ersetzten das Positionieren mit einer Bewegung :
Code: [AUSKLAPPEN]
cam_x# = (EntityX(cam_piv,1) - EntityX(camera) )
cam_y# = (EntityY(cam_piv,1) - EntityY(camera) )
cam_z# = (EntityZ(cam_piv,1) - EntityZ(camera) )
TranslateEntity camera,cam_x#,cam_y#,cam_z#


Sieht das jetzt nicvht genauso aus oO ? JA ! Weil wir den abstand errechnen und dann die camera um diesen abstand bewegen, also genau so wie oben ? NEIN ! Weil jetzt können wir die Geschwindigkeit ändern, mit der die Camera sich auf den Pivot zu bewegt. Das machen wir mit einem faktor, der < 1 aber > 0 ist (z.b. 0.03). :

Code: [AUSKLAPPEN]
cam_x# = (EntityX(cam_piv,1) - EntityX(camera) ) * 0.03
cam_y# = (EntityY(cam_piv,1) - EntityY(camera) ) * 0.03
cam_z# = (EntityZ(cam_piv,1) - EntityZ(camera) ) * 0.03
TranslateEntity camera,cam_x#,cam_y#,cam_z#


Um jetzt die Camera auch immer schön auf den Player zu richten, nehmen wir noch den schönen befehl PointEntity :
Code: [AUSKLAPPEN]
PointEntity camera,Player


(Das ganze ist auch im Sample "Driver.bb" nachzulesen...)


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!

Megamag

BeitragDi, Jun 23, 2009 16:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Antwort!
Es ist aber nicht genau das, was ich möchte.
Ich habe es wohl falsch ausgedrückt...

Es geht darum, dass die Kamera nicht durch Hindernisse gehen soll (das ist verdammt schwer).
Sondern, anstelle durch eine Wand oder einen Boden gehen, so an den Player ranzoomen, wie
man es in vielen Spielen, meistens auch in MMORPGs sieht. Ich habe es in dem Code oben schon
probiert mit dem Boden. Es klappt ganz gut, aber mit einem anderen Objekt...
kein Plan.

Sorry, wenn es unverständluich war, aber es ging um die Flüssigkeit, wie die Kamera an den Player
ranzoomt. Mit dem Boden habe ich es jetzt weitestgehend hingekriegt:

Code: [AUSKLAPPEN]
Graphics3D 1024, 768, 32, 1
SetBuffer BackBuffer()

Const links = 30
Const rechts = 32
Const hoch = 17
Const runter = 31

Const C_CAM=1
Const C_CC=2

Collisions C_CAM,C_CC,2,3

Global player=CreateCube()
EntityRadius player,1.8
EntityType player,1
Global playerpiv=CreateSphere(16,player)
ScaleEntity playerpiv,.3,.3,.3
PositionEntity playerpiv,0,3,0
EntityAlpha playerpiv,0.5

Global cam=CreateCamera()
Global cambox=CreateSphere(16)
EntityAlpha cambox,0.5
EntityType cambox,C_CAM

;Global cam2=CreateCamera()
;PositionEntity cam2,0,20,-20
;PointEntity cam2,player

light = CreateLight(2)
PositionEntity light, 0, 20, 0
LightRange light,35

scene = CreatePlane();LoadMesh("data\Models\Test.b3d")
ScaleEntity scene,2,2,2
PositionEntity scene, 0, -2, 0
EntityType scene,C_CC
EntityColor scene,0,80,0

tree=CreateCube()
PositionEntity tree,0,0,-18
ScaleEntity tree,3,4,3


Global XXX#=20
Global YYY#=20
Global ZZZ#=20
Global c#=0

;----------------------------------------------------------------------------;

While Not KeyHit(1)

winkel=winkel-MouseXSpeed()/2
winkel2=winkel2+MouseYSpeed()/1.8
X# = XXX * Cos( winkel ) * Cos( winkel2 )
Y# = XXX * Sin( winkel2 )
Z# = XXX * Sin( winkel ) * Cos( winkel2 )
PositionEntity cam,EntityX(player)+x,EntityY(player)+y,EntityZ(player)+z
RotateEntity player,EntityPitch(player),winkel+90,EntityRoll(player)

If c#>20 Then c#=20

If  EntityY(cam)<EntityY(player) Then;EntityCollided(cambox,C_CC) Then ;EntityY(cam)<EntityY(player)-1 Then ;PositionEntity cam,EntityX(cam),EntityY(player),EntityZ(cam)
XXX=c#
EndIf

If EntityDistance(cam,player)<19.5 Then
XXX=c#
EndIf


PointEntity cam,playerpiv
PositionEntity cambox,EntityX(cam),EntityY(cam),EntityZ(cam)

MoveMouse 512,384

If Not EntityPitch(cam)>-40 Then
If Not EntityPitch(cam)<90 Then
PositionEntity cam,EntityX(player),EntityY(cam),EntityZ(player)
EndIf
EndIf


If KeyDown(hoch) MoveEntity player,0,0,0.3


UpdateWorld
RenderWorld
a#=EntityPitch(cam)*EntityPitch(cam)
b#=EntityPitch(cam)/a
c#=b*-200
Text 0,0,"X: "+EntityCollided(cambox,C_CC)
Flip
Wend
End

;----------------------------------------------------------------------------;


Bwegt bei dem Code die Kamera nach unten, und sie zoomt schön an den Palyer ran Very Happy
Wie ich es jetzt aber mit Seitenwänden hinkriegen soll, weiß ich echt nicht Sad

ToeB

BeitragDi, Jun 23, 2009 16:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich versuch grad deinen code ein wenig um zu schreiben, gib ihn dir gleich.

Also du willst versuchen, das die Camera sich so "klug" verhält, das sie, wenn irgentwas die sicht auf den player behindert, sie solange reinzoomt, bis es nicht mehr der fall ist ?

Gut. Stellen wir uns mal eine gerade vor. Diese gerade geht vom player bis zur Camera. Diese gerade nennen wir mal "Sichtbarkeits-gerade". Wenn jetzt irgentwas diese Gerade berüht, also die sicht verdeckt, fährt die camera heran, solange bis nix mehr verdeckt wird (Kollision ausgeschaltet).
Jetzt wird die Kollision wieder angeschaltet, sodass, wenn eine wand hinter der camera ist, sie dort hängen bleibt, und man bewegt sie langsam zurück. wärendessen prüft man aber immer weiter, ob gegenstände in dieser Linine sind, und verfährt dann dem entsprechend. Probiers mal mit LinePick, EntityPick oder CameraPick. (Wobei ich hier zu Camerapick rate, ist 100mal schneller als linepick, aber ungenauer)

Ich versuchs auch mal einzubauen, garantiere aber für nix Wink

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!

Megamag

BeitragDi, Jun 23, 2009 16:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke sehr! Very Happy
Aber Die Picks klappen ja nur in eine Richtung, oder?
Dann ist die Kamera ja eigentlich schon durch die wAnd durch, bevor sie merkt,
dass es eine Wand gibt, oder? Naja, ich schau mal, ob ich es irgendwie hinkriege,
du kannst ja auch probieren Wink

ToeB

BeitragDi, Jun 23, 2009 16:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier schonmal ein ansatz, den rest musst du selber machen Wink

Code: [AUSKLAPPEN]
Graphics3D 1024, 768, 32, 2
SetBuffer BackBuffer()

Const links = 30
Const rechts = 32
Const hoch = 17
Const runter = 31

Global player=CreateCone()
RotateMesh player,90,0,0
EntityRadius player,1.8
EntityType player,1
EntityPickMode player,1
NameEntity(player,"Player")


Global cam=CreateCamera()
   CameraRange cam,0.1,1000
   

Global ply_piv = CreatePivot(player)

Global cam_piv = CreatePivot(ply_piv)
   PositionEntity cam_piv,0,10,10
   EntityType cam_piv,5
   EntityRadius cam_piv,0.25


light = CreateLight(2)
PositionEntity light, 0, 20, 0
LightRange light,35

scene = CreatePlane();LoadMesh("data\Models\Test.b3d")
PositionEntity scene, 0, -2, 0
EntityColor scene,0,80,0
EntityType scene,6
EntityPickMode scene,2
NameEntity(scene,"Plane")

tree=CreateCube()
PositionEntity tree,0,0,0
EntityType tree,6
EntityPickMode tree,2
NameEntity(tree,"Tree")

Global XXX#=20
Global YYY#=20
Global ZZZ#=20
Global c#=0

Collisions 5,6,2,2

PointEntity cam_piv,player

Global steps = 0

;----------------------------------------------------------------------------;

While Not KeyHit(1)



;Drehen
winkel_old_x# = EntityPitch(ply_piv)
winkel_old_y# = EntityYaw(player)
winkel_x# = winkel_old_x - MouseYSpeed()/3.0
winkel_y# = winkel_old_y - MouseXSpeed()/3.0

;ausrichten
TurnEntity ply_piv,(winkel_x-winkel_old_x)*0.3,0,0
TurnEntity player,0,(winkel_y-winkel_old_y)*0.3,0



MoveMouse 1024/2,768/2

;Camera zu dem Pivot ausrichten :
cam_x# = (EntityX(cam_piv,1) - EntityX(cam) ) * 0.3
cam_y# = (EntityY(cam_piv,1) - EntityY(cam) ) * 0.3
cam_z# = (EntityZ(cam_piv,1) - EntityZ(cam) ) * 0.3
TranslateEntity cam,cam_x#,cam_y#,cam_z#

PointEntity cam,player


;Camera auf sicht prüfen
entity = EntityPick(cam_piv,1000)
If entity <> player And entity <> 0 ;Wenn irgentwas dazwischen ist
   MoveEntity cam_piv,0,0,0.1
   ResetEntity cam_piv
   steps = steps + 1
Else
   If steps > 0
      MoveEntity cam_piv,0,0,-0.1
      steps = steps - 1
   EndIf
EndIf

If KeyDown(hoch) MoveEntity player,0,0,0.3


UpdateWorld
RenderWorld

Text 0,0 ,"Winkel(Pitch) : "+winkel_x
Text 0,15,"Winkel(  Yaw) : "+winkel_y
If entity Text 0,30,"Picked Entity : "+EntityName(entity)

Flip
Wend
End

;----------------------------------------------------------------------------;


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!

Megamag

BeitragDi, Jun 23, 2009 17:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke, für den Ansatz Very Happy
Das Problem ist nur, da geht die Kamera gar nicht mehr zurück und totzdem noch durch den Boden.
Ich habe es jetzt mal selber probiert, aber es scheint immer noch nicht zu gehen.
Das LinePick ganz am Ende zeigt nur in einer ganz bestimmten Position die weiße Box an?

Code: [AUSKLAPPEN]
Graphics3D 1024, 768, 32, 1
SetBuffer BackBuffer()

Const links = 30
Const rechts = 32
Const hoch = 17
Const runter = 31

Const C_CAM=1
Const C_CC=2

Collisions C_CAM,C_CC,2,3

Global cam=CreateCamera()

Global player=CreateCube()
EntityRadius player,1.8
EntityType player,1
Global playerpiv=CreateSphere(16,player)
ScaleEntity playerpiv,.3,.3,.3
PositionEntity playerpiv,0,3,0
EntityAlpha playerpiv,0.5

;Global cam2=CreateCamera()
;PositionEntity cam2,0,20,-20
;PointEntity cam2,player

light = CreateLight(2)
PositionEntity light, 0, 20, 0
LightRange light,35

scene = LoadMesh("data\Models\Test.b3d")
ScaleEntity scene,2,2,2
PositionEntity scene, 0, -2, 0
EntityType scene,C_CC
;EntityColor scene,0,80,0

tree=CreateCube()
PositionEntity tree,0,0,-18
ScaleEntity tree,3,4,3
EntityPickMode tree,2


Global XXX#=20
Global YYY#=20
Global ZZZ#=20
Global c#=0

;----------------------------------------------------------------------------;

While Not KeyHit(1)

winkel=winkel-MouseXSpeed()/2
winkel2=winkel2+MouseYSpeed()/1.8
X# = XXX * Cos( winkel ) * Cos( winkel2 )
Y# = XXX * Sin( winkel2 )
Z# = XXX * Sin( winkel ) * Cos( winkel2 )
PositionEntity cam,EntityX(player)+x,EntityY(player)+y,EntityZ(player)+z
RotateEntity player,EntityPitch(player),winkel+90,EntityRoll(player)

If c#>20 Then c#=20

If  EntityY(cam)<EntityY(player) Then ;EntityY(cam)<EntityY(player)-1 Then ;PositionEntity cam,EntityX(cam),EntityY(player),EntityZ(cam)
XXX=c#
EndIf

If EntityDistance(cam,player)<19.5 Then
XXX=c#
EndIf


PointEntity cam,playerpiv

MoveMouse 512,384

If Not EntityPitch(cam)>-40 Then
If Not EntityPitch(cam)<90 Then
PositionEntity cam,EntityX(player),EntityY(cam),EntityZ(player)
EndIf
EndIf


If KeyDown(hoch) MoveEntity player,0,0,0.3


UpdateWorld
RenderWorld
a#=EntityPitch(cam)*EntityPitch(cam)
b#=EntityPitch(cam)/a
c#=b*-200
Text 0,0,"X: "+LinePick(EntityX(cam),EntityY(cam),EntityZ(cam),EntityX(player),EntityY(player),EntityZ(player))
Flip
Wend
End

;----------------------------------------------------------------------------;


EDIT: Shocked Mann, war ich dumm... Ich habe einfach mal der Kamera eine Kollision gegeben,
und jetzt rutscht sie automatisch an Wänden entlang. So einfach kann's gehen Very Happy

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group