Random tree structure generation of rooms
This commit is contained in:
+72
-51
@@ -1,4 +1,12 @@
|
||||
module Dodge.Update.Camera where
|
||||
{-
|
||||
Functions controlling the movement of the screen camera:
|
||||
'_cameraCenter', '_cameraZoom', _cameraRot';
|
||||
and the position that the character sees from: '_cameraViewFrom'.
|
||||
-}
|
||||
module Dodge.Update.Camera
|
||||
( updateCamera
|
||||
)
|
||||
where
|
||||
|
||||
import Dodge.Data
|
||||
import Dodge.Base
|
||||
@@ -18,22 +26,23 @@ updateCamera = rotCam . moveCamera . updateScopeZoom
|
||||
moveCamera :: World -> World
|
||||
moveCamera w = w & cameraCenter .~ idealPos
|
||||
& cameraViewFrom .~ sightFrom
|
||||
where aimRangeFactor | _cameraZoom w == 0 = 0
|
||||
| otherwise = (fromMaybe 0 $ yourItem w ^? itAimingRange) / _cameraZoom w
|
||||
aimingMult | SDL.ButtonRight `S.member` _mouseButtons w = 1
|
||||
| otherwise = 0
|
||||
ypos = _crPos $ you w
|
||||
idealOffset = rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
currentOffset = currentPos -.- camCenter
|
||||
idealPos = camCenter +.+ rotateV (_cameraRot w)
|
||||
(aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
currentPos = _cameraCenter w
|
||||
camCenter = ypos +.+ scope
|
||||
isCam :: Bool
|
||||
isCam = fromMaybe False $ yourItem w ^? itAttachment . _Just . scopeIsCamera
|
||||
scope = fromMaybe (0,0) $ yourItem w ^? itAttachment . _Just . scopePos
|
||||
sightFrom | isCam = camCenter
|
||||
| otherwise = ypos
|
||||
where
|
||||
aimRangeFactor | _cameraZoom w == 0 = 0
|
||||
| otherwise = (fromMaybe 0 $ yourItem w ^? itAimingRange) / _cameraZoom w
|
||||
aimingMult | SDL.ButtonRight `S.member` _mouseButtons w = 1
|
||||
| otherwise = 0
|
||||
ypos = _crPos $ you w
|
||||
idealOffset = rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
currentOffset = currentPos -.- camCenter
|
||||
idealPos = camCenter +.+ rotateV (_cameraRot w)
|
||||
(aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
currentPos = _cameraCenter w
|
||||
camCenter = ypos +.+ scope
|
||||
isCam :: Bool
|
||||
isCam = fromMaybe False $ yourItem w ^? itAttachment . _Just . scopeIsCamera
|
||||
scope = fromMaybe (0,0) $ yourItem w ^? itAttachment . _Just . scopePos
|
||||
sightFrom | isCam = camCenter
|
||||
| otherwise = ypos
|
||||
|
||||
updateScopeZoom :: World -> World
|
||||
updateScopeZoom w
|
||||
@@ -109,42 +118,54 @@ zoomCamOut w | zoomOutKey (_keyConfig w) `S.member` _keys w
|
||||
= w {_cameraZoom = max (_cameraZoom w - 0.01) 0.01}
|
||||
| otherwise = w
|
||||
|
||||
{-
|
||||
Automatically sets the zoom of the camera according to the surrounding walls.
|
||||
-}
|
||||
autoZoomCam :: World -> World
|
||||
autoZoomCam w = over cameraZoom changeZoom w
|
||||
where maxViewDistance = 800
|
||||
camPos = _cameraViewFrom w
|
||||
camRot = _cameraRot w
|
||||
wallZoom = min (halfWidth w / (horizontalMax+50) )
|
||||
(halfHeight w / (verticalMax+50) )
|
||||
idealZoom | SDL.ButtonRight `S.member` _mouseButtons w
|
||||
= scZoom *
|
||||
(
|
||||
min (fromMaybe 20 $ yourItem w ^? itZoom . itAimZoomMax)
|
||||
$ max (fromMaybe 0.2 $ yourItem w ^? itZoom . itAimZoomMin)
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itAimZoomFac))
|
||||
)
|
||||
| otherwise
|
||||
= min (fromMaybe 20 $ yourItem w ^? itZoom . itZoomMax)
|
||||
$ max (fromMaybe 0.2 (yourItem w ^? itZoom . itZoomMin))
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itZoomFac))
|
||||
changeZoom curZoom
|
||||
| curZoom > idealZoom + 0.01 = ((zoomOutSpeed-1)*curZoom + idealZoom) / zoomOutSpeed
|
||||
| curZoom < idealZoom - 0.01 = ((zoomInSpeed-1)*curZoom + idealZoom) / zoomInSpeed
|
||||
| otherwise = idealZoom
|
||||
-- these speeds are inverted, larger means slower
|
||||
zoomInSpeed = 25
|
||||
zoomOutSpeed = 15
|
||||
zs = take 9 [-maxViewDistance,0 - 0.8*maxViewDistance..]
|
||||
rRays = rotF [( maxViewDistance,y) | y <- zs]
|
||||
lRays = rotF [(-maxViewDistance,y) | y <- zs]
|
||||
tRays = rotF [(y, maxViewDistance) | y <- zs]
|
||||
bRays = rotF [(y,-maxViewDistance) | y <- zs]
|
||||
rotF = map (h . (+.+) camPos . rotateV (_cameraRot w))
|
||||
h p = fromMaybe p $ collidePointIndirect camPos p $ wallsAlongLine camPos p w
|
||||
h' x p = dotV (rotateV camRot x) (p -.- camPos)
|
||||
horizontalMax = maximum $ map (h' (1,0)) rRays ++ map (h' (-1,0)) lRays
|
||||
verticalMax = maximum $ map (h' (0,1)) tRays ++ map (h' (0,-1)) bRays
|
||||
scZoom = fromMaybe 1 $ yourItem w ^? itAttachment . _Just . scopeZoom
|
||||
where
|
||||
maxViewDistance = 800
|
||||
camPos = _cameraViewFrom w
|
||||
camRot = _cameraRot w
|
||||
wallZoom = farWallDist camPos w
|
||||
idealZoom | SDL.ButtonRight `S.member` _mouseButtons w
|
||||
= scZoom *
|
||||
(
|
||||
min (fromMaybe 20 $ yourItem w ^? itZoom . itAimZoomMax)
|
||||
$ max (fromMaybe 0.2 $ yourItem w ^? itZoom . itAimZoomMin)
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itAimZoomFac))
|
||||
)
|
||||
| otherwise
|
||||
= min (fromMaybe 20 $ yourItem w ^? itZoom . itZoomMax)
|
||||
$ max (fromMaybe 0.2 (yourItem w ^? itZoom . itZoomMin))
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itZoomFac))
|
||||
changeZoom curZoom
|
||||
| curZoom > idealZoom + 0.01 = ((zoomOutSpeed-1)*curZoom + idealZoom) / zoomOutSpeed
|
||||
| curZoom < idealZoom - 0.01 = ((zoomInSpeed-1)*curZoom + idealZoom) / zoomInSpeed
|
||||
| otherwise = idealZoom
|
||||
-- these speeds are inverted, larger means slower
|
||||
zoomInSpeed = 25
|
||||
zoomOutSpeed = 15
|
||||
scZoom = fromMaybe 1 $ yourItem w ^? itAttachment . _Just . scopeZoom
|
||||
|
||||
farWallDist :: Point2 -> World -> Float
|
||||
farWallDist cpos w = min (halfWidth w / (horizontalMax+50) ) (halfHeight w / (verticalMax+50) )
|
||||
where
|
||||
horizontalMax = maximum $ map (h' (1,0)) rRays ++ map (h' (-1,0)) lRays
|
||||
verticalMax = maximum $ map (h' (0,1)) tRays ++ map (h' (0,-1)) bRays
|
||||
-- TODO: fix wallsAlongLine and use instead of checking against all walls
|
||||
-- h p = fromMaybe p $ collidePointIndirect cpos p $ wallsAlongLine cpos p w
|
||||
h p = fromMaybe p . collidePointIndirect cpos p $ _walls w
|
||||
h' x p = dotV (rotateV camRot x) (p -.- cpos)
|
||||
camRot = _cameraRot w
|
||||
rRays = rotF [( maxViewDistance,y) | y <- zs]
|
||||
lRays = rotF [(-maxViewDistance,y) | y <- zs]
|
||||
tRays = rotF [(y, maxViewDistance) | y <- zs]
|
||||
bRays = rotF [(y,-maxViewDistance) | y <- zs]
|
||||
rotF = map (h . (+.+) cpos . rotateV (_cameraRot w))
|
||||
zs = take 9 [-maxViewDistance,0 - 0.8*maxViewDistance..]
|
||||
maxViewDistance = 800
|
||||
|
||||
|
||||
dirRays :: Float -> [Point2]
|
||||
dirRays dir = take 11 $ iterate (rotateV (0.5 * pi / 10)) $ rotateV (dir-pi*0.25) (600,0)
|
||||
|
||||
Reference in New Issue
Block a user