我创造了一种类似于涂鸦跳跃的游戏,其中英雄跳起来,与物体碰撞,为分数添加值并由所述物体提升。然而,我的英雄拒绝与物体碰撞,尽管碰撞和物理设置我认为他们应该如何。
这是我的GameScene代码:
import SpriteKit
var player: Player!
var ground: Ground!
var snowflake: Snowflake!
var isFingerOnPlayer = false
var gameOver = false
var playerTouched = false
var touching: Bool = false
var lastTouch: CGPoint? = nil
let xPlayerForce: CGFloat = 15
let yPlayerForce: CGFloat = 25
var touchPoint: CGPoint = CGPoint()
struct Collision {
static let player: UInt32 = 1
static let snowflake: UInt32 = 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
player = Player()
player.position = CGPointMake(20, 150)
addChild(player)
ground = Ground()
ground.position = CGPointMake(10, -37)
addChild(ground)
player.physicsBody?.linearDamping = 6.0
player.physicsBody?.angularDamping = 6.0
player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
player.physicsBody?.allowsRotation = false
player.physicsBody?.mass = 2
player.physicsBody?.friction = 2
player.physicsBody?.dynamic = true
physicsWorld.contactDelegate = self
physicsWorld.gravity = CGVector(dx: 0.0, dy: -3.0)
self.backgroundColor = SKColor(red: 0.15, green: 0.15, blue: 0.3, alpha: 1.0)
snowflake = Snowflake()
addChild(snowflake)
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
player.animatePlayer()
for touch: AnyObject in touches {
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
}
func touchedPlayer() {
playerTouched = true
snowflake.removeFromParent()
player.bounceOff()
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
lastTouch = nil
}
func didBeginContact(contact: SKPhysicsContact) {
touchedPlayer()
println("didBegin contact")
}
override func update(currentTime: NSTimeInterval) {
if let touch = lastTouch {
var xForce: CGFloat = 0.5
var yForce: CGFloat = 0.0
let xTouchOffset = (touch.x - player.position.x)
let yTouchOffset = (touch.y - player.position.y)
if xTouchOffset > 0.0 {
xForce = xPlayerForce
} else if xTouchOffset < 0.0 {
xForce = -xPlayerForce
} // else we do nothing
if yTouchOffset > 0.0 {
yForce = yPlayerForce
} else if xTouchOffset > 0.0 {
yForce = -yPlayerForce
}
// here you can choose whether you want it to push
// the player node down, using similar code from the
// above if statement
let impulseVector = CGVector(dx: xForce, dy: yForce)
player.physicsBody?.applyImpulse(impulseVector)
}
}
}
and here is my code for my Hero's class
import Foundation
import SpriteKit
class Player: SKSpriteNode {
let player = SKSpriteNode(imageNamed: "penguin_walk01")
init() {
let size = CGSizeMake(32, 44)
super.init(texture: nil, color: UIColor.clearColor(), size: size)
setUpPlayer()
playerPhysics(size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func animatePlayer() {
let frames = [
SKTexture(imageNamed: "penguin_walk01"),
SKTexture(imageNamed: "penguin_walk02"),
SKTexture(imageNamed: "penguin_walk03"),
]
let duration = 1.5 + drand48() * 1.0
let move = SKAction.animateWithTextures(frames, timePerFrame:0.10)
let wait = SKAction.waitForDuration(duration)
let rest = SKAction.setTexture(frames[0])
let sequence = SKAction.sequence([move, rest])
player.runAction(SKAction.repeatActionForever(sequence))
}
func setUpPlayer() {
player.position = CGPointMake(20, 60)
player.name = "penguin"
addChild(player)
}
func jumpPlayer() {
let jumpUp = SKAction.moveByX(0, y: 200, duration: 0.6)
let jumpDown = SKAction.moveByX(0, y: -200, duration: 0.6)
let jumpSequence = SKAction.sequence([jumpUp, jumpDown])
player.runAction(jumpSequence)
}
func playerPhysics(size: CGSize) {
player.physicsBody?.categoryBitMask = playerCategory
player.physicsBody?.contactTestBitMask = snowCategory
player.physicsBody?.affectedByGravity = false
player.physicsBody?.allowsRotation = false
player.physicsBody?.collisionBitMask = 5
player.physicsBody?.usesPreciseCollisionDetection = true
}
func bounceOff() {
player.physicsBody?.affectedByGravity = true
player.physicsBody?.applyImpulse(CGVectorMake(0, 22))
let advance = SKAction.moveByX(0, y: 20, duration: 1)
runAction(advance)
}
}
Code for Object's class:
import Foundation
import SpriteKit
class Snowflake: SKSpriteNode {
init() {
let size = CGSizeMake(32, 44)
super.init(texture: nil, color: UIColor.clearColor(), size: size)
loadBodyWithSize(size)
self.removeFromParent()
createSnowAtPosition()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func loadBodyWithSize(size: CGSize) {
physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.affectedByGravity = false
physicsBody?.categoryBitMask = snowCategory
}
func createSnowAtPosition() {
let snow = SKSpriteNode(imageNamed: "icons_winter_09")
snow.name = "snow"
snow.position = CGPointMake(50, 300)
snow.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width / 4)
snow.physicsBody?.dynamic = false
snow.physicsBody?.usesPreciseCollisionDetection = true
addChild(snow)
}
}