mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			436 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
			
		
		
	
	
			436 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
(import (rnrs)
 | 
						|
        (only (surfage s1 lists) filter-map)
 | 
						|
        (gl)
 | 
						|
        (glut)
 | 
						|
        (dharmalab records define-record-type)
 | 
						|
        (dharmalab math basic)
 | 
						|
        (agave glu compat)
 | 
						|
        (agave geometry pt)
 | 
						|
        (agave glamour window)
 | 
						|
        (agave glamour misc)
 | 
						|
        (surfage s19 time)
 | 
						|
        (surfage s27 random-bits)
 | 
						|
        (surfage s42 eager-comprehensions))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; utilities
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (say . args)
 | 
						|
  (for-each display args)
 | 
						|
  (newline))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (gl-translate-pt p)
 | 
						|
  (glTranslated (pt-x p) (pt-y p) 0.0))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (radians x) (* x (/ pi 180)))
 | 
						|
 | 
						|
(define (degrees x) (* x (/ 180 pi)))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (angle->pt a)
 | 
						|
  (pt (cos a)
 | 
						|
      (sin a)))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (current-time-in-nanoseconds)
 | 
						|
  (let ((val (current-time)))
 | 
						|
    (+ (* (time-second val) 1000000000)
 | 
						|
       (time-nanosecond val))))
 | 
						|
 | 
						|
(define (current-time-in-seconds)
 | 
						|
  (/ (current-time-in-nanoseconds)
 | 
						|
     1000.0 ;; micro
 | 
						|
     1000.0 ;; milli
 | 
						|
     1000.0))
 | 
						|
 | 
						|
(define base-time (current-time-in-seconds))
 | 
						|
 | 
						|
(define (time-step) (- (current-time-in-seconds) base-time))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define score 0)
 | 
						|
 | 
						|
(define level 1)
 | 
						|
 | 
						|
(define ships 3)
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; spaceship
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define-record-type++ spaceship
 | 
						|
  (fields (mutable pos)
 | 
						|
          (mutable vel)
 | 
						|
          (mutable theta)
 | 
						|
          (mutable force)))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; particle
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define-record-type++ particle
 | 
						|
  (fields (mutable pos)
 | 
						|
          (mutable vel)
 | 
						|
          (mutable birth)
 | 
						|
          (mutable lifetime)
 | 
						|
          (mutable color)))
 | 
						|
 | 
						|
(define particles '())
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; bullet
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define-record-type++ bullet
 | 
						|
  (fields (mutable pos)
 | 
						|
          (mutable vel)
 | 
						|
          (mutable birth)))
 | 
						|
 | 
						|
(define bullets '())
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; asteroid
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define-record-type++ asteroid
 | 
						|
  (fields (mutable pos)
 | 
						|
          (mutable vel)
 | 
						|
          (mutable radius)))
 | 
						|
 | 
						|
(define number-of-starting-asteroids 4)
 | 
						|
 | 
						|
(define asteroids #f)
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
;; bullet-pack
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define-record-type++ bullet-pack
 | 
						|
  (fields (mutable pos)
 | 
						|
          (mutable vel)))
 | 
						|
 | 
						|
(define pack #f)
 | 
						|
 | 
						|
(is-bullet-pack pack)
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(initialize-glut)
 | 
						|
 | 
						|
(window (size 800 400)
 | 
						|
        (title "Asteroids")
 | 
						|
        (reshape (width height)))
 | 
						|
 | 
						|
(random-source-randomize! default-random-source)
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define (pt-wrap p)
 | 
						|
  (pt (mod (pt-x p) width)
 | 
						|
      (mod (pt-y p) height)))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define ship
 | 
						|
  (make-spaceship (pt (/ width 2.0) (/ height 2.0))
 | 
						|
                  (pt 0.0 0.0)
 | 
						|
                  0.0
 | 
						|
                  0.0))
 | 
						|
 | 
						|
(is-spaceship ship)
 | 
						|
 | 
						|
