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
