I like this simulation:http://compsci.ca/v3/viewtopic.php?t=14897
It looks ahead to determine how long until the next collision. When you step the simulation, if a collision would happen within the step, it steps the simulation to the collision, does the collision response, and then steps the rest of the way (or until the next collision). This is really neat, but the math is a bit hairy (although it is done for you in that thread). This approach works well with a box, but less so if you want advanced features like pillars or whatever inside the box, or if you want curved trajectories.
The other (less cool but simpler) way to do it is what you already have. Just apply a constant friction to slow down your balls. Eg, vx *= 0.9.
Your pool game will look more realistic if you use two friction values. If your velocity is below some threshold, apply kinetic friction, otherwise apply static friction. The reason why is when a pool ball is hit, it is not yet rolling. The ball is being pushed along the table surface and the friction is high. The friction with the table surface causes angular momentum. As the ball slows it starts rolling, which causes less friction with the table surface.