我正在尝试在角色接触时删除一个对象(一个orb节点),但它只是像一个圆圈一样,当它到达顶部时角色会掉落。我删除了碰撞检测的代码,因为我不知道它是否正确。
这是我的GameScene.swift代码:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
override init(size:CGSize){
super.init(size:size)
let CollisionCategoryPlayer
: UInt32 = 0x1 << 1
let CollisionCategoryPowerUpOrbs
: UInt32 = 0x1 << 2
character.physicsBody?.categoryBitMask = CollisionCategoryPlayer
character.physicsBody?.contactTestBitMask = CollisionCategoryPowerUpOrbs
character.physicsBody?.collisionBitMask = 0
orbNode.physicsBody?.categoryBitMask = CollisionCategoryPowerUpOrbs
orbNode.physicsBody?.collisionBitMask = 0
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
//variables
let character = SKSpriteNode(imageNamed:"square_red.png")
let floor = SKSpriteNode(imageNamed: "platform.jpg")
let platform1 = SKSpriteNode(imageNamed: "platform2.png")
let platform2 = SKSpriteNode(imageNamed: "platform2.png")
let orbNode = SKSpriteNode(imageNamed: "PowerUp.png")
var characterSize:CGFloat = 0.2
var foodCount = 0
override func didMoveToView(view: SKView) {
//World Physics
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0)
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//Character
character.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
character.setScale(characterSize)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.allowsRotation = false
self.addChild(character)
//floor
floor.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*0.2)
floor.setScale(2.0)
floor.physicsBody = SKPhysicsBody(rectangleOfSize: floor.size)
floor.physicsBody?.dynamic = false
self.addChild(floor)
//platform one
platform1.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*0.7)
platform1.setScale(0.4)
platform1.physicsBody = SKPhysicsBody(rectangleOfSize: platform1.size)
platform1.physicsBody?.dynamic = false
self.addChild(platform1)
//platform two
platform2.position = CGPoint(x: CGRectGetMidX(self.frame)*1.4, y: CGRectGetMidY(self.frame)*1)
platform2.setScale(0.4)
platform2.physicsBody = SKPhysicsBody(rectangleOfSize: platform2.size)
platform2.physicsBody?.dynamic = false
self.addChild(platform2)
//orbNode
orbNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
orbNode.setScale(0.2)
self.addChild(orbNode)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
character.removeActionForKey("moveAction")
character.removeActionForKey("shrink")
character.removeActionForKey("rotate")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch:AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
//shrinks with each movement
characterSize-=0.005
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(-30, y: 0, duration: 0.1))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(moveAction, withKey: "moveAction")
character.runAction(shrink, withKey: "shrink")
} else if location.x > CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
//shrinks with each movement
characterSize-=0.005
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(30, y: 0, duration: 0.1))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(moveAction, withKey: "moveAction")
character.runAction(shrink, withKey: "shrink")
} else if location.y > character.position.y + 15 {
//shrinks with each movement
characterSize-=0.005
character.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(shrink, withKey: "shrink")
}
}
func didBeginContact(contact: SKPhysicsContact){
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
}
答案 0 :(得分:0)
你应该对你的物理团体进行分组,你的代码似乎到处都是。你得到错误的原因也是因为你在设置玩家之前设置了物理体,并且错过了一些Orbs。
这是相同的代码重写,我认为更具可读性和可理解性。
import SpriteKit
/// Physics category
struct PhysicsCategory {
static let player: UInt32 = 0x1 << 0
static let orb: UInt32 = 0x1 << 1
static let floor: UInt32 = 0x1 << 2
static let platform: UInt32 = 0x1 << 3
}
/// Image names
struct ImageName {
static let platform1 = "platform2.png"
static let platform2 = "platform2.png"
// can do this for other images as well, but because you create loads of platforms its nice to have a refernce like this
}
/// Always put your keys for removing actions etc into structs to avoid typos
struct Key {
static let moveAction = "moveAction"
static let shrink = "shrink"
static let rotate = "rotate"
}
/// GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
//variables
let character = SKSpriteNode(imageNamed:"square_red.png")
let floor = SKSpriteNode(imageNamed: "platform.jpg")
var platform1 = SKSpriteNode()
var platform2 = SKSpriteNode()
let orbNode = SKSpriteNode(imageNamed: "PowerUp.png")
var characterSize:CGFloat = 0.2
var foodCount = 0
//didMoveToView
override func didMoveToView(view: SKView) {
//World Physics
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0)
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//Character
character.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
character.setScale(characterSize)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.allowsRotation = false
character.physicsBody?.dynamic = true // must be true for collision to fire
character.physicsBody?.affectedByGravity = false
character.physicsBody?.categoryBitMask = PhysicsCategory.player
character.physicsBody?.contactTestBitMask = PhysicsCategory.orb
character.physicsBody?.collisionBitMask = PhysicsCategory.floor | PhysicsCategory.platform
self.addChild(character)
//floor
floor.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*0.2)
floor.setScale(2.0)
floor.physicsBody = SKPhysicsBody(rectangleOfSize: floor.size)
floor.physicsBody?.dynamic = false
floor.physicsBody?.affectedByGravity = false
floor.physicsBody?.categoryBitMask = PhysicsCategory.floor
///floor.physicsBody?.contactTestBitMask = not needed for now as character is set
///floor.physicsBody?.collisionBitMask = not needed for now as character is set
self.addChild(floor)
//platform one
platform1 = createPlatform(ImageName.platform1)
platform1.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*0.7)
platform1.setScale(0.4)
self.addChild(platform1)
//platform two
platform2 = createPlatform(ImageName.platform2)
platform2.position = CGPoint(x: CGRectGetMidX(self.frame)*1.4, y: CGRectGetMidY(self.frame)*1)
platform2.setScale(0.4)
self.addChild(platform2)
//orbNode
orbNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
orbNode.setScale(0.2)
orbNode.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
orbNode.physicsBody?.allowsRotation = false
orbNode.physicsBody?.dynamic = false
orbNode.physicsBody?.affectedByGravity = false
orbNode.physicsBody?.categoryBitMask = PhysicsCategory.orb
//orbNode.physicsBody?.contactTestBitMask = // not needed for now because pla
orbNode.physicsBody?.collisionBitMask = PhysicsCategory.platform //
self.addChild(orbNode)
}
/// Create platform (this way you can crate multiple platforms and save yourself tones of code)
func createPlatform(imageNamed: String) -> SKSpriteNode {
let platform = SKSpriteNode(imageNamed: imageNamed)
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.dynamic = false
platform.physicsBody?.affectedByGravity = false
platform.physicsBody?.categoryBitMask = PhysicsCategory.platform
//platform.physicsBody?.contactTestBitMask = /// not needed unless you want didBeginContact
platform.physicsBody?.collisionBitMask = 0 /// Not needed if you tell character to collide with it
return platform
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
character.removeActionForKey(Key.moveAction)
character.removeActionForKey(Key.shrink)
character.removeActionForKey(Key.rotate)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
//shrinks with each movement
characterSize-=0.005
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(-30, y: 0, duration: 0.1))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(moveAction, withKey: Key.moveAction)
character.runAction(shrink, withKey: Key.shrink)
} else if location.x > CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
//shrinks with each movement
characterSize-=0.005
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(30, y: 0, duration: 0.1))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(moveAction, withKey: Key.moveAction)
character.runAction(shrink, withKey: Key.shrink)
} else if location.y > character.position.y + 15 {
//shrinks with each movement
characterSize-=0.005
character.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
let shrink = SKAction.repeatActionForever(SKAction.scaleTo(characterSize, duration: 0.1))
character.runAction(shrink, withKey: Key.shrink)
}
}
}
func didBeginContact(contact: SKPhysicsContact){
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
/// Player with Orb
if (firstBody.categoryBitMask == PhysicsCategory.player) && (secondBody.categoryBitMask == PhysicsCategory.orb) {
///Player hit orb, remove Orb
secondBody.node?.removeFromParent()
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}