Nicolas Martyanoff <[EMAIL PROTECTED]> kirjoitti Sat, 20 Oct 2007 12:34:35  
+0300:

>
> Hi,
>
> Using your advices, and thank to #lisp people, I finally succeeded a
> small lisp demo using the LispBuilder bindings of SDL, SDL-image, and
> SDL-ttf.
>
> It's really simple, just a bunch of particles flying all over the
> screen, plus a bit of text rendering.
>
> My lisp code is of course unperfect; do not hesitate to signal me any
> error or crappy code.
>
> All was tested with sbcl.
>
> Demo: http://codemore.org/files/other/particles.tgz
> Screenshot: http://codemore.org/wp-content/uploads/2007/10/particles.png
>
> Bench result:
>
> ---------------------------------------------------------------------
> Athlon X2 3800+ 2GHz
>
> sbcl 1.0.10
> lispbuilder-sdl 0.9.0
> lispbuilder-sdl-image 0.4.0
> lispbuilder-sdl-ttf 0.2.0
>
> sdl-doublebuf sdl-hw-surface
> 640x480
>
> Particles   Framerate
> ---------------------
>    0           435
>   10           338
>   50           175
>  100           110
>  250            52
>  500            28
> 1000            15
> 2500             6
> ---------------------------------------------------------------------
>
> I enjoyed writing it, so I think I'm going to stay on the Lisp way to
> enlightenment :)
>
> Regards,
>

Great to hear you got it working! As for your code it looks ok to me, only  
the (return-from main 0) look weird, if you want to return a value from a  
function just having that value as the last form is enough.

For comparison, I converted it to PAL. Text handling is a bit different  
and the vec2 classes are redundant since pal already has those but I left  
them in there anyway:
(btw it runs ~8 fps with 10 000 particles on my laptop. Still a bit low I  
think though)


