【问题标题】:How to repaint over images in Java game如何在 Java 游戏中重绘图像
【发布时间】:2015-02-09 05:52:56
【问题描述】:

大家好,我在绘制与用户相交的硬币时遇到了麻烦。我想要这段代码做的是当用户精灵与它在硬币上绘制的十个硬币图像中的任何一个相交时,它不再出现在屏幕上(还需要添加某种计数器,以便当用户收集所有十个硬币都会停止线程,并说“你赢了!”)。我的问题是我将如何执行此操作,因为我已尝试在 if 语句中使用 repaint() ,但它不再正确编译。任何有关如何在硬币上绘画的帮助,甚至可能添加某种计数器(认为 for 循环会派上用场)将不胜感激!代码如下:

public void paint(Graphics g)
{
    g.clearRect(0, 0, this.getWidth(), this.getHeight());
    one.paintComponent(g);
    two.paintComponent(g);
    three.paintComponent(g);
    four.paintComponent(g);
    five.paintComponent(g);
    six.paintComponent(g);
    seven.paintComponent(g);
    eight.paintComponent(g);
    nine.paintComponent(g);
    ten.paintComponent(g);
    monster.setLocation(r.nextInt(10) - 5 + monster.x, r.nextInt(10 - 5 + monster.y));
    monster.paintComponent(g);
    user.paintComponent(g);
    if(user.intersects(one))
    {
    }
    if(user.intersects(two))
    {
    }
    if(user.intersects(three))
    {
    }
    if(user.intersects(four))
    {
    }
    if(user.intersects(five))
    {
    }
    if(user.intersects(six))
    {
    }
    if(user.intersects(seven))
    {
    }
    if(user.intersects(eight))
    {
    }
    if(user.intersects(nine))
    {
    }
    if(user.intersects(ten))
    {
    }
    if(user.intersects(monster))
    {
            g.setFont(new Font("Serif", Font.BOLD, 35));
            g.drawString("YOU HAVE DIED, YOU LOSE!", 100, 100); //Prints this when you lose
            thread.interrupt(); //Stopping the thread if you die
    }
}

