Last active
January 16, 2023 12:28
-
-
Save mika76/4b559a8096d73414e24dd5bfb83c54c9 to your computer and use it in GitHub Desktop.
Pico-8 verlet integration rope - using https://www.youtube.com/watch?v=3HjO_RGIjCU
This file contains hidden or 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
pico-8 cartridge // http://www.pico-8.com | |
version 39 | |
__lua__ | |
function _init() | |
mouse.init() | |
points = {} | |
sticks = {} | |
bounce=0.9 | |
gravity=0.1 | |
friction=0.999 | |
--create points | |
for i=1,11 do | |
add(points,{x=i*10,y=5,oldx=i*10,oldy=5}) | |
end | |
--links all points | |
for i=2,#points do | |
add(sticks,{ | |
p0=points[i-1], | |
p1=points[i], | |
len=distance(points[i-1],points[i]) | |
}) | |
end | |
--pin the last point | |
points[#points].pinned=true | |
--move last point to middle | |
points[#points].x = 64 | |
end | |
function _update() | |
if(btnp(⬅️)) points[#points].x-=10 | |
if(btnp(➡️)) points[#points].x+=10 | |
if(btnp(⬆️)) points[#points].y-=10 | |
if(btnp(⬇️)) points[#points].y+=10 | |
local x,y = mouse.pos() | |
local b = mouse.button() | |
if b==1 then | |
points[#points].x=x | |
points[#points].y=y | |
points[#points].oldx=x | |
points[#points].oldy=y | |
points[#points].pinned=true | |
end | |
if btnp(❎) then | |
showpoints=not showpoints | |
end | |
if btnp(🅾️) then | |
points[#points].oldx=points[#points].x | |
points[#points].oldy=points[#points].y | |
points[#points].pinned=not points[#points].pinned | |
end | |
updatepoints() | |
for i=0,2 do | |
updatesticks() | |
constrainpoints() | |
end | |
end | |
function _draw() | |
cls(); | |
rendersticks() | |
if (showpoints) renderpoints() | |
--mouse pointer | |
local x,y = mouse.pos() | |
--spr(0,x,y) | |
pset(x,y,7) | |
print("⬆️⬇️⬅️➡️/mouse move pinned",0,117,7) | |
print("❎ show/hide points",0,123,7) | |
end | |
function distance(p0,p1) | |
local dx,dy=p1.x-p0.x,p1.y-p0.y | |
return sqrt(dx*dx+dy*dy) | |
end | |
-->8 | |
--points | |
function updatepoints() | |
for p in all(points) do | |
if not p.pinned then | |
local vx,vy=(p.x-p.oldx)*friction,(p.y-p.oldy)*friction | |
p.oldx=p.x | |
p.oldy=p.y | |
p.x+=vx | |
p.y+=vy | |
p.y+=gravity | |
end | |
end | |
end | |
function constrainpoints() | |
for p in all(points) do | |
if not p.pinned then | |
local vx,vy=(p.x-p.oldx)*friction,(p.y-p.oldy)*friction | |
if p.x>127 then | |
p.x=127 | |
p.oldx=p.x+vx*bounce | |
elseif p.x<0 then | |
p.x=0 | |
p.oldx=p.x+vx*bounce | |
end | |
if p.y>127 then | |
p.y=127 | |
p.oldy=p.y+vy*bounce | |
elseif p.y<0 then | |
p.y=0 | |
p.oldy=p.y+vy*bounce | |
end | |
end | |
end | |
end | |
function renderpoints() | |
for p in all(points) do | |
circfill(p.x,p.y,2,11) | |
end | |
end | |
-->8 | |
--sticks | |
function updatesticks() | |
for s in all(sticks) do | |
local dx,dy=s.p1.x-s.p0.x,s.p1.y-s.p0.y | |
local dist=sqrt(dx*dx+dy*dy) | |
local diff=s.len-dist | |
local perc=diff/dist/2 | |
local offx,offy=dx*perc,dy*perc | |
if not s.p0.pinned then | |
s.p0.x-=offx | |
s.p0.y-=offy | |
end | |
if not s.p1.pinned then | |
s.p1.x+=offx | |
s.p1.y+=offy | |
end | |
end | |
end | |
function rendersticks() | |
for s in all(sticks) do | |
if not s.hidden then | |
line(s.p0.x,s.p0.y,s.p1.x,s.p1.y,5) | |
end | |
end | |
end | |
-->8 | |
--mouse | |
--from https://www.lexaloffle.com/bbs/?tid=3549 | |
mouse = { | |
init = function() | |
poke(0x5f2d, 1) | |
end, | |
-- return int:x, int:y, onscreen:bool | |
pos = function() | |
local x,y = stat(32)-1,stat(33)-1 | |
return stat(32)-1,stat(33)-1 | |
end, | |
-- return int:button [0..4] | |
-- 0 .. no button | |
-- 1 .. left | |
-- 2 .. right | |
-- 4 .. middle | |
button = function() | |
return stat(34) | |
end, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment