简体   繁体   English

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

[英]How can I make image appear randomly every x seconds in java using timer?

I'm working on a game in which I need to 'hit' a mouse/rat, it will disappear and you'll get 1 point. 我正在开发一款游戏,我需要“击中”一只老鼠/老鼠,它会消失,你会得到1分。 I made it randomly appear everytime i start the app, but I want the image te be drawn randomly every x seconds using Timer() or something. 我每次启动应用程序时都会随机出现,但我希望每隔x秒使用Timer()或其他东西随机绘制图像。

My code for the game screen looks like this: 我的游戏屏幕代码如下所示:

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");
            }
        }
}

as you can see I'm using g.drawImage(muisje, random(0, this.getWidth()), random(0, this.getHeight()), null); 你可以看到我正在使用g.drawImage(muisje,random(0,this.getWidth()),random(0,this.getHeight()),null);

So it randomly add the image on startup. 所以它在启动时随机添加图像。

How can I use a timer to do this every x seconds when the app is openend? 当应用程序开启时,如何使用计时器每隔x秒执行此操作?

"How can I use a timer to do this every x seconds when the app is openend?" “当应用程序开启时,如何每隔x秒使用计时器执行此操作?”

Have a look at this example. 看看这个例子。 I gathered Images from the internet, but you can do the same using image files. 我从互联网上收集了图像,但你可以使用图像文件来做同样的事情。 What I did was use an array of URL and BufferedImage and got a random index ever 500 milliseconds and repaint() the panel 我做的是使用一个URLBufferedImage数组,并获得一个500毫秒的随机索引并repaint()面板

Note If you are going to use image files, you may want to look at this answer also. 注意如果要使用图像文件,也可以查看此答案

在此输入图像描述

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);
        }
    }
}

Notice the Timer code. 注意Timer代码。 This is all I did 这就是我所做的一切

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

And for the .grawImage I use a random index from the array of BufferedImages 对于.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);
}

UPDATE Example. 更新示例。 I shut down my IDE for the night. 我关闭了我的IDE过夜。 Too lazy to open so I'm just going to come up with this as I go. 太懒了打开所以我只想在我走的时候拿出来。 If you still don't it, I'll add a real example tomorrow when I get up. 如果你还没有,我会在明天起床时添加一个真实的例子。

Basically you want to have global variable for the x and y locations of the mouse image 基本上,您希望为鼠标图像的x和y位置设置全局变量

int x = 0;
int y = 0;

When you draw the image, you want to use these locations 绘制图像时,您希望使用这些位置

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

In the timer, you can modify the x and y randomly before you paint. 在计时器中,您可以在绘制之前随机修改x和y。 Let use some logic. 让我们用一些逻辑。

Let say your scree width is 500 and screen height is 500 and mouse image width is 100 and mouse image height is 100 假设您的scree宽度为500,屏幕高度为500,鼠标图像宽度为100,鼠标图像高度为100

  • So the max x location will be 400 = screen width - mouse image width 所以max x位置将是400 =屏幕宽度 - 鼠标图像宽度
  • And max y location will be 400 = screen height - mouse image height 并且最大y位置将是400 =屏幕高度 - 鼠标图像高度

So now we have our ranges. 所以现在我们有了我们的范围。 We know min x location is 0 and min y location is 0. So we want a random number from 0 to 400 for each x and y. 我们知道min x位置是0而min y位置是0.所以我们想要每个x和y的0到400的随机数。 So in the timer you can do 所以在计时器中你可以做到

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

This will repaint your mouse image at a random location every time repaint is called. 每次调用重绘时,这将在随机位置重新绘制鼠标图像。


UPDATE 2 更新2

I don't know what else is there to explain. 我不知道还有什么可以解释。 I did just those things I pointed out(with my original code), just added an x and y and used them to draw the image, and got a random location in the timer . 我做我指出的那些事情(用我的原始代码),只是添加了一个xy并用它们来绘制图像,并在timer得到一个随机位置。 It's works perfectly fine for me. 它对我来说非常好。 I don't know what you're doing wrong. 我不知道你做错了什么。

在此输入图像描述

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);
        }
    }
}

Well i am a beginner too. 我也是初学者。 So if i misguide you i am sorry in advance. 所以,如果我误导你,我很抱歉。 Thats my first answer. 这是我的第一个答案。 What you are looking for is probably this 您正在寻找的可能就是这个
System.currentTimeMillis();
this will give the current time as milisecs. 这将使当前时间为milisecs。 So You will probably want to use another float to calculate passed time and lets name it deltaTime. 因此,您可能希望使用另一个浮点数来计算传递时间,并将其命名为deltaTime。 You can find deltaTime by deltaTime=System.currentTimeMillis(); 您可以通过deltaTime=System.currentTimeMillis();找到deltaTime deltaTime=System.currentTimeMillis(); use this before while loop in run method. 在run方法中使用while while循环。 Then inside the loop, if System.currentTimeMillis()-deltaTime is bigger than x number(miliseconds), spawn a rat. 然后在循环内部,如果System.currentTimeMillis()-deltaTime大于x数(毫秒),则产生一只老鼠。 And reset deltaTime. 并重置deltaTime。

And I see you didn't declared ax,y position integer to store rats x and y location. 而且我看到你没有声明ax,y位置整数来存储老鼠的x和y位置。 So declare 2 global variables for x and y of rats. 因此,为x和y大鼠声明2个全局变量。 if rats multiple that x and y int should be arrays with enough room to keep all your rats positions. 如果老鼠倍数x和y int应该是阵列有足够的空间来保持你所有的老鼠位置。

Make an method so every time a rat spawns, x and y of rat's location gets a random int. 制定一个方法,这样每当老鼠产生时,大鼠位置的x和y都会得到一个随机的int。 You actually figured it out in graphics section. 你实际上在图形部分找到了它。 But random function shouldn't be in there. 但随机功能不应该在那里。 Instead of random function x and y integers should be there. 而不是随机函数x和y整数应该在那里。 In your code it will randomize location of rat everytime it updates graphics. 在你的代码中,它会在每次更新图形时随机化鼠标的位置。 No that's not what you want (probably). 不,这不是你想要的(可能)。

One more thing, your code actually won't work without update method called. 还有一件事,如果没有调用更新方法,您的代码实际上将无法工作。 You should put update(); 你应该把update(); at the end of your while loop. 在你的while循环结束时。

Sorry if i am mistaken or not clear enough. 对不起,如果我弄错了或不够清楚。 I am only a beginner interested in the same topics before. 我以前只是对同一主题感兴趣的初学者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM