Cocos2d iPHone SDK ccPhysicsCollisionPreSolve crashing while accessing object properties - ios

I am working on Cocos2d iphone SDK and stuck with an issues. Check my code here.
Obstacle Class
#objc class Obstacle: CCNode {
weak var __pipe: CCSprite!
var ignoreCollision:Bool = false
override init!() {
super.init()
//NSLog("init plain")
userInteractionEnabled = true
ignoreCollision = false
}
func didLoadFromCCB() {
...
}
}
The main scene where I have placed collision delegate methods. The method is called once the player object collides with obstacle object.
func ccPhysicsCollisionPreSolve(pair: CCPhysicsCollisionPair!, hero: Player!, platform: Obstacle!) -> ObjCBool {
if !isGameOn {
NSLog("PLATFORM: Game finished")
return false
}
if platform.ignoreCollision {
platform.ignoreCollision = !platform.ignoreCollision
// For score updates
hudLayer.updatePlatform(++scorePlatforms)
}
return true
}
Now here, I am just trying to use simple Bool property from platform object and what I get is a crash. My app crashes on the if... condition statement where I am using that property. I am unable to get what is with this as I am simply using a property from object.
I checked the object and found platform shows me of type Some instead ob Obstacle. I have tried using
var p: Obstacle = platform as Obstacle
and replaced all platform with p but yet I am facing the crash. I thought the type now shows me some random hex number which might be the issue.
Can anyone help me here as I am unable to find out how I should access property from this platform object in ccPhysicsCollisionPreSolve method?

Sorry guys for the trouble but it was my mistake. I was understanding the same incorrectly.
The Obstacle class represents the platform as well as its background layer having tripple height of the device screen. But my ball collides only with that __pipe sprite in Obstacle class and I am referring the whole Obstacle class which is wrong.
I used platform.parent!.ignoreCollision and problem is solved. :)
This little miss costed me 3-4 days of R&D and work extra.

Related

Impossible contact in SceneKit

The physicsWorld(_:didBegin:) function should only be called when some node's category bit is set in another nodes contactTest bit mask. However, in my code, there is an impossible situation happening where a contact is occurring when neither of the contacting bodies have each other in their contactTest bit masks. Eg:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if (contact.nodeA.physicsBody!.categoryBitMask & contact.nodeB.physicsBody!.contactTestBitMask) != 0 {
print("All good")
} else if (contact.nodeA.physicsBody!.contactTestBitMask & contact.nodeB.physicsBody!.categoryBitMask) != 0 {
print("All good")
} else {
fatalError("Impossible") // << Execution reaches here
}
// .. Code handling the contact ...
}
I noticed this started happening when I added this line to the physicsWorld(_:didBegin:) function:
// The ball is the only node in the game that has a contactTestBitMask other than 0
let ball = contact.nodeA.name == "ball" ? contact.nodeA : contact.nodeB
ball.physicsBody!.contactTestBitMask = PhysicsCategory.dynamic
Regardless of what code I add to the function, that fatalError should never be reached. I don't know if changing bit masks within the didBeginContact method leads to undefined behaviour, but I still don't think the physicsWorld(_:didBegin:) should ever get called if categoryBitMask & contactTestBitMask == 0.
If I change (changing in both nodeA and nodeB) nodeA/B.physicsBody!.categoryBitMask to nodeA/B.categoryBitMask then it never crashes, but according to the documentation, a SCNNodes category bit mask property doesn't affect the SceneKit physics simulation.
If anyone has any suspicious of why this could happen please let me know as I'm convinced it's a bug.
Thanks

Easy-Game-Center Sprite-Kit Integration

I am trying to use the Easy-Game-Center by DaRkD0G from GitHub in my game (swift sprite kit). However, when calling the EasyGameCenter.Swift (using
EasyGameCenter.sharedInstance(self)
in my GameScene)
I get an error saying "Cannot convert value of type 'GameScene' to expected argument type 'UIViewController'". For the past couple days, I have tried changing up the different class types in EasyGameCenter but always get answers. Does anyone have any suggestions?
I'm the creator of this project.
You can't use the Game Center of Apple without UIViewController !
The Framework Game Center need UIViewController for work, this is the official documentation of Game Center Apple.
And Easy Game Center need create with delegate UIViewController for work perfectly, without it is impossible to use Game Center
Example projet Game Center + Sprite Kit :
http://www.raywenderlich.com/60980/game-center-tutorial-how-to-make-a-simple-multiplayer-game-with-sprite-kit-part-1
Create instance with UIViewController :
This is for create the instance of EasyGameCenter
override func viewDidLoad() {
super.viewDidLoad()
EasyGameCenter.sharedInstance(self)
}
Add this, if you change UIViewController for notifies the view controller delegate was changed, it's optional if you not change UIViewController you do not need this method
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
EasyGameCenter.delegate = self
}
just like that, now you can import the project with CocoaPods
pod 'EasyGameCenter', :git => 'https://github.com/DaRkD0G/Easy-Game-Center-Swift.git'
Never used that library, but as message says :
"Cannot convert value of type 'GameScene' to expected argument type
'UIViewController'"
This is the method you are calling:
class func sharedInstance(delegate:UIViewController)-> EasyGameCenter {
if Static.instance == nil {
dispatch_once(&Static.onceToken) {
Static.instance = EasyGameCenter()
Static.delegate = delegate
Static.instance!.loginPlayerToGameCenter()
}
}
return Static.instance!
}
You have to pass an UIViewController as an argument instead of GameScene.

