简体   繁体   中英

Using EventMotion to move my paddle in a game of pong makes it unable to register collisions

I am making a game of pong in haskell using gloss as my main library. The movement of the paddle controlled by player is tied to the x-coordinate of the mouse and is updated as it moves. The problem is, the ball doesn't register collision with the paddle while it is moving.

movePaddle :: Event -> Game -> Game
movePaddle (EventMotion (x,y)) g = g {nextPos = max 50 . min 750 $ (x+400)}
movePaddle _ g = g

movePaddle updates the next position of the player's paddle.

moveBall :: Game -> Float -> Game
moveBall g f = g {dir = dirn, ball = (xt, yt)}

Then, moveBall updates the direction in which the ball is moving, according to collision, and adjusts its coordinates.

updatePaddle :: Game -> Game
updatePaddle g = g {p1 = nextPos g}

Finally, updatePaddle updates the actual position of the paddle in the game.

My main function looks like this:

main = play
  (InWindow "pong" (800, 800) (300, 300))
  white
  60
  (Game 400 400 (400, 400) 0.72 5 400)
  gameDraw
  movePaddle
  updatePaddle . (flip moveBall)

I have tried updating the state only as the mouse moves, but then the ball won't move. If I let it move independently while also updating it during the event, it doubles its speed during the mouse movement. What can I do to create proper collision while still being able to move the paddle?

Edit: here's my moveBall code:

moveBall :: Float -> Game -> Game
moveBall f g = g {dir = dirn, ball = (xt, yt)}
 where
  xn = fst (ball g) + f * vel g * cos (dir g)
  yn = snd (ball g) + f * vel g * sin (dir g)
  dirx
    |(max 10 $ min 790 xn) == xn = 1
    |otherwise = -1
  diry
    |(max 10 $ min 790 yn) == yn = 1
    |otherwise = -1
  dirn
    |dirx == -1 = pi - diry * dir g
    |(diry == -1) && (dirx == 1) = diry * dir g
    |max (p1 g - 50) (min (p1 g + 50) xn) == xn && (yn <= 30) = paddleAngle (p1 g) xn
    |max (p2 g - 50) (min (p2 g + 50) xn) == xn && (yn >= 770) = - paddleAngle (p2 g) xn
    |otherwise = (dir g)
  xt = (f * vel g * cos dirn) + normalize (fst (ball g))
  yt = (f * vel g * sin dirn) + normalize (snd (ball g))

Solved. Turns out I was looking at the wrong paddle when registering collision and mixed up my coordinates, due to which collision for paddle 1 was being registered at the top of the screen, where paddle 2 is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM