如何使用计时器在java中每隔x秒随机显示图像?

时间:2014-01-22 16:56:59

标签: java random timer jpanel

我正在制作一款游戏,我需要“击中”一只老鼠/老鼠,它会消失,你会得到1分。 我每次启动应用程序时都会随机出现,但我希望每隔x秒使用Timer()或其他东西随机绘制图像。

我的游戏屏幕代码如下:

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Gamevenster extends JPanel implements Runnable {
        public String Gamestatus = "active";
        private Thread thread;
        //public Main game;

    public int random(int min, int max) {
         int range = (max - min) + 1;     
        return (int)(Math.random() * range) + min;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawImage(achtergrond, 0, 0, this.getWidth(), this.getHeight(), null);
        //g.drawImage(muisje, 10, 10, null);
        g.drawImage(muisje, random(0, this.getWidth()), random(0, this.getHeight()), null);
    }

    private static final long serialVersionUID = 1L;

        Image achtergrond, muisje;
        JTextField invoer;
        JButton raden;
        JButton menu;

        Gamevenster() {
        setLayout(null);

        ImageIcon icon = new ImageIcon(this.getClass().getResource("assets/achtergrondspel.png"));
        achtergrond = icon.getImage();      

        ImageIcon icon2 = new ImageIcon(this.getClass().getResource("assets/muisje.png"));
        muisje = icon2.getImage();   

        //Get the default toolkit  
        Toolkit toolkit = Toolkit.getDefaultToolkit();  

        //Load an image for the cursor  
        Image image = toolkit.getImage("src/assets/hand.png");  

        //Create the hotspot for the cursor  
        Point hotSpot = new Point(0,0);

        //Create the custom cursor  
        Cursor cursor = toolkit.createCustomCursor(image, hotSpot, "Hand");

        //Use the custom cursor  
        setCursor(cursor);

        // setLayout( null );

        // Invoer feld
        invoer = new JTextField(10);
        invoer.setLayout(null);
        invoer.setBounds(150, 474, 290, 60); // Verander positie onder aan scherm is int 1

        // Button voor raden
        raden = new JButton("Raden");
        raden.setLayout(null);
        raden.setBounds(10, 474, 130, 60);
        raden.setFont(new Font("Dialog", 1, 20));
        raden.setForeground(Color.white);
        raden.setBackground(new Color(46, 204, 113));
        raden.setPreferredSize(new Dimension(130, 60));

        // Menu knop
        menu = new JButton("Menu");
        menu.setLayout(null);
        menu.setBounds(450, 474, 130, 60);
        menu.setFont(new Font("Dialog", 1, 20));
        menu.setForeground(Color.white);
        menu.setBackground(new Color(46, 204, 113));
        menu.setPreferredSize(new Dimension(130, 60));

        // Toevoegen aan screen
        add(invoer);
        //add(raden);
        add(menu);

        menu.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
        String i = invoer.getText();
        System.out.println("Er is gedrukt! " + i);
                }
            });
        }

        public void start(){
            thread = new Thread(this,"spelloop");
            thread.start();
        }

        public void run() {
            // TODO Auto-generated method stub
            while(Gamestatus=="active"){
                System.out.println("Gameloop werkt");
            }
        }
}

你可以看到我正在使用g.drawImage(muisje,random(0,this.getWidth()),random(0,this.getHeight()),null);

因此它会在启动时随机添加图像。

当应用程序开启时,如何每隔x秒使用计时器执行此操作?

2 个答案:

答案 0 :(得分:2)

  

“当应用程序开启时,如何每隔x秒使用计时器执行此操作?”

看看这个例子。我从互联网上收集了图像,但你可以使用图像文件来做同样的事情。我所做的是使用一个URLBufferedImage数组,并获得一个随机索引500毫秒和repaint()面板

注意如果您要使用图像文件,也可以查看this answer

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestImageRotate {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new JFrame("Image Timer");
                frame.add(new ImagePanel());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class ImagePanel extends JPanel {

        URL[] urls;
        BufferedImage[] images;
        Random rand = new Random();

        public ImagePanel() {
            urls = new URL[5];
            try {
                urls[0] = new URL("http://www.atomicframework.com/assetsY/img/stackoverflow_chicklet.png");
                urls[1] = new URL("http://www.iconsdb.com/icons/download/orange/stackoverflow-256.png");
                urls[2] = new URL("http://img.1mobile.com/market/screenshot/50/com.dd.stackoverflow/0.png");
                urls[3] = new URL("http://www.iconsdb.com/icons/download/orange/stackoverflow-4-512.png");
                urls[4] = new URL("http://www.iconsdb.com/icons/preview/light-gray/stackoverflow-xxl.png");

                images = new BufferedImage[5];
                images[0] = ImageIO.read(urls[0]);
                images[1] = ImageIO.read(urls[1]);
                images[2] = ImageIO.read(urls[2]);
                images[3] = ImageIO.read(urls[3]);
                images[4] = ImageIO.read(urls[4]);

            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            setBackground(Color.BLACK);

            Timer timer = new Timer(500, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.start();
        }

        private int random() {
            int index = rand.nextInt(5);
            return index;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            BufferedImage img = images[random()];
            g.drawImage(img, 0, 0, 400, 400, 0, 0,
                    img.getWidth(), img.getHeight(), this);
        }

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

请注意Timer代码。这就是我所做的一切

Timer timer = new Timer(500, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }
});
timer.start();

对于.grawImage,我使用BufferedImages

数组中的随机索引
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    BufferedImage img = images[random()];
    g.drawImage(img, 0, 0, 400, 400, 0, 0,
                           img.getWidth(), img.getHeight(), this);
}

更新示例。我关闭了我的IDE过夜。太懒了打开所以我只想在我走的时候拿出来。如果你还没有,我会在明天起床时添加一个真实的例子。

基本上你想要为鼠标图像的x和y位置设置全局变量

int x = 0;
int y = 0;

绘制图像时,您想要使用这些位置

g.drawImage(img, x, y, whatEverWidth, whatEverHeight, this);

在计时器中,您可以在绘制之前随机修改x和y。让我们用一些逻辑。

假设你的scree宽度为500,屏幕高度为500,鼠标图像宽度为100,鼠标图像高度为100

  • 因此,最大x位置将为400 =屏幕宽度 - 鼠标图像宽度
  • 最大y位置将为400 =屏幕高度 - 鼠标图像高度

所以现在我们有了我们的范围。我们知道min x位置是0而min y位置是0.所以我们想要每个x和y的0到400的随机数。所以在计时器中你可以做到

Timer timer = new Timer(1000, new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        x = rand.nextInt(400) + 1;     
        y = rand.nextInt(400) + 1;
        repaint();   
    }
});

每次调用重绘时,这将在随机位置重新绘制鼠标图像。


更新2

我不知道还有什么可以解释。我做了只是我指出的那些事情(使用我的原始代码),只添加了xy并使用它们来绘制图像,并获得了一个随机位置timer。它对我来说非常好。我不知道你做错了什么。

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestImageRotate {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new JFrame("Image Timer");
                frame.add(new ImagePanel());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class ImagePanel extends JPanel {

        URL[] urls;
        BufferedImage[] images;
        Random rand = new Random();
        private int x = 0;
        private int y = 0;

        public ImagePanel() {
            urls = new URL[5];
            try {
                urls[0] = new URL("http://www.atomicframework.com/assetsY/img/stackoverflow_chicklet.png");
                urls[1] = new URL("http://www.iconsdb.com/icons/download/orange/stackoverflow-256.png");
                urls[2] = new URL("http://img.1mobile.com/market/screenshot/50/com.dd.stackoverflow/0.png");
                urls[3] = new URL("http://www.iconsdb.com/icons/download/orange/stackoverflow-4-512.png");
                urls[4] = new URL("http://www.iconsdb.com/icons/preview/light-gray/stackoverflow-xxl.png");

                images = new BufferedImage[5];
                images[0] = ImageIO.read(urls[0]);
                images[1] = ImageIO.read(urls[1]);
                images[2] = ImageIO.read(urls[2]);
                images[3] = ImageIO.read(urls[3]);
                images[4] = ImageIO.read(urls[4]);

            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            setBackground(Color.BLACK);

            Timer timer = new Timer(500, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    x = rand.nextInt(325);
                    y = rand.nextInt(325);
                    repaint();
                }
            });
            timer.start();
        }

        private int random() {
            int index = rand.nextInt(5);
            return index;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            BufferedImage img = images[random()];
            g.drawImage(img, x, y, 75, 75, this);
        }

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

答案 1 :(得分:0)

我也是初学者。所以,如果我误导你,我很抱歉。这是我的第一个答案。您正在寻找的可能就是这个    System.currentTimeMillis();
这将使当前时间为milisecs。因此,您可能希望使用另一个浮点数来计算传递时间,并将其命名为deltaTime。您可以在deltaTime=System.currentTimeMillis();中找到deltaTime,在run方法中使用while循环。然后在循环内,如果System.currentTimeMillis()-deltaTime大于x数(毫秒),则产生一只老鼠。并重置deltaTime。

我看到你没有声明x,y位置整数来存储老鼠的x和y位置。因此,为x和y大鼠声明2个全局变量。如果老鼠倍数x和y int应该是阵列有足够的空间来保持你所有的老鼠位置。

制作方法,这样每当老鼠产生时,大鼠位置的x和y都会随机变成int。你实际上在图形部分找到了它。但随机功能不应该在那里。而不是随机函数x和y整数应该在那里。在你的代码中,它会在每次更新图形时随机化鼠标的位置。不,这不是你想要的(可能)。

还有一件事,如果没有调用更新方法,您的代码实际上将无法工作。您应该将update();放在while循环的末尾。

对不起,如果我弄错了或不够清楚。我以前只是对同一主题感兴趣的初学者。