我一直试图让这个工作用于简单的平台游戏,但是联系人检测一直给我带来问题。当两个节点接触时,didBeginContact函数似乎没有被调用,这里是代码:
import SpriteKit
var idleFrames = [SKTexture]()
var walkFrames = [SKTexture]()
var player: SKSpriteNode!
var touchingGround = 0
var idling = 0
class GameScene: SKScene, SKPhysicsContactDelegate {
var sp33d: CGVector = CGVectorMake(0.0,0.0)
var jsp33d: CGFloat = 30
var gameStick: Joystick?
var ground: SKSpriteNode?
let playerskin = character(charnumber: 1)
func didBeginContact(contact: SKPhysicsContact) {
print("hit")
let firstNode = contact.bodyA.node as! SKSpriteNode
let secondNode = contact.bodyB.node as! SKSpriteNode
if (contact.bodyA.categoryBitMask == category.player) && (contact.bodyB.categoryBitMask == category.ground) {
touchingGround = 1
}else{
touchingGround = 0
}
}
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.physicsWorld.gravity = CGVectorMake(0, -10.0)
gameStick = Joystick()
gameStick?.createJoystick(self.scene!.frame.width/4, nameBack: "joystick", nameMoving: "joystick1")
gameStick!.backPart!.zPosition = 4
gameStick!.movingPart!.zPosition = 5
self.addChild(gameStick!.backPart!)
self.addChild(gameStick!.movingPart!)
player = self.childNodeWithName("player") as? SKSpriteNode
ground = self.childNodeWithName("testGround") as? SKSpriteNode
player?.physicsBody?.categoryBitMask = category.player
ground?.physicsBody?.categoryBitMask = category.ground
let idleAtlas = SKTextureAtlas(named: "idle.atlas")
var idleframes = [SKTexture]()
let numImages = idleAtlas.textureNames.count
for var i=1; i<=4; i++ {
let idleframe = "JohnIdle\(i)"
idleframes.append(idleAtlas.textureNamed(idleframe))
}
idleFrames = idleframes
let firstFrame = idleframes[0]
}
func idleflag() {
idling = 0
}
func idlejohn() {
if sp33d.dx < 1 || sp33d.dx > -1{
print("boop")
idling = 1
player?.runAction(SKAction.repeatAction(SKAction.animateWithTextures(idleFrames, timePerFrame: 0.4, resize: false, restore: true), count: 1))
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
gameStick?.movingPart?.position = location
if location.x > gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2, gameStick!.movingPart!.position.y)
}
if location.y > gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.movingPart!.position.x, gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2)
}
}
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
gameStick?.movingPart?.position = location
if location.x > gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2, gameStick!.movingPart!.position.y)
}
if location.y > gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.movingPart!.position.x, gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2)
}
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
let act = SKAction.moveTo(gameStick!.backPart!.position, duration: 0.2)
gameStick?.movingPart?.runAction(act)
}
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
let vX = gameStick!.movingPart!.position.x - gameStick!.backPart!.position.x
var vY: CGFloat = gameStick!.movingPart!.position.y
if vY > gameStick!.backPart!.position.y + 20 && touchingGround == 1{
sp33d = CGVectorMake(vX/13, jsp33d)
}else{
sp33d = CGVectorMake(vX/13, 0)
}
player?.physicsBody?.applyImpulse(sp33d)
idlejohn()
}
}
这是位掩码:
import Foundation
import SpriteKit
var charnumber = 0
var charsize = [0: CGSizeMake(80,80)]
struct category {
static let player: UInt32 = 0x1 << 0
static let ground: UInt32 = 0x1 << 1
}
非常感谢任何帮助,谢谢!
答案 0 :(得分:0)
似乎你还没有初始化玩家和地面物理主体
player = self.childNodeWithName("player") as? SKSpriteNode
ground = self.childNodeWithName("testGround") as? SKSpriteNode
player?.physicsBody?.categoryBitMask = category.player
ground?.physicsBody?.categoryBitMask = category.ground
播放器?.physicsBody = SKPhysicsBody()//括号内选择body的类型(rect,circle等..) 同样适用于地面,如果你想要对象是联系人,首先你需要分配主体。