topkata 0.2.1 → 0.2.2
raw patch · 6 files changed
+91/−14 lines, 6 files
Files
- Labygen.hs +15/−0
- Main.hs +17/−10
- PdfLaby.hs +28/−0
- Topkata/Topka/Base.hs +12/−0
- Topkata/Topka/Ghost.hs +18/−3
- topkata.cabal +1/−1
Labygen.hs view
@@ -4,6 +4,7 @@ import Data.List import Data.Array import System.Random+import qualified Dijkstra data Block = Block | Free deriving (Show, Eq, Ord) @@ -89,3 +90,17 @@ randomFreePosIO laby = do g <- newStdGen return $ fst $ randomFreePos laby g++isFree laby p = laby ! p == Free++dijkstra laby p = Dijkstra.dijkstra laby p bnds neighbors+ where bnds = bounds laby+ neighbors w p = filter (isFree w) $ adjacent (bounds w) p++distance laby p1 p2 =+ dij ! p2+ where+ dij = dijkstra laby p1++ways laby p =+ filter (isFree laby) $ adjacent (bounds laby) p
Main.hs view
@@ -1,7 +1,5 @@ module Main where -- import System.Exit ( exitWith, ExitCode(ExitSuccess) ) import Graphics.UI.GLUT #ifdef USE_FTGL@@ -13,6 +11,7 @@ import Topkata.Topka.Ghost import Topkata.Topka.Topka import Data.Maybe (listToMaybe, maybeToList)+import Data.Array import Labygen import Labygen.Render import ReadImage (readImageWithSize)@@ -50,6 +49,7 @@ camera :: IORef Camera, vmode :: IORef ViewMode, laby :: World Pos3,+ dij :: Array Pos3 Int, worldDL :: DisplayList, textures :: Textures, score :: IORef Int@@ -81,7 +81,9 @@ setFontFaceSize font 24 72 #endif score <- newIORef 0- return $ State { topka = ts, laby = laby, vmode = vm,+ return $ State { topka = ts, + laby = laby, dij = dijkstra laby target,+ vmode = vm, camera = camera, worldDL = worldDL, ghosts = ghosts, score = score,@@ -90,10 +92,11 @@ , font1 = font #endif }- where origin = Pos3 (0, 0, 0)- target = Pos3 (30, 0, 30)- middle x = fromIntegral x - 0.5+ where middle x = fromIntegral x + 0.5 +origin = Pos3 (0, 0, 0)+target = Pos3 (30, 0, 30)+ tex e = e . textures incrScore state amount =@@ -459,17 +462,21 @@ return () isWinPosition ts = ix == 30 && iz == 30+ where (ix, _, iz) = topPos ts++topPos ts = (ifloor x, ifloor y, ifloor z) where Vector3 x y z = transVec ts ifloor x = fromIntegral (floor x)- ix = ifloor x- iz = ifloor z +topPos3 = Pos3 . topPos animate snds state = do ts <- readIORef (topka state) when (not (topInWall lab ts)) $ do- let ts' = animateTop mstime ts+ let ts' = animateTop mstime ts+ dist = (dij state) ! topPos3 ts+ putStrLn $ show dist if (topInWall lab ts') then do topkaUpd state updateOrientation flipOrientation when (isWinPosition ts) $ do @@ -482,7 +489,7 @@ hitGroundSnd snds ts ts' rand <- randomIO :: IO Int ghosts state $~ \ gs ->- map (animateGhost rand lab) gs+ map (\ ghost -> animateGhost rand lab ghost (topPos3 ts)) gs addTimerCallback mstime $ animate snds state postRedisplay Nothing where mstime = 10
+ PdfLaby.hs view
@@ -0,0 +1,28 @@+module Main (main) where++import Labygen+import Graphics.Rendering.Cairo+import System.Random+import Data.Array +++drawBlock p Free = return ()+drawBlock (Pos2 (x,y)) Block = do+ rectangle (fromIntegral (x-1) * 20.0) (fromIntegral (y-1) * 40.0) 20 40+ fill ++draw laby = do+ setSourceRGBA 0.0 0.0 0.0 1.0+ translate 20 40 + rectangle 0 0 (fromIntegral xb * 20.0) (fromIntegral yb * 40.0)+ stroke+ sequence_ [ drawBlock p b | (p, b) <- assocs laby ]+ where (_, Pos2 (xb, yb)) = bounds laby++main = do+ putStrLn "LabyGen"+ laby <- labygenIO (Pos2 (1,1), (Pos2 (30,50))) (Pos2 (1,1)) (Pos2 (30, 50))+ withPDFSurface "laby.pdf" 740 2100 $ \ sf ->+ renderWith sf $ draw laby++
Topkata/Topka/Base.hs view
@@ -1,6 +1,7 @@ module Topkata.Topka.Base where import Graphics.UI.GLUT+import Labygen data Textures = Textures { texTopkata, texGhost :: Maybe TextureObject@@ -75,3 +76,14 @@ East -> West West -> East ++ifloor x = fromIntegral $ floor x++dirToNeighbor :: Pos3 -> Pos3 -> Direction+dirToNeighbor (Pos3 (x1, _, z1)) (Pos3 (x2, _, z2)) =+ case (x2-x1, z2-z1) of+ (1, 0) -> West+ (0, -1) -> South+ (-1, 0) -> East+ (0, 1) -> North+ _ -> error "angleTo"
Topkata/Topka/Ghost.hs view
@@ -4,6 +4,8 @@ import Topkata.Topka.Base import Vector import Labygen+import Data.Array ( (!) )+import Data.List -- import Debug.Trace (trace) data GhostState = GhostState {@@ -51,7 +53,9 @@ depthMask $= Enabled blend $= Disabled -animateGhost rand laby ghost = +++animateGhost rand laby ghost target = let speed = ghostSpeed ghost dir = ghostOrientation ghost angle = angleOfDirection dir@@ -59,6 +63,17 @@ dz = speed * cos angle pos@(Vector3 x y z) = ghostPosition ghost (nx, nz) = (x+dx, z+dz)+ isMiddle1 c = c' >= 0.45 && c' <= 0.55 where c'= c - ifloor c + isMiddle2 = isMiddle1 nx && isMiddle1 nz+ lpos = Pos3 (floor x, 0, floor z)+ flur = ways laby lpos+ dij = dijkstra laby target+ shorter p1 p2 = compare (dij ! p1) (dij !p2) + dbg l = l --trace (show (zip l (map (\x -> dij !x) l))) l+ best = head $ sortBy shorter flur+ bestDir = if isMiddle2 + then dirToNeighbor lpos best+ else dir (wx, wz) = (nx+0.3*sin angle, nz +0.3 * cos angle) rot = if odd rand then rotCW else rotCCW rangle = angleOfDirection (rot dir)@@ -67,9 +82,9 @@ not $ inWall laby (tx+1) (y+1) (tz+1) (newOrient, newPos) = if inWall laby wx y wz || randomTurn then (rot dir, pos)- else (dir, Vector3 nx y nz)+ else (bestDir, Vector3 nx y nz) newSpeed = if newOrient == dir - then min 0.039 (speed + 0.001)+ then min 0.020 (speed + 0.001) else 0.005 ghostPhase' = (ghostPhase ghost + 1) `mod` 51 ghost' = ghost { ghostOrientation = newOrient,
topkata.cabal view
@@ -1,5 +1,5 @@ Name: topkata-Version: 0.2.1+Version: 0.2.2 Synopsis: OpenGL Arcade Game Description: Guide a jumping ball through a maze. License: GPL