java - 对绘制的对象进行动画处理

标签 java swing graphics paint

我已经为我的对象创建了类,并在我的绘画组件中调用它们,但我实际上无法让它们移动。这是我在对象类中的移动和检查墙程序:

public void move()
{
    ballX += dx;
    ballY += dy;

    checkWalls();
}

//bounce of top/bottom, pass through left/right
public void checkWalls() {
    //left-right
    if(ballX > w) {
        ballX = -diam;
    }
    else if(ballX < -diam) {
        ballX = w;
    }

    //top-bottom
    if(ballY < 0) {
        dy *= -1;
    }
    else if(ballY + diam > h) {
        dy *= -1;
    }
}

这是我对他们的呼吁:

while(true) // infinite loop 
{
    jelly1.move();

    frame.repaint();

    try
    {
        Thread.sleep(10);
    }
    catch(Exception e){}
}

此外,我觉得有必要提及我有一个背景和一个背景组件。 while(true) 位于后台组件中,因为那是创建对象的地方。并且框架被设置为在 main 方法所在的背景中可见。

Paint组件如下:

public class BackgroundComponent extends JComponent {
    Jellyfish jelly1;
    Jellyfish jelly2;
    Jellyfish jelly3;
    Diver diver;

    public BackgroundComponent() {
        diver = new Diver(100, 300);
        jelly1 = new Jellyfish(450, 450);
        jelly2 = new Jellyfish(150, 300);
        jelly3 = new Jellyfish(350, 75);
        diver = new Diver(100, 300);
    }


    public void paintComponent(Graphics g){
        //Drawing instructions go here
        //Recover Graphics2D
        Graphics2D g2 = (Graphics2D)g;
        //Make gradient
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        int w = getWidth();
        int h = getHeight();
        Color color1 = Color.CYAN;
        Color color2 = Color.BLACK;
        GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
        g2.setPaint(gp);
        g2.fillRect(0, 0, w, h);
        //Constructs rectangles on edge of screen and draws them
        Rectangle box = new Rectangle(0,0,75,700);
        g.setColor(Color.LIGHT_GRAY);
        g2.fill(box);
        Rectangle box2 = new Rectangle(625, 0, 75, 700);
        g.setColor(Color.LIGHT_GRAY);
        g2.fill(box2);
        //Draws lines, with a stroke of 5, over rectangles
        Line2D.Double segment = new Line2D.Double(10, 0, 10, 700);
        g2.setStroke(new BasicStroke(5));
        g.setColor(Color.GRAY);
        g2.draw(segment);
        Line2D.Double segment2 = new Line2D.Double(30, 0, 30, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment2);
        Line2D.Double segment3 = new Line2D.Double(50, 0, 50, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment3);
        Line2D.Double segment4 = new Line2D.Double(70, 0, 70, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment4);
        Line2D.Double segment5 = new Line2D.Double(690, 0, 690, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment5);
        Line2D.Double segment6 = new Line2D.Double(670, 0, 670, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment6);
        Line2D.Double segment7 = new Line2D.Double(650, 0, 650, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment7);
        Line2D.Double segment8 = new Line2D.Double(630, 0, 630, 700);
        g.setColor(Color.GRAY);
        g2.draw(segment8);
        //Draws rectangle around title with thick boarder
        Rectangle box3 = new Rectangle(40,40,620,75);
        g.setColor(Color.WHITE);
        g2.setStroke(new BasicStroke(5));
        g2.draw(box3);
        //Drawing text
        String title = "Through the Depths";
        //Sets font, font size, and color
        g.setFont(new Font("Purisa", Font.BOLD, 50));
        g.setColor(Color.DARK_GRAY);
        g2.drawString(title, (50), 100);
        //Places same text slightly up and over
        g.setFont(new Font("Purisa", Font.BOLD, 50));
        g.setColor(Color.WHITE);
        g2.drawString(title, 53, 97);
        //Draws ellipses with a stroke of 2 (these are the bubbles)
        Ellipse2D.Double ellipse = new Ellipse2D.Double(450, 200, 150, 150);
        g2.setStroke(new BasicStroke(2));
        g2.draw(ellipse);
        Ellipse2D.Double ellipse2 = new Ellipse2D.Double(510, 375, 90, 90);
        g2.draw(ellipse2);
        Ellipse2D.Double ellipse3 = new Ellipse2D.Double(470, 485, 70, 70);
        g2.draw(ellipse3);
        Ellipse2D.Double ellipse4 = new Ellipse2D.Double(510, 580, 45, 45);
        g2.draw(ellipse4);
        // Draws curves for bubbles
        QuadCurve2D q = new QuadCurve2D.Float();
        q.setCurve(548, 210, 607, 240, 590, 295);
        g2.setStroke(new BasicStroke(3));
        g2.draw(q);
        QuadCurve2D q2 = new QuadCurve2D.Float();
        q2.setCurve(575, 387, 607, 415, 585, 445);
        g2.draw(q2);
        QuadCurve2D q3 = new QuadCurve2D.Float();
        g2.setStroke(new BasicStroke(2));
        q3.setCurve(515, 493, 545, 511, 528, 540);      
        g2.draw(q3);
        QuadCurve2D q4 = new QuadCurve2D.Float();
        g2.setStroke(new BasicStroke(1));
        q4.setCurve(538, 585, 558, 595, 545, 617);
        g2.draw(q4);
        // Sets color to pink before drawing jellyfish
        g.setColor(Color.PINK);
        //draws jellyfish
        jelly1.draw(g);
        jelly2.draw(g);
        jelly3.draw(g);
        // Draws diver
        diver.draw(g);
        while(true) // infinite loop 
        {
        jelly1.move();


        repaint();

        try
        {
        Thread.sleep(10);
        }
        catch(Exception e){}
        }
        }
}

最佳答案

while(true){ ... }Thread.Sleep里面 paintComponent实现完全是错误的做事方式。通过这样做,您将阻止 Event Dispatching Thread完全,这意味着您的 UI 将不再正确更新,并且 UI 将不再响应。

你应该做什么:

  • 删除 while(true){ ... }paintComponent循环覆盖
  • 创建 javax.swing.Timer ,将其设置为每 10 毫秒运行一次
  • ActionListener.actionPerformed实现 - 每 10 毫秒执行一次的操作 - 移动果冻并调用 repaint
  • 在初始化完成后启动此计时器,例如在构造函数或初始化方法(不是paintComponent)的末尾。
  • 不再需要时停止计时器
<小时/>

根据您的代码片段,此计时器的简化示例:

new javax.swing.Timer( 10, new ActionListener( ) {
    @override
    public void actionPerformed( ActionEvent e ) {
        jelly1.move();
        repaint();
    }
}).start();

关于java - 对绘制的对象进行动画处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35244365/

相关文章:

java - 使用 OnClick 方法更改数组的长度

java - 使用 ByteBuffer 处理 byte[]

java - 从 JTable 解析的 double 总和

java - 如何在JPanel中设置背景图片

visual-c++ - Gdiplus 64 位颜色

java - 全局双鼠标点击中心和全局鼠标点击中心有什么区别

java - 在 Play Framework 2 上使用 ManyToOne 字段绑定(bind)表单请求

java - 一些 2D Java 代码问题

Java 上边界图形

java - 旋转和缩放——如何同时进行并获得正确的结果?