Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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);
}

}

share|improve this question
    
Can you also show us the code you're using to convert screen to world position? –  Byte56 Apr 12 '12 at 22:31
    
I edited it in at the bottom –  Corey Apr 12 '12 at 22:47
    
Is the offset always the same or does it change? –  Byte56 Apr 12 '12 at 23:05
    
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 –  Corey Apr 12 '12 at 23:19

4 Answers 4

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.

share|improve this answer
    
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 –  Corey Apr 12 '12 at 23:50
    
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. –  Byte56 Apr 13 '12 at 0:58
    
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 –  Corey Apr 13 '12 at 1:23
    
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. –  Byte56 Apr 13 '12 at 1:45
    
Yeah, I'm pretty sure I have everything where it is supposed to be. I spent most of yesterday going over it –  Corey Apr 14 '12 at 18:51

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.

share|improve this answer
    
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 –  TheLima Jun 21 '12 at 17:14

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.

share|improve this answer

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

share|improve this answer
3  
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. –  Byte56 May 1 at 20:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.