java.awt.Graphics.fillRect() 行为不当
下面我有一个简单的方法,用于将一组对象绘制到 java.awt.applet.Applet
上。我认为这非常简单,但最终只会将对象绘制为小程序左上角的单个像素。这个想法是 Display 类接受一组相当轻量级的对象,这些对象扩展了 GameObject 并包含有关它们在屏幕上的位置、大小和外观的信息,然后将它们逐像素绘制到小程序,根据指定的显示高度和宽度按比例拉伸和定位它们。在测试过程中,我将 Display
的宽度和高度设置为 128,并将两个对象传递给 Display
,它们都是 32 像素的正方形(都返回
),其中一个为红色,对于 getWidth()
和 getHeight()
为 >32getX() 返回
和24
getY()
,另一个是蓝色的,对于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于
如果 x 和 this.w 都是整数并且 x
将 x 和 w 中的一个或多个转换为 float 以强制进行浮点除法。
The problem lies with
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.