skphysicsbody to skspritenode error - swift

Here is the code:
import SpriteKit
import CoreMotion
struct PhysicsCatagory {
static let Player :UInt32 = 0x1 << 0
static let shark :UInt32 = 0x1 << 1
static let jellyfish :UInt32 = 0x1 << 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var Player = SKSpriteNode()
var game = true
var playerPos = false
var ScoreCount = 0
let myLabel = SKLabelNode(fontNamed: "3D-Thirteen-Pixel-Fonts")
var HighScore = 0
let DisplayScore = SKLabelNode(fontNamed: "3D-Thirteen-Pixel-Fonts")
let LeaderBoardScore = SKLabelNode(fontNamed: "3D-Thirteen-Pixel-Fonts")
let LeaderBoardHighscore = SKLabelNode(fontNamed: "3D-Thirteen-Pixel-Fonts")
var CheckGameState = false
let playButton = SKSpriteNode(imageNamed: "Play")
let Scores = SKSpriteNode(imageNamed: "LeaderBoard")
var PlayerUpState = false
var PlayerDownState = false
var ifPlayerDrawJustCalled = false
var TextureAtlas = SKTextureAtlas()
var TextureArray = [SKTexture]()
var TextureAtlas2 = SKTextureAtlas()
var TextureArray2 = [SKTexture]()
var TextureAtlas3 = SKTextureAtlas()
var TextureArray3 = [SKTexture]()
var motionManager: CMMotionManager!
var fishYpos = 115.0
let shark = SKSpriteNode(imageNamed: "shark")
let jellyfish = SKSpriteNode(imageNamed: "jellyfish")
override func didMoveToView(view: SKView) {
print("called")
motionManager = CMMotionManager()
motionManager.startGyroUpdates()
motionManager.gyroUpdateInterval = 0.02
backgroundColor = UIColor(red: 0.0, green: 7.0, blue: 1.0, alpha: 1.0)
let HighscoreDefault = NSUserDefaults.standardUserDefaults()
if(HighscoreDefault.valueForKey("Highscore") != nil){
HighScore = HighscoreDefault.valueForKey("Highscore") as! Int
}
TextureAtlas = SKTextureAtlas(named: "Images")
TextureArray.append(SKTexture(imageNamed: "win_1.png"))
TextureArray.append(SKTexture(imageNamed: "win_2.png"))
TextureArray.append(SKTexture(imageNamed: "win_3.png"))
TextureArray.append(SKTexture(imageNamed: "win_4.png"))
TextureAtlas3 = SKTextureAtlas(named: "Images")
TextureArray3.append(SKTexture(imageNamed: "jellyfish_1.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_2.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_3.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_4.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_5.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_6.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_7.png"))
TextureArray3.append(SKTexture(imageNamed: "jellyfish_8.png"))
TextureAtlas2 = SKTextureAtlas(named: "Images")
TextureArray2.append(SKTexture(imageNamed: "shark_1.png"))
TextureArray2.append(SKTexture(imageNamed: "shark_2.png"))
TextureArray2.append(SKTexture(imageNamed: "shark_3.png"))
TextureArray2.append(SKTexture(imageNamed: "shark_4.png"))
TextureArray2.append(SKTexture(imageNamed: "shark_5.png"))
TextureArray2.append(SKTexture(imageNamed: "shark_6.png"))
Player = SKSpriteNode(imageNamed: TextureAtlas.textureNames[0])
self.physicsWorld.contactDelegate = self
Player.zPosition = 10.0
Player.position = CGPoint(x: 80, y: fishYpos)
Player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 30, height: 30))
Player.physicsBody?.dynamic = false
Player.physicsBody?.affectedByGravity = false
myLabel.text = "\(ScoreCount)"
myLabel.fontSize = 70
myLabel.position = CGPointMake(CGRectGetMidX(self.frame), frame.size.height-150)
myLabel.zPosition = 18.0
addChild(myLabel)
addChild(Player)
Player.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(TextureArray, timePerFrame: 0.20)))
var BubbleTimer = NSTimer.scheduledTimerWithTimeInterval(1, target:self,selector: "addBubble", userInfo: nil, repeats: true)
var Gyro = NSTimer.scheduledTimerWithTimeInterval(0.02, target:self,selector: "gyroFunction", userInfo: nil, repeats: true)
var MainTimer1 = NSTimer.scheduledTimerWithTimeInterval(1, target:self,selector: "RunTimeTimer", userInfo: nil, repeats: true)
var sharkTimer = NSTimer.scheduledTimerWithTimeInterval(0.70, target: self, selector: "RunSharkTimer", userInfo: nil, repeats: true)
var jellyfishTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "RunJellyfishTimer", userInfo: nil, repeats: true)
}
func addBubble(){
let randomNum1 = Int(arc4random_uniform(3))
if(randomNum1 == 2){
let randomNum2 = Int(arc4random_uniform(2))
if(randomNum2 == 1){
let Bubble1 = SKSpriteNode(imageNamed: "Bubble1")
Bubble1.position.x = Player.position.x+9
Bubble1.position.y = Player.position.y
Bubble1.zPosition = 2.0
addChild(Bubble1)
Bubble1.runAction(SKAction.moveToY( frame.size.height+20, duration: 3.0))
}
if(randomNum2 == 0){
let Bubble2 = SKSpriteNode(imageNamed: "Bubble2")
Bubble2.position.x = Player.position.x+9
Bubble2.position.y = Player.position.y
Bubble2.zPosition = 3.0
addChild(Bubble2)
Bubble2.runAction(SKAction.moveToY( frame.size.height+20, duration: 3.0))
}
}
}
func RunTimeTimer(){
if(game == true){
timer()
}
}
func RunSharkTimer(){
if(game == true){
addShark()
}
}
func RunJellyfishTimer(){
if(game == true){
addJellyfish()
}
}
func gyroFunction(){
if let gyro_y = motionManager.gyroData?.rotationRate.y {
if(fishYpos+gyro_y*(-10) > 115){
if(CGFloat(fishYpos+gyro_y*(-10)) < frame.size.height-115){
fishYpos = fishYpos+gyro_y*(-10)
let fishAction = SKAction.moveToY(CGFloat(fishYpos), duration: 0.05)
Player.runAction(fishAction)
}
}
}
}
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA as! SKSpriteNode
let secondBody = contact.bodyB as! SKSpriteNode
if(((firstBody.name == "Player") && (secondBody.name == "shark")) || (firstBody.name == "shark") && (secondBody.name == "Player") || ((firstBody.name == "Player") && (secondBody.name == "jellyfish")) || (firstBody.name == "jellyfish") && (secondBody.name == "Player")){
game = false
if(CheckGameState == false){
playButton.xScale = 1.9
playButton.yScale = 1.9
playButton.zPosition = 12.0
playButton.position = CGPoint(x: frame.midX-50, y: frame.midY-140)
playButton.name = "playButton"
playButton.userInteractionEnabled = false
addChild(playButton)
if(ScoreCount>HighScore){
HighScore = ScoreCount
let HighscoreDefault = NSUserDefaults.standardUserDefaults()
HighscoreDefault.setInteger(HighScore, forKey: "Highscore")
}
LeaderBoardScore.text = "\(ScoreCount)"
LeaderBoardHighscore.text = "\(HighScore)"
LeaderBoardHighscore.position = CGPoint(x: frame.midX+30 , y: frame.midY+5)
LeaderBoardHighscore.xScale = 2.0
LeaderBoardHighscore.yScale = 2.0
LeaderBoardHighscore.zPosition = 15.0
LeaderBoardHighscore.fontColor = UIColor.purpleColor()
LeaderBoardScore.position = CGPoint(x: frame.midX+60 , y: frame.midY+72)
LeaderBoardScore.fontColor = UIColor.purpleColor()
LeaderBoardScore.xScale = 2.0
LeaderBoardScore.zPosition = 15.0
LeaderBoardScore.yScale = 2.0
addChild(LeaderBoardHighscore)
addChild(LeaderBoardScore)
Scores.xScale = 2
Scores.yScale = 2
Scores.zPosition = 11.0
Scores.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(Scores)
CheckGameState = true
}
}
}
func addShark(){
Player.physicsBody?.collisionBitMask = PhysicsCatagory.shark
Player.physicsBody?.contactTestBitMask = PhysicsCatagory.shark
Player.name = "Player"
Player.physicsBody?.dynamic = true
Player.physicsBody?.affectedByGravity = false
let randomNumShark = arc4random_uniform(2)
if(randomNumShark == 1){
let shark = SKSpriteNode(imageNamed: "shark_1.png")
shark.position.x = frame.size.width
let PositionY = arc4random_uniform(UInt32(frame.size.height))
shark.position.y = CGFloat(PositionY)
addChild(shark)
let sharkGoForward = SKAction.moveToX(CGFloat(-1100), duration: 1.5)
shark.runAction(sharkGoForward)
shark.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: shark.size.width, height:shark.size.height))
shark.physicsBody?.categoryBitMask = PhysicsCatagory.Player
shark.physicsBody?.contactTestBitMask = PhysicsCatagory.Player
shark.physicsBody?.collisionBitMask = PhysicsCatagory.Player
shark.physicsBody?.dynamic = true
shark.physicsBody?.affectedByGravity = false
shark.name = "shark"
shark.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(TextureArray2, timePerFrame: 0.05)))
}
}
func addJellyfish(){
Player.physicsBody?.collisionBitMask = PhysicsCatagory.jellyfish
Player.physicsBody?.contactTestBitMask = PhysicsCatagory.jellyfish
Player.name = "Player"
Player.physicsBody?.dynamic = true
Player.physicsBody?.affectedByGravity = false
let randomNumJelly = arc4random_uniform(2)
if(randomNumJelly == 1){
let jellyfish = SKSpriteNode(imageNamed: "jellyfish")
jellyfish.position.y = 0
let PositionX = arc4random_uniform(UInt32(frame.size.width))
jellyfish.position.x = CGFloat(PositionX)
addChild(jellyfish)
let jellyfishGoUp = SKAction.moveToY(CGFloat(frame.size.height+100), duration: 2.0)
jellyfish.runAction(jellyfishGoUp)
jellyfish.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: jellyfish.size.width, height:jellyfish.size.height))
jellyfish.physicsBody?.categoryBitMask = PhysicsCatagory.Player
jellyfish.physicsBody?.contactTestBitMask = PhysicsCatagory.Player
jellyfish.physicsBody?.collisionBitMask = PhysicsCatagory.Player
jellyfish.physicsBody?.dynamic = true
jellyfish.physicsBody?.affectedByGravity = false
jellyfish.name = "jellyfish"
jellyfish.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(TextureArray3, timePerFrame: 0.05)))
}
}
func timer(){
if(game == true){
ScoreCount++
myLabel.text = "\(ScoreCount)"
}
}
func rePositionPlayer(){
Player.removeFromParent()
Player.position = CGPoint(x: 80, y: 220)
addChild(Player)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in (touches ) {
let location = touch.locationInNode(self)
if(game == false){
if playButton.containsPoint(location){
game = true
LeaderBoardHighscore.removeFromParent()
LeaderBoardScore.removeFromParent()
playButton.removeFromParent()
Scores.removeFromParent()
CheckGameState = false
rePositionPlayer()
ScoreCount = 0
fishYpos = 220
}
}
if(game == true){
}
}
}
override func update(currentTime: CFTimeInterval) {
}
}
My error is at the line
let secondbody = contact.bodyB as! SKSpriteNode
It says
can cast SKPhysicsBody to unrealted SKSpriteNode
How to fix this issue?

