如何使 SurfaceView 内的矩形对象可点击(setOnItemClickListener)
How to make rect object inside SurfaceView clickable (setOnItemClickListener)
我正在制作某种益智游戏,其中有方块,用户必须点击它才能移动方块,我需要在每个单独的方块(矩形对象)上设置 setOnItemClickListener,因为每个方块都会起作用根据其位置单击时会有所不同。现在我已经设法绘制了块,但是我无法为每个不同的块添加项目点击监听器。
MainActivity.java
public class MainActivity extends Activity {
PuzzleView puzzleView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a display object to access screen details
Display display = getWindowManager().getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
display.getSize(size);
// Initialize gameView and set it as the view
puzzleView = new PuzzleView(this, size.x, size.y);
setContentView(puzzleView);
}
// This method executes when the player starts the game
@Override
protected void onResume() {
super.onResume();
// Tell the gameView resume method to execute
puzzleView.resume();
}
}
PuzzleView.java
public class PuzzleView extends SurfaceView implements Runnable {
Context context;
// This is our thread
private Thread gameThread = null;
// Our SurfaceHolder to lock the surface before we draw our graphics
private SurfaceHolder ourHolder;
// A boolean which we will set and unset
// When the game is running or not
private volatile boolean playing;
// Game is paused at the start
private boolean paused = true;
// A canvas and a Paint object
private Canvas canvas;
private Paint paint;
// Size of screen in pixels
private int screenX;
private int screenY;
// Blocks of puzzle
private Block[] blocks = new Block[10];
private int numBlocks;
// Position of block
private int block_right;
// When we initialize call on gameView
// This constructor runs
public PuzzleView(Context context, int x, int y) {
// Ask SurfaceView class to set up our object
super(context);
// Make a globally available copy of the context so we can use it in another method
this.context = context;
// Initialize ourHolder and paint objects
ourHolder = getHolder();
paint = new Paint();
screenX = x;
screenY = y;
block_right = 0;
prepareLevel();
}
private void prepareLevel() {
// Here we will intialize all game objects
// Build the blocks
numBlocks = 0;
for(int column = 0; column < 2; column++) {
for(int row = 0; row < 2; row++) {
blocks[numBlocks] = new Block(row, column, screenX, screenY);
numBlocks++;
}
}
}
@Override
public void run() {
while(playing) {
// Update the frame
if(!paused) {
update();
}
// Draw the frame
draw();
}
}
private void update() {
// Move the block
}
private void draw() {
// Make sure our drawing surface is valid or we crash
if(ourHolder.getSurface().isValid()) {
// Lock the canvas ready to draw
canvas = ourHolder.lockCanvas();
// Draw the background color
canvas.drawColor(Color.argb(255, 255, 255, 255));
// Choose the brush color for drawing
paint.setColor(Color.RED);
// Draw the block
for(int i = 0; i < numBlocks; i++) {
canvas.drawRect(blocks[i].getRect(), paint);
}
//Change brush color for text
paint.setColor(Color.BLACK);
// Draw the score
paint.setTextSize(20);
canvas.drawText("Right: " + block_right, 10, screenY - 50, paint);
// Draw everything to the screen
ourHolder.unlockCanvasAndPost(canvas);
}
}
// If MainActivity is started then start our thread
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
}
Block.java
public class Block {
private RectF rect;
public Block(int row, int column, int screenX, int screenY) {
int padding = 1;
int width = 50;
int height = 50;
int outer_padding = (screenX - 104) / 2;
rect = new RectF(column * width + padding + outer_padding,
row * height + padding + 40,
column * width + width - padding + outer_padding,
row * height + height - padding + 40);
}
public RectF getRect() {
return this.rect;
}
}
现在如何为每个块对象创建点击事件侦听器?
非常欢迎所有建议和改进。
提前致谢。
您不能为绘制的对象添加监听器。听众是为了不同的观点。
如果您想自己绘制所有内容,您仍然可以确定是否在矩形内部发生了触摸事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Check if click is within bounds of your rect
if (event.getX() >= mRectStartX && event.getX() <= mRectEndX && event.getY() >= mRectStartY && event.getY() <= mRectEndY) {
// Clicked within your rect, register further clicks by consuming this click
return true;
}
}
return super.onTouchEvent(event);
}
检测到触摸后,您必须重新绘制矩形。
这比简单的点击侦听器复杂得多,但这就是你想要自己绘制的结果:P
P.S。您可以使用 GestureDetector
来简化此过程,但本质上它保持不变。
我正在制作某种益智游戏,其中有方块,用户必须点击它才能移动方块,我需要在每个单独的方块(矩形对象)上设置 setOnItemClickListener,因为每个方块都会起作用根据其位置单击时会有所不同。现在我已经设法绘制了块,但是我无法为每个不同的块添加项目点击监听器。
MainActivity.java
public class MainActivity extends Activity {
PuzzleView puzzleView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a display object to access screen details
Display display = getWindowManager().getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
display.getSize(size);
// Initialize gameView and set it as the view
puzzleView = new PuzzleView(this, size.x, size.y);
setContentView(puzzleView);
}
// This method executes when the player starts the game
@Override
protected void onResume() {
super.onResume();
// Tell the gameView resume method to execute
puzzleView.resume();
}
}
PuzzleView.java
public class PuzzleView extends SurfaceView implements Runnable {
Context context;
// This is our thread
private Thread gameThread = null;
// Our SurfaceHolder to lock the surface before we draw our graphics
private SurfaceHolder ourHolder;
// A boolean which we will set and unset
// When the game is running or not
private volatile boolean playing;
// Game is paused at the start
private boolean paused = true;
// A canvas and a Paint object
private Canvas canvas;
private Paint paint;
// Size of screen in pixels
private int screenX;
private int screenY;
// Blocks of puzzle
private Block[] blocks = new Block[10];
private int numBlocks;
// Position of block
private int block_right;
// When we initialize call on gameView
// This constructor runs
public PuzzleView(Context context, int x, int y) {
// Ask SurfaceView class to set up our object
super(context);
// Make a globally available copy of the context so we can use it in another method
this.context = context;
// Initialize ourHolder and paint objects
ourHolder = getHolder();
paint = new Paint();
screenX = x;
screenY = y;
block_right = 0;
prepareLevel();
}
private void prepareLevel() {
// Here we will intialize all game objects
// Build the blocks
numBlocks = 0;
for(int column = 0; column < 2; column++) {
for(int row = 0; row < 2; row++) {
blocks[numBlocks] = new Block(row, column, screenX, screenY);
numBlocks++;
}
}
}
@Override
public void run() {
while(playing) {
// Update the frame
if(!paused) {
update();
}
// Draw the frame
draw();
}
}
private void update() {
// Move the block
}
private void draw() {
// Make sure our drawing surface is valid or we crash
if(ourHolder.getSurface().isValid()) {
// Lock the canvas ready to draw
canvas = ourHolder.lockCanvas();
// Draw the background color
canvas.drawColor(Color.argb(255, 255, 255, 255));
// Choose the brush color for drawing
paint.setColor(Color.RED);
// Draw the block
for(int i = 0; i < numBlocks; i++) {
canvas.drawRect(blocks[i].getRect(), paint);
}
//Change brush color for text
paint.setColor(Color.BLACK);
// Draw the score
paint.setTextSize(20);
canvas.drawText("Right: " + block_right, 10, screenY - 50, paint);
// Draw everything to the screen
ourHolder.unlockCanvasAndPost(canvas);
}
}
// If MainActivity is started then start our thread
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
}
Block.java
public class Block {
private RectF rect;
public Block(int row, int column, int screenX, int screenY) {
int padding = 1;
int width = 50;
int height = 50;
int outer_padding = (screenX - 104) / 2;
rect = new RectF(column * width + padding + outer_padding,
row * height + padding + 40,
column * width + width - padding + outer_padding,
row * height + height - padding + 40);
}
public RectF getRect() {
return this.rect;
}
}
现在如何为每个块对象创建点击事件侦听器? 非常欢迎所有建议和改进。 提前致谢。
您不能为绘制的对象添加监听器。听众是为了不同的观点。
如果您想自己绘制所有内容,您仍然可以确定是否在矩形内部发生了触摸事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Check if click is within bounds of your rect
if (event.getX() >= mRectStartX && event.getX() <= mRectEndX && event.getY() >= mRectStartY && event.getY() <= mRectEndY) {
// Clicked within your rect, register further clicks by consuming this click
return true;
}
}
return super.onTouchEvent(event);
}
检测到触摸后,您必须重新绘制矩形。
这比简单的点击侦听器复杂得多,但这就是你想要自己绘制的结果:P
P.S。您可以使用 GestureDetector
来简化此过程,但本质上它保持不变。