java撕裂_Java动画中的跳过和撕裂

以下代码绘制了一个正方形,其中两个较小的正方形在其中旋转.每当您单击键盘上的箭头时,整个系统都会朝该方向移动.但是我在图像撕裂和有时跳过时遇到一些问题(它很小,但仍然存在).我想知道是否有人知道如何解决这些问题而无需大量修改代码.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import static java.awt.Color.*;

public class GUI extends JPanel implements ActionListener, KeyListener

{

int x, y, x1, y1, x2, y2, changeX, changeY, changeX2, changeY2;

JFrame frame;

Runtime r;

public static void main(String[] args)

{

new GUI();

}

public GUI()

{

try

{

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (Exception e)

{

e.printStackTrace();

}

setSize(1020,770);

setBackground(WHITE);

setOpaque(true);

setVisible(true);

x = 0;

y = 0;

x1 = 0;

y1 = 0;

x2 = 0;

y2 = 0;

changeX=1;

changeY=0;

changeX2=1;

changeY2=0;

r = Runtime.getRuntime();

frame = new JFrame();

frame.setSize(1020,819);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setJMenuBar(createMenuBar());

frame.validate();

frame.setBackground(WHITE);

frame.addKeyListener(this);

frame.setTitle("GUI");

frame.setContentPane(this);

frame.setVisible(true);

frame.createBufferStrategy(2);

Timer t = new Timer(100,this);

t.setActionCommand("Draw");

t.start();

repaint();

}

public JMenuBar createMenuBar()

{

JMenuBar menuBar = new JMenuBar();

JMenu fileMenu = new JMenu("File");

JMenuItem save = new JMenuItem("Save");

save.setMnemonic(KeyEvent.VK_S);

save.setContentAreaFilled(false);

save.setOpaque(false);

save.addActionListener(this);

JMenuItem load = new JMenuItem("Load");

load.setMnemonic(KeyEvent.VK_L);

load.setContentAreaFilled(false);

load.setOpaque(false);

load.addActionListener(this);

JMenuItem quit = new JMenuItem("Quit");

quit.setMnemonic(KeyEvent.VK_Q);

quit.setContentAreaFilled(false);

quit.setOpaque(false);

quit.addActionListener(this);

fileMenu.add(save);

fileMenu.add(load);

fileMenu.addSeparator();

fileMenu.add(quit);

fileMenu.setContentAreaFilled(false);

fileMenu.setBorderPainted(false);

fileMenu.setOpaque(false);

JMenu editMenu = new JMenu("Edit");

JMenuItem undo = new JMenuItem("Undo");

undo.setMnemonic(KeyEvent.VK_U);

undo.setContentAreaFilled(false);

undo.setOpaque(false);

undo.addActionListener(this);

JMenuItem redo = new JMenuItem("Redo");

redo.setMnemonic(KeyEvent.VK_R);

redo.setContentAreaFilled(false);

redo.setOpaque(false);

redo.addActionListener(this);

editMenu.add(undo);

editMenu.add(redo);

editMenu.setContentAreaFilled(false);

editMenu.setBorderPainted(false);

editMenu.setOpaque(false);

JMenu helpMenu = new JMenu("Help");

JMenuItem controls = new JMenuItem("Controls");

controls.setMnemonic(KeyEvent.VK_C);

controls.setContentAreaFilled(false);

controls.setOpaque(false);

controls.addActionListener(this);

JMenuItem about = new JMenuItem("About");

about.setMnemonic(KeyEvent.VK_A);

about.setContentAreaFilled(false);

about.setOpaque(false);

about.addActionListener(this);

helpMenu.add(controls);

helpMenu.addSeparator();

helpMenu.add(about);

helpMenu.setContentAreaFilled(false);

helpMenu.setBorderPainted(false);

helpMenu.setOpaque(false);

menuBar.add(fileMenu);

menuBar.add(editMenu);

menuBar.add(helpMenu);

return menuBar;

}

public void paintComponent(Graphics g)

{

g.clearRect(0, 0, 1020, 770);

g.setColor(BLACK);

g.fillRect(x,y,100,100);

g.setColor(RED);

g.fillRect(x1,y1,50,50);

g.setColor(BLUE);

g.fillRect(x2,y2,25,25);

g.dispose();

}

public void change()

{

if(x1>=x+50&&changeY==0&&changeX==1)

{

changeX=0;

changeY=1;

}

else if(y1>=y+50&&changeX==0&&changeY==1)

{

changeX=-1;

changeY=0;

}

else if(x1<=x&&changeX==-1&&changeY==0)

{

changeX=0;

changeY=-1;

}

else if(y1<=y&&changeY==-1&&changeX==0)

{

changeX=1;

changeY=0;

}

x1+=changeX*5;

y1+=changeY*5;

}

public void change2()

{

if(x2>=x1+25&&changeY2==0&&changeX2==1)

{

changeX2=0;

changeY2=1;

}

else if(y2>=y1+25&&changeX2==0&&changeY2==1)

{

changeX2=-1;

changeY2=0;

}

else if(x2<=x1&&changeX2==-1&&changeY2==0)

{

changeX2=0;

changeY2=-1;

}

else if(y2<=y1&&changeY2==-1&&changeX2==0)

{

changeX2=1;

changeY2=0;

}

x2+=changeX2*2;

y2+=changeY2*2;

}

public void actionPerformed(ActionEvent e)

{

if(e.getActionCommand().equalsIgnoreCase("Draw"))

{

r.runFinalization();

r.gc();

change();

change2();

repaint();

}

}

public void keyPressed(KeyEvent e)

{

if(e.getKeyCode()==KeyEvent.VK_UP)

{

if(y-10>=0)

{

y-=10;

y1-=10;

y2-=10;

}

}

if(e.getKeyCode()==KeyEvent.VK_DOWN)

{

if(y+110<=getHeight())

{

y+=10;

y1+=10;

y2+=10;

}

}

if(e.getKeyCode()==KeyEvent.VK_LEFT)

{

if(x-10>=0)

{

x-=10;

x1-=10;

x2-=10;

}

}

if(e.getKeyCode()==KeyEvent.VK_RIGHT)

{

if(x+110<=getWidth())

{

x+=10;

x1+=10;

x2+=10;

}

}

repaint();

}

public void keyReleased(KeyEvent e)

{

}

public void keyTyped(KeyEvent e)

{

}

}

解决方法:

您不是在EDT上构建.由于动作事件处理程序在EDT上执行,因此javax.swing.Timer的实例使此操作变得容易.

附录1:您可能会决定需要double buffering,但首先将下面的代码与您的代码进行比较,然后看看.如果您走那条路线,则可以查看此tutorial.

附录2:下面的示例显示了如何维护屏幕外缓冲区,但是有时使用JPanel(boolean isDoubleBuffered)构造函数更容易获得类似效果.

import java.awt.event.KeyAdapter;

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.Graphics;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.Timer;

import static java.awt.Color.*;

/** @see https://stackoverflow.com/questions/2114455 */

public class GUI extends JPanel implements ActionListener {

int x, y, x1, y1, x2, y2, changeY, changeY2;

int changeX = 1; int changeX2 = 1;

Timer t = new Timer(100, this);

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

new GUI(true).display();

}

});

}

