0

I am trying to build a simple game in gloss that uses BMP files for sprites that will be animated and moved around after being loaded. I am trying to get a few of these images of them to move using the animate or simulate functions.

One of the parameters of simulate is of type (model -> Picture) (i.e. a function that takes a user defined data type storing the state of the game and returning a Picture), while the loadBMP function typically used to load files is loadBMP :: FilePath -> IO Picture.

Having some trouble grasping what exactly I should be doing at a higher level to get the images to move, particularly given that loadBMP would return Picture IO not Picture. Any ideas? Sorry if this wasn't specific enough.

module Main(main) where

import Graphics.Gloss
import System.IO  
import Control.Monad
import Graphics.Gloss.Data.ViewPort

data GameState = State{ 
      boardpic::Picture
    , ballpic :: Picture
    , ballCoords :: (Float, Float)  
    , ballSpeed :: (Float, Float) 
    , paddle1pic::Picture  
    , p1Coords :: (Float, Float)
    , paddle2pic::Picture
    , p2Coords:: (Float,Float)
    , paused::Bool
    , turnscore::Integer                                  
    } deriving (Show) 

moveBall time state = state {ballCoords = (xnew, ynew)} 
    where
    (xposbefore, yposbefore) = ballCoords state 
    (xspeed, yspeed) = ballSpeed state
    (xnew, ynew) = (xposbefore + xspeed*time, yposbefore+xspeed*time)

render::GameState->Picture
render state =  
  pictures[board, 
           paddle1, 
           paddle2,
           ball]
  where
    board = boardpic state
    ball = translate 0 0 $ ballpic state
    paddle1 = translate (-300) 0 $ paddle1pic state
    paddle2 = translate 300 0 $ paddle2pic state  

--calculates running sum of score for the player from list 
score xs = tail.reverse $ foldl f [0] xs 
  where 
    f (y:ys) x = (x+y):y:ys
 
window :: Display
window = InWindow "SuperPong" (800, 800) (0,0)

background::Color
background = blue

fps :: Int
fps = 60
    
printState::GameState->IO ()
printState state = do
  putStrLn $ show $ boardpic state
  putStrLn $ show $ ballpic state
  putStrLn $ ("ball coordinates: ")++(show $ ballCoords state)
  putStrLn $ ("paddle1 coords:  " )++(show $ p1Coords state)
  putStrLn $ ("paddle2 coords: " )++(show $ p2Coords state)
  putStrLn $ ("paused or not: " ) ++ (show $ paused state)
  putStrLn $ ("score: " )++(show $ turnscore state)

--paddlecollision::

--outofbounds::

main :: IO ()
main = do
  pad1 <- loadBMP "paddle1.bmp"
  pad2 <- loadBMP "paddle2.bmp"
  board <- loadBMP "board.bmp"
  ball1 <- loadBMP "ball.bmp"

  let initstate = State{
    boardpic = board
  , ballpic = ball1
  , ballCoords = (-10, 10)
  , ballSpeed = (50, -50)
  , paddle1pic = pad1
  , p1Coords = (-300, 0)
  , paddle2pic = pad2
  , p2Coords = (300, 0)
  , paused = False
  , turnscore = 0
  }
    
  let update _ = moveBall 
  
  printState initstate
  let allpics = render initstate     

  simulate window background fps initstate render update

updated

floxam
  • 25
  • 5
  • 2
    Load the bitmap at the beginning of `main` and store the resulting `Picture` in your `model`. – Daniel Wagner Feb 23 '23 at 04:16
  • It looks like you're trying to update your state as you go. `animate` doesn't do that. If you want to use `animate`, you must always compute the current picture given *only* a timestamp (though of course you can close over your model to include whatever other static data you want). If you'd like to iteratively update your state, you should use `simulate` instead. – Daniel Wagner Feb 25 '23 at 16:35
  • thanks, updated the code. any reason you can see why the ball isnt moving? – floxam Feb 26 '23 at 20:53
  • Where are you using `ballCoords`? – Daniel Wagner Feb 27 '23 at 00:14

0 Answers0