2017-02-08 6 views
2

Новый кодер здесь, я сделал код для перетаскивания/метания объекта, и я хотел знать, как сделать его так, чтобы только часть экрана могла использоваться для прикосновения, то есть только нижнюю половину экрана можно коснуться. Это мой код игры, и я использую Swift 2.0.Spritekit Отключить Touch в определенной области зрения

import SpriteKit 

var sprite = SKSpriteNode!() 
var touchPoint: CGPoint = CGPoint() 

var touching: Bool = false 
class GameScene: SKScene { 
override func didMoveToView(view: SKView) { 

    self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 
    sprite = SKSpriteNode(imageNamed: "Bottle") 
    sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size) 
    sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0) 
    self.addChild(sprite) 
    self.physicsWorld.gravity = CGVectorMake(0.0, -4.9) 

} 

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first as UITouch! 
    let location = touch.locationInNode(self) 
    let sprite = StarNode.star(touch.locationInNode(self)) 
    touchPoint = location 
    touching = true 
    } 

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first as UITouch! 
    let location = touch.locationInNode(self) 
    touchPoint = location 

} 

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    touching = false 

} 

override func update(currentTime: CFTimeInterval) { 
    if touching { 
     let dt:CGFloat = 1.0/5.0 
     let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy:  touchPoint.y-sprite.position.y) 
     let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt) 
     sprite.physicsBody!.velocity=velocity 
    } 
} 

}

ответ

1

Это звучит, как вы хотите игнорировать штрихи в верхней части экрана. Если да, то вы можете добавить проверку на touchesBegan и touchesMoved так:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first as UITouch! 
    let location = touch.locationInNode(self) 

    guard location.y < self.frame.midY else { 
     return 
    } 

    let sprite = StarNode.star(touch.locationInNode(self)) 
    touchPoint = location 
    touching = true 
} 

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first as UITouch! 
    let location = touch.locationInNode(self) 

    guard location.y < self.frame.midY else { 
     // You might want set touching to false here, depends on the rest of your code 
     return 
    } 


    touchPoint = location 
} 

Новый код я добавил проверки, что позиция Y на ощупь меньше половины высоты сцены, предполагая, что начало координат находится в внизу слева. Если проверка завершилась неудачей, функция выйдет - вы можете добавить код для отмены действий касания. Если вы хотите определенную часть экрана, чтобы быть неприкосновенным, вы могли бы сделать CGRect и проверить, что прикосновение место всегда находится вне прямоугольника, например:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first as UITouch! 
    let location = touch.locationInNode(self) 
    let untouchableArea = CGRect(x: 100, y: 100, width: 200, height: 150) 

    guard !untouchableArea.contains(location) else { 
     return 
    }  
    // Could do something similar in touchesMoved to guard against moving into the untouchable area 
} 
+0

Спасибо за это! Но у меня другая проблема. Я хочу сделать так, чтобы, когда объект перетаскивался из области с включенным касанием, чтобы отключиться, он будет выпущен сам по себе, даже если вы все еще трогаете. Как я буду заниматься этим? В настоящее время, если вы продолжаете удерживать объект, он останется на границе и упадет только при его освобождении. – shadokyr

+0

@shadokyr. Посмотрев на свой код, я думаю, вы захотите вызвать тот же код в вашей функции 'touchhesEnded', которая является' touching = false', когда объект перетаскивается в отключенную область. Поэтому в инструкции 'guard' в' touchhesMoved: ', в строке перед' return', попробуйте положить 'touching = false', что должно вызвать такое же поведение, как и удаление пальца. – nanothread59

+0

Это сработало, спасибо! – shadokyr

0

ответ Алессандро ORNANO будет работать - анализируя местоположение касания.

Другим подходом является использование «сенсорного блокатора». Поскольку SpriteKit регистрирует только самое верхнее касание, вы можете разместить SKSpriteNode, который использует цвет UIColor.clear и установить его isUserInteractionEnabled в true и его позицию z достаточно высок, чтобы он находился над другим осязаемым контентом. Это сделает прозрачный регион, который «ест» затрагивает его.

(Удобная техника отладки/визуализации для этого заключается в том, чтобы во время разработки придавать ей слабый прозрачный цвет, а не полностью прозрачный, чтобы вы могли видеть затронутую область и не попали ли какие-либо спрайты выше зоны блокировки .)

Это имеет преимущество, заключающееся в простоте и облегчении включения и выключения функции или ее изменения. Но это также имеет некоторые отличия от подхода Алессандро. Например, он не блокирует перетаскивание, которое будет подниматься в его область; после того, как сопротивление будет установлено за пределами области сенсорного блокатора, оно будет продолжать получать штрихи. Модифицированные события, даже если вы перетащите палец по области сенсорного блокатора. Любой из этих методов будет работать. Вам просто нужно выбрать тот, который лучше всего подходит для ваших конкретных потребностей.

+0

Спасибо, что процитировал меня, но ответ был @ nanothread59 –