java.awt.Graphics.fillRect() 行为不当

发布于 2024-12-18 15:08:42 字数 2634 浏览 0 评论 0原文

下面我有一个简单的方法,用于将一组对象绘制到 java.awt.applet.Applet 上。我认为这非常简单,但最终只会将对象绘制为小程序左上角的单个像素。这个想法是 Display 类接受一组相当轻量级的对象,这些对象扩展了 GameObject 并包含有关它们在屏幕上的位置、大小和外观的信息,然后将它们逐像素绘制到小程序,根据指定的显示高度和宽度按比例拉伸和定位它们。在测试过程中,我将 Display 的宽度和高度设置为 128,并将两个对象传递给 Display,它们都是 32 像素的正方形(都返回 getWidth()getHeight() 为 >32),其中一个为红色,对于 getX() 返回 24getY(),另一个是蓝色的,对于 getX()getY() 返回 16。我将 Display 放入 javax.swing.JFrame 中,并使用 java.awt.BorderLayout 确保它填充框架(我使用 < code>add(display, java.awt.BorderLayout.CENTER); 在上述 javax.swing.JFrame 中)。

据我所知,这应该绘制一个蓝色的 32 像素正方形,距离顶部和左侧边缘 16 像素,以及一个红色的 32 像素正方形,该正方形被另一个正方形遮挡或遮挡了另一个正方形的一部分。然而,我得到的只是显示左上角的单个红色或蓝色像素。无论窗口有多大或多小,这都是一致的。

代码


public class Display extends java.awt.applet.Applet
{
  private int w,h;
  private ArrayPP<GameObject> gameObjects;//ArrayPP is my way of making a dynamically expanding array. It is similar to Vector, but has many more useful methods I use elsewhere.

  public Display(int width, int height)
  {
    w = width;
    h = height;
  }

  public void addGameObject(GameObject go)
  {
    gameObjects.add(go);
  }

  public void refresh(java.awt.Graphics g)
  {
    int x, y, w, h;
    final int W = getWidth(), H = getHeight();
    for (GameObject go : gameObjects)//Draw all objects
      for (x = go.getX(), y = go.getY(), w = go.getWidth() + x, h = go.getHeight() + y; y < h; y++)//Draw all lines of the object
        for (x = go.getX(); x < w; x++)//Draw all the pixels on this line of the object
        {
          g.setColor(go.getColorForPixel(x, y));
          g.fillRect((x / this.w) * W, (y / this.h) * H, w/W, h/H);
        }
  }
}

public interface GameObject
{
  public int getX();
  public int getY();
  public int getWidth();
  public int hetHeight();
  public java.awt.Color getColorForPixel(int x, int y);
}

问题


为什么java.awt.Graphics.fillRect(int x, int y, int width, int height)只绘制小程序的左上角?

解决方案


解决方案在于 在其中整数计算导致所有值都为 0 的行中。

          g.fillRect((x / this.w) * W, (y / this.h) * H, w/W, h/H);

解决方案如下:

          g.fillRect((int)(((float)x/(float)this.w) *W),
                     (int)(((float)y/(float)this.h) *H),
                     (int)((float)W/(float)w),
                     (int)((float)H/(float)h));

Below I have a simple method for painting a set of objects onto an java.awt.applet.Applet. I thought this was very straightforward, but it ends up only painting the objects as a single pixel at the top-left corner of the applet. The idea is that the Display class takes in a set of fairly lightweight objects that extend GameObject and contain information about their location, size, and appearance on the screen, and then draws them pixel-by-pixel onto the applet, stretching and positioning them proportionally depending on the specified display height and width. In testing this, I set the width and height of the Display to 128, and pass two objects to the Display, which are both 32-pixel squares (both return 32 for getWidth() and getHeight()), one is red and returns 24 for getX() and getY(), and the other is blue and returns 16 for getX() and getY(). I put the Display in a javax.swing.JFrame and use a java.awt.BorderLayout to ensure it fills the frame (I use add(display, java.awt.BorderLayout.CENTER); within the aforementioned javax.swing.JFrame).

As far as I can tell, this should be paining a blue 32-pixel square that's 16 pixels from the top and left edges and a red 32-pixel square that is either obscured by or obscuring part of the other one. However, all I get is a single red or blue pixel in the top-left corner of the Display. This is consistent no matter how big or small the window is.

Code


public class Display extends java.awt.applet.Applet
{
  private int w,h;
  private ArrayPP<GameObject> gameObjects;//ArrayPP is my way of making a dynamically expanding array. It is similar to Vector, but has many more useful methods I use elsewhere.

  public Display(int width, int height)
  {
    w = width;
    h = height;
  }

  public void addGameObject(GameObject go)
  {
    gameObjects.add(go);
  }

  public void refresh(java.awt.Graphics g)
  {
    int x, y, w, h;
    final int W = getWidth(), H = getHeight();
    for (GameObject go : gameObjects)//Draw all objects
      for (x = go.getX(), y = go.getY(), w = go.getWidth() + x, h = go.getHeight() + y; y < h; y++)//Draw all lines of the object
        for (x = go.getX(); x < w; x++)//Draw all the pixels on this line of the object
        {
          g.setColor(go.getColorForPixel(x, y));
          g.fillRect((x / this.w) * W, (y / this.h) * H, w/W, h/H);
        }
  }
}

 

public interface GameObject
{
  public int getX();
  public int getY();
  public int getWidth();
  public int hetHeight();
  public java.awt.Color getColorForPixel(int x, int y);
}

Question


Why is java.awt.Graphics.fillRect(int x, int y, int width, int height) only painting the topleft corner of the applet?

Solution


The solution lies in the line that reads

          g.fillRect((x / this.w) * W, (y / this.h) * H, w/W, h/H);

wherein integer calculations cause all values to be 0. The solution is as follows:

          g.fillRect((int)(((float)x/(float)this.w) *W),
                     (int)(((float)y/(float)this.h) *H),
                     (int)((float)W/(float)w),
                     (int)((float)H/(float)h));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无敌元气妹 2024-12-25 15:08:42

问题在于

(x / this.w) * W

如果 x 和 this.w 都是整数并且 x

将 x 和 w 中的一个或多个转换为 float 以强制进行浮点除法。

(int)(((float)x/(float)this.w) *W)

The problem lies with

(x / this.w) * W

If x and this.w are both integers and x

Convert one or more of x and w to float to force a floting point division.

(int)(((float)x/(float)this.w) *W)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文