Try saying let secondbody.node = contact.bodyB as! SKSpriteNode

Related

SpriteKit - Collision Off after HIT

I am writing a spritekit game and I have a problem, I would like the framework not to detect collisions after it is detected. For example, the player is dealt damage and becomes insensitive to attacks, e.g. for 20 seconds. Now when a collision is detected, it is detected all the time (e.g. 50 times)
Is there a way to temporarily disable collisions ??
Player code :
func createPlayer() {
var walkFrames: [SKTexture] = []
var walkFrames2: [SKTexture] = []
var walkFrames3: [SKTexture] = []
var walkFrames4: [SKTexture] = []
// let spaceShipTexture = SKTexture(imageNamed: "p2.png")
let playerAnimatedAtlas = SKTextureAtlas(named: "walk")
let playerAnimatedAtlas_idle = SKTextureAtlas(named: "idle")
let playerAnimatedAtlas_jump = SKTextureAtlas(named: "jump")
let playerAnimatedAtlas_attack = SKTextureAtlas(named: "attack")
var _: [SKTexture] = []
for i in 0...6 {
let playerTextureName = "1_entity_000_WALK_00\(i).png"
walkFrames.append(playerAnimatedAtlas.textureNamed(playerTextureName))
}
for z in 0...6 {
let playerTextureName_idle = "1_entity_000_IDLE_00\(z).png"
walkFrames2.append(playerAnimatedAtlas_idle.textureNamed(playerTextureName_idle))
}
for p in 0...6 {
let playerTextureName_jump = "1_entity_000_JUMP_00\(p).png"
walkFrames3.append(playerAnimatedAtlas_jump.textureNamed(playerTextureName_jump))
}
for k in 0...6 {
let playerTextureName_attack = "1_entity_000_ATTACK_00\(k).png"
walkFrames4.append(playerAnimatedAtlas_attack.textureNamed(playerTextureName_attack))
}
playerWalkingFrames = walkFrames
let firstFrameTexture = playerWalkingFrames[0]
player.position = CGPoint(x: -1050, y: -90 )
//player.setScale(0.090)
player.size = CGSize(width: 170, height: 120)
// player.physicsBody = SKPhysicsBody(rectangleOf:CGSize(width: 35, height: 100))
let spaceShipTexture = SKTexture(imageNamed: "p2.png")
let texturedSpaceShip = SKSpriteNode(texture: spaceShipTexture)
player.physicsBody = SKPhysicsBody(texture: spaceShipTexture , size: CGSize(width: player.size.width,
height: player.size.height));
player.physicsBody?.usesPreciseCollisionDetection = true
//player.physicsBody = SKPhysicsBody(texture: play, size: player.size)
player.physicsBody?.allowsRotation = false
player.physicsBody?.categoryBitMask = playerCategory
player.physicsBody?.collisionBitMask = enemy1Category
//player.physicsBody?.contactTestBitMask = enemy1Category
playerWalkingFrames_idle = walkFrames2
playerWalkingFrames_jump = walkFrames3
playerWalkingFrames_attack = walkFrames4
self.addChild(player)
}
collision code :
func didBegin(_ contact: SKPhysicsContact) {
let collison: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collison == playerCategory | enemy1Category{
print("COLLISION") }
else {
//print("Brak Kolizji" )
}
if collison == playermieczCategory | enemy1Category {
print("miecz")
}
if collison == playermieczCategory | piratkaCategory {
print("miecz_Piratka")
// health -= 0.2
// piratka.isHidden = true
}
if collison == playerCategory | piratkaCategory{
// if collison == nil {return}
player.physicsBody?.contactTestBitMask = 0
// czarny.physicsBody?.applyImpulse(CGVector(dx: 10, dy: 0))
// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(5)) {
// self.playerhealth -= 0.01
// print("nico")
print("HIT3")
// }
}

Integer is not being updated

I am making a game that includes a high score label that comes up once the player dies, along with a restart button. Overall the high score, which is an integer, works fine but there is one problem. If you reach a new high score in that round you just finished you have to die again for it to show the new high score. Lets say I play the game while the high score is already 15 and I score 17 when the high score label comes up it still shows 15. After I restart the game and the high score comes up again it will now show 17. The high score is not updating when I want it to.
import SpriteKit
struct physicsCatagory {
static let person : UInt32 = 0x1 << 1
static let Ice : UInt32 = 0x1 << 2
static let IceTwo : UInt32 = 0x1 << 3
static let IceThree : UInt32 = 0x1 << 4
static let Score : UInt32 = 0x1 << 5
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var Highscore = Int()
var timeOfLastSpawn: CFTimeInterval = 0.0
var timePerSpawn: CFTimeInterval = 1.2
var scorenumber = Int()
var lifenumber = Int()
var SpeedNumber : Double = 0.5
var person = SKSpriteNode(imageNamed: "Person1")
let Score = SKSpriteNode()
var ScoreLable = SKLabelNode()
var Highscorelabel = SKLabelNode()
let BackGround = SKSpriteNode (imageNamed: "BackGround")
var restartButton = SKSpriteNode()
var Died = Bool()
func restartScene(){
self.removeAllChildren()
self.removeAllActions()
scorenumber = 0
lifenumber = 0
createScene()
random()
//spawnThirdIce()
Died = false
timeOfLastSpawn = 0.0
timePerSpawn = 1.2
}
func createScene(){
physicsWorld.contactDelegate = self
if (scorenumber > Highscore){
var Highscoredefault = NSUserDefaults.standardUserDefaults()
Highscoredefault.setValue(scorenumber, forKey: "HighScore")
}
var Highscoredefault = NSUserDefaults.standardUserDefaults()
if (Highscoredefault.valueForKey("HighScore") != nil){
Highscore = Highscoredefault.valueForKey("HighScore") as! NSInteger
}
else{
Highscore = 0
}
lifenumber = 0
SpeedNumber = 1
BackGround.size = CGSize(width: self.frame.width, height: self.frame.height)
BackGround.position = CGPointMake(self.size.width / 2, self.size.height / 2)
BackGround.zPosition = -5
self.addChild(BackGround)
Score.size = CGSize(width: 2563, height: 1)
Score.position = CGPoint(x: 320, y: -20)
Score.physicsBody = SKPhysicsBody(rectangleOfSize: Score.size)
Score.physicsBody?.affectedByGravity = false
Score.physicsBody?.dynamic = false
Score.physicsBody?.categoryBitMask = physicsCatagory.Score
Score.physicsBody?.collisionBitMask = 0
Score.physicsBody?.contactTestBitMask = physicsCatagory.IceThree
Score.color = SKColor.blueColor()
Score.zPosition = -5
self.addChild(Score)
person.zPosition = 1
person.position = CGPointMake(self.size.width/2, self.size.height/9.5)
person.setScale(0.6)
person.physicsBody = SKPhysicsBody (rectangleOfSize: CGSize(width: 1000, height: 50))
person.physicsBody?.affectedByGravity = false
person.physicsBody?.categoryBitMask = physicsCatagory.person
person.physicsBody?.contactTestBitMask = physicsCatagory.Ice
person.physicsBody?.collisionBitMask = physicsCatagory.Ice
person.physicsBody?.dynamic = false
person.physicsBody?.affectedByGravity = false
self.addChild(person)
ScoreLable = SKLabelNode()
ScoreLable.fontName = "Arial"
ScoreLable.position = CGPoint(x: self.frame.width / 2, y: 1700)
ScoreLable.text = "\(scorenumber)"
ScoreLable.fontColor = UIColor.yellowColor()
ScoreLable.fontSize = 150
self.addChild(ScoreLable)
Highscorelabel.fontName = "Arial"
Highscorelabel.position = CGPoint(x: self.frame.width / 2, y: 1400)
Highscorelabel.text = "HighScore: \(Highscore)"
Highscorelabel.fontSize = 150
Highscorelabel.fontColor = UIColor.yellowColor()
Highscorelabel.zPosition = -7
self.addChild(Highscorelabel)
}
func random() -> CGFloat{
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min min: CGFloat, max: CGFloat) -> CGFloat{
return random() * (max - min) + min
}
var gameArea: CGRect
override init(size: CGSize) {
let maxAspectRatio: CGFloat = 16.0/9.0
let playableWidth = size.height / maxAspectRatio
let margin = (size.width - playableWidth) / 2
gameArea = CGRect(x: margin, y: 0, width: playableWidth, height: size.height)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToView(view: SKView) {
createScene()
}
func createButton(){
restartButton = SKSpriteNode(imageNamed: "Restart Button")
restartButton.position = CGPoint(x: 768, y: 1024)
restartButton.zPosition = 6
restartButton.setScale(2.3)
self.addChild(restartButton)
}
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == physicsCatagory.person && secondBody.categoryBitMask == physicsCatagory.IceThree || firstBody.categoryBitMask == physicsCatagory.IceThree && secondBody.categoryBitMask == physicsCatagory.person{
scorenumber++
if scorenumber == 20 {
timePerSpawn = 1.0
}
if scorenumber == 40{
timePerSpawn = 0.89
}
if scorenumber == 60{
timePerSpawn = 0.6
}
if scorenumber == 80{
timePerSpawn = 0.5
}
if scorenumber == 100{
timePerSpawn = 0.4
}
if scorenumber == 120{
timePerSpawn = 0.3
}
ScoreLable.text = "\(scorenumber)"
CollisionWithPerson(firstBody.node as! SKSpriteNode, Person: secondBody.node as! SKSpriteNode)
}
if firstBody.categoryBitMask == physicsCatagory.Score && secondBody.categoryBitMask == physicsCatagory.IceThree ||
firstBody.categoryBitMask == physicsCatagory.IceThree && secondBody.categoryBitMask == physicsCatagory.Score{
lifenumber++
if lifenumber == 1{
//person.texture
person.texture = SKTexture (imageNamed: "Flower#2")
}
if lifenumber == 2{
person.texture = SKTexture (imageNamed: "Flower#3")
}
if lifenumber == 3{
// self.addChild(Highscorelabel)
Highscorelabel.zPosition = 5
createButton()
person.zPosition = -6
person.texture = SKTexture (imageNamed: "Person1")
//person.removeFromParent()
Died = true
}
}
}
func CollisionWithPerson (Ice: SKSpriteNode, Person: SKSpriteNode){
Person.removeFromParent()
// if (scorenumber > Highscore){
// var Highscoredefault = NSUserDefaults.standardUserDefaults()
// Highscoredefault.setValue(scorenumber, forKey: "HighScore")
//}
}
func spawnThirdIce(){
if Died == true {
} else
{
var Ice = SKSpriteNode(imageNamed: "Ice")
Ice.zPosition = 2
Ice.setScale(1.5)
Ice.physicsBody = SKPhysicsBody(rectangleOfSize: Ice.size)
Ice.physicsBody?.categoryBitMask = physicsCatagory.IceThree
Ice.physicsBody?.contactTestBitMask = physicsCatagory.person | physicsCatagory.Score
Ice.physicsBody?.affectedByGravity = false
Ice.physicsBody?.dynamic = true
let randomXStart = random(min:CGRectGetMinX(gameArea), max: CGRectGetMaxX(gameArea))
let randomXend = random(min:CGRectGetMinX(gameArea),max: CGRectGetMaxX(gameArea))
let startPoint = CGPoint(x: randomXStart, y: self.size.height * 1.2)
let endpoint = CGPoint(x: randomXend, y: -self.size.height * 0.2)
Ice.position = startPoint
let moveEnemy = SKAction.moveTo(endpoint, duration: 2.0)
let deleteEnemy = SKAction.removeFromParent()
let enemySequence = SKAction.sequence([moveEnemy , deleteEnemy])
Ice.runAction(enemySequence)
self.addChild(Ice)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches{
let location = touch.locationInNode(self)
if Died == true{
if restartButton.containsPoint(location){
restartScene()
}
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if Died == true {
}
else{
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let previousTouch = touch.previousLocationInNode(self)
let ammountDragged = location.x - previousTouch.x
person.position.x += ammountDragged
if person.position.x > CGRectGetMaxX(gameArea) - person.size.width/2{
person.position.x = CGRectGetMaxX(gameArea) - person.size.width/2
}
if person.position.x < CGRectGetMinX(gameArea) + person.size.width/2{
person.position.x = CGRectGetMinX(gameArea) + person.size.width/2
}
}
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if (currentTime - timeOfLastSpawn > timePerSpawn) {
spawnThirdIce()
self.timeOfLastSpawn = currentTime
}
}
}
Ok this is what I added to if life number = 3:
if lifenumber == 3{
if (scorenumber > Highscore){
var Highscoredefault = NSUserDefaults.standardUserDefaults()
Highscoredefault.setValue(scorenumber, forKey: "HighScore")
}
var Highscoredefault = NSUserDefaults.standardUserDefaults()
if (Highscoredefault.valueForKey("HighScore") != nil){
Highscore = Highscoredefault.valueForKey("HighScore") as! NSInteger
}
else{
Highscore = 0
}
self.addChild(Highscorelabel)
createButton()
person.zPosition = -6
person.texture = SKTexture (imageNamed: "Person1")
Died = true
}
It appears you only set the text property of Highscorelabel when you initialize it. If you want the Highscorelabel to be updated immediately upon death then you should update it at such time.
if lifenumber == 3 {
/* Check if new highscore, update HighscoreLabel */
I think you must add just this:
after scorenumber++ in func didBeginContact(contact: SKPhysicsContact)
//ADD THIS
if scorenumber > Highscore {
Highscore = scorenumber
Highscorelabel.text = "HighScore: \(Highscore)"
}

SKPhysics Contact not functioning properly

I am trying to use the SKPhysicsContactDelegate function in SpriteKit and it will not seem to work. I want one sprite to perform an action when it hits the other. I have set up breakpoints at the didBeginContact function and for some reason my application never calls this function. All help appreciated. Code posted below.
struct PhysicsCatagory {
static let Enemy :UInt32 = 0x1 << 0
static let Slider :UInt32 = 0x1 << 1
static let Circle :UInt32 = 0x1 << 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var EnemyTimer = NSTimer()
var Circle = SKSpriteNode()
var Slider = SKSpriteNode()
var FastButton = SKNode()
var Title = SKSpriteNode()
var Text = SKSpriteNode()
var Path = UIBezierPath()
var gameStarted = Bool()
override func didMoveToView(view: SKView) {
self.physicsWorld.contactDelegate = self
self.backgroundColor = UIColor.whiteColor()
Circle = SKSpriteNode(imageNamed:"blueCircle")
Circle.size = CGSize(width: 140, height: 140)
Circle.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
Circle.zPosition = 1.0
self.addChild(Circle)
Slider = SKSpriteNode(imageNamed: "blocker1")
Slider.size = CGSize(width: 15, height: 50)
Slider.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 80)
addChild(Slider)
Slider.zPosition = 1.0
moveClockWise()
}
func didBeginContact(contact: SKPhysicsContact) {
if contact.bodyA.node != nil && contact.bodyB.node != nil{
let firstBody = contact.bodyA.node as! SKSpriteNode
let secondBody = contact.bodyB.node as! SKSpriteNode
if ((firstBody.name == "Enemy") && (secondBody.name == "Slider")){
collisionBall(firstBody, Slider: secondBody)
}
else if ((firstBody.name == "Slider") && (secondBody.name == "Enemy")) {
collisionBall(secondBody, Slider: firstBody)
}
}
}
func collisionBall(Enemy : SKSpriteNode, Slider : SKSpriteNode){
Enemy.physicsBody?.dynamic = true
Enemy.physicsBody?.affectedByGravity = true
Enemy.physicsBody?.mass = 4.0
Slider.physicsBody?.mass = 4.0
Enemy.removeAllActions()
Enemy.physicsBody?.contactTestBitMask = 0
Enemy.physicsBody?.collisionBitMask = 0
Enemy.name = nil
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//Slider.hidden = false
FastButton.hidden = false
Title.hidden = true
Text.hidden = true
EnemyTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(GameScene.Enemies), userInfo: nil, repeats: true)
//Physics
Slider.physicsBody?.categoryBitMask = PhysicsCatagory.Slider
Slider.physicsBody?.collisionBitMask = PhysicsCatagory.Enemy
Slider.physicsBody?.contactTestBitMask = PhysicsCatagory.Enemy
Slider.name = "Slider"
Slider.physicsBody?.dynamic = true
Slider.physicsBody?.affectedByGravity = true
if gameStarted == false{
gameStarted = true
}
else if gameStarted == true{
}
}
func moveClockWise(){
let dx = Slider.position.x / 2
let dy = Slider.position.y / 2
let rad = atan2(dy, dx)
let Path = UIBezierPath(arcCenter: CGPoint(x: self.frame.width / 2, y: self.frame.height / 2), radius: 90, startAngle: rad, endAngle: rad + CGFloat(M_PI * 4), clockwise: true)
let follow = SKAction.followPath(Path.CGPath, asOffset: false, orientToPath: true, speed: 150)
//let rotate = SKAction.rotateByAngle(75, duration: 100)
Slider.runAction(SKAction.repeatActionForever(follow).reversedAction())
//Slider.runAction(SKAction.repeatActionForever(rotate).reversedAction())
}
func Enemies(){
let Enemy = SKSpriteNode(imageNamed: "darkRedDot")
Enemy.size = CGSize(width: 20, height: 20)
//Physics
Enemy.physicsBody = SKPhysicsBody(circleOfRadius: Enemy.size.width / 2)
Enemy.physicsBody?.categoryBitMask = PhysicsCatagory.Enemy
Enemy.physicsBody?.contactTestBitMask = PhysicsCatagory.Slider //| PhysicsCatagory.Circle
Enemy.physicsBody?.collisionBitMask = PhysicsCatagory.Slider //| PhysicsCatagory.Circle
Enemy.physicsBody?.dynamic = true
Enemy.physicsBody?.affectedByGravity = false
Enemy.name = "Enemy"
The contact is not beginning because your slider has no physics body, making it impossible to recognize contact. Unless, it's not in this code, your slider has no physics body, but your enemy does. Try declaring Slider.phisicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "blocker1"), size: Slider.size)
Also, you should read about standard naming conventions in Swift. It is recommended that your variables always start with lowercase letters (eg. enemyTimer, circle, slider, fastButton, etc...).

didBeginContact not working in Swift 2 + SpriteKit

I'm working on a game, and I'm using spritekit and Swift.
This is my code:
import SpriteKit
struct collision {
static let arrow:UInt32 = 0x1 << 1
static let runner:UInt32 = 0x1 << 2
static let target:UInt32 = 0x1 << 3
static let targetCenter:UInt32 = 0x1 << 4
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var person = SKSpriteNode()
var box = SKSpriteNode()
var screenSize:CGSize!
var gameScreenSize:CGSize!
var gameStarted:Bool = false
var moveAndRemove = SKAction()
var boxVelocity:NSTimeInterval = 5.5
override func didMoveToView(view: SKView) {
self.physicsWorld.gravity = CGVectorMake(0, -1.0)
self.physicsWorld.contactDelegate = self
screenSize = self.frame.size
gameScreenSize = view.frame.size
createPerson()
}
func createPerson() -> Void {
person.texture = SKTexture(imageNamed:"person")
person.setScale(1.0)
person.size = CGSize(width: 80, height: 80)
person.position = CGPoint(x: screenSize.width / 2, y: 150)
person.physicsBody = SKPhysicsBody(rectangleOfSize: person.size)
person.physicsBody?.affectedByGravity = false
person.physicsBody?.dynamic = false
self.addChild(person)
}
func createTarget() -> Void {
box = SKSpriteNode()
box.size = CGSize(width: 70, height: 100)
box.setScale(1.0)
box.position = CGPoint(x: (screenSize.width / 3) * 2, y: screenSize.height + box.size.height)
box.texture = SKTexture(imageNamed: "box")
box.physicsBody? = SKPhysicsBody(rectangleOfSize: box.size)
box.physicsBody?.categoryBitMask = collision.target
box.physicsBody?.collisionBitMask = collision.arrow
box.physicsBody?.contactTestBitMask = collision.targetCenter
box.physicsBody?.affectedByGravity = false
box.physicsBody?.dynamic = true
box.physicsBody?.usesPreciseCollisionDetection = true
self.addChild(box)
let distance = CGFloat(self.frame.height - box.frame.height)
let moveTargets = SKAction.moveToY(-distance, duration: boxVelocity)
let removeTargets = SKAction.removeFromParent()
moveAndRemove = SKAction.sequence([moveTargets,removeTargets])
box.runAction(moveAndRemove)
}
func createBall() ->Void {
let ball = SKSpriteNode()
ball.size = CGSize(width: 20, height: 22)
ball.zPosition = 5
let moveToXY = CGPoint(x: self.size.width, y: self.size.height)
ball.texture = SKTexture(imageNamed: "ball")
ball.position = CGPointMake(person.position.x + ball.size.width, person.position.y + ball.size.height)
ball.physicsBody? = SKPhysicsBody(rectangleOfSize: ball.size)
ball.physicsBody?.categoryBitMask = collision.arrow
ball.physicsBody?.collisionBitMask = collision.target
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.dynamic = true
ball.physicsBody?.usesPreciseCollisionDetection = true
let action = SKAction.moveTo(moveToXY, duration: 1.5)
let delay = SKAction.waitForDuration(1.5)
ball.runAction(SKAction.sequence([action,delay]))
self.addChild(ball)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if gameStarted == false {
gameStarted = true
let spawn = SKAction.runBlock { () in
self.createTarget()
}
let delay = SKAction.waitForDuration(1.5)
let spawnDelay = SKAction.sequence([spawn, delay])
let spanDelayForever = SKAction.repeatActionForever(spawnDelay)
self.runAction(spanDelayForever)
} else {
createBall()
boxVelocity -= 0.1
}
}
func didBeginContact(contact: SKPhysicsContact) {
print("Detect")
}
func didEndContact(contact: SKPhysicsContact) {
print("end detect")
}
override func update(currentTime: CFTimeInterval) {
}
}
But when I run the game, the collision between objects does not. I'm trying to solve a while, but found nothing. Can someone help me?
Project files.
Try with these to modifications:
box.physicsBody = SKPhysicsBody(rectangleOfSize: box.size)
box.physicsBody?.categoryBitMask = collision.target
box.physicsBody?.collisionBitMask = collision.arrow
box.physicsBody?.contactTestBitMask = collision.targetCenter
and
ball.physicsBody = SKPhysicsBody(rectangleOfSize: ball.size)
ball.physicsBody?.categoryBitMask = collision.arrow
ball.physicsBody?.collisionBitMask = collision.target
ball.physicsBody?.contactTestBitMask = collision.target
Note the absence of "?" while you init the physicsBody and the new contactTestBitMask

Pong-after a restart no ball on screen

I'm a newbee in Swift and SpriteKit. I have made a simple one player version of Pong. After a score the game restarts. Switches to the Game Over scene and returns. After that I cannot get the ball back on the screen. I do not understand that the spawnBall() does not reply, while the spawnPaddle, and the spawnBottom() do. Please help.
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
override init(size: CGSize) { super.init(size: CGSize()) }
var gameScene: GameScene!
let BallCategoryName = "ball" let BottomCategoryName = "bottom" let PaddleCategoryName = "paddle"
var isFingerOnPaddle = false
let BallCategory: UInt32 = 0x1 << 0
let BottomCategory : UInt32 = 0x1 << 1
let PaddleCategory : UInt32 = 0x1 << 3
var score = 0
var start: UIButton!
var isRunning = false
var scoreLabel = SKLabelNode()
var ball = SKSpriteNode()
var paddle = SKSpriteNode()
var bottom = SKSpriteNode()
var isBall = false
func spawnBall() {
ball = SKSpriteNode(imageNamed: "ball")
ball.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
ball.xScale = 0.1
ball.yScale = 0.1
ball.hidden = false
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height/2)
ball.physicsBody?.categoryBitMask = BallCategory
ball.physicsBody?.contactTestBitMask = BottomCategory
ball.physicsBody?.restitution = 1.0
ball.physicsBody?.linearDamping = 0.0
ball.physicsBody?.angularDamping = 0.0
addChild(ball)
isBall = true
println("***")
}
func spawnPaddle() {
paddle = SKSpriteNode(imageNamed: "wit")
paddle.position = CGPointMake(200, 50)
paddle.xScale = 0.09
paddle.yScale = 0.09
paddle.physicsBody = SKPhysicsBody(rectangleOfSize: paddle.size)
paddle.physicsBody?.categoryBitMask = PaddleCategory
paddle.physicsBody?.contactTestBitMask = BottomCategory
paddle.physicsBody?.restitution = 1.0
paddle.physicsBody?.linearDamping = 0.0
paddle.physicsBody?.angularDamping = 0.0
paddle.physicsBody?.dynamic = false
paddle.name = "paddle"
addChild(paddle)
}
func spawnBottom() {
bottom = SKSpriteNode(imageNamed: "wit")
bottom.position = CGPointMake(0, -111)
bottom.physicsBody = SKPhysicsBody(rectangleOfSize: bottom.size)
bottom.physicsBody?.dynamic = false
bottom.physicsBody?.restitution = 1
bottom.physicsBody?.angularDamping = 0
bottom.physicsBody?.linearDamping = 0.0
bottom.physicsBody?.categoryBitMask = BottomCategory
addChild(bottom)
println("Bottom")
}
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
physicsWorld.gravity = CGVectorMake(0, 0)
physicsWorld.contactDelegate = self
backgroundColor = UIColor.blackColor()
scoreLabel.fontColor = UIColor.whiteColor()
scoreLabel.fontName = "Avenir"
scoreLabel.fontSize = 25
scoreLabel.text = "0"
scoreLabel.position = CGPoint(x:CGRectGetMidX(frame) + 140, y: CGRectGetMidY(frame))
addChild(scoreLabel)
//////THE LOOP/////////////////////////////////////////////
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
spawnPaddle()
spawnBottom()
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
var touch = touches.anyObject() as UITouch
var touchLocation = touch.locationInNode(self)
if let body = physicsWorld.bodyAtPoint(touchLocation) {
if body.node?.name == PaddleCategoryName {
println("On the paddle")
isFingerOnPaddle = true
}
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
if isFingerOnPaddle {
var touch = touches.anyObject() as UITouch
var touchLocation = touch.locationInNode(self)
var previousLocation = touch.previousLocationInNode(self)
var paddleX = paddle.position.x + (touchLocation.x - previousLocation.x)
paddleX = max(paddleX, paddle.size.width/2)
paddleX = min(paddleX, size.width - paddle.size.width/2)
paddle.position = CGPointMake(paddleX, paddle.position.y)
}
}
func random(x: Int) -> Int {
var y = arc4random_uniform(UInt32(x))
return Int(y)
}
func start(sender: AnyObject) {
if isBall == false {
spawnBall()
ball.physicsBody?.applyImpulse(CGVectorMake(12, 40))
println("ball")
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
isFingerOnPaddle = false
}
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
}
func changeScene() {
let gameOverScene = GameOverScene(size: size)
gameOverScene.scaleMode = scaleMode
let reveal = SKTransition.flipHorizontalWithDuration(0.5)
view?.presentScene(gameOverScene, transition: reveal)
}
if firstBody.categoryBitMask == BallCategory && secondBody.categoryBitMask == BottomCategory {
println("Hit bottom.")
ball.physicsBody?.velocity = CGVectorMake(0, 0)
isBall = false
ball.removeFromParent()
score++
println(score)
scoreLabel.text = String(score)
isRunning = false
if score >= 3 {
ball.physicsBody?.velocity = CGVectorMake(0, 0)
isBall = false
ball.removeFromParent()
println("Game Over")
changeScene()
}
}
}
}