Multi Key Press Animation

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

// in this version of the animation you can press two keys at once and also
// get autorepeat instantly, instead of after a delay
public class MultiKeyAnimation implements KeyListener
{
   static final int WIDTH = 500;
   static final int HEIGHT = 400;
   JFrame frame = new JFrame("Threads for Animation");
   Drawing draw = new Drawing();
   int x, y = (int)(Math.random() * HEIGHT);
   int shipX = 200, shipY = 300;
   boolean[] keys = new boolean[4];

   Animation animation = new Animation();
   
   public MultiKeyAnimation()
   {
      frame.add(draw,"Center");
      frame.addKeyListener(this);
      frame.setLocation(100,200);
      frame.setSize(WIDTH, HEIGHT);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
      // start the animation (causes the run()method to be called)
      animation.start();
   }

   // called when a key is pressed (if the key is held down it will
   // get called repeatedly until another key is pressed
   public void keyPressed(KeyEvent e)
   {
      int typed = e.getKeyCode();
      
      if (typed == KeyEvent.VK_LEFT)
         keys[0]=true;
      else if (typed == KeyEvent.VK_RIGHT)
         keys[2]=true;
      else if (typed == KeyEvent.VK_UP)
         keys[1]=true;
      else if (typed == KeyEvent.VK_DOWN)
         keys[3]=true;
   }
   
   // called when a key that was pressed is released
   public void keyReleased(KeyEvent e)
   {
      int released = e.getKeyCode();
      
      if (released == KeyEvent.VK_LEFT)
         keys[0]=false;
      else if (released == KeyEvent.VK_RIGHT)
         keys[2]=false;
      else if (released == KeyEvent.VK_UP)
         keys[1]=false;
      else if (released == KeyEvent.VK_DOWN)
         keys[3]=false;
   }
   
   // called when a key is pressed and released immediatley (typed)
   public void keyTyped(KeyEvent e)
   {        
   }
   
   public static void main (String[] args)
   {  
      new MultiKeyAnimation();
   }

   class Drawing extends JComponent
   {      
      public void paint(Graphics g)
      {
         Rectangle r = new Rectangle(shipX, shipY, 50, 100);
         g.setColor(Color.black);

         g.fillRect(0,0,frame.getWidth(),frame.getHeight());
         g.setColor(Color.white);
         g.fillOval(shipX+8, shipY+16, 50/6, 100/6);
         g.drawOval(shipX, shipY, 50/2, 100/2);
         g.drawRect(shipX, shipY + 50, 10, 50);
         g.drawRect(shipX+15, shipY+50, 10, 50);
         g.setColor(Color.yellow);
         g.fillOval(x, y, 10, 10);
         
         // if the bullet hits the ship
         if (r.contains(x, y))
         {
            g.setColor(Color.red);
            g.fillRect(shipX, shipY, 50, 105);
            // stop the animation
            animation.interrupt();
         }
      }
   }
   
   // a class for keeping track of bullet positions (note: it doesn't draw
   // the bullets, the Drawing class does that)
   class Animation extends Thread
   {
      // do the animation      
      public void run()
      {
         try
         {
            while (true)
            {
               sleep(50);
               if( keys[0]) 
                  shipX -= 10;
               if( keys[1]) 
                  shipY -= 10;
               if (keys[2])
                  shipX += 10;
               if (keys[3])
                  shipY += 10;
               if (shipX < 0)  
                  shipX = WIDTH;
               if (shipX > WIDTH) 
                  shipX = 0;
               if (shipY < 0)  
                  shipY = HEIGHT-100;
               if (shipY > HEIGHT)   
                  shipY = 100;

               
               x += 10;
               if (x >= WIDTH)
               {
                  x = 30;
                  y = (int)(Math.random() * HEIGHT);
               }
               draw.repaint();
            }
         }
         catch (InterruptedException e)
         {
         }
      }
   }
   
}