我遇到的问题是我的onFrame
方法在paintComponent
期间修改了对象的位置。因为我的JPanel渲染相对于其focus
对象位置的场景,所以在绘画期间焦点位置的任何移动都会导致场景的一部分从场景的其余部分转换(这对于玩家来说是可见的屏幕上有白色条纹)。因此,我希望阻止在focus
的部分内修改paintComponent
。
这里的涂料成分:
@Override
public void paintComponent(Graphics g) {
if (focus == null) {
return;
}
super.paintComponent(g);
synchronized (focus) {
universe.getCurrentWorld().render(this, g, true); //draws scene around focus
}
focus.getInventory().render(this, g);
focus.renderHealthBar(g);
if (dialogQ.peek() != null) {
dialogQ.peek().render(this, g);
}
}
调用render方法:
public void render(FocusedWindow g, Graphics gr, boolean showOutlands) {
level.renderMap(g, gr, showOutlands);
col.renderAround(g, gr);
for (Detector p : colliders.toArray(new Detector[0])) {
p.renderAround(g, gr);
}
}
实际使用focus
的水平渲染方法:
public void renderMap(FocusedWindow g, Graphics gr, boolean renderOutside) {
int cushion = 4;
int scaleFactor = 2;
int minX = g.getFocus().getPos().getX() / Tile.WIDTH - g.getDimensions().getX() / Tile.WIDTH / scaleFactor - cushion;
int maxX = g.getFocus().getPos().getX() / Tile.WIDTH + g.getDimensions().getX() / Tile.WIDTH / scaleFactor + cushion;
int minY = g.getFocus().getPos().getY() / Tile.WIDTH - g.getDimensions().getY() / Tile.WIDTH / scaleFactor - cushion;
int maxY = g.getFocus().getPos().getY() / Tile.WIDTH + g.getDimensions().getX() / Tile.WIDTH / scaleFactor + cushion;
for (int i = minX; i < maxX; i++) {
for (int j = minY; j < maxY; j++) {
if (i >= 0 && i < map.length) {
if (j >= 0 && j < map[i].length) {
map[i][j].drawTile(g, gr, new Vector(i,j));
}
else if (renderOutside) {
map[0][0].drawTile(g, gr, new Vector(i,j));
}
}
else if (renderOutside) {
map[0][0].drawTile(g, gr, new Vector(i,j));
}
}
}
}
答案 0 :(得分:0)
啊,我还需要同步更新世界的onFrame
中的代码。添加两个同步块后,它可以正常工作:
@Override
protected void onFrame() {
long time = getTimestamp();
double deltaTime = (time - lastTime) / 1000000000d;
lastTime = time;
if (deltaTime > 0.2) { //this is shitty
Main.log("high delta time detected (" + deltaTime + " sec)");
}
if (dialogQ != null && dialogQ.peek() != null && dialogQ.peek().update(deltaTime)) {
dialogQ.poll();
}
if (isPaused() || isEditingInventory()) {
return;
}
if (!hasDied && focus != null && focus.isDead()) {
hasDied = true;
Main.setOverlay(new DeathOverlay());
}
if (universe == null || universe.getCurrentWorld() == null) {
return;
}
repaint();
synchronized (this) {
universe.getCurrentWorld().update(deltaTime);
}
}
@Override
public void paintComponent(Graphics g){
if (focus == null) {
return;
}
super.paintComponent(g);
synchronized (this) {
universe.getCurrentWorld().render(this, g, true);
}
focus.getInventory().render(this, g);
focus.renderHealthBar(g);
if (dialogQ.peek() != null) {
dialogQ.peek().render(this, g);
}
}