Swing JPanel - 绘制的图形复制而不是移动

时间:2017-03-12 02:53:16

标签: java multithreading swing jpanel keylistener

出于某种原因,我的KeyListener工作得很好并且触发布尔运算使得向下和向上变为真和假,并且y值根据我想要的那些根据那些布尔值而变化。我的问题是,由于某种原因,红色矩形看起来大小而不是移动,我很确定这是因为前一帧未被清除。我试着用super.paintComponent(g);清除框架,但这没有任何结果。这是代码:

的JFrame:

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

public class H extends JFrame
{
    public H()
    {
        super("Atlas Blade");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        pack();

        P p = new P();
        Insets frameInsets = getInsets();

        int frameWidth = p.getWidth()    + 
            (frameInsets.left + frameInsets.right);   
        int frameHeight = p.getHeight()    + (
            frameInsets.top + frameInsets.bottom); 

        setPreferredSize(new Dimension(frameWidth, frameHeight));    
        setLayout(null);   
        add(p);   

        pack();   
        setVisible(true);  
    }
}

的JPanel:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.image.*;

public class P extends JPanel implements KeyListener, Runnable
{

    private long updateCount=0;
    private long paintCount=0;
    private int updatesPerSecond = 50;

    private boolean aLeft,aRight,aDown,aUp=false;
    private boolean up,down,left,right=false;

    int x = 20;
    int y=20;
    Hb box = new Hb(x,y);
    Rectangle rect = new Rectangle(0,300,300,50);
    BufferedImage buffer;


    public P()
    {
        super();
        setSize(600,350);
        //setSize(50,50);
        buffer = new BufferedImage    (600,350,BufferedImage.TYPE_4BYTE_ABGR);
        addKeyListener(this);
        Thread jim = new Thread(this);


    jim.start();


    }
    public void run()
    {
        int waitToUpdate = 1000/updatesPerSecond;
        long startTime = System.nanoTime();

        while(true)
        {
            boolean shouldRepaint = false;
            long currentTime = System.nanoTime();
            long updatesNeeded = (((currentTime-startTime) /     1000000))/ waitToUpdate;

            for(long x = updateCount; x< updatesNeeded; x++)
            {
                updateGame();
                shouldRepaint=true;
                updateCount++;
            }

            if(shouldRepaint)
            {
                paintCount++;
                repaint();
            }
            try
            {
                Thread.sleep(5);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics bg = buffer.getGraphics();

        bg.setColor(Color.BLACK);
        bg.drawRect(0,300,300,50);
        bg.setColor(Color.RED);
        bg.fillRect(x,y,35,35);

        g.drawImage(buffer,0,0,null);
    }

    public void updateGame()
    {
        box.updateHitbox(x,y);
        if(down)
        {
            if(!box.center.intersects(rect))
            {
                y++;
                //y=y+40;
            }

        }
        else if(up)
        {
            if(!box.center.intersects(rect))
            {
                y--;
            }
        }

    }

    public void keyPressed(KeyEvent e)
    {
        int code = e.getKeyCode();

        if(code==KeyEvent.VK_A)
        {
            left=true;
            right=false;
            aLeft=true;
            aRight=false;
            aDown=false;
            aUp=false;

        }
        if(code==KeyEvent.VK_D)
        {
            left=false;
            right=true;
            aLeft=false;
            aRight=true;
            aDown=false;
            aUp=false;
        }
        if(code==KeyEvent.VK_S)
        {
            System.out.println(y);

            down=true;
            up=false;
            aLeft=false;
            aRight=false;
            aDown=true;
            aUp=false;
        }
        if(code==KeyEvent.VK_W)
        {
            down=false;
            up=true;
            aLeft=false;
            aRight=false;
            aDown=false;
            aUp=true;
        }

        repaint();
    }
    public void keyTyped(KeyEvent e)
    {

    }
    public void keyReleased(KeyEvent e)
    {
        int code = e.getKeyCode();

        if(code==e.VK_A)
        {
            left=false;
            aLeft=false;
        }
        if(code==e.VK_D)
        {
            right=false;
            aRight=false;
        }
        if(code==e.VK_S)
        {
            down=false;
            aDown=false;
        }
        if(code==e.VK_W)
        {
            up=false;
            aUp=false;
        }
    }

    public void addNotify()
    {
        // call super so the method still does what it was built to do
        super.addNotify();

        // requests focus so that key inputs are sent to this screen
        requestFocus();
    }
}

和Hb类:

import java.awt.Rectangle;

public class Hb
{
public Rectangle center,left,right,up,down;

public Hb(int x, int y)
{
    center = new Rectangle(x,y,50,50);
    left = new Rectangle(x-1,y+1,1,48);
    right = new Rectangle(x+50,y+1,1,48);
    up = new Rectangle(x+1,y-1,48,1);
    down = new Rectangle(x+1,y+50,48,1);
}

public void updateHitbox(int x, int y)
{
    center = new Rectangle(x,y,50,50);
    left = new Rectangle(x-1,y+1,1,48);
    right = new Rectangle(x+50,y+1,1,48);
    up = new Rectangle(x+1,y-1,48,1);
    down = new Rectangle(x+1,y+50,48,1);
}
}

1 个答案:

答案 0 :(得分:3)

你的问题是你在BufferedImage中进行了所有绘图,并且不能删除&#34;脏&#34;像素。相反,只能在BufferedImage中绘制应该是图像的静态且不变的部分,通常是背景。移动的前景图像应使用JVM为方法提供的Graphcis对象直接在paintComponent中绘制。

public P() {
    super();
    setSize(600, 350);  // not recommended
    buffer = new BufferedImage(600, 350, BufferedImage.TYPE_4BYTE_ABGR);
    Graphics bg = buffer.getGraphics();
    bg.setColor(Color.BLACK);
    bg.drawRect(0, 300, 300, 50);
    bg.dispose();

    // ....

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(buffer, 0, 0, null);
    g.setColor(Color.RED);
    g.fillRect(x, y, 35, 35);
}