重绘留下痕迹

我知道这不是第一次提出这个问题,但是回复对我没什么帮助,所以我正在帮助我最终得到我的答案

我已经制作了这个小游戏,我在轨道周围开了一个汽车(使用矩形是强制性的)。 当我使用repaint()方法时,代表汽车的矩形在新位置重新绘制,但留下了一条痕迹。

我有这个代码:

 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(); } } 

在paint方法中取消注释super.paint(g)[第87行]。

它负责清除任何陈旧对象的canvas。

原因是在行g.fillRect(0,0,WIDTH,HEIGHT); 它实际上是指java.awt.image.ImageObserver#WIDTHjava.awt.image.ImageObserver#HEIGHT而不是你的实例变量。 你可以在任何IDE中看到这一点。

因此,预期的黑色背景仅在左上角的1​​x2像素区域中绘制。 自从调用super.paint(g); 被注释掉了,甚至灰色背景都没有重新粉刷。 结果,汽车的旧图纸没有透支。

需要将代码更改为使用MAP.this.WIDTH ,或者需要将WIDTH字段重命名为与从JPanelinheritance的字段不冲突的内容,或者需要将字段移动到同一JPanel中以获得更高的优先级,或者您也可以使用JPanel中的getWidth()方法。 同样适合身高。