(define ammo 0)
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(set! asteroids
 | 
						|
      (list-ec (: i number-of-starting-asteroids)
 | 
						|
        (make-asteroid (pt (inexact (random-integer width))
 | 
						|
                           (inexact (random-integer height)))
 | 
						|
                       (pt (inexact (+ -50 (random-integer 100)))
 | 
						|
                           (inexact (+ -50 (random-integer 100))))
 | 
						|
                       50.0)))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(set! pack (make-bullet-pack (pt (inexact (random-integer width))
 | 
						|
                                 (inexact (random-integer height)))
 | 
						|
                             (pt (inexact (+ -50 (random-integer 100)))
 | 
						|
                                 (inexact (+ -50 (random-integer 100))))))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(buffered-display-procedure
 | 
						|
 (lambda ()
 | 
						|
   (background 0.0)
 | 
						|
 | 
						|
   ;; ship
 | 
						|
 | 
						|
   (glColor3f 0.0 1.0 0.0)
 | 
						|
 | 
						|
   (gl-matrix-excursion
 | 
						|
    (gl-translate-pt ship.pos)
 | 
						|
    (glRotated 90.0 0.0 1.0 0.0)
 | 
						|
    (glRotated (degrees ship.theta) -1.0 0.0 0.0)
 | 
						|
    (glutWireCone 10.0 30.0 5 5))
 | 
						|
 | 
						|
   ;; particles
 | 
						|
 | 
						|
   (for-each
 | 
						|
    (lambda (par)
 | 
						|
 | 
						|
      (let ((c (particle-color par)))
 | 
						|
        (glColor3f (vector-ref c 0)
 | 
						|
                   (vector-ref c 1)
 | 
						|
                   (vector-ref c 2)))
 | 
						|
      
 | 
						|
      (gl-matrix-excursion
 | 
						|
       (gl-translate-pt (particle-pos par))
 | 
						|
       (glutWireSphere 2.0 5 5)))
 | 
						|
    particles)
 | 
						|
 | 
						|
   ;; bullets
 | 
						|
 | 
						|
   (glColor3f 0.0 0.0 1.0)
 | 
						|
   
 | 
						|
   (for-each
 | 
						|
    (lambda (bullet)
 | 
						|
      (gl-matrix-excursion
 | 
						|
       (gl-translate-pt (bullet-pos bullet))
 | 
						|
       (glutWireSphere 5.0 10 10)))
 | 
						|
    bullets)
 | 
						|
 | 
						|
   ;; asteroids
 | 
						|
 | 
						|
   (glColor3f 1.0 0.0 0.0)
 | 
						|
 | 
						|
   (for-each
 | 
						|
    (lambda (asteroid)
 | 
						|
      (gl-matrix-excursion
 | 
						|
       (gl-translate-pt (asteroid-pos asteroid))
 | 
						|
       (glutWireSphere (asteroid-radius asteroid) 10 10)))
 | 
						|
    asteroids)
 | 
						|
 | 
						|
   ;; bullet-pack
 | 
						|
 | 
						|
   (glColor3f 0.0 0.0 1.0)
 | 
						|
 | 
						|
   (gl-matrix-excursion
 | 
						|
    (gl-translate-pt pack.pos)
 | 
						|
    (glutWireCube 10.0))
 | 
						|
 | 
						|
   ))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(define last-time (current-time-in-seconds))
 | 
						|
 | 
						|
(define dt 0)
 | 
						|
 | 
						|
