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