Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active October 26, 2021 03:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/954637bb0aa926bd44c6 to your computer and use it in GitHub Desktop.
Save JoshCheek/954637bb0aa926bd44c6 to your computer and use it in GitHub Desktop.
"Physics engine" in the terminal (https://vimeo.com/146376459)
require 'io/console'
puts"\e[?25l\e[?1000h";at_exit{puts"\e[?25h\e[?1000l"} # no cursor, yes mouse
x = y = dy = ax = ay = 0; dy = dx = 0.5
height, width = $>.winsize
def hot_cold(name, val)
index = (3*Math.tanh(val)).to_i+2
"\e[38;5;16m" << [{r:5},{r:5,g:2},{r:4,g:4},{g:3,b:4},{b:5}]
.map{ |r:0,g:0,b:0| "\e[48;5;#{r*36+g*6+b+16}m" }
.map.with_index{|c,i| c+(i==index ? name : "-") }
.join <<
"\e[40;37m %6.2f"%val
end
done = false
fg = 7
Thread.new{$stdin.raw{
until done
case c=$stdin.readpartial(20)
when "\e[A" then ay -= 0.1 # arrow keys change acceleration
when "\e[B" then ay += 0.1
when "\e[C" then ax += 0.1
when "\e[D" then ax -= 0.1
when 3.chr then done = true # C-c kills program
when /\e\[M (.)(.)/ # mouse down
dx,dy,x,y = 0,0,*[$1,$2].map { |n| n.force_encoding(Encoding::ASCII_8BIT).ord-32 }
when /^\d/ then fg = $&
end
end
}}
until done
sleep 0.05
# multipliers are to make the change less volatile
dx += ax*0.1 # apply x acceleration
dy += ay*0.1 # apply y acceleration
x += dx/2 # apply x velocity
y += dy/2 # apply y velocity
# Detect wall collisions. I think this probably requires consideration of how long they are in contact
# and what kind of material they are, but thats more real than I care to get with it
y,dy = y<1 ? [1,-dy*0.8] : y>height ? [height, -dy*0.8] : [y,dy]
x,dx = x<1 ? [1,-dx*0.8] : x+1>width ? [width-2,-dx*0.8] : [x,dx]
print "\e[40m\e[H\e[2J" << # reset
hot_cold(?x,dx)+" x-velocity\r\n" <<
hot_cold(?y,dy)+" y-velocity\r\n" <<
hot_cold(?x,ax)+" x-accel\r\n" <<
hot_cold(?y,ay)+" y-accel" <<
"\e[%d;%dH\e[4#{fg}m "%[y.to_i,x.to_i] # ball
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment