Skip to content

Instantly share code, notes, and snippets.

@rross101
Created September 18, 2018 22:03
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 rross101/80966e16d7067d103370791f3b704ee2 to your computer and use it in GitHub Desktop.
Save rross101/80966e16d7067d103370791f3b704ee2 to your computer and use it in GitHub Desktop.
Bounce for Norns
--- bounce by declutter; can't remember who first created this app in Max for the monome
--- to-do:
--- sound on collision
--- multiple balls
g = grid.connect()
function init()
--- set up variables and grid
position = {1,1}
v = {1,1}
map = {}
for i = 1,16 do
map[i] = {}
for j = 1,8 do
map[i][j] = 0
end
end
--- initial state to make it more interesting
map[4][1] = 1
map[4][2] = 1
map[4][3] = 1
map[9][6] = 1
map[9][7] = 1
map[9][8] = 1
---timing
counter = metro.alloc()
counter.time = 0.1
counter.count = -1
counter.callback = count
counter:start()
end
function count()
--- move ball
position[1] = position[1] + v[1]
position[2] = position[2] + v[2]
--- detect edges
--- this is ugly; there must be a prettier way
if (position[1] == 16) or (position[1] == 1) or (map[position[1]+1][position[2]] == 1) or (map[position[1]-1][position[2]] == 1) then v[1] = (-1)*v[1] end
if (position[2] == 8) or (position[2] == 1) or (map[position[1]][position[2]+1] == 1) or (map[position[1]][position[2]-1] == 1) then v[2] = (-1)*v[2] end
--- redraw grid
g.all(0)
for i = 1,16 do
for j = 1,8 do
g.led(i,j,(map[i][j] == 1) and 5 or 0)
end
end
g.led(position[1],position[2],15)
g.refresh()
end
g.event = function(x,y,z)
--- key presses build walls
if z == 1 then
map[x][y] = 1 - map[x][y]
end
g.refresh()
end
@trentgill
Copy link

trentgill commented Sep 20, 2018

this looks pretty clean to me, mostly just about readability.

your position and v tables could use key-value pairs, rather than just be integers, eg v = { x=1, y=1 }. that way you can refer to them using v.x rather than v[1]. this clarifies that v is table with entries x and y, rather than a generic array.

it's weird having position in full, and v as short for velocity. i'd use the full form for both, or the 1letter form. use the full form if the program is going to grow in complexity.

i'd name map something else, like walls or obstacles. map usually refers to a function that applies a function over all elements of a list.

put the move ball into a function called move_ball() then you don't need the documentation. the code documents the intention. inside this function you can use position.* and velocity.* rather than the array notation.

if you're thinking about adding multiple balls you're going to need multiple position and v tables. one set per ball. so make a table ball which contains a position and v table. then your move_ball() function can take a ball table as it's argument, meaning it could be applied to different balls just by sending a different argument to the function.

regarding the edge detection, there's not a lot you can do structurally - you need to check all these cases - but you can make it a little prettier. first is (again) wrapping it in a function detect_collision() which you can send a ball table.

inside this function (your current or chain), you don't need the parentheses around each condition as or has higher precedence. you can also split the lines across multiple lines like:

if   position.x = 16
  or position.x = 1
  etc...
  then

which should make it clearer that you are checking a series of conditions, any of which will cause the action.

in terms of the action, you can simply negate by prefacing it with a - symbol. no need to explicitly multiply.

final suggestion is that map could contain a boolean (true/false) rather than a number. this limits you to 'on/off' state, but it allows you to simplify the map[][] lookup. if it's a bool you would change == 1 to == true which is the default condition, so you can drop it altogether for or map[*][*] or <next condition>.

following from here @64: i think it would be more idiomatic to say map[x][y] = not map[x][y] to invert the state.

that's all i've got!

@rross101
Copy link
Author

@trentgill somehow I missed this comment. This is excellent - will do some looking at it. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment