I have a small app that I have several sprite "balls" that move around the board using MotionManager.gravity.
I have code that when one of any of the balls meets an edge the stop at the edge. also if one of any of the balls gets to the corner it stops in the corner. I have also written code in which if two or three of the balls are on any one edge and touch each other (they have collision detection turned on) they stop in they maintain their relative position to the other ball.
Here is my code for that:
//this allocs the motionManager and set up the gravity values.
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 0.005f;
self.motionQueue = [[NSOperationQueue alloc] init];
self.motionQueue.name = [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".motion"];
self.updatePosition = NO;
[self.motionManager startDeviceMotionUpdatesToQueue:self.motionQueue withHandler:^(CMDeviceMotion *motion, NSError *error) {
@synchronized(self) {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
{
_numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:motion.gravity.x / 15.0 *200]];
_numberStringy = [formatter stringFromNumber:[NSNumber numberWithFloat:motion.gravity.y / 15.0 *200]];
n = [_numberString intValue];
y = [_numberStringy intValue];
}
self.gravity = motion.gravity;
self.updatePosition = YES;
}
}];
[self startDisplayLink];
//this shows how I stop the ball at the edge
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
@synchronized(self) {
if (!self.updatePosition)
return;
self.ball.position = CGPointMake(self.ball.position.x + (n*.99), self.ball.position.y + (y*.99));
self.ball2.position = CGPointMake(self.ball2.position.x + (n*.98), self.ball2.position.y +(y*.98));
self.ball3.position = CGPointMake(self.ball3.position.x + n, self.ball3.position.y + y);
if (ball.position.x <=340) {
ball.position = CGPointMake(340, ball.position.y);
}
if (ball.position.x >=684) {
ball.position = CGPointMake(684, ball.position.y);
}
if (ball.position.y <=148) {
ball.position = CGPointMake( ball.position.x,148);
}
if (ball.position.y >=620) {
ball.position = CGPointMake(ball.position.x,620);
}
//this stops it in the corner
if ( ball.position.x >=684 && ball.position.y <=148 ) {
ball.position = CGPointMake(684, 148);
}
if ( ball.position.x >=684 && ball.position.y >=620 ) {
ball.position = CGPointMake(684, 620);
}
if ( ball.position.x <=340 && ball.position.y <=148 ) {
ball.position = CGPointMake(340, 148);
}
if ( ball.position.x <=340 && ball.position.y >=620 ) {
ball.position = CGPointMake(340, 620);
}
//and this shows how I have set it up that if they are on one side and ball1 is in the corner and ball2 is next and ball3 is next they keep their relative positions. I thought if I set the corner ball and the rest had collision detection turned on they would just stop. They do but they push ball1 in the corner out of its position. So I wrote the code
if (ball2.position.y == ball3.position.y && ball.position.y == ball2.position.y && ball.position.x < ball2.position.x && ball2.position.x < ball3.position.x ) {
int s = (self.ball3.position.x - self.ball2.position.x);
int t = ((self.ball2.position.y - self.ball3.position.y));
k = t + s;
int f =(self.ball2.position.x - self.ball.position.x);
int g = ((self.ball2.position.y - self.ball.position.y));
j = f+g;
int h =(self.ball3.position.x - self.ball.position.x);
int i = ((self.ball3.position.y - self.ball.position.y));
l = h + i;
NSLog(@"ball2centerx:%f",ball2.position.x);
NSLog(@"ball2centery:%f",ball2.position.y);
NSLog(@"ballcenterx:%f",ball.position.x);
NSLog(@"ballcentery:%f",ball.position.y);
NSLog(@"ball3centerx:%f",ball3.position.x);
NSLog(@"ball3centery:%f",ball3.position.y);
CGPoint w = CGPointMake(340, 148);
CGPoint x = CGPointMake(340, 620);
CGPoint v = CGPointMake(684, 148);
CGPoint z = CGPointMake(684, 620);
CGPoint m = CGPointMake(370, 148);
CGPoint q = CGPointMake(370, 620);
CGPoint o = CGPointMake(654, 148);
CGPoint p = CGPointMake(654, 620);
if (CGPointEqualToPoint(ball.position,w) ) {
if (f < 30) {
ball2.position = CGPointMake(370, 148);
}
}
if (CGPointEqualToPoint(ball.position,x)) {
if (f<30) {
ball2.position = CGPointMake(370, 620);
}
}
if (CGPointEqualToPoint(ball3.position,v)) {
if (s <30){
ball2.position = CGPointMake(654, 148);
}
}
if (CGPointEqualToPoint(ball3.position,z)) {
if (s <30){
ball2.position = CGPointMake(654, 620);
}
}
if (CGPointEqualToPoint(ball2.position,m)) {
if (s <30){
ball3.position = CGPointMake(400, 148);
}
}
if (CGPointEqualToPoint(ball2.position,o)) {
if (f<30) {
ball.position = CGPointMake(624, 148);
}
}
if (CGPointEqualToPoint(ball2.position,q)) {
if (s <30){
ball3.position = CGPointMake(400, 620);
}
}
if (CGPointEqualToPoint(ball2.position,p)) {
if (f<30) {
ball.position = CGPointMake(624, 620);
}
}
}
The problem is that as I add more ball the code is going to become extremely complex.
is there a way to write it so that if one ball (any ball) is in the corner and another one is in position two it will stay there and so forth. Kind of like a generic code for all ball configuration. instead of writing it for every configuration?
If you are going to have a number of nodes in your scene, it becomes tedious and impractical to create a property for each one. A good solution is to create each node and add it into an array. The array will allow you to keep a reference to it. The important thing is to create each node with its own unique name. You can do this by creating a counter property.
Then when you create your node set the node's name property like this:
Once you have fully created the node, add it to a NSMutableArray like this:
You can add as many nodes to the array as you need.
To enumerate through the array you can do this:
Here is an example to enumerate the array to check for each node's position and set its speed to zero dependent on the IF statement:
Remember that because you are storing the objects in your array as SKSpriteNodes and enumerating your array using SKSpriteNode, you have access to all the corresponding properties like speed, position, name, etc...