Wednesday, 27 August 2014

How to create a "cross" (or "plus") shape spinning object with Sprite Kit Physics?

Was following the example in this Free PoBo site, but want to create a "cross" (or "plus") shape instead of just a seesaw.

Uploaded a small test project here, basically it creates a scene as shown below, some seesaws with one of them replaced by the cross thing I tried to put it.

When you tapped on anywhere on the screen, you will either create a small ball or square box which will drop down from where you tapped. When the object hits the seesaw it spins as expected.

Problem is, the cross object doesn't always spin as expected - only when the object hits the middle green circle of the cross shape object, then it will start spinning. Otherwise the object just drop through the blue area as if it doesn't exist. Wonder what have I done wrong??!!

This is how the cross been added in the code:


        float wWidth = 100.0f;
        float wHeight = 10.0f;
        
        
        [self addCross:CGPointMake(self.frame.size.width*0.75f, self.frame.size.height*0.60f)
                  game:self
             whipWidth:wWidth*0.5f

            whipHeight:wHeight];


-(CGMutablePathRef)getCGMutablePathRef:(float)ww thickness:(float)tt {
    
    CGMutablePathRef boundingPath = CGPathCreateMutable();
    float halfTT = tt*0.5;
    
    CGPathMoveToPoint(boundingPath, NULL, halfTT, halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT+ww, halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT+ww, -halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT, -halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT, -halfTT-ww);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT, -halfTT-ww);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT, -halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT-ww, -halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT-ww, halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT, halfTT);
    CGPathAddLineToPoint(boundingPath, NULL, -halfTT, halfTT+ww);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT, halfTT+ww);
    CGPathAddLineToPoint(boundingPath, NULL, halfTT, halfTT);
    
    return boundingPath;
    
}

-(void)addCross:(CGPoint)pos game:(SKScene*)game  whipWidth:(float)whipWidth whipHeight:(float)whipHeight {
    
    idNumber++;
    
    SKSpriteNode * anchor = [SKSpriteNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(1, 1)];
    anchor.position = pos;
    anchor.name = [NSString stringWithFormat:@"whip_anchor-%d",idNumber];
    anchor.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:1];
    anchor.physicsBody.affectedByGravity = false;
    anchor.physicsBody.dynamic = false;
    [game addChild:anchor];
    
    CGMutablePathRef boundingPath = [self getCGMutablePathRef:whipWidth thickness:whipHeight];
    
    CGMutablePathRef boundingPath2 = [self getCGMutablePathRef:whipWidth thickness:whipHeight];
    
    SKShapeNode* polygon = [[SKShapeNode alloc]init];
    
    polygon.path = CGPathCreateMutableCopy(boundingPath2);
    
    polygon.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:boundingPath];
    CGPathRelease(boundingPath);
    CGPathRelease(boundingPath2);
    
    polygon.name = @"polygon";
    
    polygon.lineWidth = 0.01;
    polygon.fillColor = [SKColor blueColor];
    polygon.lineWidth = 0;

    polygon.physicsBody.affectedByGravity = NO;
    [anchor addChild:polygon];
    
    SKSpriteNode * gear = [SKSpriteNode spriteNodeWithImageNamed:@"ball"];
    gear.size = CGSizeMake(whipHeight+5, whipHeight+5);
    gear.name = [NSString stringWithFormat:@"gear-%d",idNumber];
    [anchor addChild:gear];
    
    SKPhysicsJointPin* jointPin = [SKPhysicsJointPin jointWithBodyA:anchor.physicsBody
                                                              bodyB:polygon.physicsBody
                                                             anchor:anchor.position];
    [game.physicsWorld addJoint:jointPin];
    
    
    idNumber++;

}

[2014-08-29 Update]
Posted the question on stackoverflow.com

[2014-09-03 Update]
Was trying different ways of creating the polygon - clock-wise, anti-clock-wise, …etc. Sometimes only the left hand side of the cross works and sometimes the right hand side, sometimes keep getting this "Assertion failed: (area > 1.19209290e-7F), function ComputeCentroid, file /SourceCache/PhysicsKit/PhysicsKit-6.5.4/PhysicsKit/Box2D/Collision/Shapes/b2PolygonShape.cpp, line 122." error similar to this link due to polygon not convex,  quite frustrating.

Finally got it working today by joining the second rectangle to the first one using fixed joint. The code as below:

-(void)addCross2:(CGPoint)pos game:(SKScene*)game whipWidth:(float)whipWidth whipHeight:(float)whipHeight {
    
    idNumber++;
    
    SKSpriteNode * anchor = [SKSpriteNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(1, 1)];
    anchor.position = pos;
    anchor.name = [NSString stringWithFormat:@"whip_anchor-%d",idNumber];
    anchor.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:1];
    anchor.physicsBody.affectedByGravity = false;
    anchor.physicsBody.dynamic = false;
    [game addChild:anchor];
    
    SKSpriteNode * whip = [SKSpriteNode spriteNodeWithImageNamed:@"box"];
    whip.name = [NSString stringWithFormat:@"whip-%d",idNumber];
    whip.size = CGSizeMake(whipWidth, whipHeight);
    whip.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(whipWidth, whipHeight)];
    whip.physicsBody.mass = objMass*0.5f;
    whip.physicsBody.friction = 0;
    whip.physicsBody.linearDamping = 0;
    [anchor addChild:whip];
    
    SKSpriteNode * gear = [SKSpriteNode spriteNodeWithImageNamed:@"ball"];
    gear.size = CGSizeMake(whipHeight+5, whipHeight+5);
    gear.name = [NSString stringWithFormat:@"gear-%d",idNumber];
    [anchor addChild:gear];
    
    
    ///////////////
    // extra whip
    SKSpriteNode * whip2 = [SKSpriteNode spriteNodeWithImageNamed:@"box"];
    whip2.name = [NSString stringWithFormat:@"whip-%d-2",idNumber];
    whip2.size = CGSizeMake(whipHeight, whipWidth);
    whip2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(whipHeight, whipWidth)];
    whip2.physicsBody.mass = objMass*0.5f;
    whip2.physicsBody.friction = 0;
    whip2.physicsBody.linearDamping = 0;
    [whip addChild:whip2];
    
    ////////////
    // join with whip 1 using fixed joint
    SKPhysicsJointFixed* jointPin2 = [SKPhysicsJointFixed  jointWithBodyA:whip.physicsBody
                                                                    bodyB:whip2.physicsBody
                                                                   anchor:whip.position];
    
    [game.physicsWorld addJoint:jointPin2];
    
    //////////////
    
    
    SKPhysicsJointPin* jointPin = [SKPhysicsJointPin jointWithBodyA:anchor.physicsBody
                                                              bodyB:whip.physicsBody
                                                             anchor:anchor.position];
    
    [game.physicsWorld addJoint:jointPin];


   
    idNumber++;

}


[Update 25/Apr/2015]
The guys at free-pobo.com/waveworks.de are really nice and they provided a new working sample using rotating mills as I request, see further info here. Even have a YouTube video for it!

Really appreciated!


Monday, 25 August 2014

iPhone 5 Battery Replacement Program

Have you checked the serial number of your iPhone 5 on Apple's iPhone 5 Battery Replacement Program page?

As shown below, mine is one of the unlucky ones... No wonder some time last week it suddenly dropped from about 80% to 0 and I thought it was dead! Have to wait for a long time for it to be charged.


This is not the first time my phone has issue, remember the previous sleep/awake button replacement program? Mine was in there too....

[Update 10/Sep/2014]
My iPhone 5 was replaced, see this post for details.

Sunday, 24 August 2014

Background color change effect similar to "Spikes"(Don't touch the spikes) game

If you ever played the popular "Spikes"(Don't touch the spikes) game, you will notice that every 5 levels, the background color changed. You can have a look using this YouTube video:



Since background color is controlled by 3 RGB value, I use info from this stackover page to create a "number to binary string converter". Then based on the returned result, add together required value for each R, G, B colour depending on the "0" and "1" of every group of 3 digits.

I have created a test project to simulate the effect at this github repository.


Tuesday, 19 August 2014

Open Source Piano Tiles game published!

After last week's small incident, we finally have our "Open Source Piano Tiles" game published in the App Store!



The game was written in Sprite Kit, and the source is published both as a marketing tool to promote my other games, plus help anyone who might be interesting in learning Sprite Kit or writing his/her own Piano Tiles game.

High level structure is as below and shouldn't be too hard to understand.



FAQ:
(1) What's the difference between the published game and source available for download?
The only difference is the launch image been replaced by simple image as below.

(2) I can't find the link to download the code?
After you clicked on the link (shown far, far below...), as shown highlighted in red below, click on the icon with downward pointing arrow in the upper middle of the screen to download the file.




(3) Under what license was the code released with?
The only condition for downloading the source will be to download all my games as below and play everyone of them for a few times, simple as that! Optionally, please leave a positive comment for me!



(4) I found a bug, what next?
Well done, thanks for that! Please post it as comment below or email me, and I will try to fix it in the next release.

(5) I don't understand why you do xxx this way....
Please post any question or suggestion or further improvements ideas below and I will try to explain it here if possible.

(6) Cut the crap, where is the link?
Alright, assuming you did follow my conditions above and downloaded all my other games, here it is , enjoy!


[Update 24/08/2014]
For those who prefer github, it's also available here


Thursday, 14 August 2014

Open Source game rejected by Apple because of the word "Demo" mentioned in the description

OMG! My Open Source game was rejected by Apple!

Checked the "Resolution Center" and as shown below, it's because of this rule '2.9 Apps that are "beta", "demo", "trial", or "test" versions will be rejected' ... Never heard of that??!!

I guess lots of people are like me who never carefully study and remember each and every rule and policy and whatever clauses and conditions for App submission...

Ok, I reviewed what I entered and have to admit that I did mention the word "Demo" in the description:

"Demo game with full source code in objective-c available on blog URL specified within the game."

But, but, but it's a fully functioning game!.... Well, don't think the chance of arguing and winning would be that high. So I changed the word "Demo" to "Simple" and resubmitted the game, another long week of waiting, damn!

Hope you find this information helpful and none of you ever made the same mistake like me!


[Updated 02-Sep-2014]

See this "Common App Rejections" page published by Apple.

Friday, 1 August 2014

New Open Source Game

We will be releasing a new open source game in the coming weeks, more details coming soon...