How to select and deselect a Rectangle/texture properly on click

那年仲夏 提交于 2019-12-25 06:47:09

问题


A video of the problem itself : https://www.youtube.com/watch?v=cJfFIB3baAg

I know there's a simple way to do this with scene2d but i chose to make this project with Rectangle and Texture variables, that means I have 20 Textures(1 to 9 with blank background and 1 to 9 with green blackground as shown in matrix[0][0]) and 20 Rectangles , which each one represents one of the Texture variables created. Like you see, the square[0][0] is selected at this very momment.

What I want to do Is, by selecting another square , to be this the result:

and that is happening! The problem is that when i click a square, for it to be selected i need to click like... 2 or 3 times instead of only one time! And i can't figure it out why's that happening! Here's some of my code, if you don't understand something please ask me. Hope you can help me.

@Override
public void render() {
batch.begin();

...(drawing of the matrix)...

if(Gdx.input.isTouched()){
              Vector3 touchPos = new Vector3();
                 touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
                 camera.unproject(touchPos);
                 System.out.println(touchPos.x+ " "+touchPos.y);
                  checkTexture();
                 }
batch.end();
}

I'm only giving you one example here because there are 80 more of this kind in checkTexture() method. The x and y variables are used in batch.draw in associateImage();...

      public Texture checkTexture() {
                 int number=0;int x=0,y=0;
                 Vector3 touchPos = new Vector3();
                touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
                camera.unproject(touchPos);
                int lastX=0,lastY=0;
                if((touchPos.x>=125 && touchPos.x<=164) && (touchPos.y>=400 && touchPos.y<=440)){
                 number=matrix[0][0];x=125;y=400;lastX=currentX;lastY=currentY;squares[lastX][lastY]=false;currentX=0;currentY=0;squares[currentX][currentY]=true;
                }
            return associateImage(number,x,y);
}

Here are the selected textures
public Texture associateImage(int n,int x,int y) {
        Texture t=null;
        switch(n) {
        case 1: t=numberOneSEL;break;
        case 2: t= numberTwoSEL;break;
        case 3: t= numberThreeSEL;break;
        case 4: t= numberFourSEL;break;
        case 5: t= numberFiveSEL;break;
        case 6: t= numberSixSEL;break;
        case 7: t= numberSevenSEL;break;
        case 8: t= numberEightSEL;break;
        case 9: t= numberNineSEL;break;
        case 10: t= emptySquareSEL;break;
        }
        batch.draw(t, x, y);
        return t;
    }

And then in the render method I'll give you only one of the 9 examples of what I do (drawing the 80 that are not selected)

@Override
public void render() {

...batch.begin()...

for(x=0;x<matrix.length;x++){
            for(y=0;y<matrix.length;y++){
                switch(matrix[x][y]){
                case 1: 
                    if(squareCounter==9) {squareCounter=0;startingX=125;startingY-=40;numberOneR.x=startingX;numberOneR.y=startingY; }
                    numberOneR.setX(startingX);numberOneR.setY(startingY);
                    if(squares[x][y]==false)
                    batch.draw(numberOne, numberOneR.x, numberOneR.y);
                    squareCounter++;
                    startingX+=40;
                    numberOneR.x=startingX;
                break;
...
}

回答1:


Hmm...I don't like idea that you are reading that isTouched in the loop. I guess that when you touch it "once" you are inverting square state many times, so it's a gamble what state will remain when you release the button (finger).

My advice is to use onTouchDown or onTouchUp or similar click event listeners which will execute your code only ONCE when touch/click occurs. With isTouched your code that detects touch is executed as long as your finger is touching the screen.




回答2:


Implement interface(s) GestureListener and/or InputProcessor and create needed methods. Your IDE can automatically import needed files that contain those classes, but anyway:

import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.input.GestureDetector.GestureListener;



回答3:


In my opinion you should use 1 Rectangle/cell, not 1 per number and background color.
So you should have 9*9=81 Rectangles, where every Rectangle represent 1 cell of the sudoku field.
In the touchDown(touchDown(int screenX, int screenY, int pointer, int button) you can simply check, which Rectangle has been touched, by using Rectangle.contains(Vector2 point).
To know, which Rectangle is selected you can store an int selRect, which stores the index of the selected Rectangle or -1, if no Rectangle is selected.
The lower left Rectangle would have the index 0, the lower right the index 8 and the top right would have the index 80.
The whole sudoku-field can be stored in a 2D int array, containing the numbers from 0-9, where 0 is an empty field.
In the render you can simply cycle through the 2D array and check the selRect and render the right Texture

I hope i was clear enough.



来源:https://stackoverflow.com/questions/27986403/how-to-select-and-deselect-a-rectangle-texture-properly-on-click

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!