Как я могу заставить изображение появляться случайным образом каждые x секунд в Java, используя таймер?

Я работаю над игрой, в которой мне нужно "ударить" мышь / крысу, она исчезнет, ​​и вы получите 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 ответа

Решение

"Как я могу использовать таймер, чтобы делать это каждые x секунд, когда приложение открыто?"

Посмотрите на этот пример. Я собрал изображения из интернета, но вы можете сделать то же самое, используя файлы изображений. Я использовал массив URL а также BufferedImage и получил случайный индекс каждые 500 миллисекунд и repaint() панель

Примечание. Если вы собираетесь использовать файлы изображений, возможно, вы захотите посмотреть и на этот ответ.

введите описание изображения здесь

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/stackru_chicklet.png");
                urls[1] = new URL("http://www.iconsdb.com/icons/download/orange/stackru-256.png");
                urls[2] = new URL("http://img.1mobile.com/market/screenshot/50/com.dd.stackru/0.png");
                urls[3] = new URL("http://www.iconsdb.com/icons/download/orange/stackru-4-512.png");
                urls[4] = new URL("http://www.iconsdb.com/icons/preview/light-gray/stackru-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 перед тем, как рисовать. Давайте использовать некоторую логику.

Допустим, ваша ширина экрана составляет 500, а высота экрана равна 500, а ширина изображения мыши равна 100, а высота изображения мыши равна 100

  • Таким образом, максимальное значение x будет 400 = ширина экрана - ширина изображения мыши
  • И max y location будет 400 = высота экрана - высота изображения мыши

Так что теперь у нас есть наши диапазоны. Мы знаем, что min x location равно 0, а min y location равно 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

Я не знаю, что еще можно объяснить. Я сделал только те вещи, которые я указал (с моим исходным кодом), просто добавил x а также y и использовал их, чтобы нарисовать изображение, и получил случайное место в timer, Это прекрасно работает для меня. Я не знаю, что ты делаешь неправильно.

введите описание изображения здесь

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/stackru_chicklet.png");
                urls[1] = new URL("http://www.iconsdb.com/icons/download/orange/stackru-256.png");
                urls[2] = new URL("http://img.1mobile.com/market/screenshot/50/com.dd.stackru/0.png");
                urls[3] = new URL("http://www.iconsdb.com/icons/download/orange/stackru-4-512.png");
                urls[4] = new URL("http://www.iconsdb.com/icons/preview/light-gray/stackru-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);
        }
    }
}

Ну, я тоже новичок. Поэтому, если я введу вас в заблуждение, заранее извините. Это мой первый ответ. То, что вы ищете, вероятно, это
System.currentTimeMillis();
это даст текущее время как милисек. Таким образом, вы, вероятно, захотите использовать другое число с плавающей точкой для вычисления пройденного времени и назовем его deltaTime. Вы можете найти deltaTime по deltaTime=System.currentTimeMillis(); используйте это перед циклом while в методе run. Тогда внутри цикла, если System.currentTimeMillis()-deltaTime больше, чем число х (милисекунды), порождает крысу. И сбросьте deltaTime.

И я вижу, что вы не объявили a x,y position целое число для хранения крыс x и y location. Итак, объявите 2 глобальные переменные для х и у крыс. если крысы кратны, то x и y int должны быть массивами с достаточным пространством, чтобы сохранить все ваши позиции крыс.

Создайте метод, чтобы каждый раз, когда крыса появлялась, x и y местоположения крысы получали случайное значение int. Вы действительно поняли это в графическом разделе. Но случайной функции там быть не должно. Вместо случайной функции должны быть целые числа x и y. В вашем коде он будет случайным образом определять местоположение крысы при каждом обновлении графики. Нет, это не то, что вы хотите (вероятно).

Еще одна вещь, ваш код на самом деле не будет работать без вызова метода обновления. Вы должны положить update(); в конце вашего цикла while.

Извините, если я ошибаюсь или недостаточно ясно. Я только новичок, интересующийся такими же темами раньше.

Другие вопросы по тегам