;;;; ---------------------------------------------------------------------
;;;; Particle Demo: a simple SDL demo using common lisp.
;;;; Copyright (C) 2007 Nicolas Martyanoff <[EMAIL PROTECTED]>
;;;; Converted to PAL by T Neste
;;;;
;;;; This program is free software: you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation, either version 3 of the License, or
;;;; (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;;; ---------------------------------------------------------------------

;;; ----------------------------------------------------------------------
;;; Packages.
;;; ----------------------------------------------------------------------

(require :pal)

;;; ----------------------------------------------------------------------
;;; Parameters of the demo.
;;; ----------------------------------------------------------------------
(defparameter *screen-width* 800)
(defparameter *screen-height* 600)
(defparameter *particle-speed-min* 120.0)
(defparameter *particle-speed-max* 200.0)
(defparameter *particle-count* 10000)

;;; ----------------------------------------------------------------------
;;; Global variables.
;;; ----------------------------------------------------------------------
(defvar *screen* nil)
(defvar *particle-img* nil)
(defvar *particles* nil)

(defvar *fps* 0)
(defvar *frame-count* 0)
(defvar *last-ticks* 0)
(defvar *last-fticks* 0)
(defvar *ftime* 0.1)

(defvar *sans-big* nil)
(defvar *sans-small* nil)

;;; ----------------------------------------------------------------------
;;; Generate a random number in the range [a, b].
;;; ----------------------------------------------------------------------
(defun rand-range (a b)
   (+ (* (random 1.0) (- b a)) a))

;;; ----------------------------------------------------------------------
;;; A 2D vector.
;;; ----------------------------------------------------------------------
(defclass vec2 ()
   ((x :accessor vec2-x :initform 0.0 :initarg :x)
    (y :accessor vec2-y :initform 0.0 :initarg :y)))

;;; ----------------------------------------------------------------------
;;; Create a 2D vector.
;;; ----------------------------------------------------------------------
(defun make-vec2 (x y)
   (make-instance 'vec2 :x x :y y))

;;; ----------------------------------------------------------------------
;;; Normalize a 2D vector.
;;; ----------------------------------------------------------------------
(defun vec2-normalize (v)
   (let ((n (sqrt (+ (* (vec2-x v) (vec2-x v))
                     (* (vec2-y v) (vec2-y v))))))
     (when (not (zerop n))
       (setf (vec2-x v) (/ (vec2-x v) n))
       (setf (vec2-y v) (/ (vec2-y v) n)))))

;;; ----------------------------------------------------------------------
;;; A particule.
;;; ----------------------------------------------------------------------
(defclass particle ()
   ((pos :accessor particle-pos :initarg :pos)
    (velocity :accessor particle-velocity :initarg :velocity)))

;;; ----------------------------------------------------------------------
;;; Create a particle.
;;; ----------------------------------------------------------------------
(defun make-particle (pos vel)
   (make-instance 'particle :pos pos :velocity vel))

;;; ----------------------------------------------------------------------
;;; Initialize a particle, position it to the center of the screen,
;;; and give it a random velocity.
;;; ----------------------------------------------------------------------
(defun init-particle (p)
   (let ((hx (/ *screen-width* 2)) (hy (/ *screen-height* 2)))
     (let ((vel (make-vec2 (rand-range -1.0 1.0) (rand-range -1.0 1.0))))
       (vec2-normalize vel)
       (let ((sp (rand-range *particle-speed-min* *particle-speed-max*)))
         (setf (vec2-x vel) (* (vec2-x vel) sp))
         (setf (vec2-y vel) (* (vec2-y vel) sp))
         (setf (particle-pos p) (make-vec2 hx hy))
         (setf (particle-velocity p) vel))))
   p)

;;; ----------------------------------------------------------------------
;;; Update the position of a particle.
;;; ----------------------------------------------------------------------
(defun update-particle (p ftime)
   (let ((vel (particle-velocity p)))
     (incf (vec2-x (particle-pos p)) (* (vec2-x vel) ftime))
     (incf (vec2-y (particle-pos p)) (* (vec2-y vel) ftime)))
   (let ((pos (particle-pos p)))
     (when (or (< (vec2-x pos) (- 0 (pal:image-width *particle-img*)))
               (< (vec2-y pos) (- 0 (pal:image-height *particle-img*)))
               (> (vec2-x pos) *screen-width*)
               (> (vec2-y pos) *screen-height*))
       ;; The particle is out of screen, re-init it
       (init-particle p))))

;;; ----------------------------------------------------------------------
;;; Main function.
;;; ----------------------------------------------------------------------

(defun main ()
   ;; Create window
   (pal:with-pal (:fps 1000 :width *screen-width* :height *screen-height*  
:title "Particles Demo" :paths "put here/the/path to your/data folder")

     ;; Load images
     (setf *particle-img* (pal:load-image "particle.png"))

     ;; Create the particles

     (setf *particles* (loop repeat *particle-count* collecting  
(init-particle (make-instance 'particle))))

     ;; Event loop, quit events are handled automatically if no  
:key-down-fn arguments are not given to pal:event-loop
     (pal:event-loop ()

       ;; Clear screen
       (pal:clear-screen 0 0 0)

       ;; Draw the particles
       (dolist (p *particles*)
         (update-particle p *ftime*) ;; *ftime* etc. is not updated in this  
version.
         (let ((pos (particle-pos p)))
           ;; This is actually redundant and clumsy since PAL has it's own  
vec2s that it uses.
           (pal:draw-image *particle-img* (v-floor (v (vec2-x pos) (vec2-y  
pos))))))

       ;; Display text

       (draw-text "Particles Demo" (v 5 5))
       (draw-text (format nil "Particles: ~d" *particle-count*) (v 5 35))
       (draw-text (format nil "Framerate: ~f" (pal:get-fps)) (v 5 50)))))

;; (main)



-- 
tomppa
_______________________________________________
Gardeners mailing list
[email protected]
http://www.lispniks.com/mailman/listinfo/gardeners

Reply via email to