Reputation: 161
I have an SKSpriteNode which is controlled by the accelerometer to move left and right like so:
var destX = myNode.position.x
override func update(currentTime: CFTimeInterval) {
if let data = motionManager.accelerometerData {
let currentX = self.myNode.position.x
if data.acceleration.x < 0 {
self.destX = currentX + CGFloat(data.acceleration.x * 2000)
} else if data.acceleration.x > 0 {
self.destX = currentX + CGFloat(data.acceleration.x * 2000)
}
else if data.acceleration.x == 0 {
self.destX = currentX
}
}
}
Then, also in the update method, I create an SKAction
to move the SpriteNode to destX
:
if alive {
let action = SKAction.moveToX(destX, duration: 1)
self.myNode.runAction(action)
}
The right - left movement works fine. What I need to do now, though is to make the node so that it can't leave the screen. I tried putting a physics body around the edge of the screen:
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRectMake(0, 0, self.size.width, self.size.height))
self.physicsBody?.categoryBitMask = PhysicsCategory.ScreenEdge
myNode.physicsBody?.collisionBitMask = PhysicsCategory.ScreenEdge
I have the physics bodies themselves running fine, but the reason the collision is not working between the sprite node and the edge of the screen is that the node is running an action, and actions kind of 'override' physics. Is there any way to make the the node stop at the edge of the screen while still keeping the acceleration from the accelerometer's data? I know that currently, destX
is a very high or low number, but that is to cause the sprite node to move side to side quickly.
Basically, I need a way to either a) allow collisions even with an SKAction
running on the node, or b) make the moveToX
action stop when the sprite node gets off the screen, and make it start again once the node is back on the screen.
Thanks!
Upvotes: 0
Views: 523
Reputation: 491
Maybe this can help:
(sorry for the Objective C, I am not a swift programmer but will still try to explain how you could do this in your own language)
-(BOOL)isNode:(*SKnode)theNode outOfScene:(*SKScene)theScene
{
BOOL isIt = NO;
if (theNode.position.x > theScene.frame.size.width + (theNode.frame.size.width / 2)){isIt = YES;}
if (theNode.position.x < -(theNode.frame.size.width / 2)){isIt = YES;}
if (theNode.position.y > theScene.frame.size.height + (theNode.frame.size.height / 2)){isIt = YES;}
if (theNode.position.y < -(theNode.frame.size.height / 2)){isIt = YES;}
return isIt;
}
Here is how it works
-(BOOL)isNode:(*SKnode)theNode outOfScene:(*SKScene)theScene
new funtion,
input variables are: theNode
a node, and theScene
the scene to see if it is in in the bounds of.
BOOL isIt = NO;
creates a new Boolean variable, it's default value is NO
if (theNode.position.x > theScene.frame.size.width){isIt = YES;}
if (theNode.position.x < 0){isIt = YES;}
if (theNode.position.y > theScene.frame.size.height){isIt = YES;}
if (theNode.position.y < 0){isIt = YES;}
check to see if theNode
is not within theScene
's visible bounds.
Sets isIt to Yes if it is out of theScene
's bounds.
This assumes that theNode
's orientation is (0,0) -if you do not know what this means than you should probably ignore it.
return isIt
return isIt
to the sender (thing who 'called' the function)
That is how it is.
theNode
is not a child of theScene
you may have to convert the position of theNode
's coordinate space to that of theScene
.Upvotes: 1