func UpdatePlayer(p *gamestate.Player, gs *gamestate.GameState) { rot := p.Input.Rotate p.Camera.Yaw(rot[0]) p.Camera.Pitch(rot[1]) p.Camera.Roll(rot[2]) move := p.Input.Move if move.Len() > 0 { move = move.Normalize() } move_xyz := p.Camera.Orientation.Rotate(move.Vec3()) move = move_xyz.Vec4(0) if !gs.Options.PlayerPhysics { move = move.Mul(0.1) p.Velocity = move p.Camera.MoveAbsolute(move) } else { move = move.Mul(0.01) p.Velocity = p.Velocity.Add(move) p.Camera.MoveAbsolute(p.Velocity) pos := p.Position() groundHeight := gs.World.HeightMap.Get2f(pos[0], pos[1]) groundNormal := gs.World.HeightMap.Normal2f(pos[0], pos[1]) height := p.Camera.Position[2] minHeight := groundHeight + 1.5 maxHeight := groundHeight + 20 if height < minHeight { diff := minHeight - height p.Velocity = p.Velocity.Add(helpers.Vector(groundNormal.Mul(diff))) //p.Camera.Position[2] += diff } p.Velocity = p.Velocity.Mul(0.95) if height > maxHeight && p.Velocity[2] > -0.0 { p.Velocity[2] -= 0.001 } groundFactor := (height - groundHeight) / 20 if groundFactor > 1 { groundFactor = 1 } if groundFactor < 0 { groundFactor = 0 } groundFactor = 1 - groundFactor groundFactor = groundFactor * groundFactor } }
// returns false if the player wants to quit func Input(gs *gamestate.GameState, worldRenderer *rendering.WorldRenderer) bool { running := true window := gs.Window inp := gamestate.PlayerInput{} for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { consumeEvent := true if !sdl.GetRelativeMouseMode() { consumeEvent = tw.EventSDL(event, 2, 0) } if consumeEvent { switch e := event.(type) { case *sdl.WindowEvent: switch e.Event { case sdl.WINDOWEVENT_CLOSE: running = false case sdl.WINDOWEVENT_RESIZED: width, height := int(e.Data1), int(e.Data2) worldRenderer.Resize(width, height) tw.WindowSize(width, height) } case *sdl.MouseButtonEvent: button := e.Button if e.State == sdl.PRESSED && drag == 255 { drag = e.Button } if e.State == sdl.RELEASED && drag == button { drag = 255 } if e.State == sdl.PRESSED && button == sdl.BUTTON_RIGHT { GrabCursor() } // ray cast testing if e.State == sdl.PRESSED && button == sdl.BUTTON_LEFT { dir_cs := GetMouseDirection(window, int(e.X), int(e.Y)) out, hit := RayCastInCameraSpace(gs, dir_cs) if hit { n := helpers.Vector(gs.World.HeightMap.Normal2f(out[0], out[1])) debug.Color(mgl.Vec4{0, 1, 0, 1}) debug.Line(out, out.Add(n)) } } case *sdl.KeyDownEvent: switch e.Keysym.Scancode { case sdl.SCANCODE_RETURN: GrabCursor() case sdl.SCANCODE_SPACE: case sdl.SCANCODE_ESCAPE: running = false } case *sdl.KeyUpEvent: } } } if sdl.GetRelativeMouseMode() { x, y, _ := sdl.GetRelativeMouseState() inp.Rotate[0] = -float32(y) / 500 inp.Rotate[1] = -float32(x) / 500 } keyState := sdl.GetKeyboardState() if keyState[sdl.SCANCODE_E] == 1 { inp.Move[2] -= 1 } if keyState[sdl.SCANCODE_D] == 1 { inp.Move[2] += 1 } if keyState[sdl.SCANCODE_S] == 1 { inp.Move[0] -= 1 } if keyState[sdl.SCANCODE_F] == 1 { inp.Move[0] += 1 } if keyState[sdl.SCANCODE_R] == 1 { inp.Rotate[2] -= 0.01 } if keyState[sdl.SCANCODE_W] == 1 { inp.Rotate[2] += 0.01 } x, y, button_state := sdl.GetMouseState() if button_state&sdl.BUTTON_LEFT != 0 { dir_cs := GetMouseDirection(window, x, y) out, hit := RayCastInCameraSpace(gs, dir_cs) if hit { heightMap := gs.World.HeightMap heightMap.Bump(mgl.Vec2{out[0], out[1]}, 3) } } gs.World.Player.Input = inp return running }