【问题标题】:Image circling the window using JApplet使用 JApplet 环绕窗口的图像
【发布时间】:2015-11-12 13:01:13
【问题描述】:

所以这就是我卡住的地方......我让它水平走到窗口的尽头,然后下降,但我不知道如何让它在到达窗口底部后向左移动并且然后当它到达屏幕的左侧时上升。 谢谢,

import javax.swing.*;
import java.awt.*;
public class AnimatedImageApplet extends JApplet implements Runnable {

private static final long serialVersionUID = 1L;
private Thread t = null;
private Image image;
private int x = 0;
private int y = 0;
private static final int vx = 1;
private static final int vy= 1;
private boolean horizontal = true;
private boolean vertical = true;

public void init() {
    image = getImage(getDocumentBase(), "face.png");
}

public void start() {
    if (t == null) {
        t = new Thread(this);
        t.start();
    }
}

public void paint(Graphics canvas) {
    canvas.fillRect(0,0,getWidth(),getHeight());
    synchronized (this) {
        canvas.drawImage(image, x, y, this);
    }
}

@Override
public void run() {
    int direction = 1;
    while (true) {
        synchronized (this) {
            x += vx * direction;
            y += vy * (horizontal ? 0 : 1);
            if (x + image.getWidth(this) == getWidth()) {
                horizontal = false;
                direction = 0;
            }
        }
        repaint();
        try {
            Thread.sleep(15);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}

【问题讨论】:

  • 有一个 x/y 增量,当不需要时,只需将其设置为 0,当您到达其中一个边界(垂直/水平)时,将另一个增量设置为非 0 值跨度>
  • 我一直盯着这段代码太久了。迷路了,不过还是谢谢。

标签: java animation applet japplet


【解决方案1】:

从概念上讲,这个想法很简单。当你到达你的一个边缘时,你需要改变你的运动方向。

if x + image.width > width then go down
else if x < 0 then go up
else if y + image.height > height then go left
else if y < 0 then go right

用于顺时针运动。

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MoveTest {

    public static void main(String[] args) {
        new MoveTest();
    }

    public MoveTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;

        private int xDelta = 2;
        private int yDelta = 0;

        private int x, y = 0;

        public TestPane() {
            try {
                img = ImageIO.read(...);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            Timer timer = new Timer(15, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    x += xDelta;
                    y += yDelta;
                    if (x + img.getWidth() > getWidth()) {
                        x = getWidth() - img.getWidth();
                        xDelta = 0;
                        yDelta = 2;
                    } else if (x < 0) {
                        x = 0;
                        xDelta = 0;
                        yDelta = -2;
                    }
                    if (y + img.getHeight() > getHeight()) {
                        y = getHeight() - img.getHeight();
                        xDelta = -2;
                        yDelta = 0;
                    } else if (y < 0) {
                        y = 0;
                        xDelta = 2;
                        yDelta = 0;
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(img, x, y, this);
            g2d.dispose();
        }

    }

}

你应该小心 Swing 中的线程,因为 Swing 不是线程保存。查看Concurrency in SwingHow to use Swing Timers 了解更多详情

【讨论】:

  • 谢谢。我会怎么做才能点击我希望最初绘制图像的位置?
  • 添加一个MouseLiistener,当mouseClicked被调用时,记录点击的x/y点然后启动Timer
猜你喜欢
  • 2013-11-06
  • 2023-01-28
  • 1970-01-01
  • 2017-01-26
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多