ontouch is called twice aftr single click on image in canvas

Problems with Canvas, OpenGL, etc...

ontouch is called twice aftr single click on image in canvas

Postby sahil.suri » Wed Oct 27, 2010 7:28 am

I am creating a memory matching game in which i have placed grid of images in canvas.
as i have created customized view class which implements ontouchListener.
but the callback onTouch() is getting called twice on each click of image as i have checked the logs.
so help m regarding this as what other callback do i need to implement or what i am doing wrong...
here's the code below
package com.sasken.app;

import java.util.Arrays;
import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import android.view.View.OnTouchListener;;

public class GameScreen extends View implements OnTouchListener {
private static final String TAG = "Touchimage";
private Game game;


public GameScreen(Context context) {
super(context);

Log.i(TAG,"constructor()....");
this.game = (Game) context;
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);

/*thumbnailStoped = false;
thumbnailThread = new Thread(new Runnable() {
public void run() {
Log.i(TAG,"***thumbnailThread run***");
while(! thumbnailStoped )
{
view.invalidate();
Log.d(TAG, "after calling postinvalidate");
thumbnailStoped = true;
}

Log.i(TAG, "***thumbnailThread continue running***");
SystemClock.sleep (1000);

}}); */
}

public GameScreen(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public GameScreen(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
private float width; // width of one tile
private float height; // height of one tile
private int selX; // X index of selection
private int selY; // Y index of selection
private final Rect selRect = new Rect();
private static Bitmap _sct[];

private static Bitmap _sct1[];
private static Bitmap[] _sctb2;
private static Bitmap [] _sctb3;
private Bitmap cnst;
private static boolean touched=false;
private static Integer[] mThumbIds = {
R.drawable.icon,
R.drawable.snowflake,R.drawable.a,R.drawable.b,R.drawable.c,
R.drawable.e,R.drawable.f,R.drawable.j,R.drawable.a,R.drawable.a,R.drawable.a,
R.drawable.a,R.drawable.a,R.drawable.a,R.drawable.a,R.drawable.a

};
private static Integer[] mThumbblank = {
R.drawable.blanksmall,R.drawable.blanksmall,R.drawable.blanksmall,
R.drawable.blanksmall,R.drawable.blanksmall,R.drawable.blanksmall,
R.drawable.blanksmall,R.drawable.blanksmall,R.drawable.blanksmall,
R.drawable.blanksmall,R.drawable.blanksmall,R.drawable.blanksmall,
R.drawable.blanksmall,R.drawable.blanksmall,R.drawable.blanksmall,
R.drawable.blanksmall};
private static int ond;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w / 4f;
height = h / 4f;
getRect(selX, selY, selRect);
Log.d(TAG, "onSizeChanged: width " + width + ", height "
+ height);
super.onSizeChanged(w, h, oldw, oldh);
}
private void getRect(int x, int y, Rect rect) {
rect.set((int) (x * width), (int) (y * height), (int) (x
* width + width), (int) (y * height + height));
}
private static int k=0;
@Override
protected void onDraw(Canvas canvas) {
Log.d(TAG, "inside ondraw. "+ond);
ond++;
Paint background = new Paint();
background.setColor(getResources().getColor(
R.color.puzzle_background));
canvas.drawRect(0, 0, getWidth(), getHeight(), background);
Paint dark = new Paint();
dark.setColor(getResources().getColor(R.color.puzzle_dark));
Log.d(TAG, "onDraw " + getWidth() + ", y " + getHeight());
for (int i = 0; i<4; i++) {

canvas.drawLine(0, i * height, getWidth(), i * height,
dark);
canvas.drawLine(0, i * height + 1, getWidth(), i * height
+ 1, dark);
canvas.drawLine(i * width, 0, i * width, getHeight(), dark);
canvas.drawLine(i * width + 1, 0, i * width + 1,
getHeight(), dark);
}
Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);
FontMetrics fm = foreground.getFontMetrics();
// Centering in X: use alignment (and X at midpoint)
float x = width / 2;
// Centering in Y: measure ascent/descent first
float y = height / 2- (fm.ascent + fm.descent) / 2;
/*Integer[] mThumbIds = {
R.drawable.icon,
R.drawable.snowflake,R.drawable.a,R.drawable.b,R.drawable.c,
R.drawable.g,R.drawable.e,R.drawable.f,R.drawable.j,
R.drawable.k,R.drawable.l,R.drawable.m,R.drawable.h,
R.drawable.j,R.drawable.p,R.drawable.i
};
*/

if(k==0)
{
_sct=new Bitmap[mThumbIds.length];
//converting image to bitmap
imageviewtobimap(_sct,mThumbIds);

_sct1=new Bitmap[mThumbIds.length];
for(int k=0;k<mThumbIds.length;k++)
{
_sct1[k]=getResizedBitmap(_sct[k],height, width);
}



_sctb2=new Bitmap[mThumbblank.length];
//converting image to bitmap
imageviewtobimap(_sctb2,mThumbblank);
}
k++;
cnst=BitmapFactory.decodeResource(getResources(), R.drawable.blanksmall);


//Bitmap _sct1[]=new Bitmap[mThumbIds.length];
_sctb3=new Bitmap[mThumbblank.length];

//resizing all images bitmaps
for(int k=0;k<mThumbblank.length;k++)
{
_sctb3[k]=getResizedBitmap(_sctb2[k],height, width);
}

//Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
//ImageView img= new ImageView(Tutorial2D.this);
//img.setImageBitmap(_scratch);
//canvas.drawColor(Color.BLACK);

for (int i = 0; i<4; i++) {
for (int j = 0; j<4; j++) {
canvas.drawBitmap(_sctb3[(i*4)+j], j
* width , i * height , foreground);
}
}
//setOnTouchListener(this);
/* Thread t=Thread.currentThread();
try {
t.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/


//canvas.drawBitmap(_scratch, 0, 0, null);
super.onDraw(canvas);
}

public void numbergenerator(int [][] dArray)
{
int[] t = new int[8];
for (int i=0; i<8; i++){
t[i] = 0;
}
Random r = new Random();

int number;
for (int i = 0; i<4; i++){
for (int j = 0; j<4; j++){
number = r.nextInt(8) ; // generate a number
while (t[number] == 2){
// if the number was already generated 2 times
number = r.nextInt(8) ; // generate another number
}
// we have a number that was NOT generated 2 times
// add it to 2D array
dArray[i][j] = number;
// increment the times he was generated
t[number] = t[number] + 1;
// number-1 because the index of an array starts from 0, not from 1
}
}
}
public void imageviewtobimap(Bitmap []_sct,Integer[] mThumbIds1)
{
int[][] dArray = new int[4][4];
numbergenerator(dArray);
/*int[] t = new int[8];
for (int i=0; i<8; i++){
t[i] = 0;
}
Random r = new Random();

int number;
for (int i = 0; i<4; i++){
for (int j = 0; j<4; j++){
number = r.nextInt(8) ; // generate a number
while (t[number] == 2){
// if the number was already generated 2 times
number = r.nextInt(8) ; // generate another number
}
// we have a number that was NOT generated 2 times
// add it to 2D array
dArray[i][j] = number;
// increment the times he was generated
t[number] = t[number] + 1;
// number-1 because the index of an array starts from 0, not from 1
}
}*/
if(mThumbIds1==mThumbIds)
{
//Random generator = new Random();
//for(int k=0;k<mThumbIds.length;k++)
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
Log.d("thumbs id","-------------Random number----------"+dArray[i][j]);

//int w=generator.nextInt( 7 );
_sct[(i*4)+j] = BitmapFactory.decodeResource(getResources(),mThumbIds[ dArray[i][j]]);
//Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
}
}
if(mThumbIds1==mThumbblank)
{
for(int k=0;k<mThumbblank.length;k++)
{

_sct[k] = BitmapFactory.decodeResource(getResources(),mThumbblank[k]);
//Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
}
}
public Bitmap getResizedBitmap(Bitmap bm, float newHeight, float newWidth)
{
int width1 = bm.getWidth();
int height1 = bm.getHeight();
float scaleWidth = (((float) newWidth) / width1);
scaleWidth-=scaleWidth*0.1;
float scaleHeight = ((float) newHeight) / height1;
scaleHeight-=scaleHeight*0.1;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width1, height1, matrix, false);
return resizedBitmap;

}


