java.awt.Graphics.fillRect() плохо себя ведет
Ниже у меня есть простой метод для рисования набора объектов на java.awt.applet.Applet
, Я думал, что это было очень просто, но в конечном итоге это только рисование объектов одним пикселем в верхнем левом углу апплета. Идея состоит в том, что класс Display принимает набор довольно легких объектов, которые расширяют GameObject
и содержат информацию об их расположении, размере и внешнем виде на экране, а затем перетаскивают их попиксельно на апплет, растягивая и располагая их пропорционально в зависимости от заданной высоты и ширины дисплея. При тестировании я установил ширину и высоту Display
до 128 и передать два объекта Display
, которые являются 32-пиксельными квадратами (оба возвращают 32
за getWidth()
а также getHeight()
), один красный и возвращается 24
за getX()
а также getY()
, а другой синий и возвращает 16
за getX()
а также getY()
, Я положил Display
в javax.swing.JFrame
и использовать java.awt.BorderLayout
чтобы убедиться, что он заполняет кадр (я использую add(display, java.awt.BorderLayout.CENTER);
в пределах вышеупомянутого javax.swing.JFrame
).
Насколько я могу судить, это должно быть закрашено синим 32-пиксельным квадратом, который находится в 16 пикселях от верхнего и левого краев, и красным 32-пиксельным квадратом, который либо скрыт, либо скрыт частью другого. Тем не менее, все, что я получаю, это один красный или синий пиксель в верхнем левом углу Display
, Это согласуется независимо от того, насколько большое или маленькое окно.
Код
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)
рисовать только верхний угол апплета?
Решение
Решение лежит в строке, которая гласит
g.fillRect((x / this.w) * W, (y / this.h) * H, w/W, h/H);
где целочисленные вычисления приводят к тому, что все значения равны 0. Решение состоит в следующем:
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));
1 ответ
Проблема заключается в
(x / this.w) * W
Если x и this.w оба являются целыми числами и x
Преобразуйте одно или несколько из x и w в float, чтобы вызвать деление с плавающей точкой.
(int)(((float)x/(float)this.w) *W)