public GUI(boolean doubleBuffered) {

super(doubleBuffered);

this.setPreferredSize(new Dimension(320, 240));

}

private void display() {

JFrame frame = new JFrame("GUI");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.addKeyListener(new KeyListener());

frame.add(this);

frame.pack();

frame.setVisible(true);

t.start();

}

@Override

public void paintComponent(Graphics g) {

g.setColor(WHITE);

g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(BLACK);

g.fillRect(x, y, 100, 100);

g.setColor(RED);

g.fillRect(x1, y1, 50, 50);

g.setColor(BLUE);

g.fillRect(x2, y2, 25, 25);

}

public void change() {

if (x1 >= x + 50 && changeY == 0 && changeX == 1) {

changeX = 0;

changeY = 1;

} else if (y1 >= y + 50 && changeX == 0 && changeY == 1) {

changeX = -1;

changeY = 0;

} else if (x1 <= x && changeX == -1 && changeY == 0) {

changeX = 0;

changeY = -1;

} else if (y1 <= y && changeY == -1 && changeX == 0) {

changeX = 1;

changeY = 0;

}

x1 += changeX * 5;

y1 += changeY * 5;

}

public void change2() {

if (x2 >= x1 + 25 && changeY2 == 0 && changeX2 == 1) {

changeX2 = 0;

changeY2 = 1;

} else if (y2 >= y1 + 25 && changeX2 == 0 && changeY2 == 1) {

changeX2 = -1;

changeY2 = 0;

} else if (x2 <= x1 && changeX2 == -1 && changeY2 == 0) {

changeX2 = 0;

changeY2 = -1;

} else if (y2 <= y1 && changeY2 == -1 && changeX2 == 0) {

changeX2 = 1;

changeY2 = 0;

}

x2 += changeX2 * 2;

y2 += changeY2 * 2;

}

@Override

public void actionPerformed(ActionEvent e) {

change();

change2();

repaint();

}

private class KeyListener extends KeyAdapter {

@Override

public void keyPressed(KeyEvent e) {

int d = 5;

if (e.getKeyCode() == KeyEvent.VK_UP) {

if (y - d >= 0) {

y -= d;

y1 -= d;

y2 -= d;

}

}

if (e.getKeyCode() == KeyEvent.VK_DOWN) {

if (y + 100 + d <= getHeight()) {

y += d;

y1 += d;

y2 += d;

}

}

if (e.getKeyCode() == KeyEvent.VK_LEFT) {

if (x - d >= 0) {

x -= d;

x1 -= d;

x2 -= d;

}

}

if (e.getKeyCode() == KeyEvent.VK_RIGHT) {

if (x + 100 + d <= getWidth()) {

x += d;

x1 += d;

x2 += d;

}

}

}

}

}

标签:animation,tearing,java

来源: https://codeday.me/bug/20191210/2100863.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值