@Override
public boolean onTouch(View v, MotionEvent event) {

Log.d("ONTOUCH","<<<<<<<<<<<<<<INSIDE ON TOUCH>>>>>>>>>>>>>>>>");
float x=event.getX();
float y=event.getY();
Log.d(TAG, "width" + width );
Log.d(TAG, "X" + x );
Log.d(TAG, "height" +height );
Log.d(TAG, "Y" + y);
int i=0,j=0;
for( i=1;i<=4;i++)
{
if(width>x)
{
Log.i(TAG, "inside i" + i);
break;

}
if((i)*width <x )
{

if((i+1)*width >x)
{
i++;
Log.d(TAG, "inside i.." + (i));
break;
}
else
{
continue;
}
}

}
for( j=1;j<=4;j++)
{
if(height>y)
{
Log.d(TAG, "inside j" + j);
break;

}
if((j)*height<y)
{
if((j+1)*height>y)
{
j++;
Log.d(TAG, "inside j.." + (j) );
break;
}
else
{
continue;
}
}

}
//Toast.makeText(this,x, System.currentTimeMillis());
//Toast.makeText(Game.class,"you have clicked on"+x,Toast.LENGTH_LONG).show();
Log.d(TAG, "onTouch: x " + x + ", y " + y);
Log.d(TAG, "image no. " +(((j-1)*4)+i));
change(j-1,i-1,v);
postInvalidate();
//invalidate();
/* if(j==4)
{
Log.d(TAG, "image no. " +((j*3)+(i)));
}
else if(j%2!=0)
{
Log.d(TAG, "image no. " +((j*j)+(i-1)));
}
else
{
Log.d(TAG, "image no. " +((j*j)+(i)));
}*/
return true;
}
private static int cm=0;
private static int index=0;
private static int cm1;
private static int cm2;
private static Bitmap cmp1;
private static Bitmap cmp2;
private int [] a=new int[30];
public void change(int i,int j,View v)
{


cm++;
Log.d("change..",">>>cm<<<<"+cm);
//mThumbIds[(i*4)+j]=R.drawable.blanksmall;
// _sctb2[(i*4)+j] =_sct[(i*4)+j];
if(cm==1 )
{
cmp1=_sct[(i*4)+j];

//cmp1.copy(_sct[(i*4)+j].getConfig(), true);
cm1=(i*4)+j;
Log.d(">>>>>>1st image position>>>>>>",">>>>>>>>><<<<<<<<<<<<<"+cm1);
_sctb2[(i*4)+j] =_sct[(i*4)+j];
//_sctb2[(i*4)+j].copy(_sct[(i*4)+j].getConfig(), true);
Log.d("Change","1stimage clicked");


}
else if(((i*4)+j)!=cm1)
{
Log.d("Change","2ndimage clicked");
cm=0;
cm2=(i*4)+j;
cmp2=_sct[(i*4)+j];
//cmp2.copy(_sct[(i*4)+j].getConfig(),true);
Log.d(">>>>>>2st image position>>>>>>",">>>>>>>><<<<<<<<<<"+cm2);
int w = cmp1.getWidth();

int h = cmp2.getHeight();



int[] pixels1 = new int[w * h];
cmp1.getPixels(pixels1, 0, w, 0, 0, 1, 1);

w = cmp2.getWidth();

h = cmp2.getHeight();

int[] pixels2 = new int[w * h];
cmp2.getPixels(pixels2, 0, w, 0, 0, 1, 1);;

boolean isEqual = Arrays.equals(pixels1, pixels2);
if(isEqual)
{
Log.d("Change","images are equal");
_sctb2[(i*4)+j] =_sct[(i*4)+j];
_sctb2[cm1] =_sct[cm1];
a[++index]=cm1;
a[++index]=(i*4)+j;
//_sctb2[(i*4)+j].copy(_sct[(i*4)+j].getConfig(), true);
//_sctb2[cm1].copy(_sct[cm1].getConfig(), true);

}
else
{
Log.d("Change","images are not equal");
boolean flag=true;
for(int k=0;k<a.length;k++)
{
if(cm1==a[k] || ((i*4)+j)==a[k])
{

flag=false;
break;
}

}
if(flag)
{
_sctb2[(i*4)+j] =cnst;
_sctb2[cm1] =cnst;
flag=false;
}
//_sctb2[(i*4)+j].copy(cnst.getConfig(), true);
//_sctb2[cm1].copy(cnst.getConfig(), true);
//touched=true;

}
cm1=0;
}
//Log.i(TAG, "change"+(((j*4)+i+1))+"image");

//v.postInvalidate();
Log.d(TAG, "after calling invalidate");


//View view=new View(getContext());
//view.postInvalidate();
//Log.d(TAG, "after calling postinvalidate");

/*if(!thumbnailThread.isAlive()){
thumbnailStoped=false;
thumbnailThread.start();
Log.d(TAG, "after calling postinvalidate");
}
*/



}

}
sahil.suri
Freshman
Freshman
 
