Я сделал это наиболее успешно, масштабируя графический объект. В итоге вы получите что-то вроде следующего:
final int gameUnitsPerScreenDim = 32;
void render(JPanel panel, Graphics2D g2) {
double pixelHeight = panel.getHeight();
double pixelsPerGameUnit = pixelHeight / gameUnitsPerScreenDim;
g2.scale(pixelsPerGameUnit, pixelsPerGameUnit);
...
}
А затем для симуляции вы используете игровые юниты. То, насколько большой игровой юнит на самом деле, немного произвольно, хотя, если вы создаете мозаичную игру, вероятно, есть некоторая очевидная ценность, которой он должен быть.
Вместо использования scale
вы также можете создать AffineTransform
, который позволит вам повторно использовать его:
if (this.tf == null || /* image size changed since the last frame */) {
...
this.tf = AffineTransform.getScaleInstance(pxPerGu, pxPerGu);
}
g2.setTransform(this.tf);
(вызов scale
создает новый AffineTransform
каждый раз, когда вы его вызываете.)
Это даже немного более эффективно, хотя, вероятно, ненамного.
(Если вы хотите, вы также можете использовать преобразование, чтобы инвертировать ось Y и перевести так, чтобы начало координат было в центре изображения. Это делает большую часть тригонометрии и материала более естественными. Инвертирование оси Y хотя работа с текстом становится болезненной.)
Кроме того, использование OpenGL, вероятно, лучше. Написав пару простых игр с использованием Swing для развлечения, я не вижу веской причины для этого.