我正在尝试实现将改变单位方向的游戏控制 移动。因此,如果我向右滑动,它会向右滑动,如果我向下滑动,它会向右滑动,等等。
这是cocos2d游戏,我正在使用
CCNode+SFGestureRecognizers
和UISwipeGestureRecognizer
。
现在我有下一个实现
UISwipeGestureRecognizer *rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipe:)];
[self addGestureRecognizer:rightSwipeGestureRecognizer];
rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipeGestureRecognizer.delegate = self;
[rightSwipeGestureRecognizer release];
UISwipeGestureRecognizer *upSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleUpSwipe:)];
[self addGestureRecognizer:upSwipeGestureRecognizer];
upSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
upSwipeGestureRecognizer.delegate = self;
[upSwipeGestureRecognizer release];
UISwipeGestureRecognizer *leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipe:)];
[self addGestureRecognizer:leftSwipeGestureRecognizer];
leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
leftSwipeGestureRecognizer.delegate = self;
[leftSwipeGestureRecognizer release];
UISwipeGestureRecognizer *downSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleDownSwipe:)];
[self addGestureRecognizer:downSwipeGestureRecognizer];
downSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
downSwipeGestureRecognizer.delegate = self;
[downSwipeGestureRecognizer release];
但问题是,要识别以下手势,您需要将手指从屏幕上抬起。如果您在第一次滑动后没有抬起手指,它将仅识别第一次滑动。
现在:
应该如何:
最好的方法是什么?谢谢!
cancelsTouchesInView 应该有所帮助,它可以防止手势识别器识别出手势时取消触摸事件。这将允许其他手势识别器继续检查他们的手势。
rightSwipeGestureRecognizer.cancelsTouchesInView = NO;
upSwipeGestureRecognizer.cancelsTouchesInView = NO;
leftSwipeGestureRecognizer.cancelsTouchesInView = NO;
downSwipeGestureRecognizer.cancelsTouchesInView = NO;
好的,这是我的解决方案。我认为这不是一个很好的解决方案,但就我而言它是有效的,因为我需要在每个时间间隔得到指导。
所以,在我的
CCLayer
子类中:
#define SWIPE_LENGTH 60
#define SWIPE_TANGENT 2
...
@property(nonatomic, assign) CGPoint latestLocation;
...
-(id) init
{
if( (self=[super init]) )
{
self.isTouchEnabled = YES;
}
return self;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
self.latestLocation = location;
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGPoint delataLocation = CGPointMake(location.x - self.latestLocation.x, location.y - self.latestLocation.y);
if ( sqrt(pow((delataLocation.x), 2) + pow((delataLocation.y), 2) ) > SWIPE_LENGTH ) {
if (delataLocation.y > 0 && delataLocation.y > SWIPE_TANGENT * ABS(delataLocation.x))
{
[self handleSwipeWithDirestion:SDirectionTypeUp];
} else if (delataLocation.y < 0 && ABS(delataLocation.y) > SWIPE_TANGENT * ABS(delataLocation.x))
{
[self handleSwipeWithDirestion:SDirectionTypeDown];
} else if (delataLocation.x > 0 && delataLocation.x > SWIPE_TANGENT * ABS(delataLocation.y))
{
[self handleSwipeWithDirestion:SDirectionTypeRight];
} else if (delataLocation.x < 0 && ABS(delataLocation.x) > SWIPE_TANGENT * ABS(delataLocation.y))
{
[self handleSwipeWithDirestion:SDirectionTypeLeft];
}
self.latestLocation = location;
}
}
你可以像这样子类化
UIGestureRecognizer
:
class CustomSwipeGestureRecognizer: UIGestureRecognizer {
private var prevLocation = CGPoint(x: 0, y: 0)
public var dir = ""
override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
self.cancelsTouchesInView = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let location = touch?.location(in: self.view) ?? CGPoint(x: 0, y: 0)
prevLocation = location
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let location = touch?.location(in: self.view) ?? CGPoint(x: 0, y: 0)
let deltaX = location.x - prevLocation.x
let deltaY = location.y - prevLocation.y
let isVertical = abs(deltaY) > (1.2 * abs(deltaX))
let isHorizontal = abs(deltaX) > (1.2 * abs(deltaY))
let distance = sqrt(pow(deltaX, 2) + pow(deltaY, 2))
if (distance <= 60) {
return
}
if (isVertical) {
dir = deltaY > 0 ? "down" : "up"
prevLocation = location
state = .changed
} else if (isHorizontal) {
dir = deltaX > 0 ? "right" : "left"
prevLocation = location
state = .changed
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
state = .ended
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
state = .cancelled
}
}
并在视图控制器中使用它,如下所示:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swipeGesture = CustomSwipeGestureRecognizer(target: self, action: #selector(onSwipe))
self.view.addGestureRecognizer(swipeGesture)
}
@objc func onSwipe(sender: CustomSwipeGestureRecognizer) {
// this callback is called repeatedly with every movement, even when the gesture recognizer has not changed state
if (sender.dir == "") {
return
}
print(sender.dir)
sender.dir = ""
}
}