Posts: 5
Joined: Wed Jul 21, 2010 4:19 am

Top

Re: ontouch is called twice aftr single click on image in ca

Postby Schermvlieger » Wed Oct 27, 2010 8:59 am

onTouch is called for DOWN, MOVE and UP events respectively, so you'll have to check the event action type as well as its coordinates.
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Re: ontouch is called twice aftr single click on image in ca

Postby sahil.suri » Wed Oct 27, 2010 10:24 am

can you please show me demo example with regards to what i need in m application.
sahil.suri
Freshman
Freshman
 
Posts: 5
Joined: Wed Jul 21, 2010 4:19 am

Re: ontouch is called twice aftr single click on image in ca

Postby Schermvlieger » Wed Oct 27, 2010 11:01 am

just check the value coming back from event.getAction() and compare with the constants for the MotionEvent class:

http://developer.android.com/reference/ ... Event.html
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Re: ontouch is called twice aftr single click on image in ca

Postby sahil.suri » Wed Oct 27, 2010 12:06 pm

@Schermvliege...
first of all thanks 4 ur replies..
the point here is that i want to get the image position like image1 or image5...
as i am storing the image in an array.
by using
switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
// Remember our initial down event location.

startX = event.getRawX();
startY = event.getRawY();
break;

case MotionEvent.ACTION_MOVE:
float x = event.getRawX();