【问题讨论】:

    标签: java graphics paint intersection bluej


    【解决方案1】:

    在我的脑海中,将while(true) 放在你的Run() 方法中(你说你正在使用一个线程)并在循环中调用 repaint(),在循环结束时(在 try/catch 中) 输入//thread//.sleep(allotted time) 之类的内容,这将在设定的毫秒数内停止线程。在repaint() 的Javadoc 中,您会看到它调用了最近的paint(Graphics g) 方法。通过这样做,您可以从程序中的任何位置访问您的 paint() 方法。

    我对硬币的建议是让它成为自己的类。该类看起来类似于:

    public class Coin{
    int x;
    int y;
    public void Coin(int x, int y, Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        Image img1 = (//File Location);
        g2.drawImage(img1, x, y, //this);
        //If you have trouble with the ImageObserver (this part) try //class name of the applet.this
        this.x = x;
        this.y = y;
    
        g2.finalize();
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
    }
    

    之后,在您的绘制方法中,您可以创建 10 个Coin 对象并使用您在参数中实例化的g。然后,您可以创建一个 Coin 对象数组,并手动添加您在 paint 方法中创建的 10 个 Coins(是的,这很痛苦)(您必须在油漆中制作它们才能传递 Graphics 变量)

    Coin[] coins = new Coin[10];

    顺便说一下,你是如何制作数组的。制作完硬币数组后,在 paint 方法中创建 for 循环。它应该看起来像这样:

            for(int i = 0; i < coins.length; i++){
                if(coins[i].getX == //user X && coins[i].getY == //user Y){
                        g.clearRect(coins[i].getX, coins[i].getY, //Coin radius, //Coin radius);
                }
    
            }
    

    如果用户的 X 和 Y 等于硬币的 X 和 Y,这将在硬币所在的任何位置绘制一个清晰的矩形。

    【讨论】:

    • 我应该在 for 循环中那些被注释掉的部分放什么?我也有一个我想使用的硬币 gif,但如果它引起问题,我只会画我自己的硬币(我应该如何添加十个硬币?)。它还说找不到符号 - 变量 getX。
    • 要将 10 个硬币添加到数组中,您必须执行 coin[1] = coin1 等等。那些评论的部分就是他们所说的,我假设你有办法跟踪用户的 x 和 y 例如。硬币直径在那里,因此当用户和硬币的 x 和 y 相同时,您可以在硬币上绘制完美尺寸的 clearRect。 getX 不是变量,它是一种方法,而且在使用 getX 之前还必须先 setX。不过,我会发布一个修改来为你改变它。
    • @Fyree 检查我对Coin 类所做的编辑,它现在在构造函数中设置 X 和 Y,因此 getX 可以工作。你可以使用 Gif,你只需要使用 drawImage 使用这个链接来学习如何做到这一点java2s.com/Tutorial/Java/0261__2D-Graphics/DrawImage.htm
    • @Fyree 我将编辑 Coin 类,使其看起来像该网站的 drawImage,但我也会将其注释掉,因此您必须将所需内容放在 cmets 所在的位置
    • 我尝试了您对 getX 和 getY 所做的更改,但它仍然给我同样的错误。
    【解决方案2】:

    此代码取自我当前的项目(正在运行),我尝试将其调整为您的项目。

    private void render () {
        BufferStrategy bufferstrategy = getBufferStrategy ();
    
        if (bufferstrategy == null) {
            createBufferStrategy(3);
            return;
        }
    
        Graphics g = bufferstrategy.getDrawGraphics();
    
        g.setColor(Color.white);
        g.fillRect(0, 0, getWidth(), getHeight());
    
        paint (g);
    
        g.dispose();
        bufferstrategy.show();
    }
    

    render() 从 run() 调用,Thread 所在的位置。

    让我们分解一下,看看它是否可以帮助你。

    1. 它会获得一个 BufferStrategy 来确定要准备多少张图像。它可以在合理范围内设置为您喜欢的任何内容。 2 - 4 就可以了。甚至可以工作。
    2. 它将您当前的BufferStrategy 设置为您的Graphics
    3. 然后它用白色填充屏幕(也可以是透明的)。
    4. 然后它绘制所有组件,在您的情况下它调用 paint (Graphics g) 而在我的情况下它遍历所有可绘制对象。
    5. 它会重新渲染所有内容,就像现在应该看到的那样。

    希望你能从中吸取一些教训。

    【讨论】:

      【解决方案3】:

      首先,您应该将硬币放在一个列表中。然后,如果有交互,您只需删除列表中的项目(硬币)。像这样:

      private List<Coin> coins;
      
      public ClassConstructor() {
          coins = new ArrayList();
          coins.add(new Coin(type value,...)); //this ten times if every Coin is different from other
          //or this if every Coin are same:
          for (int i = 0; i < 10; i++) {
              coins.add(new Coin(type value,...));
          }
      }
      
      public void update() {
          //whatever
          for (int i = coins.size(); i >= 0; i--) {
              if (user.intersects(coins.get(i))) {
                  coins.remove(i);
                  //...
              }
          }
      
      }
      
      public void paint(Graphics g) {
          for (int i = coins.size(); i >= 0; i--) {
              coins.get(i).paintComponent(g);
          }
      }
      

      现在,您不应该使用 thread.interrupt() 来结束线程。如果该线程是您的游戏循环,您应该发送一个结束循环的标志。你的线程游戏循环:

      @Override
      public void run() {
          while (running) { //boolean running
              update();
              paint(g);
          }}
      

      最后,您的更新将如下所示:

      public void update() {
          //whatever
          for (int i = coins.size(); i >= 0; i--) {
              if (user.intersects(coins.get(i))) {
                  coins.remove(i);
                  //...
              }
          }
          if (user.intersects(monster)) {
              youThread.setRunning(false);
              try {
                  gameLoopThread.join(); //"wait" until thread ends
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      

      【讨论】:

      • 类型值是什么意思?
      • 获取无效的方法声明; public ClassConstructor(){. 需要返回类型
      • 只是一个实体的例子,是伪代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多