Compare commits
7 commits
12a5618779
...
934cd5e819
Author | SHA1 | Date | |
---|---|---|---|
934cd5e819 | |||
5106ffc76f | |||
5239a89274 | |||
e763bae3b2 | |||
532d5e5073 | |||
5e85beab3f | |||
6beae9d591 |
|
@ -16,3 +16,8 @@ authored by Alex Griffith.
|
|||
A huge thank you to all aforementioned. You have made my learning possible, and
|
||||
my exploration into game-dev and Fennel/Love2D much more accessible and
|
||||
enjoyable!
|
||||
|
||||
## Assets
|
||||
|
||||
This project uses textures made by thatguynm found here:
|
||||
[64px Textures/Tilesheet](https://thatguynm.itch.io/pixelated-textures).
|
||||
|
|
BIN
assets/textures/walls/001_tgnm-wall-10.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
assets/textures/walls/002_tgnm-wall-11.png
Normal file
After Width: | Height: | Size: 692 B |
BIN
assets/textures/walls/003_tgnm-wall-14.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
7
conf.lua
|
@ -3,8 +3,11 @@ love.conf = function(t)
|
|||
t.title, t.identity = "Space Crawler", "Bill Niblock"
|
||||
t.modules.joystick = false
|
||||
t.modules.physics = false
|
||||
t.window.width = 1280
|
||||
t.window.height = 720
|
||||
-- This scales the game, and it still looks quite nice at 1440p!
|
||||
-- t.window.fullscreen = true
|
||||
-- t.window.fullscreentype = "desktop"
|
||||
t.window.width = 640
|
||||
t.window.height = 360
|
||||
t.window.vsync = false
|
||||
t.version = "11.5"
|
||||
end
|
||||
|
|
|
@ -54,7 +54,8 @@
|
|||
(- x dx) (+ y by dy)))
|
||||
(set dx (+ dx bb))))
|
||||
|
||||
(fn overlay []
|
||||
(fn overlay [dx dy]
|
||||
(love.graphics.translate dx (- dy))
|
||||
(oxygen-ui (+ (/ screen-width 2) 100) (- screen-height 100))
|
||||
(power-ui (- (/ screen-width 2) 100) (- screen-height 100))
|
||||
(love.graphics.setColor 1 1 1)
|
||||
|
|
BIN
pics/barrel.png
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.3 KiB |
BIN
pics/eagle.png
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 393 B |
Before Width: | Height: | Size: 3.6 KiB |
BIN
pics/mossy.png
Before Width: | Height: | Size: 4.2 KiB |
BIN
pics/pillar.png
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3 KiB |
BIN
pics/wood.png
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1,132 +0,0 @@
|
|||
; Much of this is derived from https://lodev.org/cgtutor/raycasting.html
|
||||
(local pi math.pi)
|
||||
(love.graphics.setColor 1 1 1)
|
||||
(love.graphics.setNewFont 30)
|
||||
|
||||
; Define map (0 is empty space, 1 is wall)
|
||||
(var map [[1 1 1 1 1 ]
|
||||
[2 0 0 0 4 ]
|
||||
[2 0 0 0 4 ]
|
||||
[2 0 0 0 4 ]
|
||||
[1 3 3 3 1 ]])
|
||||
|
||||
; This sets the wall texture data
|
||||
(var walls [])
|
||||
(var wall-textures (love.filesystem.getDirectoryItems "textures/walls"))
|
||||
|
||||
(each [_ v (ipairs wall-textures)]
|
||||
(local wall {})
|
||||
(tset wall :t (love.graphics.newImage (.. "textures/walls/" v)))
|
||||
(tset wall :w (love.graphics.getWidth (. wall :t)))
|
||||
(tset wall :h (love.graphics.getHeight (. wall :t)))
|
||||
(table.insert walls wall))
|
||||
|
||||
; Map size
|
||||
(var map-height (length map))
|
||||
(var map-width (length (. map 1)))
|
||||
|
||||
; Player position and direction
|
||||
; pos{x,y}: position vector of the player
|
||||
; dir{x,y}: direction vector of the player
|
||||
; pln{x,y}: camera plane of the player
|
||||
(var player {:posx 3 :posy 3
|
||||
:dirx -1 :diry 0
|
||||
:plnx 0 :plny 0.66})
|
||||
|
||||
; Screen size
|
||||
(var screen-width 1920)
|
||||
(var screen-height 1080)
|
||||
(var texel-width 64)
|
||||
(var texel-height 64)
|
||||
|
||||
; Function to handle player movement
|
||||
(fn move-player [move-speed]
|
||||
(let [new-x (+ player.posx (* (math.cos player.dir) move-speed))
|
||||
new-y (+ player.y (* (math.sin player.dir) move-speed))]
|
||||
; Check for collisions with walls
|
||||
(when (= (. map (math.floor new-y) (math.floor new-x)) 0)
|
||||
(set player.x new-x)
|
||||
(set player.y new-y))))
|
||||
|
||||
; Function to handle player rotation
|
||||
(fn rotate-player [rot]
|
||||
(local (o-dx o-px) (values player.dirx player.plnx))
|
||||
(set player.dirx (- (* player.dirx (math.cos rot)) (* player.diry (math.sin rot))))
|
||||
(set player.plnx (- (* player.plnx (math.cos rot)) (* player.plny (math.sin rot))))
|
||||
(set player.diry (+ (* o-dx (math.sin rot)) (* player.diry (math.cos rot))))
|
||||
(set player.plny (+ (* o-px (math.sin rot)) (* player.plny (math.cos rot))))
|
||||
)
|
||||
|
||||
; Draw function for rendering
|
||||
{:draw (fn love.draw []
|
||||
(love.graphics.clear)
|
||||
|
||||
; For each vertical slice of the screen
|
||||
(for [i 0 (- screen-width 1)]
|
||||
; Setup a bunch of variables
|
||||
; Camera Space x-coordinate, kind of the ray position
|
||||
(local cam-x (- (/ (* 2 i) screen-width) 1))
|
||||
; Ray direction vector values
|
||||
(local (ray-dir-x ray-dir-y) (values (+ player.dirx (* player.plnx cam-x)) (+ player.diry (* player.plny cam-x))))
|
||||
; Current player position on the map grid
|
||||
(var (map-x map-y) (values (math.floor player.posx) (math.floor player.posy)))
|
||||
; Length of ray from first x/y to the next x/y
|
||||
(local (delta-dist-x delta-dist-y) (values
|
||||
(math.sqrt (+ 1 (/ (* ray-dir-y ray-dir-y) (* ray-dir-x ray-dir-x))))
|
||||
(math.sqrt (+ 1 (/ (* ray-dir-x ray-dir-x) (* ray-dir-y ray-dir-y))))))
|
||||
; Side hit (n/s or e/w)
|
||||
(var side nil)
|
||||
; Calculate step and distance from player to first x/y-side (as per Love graphics grid)
|
||||
(var (step-x side-dist-x) (if (< ray-dir-x 0)
|
||||
(values -1 (* (- player.posx map-x) delta-dist-x))
|
||||
(values 1 (* (- player.posx (+ map-x 1)) delta-dist-x))))
|
||||
(var (step-y side-dist-y) (if (< ray-dir-y 0)
|
||||
(values -1 (* (- player.posy map-y) delta-dist-y))
|
||||
(values 1 (* (- player.posy (+ map-y 1)) delta-dist-y))))
|
||||
; Shoot ze ray until it hits something
|
||||
(var wall-hit false)
|
||||
(while (not wall-hit)
|
||||
(if (< side-dist-x side-dist-y)
|
||||
(set (side-dist-x map-x side) (values (+ side-dist-x delta-dist-x) (+ map-x step-x) 0))
|
||||
(set (side-dist-y map-y side) (values (+ side-dist-y delta-dist-y) (+ map-y step-y) 1)))
|
||||
(set wall-hit (if (> (. map map-x map-y) 0) true false)))
|
||||
; Set the perpindicular length from the camera plane to the wall
|
||||
(var ray-length (if (= side 0) (- side-dist-x delta-dist-x) (- side-dist-y delta-dist-y)))
|
||||
; Determine pixel-column height
|
||||
(var line-height (math.floor (/ screen-height ray-length)))
|
||||
(var (draw-start draw-end) (values (+ (/ (* -1 line-height) 2) (/ screen-height 2)) (+ (/ line-height 2) (/ screen-height 2))))
|
||||
(if (< draw-start 0) (set draw-start 0))
|
||||
(if (>= draw-end screen-height) (set draw-end (- screen-height 1)))
|
||||
; Determine exactly where along the wall the ray hits
|
||||
(var wall-col (if (= side 0) (+ player.posy (* ray-length ray-dir-y)) (+ player.posx (* ray-length ray-dir-x))))
|
||||
(set wall-col (- wall-col (math.floor wall-col)))
|
||||
; Select the texture data based on the grid number
|
||||
(local wall-texture (. walls (. map map-x map-y)))
|
||||
; Calculate the part of the texture to paint, and then do so
|
||||
(var texture-x (math.floor (* wall-col (. wall-texture :w))))
|
||||
(if (and (= side 0) (> ray-dir-x 0)) (set texture-x (- (- (. wall-texture :w) texture-x) 1)))
|
||||
(if (and (= side 1) (< ray-dir-y 0)) (set texture-x (- (- (. wall-texture :w) texture-x) 1)))
|
||||
(love.graphics.setColor 1 1 1)
|
||||
(love.graphics.draw (. wall-texture :t)
|
||||
(love.graphics.newQuad texture-x 0 1 (. wall-texture :h) (. wall-texture :w) (. wall-texture :h))
|
||||
i draw-start 0 1 (/ line-height (. wall-texture :h)))
|
||||
; Draw simple lines
|
||||
; (love.graphics.line i draw-start i draw-end)
|
||||
(love.graphics.setColor 1 0 0)
|
||||
(love.graphics.print (.. "player-x: " player.posx ", player-y:" player.posy) 50 300)
|
||||
(love.graphics.print (.. "map-x: " map-x ", map-y:" map-y ", val:" (. map map-x map-y)) 50 330)
|
||||
(love.graphics.print (.. "side: " side ", ray-length:" ray-length) 50 370)
|
||||
(love.graphics.print (.. "step-x: " step-x ", step-y:" step-y) 50 400)
|
||||
)
|
||||
)
|
||||
|
||||
:update (fn update [dt]
|
||||
(when (love.keyboard.isDown "j") (rotate-player 0.1))
|
||||
(when (love.keyboard.isDown "l") (rotate-player -0.1)))
|
||||
|
||||
:keypressed (fn keypressed [key set-mode]
|
||||
(when (= key "j") (rotate-player 0.05))
|
||||
(when (= key "l") (rotate-player -0.05))
|
||||
(when (= key "i") (move-player 1))
|
||||
(when (= key "k") (move-player -1))
|
||||
(when (= key "x") (love.event.quit)))}
|
61
ray-cast.fnl
|
@ -1,61 +0,0 @@
|
|||
(local pi (math.pi))
|
||||
|
||||
; Define map (0 is empty space, 1 is wall)
|
||||
(var map [[1 1 1 1 1]
|
||||
[1 0 0 0 1]
|
||||
[1 0 1 0 1]
|
||||
[1 0 0 0 1]
|
||||
[1 1 1 1 1]])
|
||||
|
||||
; Map size
|
||||
(var map-width (length map))
|
||||
(var map-height (length (first map)))
|
||||
|
||||
; Player position and direction
|
||||
(var player {:x 2.5 :y 2.5 :dir 0 :fov (/ pi 3)})
|
||||
|
||||
; Screen size
|
||||
(var screen-width 640)
|
||||
(var screen-height 480)
|
||||
|
||||
; Ray-casting function
|
||||
(fn cast-ray [ray-angle]
|
||||
(local dx (math.cos ray-angle))
|
||||
(local dy (math.sin ray-angle))
|
||||
|
||||
(var distance 0)
|
||||
(while true
|
||||
(var ray-x (+ player.x (* dx distance)))
|
||||
(var ray-y (+ player.y (* dy distance)))
|
||||
|
||||
; Check if ray hits a wall (1) on the map
|
||||
(when (or (>= (math.floor ray-x) map-width)
|
||||
(>= (math.floor ray-y) map-height)
|
||||
(<= ray-x 0)
|
||||
(<= ray-y 0)
|
||||
(= (nth (nth map (math.floor ray-y)) (math.floor ray-x)) 1))
|
||||
(return distance))
|
||||
|
||||
; Increment distance
|
||||
(set distance (+ distance 0.01))))
|
||||
|
||||
; Draw function for rendering
|
||||
(fn love.draw []
|
||||
(love.graphics.clear)
|
||||
|
||||
; For each vertical slice of the screen
|
||||
(for [i 0 (- screen-width 1)]
|
||||
; Calculate angle of ray relative to player direction
|
||||
(local ray-angle (+ player.dir
|
||||
(- (* (/ i screen-width) player.fov) (/ player.fov 2))))
|
||||
|
||||
; Cast the ray to find distance to the nearest wall
|
||||
(local distance (cast-ray ray-angle))
|
||||
|
||||
; Calculate height of the wall slice
|
||||
(local wall-height (math.floor (/ screen-height distance)))
|
||||
|
||||
; Draw the wall slice (centered vertically)
|
||||
(love.graphics.line i (/ (- screen-height wall-height) 2)
|
||||
i (/ (+ screen-height wall-height) 2))))
|
||||
|
199
raycaster.fnl
|
@ -6,43 +6,115 @@
|
|||
(var (screen-width screen-height) (love.window.getMode))
|
||||
|
||||
; ### Map Information ###
|
||||
(var map (mapper.generate 15 15))
|
||||
; (var map [[1 1 1 1 1 1 1 1 1 1 1 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 3 0 4 ]
|
||||
; [2 0 0 0 0 0 0 3 3 0 4 ]
|
||||
; [2 0 0 0 0 0 0 0 0 0 4 ]
|
||||
; [1 1 1 1 1 1 1 1 1 1 1 ]])
|
||||
; (var map (mapper.generate 15 15))
|
||||
(var map [[1 1 2 1 1 1 1 2 1 1 1 ]
|
||||
[1 0 0 0 0 0 0 0 0 0 1 ]
|
||||
[1 0 0 0 0 0 0 0 0 0 2 ]
|
||||
[2 0 0 0 0 0 0 0 0 0 2 ]
|
||||
[1 0 0 0 0 0 0 0 0 0 1 ]
|
||||
[1 0 0 0 0 0 0 0 0 0 1 ]
|
||||
[1 0 0 0 0 0 0 0 3 0 1 ]
|
||||
[1 0 0 0 0 0 0 3 3 0 1 ]
|
||||
[1 0 0 0 0 0 0 0 0 0 1 ]
|
||||
[1 1 1 1 1 1 1 1 1 1 1 ]])
|
||||
|
||||
; ### Texture Information ###
|
||||
(var walls [])
|
||||
(var wall-textures (love.filesystem.getDirectoryItems "textures/walls"))
|
||||
(var wall-textures (love.filesystem.getDirectoryItems "assets/textures/walls"))
|
||||
(var (tex-height tex-width) (values 64 64))
|
||||
|
||||
(var skybox [])
|
||||
(var skybox-textures (love.filesystem.getDirectoryItems "assets/textures/skybox"))
|
||||
|
||||
(each [_ v (ipairs wall-textures)]
|
||||
(local wall {})
|
||||
(tset wall :t (love.graphics.newImage (.. "textures/walls/" v)))
|
||||
(tset wall :t (love.graphics.newImage (.. "assets/textures/walls/" v)))
|
||||
(tset wall :w (love.graphics.getWidth (. wall :t)))
|
||||
(tset wall :h (love.graphics.getHeight (. wall :t)))
|
||||
(table.insert walls wall))
|
||||
|
||||
(each [_ v (ipairs skybox-textures)]
|
||||
(local skyb {})
|
||||
(tset skyb :t (love.graphics.newImage (.. "assets/textures/skybox/" v)))
|
||||
(tset skyb :w (love.graphics.getWidth (. skyb :t)))
|
||||
(tset skyb :h (love.graphics.getHeight (. skyb :t)))
|
||||
(table.insert skybox skyb))
|
||||
|
||||
; ### "Player" variables ###
|
||||
(var (posx posy) (values 4.0 4.0)) ; Initial map position
|
||||
(var (dirx diry) (values -1.0 0.0)) ; Initial direction vector
|
||||
(var (planex planey) (values 0 0.80)) ; Camera plane
|
||||
(var (planex planey) (values 0 0.66)) ; Camera plane
|
||||
|
||||
; ### Offset experimentation ###
|
||||
(var (offst-x offst-y) (values 0 0))
|
||||
|
||||
{
|
||||
:draw (fn love.draw []
|
||||
; Mouse-Look
|
||||
(love.graphics.translate offst-x offst-y)
|
||||
|
||||
; "Skybox"
|
||||
; Draw a big thing before everything else
|
||||
; (love.graphics.draw (. skybox 1 :t) -20 -20)
|
||||
|
||||
; CEILING/FLOOR CASTING
|
||||
(var cf-f-tex-num (. walls 7))
|
||||
(var cf-c-tex-num (. walls 6))
|
||||
(var floor-texel (love.graphics.newQuad 0 0 1 1 (. cf-f-tex-num :w) (. cf-f-tex-num :h)))
|
||||
(for [i (/ screen-height 2) screen-height]
|
||||
; Set ray-dir for left-most (i = 0) and right-most (i = screen-width) rays
|
||||
(var (cf-ray-dir-x0 cf-ray-dir-y0) (values (- dirx planex) (- diry planey)))
|
||||
(var (cf-ray-dir-x1 cf-ray-dir-y1) (values (+ dirx planex) (+ diry planey)))
|
||||
|
||||
; Current y position compared to horizon
|
||||
(var cf-p (math.floor (/ (- i screen-height) 2)))
|
||||
|
||||
; Vertical position of the camera
|
||||
(var cf-pos-z (* 0.5 screen-height))
|
||||
|
||||
; Horizontal distance from camera to floor for current row
|
||||
(var cf-row-distance (/ cf-pos-z cf-p))
|
||||
|
||||
; Calculate step vectors
|
||||
(var cf-floor-step-x (/ (* cf-row-distance (- cf-ray-dir-x1 cf-ray-dir-x0)) screen-width))
|
||||
(var cf-floor-step-y (/ (* cf-row-distance (- cf-ray-dir-y1 cf-ray-dir-y0)) screen-width))
|
||||
|
||||
; Coordinates of left-most column, updated stepping to the right
|
||||
(var (cf-floor-x cf-floor-y) (values (+ posx (* cf-row-distance cf-ray-dir-x0))
|
||||
(+ posy (* cf-row-distance cf-ray-dir-y0))))
|
||||
|
||||
; Draw floor and ceiling
|
||||
(for [j 0 screen-width]
|
||||
; Get cell
|
||||
(var (cf-cell-x cf-cell-y) (values (math.floor cf-floor-x) (math.floor cf-floor-y)))
|
||||
|
||||
; Get texture coordinate from fractional part
|
||||
; CPP Code: wtf is the & doing there?
|
||||
; (var (cf-tx cf-ty) (values (math.floor (% (* tex-width (- cf-floor-x cf-cell-x)) tex-width))
|
||||
; (math.floor (% (* tex-height (- cf-floor-y cf-cell-y)) tex-height))))
|
||||
(var (cf-tx cf-ty) (values (math.floor (* tex-width (- cf-floor-x cf-cell-x)))
|
||||
(math.floor (* tex-height (- cf-floor-y cf-cell-y)))))
|
||||
|
||||
;; Draw the texture
|
||||
; (love.graphics.draw (. tex-num :t)
|
||||
; (love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
|
||||
; i draw-start 0 1 (/ line-height (. tex-num :h)))
|
||||
; (love.graphics.draw (. cf-f-tex-num :t)
|
||||
; floor-texel
|
||||
; j i 0 1 1)
|
||||
|
||||
; Step
|
||||
(set cf-floor-x (+ cf-floor-x cf-floor-step-x))
|
||||
(set cf-floor-y (+ cf-floor-y cf-floor-step-y))
|
||||
)
|
||||
)
|
||||
; WALL CASTING
|
||||
(for [i 0 screen-width]
|
||||
; Calculate ray position and direction
|
||||
; Originals, giving a fish-eye lens effect:
|
||||
; (var camerax (/ (* 2 i) (- screen-width 1)))
|
||||
; (var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
(var camerax (/ (* 2 i) (- screen-width 1)))
|
||||
(var camerax (- (/ (* 2 i) (- screen-width 1)) 1.0))
|
||||
(var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
|
||||
; Which map square we're in
|
||||
|
@ -55,6 +127,9 @@
|
|||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-y ray-dir-y) (* ray-dir-x ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-x ray-dir-x) (* ray-dir-y ray-dir-y))))))
|
||||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-y ray-dir-x) (/ ray-dir-y ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-x ray-dir-y) (/ ray-dir-x ray-dir-y))))))
|
||||
(var (delta-dist-x delta-dist-y) (values (math.abs (/ 1 ray-dir-x)) (math.abs (/ 1 ray-dir-y))))
|
||||
|
||||
(var perp-wall-dist 0)
|
||||
|
@ -109,24 +184,6 @@
|
|||
(var draw-end (+ (/ line-height 2) (/ screen-height 2)))
|
||||
(if (>= draw-end screen-height) (set draw-end (- screen-height 1)))
|
||||
|
||||
; Draw wall slice
|
||||
; (var color [1 1 1 1])
|
||||
; (case (. map mapx mapy)
|
||||
; 1 (set color [1 1 1 1])
|
||||
; 2 (set color [1 0 0 1])
|
||||
; 3 (set color [0 1 0 1])
|
||||
; 4 (set color [0 0 1 1])
|
||||
; )
|
||||
|
||||
; (when (= side 1)
|
||||
; (tset color 1 (/ (. color 1) 2))
|
||||
; (tset color 2 (/ (. color 2) 2))
|
||||
; (tset color 3 (/ (. color 3) 2)))
|
||||
|
||||
; (love.graphics.setColor color)
|
||||
; (love.graphics.line i draw-start i draw-end)
|
||||
; (love.graphics.setColor 1 1 1)
|
||||
|
||||
; Draw textured wall
|
||||
;; Choose texture
|
||||
(var tex-num (. walls (. map mapx mapy)))
|
||||
|
@ -140,34 +197,64 @@
|
|||
(var tex-x (math.floor (* wallx (. tex-num :w))))
|
||||
(if (and (= side 0) (> ray-dir-x 0)) (set tex-x (- (. tex-num :w) tex-x 1)))
|
||||
(if (and (= side 1) (< ray-dir-y 0)) (set tex-x (- (. tex-num :w) tex-x 1)))
|
||||
;; Draw the texture
|
||||
;; Draw the texture, accounting for "fog"
|
||||
(var fog-dist (- 1 (/ perp-wall-dist 7)))
|
||||
(love.graphics.setColor 1 1 1 fog-dist)
|
||||
(love.graphics.draw (. tex-num :t)
|
||||
(love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
|
||||
i draw-start 0 1 (/ line-height (. tex-num :h)))
|
||||
(when (= (. map mapx mapy) 3)
|
||||
(for [q 1 3]
|
||||
(set fog-dist (- fog-dist 0.1))
|
||||
(love.graphics.setColor 1 1 1 fog-dist)
|
||||
(love.graphics.draw (. tex-num :t)
|
||||
(love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
|
||||
i (- draw-start (* line-height q)) 0 1 (/ line-height (. tex-num :h)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(overlay.overlay)
|
||||
(overlay.overlay offst-x offst-y)
|
||||
)
|
||||
|
||||
:update (fn update [dt]
|
||||
(var mvspeed (* dt 3.0))
|
||||
(var rtspeed (* dt 1.0))
|
||||
|
||||
(when (love.keyboard.isDown "up")
|
||||
(when (love.keyboard.isDown "e")
|
||||
(when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy)))
|
||||
(set posx (+ (* mvspeed dirx) posx)))
|
||||
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy))))
|
||||
(set posy (+ (* mvspeed diry) posy)))
|
||||
)
|
||||
|
||||
(when (love.keyboard.isDown "down")
|
||||
(when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy)))
|
||||
(when (love.keyboard.isDown "d")
|
||||
(when (= 0 (. map (math.floor (- posx (* mvspeed dirx))) (math.floor posy)))
|
||||
(set posx (- posx (* mvspeed dirx))))
|
||||
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy))))
|
||||
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed diry)))))
|
||||
(set posy (- posy (* mvspeed diry))))
|
||||
)
|
||||
|
||||
(when (love.keyboard.isDown "right")
|
||||
(when (love.keyboard.isDown "s")
|
||||
(var strafe-x (- (* dirx (math.cos (- (/ math.pi 2)))) (* diry (math.sin (- (/ math.pi 2))))))
|
||||
(var strafe-y (+ (* dirx (math.sin (- (/ math.pi 2)))) (* diry (math.cos (- (/ math.pi 2))))))
|
||||
|
||||
(when (= 0 (. map (math.floor (- posx (* mvspeed strafe-x))) (math.floor posy)))
|
||||
(set posx (- posx (* mvspeed strafe-x))))
|
||||
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed strafe-y)))))
|
||||
(set posy (- posy (* mvspeed strafe-y))))
|
||||
)
|
||||
|
||||
(when (love.keyboard.isDown "f")
|
||||
(var strafe-x (- (* dirx (math.cos (+ (/ math.pi 2)))) (* diry (math.sin (+ (/ math.pi 2))))))
|
||||
(var strafe-y (+ (* dirx (math.sin (+ (/ math.pi 2)))) (* diry (math.cos (+ (/ math.pi 2))))))
|
||||
|
||||
(when (= 0 (. map (math.floor (- posx (* mvspeed strafe-x))) (math.floor posy)))
|
||||
(set posx (- posx (* mvspeed strafe-x))))
|
||||
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed strafe-y)))))
|
||||
(set posy (- posy (* mvspeed strafe-y))))
|
||||
)
|
||||
|
||||
(when (love.keyboard.isDown "r")
|
||||
(var old-dirx dirx)
|
||||
(set dirx (- (* dirx (math.cos (- rtspeed))) (* diry (math.sin (- rtspeed)))))
|
||||
(set diry (+ (* old-dirx (math.sin (- rtspeed))) (* diry (math.cos (- rtspeed)))))
|
||||
|
@ -176,7 +263,7 @@
|
|||
(set planey (+ (* old-planex (math.sin (- rtspeed))) (* planey (math.cos (- rtspeed)))))
|
||||
)
|
||||
|
||||
(when (love.keyboard.isDown "left")
|
||||
(when (love.keyboard.isDown "w")
|
||||
(var old-dirx dirx)
|
||||
(set dirx (- (* dirx (math.cos rtspeed)) (* diry (math.sin rtspeed))))
|
||||
(set diry (+ (* old-dirx (math.sin rtspeed)) (* diry (math.cos rtspeed))))
|
||||
|
@ -186,21 +273,21 @@
|
|||
)
|
||||
)
|
||||
|
||||
:mousemoved (fn mousemoved [x y dx dy]
|
||||
(var rtspeed (* dx -0.001))
|
||||
(var yawspeed (* dy -0.5))
|
||||
|
||||
(var old-dirx dirx)
|
||||
(set dirx (- (* dirx (math.cos rtspeed)) (* diry (math.sin rtspeed))))
|
||||
(set diry (+ (* old-dirx (math.sin rtspeed)) (* diry (math.cos rtspeed))))
|
||||
(var old-planex planex)
|
||||
(set planex (- (* planex (math.cos rtspeed)) (* planey (math.sin rtspeed))))
|
||||
(set planey (+ (* old-planex (math.sin rtspeed)) (* planey (math.cos rtspeed))))
|
||||
|
||||
(set offst-y (+ offst-y yawspeed))
|
||||
)
|
||||
|
||||
:keypressed (fn keypressed [k]
|
||||
(when (= k "x") (love.event.quit))
|
||||
)
|
||||
}
|
||||
|
||||
; (fn move-player [x]
|
||||
; (let [new-x (+ posx (* (math.cos dirx)) x) new-y (+ posy (* (math.sin diry)) x)]
|
||||
; (when (= (. map (math.floor new-y) (math.floor new-x)) 0)
|
||||
; (set posx new-x) (set posy new-y))))
|
||||
|
||||
; (fn rotate-player [d]
|
||||
; (local rotation-speed 1)
|
||||
; (var old-dirx dirx)
|
||||
; (set dirx (- (* dirx (math.cos (* d rotation-speed))) (* diry (math.sin (* d rotation-speed)))))
|
||||
; (set diry (+ (* old-dirx (math.sin (* d rotation-speed))) (* diry (math.cos (* d rotation-speed)))))
|
||||
; (var old-planex planex)
|
||||
; (set planex (- (* planex (math.cos (* d rotation-speed))) (* planey (math.sin (* d rotation-speed)))))
|
||||
; (set planey (+ (* old-planex (math.sin (* d rotation-speed))) (* planey (math.cos (* d rotation-speed))))))
|
||||
|
|
57
reference/lodev/lodev_floor-casting-example.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
//FLOOR CASTING
|
||||
for(int y = 0; y < h; y++)
|
||||
{
|
||||
// rayDir for leftmost ray (x = 0) and rightmost ray (x = w)
|
||||
float rayDirX0 = dirX - planeX;
|
||||
float rayDirY0 = dirY - planeY;
|
||||
float rayDirX1 = dirX + planeX;
|
||||
float rayDirY1 = dirY + planeY;
|
||||
|
||||
// Current y position compared to the center of the screen (the horizon)
|
||||
int p = y - screenHeight / 2;
|
||||
|
||||
// Vertical position of the camera.
|
||||
float posZ = 0.5 * screenHeight;
|
||||
|
||||
// Horizontal distance from the camera to the floor for the current row.
|
||||
// 0.5 is the z position exactly in the middle between floor and ceiling.
|
||||
float rowDistance = posZ / p;
|
||||
|
||||
// calculate the real world step vector we have to add for each x (parallel to camera plane)
|
||||
// adding step by step avoids multiplications with a weight in the inner loop
|
||||
float floorStepX = rowDistance * (rayDirX1 - rayDirX0) / screenWidth;
|
||||
float floorStepY = rowDistance * (rayDirY1 - rayDirY0) / screenWidth;
|
||||
|
||||
// real world coordinates of the leftmost column. This will be updated as we step to the right.
|
||||
float floorX = posX + rowDistance * rayDirX0;
|
||||
float floorY = posY + rowDistance * rayDirY0;
|
||||
|
||||
for(int x = 0; x < screenWidth; ++x)
|
||||
{
|
||||
// the cell coord is simply got from the integer parts of floorX and floorY
|
||||
int cellX = (int)(floorX);
|
||||
int cellY = (int)(floorY);
|
||||
|
||||
// get the texture coordinate from the fractional part
|
||||
int tx = (int)(texWidth * (floorX - cellX)) & (texWidth - 1);
|
||||
int ty = (int)(texHeight * (floorY - cellY)) & (texHeight - 1);
|
||||
|
||||
floorX += floorStepX;
|
||||
floorY += floorStepY;
|
||||
|
||||
// choose texture and draw the pixel
|
||||
int floorTexture = 3;
|
||||
int ceilingTexture = 6;
|
||||
Uint32 color;
|
||||
|
||||
// floor
|
||||
color = texture[floorTexture][texWidth * ty + tx];
|
||||
color = (color >> 1) & 8355711; // make a bit darker
|
||||
buffer[y][x] = color;
|
||||
|
||||
//ceiling (symmetrical, at screenHeight - y - 1 instead of y)
|
||||
color = texture[ceilingTexture][texWidth * ty + tx];
|
||||
color = (color >> 1) & 8355711; // make a bit darker
|
||||
buffer[screenHeight - y - 1][x] = color;
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
9
wrap.fnl
|
@ -4,6 +4,8 @@
|
|||
(love.graphics.newCanvas w h)))
|
||||
|
||||
(var scale 1)
|
||||
(love.mouse.setGrabbed true)
|
||||
(love.mouse.setRelativeMode true)
|
||||
|
||||
;; set the first mode
|
||||
(var (mode mode-name) nil)
|
||||
|
@ -18,8 +20,8 @@
|
|||
; THIS IS WHERE WE SET THE START MODE
|
||||
; ###################################
|
||||
; (set-mode :ray-cast-vectors)
|
||||
(set-mode :mode-intro)
|
||||
; (set-mode :raycaster)
|
||||
; (set-mode :mode-intro)
|
||||
(set-mode :raycaster)
|
||||
; ###################################
|
||||
(canvas:setFilter "nearest" "nearest")
|
||||
(when (~= :web (. args 1)) (repl.start)))
|
||||
|
@ -42,6 +44,9 @@
|
|||
(when mode.update
|
||||
(safely #(mode.update dt set-mode))))
|
||||
|
||||
(fn love.mousemoved [x y dx dy istouch]
|
||||
(safely #(mode.mousemoved x y dx dy istouch)))
|
||||
|
||||
(fn love.keypressed [key]
|
||||
(if (and (love.keyboard.isDown "lctrl" "rctrl" "capslock") (= key "q"))
|
||||
(love.event.quit)
|
||||
|
|