1
\$\begingroup\$

I am having much difficulty trying to figure out how to draw the cross in the square of where the person just touched.

I have made a class called 'CellPositions', by making 9 invisible squares around my board Texture; Example of CellOne...

public CellOne cellOne;

public CellPositions(Board board) {
    load(board);
}

public void load (Board board) {
    cellOne = new CellOne(board);

}

public class CellOne {
    public Rectangle square = new Rectangle();

    public CellOne (Board board) {

        square.x = board.boardRect.x;
        square.y = (board.boardRect.y + board.boardRect.height) - (board.boardRect.height / 3);
        square.width = board.boardRect.width / 3;
        square.height = board.boardRect.height / 3;
    }
}

I have made a 'Controller' class to handle my input and a 'Renderer' class to handle rendering images to the game.

Here is an image of my atlas

What I want to do is draw the "Cross" on the square the person touched. For eg. if he/she touches the first square - cellOne - how would i render my "cross" to that specific square.

I've tried making a class called "Cross" and made the x and y coordinates Gdx.input.getX() and Gdx.input.getY(), but the 'cross' was not in the square, but intersecting the lines.

Please help! I am trying to get used to libGdx by making a simple game like tic-tac-toe, but it's really not so simple when trying to draw your cross on a certain square.

Here is my board class for further info

private TextureRegion reg;
public Rectangle boardRect;

public Board () {
    init();
}

private void init () {
    reg = Assets.instance.board.boardRegion;
    boardRect = new Rectangle();
    boardRect.set((Constants.SCREEN_WIDTH / 2) - (340 / 2), 15, 
            340, 340);

}

public void render (SpriteBatch batch) {
    batch.draw(reg, boardRect.x, boardRect.y, 
            boardRect.width, boardRect.height);
}

I have made my screen width and height be 480x480.

\$\endgroup\$
0
\$\begingroup\$

I have a multiple-step solution for you:

  1. Change your cell classes to be more generic. You currently have one class for each cell position (I assume from your code). You should just have one Cell class that you re-use for every cell.

    public class Cell {
        public Rectangle square;
    
        public Cell (float x, float y, float width, float height) {
            square = new Rectangle(x, y, width, height);
        }
    }
    
  2. Set the position of the cell when you create it (probably in your init() method of your board class).

    float width = boardRect.width / 3f;
    float height = boardRect.height / 3f;
    
    for(int y = 0; y < 3; y++) {
        for(int x = 0; x < 3; x++) {
            // Create new cell att appropriate position and
            // add it to a list of all 9 cells.
            // You might need to offset the x & y position by your boards
            // position as well. In that case just do: 
            // x * width + boardRect.x
            // y * height + boardRect.y
            cells.add(new Cell(x * width, y * height, width, height);
        }
    }
    
  3. When you click you search thorough all cells and see which one you clicked in.

    int mouseX = Gdx.input.getX();
    int mouseY = Gdx.input.getY();
    
    for(Cell cell : cells) {
        if(cell.square.contains(mouseX, mouseY) {
            // We pressed in this tile. Draw image here and size
            // it to be the same size and in the same position
            // as the cell.
            float x = cell.square.x;
            float y = cell.square.y;
            float width = cell.square.width;
            float height = cell.square.height;
            // Draw image at (x, y) with size (width, height).
            // If you're using sprites do this:
            crossImage.setBounds(x, y, width, height);
            // If you're using textures do this:
            batch.draw(crossImage, x, y, width, height);
        }
    }
    
\$\endgroup\$
0
\$\begingroup\$

(alternative to my first answer)

You can round the clicked position to get which cell you clicked in.

int mouseX = Gdx.input.getX();
int mouseY = Gdx.input.getY();

// Move coordinates so we are relative to origin (0, 0).
// This makes calculations easier.
mouseX -= boardRect.x;
mouseY -= boardRect.y;

// Divide x and y by cell width and height.
mouseX /= (boardRect.width / 3);
mouseY /= (boardRect.height / 3);

// Check if you clicked outside the board.
if(mouseX > 2 || mouseY > 2) {
    // You clicked outside of the board. Do something.
}

// mouseX & mouseY is now in the range [0, 2].
// Multiply by cell width and height again.
mouseX *= (boardRect.width / 3);
mouseY *= (boardRect.height / 3);

// Move coordinates back so they match with the board position.
mouseX += boardRect.x;
mouseY += boardRect.y;

// mouseX & mouseY should now be in the correct position.
batch.draw(crossImage, mouseX, mouseY, boardRect.width / 3, boardRect.height / 3);

This might be a little confusing but this works because of integer division rounding (see this short wolfram alpha explaination). Basically after integer division the decimals (if they are present) are truncated. So for example 5 / 2 = 2.5 but since it is integer division decimals get removed so the result is 2.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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