简体   繁体   English

Java:如何使JPanel中的ImageIcon在随机持续时间内随机出现/重新出现

[英]Java: How to make an ImageIcon in JPanel appear/reappear randomly for random durations

I am working on an assignment, and I am stuck on one requirement. 我正在做一项作业,但我坚持一项要求。 I have made as much of a good faith effort as I can, and have no choice but to humbly ask for your expertise. 我尽了最大的努力,除了谦虚地要求您提供专业知识外,别无选择。 My assignment requires that I make a simple game in Java where an image is to appear and reappear randomly for random duration. 我的作业要求我用Java做一个简单的游戏,在其中随机出现图像并随机出现。 The user is to click on the image, and if the user clicks on the image, the number of clicks is output to the screen. 用户将单击图像,如果用户单击图像,则将点击数输出到屏幕。 My main question is how do I make said image appear/reappear at random postitions for random durations? 我的主要问题是如何使图像在随机位置随机出现/重复出现? To make the duration random would I somehow set that in the Timer? 为了使持续时间随机,我会以某种方式在计时器中进行设置吗? I tried that and it did not work. 我尝试过,但没有成功。 As for the random positions, I do not even know how to get started coding that, could someone point me in the right direction? 至于随机位置,我什至不知道如何开始编码,有人可以指出我正确的方向吗? Would I do that in the actionPerformed method? 我会在actionPerformed方法中这样做吗?

Anyways, here is my code so far. 无论如何,这是到目前为止的代码。 It compiles, but the movement and speed are smooth and constant. 它可以编译,但运动和速度平稳且恒定。 I need the image to appear/reappear randomly instead of "gliding" at a smooth constant rate. 我需要图像随机出现/重新出现,而不是以平稳的恒定速率“滑行”。

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.Random;

public class CreatureClass extends JPanel
{

   private final int WIDTH = 400, HEIGHT = 300;
   private final int DELAY=20, IMAGE_SIZE = 60;

   Random r = new Random();
   private ImageIcon image;
   private Timer timer;
   private int x, y, moveX, moveY;
   private int catchCount=0;

   //-----------------------------------------------------------------
   //  Sets up the panel, including the timer for the animation.
   //-----------------------------------------------------------------
   public CreatureClass()
   {
      timer = new Timer(DELAY, new CreatureListener());//how to make duration random here?

      addMouseListener (new MouseClickedListener());

      image = new ImageIcon ("UMadBro.gif");

      x = 0; //starting coordinates of image
      y = 40;

      moveX = moveY = 3;//image is shifted 3 pixels every time image is updated. I  
                        // tried setting these to a random number, but it makes the 
                        // image "stuck" in one position. 

      setPreferredSize (new Dimension(WIDTH, HEIGHT));
      setBackground (Color.yellow);
      timer.start();
   }

   //-----------------------------------------------------------------
   //  Draws the image in the current location.
   //-----------------------------------------------------------------
   public void paintComponent (Graphics page)
   {
      super.paintComponent (page);
      image.paintIcon (this, page, x, y);
      page.drawString("Number of clicks: " + catchCount, 10, 15);

   }
   //*****************************************************************
   // Detects when mouse clicked=image postition
   //*****************************************************************
   public boolean pointInMe(int posX, int posY)
   {
      if(x == posX && y == posY)
      {
         catchCount++;
         return true;
      }
      return false;
      }
   public int getCatchCount()
   {
      return catchCount;
   }

   private class MouseClickedListener extends MouseAdapter
   {

      public void mouseClicked (MouseEvent event)
      {
         pointInMe(event.getX(), event.getY());

      }
   }

   //*****************************************************************
   //  Represents the action listener for the timer.
   //*****************************************************************
   private class CreatureListener implements ActionListener
   {
      //--------------------------------------------------------------
      //  Updates the position of the image and possibly the direction
      //  of movement whenever the timer fires an action event.
      //  (I don't know how to make the image appear and reappear
      //   randomly for random durations)
      //--------------------------------------------------------------

      public void actionPerformed (ActionEvent event)
      {

         x += moveX;
         y += moveY;

         if (x <= 0 || x >= WIDTH-IMAGE_SIZE)
            moveX = moveX * -1;

         if (y <= 0 || y >= HEIGHT-IMAGE_SIZE)
            moveY = moveY * -1;

        repaint();

      }
    }
 }

