The only thing I really don't like is how I had to divide paddle's input functions to InputRight() and InputLeft(), but I didn't know any other good way of doing this (aside from making subclasses for left and right paddle, which didn't seem worth the effort to me).
A simple way to solve this would be to pass the SDLKey values that are being listened for to the Paddle constructor:
int leftX = /* ... */;
int rightX = /* ... */;
Paddle left(leftX, SDLK_w, SDLK_s);
Paddle right(rightX, SDLK_UP, SDLK_DOWN);
However, another way to think about this is that the paddle is too "low level" to be worrying about this. It shouldn't need to care whether it is controlled by keyboard, or maybe by tilt for a mobile device, responding to incoming packets from a remote network player or even by the output of some A.I. decision logic.
We can do this by exposing a Paddle interface that can be "bound" to any of the above:
class Paddle
{
public:
void MoveUp();
void MoveDown();
void StopMoving();
// ...
};
Now, the higher level code can be responsible for dispatching input events into game logic:
while(SDL_PollEvent(&event))
{
if( event.type == SDL_KEYDOWN )
{
SDLKey key = event.key.keysym.sym;
if(key == SDLK_UP)
{
leftPaddle->MoveUp();
}
else if(key == SDLK_DOWN)
{
leftPaddle->MoveDown();
}
else if(key == SDLK_w)
{
rightPaddle->MoveUp();
}
else if(key == SDLK_s)
{
rightPaddle->MoveDown();
}
}
else if(event.type == SDL_KEYUP)
{
SDLKey key = event.key.keysym.sym;
if(key == SDLK_UP || key == SDLK_DOWN)
{
leftPaddle->StopMoving();
}
else if(key == SDLK_w || key == SDLK_s)
{
rightPaddle->StopMoving();
}
}
}