From cdc4cacbc8d3c5721c078d76f69a0327c3a1997a Mon Sep 17 00:00:00 2001 From: Quinn Date: Sun, 26 Dec 2021 20:27:32 -0800 Subject: [PATCH] Converted VectorTest into project --- main.lua | 170 +++++++++++++++++++++ picosync.json | 7 + prototypes/ballphys.p8 | 142 ++++++++++++++++++ prototypes/phystest.p8 | 154 +++++++++++++++++++ prototypes/untitled.p8 | 142 ++++++++++++++++++ prototypes/vectortest.p8 | 310 +++++++++++++++++++++++++++++++++++++++ qphys.p8 | 181 +++++++++++++++++++++++ sprites.png | Bin 0 -> 217 bytes 8 files changed, 1106 insertions(+) create mode 100644 main.lua create mode 100644 picosync.json create mode 100644 prototypes/ballphys.p8 create mode 100644 prototypes/phystest.p8 create mode 100644 prototypes/untitled.p8 create mode 100644 prototypes/vectortest.p8 create mode 100644 qphys.p8 create mode 100644 sprites.png diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..69d9339 --- /dev/null +++ b/main.lua @@ -0,0 +1,170 @@ +ball_count = 16 +ball_radius = 5 + +function _init() + balls = {} + collisions = {} + for i=1,ball_count do + add(balls, ball:new({ + pos=vec2:new(rnd(127),rnd(127)), + vel=vec2:new(rnd(2)-1,rnd(2)-1):normal(), + col=rnd(15)+1 + })) + end +end + +function _update60() + for b in all(balls) do + b:move() + b:edge_bounce() + end + for b in all(balls) do + b:check_collisions(balls) + end + handle_collisions(balls) + collisions = {} +end + +function _draw() + cls() + for b in all(balls) do + b:draw() + end +end + +function handle_collisions() + for source,colls in pairs(collisions) do + for target,diff in pairs(colls) do + local n = diff:normal() + local steps = 0 + local rewind = 0 + local s_xpoint = source.pos + local t_xpoint = target.pos + repeat + steps += 1 + rewind += 0.1 * steps + s_xpoint = source.pos - source.vel * rewind + t_xpoint = target.pos - target.vel * rewind + until (s_xpoint - t_xpoint):mag() >= source.rad + target.rad + source.vel = collision_vel(s_xpoint, source.vel, t_xpoint, target.vel) + target.vel = collision_vel(t_xpoint, target.vel, s_xpoint, source.vel) + source.pos = s_xpoint + source.vel * rewind + target.pos = t_xpoint + target.vel * rewind + end + end +end + +vec2 = { + x = 0, + y = 0, + + mag = function(self) + return sqrt(self.x^2+self.y^2) + end, + + dot = function(self,v) + return self.x * v.x + self.y * v.y + end, + + normal = function(self) + local mag = self:mag() + return vec2:new(self.x/mag, self.y/mag) + end, + + bounce = function(self, n, b) + local b = b or 1 + local n = n:normal() + return (n * -2 * self:dot(n) + self) * b + end +} + +vec2.__eq = function(v1,v2) return v1.x == v2.x and v1.y == v2.y end +vec2.__add = function(v1,v2) return vec2:new(v1.x+v2.x,v1.y+v2.y) end +vec2.__sub = function(v1,v2) return vec2:new(v1.x-v2.x,v1.y-v2.y) end +vec2.__mul = function(v,s) return vec2:new(v.x*s,v.y*s) end +vec2.__div = function(v,s) return vec2:new(v.x/s,v.y/s) end +vec2.__unm = function(v) return vec2:new(-v.x,-v.y) end +vec2.__tostring = function(v) return "{x: "..v.x..",y: "..v.y.."}" end +vec2.__index = vec2 + +function vec2:new(x,y) + local x = x or 0 + local y = y or 0 + local o = {x=x,y=y} + setmetatable(o, self) + o.__index = self + return o +end + +function vec2:print_debug(v) + local v = v or vec2:new(0,1) + print("vec: "..vec2.__tostring(self)) + print("mag: "..self:mag()) + print("dot: "..self:dot(v)) + print("normal: "..vec2.__tostring(self:normal())) + print("bounce: "..vec2.__tostring(self:bounce(v))) + print("inv: "..vec2.__tostring(-self)) +end + +ball = { + __count = 0, + id = nil, + pos = vec2:new(0,0), + vel = vec2:new(0,0), + rad = ball_radius, + col = 7, + + draw = function(self) + circfill(self.pos.x, self.pos.y, self.rad, self.col) + end, + + move = function(self) + self.pos += self.vel + end, + + edge_bounce = function(self) + edge_normal = vec2:new() + for axis in all({"x","y"}) do + val = self.pos[axis] + if (val - self.rad < 0) then + self.pos[axis] = self.rad + edge_normal[axis] = 1 + elseif (val + self.rad > 127) then + self.pos[axis] = 127 - self.rad + edge_normal[axis] = -1 + end + end + if (edge_normal.x != 0 or edge_normal.y != 0) then + self.vel = self.vel:bounce(edge_normal) + end + end, + + check_collisions = function(self, balls) + for b in all(balls) do + if (b.id != self.id and (collisions[b] == nil or collisions[b][self] == nil)) then + local diff = self.pos - b.pos + if ((diff):mag() < self.rad + b.rad) then + collisions[self] = collisions[self] or {} + collisions[self][b] = diff + end + end + end + end, +} +ball.__index = ball + +function ball:new(o) + ball.__count += 1 + local o = o or {} + o.id = ball.__count + o.col = o.id % 16 + setmetatable(o, self) + o.__index = self + return o +end + +function collision_vel(x1,v1,x2,v2) + local x_diff = x1 - x2 + local v_diff = v1 - v2 + return v1 - x_diff * v_diff:dot(x_diff) / x_diff:mag()^2 +end diff --git a/picosync.json b/picosync.json new file mode 100644 index 0000000..38a743f --- /dev/null +++ b/picosync.json @@ -0,0 +1,7 @@ +{ + "picoFile":"qphys.p8", + + "sources":[ + "main.lua" + ] +} diff --git a/prototypes/ballphys.p8 b/prototypes/ballphys.p8 new file mode 100644 index 0000000..0185603 --- /dev/null +++ b/prototypes/ballphys.p8 @@ -0,0 +1,142 @@ +pico-8 cartridge // http://www.pico-8.com +version 34 +__lua__ +pi=3.14159 +balls = 8 +ball_rad = 4 + +function _init() + bullets = {} + collisions = {} + for i=1,balls do + bullets[i] = {id=i,coll=false,pos={x=rnd(127),y=rnd(127)},vel=normalize{x=rnd()-0.5,y=rnd()-0.5}} + end +end + +function _update60() + for b in all(bullets) do + //grav(b,5) + move(b) + edgebounce(b) + collide(b) + end +end + +function magnitude(v) + return sqrt(v.x^2 + v.y^2) +end + +function normalize(v) + length = magnitude(v) + return {x=v.x/length,y=v.y/length} +end + +function dot(v1,v2) + return v1.x*v2.x + v1.y*v2.y +end + +function reflect(v,n) + n = normalize(n) + return vsub(scale(scale(n,dot(v,n)),2),v) +end + +function bounce(v,n) + n = normalize(n) + return vadd(scale(scale(n,dot(v,n)),-2),v) +end + +function vadd(v1,v2) + return {x=v1.x+v2.x,y=v1.y+v2.y} +end + +function vsub(v1,v2) + return {x=v1.x-v2.x,y=v1.y-v2.y} +end + +function scale(v,s) + return {x=v.x*s, y=v.y*s} +end + +function vinv(v) + return {x=-v.x,y=-v.y} +end + +function collide(b) + for t in all(bullets) do + if t.id != b.id then + diff = vsub(b.pos,t.pos) + ndif = normalize(diff) + midp = scale(vadd(b.pos,t.pos),0.5) + if (magnitude(diff) < ball_rad*2) then + b.vel = bounce(b.vel,ndif) + t.vel = bounce(t.vel,vinv(ndif)) + b.pos = vadd(midp,scale(ndif,ball_rad+0.5)) + t.pos = vsub(midp,scale(ndif,ball_rad+0.5)) + add_collision(midp) + end + end + end +end + +function add_collision(v) + add(collisions,v) + if(#collisions > 10) then + del(collisions, collisions[1]) + end +end + +function move(b) + b.pos.x += b.vel.x + b.pos.y += b.vel.y +end + +function chaos(b, rate) + b.vel.x += rnd(rate) - rate/2 + b.vel.y += rnd(rate) - rate/2 +end + +function edgebounce(b) + pos = b.pos + n = {x=0,y=0} + if (pos.x < 0) then + b.pos.x = -pos.x + n.x = 1 + elseif (pos.x > 127) then + b.pos.x = 127 - (pos.x - 127) + n.x = -1 + end + if (pos.y < 0) then + b.pos.y = -pos.y + n.y = 1 + elseif (pos.y > 127) then + b.pos.y = 127 - (pos.y - 127) + n.y = -1 + end + if (n.x != 0 or n.y != 0) then + n = normalize(n) + b.vel = bounce(b.vel, n) + end +end + +function grav(b, speed) + b.vel.y += speed/60 +end + +function _draw() + cls() + for c in all(collisions) do + circfill(c.x, c.y, 1, 10) + end + for b in all(bullets) do + circfill(b.pos.x, b.pos.y, ball_rad, 7) + end + //print(bullets[1].vel.x) + //print(bullets[1].vel.y) +end +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/prototypes/phystest.p8 b/prototypes/phystest.p8 new file mode 100644 index 0000000..e81b5c4 --- /dev/null +++ b/prototypes/phystest.p8 @@ -0,0 +1,154 @@ +pico-8 cartridge // http://www.pico-8.com +version 34 +__lua__ +pi=3.14159 +balls = 8 +ball_rad = 4 + +function _init() + bullets = {} + collisions = {} + for i=1,balls do + bullets[i] = {id=i,coll=false,pos={x=rnd(127),y=rnd(127)},vel=normalize{x=rnd()-0.5,y=rnd()-0.5}} + end +end + +function _update60() + for b in all(bullets) do + //grav(b,5) + move(b) + edgebounce(b) + handle_collisions(b) + end +end + +function magnitude(v) + return sqrt(v.x^2 + v.y^2) +end + +function normalize(v) + length = magnitude(v) + return {x=v.x/length,y=v.y/length} +end + +function dot(v1,v2) + return v1.x*v2.x + v1.y*v2.y +end + +function reflect(v,n) + n = normalize(n) + return vsub(scale(scale(n,dot(v,n)),2),v) +end + +function bounce(v,n) + n = normalize(n) + return vadd(vmul(vmul(n,dot(v,n)),-2),v) +end + +function vadd(v1,v2) + return {x=v1.x+v2.x,y=v1.y+v2.y} +end + +function vsub(v1,v2) + return {x=v1.x-v2.x,y=v1.y-v2.y} +end + +function vmul(v,s) + return {x=v.x*s, y=v.y*s} +end + +function vdiv(v,s) + return {x=v.x/s, y=v.y/s} +end + +function vinv(v) + return {x=-v.x,y=-v.y} +end + +function handle_collisions(b) + for t in all(bullets) do + if t.id != b.id then + diff = vsub(b.pos,t.pos) + if (magnitude(diff) < ball_rad*2) then + body_bounce(b,t) + end + end + end +end + +function body_bounce(b1,b2) + diff = vsub(b1.pos,b2.pos) + ndif = normalize(diff) + midp = vmul(vadd(b1.pos,b2.pos),0.5) + + add_collision(midp) + + b1.pos = vadd(midp,vmul(ndif,ball_rad+0.5)) + b2.pos = vsub(midp,vmul(ndif,ball_rad+0.5)) + + b1.vel = vsub(b1.vel,vmul(vsub(b1.pos,b2.pos),dot(vsub(b1.vel,b2.vel),vsub(b1.pos,b2.pos)),magnitude(vsub(b1.pos,b2.pos))^2)) + b2.vel = vsub(b2.vel,vmul(vsub(b2.pos,b1.pos),dot(vsub(b2.vel,b1.vel),vsub(b2.pos,b1.pos)),magnitude(vsub(b2.pos,b1.pos))^2)) +end + +function add_collision(v) + add(collisions,v) + if(#collisions > 10) then + del(collisions, collisions[1]) + end +end + +function move(b) + b.pos.x += b.vel.x + b.pos.y += b.vel.y +end + +function chaos(b, rate) + b.vel.x += rnd(rate) - rate/2 + b.vel.y += rnd(rate) - rate/2 +end + +function edgebounce(b) + pos = b.pos + n = {x=0,y=0} + if (pos.x < 0) then + b.pos.x = -pos.x + n.x = 1 + elseif (pos.x > 127) then + b.pos.x = 127 - (pos.x - 127) + n.x = -1 + end + if (pos.y < 0) then + b.pos.y = -pos.y + n.y = 1 + elseif (pos.y > 127) then + b.pos.y = 127 - (pos.y - 127) + n.y = -1 + end + if (n.x != 0 or n.y != 0) then + n = normalize(n) + b.vel = bounce(b.vel, n) + end +end + +function grav(b, speed) + b.vel.y += speed/60 +end + +function _draw() + cls() + for c in all(collisions) do + circfill(c.x, c.y, 1, 10) + end + for b in all(bullets) do + circfill(b.pos.x, b.pos.y, ball_rad, 7) + end + //print(bullets[1].vel.x) + //print(bullets[1].vel.y) +end +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/prototypes/untitled.p8 b/prototypes/untitled.p8 new file mode 100644 index 0000000..7d8610c --- /dev/null +++ b/prototypes/untitled.p8 @@ -0,0 +1,142 @@ +pico-8 cartridge // http://www.pico-8.com +version 34 +__lua__ +pi=3.14159 +balls = 16 +ball_rad = 4 + +function _init() + bullets = {} + collisions = {} + for i=1,balls do + bullets[i] = {id=i,coll=false,pos={x=rnd(127),y=rnd(127)},vel=normalize{x=rnd()-0.5,y=rnd()-0.5}} + end +end + +function _update60() + for b in all(bullets) do + grav(b,5) + move(b) + edgebounce(b) + collide(b) + end +end + +function magnitude(v) + return sqrt(v.x^2 + v.y^2) +end + +function normalize(v) + length = magnitude(v) + return {x=v.x/length,y=v.y/length} +end + +function dot(v1,v2) + return v1.x*v2.x + v1.y*v2.y +end + +function reflect(v,n) + n = normalize(n) + return vsub(scale(scale(n,dot(v,n)),2),v) +end + +function bounce(v,n) + n = normalize(n) + return vadd(scale(scale(n,dot(v,n)),-2),v) +end + +function vadd(v1,v2) + return {x=v1.x+v2.x,y=v1.y+v2.y} +end + +function vsub(v1,v2) + return {x=v1.x-v2.x,y=v1.y-v2.y} +end + +function scale(v,s) + return {x=v.x*s, y=v.y*s} +end + +function vinv(v) + return {x=-v.x,y=-v.y} +end + +function collide(b) + for t in all(bullets) do + if t.id != b.id then + diff = vsub(b.pos,t.pos) + ndif = normalize(diff) + midp = scale(vadd(b.pos,t.pos),0.5) + if (magnitude(diff) < ball_rad*2) then + b.vel = bounce(b.vel,ndif) + t.vel = bounce(t.vel,vinv(ndif)) + b.pos = vadd(midp,scale(ndif,ball_rad+0.5)) + t.pos = vsub(midp,scale(ndif,ball_rad+0.5)) + add_collision(midp) + end + end + end +end + +function add_collision(v) + add(collisions,v) + if(#collisions > 10) then + del(collisions, collisions[1]) + end +end + +function move(b) + b.pos.x += b.vel.x + b.pos.y += b.vel.y +end + +function chaos(b, rate) + b.vel.x += rnd(rate) - rate/2 + b.vel.y += rnd(rate) - rate/2 +end + +function edgebounce(b) + pos = b.pos + n = {x=0,y=0} + if (pos.x < 0) then + b.pos.x = -pos.x + n.x = 1 + elseif (pos.x > 127) then + b.pos.x = 127 - (pos.x - 127) + n.x = -1 + end + if (pos.y < 0) then + b.pos.y = -pos.y + n.y = 1 + elseif (pos.y > 127) then + b.pos.y = 127 - (pos.y - 127) + n.y = -1 + end + if (n.x != 0 or n.y != 0) then + n = normalize(n) + b.vel = bounce(b.vel, n) + end +end + +function grav(b, speed) + b.vel.y += speed/60 +end + +function _draw() + cls() + for c in all(collisions) do + circfill(c.x, c.y, 1, 10) + end + for b in all(bullets) do + circfill(b.pos.x, b.pos.y, ball_rad, 7) + end + //print(bullets[1].vel.x) + //print(bullets[1].vel.y) +end +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/prototypes/vectortest.p8 b/prototypes/vectortest.p8 new file mode 100644 index 0000000..f2ba3ee --- /dev/null +++ b/prototypes/vectortest.p8 @@ -0,0 +1,310 @@ +pico-8 cartridge // http://www.pico-8.com +version 34 +__lua__ +ball_count = 16 +ball_radius = 4 + +function _init() + balls = {} + collisions = {} + for i=1,ball_count do + add(balls, ball:new({ + pos=vec2:new(rnd(127),rnd(127)), + vel=vec2:new(rnd(2)-1,rnd(2)-1):normal(), + col=rnd(15)+1 + })) + end +end + +function _update60() + for b in all(balls) do + b:move() + b:edge_bounce() + end + for b in all(balls) do + b:check_collisions(balls) + end + handle_collisions(balls) + collisions = {} +end + +function _draw() + cls() + for b in all(balls) do + b:draw() + end +end + +function handle_collisions() + for source,colls in pairs(collisions) do + for target,diff in pairs(colls) do + local n = diff:normal() + local steps = 0 + local rewind = 0 + local s_xpoint = source.pos + local t_xpoint = target.pos + repeat + steps += 1 + rewind += 0.1 * steps + s_xpoint = source.pos - source.vel * rewind + t_xpoint = target.pos - target.vel * rewind + until (s_xpoint - t_xpoint):mag() >= source.rad + target.rad + source.vel = collision_vel(s_xpoint, source.vel, t_xpoint, target.vel) + target.vel = collision_vel(t_xpoint, target.vel, s_xpoint, source.vel) + source.pos = s_xpoint + source.vel * rewind + target.pos = t_xpoint + target.vel * rewind + end + end +end + +vec2 = { + x = 0, + y = 0, + + mag = function(self) + return sqrt(self.x^2+self.y^2) + end, + + dot = function(self,v) + return self.x * v.x + self.y * v.y + end, + + normal = function(self) + local mag = self:mag() + return vec2:new(self.x/mag, self.y/mag) + end, + + bounce = function(self, n, b) + local b = b or 1 + local n = n:normal() + return (n * -2 * self:dot(n) + self) * b + end +} + +vec2.__eq = function(v1,v2) return v1.x == v2.x and v1.y == v2.y end +vec2.__add = function(v1,v2) return vec2:new(v1.x+v2.x,v1.y+v2.y) end +vec2.__sub = function(v1,v2) return vec2:new(v1.x-v2.x,v1.y-v2.y) end +vec2.__mul = function(v,s) return vec2:new(v.x*s,v.y*s) end +vec2.__div = function(v,s) return vec2:new(v.x/s,v.y/s) end +vec2.__unm = function(v) return vec2:new(-v.x,-v.y) end +vec2.__tostring = function(v) return "{x: "..v.x..",y: "..v.y.."}" end +vec2.__index = vec2 + +function vec2:new(x,y) + local x = x or 0 + local y = y or 0 + local o = {x=x,y=y} + setmetatable(o, self) + o.__index = self + return o +end + +function vec2:print_debug(v) + local v = v or vec2:new(0,1) + print("vec: "..vec2.__tostring(self)) + print("mag: "..self:mag()) + print("dot: "..self:dot(v)) + print("normal: "..vec2.__tostring(self:normal())) + print("bounce: "..vec2.__tostring(self:bounce(v))) + print("inv: "..vec2.__tostring(-self)) +end + +ball = { + __count = 0, + id = nil, + pos = vec2:new(0,0), + vel = vec2:new(0,0), + rad = ball_radius, + col = 7, + + draw = function(self) + circfill(self.pos.x, self.pos.y, self.rad, self.col) + end, + + move = function(self) + self.pos += self.vel + end, + + edge_bounce = function(self) + edge_normal = vec2:new() + for axis in all({"x","y"}) do + val = self.pos[axis] + if (val - self.rad < 0) then + self.pos[axis] = self.rad + edge_normal[axis] = 1 + elseif (val + self.rad > 127) then + self.pos[axis] = 127 - self.rad + edge_normal[axis] = -1 + end + end + if (edge_normal.x != 0 or edge_normal.y != 0) then + self.vel = self.vel:bounce(edge_normal) + end + end, + + check_collisions = function(self, balls) + for b in all(balls) do + if (b.id != self.id and (collisions[b] == nil or collisions[b][self] == nil)) then + local diff = self.pos - b.pos + if ((diff):mag() < self.rad + b.rad) then + collisions[self] = collisions[self] or {} + collisions[self][b] = diff + end + end + end + end, +} +ball.__index = ball + +function ball:new(o) + ball.__count += 1 + local o = o or {} + o.id = ball.__count + o.col = o.id % 16 + setmetatable(o, self) + o.__index = self + return o +end + +function collision_vel(x1,v1,x2,v2) + local x_diff = x1 - x2 + local v_diff = v1 - v2 + return v1 - x_diff * v_diff:dot(x_diff) / x_diff:mag()^2 +end +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__label__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000033300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000003333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000003333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000033333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000033333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000033333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000003333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000003333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000033300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000009990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000999999900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000999999900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000009999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000009999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000009999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000999999900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000999999900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000009990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000055555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000055555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000111055555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00011111155555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00011111110555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000008880000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000888888800000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000888888800000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000008888888880000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000008888888880000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000008888888880000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000888888800000000000000000000000000000000000000000000000000000000000 +000000000000000aaa00000000000000000000000000000000000000000000888888800000000000000000000000000000000000000000000000000000000000 +0000000000000aaaaaaa000000000000000000000000000000000000000000008880000000222000000000000000000000000000000000000000000000000000 +0000000000000aaaaaaa000000000000000000000000000000000000000000000000000022222220000000000000000000000000000000000000000000000000 +000000000000aaaaaaaaa00000000000000000000000000000000000000000000000000022222220000000000000000000000000000000000000000000000000 +000000000000aaaaaaaaa00000000000000000000000000000000000000000000000000222222222000000000000000000000000000000000000000000000000 +000000000000aaaaaaaaa00000000000000000000000000000000000000000000000000222222222000000000000000000000000000000000000000000000000 +0000000000000aaaaaaa000000000000000000000000000000000000000000000000000222222222000000000000000000000000000000000000000000000000 +0000000000000aaaaaaa000000000000000000000000000000000000000000000000000022222220000000000000000000000000000000000000000000000000 +000000000000000aaa00000000000000000000000000000000000000000000000000000022222220000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000222000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000077700000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000007777777000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000007777777000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000077777777700000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000077777777700000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000077777777700000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000007777777000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000007777777000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000077700000000000000000000000000000000000000004440000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000444444400000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000444444400000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004444444440000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004444444440000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004444444440000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000444444400000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000666444444400000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000066666664440000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000066666660000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000666666666000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000666666666000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000666666666000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000066666660000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000066666660000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000666000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + diff --git a/qphys.p8 b/qphys.p8 new file mode 100644 index 0000000..57e8231 --- /dev/null +++ b/qphys.p8 @@ -0,0 +1,181 @@ +pico-8 cartridge // http://www.pico-8.com +version 34 +__lua__ +ball_count = 16 +ball_radius = 5 + +function _init() + balls = {} + collisions = {} + for i=1,ball_count do + add(balls, ball:new({ + pos=vec2:new(rnd(127),rnd(127)), + vel=vec2:new(rnd(2)-1,rnd(2)-1):normal(), + col=rnd(15)+1 + })) + end +end + +function _update60() + for b in all(balls) do + b:move() + b:edge_bounce() + end + for b in all(balls) do + b:check_collisions(balls) + end + handle_collisions(balls) + collisions = {} +end + +function _draw() + cls() + for b in all(balls) do + b:draw() + end +end + +function handle_collisions() + for source,colls in pairs(collisions) do + for target,diff in pairs(colls) do + local n = diff:normal() + local steps = 0 + local rewind = 0 + local s_xpoint = source.pos + local t_xpoint = target.pos + repeat + steps += 1 + rewind += 0.1 * steps + s_xpoint = source.pos - source.vel * rewind + t_xpoint = target.pos - target.vel * rewind + until (s_xpoint - t_xpoint):mag() >= source.rad + target.rad + source.vel = collision_vel(s_xpoint, source.vel, t_xpoint, target.vel) + target.vel = collision_vel(t_xpoint, target.vel, s_xpoint, source.vel) + source.pos = s_xpoint + source.vel * rewind + target.pos = t_xpoint + target.vel * rewind + end + end +end + +vec2 = { + x = 0, + y = 0, + + mag = function(self) + return sqrt(self.x^2+self.y^2) + end, + + dot = function(self,v) + return self.x * v.x + self.y * v.y + end, + + normal = function(self) + local mag = self:mag() + return vec2:new(self.x/mag, self.y/mag) + end, + + bounce = function(self, n, b) + local b = b or 1 + local n = n:normal() + return (n * -2 * self:dot(n) + self) * b + end +} + +vec2.__eq = function(v1,v2) return v1.x == v2.x and v1.y == v2.y end +vec2.__add = function(v1,v2) return vec2:new(v1.x+v2.x,v1.y+v2.y) end +vec2.__sub = function(v1,v2) return vec2:new(v1.x-v2.x,v1.y-v2.y) end +vec2.__mul = function(v,s) return vec2:new(v.x*s,v.y*s) end +vec2.__div = function(v,s) return vec2:new(v.x/s,v.y/s) end +vec2.__unm = function(v) return vec2:new(-v.x,-v.y) end +vec2.__tostring = function(v) return "{x: "..v.x..",y: "..v.y.."}" end +vec2.__index = vec2 + +function vec2:new(x,y) + local x = x or 0 + local y = y or 0 + local o = {x=x,y=y} + setmetatable(o, self) + o.__index = self + return o +end + +function vec2:print_debug(v) + local v = v or vec2:new(0,1) + print("vec: "..vec2.__tostring(self)) + print("mag: "..self:mag()) + print("dot: "..self:dot(v)) + print("normal: "..vec2.__tostring(self:normal())) + print("bounce: "..vec2.__tostring(self:bounce(v))) + print("inv: "..vec2.__tostring(-self)) +end + +ball = { + __count = 0, + id = nil, + pos = vec2:new(0,0), + vel = vec2:new(0,0), + rad = ball_radius, + col = 7, + + draw = function(self) + circfill(self.pos.x, self.pos.y, self.rad, self.col) + end, + + move = function(self) + self.pos += self.vel + end, + + edge_bounce = function(self) + edge_normal = vec2:new() + for axis in all({"x","y"}) do + val = self.pos[axis] + if (val - self.rad < 0) then + self.pos[axis] = self.rad + edge_normal[axis] = 1 + elseif (val + self.rad > 127) then + self.pos[axis] = 127 - self.rad + edge_normal[axis] = -1 + end + end + if (edge_normal.x != 0 or edge_normal.y != 0) then + self.vel = self.vel:bounce(edge_normal) + end + end, + + check_collisions = function(self, balls) + for b in all(balls) do + if (b.id != self.id and (collisions[b] == nil or collisions[b][self] == nil)) then + local diff = self.pos - b.pos + if ((diff):mag() < self.rad + b.rad) then + collisions[self] = collisions[self] or {} + collisions[self][b] = diff + end + end + end + end, +} +ball.__index = ball + +function ball:new(o) + ball.__count += 1 + local o = o or {} + o.id = ball.__count + o.col = o.id % 16 + setmetatable(o, self) + o.__index = self + return o +end + +function collision_vel(x1,v1,x2,v2) + local x_diff = x1 - x2 + local v_diff = v1 - v2 + return v1 - x_diff * v_diff:dot(x_diff) / x_diff:mag()^2 +end + +__gfx__ +01230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +45670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +89ab0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cdef7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/sprites.png b/sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..7c3dfb89cc11f2ceea8d39dad11835f835a7a77a GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!3-pya`gKGDaPU;cPEB*=VV?2ImQ7#A+A6g z2xPT`>r{go+5=YynZ<|uA3A*e|Hl{q8GQdQX88X`o#Ba@=Gyy}=@@=c%dSVBAXVa0OS5h;# sU31S$cz1lJ)Q)%0eR)An0D=$I@|)H$bWU>GI|Ib^boFyt=akR{09kTXQ~&?~ literal 0 HcmV?d00001