This was built through incremental edits from a Python proof-of-concept, which you can see here:
https://github.com/yeahpython/ascii-renderer/blob/master/fun...
It doesn't have any real physics, but reading through it might help reveal how the rendering works.
For the physics, I'm basically colliding against a grid of tiles, so this might be a helpful tutorial to do the same: https://jonathanwhiting.com/tutorial/collision/