Repaint deja rastro

Sé que esta no es la primera vez que se hace esta pregunta, pero las respuestas no me han ayudado mucho, así que estoy ayudando y finalmente voy a obtener mi respuesta

He creado este pequeño juego en el que he conducido un automóvil por una pista (el uso de rectángulos era obligatorio). Cuando uso larepaint() metod el rectángulo que representa el auto repinta en la nueva ubicación, pero deja un rastro atrás.

Tengo este código:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;

import javax.swing.JFrame;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class MAP extends JFrame
{
    //constant for the screen size and used for the drawing the terrain
    final int WIDTH = 900, HEIGHT = 650;
    //the URL and Img designed for the images
    URL cLeft,cRight,cUp;
    Image img1,img2,img3;

//these will keep track of each player’s speed:
double p1Speed =.5;



//these are ints that represent directions:
final int UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
//these will keep track of the player’s directions (default = up)
int p1Direction = 0;
JPanel panel;

//draw the terrain
Rectangle left = new Rectangle(0,0,WIDTH/9,HEIGHT);
Rectangle right = new Rectangle((WIDTH/9)*9,0,WIDTH/9,HEIGHT);
Rectangle top = new Rectangle(0,0,WIDTH, HEIGHT/9);
Rectangle bottom = new Rectangle(0,(HEIGHT/9)*9,WIDTH,HEIGHT/9);
Rectangle center = new Rectangle((int)((WIDTH/9)*2.5),(int)((HEIGHT/9)*2.5),(int)((WIDTH/9)*5),(HEIGHT/9)*4);

//these obstacles will obstruct the path and make navigating harder
Rectangle obstacle = new
Rectangle(WIDTH/2,(int)((HEIGHT/9)*7),WIDTH/10,HEIGHT/9);
Rectangle obstacle2 = new
Rectangle(WIDTH/3,(int)((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
Rectangle obstacle3 = new
Rectangle(2*(WIDTH/3),(int)((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
Rectangle obstacle4 = new Rectangle(WIDTH/3,HEIGHT/9,WIDTH/30,HEIGHT/9);
Rectangle obstacle5 = new Rectangle(WIDTH/2,(int)((HEIGHT/9)*1.5),WIDTH/30,HEIGHT/4);
Rectangle finish = new Rectangle(WIDTH/9,(HEIGHT/2)-HEIGHT/9,(int)((WIDTH/9)*1.5),HEIGHT/70);
Rectangle lineO=new Rectangle(WIDTH/9,HEIGHT/2,(int)((WIDTH/9)*1.5)/2,HEIGHT/140);
Rectangle lineI = new Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+(HEIGHT/10),(int)((WIDTH/9)*1.5)/2, HEIGHT/140);


//this is the rectangle for player 1’s (outer) car:
Rectangle p1 = new Rectangle(WIDTH/9,HEIGHT/2, WIDTH/30,WIDTH/30);
public MAP(){
    super("Radical Racing");
    setSize(WIDTH,HEIGHT);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    setResizable(false);
    setVisible(true);
    setLocationRelativeTo(null);


    //the following code creates the JFrame

    try
    {
        cUp = this.getClass().getResource("carUp.jpg");
        cLeft = this.getClass().getResource("carLeft.jpg");
        cRight = this.getClass().getResource("carRight.jpg");
    }catch(Exception e)
    {}

    //attach the URLs to the images
    img1 = Toolkit.getDefaultToolkit().getImage(cUp);
    img2 = Toolkit.getDefaultToolkit().getImage(cLeft);
    img3 = Toolkit.getDefaultToolkit().getImage(cRight);

    panel=new JPanel(){
        public void paint(Graphics g)
        {
            //super.paint(g);
            //draw the background for the racetrack
            g.setColor(Color.DARK_GRAY);
            g.fillRect(0,0,WIDTH,HEIGHT);

            //when we draw, the border will be green
            g.setColor(Color.GREEN);

            //fill rectangle
            g.fillRect(left.x,left.y,left.width,left.height);
            g.fillRect(right.x,right.y,right.width,right.height);
            g.fillRect(top.x,top.y,top.width,top.height);
            g.fillRect(bottom.x,bottom.y,bottom.width,bottom.height);
            g.fillRect(center.x,center.y,center.width,center.height);

g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
                                g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
            g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
            g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
            g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);

            //set the starting line color to white
            g.setColor(Color.WHITE);

            //now draw the starting line
            g.fillRect(lineO.x,lineO.y,lineO.width,lineO.height);
            g.fillRect(lineI.x,lineI.y,lineI.width,lineI.height);

            //set the color of the finish line to yellow
            g.setColor(Color.YELLOW);

            //now draw the finish line
            g.fillRect(finish.x,finish.y,finish.width,finish.height);

            //set the color to blue for p1
            g.setColor(Color.WHITE);

            //now draw the actual player
            g.fill3DRect(p1.x,p1.y,p1.width,p1.height,true);

            //draw the images for the player
            if(p1Direction==UP)
                g.drawImage(img1,p1.x,p1.y,this);
            if(p1Direction==LEFT)
                g.drawImage(img2,p1.x,p1.y,this);
            if(p1Direction==RIGHT)
                g.drawImage(img3,p1.x,p1.y,this);
        }
    };


    panel.setPreferredSize(new Dimension(950,600));
    this.add(panel);
    pack();
    Move1 move=new Move1();
    move.start();

}

private class Move1 extends Thread implements KeyListener
{
    public void run()
    {
        //now, this should all be in an infinite loop, so the process
        //repeats
        addKeyListener(this);
        while(true)
        {
            //now, put the code in a try block. This will let the
            //program exit
            //if there is an error.
            try
            {
                //increase speed a bit
                //  if(p1Speed<=5)
                //  p1Speed+=.2;
                //p1.y-=(int) p1Speed;
                if(p1.intersects(left) || p1.intersects(right) || p1.intersects(top) ||
                        p1.intersects(bottom) || p1.intersects(obstacle) || p1.intersects(obstacle2)||
                        p1.intersects(obstacle3) || p1.intersects(obstacle4) || p1.intersects(obstacle5))
                {
                    p1Speed = -5;
                }
                //if the car hits the center, do the same as above
                //but make the speed -2.5.
                if(p1.intersects(center))
                {
                    p1Speed = -2.5;
                }
                //increase speed a bit
                if(p1Speed<=5)
                    p1Speed+=.2;
                //these will move the player based on direction
                if(p1Direction==UP)
                {
                    p1.y-=(int)p1Speed;
                }
                if(p1Direction==DOWN)
                {
                    p1.y+=(int)p1Speed;
                }
                if(p1Direction==LEFT)
                {
                    p1.x-=(int)p1Speed;
                }
                if(p1Direction==RIGHT)
                {
                    p1.x+=(int)p1Speed;
                }
                panel.repaint();
                //this delays the refresh rate:
                Thread.sleep(200);
            }
            catch(Exception e)
            {
                //if there is an exception (an error), exit the loop.
                break;
            }
        }
    }

    @Override
    public void keyPressed(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent event) {
        if(event.getKeyChar()=='a')
        {
            p1Direction = LEFT;

        }
        if(event.getKeyChar()=='s')
        {
            p1Direction = DOWN;
        }
        if(event.getKeyChar()=='d')
        {
            p1Direction = RIGHT;
        }
        if(event.getKeyChar()=='w')
        {
            p1Direction = UP;
        }
    }

}
//this starts the program by calling the constructor:
public static void main (String[ ] args)
{
    new MAP();
}
}

Respuestas a la pregunta(4)

Su respuesta a la pregunta