Created
April 7, 2019 20:50
-
-
Save felipetavares/fe09ee7411262cdace98203059475a39 to your computer and use it in GitHub Desktop.
Weird-ass Pong
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function vec_(x, y) | |
return { x = x, y = y } | |
end | |
function add(a, b) | |
return vec_(a.x+b.x, a.y+b.y) | |
end | |
function sub(a, b) | |
return vec_(a.x-b.x, a.y-b.y) | |
end | |
function mul(v, s) | |
return vec_(v.x*s, v.y*s) | |
end | |
function cross(a, b) | |
return a.x*b.y - b.x*a.y; | |
end | |
function dot(a, b) | |
return a.x*b.x + a.y*b.y; | |
end | |
function inverse(v) | |
return vec_(-v.x, -v.y) | |
end | |
function length2(v) | |
return v.x*v.x+v.y*v.y | |
end | |
function length(v) | |
return math.sqrt(length2(v)) | |
end | |
function rot(v, a) | |
local s = math.sin(a) | |
local c = math.cos(a) | |
return vec_(v.x*c - v.y*s, | |
v.x*s + v.y*c) | |
end | |
function normalized(v) | |
local l = length(v) | |
return vec_(v.x/l, v.y/l) | |
end | |
function perpendicular(v) | |
return vec_(v.y, -v.x) | |
end | |
function line_(origin, segment, angular_velocity) | |
return { o = origin, s = segment, a = 0, w = angular_velocity } | |
end | |
function ball_(origin, velocity) | |
return { o = origin, v = velocity } | |
end | |
function project(a, b) | |
local intensity = dot(a, b) | |
return mul(b, intensity), intensity | |
end | |
function distance(line_segment, point) | |
local distance = sub(line_segment.o, point) | |
local distance_end = add(distance, line_segment.s) | |
local normal = normalized(perpendicular(line_segment.s)) | |
local side_a = cross(normal, distance) | |
local side_b = cross(normal, distance_end) | |
if side_b < 0 then | |
return distance_end, inverse(normalized(distance_end)) | |
end | |
if side_a > 0 then | |
return distance, inverse(normalized(distance)) | |
end | |
local min_distance = project(distance, normal) | |
return min_distance, normal | |
end | |
local lines = {} | |
local lines_n = 6 | |
local point = nil | |
local prev_point = nil | |
for i=1,lines_n+1 do | |
prev_point = point | |
point = add(rot(vec_(0, 119), math.pi*2/lines_n*(i-1)), mul(vec_(320, 240), 0.5)) | |
if i >= 2 then | |
local p1 = point | |
local p2 = sub(prev_point, point) | |
local w = (math.random()-0.5)*2 | |
table.insert(lines, line_(p1, p2, w)) | |
end | |
end | |
local ball = ball_(mul(vec_(320, 240), 0.5), vec_(150, 150)) | |
local radius = 2 | |
function draw() | |
clr(0) | |
for _, ln in ipairs(lines) do | |
local ds, n = distance(ln, ball.o) | |
local d = length(ds) | |
-- Draw distance | |
--line(ball.o.x, ball.o.y, ball.o.x+ds.x, ball.o.y+ds.y, 2) | |
end | |
circf(ball.o.x, ball.o.y, radius, math.random(2)+13) | |
for _, ln in ipairs(lines) do | |
line(ln.o.x, ln.o.y, ln.o.x+ln.s.x, ln.o.y+ln.s.y, 8) | |
end | |
end | |
function update(dt) | |
-- Collision | |
local solved = false | |
local counter = 4 | |
while counter > 0 do | |
solved = true | |
counter -= 1 | |
for _, ln in ipairs(lines) do | |
local ds, n = distance(ln, ball.o) | |
local d = length(ds)-radius | |
ds = mul(normalized(ds), d) | |
local movement_towards, amount = project(mul(ball.v, dt), normalized(ds)) | |
if amount > d then | |
ball.v = add(ball.v, inverse(mul(project(ball.v, n), 2))) | |
solved = false | |
end | |
end | |
end | |
ball.o.x += ball.v.x*dt | |
ball.o.y += ball.v.y*dt | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment