简体   繁体   中英

LibGdx Mouse Position relative to Orthographic Camera instead of Screen

Basically I wrote a "Dota like Style" based on the OrthographicCamera from libgdx. You can test it out for youself here is the class.

I am using this to draw a TiledMap, and I have and array of tiles corresponding with the graphical tiles, however if I move the mouse, and with that the camera.
The coordinates off the mouse and the tiles are completely different.
Gdx.input x and y get their coordinates relative to the screen and not where the mouse is in the world relative to the camera.

I can't figure out a way to get the mouse position relative to the camera, so that if I move the camera I won't just get the regular mouse coordinates, but the actual world coordinates that the camera is showing, and where my mouse is located within the confines of the view of the camera relative to the world.

public class DotaCamera extends OrthographicCamera {

    private float xmin;
    private float xmax;
    private float ymin;
    private float ymax;

    private float x;
    private float y;

    private int Width = Gdx.graphics.getWidth();;
    private int Height = Gdx.graphics.getHeight();

    private int camSpeedMax = 16;
    private float camAcceleration = 0.3f;
    private int camSpeedSmoother = 3;

    private float camVelocityX = 0;
    private float camVelocityY = 0;

    private float fZoomMax = 1f;
    private float fZoomMin = 0.5f;
    private float fZoomSpeed = 0.03f;

    public DotaCamera() {
        this(0, 0, 0, 0);
    }

    public DotaCamera(float xmin, float xmax, float ymin, float ymax) {
        super();
        setBounds(xmin, xmax, ymin, ymax);
    }

    public void setBounds(float xmin, float xmax, float ymin, float ymax) {
        this.xmin = xmin;
        this.xmax = xmax;
        this.ymin = ymin;
        this.ymax = ymax;
    }

    public void setPosition(float x, float y) {
        setPosition(x, y, 0);
    }

    public void setPosition(float x, float y, float z) {
        position.set(x, y, z);
        this.x = x;
        this.y = y;
        fixBounds();
    }

    private void fixBounds() {
        if (position.x < xmin + viewportWidth / 2) {
            position.x = xmin + viewportWidth / 2;
        }
        if (position.x > xmax - viewportWidth / 2) {
            position.x = xmax - viewportWidth / 2;
        }
        if (position.y < ymin + viewportHeight / 2) {
            position.y = ymin + viewportHeight / 2;
        }
        if (position.y > ymax - viewportHeight / 2) {
            position.y = ymax - viewportHeight / 2;
        }
    }

    /**
     * Controls the zoom of the of the camera.
     */
    public void updateZoom() {
        int mouseWheelMovement = Mouse.getDWheel();
        if (mouseWheelMovement > 0) {
            if (this.zoom > fZoomMin) {
                this.zoom -= fZoomSpeed;
            } else {
                this.zoom = fZoomMin;
            }
        }else if(mouseWheelMovement < 0){
            if (this.zoom < fZoomMax) {
                this.zoom += fZoomSpeed;
            } else {
                this.zoom = fZoomMax;
            }
        }
    }

    /**
     * Update And move the Camera DOTA Stylized movement.
     */
    public void updateAndMove() {
        float dt = Gdx.graphics.getDeltaTime();

        int MouseX = Mouse.getX(); // Get MouseX
        int MouseY = Height - Mouse.getY(); // Get MouseY

        int camSpeedX = 0;
        int camSpeedY = 0;

        String horizontalDirection = getMoveLeftRight(MouseX); // Get
                                                                // horizontalDirection
        String verticalDirection = getMoveUpDown(MouseY); // Get
                                                            // verticalDirection

        /* * * * * * * *
         * Decide what to do with the horizontalDirection.
         */
        switch (horizontalDirection) {
        case "left":
            camSpeedX = ((Width / 2) - (MouseX + (Width / 4)))
                    / camSpeedSmoother; // Create Speed -X

            camSpeedX = ((camSpeedX > camSpeedMax) ? camSpeedMax : camSpeedX); // Limit
                                                                                // the
                                                                                // speed.
            if (camVelocityX < camSpeedX)
                camVelocityX += camAcceleration;
            break;
        case "right":
            camSpeedX = (((MouseX + (Width / 4)) - ((Width / 4) * 3)) - (Width / 4))
                    / camSpeedSmoother; // Create speed +X.

            camSpeedX = ((camSpeedX > camSpeedMax) ? camSpeedMax : camSpeedX); // Limit
                                                                                // the
                                                                                // speed.

            if (camVelocityX < camSpeedX)
                camVelocityX += camAcceleration; // Accelerate

            camSpeedX *= -1; // To negate the speed.
            break;
        case "":
            camVelocityX = 0;
            break;
        }

        /* * * * * * * *
         * Decide what to do with the verticalDirection.
         */
        switch (verticalDirection) {
        case "up":
            camSpeedY = (Height / 4) - MouseY; // Create speed -Y

            camSpeedY = ((camSpeedY > camSpeedMax) ? camSpeedMax : camSpeedY); // Limit
                                                                                // the
                                                                                // speed.

            if (camVelocityY < camSpeedY)
                camVelocityY += camAcceleration;

            camSpeedY *= -1;
            break;
        case "down":
            camSpeedY = (((MouseY + (Height / 4)) - ((Height / 4) * 3)) - (Height / 4))
                    / camSpeedSmoother; // Create speed +Y.

            camSpeedY = ((camSpeedY > camSpeedMax) ? camSpeedMax : camSpeedY); // Limit
                                                                                // the
                                                                                // speed.
            if (camVelocityY < camSpeedY)
                camVelocityY += camAcceleration;
            break;
        case "":
            camVelocityY = 0;
            break;
        }

        // System.out.println("vX:" +camVelocityX+ "vY: " +camVelocityY+ "sX: "
        // +camSpeedX+ "sY: " +camSpeedY);

        this.position.x -= (camVelocityX * camSpeedX) * dt;
        this.position.y -= (camVelocityY * camSpeedY) * dt;
        this.update();
    }

    /**
     * Get the X-Axial Direction.
     * 
     * @param MouseX
     * @return Direction
     */
    private String getMoveLeftRight(int MouseX) {
        if (MouseX + (Width / 4) < Width / 2) {// Needs to move left?
            return "left";
        } else if (MouseX > (Width / 4) * 3) {// Needs to move right?
            return "right";
        }
        return "";
    }

    /**
     * Get the Y-Axial Direction.
     * 
     * @param MouseY
     * @return Direction
     */
    private String getMoveUpDown(int MouseY) {
        if (MouseY < Height / 4) {// Needs to move up?
            return "up";
        } else if (MouseY > (Height / 4) * 3) {// Needs to move down?
            return "down";
        }
        return "";
    }

Came across this problem and discovered the answer here:

https://gamedev.stackexchange.com/questions/27786/camera-coordinate-to-screen-coordinate

Supposedly, using Camera.unproject(Vector3 screenCoords) is the correct way of doing this.

My solution looks like this:

Vector3 getMousePosInGameWorld() {
 return camera.unproject(new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM