Java 对齐网格

Java snap to grid

好的,所以我正在努力使事物与我拥有的网格对齐。

这是我捕捉到屏幕本身的方式:

int finalCalcX = (mouseX / Handler.gridSpace32) * Handler.gridSpace32;
int finalCalcY = (mouseY / Handler.gridSpace32) * Handler.gridSpace32;

我认为变量名不言自明。 鼠标坐标除以我的图块为 32x32 像素,再乘以该值以获得对齐网格功能。

现在这对屏幕来说效果很好,但是当我想将它添加到 "map" 本身时,我不能只将我的地图 x 和 y 偏移量添加到它,它会变得混乱。

我已经玩了大约两天了,我也让它捕捉到地图本身,但是当我说,在两个轴上的地图中途时,mouseX 和 mouseY 弄乱了网格的东西了。 我有点难以解释,但是从 0、0(每个原点位置,甚至屏幕)的偏移量加上当您离开原点时的地图偏移量,被添加到光标本身和透明之间的距离我用来测试的对齐网格图块。 基本上地图原点和相机之间的偏移量由于某种原因与光标和透明图块之间的偏移量相同。所以我移动的地图越远,图块离光标越远,最终移动到屏幕宽度和高度之外...... 当我进一步进入地图时,无论我在地图上的哪个位置,我都希望对齐网格功能保持正确。

渲染方法:

for (int y = startY; y < endY; y++) {
    for (int x = startX; x < endX; x++) {
        gridSpace(graphics, (int) (x * Handler.gridSpace32 - handler.getCamera().getOffsetX()),
                    (int) (y * Handler.gridSpace32 - handler.getCamera().getOffsetY()));

        checkHighlight(graphics);
    }
}

gridSpace 就是网格本身。 以下是目前的亮点:

int finalCalcX = (mouseX / Handler.gridSpace32) * Handler.gridSpace32;
int finalCalcY = (mouseY / Handler.gridSpace32) * Handler.gridSpace32;

graphics.setColor(new Color(100, 200, 100, 3));
graphics.fillRect(finalCalcX, finalCalcY, Handler.gridSpace32, Handler.gridSpace32);

抱歉我的解释能力很差,但这是我能做的最好的了。 我做错了什么?

我想我重新创建了你得到的东西,问题在于使用不正确的登录计算相机位置和平移。执行下面的代码,您应该会得到与您所描述的类似的行为,而取消注释注释行(同时注释掉后面的注释行)应该会给您正确的行为。

package test;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.*;

public class SnapToGrid extends JPanel implements MouseMotionListener{

    private int[] camera;
    private int[] mouse;
    private final int gridSize = 16;

    SnapToGrid() {
        camera = new int[2];
        mouse = new int[2];
        setFocusable(true);
        addMouseMotionListener(this);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        //g2.translate(-camera[0], -camera[1]);
        g2.translate(camera[0], camera[1]);

        //draw background
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
            {
                Color c = ((j*9) + i) % 2 == 0 ? Color.black : Color.white;
                g2.setColor(c);
                g2.fillRect(i*gridSize, j*gridSize, gridSize, gridSize);
            }
        g2.setColor(Color.blue);
        int[] snappedPos = getSnappedMousePosition();
        g2.fillRect(snappedPos[0], snappedPos[1], gridSize, gridSize);
    }

    private int[] getSnappedMousePosition() {
        return new int[] {
            camera[0] + mouse[0] - ((camera[0] + mouse[0]) % gridSize),
            camera[1] + mouse[1] - ((camera[1] + mouse[1]) % gridSize)  
        };
    }

    public static void main (String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SnapToGrid());
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        //camera[0] -= e.getX() - mouse[0]; 
        //camera[1] -= e.getY() - mouse[1];
        camera[0] += e.getX() - mouse[0]; 
        camera[1] += e.getY() - mouse[1];

        mouse[0] = e.getX();
        mouse[1] = e.getY();
        repaint();

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mouse[0] = e.getX();
        mouse[1] = e.getY();
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(gridSize * 18, gridSize * 18);
    }

}

我非常不喜欢您的代码的一件事是您没有使用转换。使用转换允许您将世界与视口分开,提交到这里调试这样的问题要容易得多,最重要的是,如果您想稍后添加缩放或旋转之类的东西,您只需要添加几行,而不是重写渲染方法的一半。