4
\$\begingroup\$

I am translating in my main class render. How do I get the mouse position where my mouse actually is after I scroll the screen

public void render(GameContainer gc, Graphics g) throws SlickException 
{
    float centerX = 800/2;
    float centerY = 600/2;
    g.translate(centerX, centerY);
    g.translate(-player.playerX, -player.playerY);
    gen.render(g);
    player.render(g);
}

playerX = 800 /2 - sprite.getWidth();
playerY = 600 /2 - sprite.getHeight();

Image to help with explanation

game world showing selected grid not where the mouse is

I tried implementing a camera but it seems no matter what I can't get the mouse position. I was told to do this worldX = mouseX + camX; but it didn't work the mouse was still off.

Here is my Camera class if that helps:

public class Camera {
public float camX;
public float camY;

Player player;

public void init() {
    player = new Player();
}

public void update(GameContainer gc, int delta) {
    Input input = gc.getInput();

    if(input.isKeyDown(Input.KEY_W)) {
        camY -= player.speed * delta;
    }
    if(input.isKeyDown(Input.KEY_S)) {
        camY += player.speed * delta;
    }
    if(input.isKeyDown(Input.KEY_A)) {
        camX -= player.speed * delta;
    }
    if(input.isKeyDown(Input.KEY_D)) {
        camX += player.speed * delta;
    }
}

Code used to convert mouse

worldX = (int) (mouseX + cam.camX);
worldY = (int) (mouseY + cam.camY);

Tile class

public class TileGen {
Block block;
public Block[] tiles = new Block[2];
public int width, height;
public int[][] index;
int mouseX, mouseY;
int worldX, worldY;
boolean selected;

Image dirt, grass, selection;
SpriteSheet tileSheet;

int startX, startY, stopX, stopY;

Camera cam;
Player player;

public void init() throws SlickException {
    tileSheet = new SpriteSheet("assets/tiles/tileSheet.png", 64, 64);

    grass = tileSheet.getSprite(0,0);
    dirt = tileSheet.getSprite(1,0);
    selection = tileSheet.getSprite(2,0);

    tiles[0] = new Block(BlockType.Grass, new Vector2f(0,0), grass, true);
    tiles[1] = new Block(BlockType.Dirt, new Vector2f(0,0), dirt, true);

    width = 50;
    height = 50;

    index = new int[width][height];

    cam = new Camera();
    player = new Player();

    Random rand = new Random();
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            index[x][y] = rand.nextInt(2);
        }
    }
}

public void update(GameContainer gc) {
    Input input = gc.getInput();
    mouseX = input.getMouseX();
    mouseY = input.getMouseY();

    worldX = (int) (mouseX - player.playerX);
    worldY = (int) (mouseY - player.playerY);

    if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)) {
        selected = true;
    } else {selected = false;}

    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            if(IsMouseInsideTile(x, y) && selected) {
                if(tiles[index[x][y]]== tiles[0])
                    index[x][y] = 1;
            }
        }
    }

    startX = (int) (cam.camX/64);
    startY = (int) (cam.camY/64);

    stopX = startX + (gc.getWidth()/64)  + 2;
    stopY = startY + (gc.getHeight()/64) + 2;
    System.out.println(worldX);
}

public void render(Graphics g, GameContainer container) {
    for (int x = startX; x < stopX; x++) {
        for (int y = startY; y < stopY; y++) {      
            tiles[index[x][y]].texture.draw(x * 64, y *64);
            if(IsMouseInsideTile(x, y)) {
                selection.draw(x * 64, y * 64); 
            }
        }
    }
}

public boolean IsMouseInsideTile(int x, int y)
{
    return (worldX >= x * 64 && worldX <= (x + 1) * 64 &&
            worldY >= y * 64 && worldY <= (y + 1) * 64);
}

}

\$\endgroup\$
4
  • \$\begingroup\$ Can you also show us the code you're using to convert screen to world position? \$\endgroup\$
    – House
    Apr 12, 2012 at 22:31
  • \$\begingroup\$ I edited it in at the bottom \$\endgroup\$
    – Corey
    Apr 12, 2012 at 22:47
  • \$\begingroup\$ Is the offset always the same or does it change? \$\endgroup\$
    – House
    Apr 12, 2012 at 23:05
  • \$\begingroup\$ It should change when I press the keys to make my character move. Idk if my Tile class is having problems getting the camera variables, but when I try to System.out.println(cam.camX); it is always zero and my values that depend on camX in my Tile class never change. If I print to console from the camera class itself the camX actually increases \$\endgroup\$
    – Corey
    Apr 12, 2012 at 23:19

