Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --antiCaster
- --by Cumred_Snektron for SDL2, ported by Ivoah
- -- Some Lua optimizations by Adriweb
- local mathsin, mathcos, mathsqrt, mathfloor = math.sin, math.cos, math.sqrt, math.floor
- function pow(a, b) return a^b end
- --vec2.c
- function vec2_add(v0, v1, out)
- return {x = v0.x + v1.x, y = v0.y + v1.y}
- end
- function vec2_addscale(v0, v1, scale)
- return {x = v0.x + v1.x*scale, y = v0.y + v1.y*scale}
- end
- function vec2_normalize(v0)
- length = mathsqrt(v0.x*v0.x + v0.y*v0.y)
- return {x = v0.x/length, y = v0.y/length}
- end
- function vec2_rotate(v0, angle)
- return {x = v0.x * mathcos(-angle) - v0.y * mathsin(-angle), y = v0.x * mathsin(-angle) + v0.y * mathcos(-angle)}
- end
- --map.c
- function map_init(width, height, defaultblock)
- map = {width = width, height = height, map = {}}
- for i=0, width*height - 1 do
- map.map[i] = defaultblock
- end
- return map
- end
- function map_setblockat(map, x, y, block)
- if x >= 0 and x < map.width and y >= 0 and y < map.height then
- map.map[y*map.width+x] = block
- end
- end
- function map_getblockat(map, x, y)
- if (x >= 0 and x < map.width and y >= 0 and y < map.height) then
- return map.map[y*map.width+x]
- end
- return false
- end
- --game.c
- player_movespeed = 0.5
- player_rotspeed = 0.007
- p = {}
- m = {}
- function _init()
- p.pos = {x = 5, y = 5}
- p.dir = {x = -1., y = 0.}
- defaultwall = {type = 0, spacex = 1., spacey = 1.}
- m = map_init(20, 20, defaultwall)
- bluewall = {type = 1, spacex = 1., spacey = 1.}
- greenwall = {type = 2, spacex = 1., spacey = 1.}
- redwall = {type = 3, spacex = 1., spacey = 1.}
- compressedwall = {type = 0, spacex = 1., spacey = .1}
- for i=0, 20 - 1 do
- map_setblockat(m, i, 0, bluewall)
- map_setblockat(m, i, 19, bluewall)
- map_setblockat(m, 0, i, bluewall)
- map_setblockat(m, 19, i, bluewall)
- end
- map_setblockat(m, 10, 10, greenwall)
- map_setblockat(m, 11, 10, compressedwall)
- map_setblockat(m, 12, 10, compressedwall)
- map_setblockat(m, 13, 10, compressedwall)
- map_setblockat(m, 14, 10, greenwall)
- map_setblockat(m, 11, 16, redwall)
- end
- function on.arrowKey(key)
- b = map_getblockat(m, mathfloor(p.pos.x), mathfloor(p.pos.y))
- x = 0
- if key == "left" then x = -5
- elseif key == "right" then x = 5 end
- p.dir = vec2_rotate(p.dir, x*player_rotspeed)
- dir = p.dir
- dirx = {x = dir.y, y = -dir.x}
- if (b) then
- dir.x = dir.x*b.spacex
- dir.y = dir.y*b.spacey
- dirx.x = dirx.x*b.spacex
- dirx.y = dirx.y*b.spacey
- end
- if key == "up" then
- p.pos = vec2_addscale(p.pos, dir, player_movespeed)
- elseif key == "down" then
- p.pos = vec2_addscale(p.pos, dir, -player_movespeed)
- --elseif key == "left" then
- -- p.pos = vec2_addscale(p.pos, dirx, -player_movespeed)
- --elseif key == "right" then
- -- p.pos = vec2_addscale(p.pos, dirx, player_movespeed)
- end
- platform.window:invalidate()
- end
- function sign(x)
- return (x<0 and -1) or 1
- end
- function tri(a, b, c)
- if a then
- return b
- else
- return c
- end
- end
- function nexthit(r)
- hb = map_getblockat(m, r.mapx, r.mapy)
- s = tri(hb, {x = hb.spacex, y = hb.spacey}, {x = 1, y = 1})
- dir = r.dir
- r.dir.x = r.dir.x*s.x
- r.dir.y = r.dir.y*s.y
- r.dir = vec2_normalize(r.dir)
- deltadistx = mathsqrt(1 + (r.dir.y * r.dir.y) / (r.dir.x * r.dir.x))
- deltadisty = mathsqrt(1 + (r.dir.x * r.dir.x) / (r.dir.y * r.dir.y))
- stepx = sign(r.dir.x)
- stepy = sign(r.dir.y)
- sidedistx = tri(stepx < 0, (r.orig.x - r.mapx), (r.mapx + 1.0 - r.orig.x)) * deltadistx
- sidedisty = tri(stepy < 0, (r.orig.y - r.mapy), (r.mapy + 1.0 - r.orig.y)) * deltadisty
- d = {x = 0, y = 0}
- if (sidedistx < sidedisty) then
- d.x = r.dir.x * sidedistx
- d.y = r.dir.y * sidedistx
- r.mapx = r.mapx + stepx
- r.side = 0
- else
- d.x = r.dir.x * sidedisty
- d.y = r.dir.y * sidedisty
- r.mapy = r.mapy + stepy
- r.side = 1
- end
- r.orig.x = r.orig.x + d.x
- r.orig.y = r.orig.y + d.y
- r.distance = r.distance + mathsqrt(pow(d.x/s.x, 2) + pow(d.y/s.y, 2))
- r.dir = dir
- return r
- end
- -- cast the ray.
- function cast(r)
- hit = {}
- hit.hit = false
- r.mapx = mathfloor(r.orig.x)
- r.mapy = mathfloor(r.orig.y)
- r.distance = 0
- for i=0, 99 do
- r = nexthit(r)
- hb = map_getblockat(m, r.mapx, r.mapy)
- if hb and hb.type > 0 then
- hit.distance = r.distance
- hit.hitblock = hb
- hit.side = r.side
- hit.hit = true
- hit.point = {x = r.orig.x, y = r.orig.y}
- return hit
- end
- end
- return hit
- end
- function vline(gc, x, y0, y1, c)
- gc:setColorRGB(c)
- gc:drawLine(x, y0, x, y1)
- end
- function on.resize(w, h)
- pww, pwh = w, h
- platform.window:setBackgroundColor(0)
- end
- function on.paint(gc)
- -- If running on OS 3.9, you can just call the platform.window:setBackgroundColor(0) in on.resize.
- -- gc:setColorRGB(0,0,0)
- -- gc:fillRect(0, 0, pww, pwh)
- plane = vec2_normalize({x = p.dir.y*0.66, y = -p.dir.x*0.66})
- for x=0, pww-1 do
- cam = 2*x/pww - 1
- r = {}
- r.orig = {x = p.pos.x, y = p.pos.y}
- r.dir = {x = p.dir.x + plane.x * cam, y = p.dir.y + plane.y * cam}
- hit = cast(r)
- if hit.hit then
- dist = hit.distance/mathsqrt(1+cam*cam)
- lineh = mathfloor(pwh/dist)
- if hit.hitblock.type == 1 then
- vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0x0000FF - hit.side * 0x000022)
- elseif hit.hitblock.type == 2 then
- vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0x00FF00 - hit.side * 0x002200)
- else
- vline(gc, x, pwh/2 - lineh/2, pwh/2 + lineh/2, 0xFF0000 - hit.side * 0x220000)
- end
- end
- end
- end
- _init()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement