moveVehicle :: Rectangle -> Direction -> VehicleS ()
moveVehicle bounds dir = use vSpeed
  >>= \s -> use vPosition >>= \p -> vPosition %= const (newPos p s)
 where
  newPos (L.V2 x y) s =
    let (ofx, ofy) = help s
        inside     = insideRectangle bounds (L.V2 (x + ofx) (y + ofy))
    in  if inside then L.V2 (x + ofx) (y + ofy) else L.V2 x y
  help s' = case dir of
    DUp    -> (0.0, s')
    DLeft  -> (-s', 0.0)
    DDown  -> (0.0, -s')
    DRight -> (s', 0.0)
moveVehicle :: Rectangle -> Direction -> VehicleS ()
moveVehicle bounds dir = use vSpeed
  >>= \s -> use vPosition >>= \p -> vPosition %= const (newPos p s)
 where
  newPos (L.V2 x y) s =
    let (ofx, ofy) = help s
        inside     = insideRectangle bounds (L.V2 (x + ofx) (y + ofy))
    in  if inside then L.V2 (x + ofx) (y + ofy) else L.V2 x y
  help s' = case dir of
    DUp    -> (0.0, s')
    DLeft  -> (-s', 0.0)
    DDown  -> (0.0, -s')
    DRight -> (s', 0.0)
moveVehicle bounds dir = use vSpeed
  >>= \s -> use vPosition >>= \p -> vPosition %= const (newPos p s)
 where
  newPos (L.V2 x y) s =
    let (ofx, ofy) = help s
        inside     = insideRectangle bounds (L.V2 (x + ofx) (y + ofy))
    in  if inside then L.V2 (x + ofx) (y + ofy) else L.V2 x y
  help s' = case dir of
    DUp    -> (0.0, s')
    DLeft  -> (-s', 0.0)
    DDown  -> (0.0, -s')
    DRight -> (s', 0.0)