AndroidSurfaceView Touch not working properly - android

I'm creating a chess Game, I am using flag variable to check white or black turn.
First i am creating a chess board by using surface view and drawing bitmap on that canvas to show element of chess.
But my problem is that when I touch canvas every time it call onDraw()-method even i am not calling invalidate(), and returning false in onTouch()
#Override
public boolean onTouchEvent(MotionEvent event) {
if(white){
// Code for select
// Code for move element
// IF Invalid move ( Donot want to call onDraw() so i return here -
false and i did not call invalidate() but it redraw view)
}else if(black){
// same code for balck
}
}

I notice that you always(?) return false by default. In general, if you have no idea what to return (returning true means you consumed that touch event), use return super.onTouchEvent(event); instead. However, this might not be relevant to your issue.

Related

Why after onAreaTouched call, onSceneTouchEvent() event is being called?

In an AndEngine game, I have implemented onAreaTouched() so that when an sprite is tapped, I detect and respond accordingly. Also, I have implemented onSceneTouchEvent() so that when user taps screen, I move the character. But I am having an issue. When user taps on some sprite, the onAreaTouched() is called but after that onSceneTouchEvent() is also being called resulting in two actions against one tap. I want that when sprite is tapped, only onAreaTouched() should be called and vice versa. I also tried to return true/false from onAreaTouched() but it did not worked. Any idea what do am am missing?
If the onAreaTouched() function is being called before the onSceneTouchEvent() function, you could just have a member boolean to control whether or not you want run the code in onSceneTouchEvent()
OnAreaTouched()
{
mIsSpriteTouched = true;
// then run all relevant code when the sprite is touched
}
onSceneTouchEvent()
{
if (!mIsSpriteTouched)
{
//execute code that should run when the sprite isn't touched
}
mIsSpriteTouched = false; //reset for next event;
}

Is there a offset between onTouchEvent and onTouchListener?

I have developed a game that shoots when player touches the screen by using onTouchListener for my custom SurfaceView and Thread.
But now I want to change the approach and instead of onTouchListener I added onTouchEvent to the SurfaceView o my Activity.
The problem is that I get some kind of offset when I click on the emulator.
Everything is working great, except that offset keeps appearing and I don't understand why.
Also let me mention that my app is running in landscape mode, maybe this is relevant.
I suspect that it isn't working properly because onTouchListener was added to the view and depended on it, but onTouchEvent doesn't depend on the view.
Also my view doesn't have any padding or margin properties, it is full-screen view (fill_parent).
Does anyone have any ideas on this?
I have done my application, and everything works correctly now, but i still do not know what the problem was.
After lots of debugging of my application the onTouchEvent returned random Y values that were always higher than the ones that the onTouchListener returned. And i am not sure why this is hapening since my view that recognizes the onTouchListener is a full-screen view.
So i figured out a way to get passed this by doing some math.
The first function that the android calls is the onTouch method which gives the correct values but just for one touch. I needed it to give right values even on the MotionEvent.ACTION_MOVE so i noticed that MotionEvent.ACTION_MOVE is actually doing correctly depending on the first touch recognized by the onTouchEvent.
So i just got the coordinate Y from the onTouch and the different coordinate with the offset from onTouchEvent calculated the difference and in every onTouchEvent from there, until the user lifts up their finger, i just subtract that difference and that gives me the correct value.
If anyone else has this problem, and doesn't know how to fix it, here is my code, maybe it will be helpful.
#Override
public boolean onTouchEvent(MotionEvent arg1) {
/*you can only touch when the thread is running*/
if(game.state() != STATE_PAUSE){
if(arg1.getAction() == MotionEvent.ACTION_DOWN){
coordinateX = arg1.getX();
coordinateY = arg1.getY();
differenceY = Math.abs(coordinateY - touchedY);
coordinateY = coordinateY - differenceY;
shootingIsOkay = true;
game.setDrawCircle(coordinateX,coordinateY);
}
if(arg1.getAction() == MotionEvent.ACTION_MOVE){
coordinateX = arg1.getX();
coordinateY = arg1.getY();
coordinateY = coordinateY - differenceY;
shootingIsOkay = true;
game.setDrawCircle(coordinateX,coordinateY);
}
if(arg1.getAction() == MotionEvent.ACTION_UP){
shootingIsOkay = false;
}
}
return false;
}
And the onTouch method that is called from the onTouchListener that depends on the view is just simple, here:
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
touchedY = arg1.getY();
return false;
}
If anyone knows how to fix this problem, please post your answer, i am very curious why this is happening

