About Monkey 2 › Forums › Monkey 2 Code Library › WASD camera control with mouse look
Tagged: Camera, First Person, mojo3d
This topic contains 0 replies, has 1 voice, and was last updated by
Ethernaut
1 year, 8 months ago.
-
AuthorPosts
-
August 19, 2017 at 4:19 am #9910
Since last time I did something 2D in Mojo3D Mark yelled at me (just kidding! We love you Mark), here’s something more proper for 3D. After years (decades?) playing first person games, I really don’t like the “util.Fly” camera controls that’s in every Mojo3D example, so I made my own function that uses a control scheme more familiar to that sort of game.
You can make a module out of it and it becomes really easy to Import and use. There’s one function you call at the start, and one that you call on every frame, with optional delta frame support (use delta = 1.0 for “normal” speed. I don’t like “millisecs based delta” ).
If you use touchStyle = true, it seems more appropriate for touch screens, since you have to tap (click) then drag, and the camera pan&tilt follows the same direction of the drag. But I haven’t tested it on a touch based device, so feedback is welcome.
Use example: in the Mojo3D examples, import this file and replace any line that says:
util.Fly( _camera, Self )
With:
WasdCameraControl( _camera, Self, 1.0 )Default Keys:
W,S – Move forward and back
A,D – Strafe left and right
R, F – Up and Down
Shift – Move faster modifier
Control – Move slower modifier
Mouse to look aroundStill has some kinks, like losing track of the mouse if you switch to a different window and come back, or if you start the app with the mouse cursor outside the window. But it seems to work great if the app is fullscreen, so there you go:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990Namespace util#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..'Works better in full screen! In windowed mode the mouse cursor seems to be "lost" sometimes'Call WASDInit a single time on start, then WASDCameraControl on every frame.'The default values work well with delta = 1.0. Adjust if your delta is counted in seconds instead.Function WasdInit( window:Window, showMouse:Bool = False )Mouse.Location = New Vec2i( window.Width / 2, window.Height / 2 )Mouse.PointerVisible = showMouseEndFunction WasdCameraControl( cam:Entity, window:Window, delta:Double = 1.0, touchStyle:Bool = False ,walkSpeed:Float = 0.1, mouseLookSpeed:Float = 0.2 )Global prevMouse:= New Vec2f( Float( Mouse.X ), Float( Mouse.Y ) )Global finalWalkSpeed:FloatIf App.ActiveWindowIf Keyboard.KeyDown( Key.LeftShift ) Or Keyboard.KeyDown( Key.RightShift )finalWalkSpeed = ( 3.0 * walkSpeed ) * deltaElseIf Keyboard.KeyDown( Key.LeftControl ) Or Keyboard.KeyDown( Key.RightControl )finalWalkSpeed = ( walkSpeed / 3.0 ) * deltaElsefinalWalkSpeed = walkSpeed * deltaEndIf Keyboard.KeyDown( Key.W ) Or Keyboard.KeyDown( Key.Up )cam.MoveZ( finalWalkSpeed )ElseIf Keyboard.KeyDown( Key.S ) Or Keyboard.KeyDown( Key.Down )cam.MoveZ( -finalWalkSpeed )EndIf Keyboard.KeyDown( Key.A ) Or Keyboard.KeyDown( Key.Left )cam.MoveX( -finalWalkSpeed )ElseIf Keyboard.KeyDown( Key.D ) Or Keyboard.KeyDown( Key.Right )cam.MoveX( finalWalkSpeed )EndIf Keyboard.KeyDown( Key.R )cam.MoveY( finalWalkSpeed )ElseIf Keyboard.KeyDown( Key.F )cam.MoveY( -finalWalkSpeed )EndIf touchStyleIf Mouse.ButtonHit( MouseButton.Left )prevMouse = New Vec2f( Float( Mouse.X ), Float( Mouse.Y ) )EndIf Mouse.ButtonDown( MouseButton.Left )prevMouse = MouseLook( cam, window, prevMouse, mouseLookSpeed/2.0 )EndElseprevMouse = MouseLook( cam, window, prevMouse, -mouseLookSpeed )'limits mouse to center of screen to prevent losing it out of the windowLocal threshold := window.Height / 10Local center := New Vec2i( window.Width/2, window.Height/2 )Local limit := New Recti( center.X - threshold, center.Y - threshold, center.X + threshold, center.Y + threshold )If Mouse.X < limit.Left Or Mouse.X > limit.Right Or Mouse.Y < limit.Top Or Mouse.Y > limit.BottomMouse.Location = New Vec2i( center.X, center.Y )prevMouse = Mouse.LocationEndEndEndEndPrivateFunction MouseLook:Vec2f( ent:Entity, window:Window, prevMouse:Vec2f, speed:Float )Local diff:= New Vec2f( Mouse.X - prevMouse.X, prevMouse.Y - Mouse.Y )If Abs( diff.X ) > 0ent.RotateY( diff.X * speed, False )prevMouse.X = Mouse.XEndIf Abs( diff.Y ) > 0ent.RotateX( diff.Y * speed, False )prevMouse.Y = Mouse.YEndent.LocalRotation = New Vec3f( ent.LocalRx, ent.LocalRy, 0 )Return prevMouseEndCheers!
-
AuthorPosts
You must be logged in to reply to this topic.