float y = event.getRawY();
// Calculate move update. This will happen many times
// during the course of a single movement gesture.

scrollByX = x - startX; // move update x increment
scrollByY = y - startY; // move update y increment

startX = x; // reset initial values to latest
startY = y;



break;
}
if i click on image 1 then i am getting some other image position.
but the logic i am using above by comparing coordinates gives me exact image position..
so can you tell me how do i get exact image position
sahil.suri
Freshman
Freshman
 
Posts: 5
Joined: Wed Jul 21, 2010 4:19 am

Re: ontouch is called twice aftr single click on image in ca

Postby Schermvlieger » Wed Oct 27, 2010 2:30 pm

If you want to decide with picture was clicked, you could use Rect (or RectF) in your canvas.drawBitmap method.
Then you can use Rect.contains(x, y) to check for each picture if the Touch event was within its boundary.

There are probably more efficient methods, and I am also not 100% sure if this is what you are trying to accomplish so let us know if that is the case.
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Top

Re: ontouch is called twice aftr single click on image in ca

Postby sahil.suri » Thu Oct 28, 2010 5:04 am

what i am doing is that firsly i am creating grid like view by using drawLine() function.
then i put 16 images in dat grid.
ontouch() callback i am checking the x and y coordinate to get which image is clicked.
As by using dat comparison i get the image clicked but the thing is dat by single click it is going to ontouch() twice or thrice and dats where my logic breaks when i compare the images whether dey are same or not.
sahil.suri
Freshman
Freshman
 
Posts: 5
Joined: Wed Jul 21, 2010 4:19 am

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 3 guests