Skip to content

Instantly share code, notes, and snippets.

@mika76
Last active January 16, 2023 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mika76/4b559a8096d73414e24dd5bfb83c54c9 to your computer and use it in GitHub Desktop.
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
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