Slowing down the read rate of android Ontouchlistener

I am attempting my first game using a custom view extended from view that ,as it stands, is just a background image that can pan by dragging with the ACTION_Move.
It also has a zoom image that gets drawn on the canvas and when an ACTION_UP occurs on this region, a zoom in is registered and the image is scaled up.
The problem I now experience is that although the drag works well with the ontouch function returning true, the ACTION_UP is very sensitive and a single touch executes the code in the ACTION_UP case statement a few hundred times. Instead of just incrementing the zoom up by 10% it rapidly zooms to 100%.
If I return false to the function, the zoom works normally by 10% per touch but as stated in previous posts, the function must return true for ACTION_MOVE to respond.
Things I've tried
Thread.sleep() - it does exactly the same thing by incrementing the zoom 100 times with a delay in between.
Changing the returned value in the case statements so it returns true only for ACTION_MOVE but move does not respond.
You could try using a boolean variable to control the zoom, for example:
private boolean zoom = true;
final Handler handler = new Handler();
// ACTION_UP
if(zoom) {
doZoom();
zoom = false;
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
zoom = true;
}
}, 100); // Delay 100 ms, adjust for ideal zoom speed
Now it won't zoom again until the 100ms delay is completed.

Speed up bitmap animation in custom View

In my custom view i have 1 animation that i need to run at demand (on tile click). Currently i am using this method:
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//check what tile for clicked
getHandler().removeCallbacks(explosionThread);
getHandler().post(explosionThread);
}
}
break;
}
return super.onTouchEvent(event);
}
So i am calling (or sending to view thread, to be specific) a Runnable that calls it self until it comes to an end of an image...
private Runnable explosionThread=new Runnable(){
#Override
public void run() {
invalidate();
if(expCount<15){
getHandler().postDelayed(this, 10);
}
}
};
In my onDraw() method i implemented logic to go threw bitmap and draw it on screen ( using cnavas.drawBitmap(bitmap,srcRect,destRect,paint)....
Now, I want to avoid using SurfaceView (i have only 1 animation and View uses less resources).
I think the animation is slow because onDraw needs to draw whole screen each time invalidate() is called witch can be slow ( drawing 64 tiles with png images). I know that there is an overload of invalidate method, invalidate(Rect dirty) but i don't really know how to use it. If u think that that is the answer please write how to avoid drawing whole onDraw method ( or what method can I overwrite that is used by invalidate(Rect) method, if there is any).
If you have any other better way to speed up animation post it plz.
Thanks in advance....
That's right. One of the way to speed up rendering through canvas is to use invalidate(Rect). Rect passed to invalidate method defines area which will be redrawn. Your onDraw will be called after invalidate with clipping region being set up on canvas. So all your "drawBitmap" will be clipped by the rect.
for running the animation are using a .gif file or you are using a sequence of images run on a thread to show as an animation ?

android need advice to start develop using gestures

I have a canvas.DrawText. I want to use gestures to dynamically change the text color and font. This is all working nice using a popup view class. But I want to make this more direct maybe using Fling scroll.
There are millions of colors and by sliding finger on the screen I thought I could increase/decrease the colorInteger and send it to paint.setColor(colorInteger ); before I draw. I have tried all day using various methods.
I have public boolean onTouchEvent(MotionEvent event) {
I know I must catch the x/y in MotionEvent.ACTION_DOWN
Wanted to use the screen left edge for color change and screen right for Font change. I have 21 ttf fonts.
The thing is, I see there is the OnGestureListener onscroll implementation but that will disable my onTouchEvent right? I have lots of movement going on in there.
public boolean onTouchEvent(MotionEvent event) {
Any idea?
You can use GestureDetector. Implement a GestureDetector.OnGestureListener and catch gestures there.
class MyActivity extends Activity implements GestureDetector.OnGestureListener {
// ....
gestureDetector = new GestureDetector(getContext(), this);
Provide GestureDetector with touch events like this:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else return super.onTouchEvent(event);
}
In GestureDetector.OnGestureListener's onDown you must return true if you want to process this gesture. E.g. then the user puts his finger donw in a specified area return true, and false otherwise. If false is returned here, complicated sequences (like fling or scroll) started with this event will not be detected.

Categories

Resources