Cách phân biệt một vòi với một kéo


7

Tôi đang tạo một ứng dụng và tôi đang cố gắng tạo nó để tôi có thể kéo một sprite (với một sprite thứ hai ở trên cùng) xung quanh màn hình, nhưng nếu tôi chỉ cần nhấn vào sprite, một số phương thức khác sẽ được gọi.

Tôi đã kéo được hoạt động tốt khi tôi chạm vào cạnh của sprite của mình, nhưng khi tôi cố gắng kéo từ giữa sprite (nơi sprite thứ hai ở trên cùng) thì kéo không hoạt động, nhưng vòi được gọi .

Tôi biết tại sao không làm điều này, tho, có những đụng chạm mâu thuẫn từ cả hai nhánh bởi vì cái trên cùng đang nuốt cảm ứng trước khi nó chạm vào cái thứ hai bên dưới nó.

Làm thế nào tôi có thể thực hiện điều này khi tôi muốn sprite kéo nếu ngón tay di chuyển, nhưng tôi muốn nhấn để đăng ký khi chỉ một lần nhấn (IE ngón tay không di chuyển trên màn hình)?

Một hình ảnh của các họa tiết tôi đang làm việc (nếu nó giúp): nhập mô tả hình ảnh ở đây

Rune màu vàng là một sprite riêng biệt từ đá bên dưới nó (bởi vì có hoạt hình liên quan).

--------Touch for the top sprite----------
-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event{
    lastTouchLocation = [RuneScene locationFromTouch:touch];
    BOOL isTouchHandled = CGRectContainsPoint([charSprite boundingBox], lastTouchLocation);

    return isTouchHandled;
}
-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event{
    NSLog(@"Tap received!");

}

------Touch for the bottom sprite--------

-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event{
    lastTouchLocation = [RuneScene locationFromTouch:touch];
    BOOL isTouchHandled = NO;

    // Check if this touch is on the Spider's sprite.
    if (CGRectContainsPoint([current.runeSprite boundingBox], lastTouchLocation)){
        mover = current;
        isTouchHandled = YES;
    }
    else if(CGRectContainsPoint([rune1.runeSprite boundingBox], lastTouchLocation)){
        mover = rune1;
        isTouchHandled = YES;
    }
    else if(CGRectContainsPoint([rune2.runeSprite boundingBox], lastTouchLocation)){
        mover = rune2;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune3.runeSprite boundingBox], lastTouchLocation)){
        mover = rune3;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune4.runeSprite boundingBox], lastTouchLocation)){
        mover = rune4;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune5.runeSprite boundingBox], lastTouchLocation)){
        mover = rune5;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune6.runeSprite boundingBox], lastTouchLocation)){
        mover = rune6;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune7.runeSprite boundingBox], lastTouchLocation)){
        mover = rune7;
        isTouchHandled = YES;
    }else if(CGRectContainsPoint([rune0.runeSprite boundingBox], lastTouchLocation)){
        mover = rune0;
        isTouchHandled = YES;
    }

    // Stop the move action so it doesn't interfere with the user's scrolling.
    //[self stopActionByTag:ActionTagCastingLayerMovesBack];

    // Always swallow touches, GameLayer is the last layer to receive touches.
    return isTouchHandled;

}

-(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent *)event{
    CGPoint currentTouchLocation = [RuneScene locationFromTouch:touch]; 

    // Take the difference of the current to the last touch location.
    CGPoint moveTo = ccpSub(lastTouchLocation, currentTouchLocation);

    // Then reverse it since the goal is not to give the impression of moving the camera over the background, 
    // but to touch and move the background.
    moveTo = ccpMult(moveTo, -1);

    lastTouchLocation = currentTouchLocation;

    [self moveActionWithLocation: moveTo];
}

