46 lines
2.0 KiB
Common Lisp
46 lines
2.0 KiB
Common Lisp
(defvar *frame-rate* 30)
|
|
(defvar *damping* 0.99 "Deceleration factor.")
|
|
|
|
(defun make-pendulum (length theta0 x)
|
|
"Returns an anonymous function with enclosed state representing a pendulum."
|
|
(let* ((theta (* (/ theta0 180) pi))
|
|
(acceleration 0))
|
|
(if (< length 40) (setf length 40)) ;;avoid a divide-by-zero
|
|
(lambda ()
|
|
;;Draws the pendulum, updating its location and speed.
|
|
(sdl:draw-line (sdl:point :x x :y 1)
|
|
(sdl:point :x (+ (* (sin theta) length) x)
|
|
:y (* (cos theta) length)))
|
|
(sdl:draw-filled-circle (sdl:point :x (+ (* (sin theta) length) x)
|
|
:y (* (cos theta) length))
|
|
20
|
|
:color sdl:*yellow*
|
|
:stroke-color sdl:*white*)
|
|
;;The magic constant approximates the speed we want for a given frame-rate.
|
|
(incf acceleration (* (sin theta) (* *frame-rate* -0.001)))
|
|
(incf theta acceleration)
|
|
(setf acceleration (* acceleration *damping*)))))
|
|
|
|
|
|
(defun main (&optional (w 640) (h 480))
|
|
(sdl:with-init ()
|
|
(sdl:window w h :title-caption "Pendulums"
|
|
:fps (make-instance 'sdl:fps-fixed))
|
|
(setf (sdl:frame-rate) *frame-rate*)
|
|
(let ((pendulums nil))
|
|
(sdl:with-events ()
|
|
(:quit-event () t)
|
|
(:idle ()
|
|
(sdl:clear-display sdl:*black*)
|
|
(mapcar #'funcall pendulums) ;;Draw all the pendulums
|
|
|
|
(sdl:update-display))
|
|
(:key-down-event (:key key)
|
|
(cond ((sdl:key= key :sdl-key-escape)
|
|
(sdl:push-quit-event))
|
|
((sdl:key= key :sdl-key-space)
|
|
(push (make-pendulum (random (- h 100))
|
|
(random 90)
|
|
(round w 2))
|
|
pendulums))))))))
|