Guest
Public paste!

Snarky

By: a guest | Feb 23rd, 2010 | Syntax: Scheme | Size: 10.90 KB | Hits: 278 | Expires: Never
Copy text to clipboard
  1. ;;Scheme ray casting/FOV demo
  2. ;;By Snarky
  3. ;;Adapted from pseudo code found at
  4. ;;http://roguebasin.roguelikedevelopment.org/index.php?title=Eligloscode
  5.  
  6. ;;Prep work for 7DLR 2010 (to brush back up on my Scheme)
  7.  
  8.  
  9. ;;Global defines
  10. (define char-x 1) ;;x coordinate for the fake character
  11. (define char-y 1) ;;y coordinate for the fake character
  12. (define VIEW-RADIUS 3) ;;View radius for FOV demo
  13.  
  14. (define IMPASSABLE-TILES (list #\# #\~)) ;;List of tiles we don't want to walk through (Walls and water)
  15. (define OPAQUE-TILES (list #\#)) ;;List of tiles that will break the ray casting (walls)
  16.  
  17. (define test-env (list
  18.                     "###################"
  19.                     "#...#.............#"
  20.                     "#...#...#~~~~~....#"
  21.                     "#.......#~~~~~....#"
  22.                     "###################"))
  23.  
  24. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25. ;;Functions to create the environment;;
  26. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  27.  
  28. ;;Function to create our working environment given an array of strings such as test-env
  29. (define create-env
  30.     (lambda (env)
  31.         (if (null? env)
  32.             '()
  33.             (cons (create-env-row (string->list (car env))) (create-env (cdr env))))))
  34.  
  35. ;;Function that helps create-env by creating a given row
  36. (define create-env-row
  37.     (lambda (env-row)
  38.         (if (null? env-row)
  39.             '()
  40.             (cons (create-env-cell (car env-row)) (create-env-row (cdr env-row))))))
  41.  
  42. ;;Function to create a given env cell, helps create-env-row
  43. (define create-env-cell
  44.     (lambda (env-cell)
  45.         (list env-cell #f)))
  46.  
  47.  
  48. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  49. ;;Functions to display the environment;;
  50. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  51.  
  52. ;;Function to write the env
  53. (define write-env
  54.     (lambda (env)
  55.         (write-env-help env 0 0)))
  56.  
  57. ;;Function that does the brunt of the env write
  58. (define write-env-help
  59.     (lambda (env x y)
  60.         (if (null? env)
  61.             (newline)
  62.             (begin
  63.                 (write-env-row (car env) x y)
  64.                 (write-env-help (cdr env) x (+ y 1))))))
  65.  
  66. ;;Function that writes a given row of the env
  67. (define write-env-row
  68.     (lambda (env-row x y)
  69.         (if (null? env-row)
  70.             (newline)
  71.             (begin
  72.                 (write-env-cell (car env-row) x y)
  73.                 (write-env-row (cdr env-row) (+ x 1) y)))))
  74.  
  75. ;;Function that writes out a given cell of the env
  76. (define write-env-cell
  77.     (lambda (env-cell x y)
  78.         (let ((char (car env-cell)) ;;The symbol we'll possibly display
  79.               (visible (cadr env-cell))) ;;The boolean bit of the env cell that holds if its visible or not
  80.             (if visible ;;If this cell was marked to be seen
  81.                 (if (and (= x char-x) (= y char-y)) ;;Check if its where the character is
  82.                     (print "@") ;;If so, lets show an @ symbol
  83.                     (print char)) ;;Else show whatever character should be displayed
  84.                 (print " ")) ;;If this cell wasn't marked to be shown, just put a space
  85.             (print " ")))) ;;Put a space after it for pretty printing
  86.  
  87. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  88. ;;Functions for the FOV demo;;
  89. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  90.  
  91. ;;Function to update the FOV as a whole
  92. (define update-fov
  93.     (lambda (env char-x char-y)
  94.         (update-fov-help env char-x char-y 0 0)))
  95.  
  96. ;;Function that does the actual work of updating the FOV
  97. (define update-fov-help
  98.     (lambda (env char-x char-y x y)
  99.         (if (not (null? env))
  100.             (begin
  101.                 (update-fov-row (car env) char-x char-y x y)
  102.                 (update-fov-help (cdr env) char-x char-y x (+ y 1))))))
  103.  
  104. ;;Function that updates the FOV for a given row
  105. (define update-fov-row
  106.     (lambda (env-row char-x char-y x y)
  107.         (if (not (null? env-row))
  108.             (begin
  109.                 (update-fov-cell (car env-row) char-x char-y x y)
  110.                 (update-fov-row (cdr env-row) char-x char-y (+ x 1) y)))))
  111.  
  112. ;;Function that does the real work to update a given cell's FOV
  113. (define update-fov-cell
  114.     (lambda (env-cell char-x char-y x y)
  115.         (set-cell-visible env-cell #f) ;;Set visible to false
  116.         (let* ((dx (- x char-x))
  117.                (dy (- y char-y))
  118.                (distance (sqrt (+ (* dx dx) (* dy dy))))) ;;Get the distance between the character and the cell
  119.             (if (< distance VIEW-RADIUS) ;;If we're within out viewing radius
  120.                 (set-cell-visible env-cell #t))))) ;;set the cell to be shown
  121.  
  122. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  123. ;;Function for the Ray casting demo;;
  124. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  125.  
  126. ;;Function to clear the entire env
  127. (define clear-cells
  128.     (lambda (env)
  129.         (if (not (null? env))
  130.             (begin
  131.                 (clear-cells-row (car env))
  132.                 (clear-cells (cdr env))))))
  133.  
  134. ;;Function that clears a row of the env
  135. (define clear-cells-row
  136.     (lambda (env-row)
  137.         (if (not (null? env-row))
  138.             (begin
  139.                 (clear-cells-cell (car env-row))
  140.                 (clear-cells-row (cdr env-row))))))
  141.  
  142. ;;Function to clear a cell in the env
  143. (define clear-cells-cell
  144.     (lambda (env-cell)
  145.         (set-cell-visible env-cell #f)))
  146.  
  147. ;;Function to do the ray-cast
  148. (define cast-rays
  149.     (lambda (env char-x char-y)
  150.         (clear-cells env) ;;Clear everything first
  151.         (cast-rays-help env char-x char-y 0)))
  152.  
  153. ;;Function to do the real work of casting some rays
  154. (define cast-rays-help
  155.     (lambda (env char-x char-y i)
  156.         (if (<= i 360)
  157.             (let ((x (cos (* i 0.01745)))
  158.                   (y (sin (* i 0.01745))))
  159.                   (trace-ray env char-x char-y x y (+ char-x .0) (+ char-y .0) 0)
  160.                   (cast-rays-help env char-x char-y (+ i 16))))))
  161.  
  162. ;;Function to trace the specific ray to its end
  163. (define trace-ray
  164.     (lambda (env char-x char-y x y dx dy i)
  165.         (if (not (> i VIEW-RADIUS))
  166.             (let* ((cell-x (round dx))
  167.                    (cell-y (round dy))
  168.                    (cell (get-cell env cell-x cell-y)))
  169.                 (if cell
  170.                     (begin
  171.                         (set-cell-visible cell #t)
  172.                         (if (cell-opaque? cell)
  173.                             (trace-ray env char-x char-y x y (+ dx x) (+ dy y) (+ i 1)))))))))
  174.                
  175.  
  176.  
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178. ;;Random helper functions;;
  179. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  180.  
  181. ;;Function to get a given cell
  182. (define get-cell
  183.     (lambda (env x y)
  184.         (get-cell-help env x y 0)))
  185.  
  186. ;;Function does most of the real work to get a given cell
  187. (define get-cell-help
  188.     (lambda (env new-x new-y y)
  189.         (if (not (null? env))
  190.             (if (= y new-y)
  191.                 (get-cell-x (car env) new-x new-y 0)
  192.                 (get-cell-help (cdr env) new-x new-y (+ y 1)))
  193.             #f)))
  194.  
  195. ;;Final helper to get a given cell
  196. (define get-cell-x
  197.     (lambda (env-row new-x new-y x)
  198.         (if (not (null? env-row))
  199.             (if (= x new-x)
  200.                 (car env-row)
  201.                 (get-cell-x (cdr env-row) new-x new-y (+ x 1)))
  202.             #f)))
  203.  
  204. ;;Function to tell if a cell is passable
  205. (define cell-passable?
  206.     (lambda (cell)
  207.         (not (member (car cell) IMPASSABLE-TILES)))) ;;Check to see if symbol is in our list of impassable tiles
  208.  
  209. ;;Function to tell if a cell is opaque
  210. (define cell-opaque?
  211.     (lambda (cell)
  212.         (not (member (car cell) OPAQUE-TILES)))) ;;Check to see if symbol is in our list of opaque tiles
  213.  
  214. ;;Function to 'move' our 'character' to another cell
  215. (define move-to
  216.     (lambda (env x y)
  217.         (if (cell-passable? (get-cell env x y)) ;;Check to make sure they can move there
  218.             (begin
  219.                 (set! char-x x) ;;'Move' them by changing our global vars
  220.                 (set! char-y y)))))
  221.  
  222. ;;Function to set a given cell's visibility to the given boolean
  223. (define set-cell-visible
  224.     (lambda (cell bool)
  225.         (set-cdr! cell (list bool))))
  226.  
  227. ;;;;;;;;;;;;;
  228. ;;Test code;;
  229. ;;;;;;;;;;;;;
  230.  
  231. ;;Setup the environment
  232. (define our-env (create-env test-env))
  233.  
  234. ;;Run the fov-demo
  235. (define fov-demo
  236.     (lambda (env)
  237.         (print "FOV demo, use h, j, k, and l to move, q to quit\n")
  238.         (update-fov our-env char-x char-y)
  239.         (write-env our-env)
  240.         (let read-loop ((x (read-char)))
  241.             (if (not (or (char=? x #\q) (char=? x #\newline)))
  242.                 (begin
  243.                     (case x
  244.                         [(#\l) (let ((new-x (+ char-x 1))
  245.                                      (new-y char-y))
  246.                                     (move-to our-env new-x new-y))]
  247.                         [(#\k) (let ((new-x char-x)
  248.                                      (new-y (- char-y 1)))
  249.                                     (move-to our-env new-x new-y))]
  250.                         [(#\j) (let ((new-x char-x)
  251.                                      (new-y (+ char-y 1)))
  252.                                     (move-to our-env new-x new-y))]
  253.                         [(#\h) (let ((new-x (- char-x 1))
  254.                                      (new-y char-y))
  255.                                     (move-to our-env new-x new-y))])
  256.                     (update-fov our-env char-x char-y)
  257.                     (write-env our-env)
  258.                     (read-loop (read-char)))
  259.                 (case x
  260.                     [(#\q) (print "--End of FOV Demo--\n")]
  261.                     [(#\newline) (read-loop (read-char))])))))
  262.        
  263.  
  264. ;;Run the ray-casting-demo
  265. (define ray-casting-demo
  266.     (lambda (env)
  267.         (print "Ray casting demo, use h, j, k, and l to move, q to quit\n")
  268.         (cast-rays our-env char-x char-y)
  269.         (write-env our-env)
  270.         (let read-loop ((x (read-char)))
  271.             (if (not (or (char=? x #\q) (char=? x #\newline)))
  272.                 (begin
  273.                     (case x
  274.                         [(#\l) (let ((new-x (+ char-x 1))
  275.                                      (new-y char-y))
  276.                                     (move-to our-env new-x new-y))]
  277.                         [(#\k) (let ((new-x char-x)
  278.                                      (new-y (- char-y 1)))
  279.                                     (move-to our-env new-x new-y))]
  280.                         [(#\j) (let ((new-x char-x)
  281.                                      (new-y (+ char-y 1)))
  282.                                     (move-to our-env new-x new-y))]
  283.                         [(#\h) (let ((new-x (- char-x 1))
  284.                                      (new-y char-y))
  285.                                     (move-to our-env new-x new-y))])
  286.                     (cast-rays our-env char-x char-y)
  287.                     (write-env our-env)
  288.                     (read-loop (read-char)))
  289.                 (case x ;;Enter or q was pressed
  290.                     [(#\q) (print "--End of Ray casting demo--\n")] ;;If q, lets quit
  291.                     [(#\newline) (read-loop (read-char))]))))) ;;If enter just read the next char, it happens
  292.  
  293. ;;Run our demos
  294. (fov-demo our-env)
  295. (ray-casting-demo our-env)