我正试图让画布上的图像正确缩放。
它正确缩小但不能正确缩放,那么如果“缩放”因子设置为1.0以外的任何值,只要我移动鼠标它就会一直放大。
示例:https://i.gyazo.com/98fcfd74a1094142b460781f937952c1.mp4 在这个例子中,我滚动到大约1.25的缩放,然后我移动我的鼠标,它只是放大,缩放从1.0开始。
Scaling在context.scale(scale,scale)的paint()中完成
代码:
public class MapRenderer {
private final Canvas canvas;
private final GameMap gameMap;
public MapRenderer(final Canvas canvas, final GameMap gameMap) {
this.canvas = canvas;
this.gameMap = gameMap;
}
private double mapX = 0;
private double mapY = 0;
private double scale = 1.0;
private boolean isMoving = false;
private double startMouseX = 0;
private double startMouseY = 0;
private double pressMouseX = 0;
private double pressMouseY = 0;
private double curX = 0;
private double curY = 0;
public double screenXToMap(final double x) {
return (this.mapX + (x / this.scale));
}
public double screenYToMap(final double y) {
return (this.mapY + (y / this.scale));
}
public double screenXToTile(final double x) {
return (this.screenXToMap(x) / this.gameMap.getTileSize()) + this.gameMap.getOffsetX();
}
public double screenYToTile(final double y) {
return (this.gameMap.getHeightTiles() - ((this.screenYToMap(y) + 1) / this.gameMap.getTileSize()) + this.gameMap.getOffsetY());
}
public double tileXToScreen(final double x) {
return (((x - this.gameMap.getOffsetX()) * this.gameMap.getTileSize()) - this.mapX) * this.scale;
}
public double tileYToScreen(final double y) {
return (((this.gameMap.getHeightTiles() - (y - this.gameMap.getOffsetY())) * this.gameMap.getTileSize()) - this.mapY - 1) * this.scale;
}
public void update() {
if (this.mapX < 0) {
this.mapX = 0;
} else if (this.mapX + this.canvas.getWidth() > this.gameMap.getWidth()) {
this.mapX = this.gameMap.getWidth() - this.canvas.getWidth(); // Calculate view port
}
if (this.mapY < 0) {
this.mapY = 0;
} else if (this.mapY + this.canvas.getHeight() > this.gameMap.getHeight()) {
this.mapY = this.gameMap.getHeight() - this.canvas.getHeight(); // Calculate view port
}
this.repaint();
}
public void init() {
this.canvas.setOnMousePressed(e -> {
System.out.println("PRESSED");
if (e.getButton().equals(MouseButton.MIDDLE)) {
this.isMoving = true;
this.startMouseX = this.mapX;
this.startMouseY = this.mapY;
this.pressMouseX = e.getX();
this.pressMouseY = e.getY();
}
});
this.canvas.setOnMouseReleased(event -> {
System.out.println("RELEASED");
this.isMoving = false;
});
this.canvas.setOnScroll(e -> {
System.out.println("SCROLL 1 " + this.scale);
final double oldWidth = this.mapX + (this.canvas.getWidth() / this.scale);
final double oldHeight = this.mapY + (this.canvas.getHeight() / this.scale);
this.scale += (e.getDeltaY() > 0 ? 1 : -1) * 0.25 * -1.0;
this.scale = Math.max(1.0, Math.min(8.0, this.scale));
final double newWidth = this.mapX + (this.canvas.getWidth() / this.scale);
final double newHeight = this.mapY + (this.canvas.getHeight() / this.scale);
this.mapX += Math.floor((oldWidth - newWidth) / 2.0);
this.mapY += Math.floor((oldHeight - newHeight) / 2.0);
this.update();
System.out.println("SCROLL 2 " + this.scale);
});
this.canvas.setOnMouseDragged(e -> {
System.out.println("DRAGGED");
this.curX = e.getX();
this.curY = e.getY();
if (this.isMoving) {
this.mapX = (this.startMouseX - (e.getX() - this.pressMouseX) / this.scale);
this.mapY = (this.startMouseY - (e.getY() - this.pressMouseY) / this.scale);
this.update();
}
this.update();
});
this.canvas.setOnMouseMoved(e -> {
System.out.println("MOVED " + this.mapX + ", " + this.mapY + "{ " + this.scale + " }");
System.out.println("CANVAS " + this.canvas.getWidth() + ", " + this.canvas.getHeight());
this.curX = e.getX();
this.curY = e.getY();
this.update();
});
}
public void paint() {
final GraphicsContext context = this.canvas.getGraphicsContext2D();
context.scale(scale, scale);
context.drawImage(this.gameMap.getMapImage(), -mapX, -mapY);
context.setFill(Color.GREEN);
context.fillRect(this.tileXToScreen(this.screenXToTile(this.curX)), this.tileYToScreen(this.screenYToTile(this.curY)),
(this.gameMap.getTileSize() * this.scale), (this.gameMap.getTileSize() * this.scale));
}
public void repaint() {
this.canvas.getGraphicsContext2D().clearRect(0, 0, this.canvas.getWidth(), this.canvas.getHeight());
this.paint();
}
public GameMap getGameMap() {
return gameMap;
}