在 canvas 上跟踪触摸输入
Track touch input on canvas
我有一个由 canvas drawrect 制成的 5x5 方块的游戏板:
protected void onDraw(Canvas canvas) {
for (int rowNo = 0; rowNo < nSquares; rowNo++) {
paint.setColor(((rowNo & 1) == 0) ? colorA : colorB);
for (int colNo = 0; colNo < nSquares; colNo++) {
int left = colNo * squareWidth;
int top = rowNo * squareWidth;
Rect areaRect = new Rect(left, top, left + squareWidth, top + squareWidth);
canvas.drawRect(areaRect, paint);
paint.setColor((paint.getColor() == colorA) ? colorB : colorA);
paint.setTextSize((float)(squareWidth*0.8));
RectF bounds = new RectF(areaRect);
String letter = "A";
bounds.right = paint.measureText(letter, 0, letter.length());
bounds.bottom = paint.descent() - paint.ascent();
bounds.left += (areaRect.width() - bounds.right) / 2.0f;
bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
canvas.drawText(letter, bounds.left, bounds.top - paint.ascent(), paint);
}
}
我想跟踪触摸输入以获取用户正在触摸的方块..
我的尝试是
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX();
int y = (int)event.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x,y);
}
getSquare 在哪里
public int getSquare(int x, int y) {
int row = 0;
int col = 0;
for(int rowNo = 1; rowNo <= nSquares; rowNo++) {
Log.i("Row", "Width: " + squareWidth + " rowNo: " + rowNo + " rowNo*squareW: " + rowNo*squareWidth + " y: " + y);
if(rowNo*squareWidth > y)
{
row = rowNo;
break;
}
}
for (int colNo = 1; colNo <= nSquares; colNo++) {
if(colNo*squareWidth > x)
{
col = colNo;
break;
}
}
Log.i(DEBUG_TAG, "Row: " + row + " Col: " + col);
return (row-1)*nSquares + col;
}
问题是onTouchEvent getX 和getY 指的是屏幕0,0,但是当我绘制正方形时0,0,0,0 指的是视图原点?我对吗?
如何获得相对于游戏板视图的输入位置?
获取屏幕中的视图位置并将其 add/subtract 定位到 tochEvent x 和 y 位置是否是一种解决方案?
我假设 onDraw()
和 getSquare()
属于 GameBoardView
并且 onTouchEvent()
属于其直接父级。如果是这样,那么 onTouchEvent()
应该是这样的
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX() - gameBoard.getX();
int y = (int)event.getY() - gameBoard.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x, y);
}
在视图中,onDraw()
和 onTouchEvent()
中的 x 和 y 都相对于视图本身(滚动视图时除外)。由于在您的情况下 onTouchEvent()
属于父项而 onDraw()
属于子项,因此我使用 View.getX()
和 getY()
来转换坐标。 View.getX()
returns 视图相对于其父视图的 x 位置加上 translationX。
我无法将 gameBoard().getX/Y() 设置为 return 正确的值。我的猜测是操作栏被排除在外?
我现在用getLocationOnScreen
@Override
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int boardLocation[] = new int[2];
gameBoard.getLocationOnScreen(boardLocation);
int touchX = (int)event.getX();
int touchY = (int)event.getY();
int x = touchX - boardLocation[0];
int y = touchY - boardLocation[1];
int squareTouched = gameBoard.getSquare(x,y);
}
这解决了我的问题..
我有一个由 canvas drawrect 制成的 5x5 方块的游戏板:
protected void onDraw(Canvas canvas) {
for (int rowNo = 0; rowNo < nSquares; rowNo++) {
paint.setColor(((rowNo & 1) == 0) ? colorA : colorB);
for (int colNo = 0; colNo < nSquares; colNo++) {
int left = colNo * squareWidth;
int top = rowNo * squareWidth;
Rect areaRect = new Rect(left, top, left + squareWidth, top + squareWidth);
canvas.drawRect(areaRect, paint);
paint.setColor((paint.getColor() == colorA) ? colorB : colorA);
paint.setTextSize((float)(squareWidth*0.8));
RectF bounds = new RectF(areaRect);
String letter = "A";
bounds.right = paint.measureText(letter, 0, letter.length());
bounds.bottom = paint.descent() - paint.ascent();
bounds.left += (areaRect.width() - bounds.right) / 2.0f;
bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
canvas.drawText(letter, bounds.left, bounds.top - paint.ascent(), paint);
}
}
我想跟踪触摸输入以获取用户正在触摸的方块.. 我的尝试是
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX();
int y = (int)event.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x,y);
}
getSquare 在哪里
public int getSquare(int x, int y) {
int row = 0;
int col = 0;
for(int rowNo = 1; rowNo <= nSquares; rowNo++) {
Log.i("Row", "Width: " + squareWidth + " rowNo: " + rowNo + " rowNo*squareW: " + rowNo*squareWidth + " y: " + y);
if(rowNo*squareWidth > y)
{
row = rowNo;
break;
}
}
for (int colNo = 1; colNo <= nSquares; colNo++) {
if(colNo*squareWidth > x)
{
col = colNo;
break;
}
}
Log.i(DEBUG_TAG, "Row: " + row + " Col: " + col);
return (row-1)*nSquares + col;
}
问题是onTouchEvent getX 和getY 指的是屏幕0,0,但是当我绘制正方形时0,0,0,0 指的是视图原点?我对吗? 如何获得相对于游戏板视图的输入位置? 获取屏幕中的视图位置并将其 add/subtract 定位到 tochEvent x 和 y 位置是否是一种解决方案?
我假设 onDraw()
和 getSquare()
属于 GameBoardView
并且 onTouchEvent()
属于其直接父级。如果是这样,那么 onTouchEvent()
应该是这样的
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX() - gameBoard.getX();
int y = (int)event.getY() - gameBoard.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x, y);
}
在视图中,onDraw()
和 onTouchEvent()
中的 x 和 y 都相对于视图本身(滚动视图时除外)。由于在您的情况下 onTouchEvent()
属于父项而 onDraw()
属于子项,因此我使用 View.getX()
和 getY()
来转换坐标。 View.getX()
returns 视图相对于其父视图的 x 位置加上 translationX。
我无法将 gameBoard().getX/Y() 设置为 return 正确的值。我的猜测是操作栏被排除在外?
我现在用getLocationOnScreen
@Override
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int boardLocation[] = new int[2];
gameBoard.getLocationOnScreen(boardLocation);
int touchX = (int)event.getX();
int touchY = (int)event.getY();
int x = touchX - boardLocation[0];
int y = touchY - boardLocation[1];
int squareTouched = gameBoard.getSquare(x,y);
}
这解决了我的问题..