Looks like you have defined an instance of java.util.Random named r , and all other needed functionalities have been implemented. 看起来您已经定义了一个名为r的java.util.Random实例,并且所有其他所需的功能都已实现。 So why not just modified the code in actionPerformed with 那么,为什么不修改actionPerformed的代码呢?

x = r.nextInt(WIDTH-IMAGE_SIZE);
y = r.nextInt(HEIGHT-IMAGE_SIZE);

This should work for your requirement. 这应该可以满足您的要求。

(I'm sorry my reputation is not enough to directly give this simple suggestion by commenting. :( (很抱歉,我的声誉不足以通过评论直接给出这个简单的建议。:(

This is a really good start. 这是一个很好的开始。

What I would do is create a single use (non-repeating) Swing Timer . 我要做的是创建一个单次使用(非重复)Swing Timer This would be started with a random delay (say between 1-5 seconds). 这将以随机延迟(例如1-5秒之间)开始。

When it ticks, you would determine the current state. 当它打勾时,您将确定当前状态。 If the creature is visible, you would need to stop the main timer (as there's little point in updating it's position while it's invisible), repaint the view and reset the hide/show Timer with a new random value. 如果该生物是可见的,则您需要停止主timer (因为在不可见的情况下更新其位置没有什么意义), repaint视图并使用新的随机值重置隐藏/显示Timer

If the creature is invisible, you would need to calculate new x/y coordinates and movement direction, restart the main timer and reset the hide/show Timer with a new random value. 如果该生物不可见,则需要计算新的x / y坐标和移动方向,重新启动主timer并使用新的随机值重置隐藏/显示Timer

In your paintComponent method, you would check a simple visible flag to determine the current state of the creature and determine if you should paint the creature or not. paintComponent方法中,您将检查一个简单的visible标志以确定该生物的当前状态,并确定是否应绘画该生物。

For example... 例如...

(nb: outTimer is javax.swing.Timer , visible is a boolean , rnd is a java.util.Random ) (nb: outTimerjavax.swing.Timervisiblebooleanrndjava.util.Random

outTimer = new Timer(1000 + (int)(Math.random() * 4000), new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // Are we currently visible or not
        if (!visible) {
            // Calculate the x/y position
            x = (int) (Math.random() * (WIDTH - IMAGE_SIZE));
            y = (int) (Math.random() * (HEIGHT - IMAGE_SIZE));

            // Calculate a random speed
            int xSpeed = (int) (Math.random() * 4) + 1;
            int ySpeed = (int) (Math.random() * 4) + 1;

            // Calculate the direction based on the speed
            moveX = rnd.nextBoolean() ? xSpeed : -xSpeed;
            moveY = rnd.nextBoolean() ? ySpeed : -ySpeed;
            // Restart the main timer
            timer.start();
        } else {
            // Stop the main timer
            timer.stop();
        }
        // Flip the visible flag
        visible = !visible;
        repaint();
        // Calculate a new random time
        outTimer.setDelay(1000 + (int)(Math.random() * 4000));
        outTimer.start();
    }
});
// We don't want the timer to repeat
outTimer.setRepeats(false);
outTimer.start();

I would also suggest you set the main timer 's initial delay to 0 , timer.setInitialDelay(0); 我还建议您将主timer的初始延迟设置为0timer.setInitialDelay(0); , which will allow to fire immediately the first time it is started ,这将允许它在首次启动时立即触发

...instead of "gliding" at a smooth constant rate. ...而不是以平稳的恒定速度“滑行”。

CreatureListener is responsible for the animation. CreatureListener负责动画。 Let's replace it with a new ActionListener class, RandomCreatureListener. 让我们用一个新的ActionListener类,RandomCreatureListener替换它。

timer = new Timer(DELAY, new RandomCreatureListener());

The 'r' field (Random) appears to be unused. “ r”字段(随机)似乎未使用。 It is a clue that you should apply it in RandomCreatureListener. 您应该在RandomCreatureListener中应用它是一个提示。 Eg 例如

x = r.nextInt(WIDTH - IMAGE_SIZE);
y = r.nextInt(WIDTH - IMAGE_SIZE);

You'll be getting the desired random pop-ups, but at blinding speeds. 您将获得所需的随机弹出窗口,但速度惊人。 You will need to slow it down. 您将需要放慢速度。

Since this is a assignment, I'll leave it to you to figure it out. 由于这是一项任务,因此我将由您自己解决。

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

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