问题
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 Rectangle
s, 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