Gabriel Pariat
2 years ago
16 changed files with 675 additions and 251 deletions
@ -1,44 +1,65 @@ |
|||||||
(in-package :pong.client) |
(in-package :pong.client) |
||||||
|
|
||||||
(defparameter *scene* nil) |
(defparameter *client* nil) |
||||||
|
|
||||||
(defun open-main-menu% () |
(defclass client () |
||||||
(setf *scene* (open-main-menu #'start-1-player-game |
((ip :initarg :ip :initform nil :reader client-ip) |
||||||
#'start-2-players-game |
(port :initarg :port :initform nil :reader client-port) |
||||||
#'create-online-game |
(running-p :initform nil :accessor client-running-p) |
||||||
#'join-online-game))) |
(socket :initform nil :accessor client-socket))) |
||||||
|
|
||||||
(defun start-1-player-game () |
(defmethod listen-to ((self client)) |
||||||
(setf *scene* (open-game (make-instance 'local-game-1p) #'open-main-menu%))) |
(with-slots (running-p socket) self |
||||||
|
(when (and running-p (usocket:wait-for-input socket :timeout 5) running-p) |
||||||
(defun start-2-players-game () |
(let ((data (cpk:decode-stream (usocket:socket-stream socket)))) |
||||||
(setf *scene* (open-game (make-instance 'local-game-2p) #'open-main-menu%))) |
(format t "[CLIENT] Data received: ~a~%" data))))) |
||||||
|
|
||||||
(defun create-online-game () |
(defmethod start ((self client)) |
||||||
(format t "~%Create online game.")) |
(with-slots (ip port running-p socket) self |
||||||
(defun join-online-game () |
(format t "uh?~%") |
||||||
(format t "~%Join online game.")) |
(unless running-p |
||||||
|
(setf running-p t) |
||||||
(defun main () |
(setf socket (usocket:socket-connect ip port :element-type 'unsigned-byte))))) |
||||||
(let* ((last-time nil) |
|
||||||
(current-time (get-internal-real-time))) |
(defmethod stop ((self client)) |
||||||
(r:with-window (800 600 "Pariatech's Pong") |
(with-slots (running-p socket) self |
||||||
(gui:with-gui |
(setf running-p nil) |
||||||
(open-main-menu%) |
(when socket |
||||||
|
(usocket:socket-close socket)) |
||||||
(r:set-config-flags r:+flag-window-resizable+) |
(setf socket nil))) |
||||||
(r:set-target-fps 60) |
|
||||||
(r:set-exit-key 0) |
(defmethod write-to ((self client) data) |
||||||
(loop |
(let ((stream (usocket:socket-stream (client-socket self)))) |
||||||
until (or (r:window-should-close) (scene-should-close *scene*)) |
(format t "[CLIENT] Data sent: ~a~%" data) |
||||||
do (setf last-time current-time) |
(cpk:encode data :stream stream) |
||||||
(setf current-time (/ (get-internal-real-time) internal-time-units-per-second)) |
(force-output stream))) |
||||||
|
|
||||||
(let ((timelapse (- current-time last-time))) |
(defun handle-client () |
||||||
(on-update *scene* timelapse)) |
(loop while (and *client* (client-running-p *client*)) |
||||||
(r:with-drawing |
do (let ((data (listen-to *client*)))))) |
||||||
(r:clear-background r:+gray+) |
|
||||||
(on-draw *scene*) |
(defun start-client (ip port) |
||||||
(r:draw-fps 20 20))))))) |
(unless *client* |
||||||
|
(setf *client* (make-instance 'client :ip ip :port port)) |
||||||
(main) |
(start *client*) |
||||||
|
(bt:make-thread #'handle-client))) |
||||||
|
|
||||||
|
(defun stop-client () |
||||||
|
(when *client* |
||||||
|
(stop *client*)) |
||||||
|
(setf *client* nil)) |
||||||
|
|
||||||
|
(defun send-data-to-server (data) |
||||||
|
(write-to *client* data)) |
||||||
|
|
||||||
|
(defun test-client () |
||||||
|
(start-client "127.0.0.1" 54321) |
||||||
|
(write-to *client* "hello!") |
||||||
|
(sleep 1.015) |
||||||
|
(write-to *client* "bye!") |
||||||
|
(stop-client)) |
||||||
|
|
||||||
|
;; (test-client) |
||||||
|
|
||||||
|
;; (stop-client) |
||||||
|
|
||||||
|
@ -0,0 +1,17 @@ |
|||||||
|
(in-package :pong.client) |
||||||
|
|
||||||
|
(defconstant +title-top-padding+ 30) |
||||||
|
(defconstant +menu-padding+ 10) |
||||||
|
(defconstant +menu-group-padding+ 20) |
||||||
|
(defconstant +menu-font+ "assets/ComicMono.ttf") |
||||||
|
(defconstant +menu-font-size+ 32) |
||||||
|
(defconstant +menu-title-font-size+ 52) |
||||||
|
(defconstant +menu-group-title-font-size+ 42) |
||||||
|
(defconstant +menu-text-color+ r:+white+) |
||||||
|
(defconstant +menu-local-1-player+ "1 Player") |
||||||
|
(defconstant +menu-local-2-players+ "2 Players") |
||||||
|
(defconstant +menu-online-create+ "Create Game") |
||||||
|
(defconstant +menu-online-join+ "Join Game") |
||||||
|
(defconstant +score-txt-size+ 32) |
||||||
|
(defconstant +score-padding+ 20) |
||||||
|
(defconstant +score-font+ "assets/ComicMono.ttf") |
@ -0,0 +1,59 @@ |
|||||||
|
(in-package :pong.client) |
||||||
|
|
||||||
|
(defclass create-online-game-scene (scene) |
||||||
|
((name :initform "" :accessor create-online-game-scene-name) |
||||||
|
(title :initarg :title :initform nil :reader create-online-game-scene-title) |
||||||
|
(name-field :initarg :name-field :initform nil :reader create-online-game-scene-name-field) |
||||||
|
(prompt :initarg :prompt :initform nil :reader create-online-game-scene-prompt))) |
||||||
|
|
||||||
|
(defun open-create-online-game-scene () |
||||||
|
(let ((root-element (gui:make-rectangle :color r:+darkgray+ |
||||||
|
:h-align :center |
||||||
|
:v-align :middle)) |
||||||
|
(title (gui:make-text :color r:+white+ |
||||||
|
:font +menu-font+ |
||||||
|
:font-size +menu-title-font-size+ |
||||||
|
:y +title-top-padding+ |
||||||
|
:h-align :center |
||||||
|
:text "Create online game")) |
||||||
|
(name-field (gui:make-text :color r:+white+ |
||||||
|
:font +menu-font+ |
||||||
|
:font-size +menu-font-size+ |
||||||
|
:v-align :middle)) |
||||||
|
(prompt (gui:make-text :color r:+white+ |
||||||
|
:font +menu-font+ |
||||||
|
:font-size +menu-font-size+ |
||||||
|
:h-align :right |
||||||
|
:v-align :middle |
||||||
|
:text "What is your name?:"))) |
||||||
|
(gui:add-children root-element title name-field prompt) |
||||||
|
|
||||||
|
(set-scene (make-instance 'create-online-game-scene :root-element root-element |
||||||
|
:name-field name-field |
||||||
|
:title title |
||||||
|
:prompt prompt)))) |
||||||
|
|
||||||
|
(defmethod on-update ((scene create-online-game-scene) timelapse) |
||||||
|
(with-slots (name move-back) scene |
||||||
|
;; Might be interesting to add repeating keys, but I don't care. |
||||||
|
(loop for key = (r:get-key-pressed) |
||||||
|
while (plusp key) |
||||||
|
do (format t "~a~%" key) |
||||||
|
when (= key r:+key-escape+) |
||||||
|
do (open-main-menu) |
||||||
|
when (= key r:+key-backspace+) |
||||||
|
do (setf name (str:substring 0 -1 name)) |
||||||
|
when (= key r:+key-enter+) |
||||||
|
do (start-online-game) |
||||||
|
when (and (>= key 32) (<= key 96)) |
||||||
|
do (setf name (str:concat name (string (code-char key))))))) |
||||||
|
|
||||||
|
(defmethod on-draw ((scene create-online-game-scene)) |
||||||
|
(with-slots (name root-element title name-field prompt) scene |
||||||
|
(position-root root-element) |
||||||
|
(setf (gui:x title) (floor (gui:w root-element) 2)) |
||||||
|
(setf (gui:text name-field) name) |
||||||
|
(setf (gui:x name-field) (+ (floor (gui:w root-element) 2) +score-padding+)) |
||||||
|
(setf (gui:x prompt) (- (floor (gui:w root-element) 2) +score-padding+)) |
||||||
|
(setf (gui:y name-field) (floor (gui:h root-element) 2)) |
||||||
|
(setf (gui:y prompt) (floor (gui:h root-element) 2)))) |
@ -0,0 +1,168 @@ |
|||||||
|
(in-package :pong.client) |
||||||
|
|
||||||
|
(defclass local-game-1p (g:game) |
||||||
|
((computer-paddle-target :initarg :computer-paddle-target |
||||||
|
:initform nil |
||||||
|
:accessor local-game-1p-computer-paddle-target))) |
||||||
|
|
||||||
|
(defclass local-game-2p (g:game) ()) |
||||||
|
|
||||||
|
(defun start-1-player-game () |
||||||
|
(setf *scene* (open-game (make-instance 'local-game-1p)))) |
||||||
|
|
||||||
|
(defun start-2-players-game () |
||||||
|
(setf *scene* (open-game (make-instance 'local-game-2p)))) |
||||||
|
|
||||||
|
(defun handle-player-paddle (paddle timelapse upward-keys downward-keys) |
||||||
|
(let ((paddle-y (g:paddle-y paddle)) |
||||||
|
(paddle-vy (g:paddle-vy paddle))) |
||||||
|
(setf (g:paddle-vy paddle) |
||||||
|
(cond ((member-if #'r:is-key-down downward-keys) g:+paddle-speed+) |
||||||
|
((member-if #'r:is-key-down upward-keys) (- g:+paddle-speed+)) |
||||||
|
(t 0.0))) |
||||||
|
(setf (g:paddle-y paddle) |
||||||
|
(min (max (+ paddle-y (* paddle-vy timelapse)) (/ g:+paddle-height+ 2)) |
||||||
|
(- 1.0 (/ g:+paddle-height+ 2)))))) |
||||||
|
|
||||||
|
(defun handle-left-player (state timelapse upward-keys downward-keys) |
||||||
|
(handle-player-paddle (g:state-left-paddle state) timelapse upward-keys downward-keys)) |
||||||
|
|
||||||
|
(defun handle-right-player (state timelapse upward-keys downward-keys) |
||||||
|
(handle-player-paddle (g:state-right-paddle state) timelapse upward-keys downward-keys)) |
||||||
|
|
||||||
|
(defun handle-right-computer (state timelapse target) |
||||||
|
(let* ((right-paddle (g:state-right-paddle state)) |
||||||
|
(paddle-y (g:paddle-y right-paddle)) |
||||||
|
(ball (g:state-ball state)) |
||||||
|
(ball-xy (g:ball-xy ball)) |
||||||
|
(ball-y (v:vy ball-xy)) |
||||||
|
(paddle-target (and target (+ paddle-y (- target (/ g:+paddle-height+ 2)))))) |
||||||
|
|
||||||
|
|
||||||
|
(setf (g:paddle-vy right-paddle) |
||||||
|
(if paddle-target |
||||||
|
(let ((delta (/ (- ball-y paddle-target) timelapse))) |
||||||
|
(if (minusp delta) |
||||||
|
(max delta (- g:+paddle-speed+)) |
||||||
|
(min delta g:+paddle-speed+))) |
||||||
|
0.0)) |
||||||
|
|
||||||
|
(setf (g:paddle-y right-paddle) |
||||||
|
(min (max (+ paddle-y (* (g:paddle-vy right-paddle) timelapse)) |
||||||
|
(/ g:+paddle-height+ 2)) |
||||||
|
(- 1.0 (/ g:+paddle-height+ 2)))))) |
||||||
|
|
||||||
|
(defun point-in-rect-p (px py rx ry rw rh) |
||||||
|
(and (> px rx) |
||||||
|
(< px (+ rx rw)) |
||||||
|
(> py ry) |
||||||
|
(< py (+ ry rh)))) |
||||||
|
|
||||||
|
(defun get-ball-paddle-collision (ball paddle paddle-x) |
||||||
|
(let* ((ball-xy (g:ball-xy ball)) |
||||||
|
(ball-x (v:vx ball-xy)) |
||||||
|
(ball-y (v:vy ball-xy)) |
||||||
|
(paddle-y (g:paddle-y paddle))) |
||||||
|
(when (or (point-in-rect-p (- ball-x g:+ball-radius+) |
||||||
|
(- ball-y g:+ball-radius+) |
||||||
|
paddle-x |
||||||
|
(- paddle-y (/ g:+paddle-height+ 2)) |
||||||
|
g:+paddle-width+ |
||||||
|
g:+paddle-height+) |
||||||
|
(point-in-rect-p (- ball-x g:+ball-radius+) |
||||||
|
(+ ball-y g:+ball-radius+) |
||||||
|
paddle-x |
||||||
|
(- paddle-y (/ g:+paddle-height+ 2)) |
||||||
|
g:+paddle-width+ |
||||||
|
g:+paddle-height+) |
||||||
|
(point-in-rect-p (+ ball-x g:+ball-radius+) |
||||||
|
(- ball-y g:+ball-radius+) |
||||||
|
paddle-x |
||||||
|
(- paddle-y (/ g:+paddle-height+ 2)) |
||||||
|
g:+paddle-width+ |
||||||
|
g:+paddle-height+) |
||||||
|
(point-in-rect-p (+ ball-x g:+ball-radius+) |
||||||
|
(+ ball-y g:+ball-radius+) |
||||||
|
paddle-x |
||||||
|
(- paddle-y (/ g:+paddle-height+ 2)) |
||||||
|
g:+paddle-width+ |
||||||
|
g:+paddle-height+)) |
||||||
|
(- ball-y paddle-y)))) |
||||||
|
|
||||||
|
(defun handle-ball (state timelapse) |
||||||
|
(let* ((ball (g:state-ball state)) |
||||||
|
(ball-xy (g:ball-xy ball)) |
||||||
|
(ball-x (v:vx ball-xy)) |
||||||
|
(ball-y (v:vy ball-xy)) |
||||||
|
(ball-vxy (g:ball-vxy ball)) |
||||||
|
(ball-vy (v:vy ball-vxy)) |
||||||
|
(left-paddle (g:state-left-paddle state)) |
||||||
|
(right-paddle (g:state-right-paddle state)) |
||||||
|
(ball-left-paddle-collision |
||||||
|
(get-ball-paddle-collision ball left-paddle 0.0)) |
||||||
|
(ball-right-paddle-collision |
||||||
|
(get-ball-paddle-collision ball right-paddle (- 1.0 g:+paddle-width+)))) |
||||||
|
(cond |
||||||
|
(ball-left-paddle-collision |
||||||
|
(g:launch-ball ball |
||||||
|
(incf (g:state-bounces state)) |
||||||
|
(* (/ ball-left-paddle-collision |
||||||
|
(+ (/ g:+paddle-height+ 2) g:+ball-radius+)) |
||||||
|
g:+max-launch-angle+) |
||||||
|
(+ g:+paddle-width+ g:+ball-radius+) |
||||||
|
ball-y)) |
||||||
|
(ball-right-paddle-collision |
||||||
|
(g:launch-ball ball |
||||||
|
(incf (g:state-bounces state)) |
||||||
|
(- pi |
||||||
|
(* (/ ball-right-paddle-collision |
||||||
|
(+ (/ g:+paddle-height+ 2) g:+ball-radius+)) |
||||||
|
(/ g:+max-launch-angle+ 2))) |
||||||
|
(- 1.0 g:+paddle-width+ g:+ball-radius+) |
||||||
|
ball-y)) |
||||||
|
((< (+ ball-x g:+ball-radius+) 0) |
||||||
|
(incf (g:state-right-score state)) |
||||||
|
(g:random-launch-ball state)) |
||||||
|
((> (- ball-x g:+ball-radius+) 1) |
||||||
|
(incf (g:state-left-score state)) |
||||||
|
(g:random-launch-ball state)) |
||||||
|
((< (- ball-y g:+ball-radius+) 0) |
||||||
|
(setf (v:vy ball-xy) g:+ball-radius+) |
||||||
|
(setf (v:vy ball-vxy) (* -1 ball-vy))) |
||||||
|
((> (+ ball-y g:+ball-radius+) 1) |
||||||
|
(setf (v:vy ball-xy) (- 1 g:+ball-radius+)) |
||||||
|
(setf (v:vy ball-vxy) (* -1 ball-vy))) |
||||||
|
(t |
||||||
|
(setf (g:ball-xy ball) (v:v+ ball-xy (v:v* ball-vxy timelapse))))))) |
||||||
|
|
||||||
|
(defun computer-paddle-target (game) |
||||||
|
(let* ((game-state (g:game-state game)) |
||||||
|
(ball (g:state-ball game-state)) |
||||||
|
(ball-vxy (g:ball-vxy ball))) |
||||||
|
(if (plusp (v:vx ball-vxy)) |
||||||
|
(or (local-game-1p-computer-paddle-target game) |
||||||
|
(setf (local-game-1p-computer-paddle-target game) |
||||||
|
(random g:+paddle-height+))) |
||||||
|
(setf (local-game-1p-computer-paddle-target game) nil)))) |
||||||
|
|
||||||
|
(defmethod g:on-init ((game local-game-1p)) |
||||||
|
(g:random-launch-ball (g:game-state game))) |
||||||
|
|
||||||
|
(defmethod g:on-update ((game local-game-1p) timelapse) |
||||||
|
(let ((game-state (g:game-state game))) |
||||||
|
(unless (g:state-paused game-state) |
||||||
|
(handle-left-player game-state timelapse |
||||||
|
(list r:+key-w+ r:+key-up+) |
||||||
|
(list r:+key-s+ r:+key-down+)) |
||||||
|
(handle-right-computer game-state timelapse (computer-paddle-target game)) |
||||||
|
(handle-ball game-state timelapse)))) |
||||||
|
|
||||||
|
(defmethod g:on-init ((game local-game-2p)) |
||||||
|
(g:random-launch-ball (g:game-state game))) |
||||||
|
|
||||||
|
(defmethod g:on-update ((game local-game-2p) timelapse) |
||||||
|
(let ((game-state (g:game-state game))) |
||||||
|
(unless (g:state-paused game-state) |
||||||
|
(handle-left-player game-state timelapse (list r:+key-w+) (list r:+key-s+)) |
||||||
|
(handle-right-player game-state timelapse (list r:+key-up+) (list r:+key-down+)) |
||||||
|
(handle-ball game-state timelapse)))) |
@ -0,0 +1,30 @@ |
|||||||
|
(in-package :pong.client) |
||||||
|
|
||||||
|
|
||||||
|
(defun create-online-game () |
||||||
|
(setf *scene* (open-create-online-game-scene))) |
||||||
|
|
||||||
|
(defun join-online-game () |
||||||
|
(format t "~%Join online game.")) |
||||||
|
|
||||||
|
(defun main () |
||||||
|
(let* ((last-time nil) |
||||||
|
(current-time (get-internal-real-time))) |
||||||
|
(r:with-window (800 600 "Pariatech's Pong") |
||||||
|
(gui:with-gui |
||||||
|
(open-main-menu) |
||||||
|
|
||||||
|
(r:set-config-flags r:+flag-window-resizable+) |
||||||
|
(r:set-target-fps 60) |
||||||
|
(r:set-exit-key 0) |
||||||
|
(loop |
||||||
|
until (or (r:window-should-close) (scene-should-close *scene*)) |
||||||
|
do (setf last-time current-time) |
||||||
|
(setf current-time (/ (get-internal-real-time) internal-time-units-per-second)) |
||||||
|
|
||||||
|
(let ((timelapse (- current-time last-time))) |
||||||
|
(on-update *scene* timelapse)) |
||||||
|
(r:with-drawing |
||||||
|
(r:clear-background r:+gray+) |
||||||
|
(on-draw *scene*) |
||||||
|
(r:draw-fps 20 20))))))) |
@ -0,0 +1,55 @@ |
|||||||
|
(in-package :pong.client) |
||||||
|
|
||||||
|
(defclass online-game (g:game) |
||||||
|
((actions :initarg :actions :initform nil :accessor online-game-actions) |
||||||
|
(keyboard :initform (make-hash-table) :reader online-game-keyboard) |
||||||
|
(paddle :initarg :paddle :initform :left :reader online-game-paddle))) |
||||||
|
|
||||||
|
(defun start-online-game (&optional (paddle :left)) |
||||||
|
(set-scene (open-game (make-instance 'online-game :paddle paddle)))) |
||||||
|
|
||||||
|
(defun open-create-online-game-scene () |
||||||
|
(start-online-game :left)) |
||||||
|
|
||||||
|
(defmethod g:on-init ((game online-game)) |
||||||
|
(g:random-launch-ball (g:game-state game))) |
||||||
|
|
||||||
|
(defun is-first-key-down-p (key keyboard) |
||||||
|
(and (r:is-key-down key) (not (gethash key keyboard)))) |
||||||
|
|
||||||
|
(defun is-first-key-released-p (key keyboard) |
||||||
|
(and (r:is-key-released key) (gethash key keyboard))) |
||||||
|
|
||||||
|
(defun set-key-down (key keyboard) |
||||||
|
(setf (gethash key keyboard) (r:is-key-down key))) |
||||||
|
|
||||||
|
(defmethod g:on-update ((game online-game) timelapse) |
||||||
|
(with-slots (actions keyboard paddle) game |
||||||
|
(when (or (is-first-key-down-p r:+key-s+ keyboard) |
||||||
|
(is-first-key-down-p r:+key-down+ keyboard)) |
||||||
|
(set-key-down r:+key-s+ keyboard) |
||||||
|
(set-key-down r:+key-down+ keyboard) |
||||||
|
(let ((action (make-instance 'g:start-down-action :paddle paddle))) |
||||||
|
(g:apply-action action game) |
||||||
|
(push action actions))) |
||||||
|
(when (or (is-first-key-released-p r:+key-s+ keyboard) |
||||||
|
(is-first-key-released-p r:+key-down+ keyboard)) |
||||||
|
(set-key-down r:+key-s+ keyboard) |
||||||
|
(set-key-down r:+key-down+ keyboard) |
||||||
|
(let ((action (make-instance 'g:stop-down-action :paddle paddle))) |
||||||
|
(g:apply-action action game) |
||||||
|
(push action action))) |
||||||
|
(when (or (is-first-key-down-p r:+key-w+ keyboard) |
||||||
|
(is-first-key-down-p r:+key-up+ keyboard)) |
||||||
|
(set-key-down r:+key-w+ keyboard) |
||||||
|
(set-key-down r:+key-up+ keyboard) |
||||||
|
(let ((action (make-instance 'g:start-up-action :paddle paddle))) |
||||||
|
(g:apply-action action game) |
||||||
|
(push action actions))) |
||||||
|
(when (or (is-first-key-released-p r:+key-w+ keyboard) |
||||||
|
(is-first-key-released-p r:+key-up+ keyboard)) |
||||||
|
(set-key-down r:+key-w+ keyboard) |
||||||
|
(set-key-down r:+key-up+ keyboard) |
||||||
|
(let ((action (make-instance 'g:stop-up-action :paddle paddle))) |
||||||
|
(g:apply-action action game) |
||||||
|
(push action actions))))) |
@ -0,0 +1,55 @@ |
|||||||
|
(in-package :pong.game) |
||||||
|
|
||||||
|
(defclass action () |
||||||
|
((timestamp :initarg :timestamp |
||||||
|
:initform (/ (get-internal-real-time) internal-time-units-per-second) |
||||||
|
:reader action-timestamp))) |
||||||
|
|
||||||
|
(defgeneric apply-action (action game)) |
||||||
|
|
||||||
|
(defclass start-game-action (action) |
||||||
|
((name :initarg :name :initform nil :accessor name))) |
||||||
|
|
||||||
|
(defclass start-down-action (action) |
||||||
|
((paddle :initarg :paddle :initform nil :reader paddle))) |
||||||
|
|
||||||
|
(defclass stop-down-action (action) |
||||||
|
((paddle :initarg :paddle :initform nil :reader paddle))) |
||||||
|
|
||||||
|
(defclass start-up-action (action) |
||||||
|
((paddle :initarg :paddle :initform nil :reader paddle))) |
||||||
|
|
||||||
|
(defclass stop-up-action (action) |
||||||
|
((paddle :initarg :paddle :initform nil :reader paddle))) |
||||||
|
|
||||||
|
(cpk:defencoding action timestamp) |
||||||
|
(cpk:defencoding start-game-action name) |
||||||
|
(cpk:defencoding start-down-action paddle) |
||||||
|
(cpk:defencoding stop-down-action paddle) |
||||||
|
(cpk:defencoding start-up-action paddle) |
||||||
|
(cpk:defencoding stop-up-action paddle) |
||||||
|
|
||||||
|
(defun get-paddle (paddle state) |
||||||
|
(case paddle |
||||||
|
(:left (state-left-paddle state)) |
||||||
|
(:right (state-right-paddle state))) ) |
||||||
|
|
||||||
|
(defmethod apply-action ((action start-down-action) (game game)) |
||||||
|
(let* ((state (game-state game)) |
||||||
|
(paddle (get-paddle (paddle action) state))) |
||||||
|
(incf (paddle-vy paddle) +paddle-speed+))) |
||||||
|
|
||||||
|
(defmethod apply-action ((action stop-down-action) (game game)) |
||||||
|
(let* ((state (game-state game)) |
||||||
|
(paddle (get-paddle (paddle action) state))) |
||||||
|
(decf (paddle-vy paddle) +paddle-speed+))) |
||||||
|
|
||||||
|
(defmethod apply-action ((action start-up-action) (game game)) |
||||||
|
(let* ((state (game-state game)) |
||||||
|
(paddle (get-paddle (paddle action) state))) |
||||||
|
(decf (paddle-vy paddle) +paddle-speed+))) |
||||||
|
|
||||||
|
(defmethod apply-action ((action stop-up-action) (game game)) |
||||||
|
(let* ((state (game-state game)) |
||||||
|
(paddle (get-paddle (paddle action) state))) |
||||||
|
(incf (paddle-vy paddle) +paddle-speed+))) |
Loading…
Reference in new issue