📜 ⬆️ ⬇️

Chewing Algorithm for Touchscreen

Not so long ago, my first personal mobile game came out. The bottom line is that enemies need to chew on your fingers. The algorithm is not unique, but is rare. At first glance, you only need to listen to the zoom movement of two fingers, it seems to be nothing complicated, however, various pitfalls are revealed in the process of developing the game.


All code is written in language with # for Unity3D engine, for 2D game. Let's go directly to the code. In the Update method, we calculate the number of taches, and perform the appropriate actions. Move the character in the case of a single touch:

//   if (Input.touchCount == 1) { //      ,      if (!compressing && !decompressing) { Touch singleTouch = Input.GetTouch(0); Vector3 targetPoint = Camera.main.ScreenToWorldPoint (singleTouch.position); targetPoint = new Vector3 (targetPoint.x, targetPoint.y, 0); transform.position = Vector3.MoveTowards (transform.position, targetPoint, movementSpeed * Time.deltaTime); } } 

There is nothing difficult, you can move on. Two-touch processing code. If there is no clenching / unclenching of the jaws, the character moves between two fingers.

 if (Input.touchCount > 1) { //    . Touch touch1 = Input.GetTouch(0); Touch touch2 = Input.GetTouch(1); //   ,     if (!compressing && !decompressing) { Vector3 targetPoint = Camera.main.ScreenToWorldPoint ((touch1.position + touch2.position) / 2); targetPoint = new Vector3 (targetPoint.x, targetPoint.y, 0); transform.position = Vector3.MoveTowards (transform.position, targetPoint, movementSpeed * Time.deltaTime); } float currentDistance = Vector2.Distance(touch1.position, touch2.position); if(pastFingersDistance == 0) { //  ,       pastFingersDistance = currentDistance; }else if(currentDistance < pastFingersDistance - fingersMunchDetectionMin) { //   .  ,   . SetCompression(); }else if(currentDistance > pastFingersDistance + fingersMunchDetectionMin) { //   .  ,   . SetDecompression(); } } // ,          . if(Input.touchCount < 2) pastFingersDistance = 0; //    ,    -   . if(Input.touchCount < 2 && isCompressed) SetDecompression(); 

fingersMunchDetectionMin is a variable that determines how far is enough to start chewing. Long enough set up with the help of several friends. Each had a different perception, brought something in between. During the tests, it also turned out that the user is simply uncomfortable with constantly chewing fingers. There was a need to make clenching of the jaws on a simple tap and the method outlined above acquired the following form:
')
 if (Input.touchCount > 1) { //    . Touch touch1 = Input.GetTouch(0); Touch touch2 = Input.GetTouch(1); //     if (!compressing && !decompressing) { float touch1Time = 0; float touch2Time = 0; //     1 if (tapsHash.Contains (touch1.fingerId)) { float startTouch1Time = (float) tapsHash [touch1.fingerId]; touch1Time = Time.time - startTouch1Time; } //     2 if (tapsHash.Contains (touch2.fingerId)) { float startTouch2Time = (float) tapsHash [touch2.fingerId]; touch2Time = Time.time - startTouch2Time; } //         ,    . if (touch1Time > SECONDS_FOR_TAP && touch2Time > SECONDS_FOR_TAP) { Vector3 targetPoint = Camera.main.ScreenToWorldPoint ((touch1.position + touch2.position) / 2); targetPoint = new Vector3 (targetPoint.x, targetPoint.y, 0); transform.position = Vector3.MoveTowards (transform.position, targetPoint, movementSpeed * Time.deltaTime); } } float currentDistance = Vector2.Distance(touch1.position, touch2.position); if(pastFingersDistance == 0) { //  ,       pastFingersDistance = currentDistance; }else if(currentDistance < pastFingersDistance - fingersMunchDetectionMin) { //   .  ,   . SetCompression(); }else if(currentDistance > pastFingersDistance + fingersMunchDetectionMin) { //   .  ,   . SetDecompression(); } } // ,          . if(Input.touchCount < 2) pastFingersDistance = 0; //    ,    -   . if(Input.touchCount < 2 && isCompressed) SetDecompression(); //       . SetTapAttackListener (); 

The SECONDS_FOR_TAP constant — the time allotted for tap, as well as the distance for chewing, was tested and tuned for quite a long time. Well, and actually the latest methods that carry out chewing on a simple tap:

 void SetTapAttackListener() { if (Input.touchCount > 0) { foreach (Touch touch in Input.touches) { //   DetectOneTouchTap (touch); } } } void DetectOneTouchTap(Touch touch) { if (touch.phase == TouchPhase.Began) { //     ,    -  . // -  ,  -  . tapsHash.Add (touch.fingerId, Time.time); } else if(touch.phase == TouchPhase.Ended) { float startTouchTime = (float) tapsHash [touch.fingerId]; float timeOfTouch = Time.time - startTouchTime; //    ,     if (timeOfTouch <= SECONDS_FOR_TAP) { SetCompression(); SetDecompression(); } tapsHash.Remove (touch.fingerId); } } 

In the beginning I tried to find this algorithm on the Internet, not for copy-paste, but to check my train of thought. However, I did not find anything and decided to post it to help my colleagues. Now I see very well that the code is somewhat chaotic, but for the rest I am waiting for comments.

Update 1:
Demonstration of the algorithm:


Update 2:
An article about game development

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


All Articles