(define (update-system)
 | 
						|
 | 
						|
  (set! dt (- (current-time-in-seconds) last-time))
 | 
						|
 | 
						|
  (set! last-time (current-time-in-seconds))
 | 
						|
 | 
						|
  (ship.pos! (pt-wrap (pt+ ship.pos (pt*n ship.vel dt))))
 | 
						|
 | 
						|
  (pack.pos! (pt-wrap (pt+ pack.pos (pt*n pack.vel dt))))
 | 
						|
 | 
						|
  (set! particles
 | 
						|
        (filter-map
 | 
						|
         (lambda (par)
 | 
						|
           (is-particle par)
 | 
						|
           (cond ((> (- (current-time-in-seconds) par.birth) par.lifetime) #f)
 | 
						|
                 (else (par.pos! (pt+ par.pos (pt*n par.vel dt)))
 | 
						|
                       par)))
 | 
						|
         particles))
 | 
						|
 | 
						|
  (set! bullets
 | 
						|
        (filter-map
 | 
						|
         (lambda (bullet)
 | 
						|
           (is-bullet bullet)
 | 
						|
           (cond ((> (- (current-time-in-seconds) bullet.birth) 2.0) #f)
 | 
						|
                 (else (bullet.pos! (pt+ bullet.pos (pt*n bullet.vel dt)))
 | 
						|
                       bullet)))
 | 
						|
         bullets))
 | 
						|
 | 
						|
  (set! asteroids
 | 
						|
        (filter-map
 | 
						|
         (lambda (a)
 | 
						|
           (is-asteroid a)
 | 
						|
           (a.pos! (pt-wrap (pt+ a.pos (pt*n a.vel dt))))
 | 
						|
           (if (< a.radius 10.0) #f a))
 | 
						|
         asteroids))
 | 
						|
 | 
						|
  ;; bullet asteroid contact
 | 
						|
 | 
						|
  (for-each
 | 
						|
   (lambda (b)
 | 
						|
     (is-bullet b)
 | 
						|
     (for-each
 | 
						|
      (lambda (a)
 | 
						|
        (is-asteroid a)
 | 
						|
        (when (<= (pt-distance b.pos a.pos)
 | 
						|
                  a.radius)
 | 
						|
          
 | 
						|
          (begin (set! score (+ score 1))
 | 
						|
                 (say "score: " score)
 | 
						|
                 #f)
 | 
						|
          
 | 
						|
          (set! asteroids
 | 
						|
                (append 
 | 
						|
                 (list-ec (: i 4)
 | 
						|
                   (make-asteroid a.pos
 | 
						|
                                  (pt (+ -50.0 (random-integer 100))
 | 
						|
                                      (+ -50.0 (random-integer 100)))
 | 
						|
                                  (/ a.radius 2.0)))
 | 
						|
                 asteroids))
 | 
						|
          (a.radius! 0.1)
 | 
						|
          (b.birth! 0.0)
 | 
						|
 | 
						|
          (set! particles
 | 
						|
                (append (list-ec (: i 100)
 | 
						|
                          (make-particle a.pos
 | 
						|
                                         (pt*n (angle->pt
 | 
						|
                                                (radians
 | 
						|
                                                 (random-integer 360)))
 | 
						|
 | 
						|
                                               (random-integer 100)
 | 
						|
 | 
						|
                                               )
 | 
						|
                                         (current-time-in-seconds)
 | 
						|
                                         1.0
 | 
						|
                                         (vector 1.0 1.0 1.0)))
 | 
						|
                        particles))))
 | 
						|
      asteroids))
 | 
						|
   bullets)
 | 
						|
 | 
						|
  (for-each
 | 
						|
   (lambda (a)
 | 
						|
     (is-asteroid a)
 | 
						|
     (when (<= (pt-distance a.pos ship.pos) a.radius)
 | 
						|
 | 
						|
       (set! particles
 | 
						|
             (append (list-ec (: i 100)
 | 
						|
                       (make-particle ship.pos
 | 
						|
                                      (pt*n (angle->pt
 | 
						|
                                             (radians
 | 
						|
                                              (random-integer 360)))
 | 
						|
                                            (random-integer 100))
 | 
						|
                                      (current-time-in-seconds)
 | 
						|
                                      1.0
 | 
						|
                                      (vector 0.0 1.0 1.0)))
 | 
						|
                     particles))
 | 
						|
 | 
						|
       (set! ship (make-spaceship (pt (/ width 2.0) (/ height 2.0))
 | 
						|
                                  (pt 0.0 0.0)
 | 
						|
                                  0.0
 | 
						|
                                  0.0))
 | 
						|
 | 
						|
       ))
 | 
						|
   asteroids)
 | 
						|
 | 
						|
  (when (null? asteroids)
 | 
						|
    (set! level (+ level 1))
 | 
						|
    (display "level: ")
 | 
						|
    (display level)
 | 
						|
    (newline)
 | 
						|
    (set! asteroids
 | 
						|
          (list-ec (: i (+ number-of-starting-asteroids level))
 | 
						|
            (make-asteroid (pt (inexact (random-integer width))
 | 
						|
                               (inexact (random-integer height)))
 | 
						|
                           (pt (inexact (+ -50 (random-integer 100)))
 | 
						|
                               (inexact (+ -50 (random-integer 100))))
 | 
						|
                           50.0))))
 | 
						|
 | 
						|
  ;; ship pack contact
 | 
						|
 | 
						|
  (when (<= (pt-distance ship.pos pack.pos) 10.0)
 | 
						|
    (set! ammo (+ ammo 5))
 | 
						|
    (set! pack (make-bullet-pack (pt (inexact (random-integer width))
 | 
						|
                                     (inexact (random-integer height)))
 | 
						|
                                 (pt (inexact (+ -50 (random-integer 100)))
 | 
						|
                                     (inexact (+ -50 (random-integer 100))))))
 | 
						|
    (say "ammo: " ammo))
 | 
						|
 | 
						|
  )
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(glutIdleFunc
 | 
						|
 (lambda ()
 | 
						|
   (update-system)
 | 
						|
   (glutPostRedisplay)))
 | 
						|
 | 
						|
(glutKeyboardFunc
 | 
						|
 (lambda (key x y)
 | 
						|
   (case (integer->char key)
 | 
						|
 | 
						|
     ((#\w)
 | 
						|
 | 
						|
      (ship.vel! (pt+ ship.vel (pt*n (angle->pt ship.theta) 50.0)))
 | 
						|
 | 
						|
      (set! particles
 | 
						|
            (append (list-ec (: i 10)
 | 
						|
                      (make-particle ship.pos
 | 
						|
                                     (pt*n
 | 
						|
                                      (angle->pt
 | 
						|
                                       (+ ship.theta
 | 
						|
                                          (radians 180.0)
 | 
						|
                                          (radians (+ -45 (random-integer 90)))
 | 
						|
                                          ))
 | 
						|
                                      (random-integer 50)
 | 
						|
                                      )
 | 
						|
                                     (current-time-in-seconds)
 | 
						|
                                     1.0
 | 
						|
                                     (vector 1.0 1.0 0.0)))
 | 
						|
                    particles))
 | 
						|
 | 
						|
      )
 | 
						|
 | 
						|
     ((#\a) (ship.theta! (+ ship.theta (radians 20.0))))
 | 
						|
     ((#\d) (ship.theta! (- ship.theta (radians 20.0))))
 | 
						|
 | 
						|
     ((#\s) (ship.vel! (pt 0.0 0.0)))
 | 
						|
 | 
						|
     ((#\x) (ship.theta! (+ ship.theta (radians 180.0))))
 | 
						|
 | 
						|
     ((#\space)
 | 
						|
 | 
						|
      (when (> ammo 0)
 | 
						|
 | 
						|
        (set! ammo (- ammo 1))
 | 
						|
      
 | 
						|
        (set! bullets
 | 
						|
              (cons
 | 
						|
               (make-bullet ship.pos
 | 
						|
                            (pt+ ship.vel
 | 
						|
                                 (pt*n (angle->pt ship.theta) 400.0))
 | 
						|
                            (current-time-in-seconds))
 | 
						|
               bullets)))
 | 
						|
 | 
						|
      (say "ammo: " ammo)
 | 
						|
      )
 | 
						|
     )))
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(say "w   - Thrusters")
 | 
						|
(say "a/d - Left/Right")
 | 
						|
(say "s   - Stop")
 | 
						|
(say "x   - Flip")
 | 
						|
(say "spc - Laser")
 | 
						|
 | 
						|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
						|
 | 
						|
(glutMainLoop)
 |