我有一个游戏,我的角色从一片土地跳到陆地,问题是只要用户点击屏幕他就会继续跳起来。
Knight.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
Knight.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 275))
这就是我在touchesBegan下可以让他跳到第一位的地方,我怎么做到这一点,一旦他接触到SKSprite节点,它只允许他跳一次? 每当屏幕被点击时,角色都可以跳跃,但是我希望他只有在他在地面上时能够跳跃然后用户点击屏幕
答案 0 :(得分:3)
我们将使用计数器。因此,每当您进入平台时,每次离开时添加,减去。当你的柜台为0时,你不在陆地上。
在某处为BodyTypes创建一个枚举...我把它放在我的GameScene类之上。
enum BodyType:UInt32 {
case player = 1
case platform = 2
}
设置你的骑士班......
class Knight: SKSpriteNode {
// this variable will be toggled by didBegin Contact ... when 0 you are not land. Assumes that player starts on land. //
var onLandCounter = 1
func setUpKnight() {
/// call this in didMoveToView when setting up your nodes
/// Should have other stuff in here too .. but this is the important bit //
self.physicsBody?.categoryBitMask = BodyType.player.rawValue
self.physicsBody?.collisionBitMask = BodyType.platform.rawValue
self.physicsBody?.contactTestBitMask = BodyType.platform.rawValue
}
func jump() {
if (onLandCounter >= 1) {
self.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
self.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 275))
}
}
}
在touchesBegan中你会改为
theKnight.jump()
请注意,假设您创建了一个Knight类的实例并将其命名为theKnight
然后诀窍是你需要一个平台类,你可以自定义地面体类,例如。 class Platform: SKSpriteNode {
func setUpPlatform() {
self.physicsBody?.categoryBitMask = BodyType.platform.rawValue
self.physicsBody?.collisionBitMask = BodyType.player.rawValue | BodyType.platform.rawValue
self.physicsBody?.contactTestBitMask = BodyType.player.rawValue
}
}
然后使用didBeginContact使计数器在你的theKnight实例上发生变化,并允许跳跃再次发生,因为骑士已经触地。我们添加,计数器现在至少为1,所以我们可以跳。
e.g。
@objc(didBeginContact:) func didBegin(_ contact: SKPhysicsContact) {
let firstBody: SKPhysicsBody
let secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
//MARK: KNIGHT with PLATFORM
if ( firstBody.categoryBitMask == BodyType.player.rawValue && secondBody.categoryBitMask == BodyType.platformSurface.rawValue) {
if let theKnight:Knight = firstBody.node as? Knight,
let thePlatform:Platform = secondBody.node as? Platform
{
theKnight.onLandCounter += 1
}
}
}
请记住在GameScene中正确设置
class GameScene: SKScene, SKPhysicsContactDelegate {
var theKnight: Knight = Knight()
override func didMove(to view: SKView) {
self.enumerateChildNodes(withName: "//*") {
node, stop in
if let thePlatform:Platform = node as? Platform {
thePlatform.setUpPlatform()
}
}
// MARK: SET UP PLAYER
// Assumes you call your player in the Scene "Player1"
//AND! you set it's custom class to Knight
if (self.childNode(withName: "Player1") != nil) {
theKnight = self.childNode(withName: "Player1") as! Knight
theKnight.setUpKnight()
}
}
}
最后!!!在didEndContact
中@objc(didEndContact:) func didEnd(_ contact: SKPhysicsContact) {
let firstBody: SKPhysicsBody
let secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
//MARK: KNIGHT with PLATFORM
if ( firstBody.categoryBitMask == BodyType.player.rawValue && secondBody.categoryBitMask == BodyType.platformSurface.rawValue) {
if let theKnight:Knight = firstBody.node as? Knight,
let thePlatform:Platform = secondBody.node as? Platform
{
theKnight.onLand -= 1
}
}
}
不要忘记为你的骑士定制课程!
现在你有一个设置......只有当你的玩家接触到地面时才会打开跳跃功能。节点。
调整此解决方案,但它适合您自己的代码。如果我忘了支架或其他东西,请告诉我。
关键是......你只是使用计数器来防止使用跳转功能。
答案 1 :(得分:0)
您是否尝试过检查触摸位置和节点位置? 从toughBegan获取触摸位置:
let point = touch.location(in: self)
如果该点上的节点等于您的对象,请执行跳转
let nodes = self.nodes(at: point)