SceneKit: isResting never returns true

I am trying to make an app that uses 3D physics and detects when the various nodes in the scene have all come to rest. The logical way to do this would seem to be testing their isResting property on their physics body. However, no matter how stationary the objects are, this value is never set. I have checked that allowsResting is true and am testing the attribute as follows, but I have never seen even one object 'at rest' despite logging out its status on each update. I've also tried putting this in the didRender function. Anyone got any ideas as to why isResting never seems to be set?
var isTotallyAtRest = false
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval) {
for object in allObjects {
if let physics = object {
if physics.isResting == false {return}
}
}
isTotallyAtRest = true
}

Swift: Fatal error: unexpectedly found nil while unwrapping an Optional value (SpriteKit)

I've just started learning to program iOS games with SpriteKit and I'm a novice to programming (I have only programmed in Java and Swift before this). I started out by doing a tutorial I found online. I'm at the point where I am trying to add a "Game Over" scene, and I keep getting the error
"Thread 1:EXC-BAD_INSTRUCTION(code=EXC_I386_INVOP,subcode=0x0)"
when I am declaring the gameOverLabel constant. It compiles but crashes at run time as soon as the ball hits the bottom of the screen, which is supposed to trigger the 'Game Over' screen.
import SpriteKit
let gameOverLabelCategoryName = "gameOverLabel"
class GameOverScene: SKScene {
var gameWon: Bool = false {
didSet {
let gameOverLabel = childNodeWithName(gameOverLabelCategoryName) as! SKLabelNode
gameOverLabel.text = gameWon ? "Game Won" : "Game Over"
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let view = view {
let gameScene = GameScene.unarchiveFromFile("GameScene") as! GameScene
view.presentScene(gameScene)
}
}
}
Also if anyone has suggestions of places I can go to learn more about SpriteKit, articles or videos, it would be much appreciated as most things I have found have been in Objective-C and I am doing this in Swift.
Here is the tutorial I have been following..
childNodeWithName will return nil if a node with that name does not exist. Your code is not checking for this possibility (the as! assumes that it is both not nil and of the appropriate type) so this is causing the crash.
The tutorial asks you to create this 'gameOverLabel' node and name it before creating this code. Check that you did that correctly and that you did not misname it (it is case sensitive for example).
It looks like you are declaring your gameOverLabelCategoryName constant outside of the scope of the class which looks a bit odd, but should be fine. It will be scoped to internal (docs).
On line 14: "if let view = view {" you are declaring a constant named view which masks the original self.view instance. Perhaps that could be confusing the compiler and causing an internal crash?

SKSpriteNode subclass: method to remove all joints

I have created a subclass of SKSpriteNode. I connect instances of that class together with joints of type SKPhysicsJointLimit. I do this within my didEndContact(contact: SKPhysicsContact) in my GameScene:
var joint = SKPhysicsJointLimit.jointWithBodyA(contact.bodyA, bodyB: contact.bodyB, anchorA: pos1!, anchorB: pos2!)
self.physicsWorld.addJoint(joint)
This works well so far.
Then i come to the point where i want to release the node from the joint. According to the SKPhysicsBody docs there is a property called "joints" which is an array holding SKPhysicsJoint objects. I thought thats exactly what I need, but I am not able to iterate over an instance's joints and remove them from the physicsWorld. To do the job i added a method to my custom SKSpriteNode subclass.
func freeJoints(world: SKPhysicsWorld){
if let joints = self.physicsBody?.joints {
for joint in joints{
println("found a joint: \(joint)")
// example print:
//found a joint: <PKPhysicsJointRope: 0x7fbe39e95c50>
world.removeJoint(joint as SKPhysicsJoint)
}
}
}
Calling the method fails after the println() statement with the message "Swift dynamic cast failed". I would really appreciate your opinion in how to work with an SKPhysicsBody's joint property. More specifically: How to use (cast?) the items in the array to be able to remove them from a scene's SKPhysicsWorld.
I spent a little more time in investigating this. This is what I have come up with:
I decided to add an property to my SKSpriteNode subclass and manage the joints myself
var joints: [SKPhysicsJointLimit]
override init(){
...
self.joints = []
...
}
Everytime I add an joint to the scene's SKPHysicsWorld I also add it to the joints array of the SKNNode itself. Whilst iterating the SKPHysicsBody's joints-Array failed (see question) at the point I wanted to cast it to SKPhysicsJoint, removing items from the physics world works as intended when iterating the array of SKPhysicsJointLimit items:
func freeJoints(world: SKPhysicsWorld){
for item in self.joints{
println("removing item from physics world \(item)")
world.removeJoint(item)
}
self.joints.removeAll(keepCapacity: false)
}
}
This seems not to be the most elegant way to do the job, since there already is a framework managed array that promises to be same thing. But I was unable to utilize it and this works for now.

Resources