Me despertó un trueno y aproveché para programar éste jueguito.
Es un juego de tenis como los viejos de atari (por su simplicidad). Es para dos jugadores, los goles se imprimen en consola por comodidad aunque sería muy facil colocarlos en un label.
Se utiliza multitarea, captura de eventos de click y de teclas, y graficación sobre JPanel.
Cuenta con 3 objetos instanciados, los dos jugadores y la pelota. 3 Clases en total.

Bueno, aca el codigo.
package tenis;
import java.awt.event.*;
import javax.swing.*; // Por JFrame
import java.awt.*; // Por Borders
/**
* @author Administrador
*/
public class Juego extends JFrame implements ActionListener, KeyListener, Runnable {
private static final long serialVersionUID = 1L;
private JPanel pnlLienzo;
private JPanel pnlBotonera;
private JButton btnStart;
private Pelota p;
private Thread t;
private Jugador j1, j2;
public Juego() {
super("Tenis 1.0");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
pnlLienzo = new JPanel();
pnlLienzo.setBackground(Color.BLACK);
getContentPane().add(pnlLienzo, BorderLayout.CENTER);
pnlBotonera = new JPanel();
getContentPane().add(pnlBotonera, BorderLayout.SOUTH);
btnStart = new JButton("Comenzar");
pnlBotonera.add(btnStart);
btnStart.addActionListener(this);
addKeyListener(this);
setFocusable(true);
requestFocus();
setSize(320, 240);
setVisible(true);
}
public void keyTyped(KeyEvent arg0) {}
public void keyPressed(KeyEvent arg0) {
switch (arg0.getKeyCode()) {
case KeyEvent.VK_UP : j1.mover(1); break;
case KeyEvent.VK_DOWN : j1.mover(-1); break;
case KeyEvent.VK_A : j2.mover(1); break;
case KeyEvent.VK_Z : j2.mover(-1); break;
}
}
public void keyReleased(KeyEvent arg0) {}
public void run() {
while(true){
p.dibujo(pnlLienzo.getGraphics());
j1.dibujo(pnlLienzo.getGraphics());
j2.dibujo(pnlLienzo.getGraphics());
if((p.x == 0) && ((p.y > j1.y+j1.h) || (p.y < j1.y) ))
System.out.println("Gol de Jugador 2!!");
else if((p.x >= pnlLienzo.getWidth()-14) && ((p.y > j2.y+j2.h) || (p.y < j2.y)))
System.out.println("Gol de Jugador 1!!");
try{
Thread.sleep(50);
}catch (InterruptedException ie){}
}
}
public void actionPerformed(ActionEvent arg0) {
p = new Pelota(pnlLienzo.getWidth(), pnlLienzo.getHeight());
p.start();
j1 = new Jugador(0, 0, pnlLienzo.getWidth(), pnlLienzo.getHeight(), Color.BLUE);
j1.start();
j2 = new Jugador(pnlLienzo.getWidth() - 10, 0, pnlLienzo.getWidth(), pnlLienzo.getHeight(), Color.RED);
j2.start();
t.start();
btnStart.setEnabled(false);
}
public static void main(String[] args) {
Juego j = new Juego();
j.t = new Thread(j);
}
}
package tenis;
import java.awt.Color;
import java.awt.Graphics;
public class Pelota extends Thread {
int x, y, d;
int ancho, alto; // del contenedor
int incx=5;
int incy=6;
int oldx, oldy;
public Pelota(int ancho, int alto) {
super();
x = y = oldx = oldy = 0;
d = 15;
this.ancho = ancho;
this.alto = alto;
}
public void run()
{
while (true){
x+=incx;
y+=incy;
if((x <= 0) || (x + d >= ancho)) incx*= -1;
if((y <= 0) || (y + d >= alto)) incy*= -1;
try{
Thread.sleep(50);
}catch (InterruptedException ie){}
}
}
public void dibujo(Graphics g)
{
g.setColor(Color.BLACK);
g.fillOval(oldx, oldy, d, d);
g.setColor(Color.WHITE);
g.fillOval(x, y, d, d);
oldx = x;
oldy = y;
}
}
package tenis;
import java.awt.Color;
import java.awt.Graphics;
public class Jugador extends Thread{
int x, y, w, h, incy = 7;
int oldx, oldy;
int ancho, alto; // del contenedor
Color c;
public Jugador(int x, int y, int ancho, int alto, Color c) {
super();
this.x = x;
this.y = y;
oldx = oldy = 0;
w = 10;
h = 40;
this.c = c;
this.ancho = ancho;
this.alto = alto;
}
public void mover(int dir){
if(dir < 0) incy = Math.abs(incy);
else incy = -Math.abs(incy);
}
public void run(){
while(true){
y+= incy;
if((y <= 0) || (y + h >= alto)) incy *= -1;
try{
Thread.sleep(50);
}catch (InterruptedException ie){}
}
}
public void dibujo(Graphics g)
{
g.setColor(Color.BLACK);
g.fillRect(oldx, oldy, w, h);
g.setColor(c);
g.fillRect(x, y, w, h);
oldx = x;
oldy = y;
}
}
Saludos!
PD: 90 minutos me llevó hacerlo, ojalá pueda repetirlo en el examen de esta tarde

PD2: Tiene bugs por falta de validaciones que son facilmente corregibles, pero por culpa del trueno dormí solo 2 horas, asi que a los bugs los corrija otro
