From: Mauro Aranda Date: Wed, 7 Aug 2019 00:48:41 +0000 (-0300) Subject: Fix pong collision detection X-Git-Tag: emacs-27.0.90~1656 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7ff96f95d7d67fc1489fca9fd3ab4a99328a5b8a;p=emacs.git Fix pong collision detection * lisp/play/pong.el (pong-update-game): If the ball hit the bat where bats are positioned, draw again the bat cell in the old ball position. (Bug#20579). Also, avoid changing the direction of the ball right after hitting the bats, and improve the collision detection against the borders. --- diff --git a/lisp/play/pong.el b/lisp/play/pong.el index 555c1939d26..759dbb404c6 100644 --- a/lisp/play/pong.el +++ b/lisp/play/pong.el @@ -349,46 +349,61 @@ detection and checks if a player scores." (let ((old-x pong-x) (old-y pong-y)) - + ;; Erase the last ball position. + (when (and (> old-y 0) + (< old-y (- pong-height 1))) + ;; If the ball hit the bat in the column where bats are positioned, + ;; and therefore changed its x direction, draw again the bat cell. + (if (or (and (= old-x 2) (< 0 pong-xx)) + (and (= old-x (- pong-width 3)) (> 0 pong-xx))) + (gamegrid-set-cell old-x old-y pong-bat) + (gamegrid-set-cell old-x old-y pong-blank))) + + ;; Update the ball position. (setq pong-x (+ pong-x pong-xx)) - (setq pong-y (+ pong-y pong-yy)) - - (if (and (> old-y 0) - (< old-y (- pong-height 1))) - (gamegrid-set-cell old-x old-y pong-blank)) - + ;; If the ball would go out of bounds, put it against the border. + (cond + ((<= (+ pong-y pong-yy) 0) + (setq pong-yy (- pong-yy)) + (setq pong-y 1)) + ((>= (+ pong-y pong-yy) (- pong-height 1)) + (setq pong-yy (- pong-yy)) + (setq pong-y (- pong-height 2))) + (t + (setq pong-y (+ pong-y pong-yy)) + ;; Check if the ball is against the border now, + ;; and change the y direction if it is. + (when (or (<= pong-y 1) (>= pong-y (- pong-height 2))) + (setq pong-yy (- pong-yy))))) + + ;; Draw the ball in its new position. (if (and (> pong-y 0) (< pong-y (- pong-height 1))) (gamegrid-set-cell pong-x pong-y pong-ball)) + ;; Hit bat, score a goal, or nothing. (cond - ((or (= pong-x 3) (= pong-x 2)) - (if (and (>= pong-y pong-bat-player1) - (< pong-y (+ pong-bat-player1 pong-bat-width))) - (and - (setq pong-yy (+ pong-yy - (cond - ((= pong-y pong-bat-player1) -1) - ((= pong-y (1+ pong-bat-player1)) 0) - (t 1)))) - (setq pong-xx (- pong-xx))))) - - ((or (= pong-x (- pong-width 4)) (= pong-x (- pong-width 3))) - (if (and (>= pong-y pong-bat-player2) - (< pong-y (+ pong-bat-player2 pong-bat-width))) - (and - (setq pong-yy (+ pong-yy - (cond - ((= pong-y pong-bat-player2) -1) - ((= pong-y (1+ pong-bat-player2)) 0) - (t 1)))) - (setq pong-xx (- pong-xx))))) - - ((<= pong-y 1) - (setq pong-yy (- pong-yy))) - - ((>= pong-y (- pong-height 2)) - (setq pong-yy (- pong-yy))) + ((and (or (= pong-x 3) (= pong-x 2)) + (> 0 pong-xx) ; Collide with the bat if headed towards it. + (>= pong-y pong-bat-player1) + (< pong-y (+ pong-bat-player1 pong-bat-width))) + (setq pong-yy (+ pong-yy + (cond + ((= pong-y pong-bat-player1) -1) + ((= pong-y (1+ pong-bat-player1)) 0) + (t 1)))) + (setq pong-xx (- pong-xx))) + + ((and (or (= pong-x (- pong-width 4)) (= pong-x (- pong-width 3))) + (< 0 pong-xx) ; Collide with the bat if headed towards it. + (>= pong-y pong-bat-player2) + (< pong-y (+ pong-bat-player2 pong-bat-width))) + (setq pong-yy (+ pong-yy + (cond + ((= pong-y pong-bat-player2) -1) + ((= pong-y (1+ pong-bat-player2)) 0) + (t 1)))) + (setq pong-xx (- pong-xx))) ((< pong-x 1) (setq pong-score-player2 (1+ pong-score-player2))