Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;Scheme ray casting/FOV demo
- ;;By Snarky
- ;;Adapted from pseudo code found at
- ;;http://roguebasin.roguelikedevelopment.org/index.php?title=Eligloscode
- ;;Prep work for 7DLR 2010 (to brush back up on my Scheme)
- ;;Global defines
- (define char-x 1) ;;x coordinate for the fake character
- (define char-y 1) ;;y coordinate for the fake character
- (define VIEW-RADIUS 3) ;;View radius for FOV demo
- (define IMPASSABLE-TILES (list #\# #\~)) ;;List of tiles we don't want to walk through (Walls and water)
- (define OPAQUE-TILES (list #\#)) ;;List of tiles that will break the ray casting (walls)
- (define test-env (list
- "###################"
- "#...#.............#"
- "#...#...#~~~~~....#"
- "#.......#~~~~~....#"
- "###################"))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Functions to create the environment;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function to create our working environment given an array of strings such as test-env
- (define create-env
- (lambda (env)
- (if (null? env)
- '()
- (cons (create-env-row (string->list (car env))) (create-env (cdr env))))))
- ;;Function that helps create-env by creating a given row
- (define create-env-row
- (lambda (env-row)
- (if (null? env-row)
- '()
- (cons (create-env-cell (car env-row)) (create-env-row (cdr env-row))))))
- ;;Function to create a given env cell, helps create-env-row
- (define create-env-cell
- (lambda (env-cell)
- (list env-cell #f)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Functions to display the environment;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function to write the env
- (define write-env
- (lambda (env)
- (write-env-help env 0 0)))
- ;;Function that does the brunt of the env write
- (define write-env-help
- (lambda (env x y)
- (if (null? env)
- (newline)
- (begin
- (write-env-row (car env) x y)
- (write-env-help (cdr env) x (+ y 1))))))
- ;;Function that writes a given row of the env
- (define write-env-row
- (lambda (env-row x y)
- (if (null? env-row)
- (newline)
- (begin
- (write-env-cell (car env-row) x y)
- (write-env-row (cdr env-row) (+ x 1) y)))))
- ;;Function that writes out a given cell of the env
- (define write-env-cell
- (lambda (env-cell x y)
- (let ((char (car env-cell)) ;;The symbol we'll possibly display
- (visible (cadr env-cell))) ;;The boolean bit of the env cell that holds if its visible or not
- (if visible ;;If this cell was marked to be seen
- (if (and (= x char-x) (= y char-y)) ;;Check if its where the character is
- (print "@") ;;If so, lets show an @ symbol
- (print char)) ;;Else show whatever character should be displayed
- (print " ")) ;;If this cell wasn't marked to be shown, just put a space
- (print " ")))) ;;Put a space after it for pretty printing
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Functions for the FOV demo;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function to update the FOV as a whole
- (define update-fov
- (lambda (env char-x char-y)
- (update-fov-help env char-x char-y 0 0)))
- ;;Function that does the actual work of updating the FOV
- (define update-fov-help
- (lambda (env char-x char-y x y)
- (if (not (null? env))
- (begin
- (update-fov-row (car env) char-x char-y x y)
- (update-fov-help (cdr env) char-x char-y x (+ y 1))))))
- ;;Function that updates the FOV for a given row
- (define update-fov-row
- (lambda (env-row char-x char-y x y)
- (if (not (null? env-row))
- (begin
- (update-fov-cell (car env-row) char-x char-y x y)
- (update-fov-row (cdr env-row) char-x char-y (+ x 1) y)))))
- ;;Function that does the real work to update a given cell's FOV
- (define update-fov-cell
- (lambda (env-cell char-x char-y x y)
- (set-cell-visible env-cell #f) ;;Set visible to false
- (let* ((dx (- x char-x))
- (dy (- y char-y))
- (distance (sqrt (+ (* dx dx) (* dy dy))))) ;;Get the distance between the character and the cell
- (if (< distance VIEW-RADIUS) ;;If we're within out viewing radius
- (set-cell-visible env-cell #t))))) ;;set the cell to be shown
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function for the Ray casting demo;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function to clear the entire env
- (define clear-cells
- (lambda (env)
- (if (not (null? env))
- (begin
- (clear-cells-row (car env))
- (clear-cells (cdr env))))))
- ;;Function that clears a row of the env
- (define clear-cells-row
- (lambda (env-row)
- (if (not (null? env-row))
- (begin
- (clear-cells-cell (car env-row))
- (clear-cells-row (cdr env-row))))))
- ;;Function to clear a cell in the env
- (define clear-cells-cell
- (lambda (env-cell)
- (set-cell-visible env-cell #f)))
- ;;Function to do the ray-cast
- (define cast-rays
- (lambda (env char-x char-y)
- (clear-cells env) ;;Clear everything first
- (cast-rays-help env char-x char-y 0)))
- ;;Function to do the real work of casting some rays
- (define cast-rays-help
- (lambda (env char-x char-y i)
- (if (<= i 360)
- (let ((x (cos (* i 0.01745)))
- (y (sin (* i 0.01745))))
- (trace-ray env char-x char-y x y (+ char-x .0) (+ char-y .0) 0)
- (cast-rays-help env char-x char-y (+ i 16))))))
- ;;Function to trace the specific ray to its end
- (define trace-ray
- (lambda (env char-x char-y x y dx dy i)
- (if (not (> i VIEW-RADIUS))
- (let* ((cell-x (round dx))
- (cell-y (round dy))
- (cell (get-cell env cell-x cell-y)))
- (if cell
- (begin
- (set-cell-visible cell #t)
- (if (cell-opaque? cell)
- (trace-ray env char-x char-y x y (+ dx x) (+ dy y) (+ i 1)))))))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Random helper functions;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;Function to get a given cell
- (define get-cell
- (lambda (env x y)
- (get-cell-help env x y 0)))
- ;;Function does most of the real work to get a given cell
- (define get-cell-help
- (lambda (env new-x new-y y)
- (if (not (null? env))
- (if (= y new-y)
- (get-cell-x (car env) new-x new-y 0)
- (get-cell-help (cdr env) new-x new-y (+ y 1)))
- #f)))
- ;;Final helper to get a given cell
- (define get-cell-x
- (lambda (env-row new-x new-y x)
- (if (not (null? env-row))
- (if (= x new-x)
- (car env-row)
- (get-cell-x (cdr env-row) new-x new-y (+ x 1)))
- #f)))
- ;;Function to tell if a cell is passable
- (define cell-passable?
- (lambda (cell)
- (not (member (car cell) IMPASSABLE-TILES)))) ;;Check to see if symbol is in our list of impassable tiles
- ;;Function to tell if a cell is opaque
- (define cell-opaque?
- (lambda (cell)
- (not (member (car cell) OPAQUE-TILES)))) ;;Check to see if symbol is in our list of opaque tiles
- ;;Function to 'move' our 'character' to another cell
- (define move-to
- (lambda (env x y)
- (if (cell-passable? (get-cell env x y)) ;;Check to make sure they can move there
- (begin
- (set! char-x x) ;;'Move' them by changing our global vars
- (set! char-y y)))))
- ;;Function to set a given cell's visibility to the given boolean
- (define set-cell-visible
- (lambda (cell bool)
- (set-cdr! cell (list bool))))
- ;;;;;;;;;;;;;
- ;;Test code;;
- ;;;;;;;;;;;;;
- ;;Setup the environment
- (define our-env (create-env test-env))
- ;;Run the fov-demo
- (define fov-demo
- (lambda (env)
- (print "FOV demo, use h, j, k, and l to move, q to quit\n")
- (update-fov our-env char-x char-y)
- (write-env our-env)
- (let read-loop ((x (read-char)))
- (if (not (or (char=? x #\q) (char=? x #\newline)))
- (begin
- (case x
- [(#\l) (let ((new-x (+ char-x 1))
- (new-y char-y))
- (move-to our-env new-x new-y))]
- [(#\k) (let ((new-x char-x)
- (new-y (- char-y 1)))
- (move-to our-env new-x new-y))]
- [(#\j) (let ((new-x char-x)
- (new-y (+ char-y 1)))
- (move-to our-env new-x new-y))]
- [(#\h) (let ((new-x (- char-x 1))
- (new-y char-y))
- (move-to our-env new-x new-y))])
- (update-fov our-env char-x char-y)
- (write-env our-env)
- (read-loop (read-char)))
- (case x
- [(#\q) (print "--End of FOV Demo--\n")]
- [(#\newline) (read-loop (read-char))])))))
- ;;Run the ray-casting-demo
- (define ray-casting-demo
- (lambda (env)
- (print "Ray casting demo, use h, j, k, and l to move, q to quit\n")
- (cast-rays our-env char-x char-y)
- (write-env our-env)
- (let read-loop ((x (read-char)))
- (if (not (or (char=? x #\q) (char=? x #\newline)))
- (begin
- (case x
- [(#\l) (let ((new-x (+ char-x 1))
- (new-y char-y))
- (move-to our-env new-x new-y))]
- [(#\k) (let ((new-x char-x)
- (new-y (- char-y 1)))
- (move-to our-env new-x new-y))]
- [(#\j) (let ((new-x char-x)
- (new-y (+ char-y 1)))
- (move-to our-env new-x new-y))]
- [(#\h) (let ((new-x (- char-x 1))
- (new-y char-y))
- (move-to our-env new-x new-y))])
- (cast-rays our-env char-x char-y)
- (write-env our-env)
- (read-loop (read-char)))
- (case x ;;Enter or q was pressed
- [(#\q) (print "--End of Ray casting demo--\n")] ;;If q, lets quit
- [(#\newline) (read-loop (read-char))]))))) ;;If enter just read the next char, it happens
- ;;Run our demos
- (fov-demo our-env)
- (ray-casting-demo our-env)
Advertisement
Add Comment
Please, Sign In to add comment