Question about touch input with Cocos2d-x v3

Cocos2d-JS v3
  • efares
    Likes 0

    Problem Description

    Hi,

    I am making a mobile game and I am considering a game (JavaScript) where the user can tap/touch anywhere on the screen. If the touch is on left side of the screen then the player moves left and if touch is on the right side of the screen then player moves right.

    I need some help in determining what the touches[touchIndex] is for this scenarios:

    - User touches left side = touches[0]
    - While keeping touch on left, user touches right = touches[1]
    - If user releases left touch then is the right touch still touches[1] or is it now touches[0] ?

    I am unable to test this and get the log so I'm wondering if someone from the Cocos dev team can tell me.

    Considering the user can touch left/right in any order they want and at the same time or one at a time, I am trying to figure out the best algorithm to handle this. I am thinking to always use the latest touch to determine which way the player should move regardless of any previous touches if they exist or not (if previous touch has been removed or not). So I am trying to figure out how to know what the touchIndex is for the latest touch if I don't know if the user will make their new touch before or after releasing their old touch.

    I hope that's not confusing, any help would be awesome.
    Thanks!

  • Sonar Systems admin
    Likes 0

    touches[0] and touches[1], what sort of variable/array is this?


    This reply has been verified.
  • efares
    Likes 0

    I am looking at this: http://cocos.sonarlearning.co.uk/docs/input 

    Under: MULTI TOUCH INPUT –> Cocos2d-JS

    It says Note: touchIndex is the touch you are detecting so 0 would be the first touch in multi touch, 1 would be the second touch in multi touch etc

    So I am wondering what happens when the first touch is removed, does the second touch stay 1 or does it go to 0?


  • Sonar Systems admin
    Likes 0

    For your scenario just use single touch and use an if statement to detect if the touch is on the left or right side of the screen.

  • efares
    Likes 0

    I was thinking of doing that but I’m not sure if I use single touch event listenner then will the second touch be read or ignored?

    So:

    1. First touch on left side → read
    2. Second touch on right side → ignored or read? since it’s only single touch and there’s already a previous touch

    I could just try it out but thought I’d ask if you knew.


  • Sonar Systems admin
    Likes 0

    TGenerally the users will lift their finger when pressing the other side.

  • efares
    Likes 0

    Ya but from my user testing some users tap the other side so fast that it is done before they release the previous touch so the one touch input ignore the second touch and they have to release their finger and then touch again = bad user experience in my game so I am trying to fix that with multi-touch input. I am trying to come up with an algorithm that only accepts the latest touch gesture.

    I don’t know if the touchIndex changes or remains the same.

  • efares
    Likes 0

    I am trying this:

    init: function () {
    // Add multitouch event listeners
            cc.eventManager.addListener({
                event: cc.EventListener.TOUCH_ALL_AT_ONCE,
                swallowTouches: false,
                onTouchesBegan: this.onTouchBegan,
                onTouchesMoved: this.onTouchMoved,
                onTouchesEnded: this.onTouchEnded,
                onTouchesCancelled: this.onTouchEnded
            }, this);
        },
    // When touch begins we want check where the touch is placed
        onTouchBegan: function (touches, event) {
            event.getCurrentTarget().numOfTouches++; // Increment number of touches
            event.getCurrentTarget().onTouchMoved(touches, event); // Call the onTouchMoved function to determine the location of the touch
    
            return true;
        },
    
        // When touch moves we want check if the move switches sides
        onTouchMoved: function (touches, event) {
            var touch;
    
            // Check which touch this touch is, 1st or 2nd touch
            if (event.getCurrentTarget().numOfTouches == 1)
                touch = touches[0].getLocationX();
            else if (event.getCurrentTarget().numOfTouches == 2)
                touch = touches[1].getLocationX();
    
            // Check where the touch is placed
            if (touch < event.getCurrentTarget().screenCenter.x)
                event.getCurrentTarget().moveStatus = 'down'; // Left side clicked
            else
                event.getCurrentTarget().moveStatus = 'up'; // Right side clicked
    
            return true;
        },
    
        // This is run when a touch ends (user removes a finger from the screen)
        onTouchEnded: function (touches, event) {
            // Decrement number of touches
            event.getCurrentTarget().numOfTouches--;
    
            // Check if there are any touches left, if not then we stop the car
            if (event.getCurrentTarget().numOfTouches <= 0)
                event.getCurrentTarget().moveStatus = 'stop';
    
            return true;
        },

    Which somewhat works. A scenario that DOESN’T work is this:

    1. Touch on the left side (Player moves down, expected)
    2. Keep touching left and then touch on the right side (Player should move up but doesn’t)
    3. Release the left touch (Player keeps moving down, not expected)

    My game controls are entire left side moves player down and entire right side of the screen moves player up. I don’t know why the right/up tap is not being read as a touch began. Any ideas?


  • Sonar Systems admin
    Likes 0

    Your doing if and else, therefore its never hitting the right side code. Try using a state machine.

  • efares
    Likes 0

    Wouldn’t it hit the right side code if touch is greater than screenCenter.x?


  • Sonar Systems admin
    Likes 0

    No because it’s single touch, so it hits the first one with the left side first and never hits the else.

     

    Try splitting them into if statements

  • efares
    Likes 0

    This is solved. Touch should always = touches[0].getLocationX(); I removed touches[1] and that seemed to fix my problem.

    You can mark this as solved. Thanks for all your help!


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Great to hear. 

     

    If you have any other questions on your game development journey feel free to ask them on this platform.

Login to reply