Andengine: split between OnAreaTouched and OnSceneTouched

Hello everybody,

there are a lot of sprites in the game that I am developing with AndEngine. Now each of these sprites has TouchArea registered on the scene because I show some information about the sprite when it is touched. The scene itself has an OnSceneTouchListener , which I use to move the camera and zoom.

My problem is that every time the user moves the camera (by touching the screen somewhere and moving his finger), the OnAreaTouched() method of any sprite that accidentally falls under the finger is called when the movement is finished (the finger rises). I have already limited trigger events to event.getAction()==UP (before it became a real mess called touchAreas), but this is not enough. If the user zooms in or moves the camera, do not activate sprite touch screens.

Is there a way to distinguish between OnAreaTouched -event and OnSceneTouched -event? Which one is called the first and can I crush the other?

This is my OnSceneTouched() (simplified) method:

 public boolean onSceneTouchEvent(Scene scene, final TouchEvent event) { boolean isZooming = event.getMotionEvent().getPointerCount() >= 2; if (event.getAction() == MotionEvent.ACTION_DOWN) { // REMEMBER FIRST TOUCHPOINT, TO KNOW IN WHICH DIRECTION TO MOVE this.touchPoint = new Point(event.getMotionEvent().getX(), event.getMotionEvent().getY()); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (isZooming) { // DO SOME ZOOM STUFF } else { // DO SOME MOVEMENT STUFF } return true; } 

OK, this is actually not very interesting, but as you can see, I always return true to signal that a touch event has been processed. However, OnAreaTouched() gets a call

This is a typical OnAreaTouched() sprite method:

 public boolean onAreaTouched(final TouchEvent touchEvent, float touchAreaLocalX, float touchAreaLocalY) { if (touchEvent.getAction() == TouchEvent.ACTION_UP) { // DISPLAY INFORMATION ABOUT THE SPRITE return true; } return false; } 

You see, there is nothing special. So I hope someone can help me find a solution here on how to suppress OnAreaTouch -event when using OnSceneTouch -event. Maybe I can somehow catch event.getAction()==UP in OnSceneTouched() -Method ??

Hope I could explain the problem, good enough for you to understand (sorry, this is not so easy for me :). Any help is greatly appreciated and thanks for your time!

respectfully
Christoph

edit:

After experimenting with MahdeTo's suggestion to mark the event in some way, I found out the following:

  • TouchEvent , which runs the OnSceneTouchEvent() method, does not match the one that runs the OnAreaTouched() method.
  • OnAreaTouched() receives the call 20 ms later OnSceneTouchEvent()
  • the event that OnAreaTouched() actually begins when the user places his finger on the display (by which he moves it, and OnSceneTouchEvent() is called several times), when he then raises his finger, the first event stops and gets processed. (I tried this by measuring time)

So, I came up with a solution to measure how long the touch event lasted. If the event is longer than 200 ms, I think that the user just wanted not to click, but to move or enlarge (since these actions usually take longer). So, now the OnAreaTouched() method is called only when someone really wanted to click and not accidentally miss the area.

but this is still not a very good solution, and I would really appreciate it if anyone knew about managing such events.

Thank you

+6
source share
2 answers

Recently, I wrote a rather complicated application with touch controls - pressing buttons on the screen, increasing the zoom, rotating and moving objects with two fingers, and much more. What I ended up with was an iterative improvement of the application and the addition of rules governing how to respond to various combinations of sensory events. Whenever something went wrong, I wrote down the TouchEvents sequence and added rules to handle the erroneous action.

You can also create logical keys that prevent onAreaTouched from being executed, just add a condition that, for example, if you want to touch an object, checks if doNotTouchObject true or false.

Another useful thing is touch mode switches. I wrote several methods that completely change the behavior when the user touches the screen. I believe you can switch them on the go, so you can call scene.setOnAreaTouchListener(touchListener) while you touch the screen.

Since un / registration of touch areas quickly flashes, simply unregistering some touch areas while you perform an action is an option. After the action is completed, re-register them again.

I used a combination of all of the above and it works pretty well, but it is important that the code is clean, otherwise debugging or introducing new features will be painful.

+4
source
  • maybe you can use TouchDetector. use clickDetector instead of the TouchUp event of the process, then only the processed click event is processed by sprites; use the scroll detector to scroll through the scene,

  • Turning on SceneTouchListenerBinding and TouchAreaBinding will also help you through all of the unforeseen pending events.

+2
source

Source: https://habr.com/ru/post/918657/


All Articles