-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event{
    if (!current.isPlaced && mover == current && currentR < Rune6) {
        // Move the game layer back to its designated position.
        CCMoveTo* move = [CCMoveTo actionWithDuration:1 position:curPt];
        CCEaseIn* ease = [CCEaseIn actionWithAction:move rate:0.5f];
        //ease.tag = ActionTagCastingLayerMovesBack;
        [current.runeSprite runAction:ease];

        [current setIsPlaced:YES];
        current.charSprite = [characters objectAtIndex:currentR];
        current.charSprite.position = curPt;
        //charSprite.visible = YES;
        [current performSelector:@selector(fade:) withObject:current.charSprite afterDelay:1];
        [current reorderChild:current.charSprite z:10];

        [self updateCurrentRune:currentR];
        [self updateCurrentCastNum:currentP];
        [self reorderChild:current z:10];
    }
}

Tôi đã thử xem xét UITapGestureRecognizer, nhưng mọi thứ tôi làm để cố gắng thực hiện mà không bao giờ hoạt động. Các lớp / họa tiết của tôi sẽ không cho phép tôi thêm chúng dưới dạng cử chỉ. Tôi cũng đã đọc một cái gì đó về CCGrstureRecognizer hoặc một cái gì đó trên diễn đàn cocos2d, nhưng tôi không thể tìm thấy bất kỳ tài liệu nào về lớp đó, tôi cũng không thể tìm ra cách sử dụng nó ...

Có ai ở đây biết một cách để giúp tôi với vấn đề của tôi?

Câu trả lời:


5

Tôi không thể nói cho bạn biết về cocos2d một cách cụ thể, nhưng nói chung, nhấn so với kéo là vấn đề nhận dạng đầu vào tương tự như nhấp chuột so với kéo.

Cách tiêu chuẩn để xử lý việc này là lưu ý khi xảy ra mousedown (hoặc chạm) và lưu trữ nơi xảy ra, để tham khảo sau. Theo dõi các sự kiện mousemond (hoặc touchmond) để xem nếu nó di chuyển xung quanh. Nếu nó di chuyển đến một vị trí cách khoảng cách nhất định so với lần nhấp / chạm ban đầu (thường là 3 pixel cho thao tác chuột - tôi tưởng tượng rằng ngưỡng này sẽ cao hơn một chút đối với điều khiển cảm ứng), sau đó phân loại nhấp / chạm là kéo, và bắt đầu đối xử với nó theo cách đó (di chuyển các đối tượng, v.v.). Nếu mousedown / touch được giải phóng mà không bao giờ được chuyển thành kéo, thì hãy hành động theo vị trí nhấp / chạm được lưu trữ như là một sự kiện nhấp / chạm đơn giản.

Bạn sẽ có thể triển khai hệ thống nhận dạng đơn giản này hoàn toàn trong các thông điệp C mục tiêu TouchBegan, TouchMoved và TouchEnded mà bạn đã có, chỉ bằng cách lưu trữ thêm một chút trạng thái về mỗi lần chạm.


Không quá đơn giản, bạn cũng nên suy nghĩ về đồng bằng giữa báo chí và phát hành. điều này sẽ giúp bạn hiểu nếu đó là một nhấn hoặc nhấn. Ví dụ: nếu bạn chạm vào màn hình, vượt qua 1 giây và bất kỳ sự kiện phát hành nào đã được đưa ra, hãy coi đó là một sự nhấn mạnh và bỏ qua sự kiện phát hành tiếp theo, nếu bạn nhận được một bản phát hành trước khi 1 giây trôi qua, hãy coi bản phát hành là một cú chạm.
Gustavo Maciel

0

IOS đã thực hiện phát hiện chạm / kéo.

ccTouchMoved chỉ được gọi khi ngón tay di chuyển (với dung sai). Vì vậy, chỉ cần thực hiện ccTouchMoved trong topSprite. Nếu nó được gọi, bạn có thể xem xét nó kéo.

-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event{
    lastTouchLocation = [RuneScene locationFromTouch:touch];
    BOOL isTouchHandled = CGRectContainsPoint([charSprite boundingBox], lastTouchLocation);
    dragged=NO;

    return isTouchHandled;
}
-(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent *)event{
    NSLog(@"Drag !");

    dragged=YES;
}
-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event{
    NSLog(@"Tap received!");
    if (!dragged) {
        //Follow tap event to the mainSprite
        //...TODO
    }
    dragged=NO;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.