4 Answers 4

2
\$\begingroup\$

This could explain your issues. You're drawing your scene based on the position of your character. However, you're attempting to get the mouse coordinates based on the position of your camera. Try rendering like this:

g.translate(cam.camX, cam.camY);
gen.render(g);
player.render(g);

Or try your mouse coordinates like this:

worldX = (int) (mouseX + player.playerX);
worldY = (int) (mouseY + player.playerY);

I imagine you'll be seeing something completely different than before. At the moment your camera is rather unattached to your scene. You seem to be updating it, but I guess somewhere else you're also updating the position of your player. Unless those two updates were exactly the same, you're not going to have them in-sync. Basically you want to use your camera for what it is, use it to frame the scene. If you want to set it to exactly follow your character, that's fine, but use it's values for drawing your viewport.

\$\endgroup\$
6
  • \$\begingroup\$ I did both of those, but the mouse is still not changing when I add player.playerX. It is telling me that it is always zero whenever I try to use it in my Tile class. I will edit in my Tile class at the bottom. I'm not sure what is wrong \$\endgroup\$
    – Corey
    Apr 12, 2012 at 23:50
  • \$\begingroup\$ You're not supposed to do both at the same time. Just do the first one. I showed you both to give you an example of what was wrong. You need to use the camera position throughout if you want it to work. Set the camera center to the player. You're switching between using the camera position and the character position everywhere in your code. You need to think about how they're different and separate them correctly. \$\endgroup\$
    – House
    Apr 13, 2012 at 0:58
  • \$\begingroup\$ Well I mean I tried both separately. Right now I have the first one, but no matter what I use the mouse position isn't correct \$\endgroup\$
    – Corey
    Apr 13, 2012 at 1:23
  • \$\begingroup\$ And you've checked the other places in your code? You appear to be mixing them all over the place from just the snippets you've posted. \$\endgroup\$
    – House
    Apr 13, 2012 at 1:45
  • \$\begingroup\$ Yeah, I'm pretty sure I have everything where it is supposed to be. I spent most of yesterday going over it \$\endgroup\$
    – Corey
    Apr 14, 2012 at 18:51
0
\$\begingroup\$

I wrote a class camera i use to draw a Box2D world into slick2d. It's basically the same. You get the mouse position via:

float mouseX = Input.getMouseX();
float mouseY = Input.getMouseY();

and then to mouseX you add the cameraX (that's the camera horizontal position in world) and to mouseY you add cameraY. These are my functions:

public Vec2 screenToWorld(Vec2 screenV) {
    return new Vec2(screenV.x + Camera.x, 
            screenV.y + Camera.y);
}

public Vec2 worldToScreen(Vec2 worldV) {
    return new Vec2(worldV.x - Camera.x, 
            worldV.y - Camera.y);
}

Where Vec2 is a class that has a "x" variable and a "y" variable of type float.

\$\endgroup\$
1
  • \$\begingroup\$ Just a note: A new class does not need to be made for holding X+Y floats, as Slick2D already comes with those -> Vector2f ::::: In the case of integers -> Point \$\endgroup\$ Jun 21, 2012 at 17:14
0
\$\begingroup\$

Edit: just realised this is pretty old.

Anyways, I did something similar to this in a TD game so hopefully the same would apply here.

In my TileMap class I have a method called getTileCoord(int mouseX, int mouseY) and for your game it would be translated to something like this:

int tileX = (int) (mouseX - camX) / tileWidth;
int tileY = (int) (mouseY - camY) / tileHeight;

...// cap the tile coordinates to 0 and the max width/height if needed
tileX *= tileWidth;
tileY *= tileHeight;
or multiply at at draw of selection
selection.draw(tileX * 64, tileY * 64);

Calling selection.draw should now be done outside the x and y loop.

If you can scale your camera the the code would become:

int tileX = (int) (((x - camX * scale) / tileWidth) * (1 / scale));
int tileY = (int) (((y - camY * scale) / tileHeight) * (1 / scale));

Contains some unnecessary code at the moment, I'll update it once I find the recent version.

\$\endgroup\$
-1
\$\begingroup\$

float mouseY = Math.abs(Mouse.getY() - Gamecontainer.getHeight());

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Some added explanation would flesh this out to a complete answer, right now it's a code only answer, which typically don't make for good answers. \$\endgroup\$
    – House
    May 1, 2014 at 20:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .