Please log in (or register) to post a dweet (copy-paste the code somewhere safe to save it meanwhile)

u(t) is called 60 times per second.
t: Elapsed time in seconds.
S: Shorthand for Math.sin.
C: Shorthand for Math.cos.
T: Shorthand for Math.tan.
R: Function that generates rgba-strings, usage ex.: R(255, 255, 255, 0.5)
c: A 1920x1080 canvas.
x: A 2D context for that canvas.

The code seems to work with most starting values if you change it to "C=_=>(p|q)<0?-1:u[j=q+n&-n|p/n]=-!u[j]|1" and handle negative coordinates as blockers?

Its shorter to init positions and velocities to same number but makes velocities too fast. Another problem is that init needs to happen once and shortest way to do that is t?<spot>:init which creates a spot to do something every non-first frame. I solve both problems by naming my collision detection function C and defining it on every non-first frame. On the first frame C is Math.cos so the velocity update code does r = r*C(p+=r) = 571*Math.cos(571+571) = 17.7 which is a reasonable speed.

The ball needs to be updated once per frame. Since I am iterating with a single index its easiest to check for index 0. This corresponds to the upper left block which is why it was missing in the original. A short fix is to shift everything up one block by using negative height for the blocks and adding a row to ball position encoding. The +n in q+n&-n|p/n.

I encode and decode 2d co-ordinates into one number. The block coordinates are (i%n,i/n|0) and their width is n making their real positions (i%n*n,(i/n|0)*n). Lets simplify the second one. If we choose n=2**k then (i/n|0)*n = (i/2**k|0)*2**k = (i>>k)<<k so we are zeroing out the last k binary digits. But if n=2**k then -n is a bunch of ones followed by k zeroes (https://en.wikipedia.org/wiki/Two%27s_compleâ€¦)! Therefore (i/n|0)*n = i&-n.

Need to check if ball pos (p,q) touches a new block. Ball is always in some block, find that blocks pos index. Dividing ball position by n gives the virtual coords and blocks are 1x1 so truncating gives 2d block coordinates (p/n|0,q/n|0). Want to encode this into index j where (x,y)=(j%n,j/n|0). Therefore j=(q/n|0)*n+(p/n|0). If n=2**k then in binary j=[32-k binary digits y-coord][k binary digits of x-coord] so we can use bitwise-or which also auto-truncates so j=(q/n|0)*n|p/n. And as we saw (q/n|0)*n=q&-n so j=q&-n|p/n! Real code uses j=q+n&-n|p/n to add one row to ball pos to account for shift up to hide missing (0,0)` block.

p+=r*=C(p+=r) encodes an unbelievable trick that is perfect for collision detection. For detection we need to independently try advancing vertically and horizontally, check for collision, and reverse course if hit. The temporary state involved in trying can cost a lot of chars. p+=r*=C(p+=r) does it all and C doesn't even read its argument! When C is invoked the global p it sees was already incremented by r. However, the outer p+= will eventually discard that increment. Magic!

u(t) is called 60 times per second.
t: elapsed time in seconds.
c: A 1920x1080 canvas.
x: A 2D context for that canvas.
S: Math.sin
C: Math.cos
T: Math.tan
R: Generates rgba-strings, ex.: R(255, 255, 255, 0.5)

Please log in (or register) to comment.