Sunday, 2 February 2014

Another SpriteKit game example - also about fighter planes....

Found another nice SpriteKit game example here. However this time there wasn't much details/explanation provided like other tutorials, therefore I am having some difficulties understanding the code and the design/structure.

I like the way how everything been put in it's separate classes, and the way the 2 layers of background cloud been handled, and different emitters been used when the hero fighter was hit to show how serious the plane was damaged.

The only problem is, for some unknown reason, the hero fighter wouldn't move on my iPhone 5 (iOS7). As shown in images above, the hero fighter is always stuck in the middle of the screen.

According to the code, it's using "CMDeviceMotion" in CMMotionManager to detect the roll and pitch of the device to move the hero fighter - by using "physicsBody applyImpulse" method - which is another new thing to me.

Thinking it might be problem with the device, I tried the same game on my iPad 2 (iOS7), it crashed on the first run due to "Main_iPad" storyboard missing. After I copied over an empty "Main_iPad" storyboard from another project, it works. However, still can't get the hero fighter to move at all, very strange.

Compared with the "Airplane" tutorial mentioned before - which uses "CMAccelerometerData"instead, and works on both my iPhone 5 and iPad 2. Suspect there's some problem with the code somewhere. Already left a comment and will wait for the author to help. May be if I can find some spare time, will convert it over to use "CMAccelerometerData" as well…

[Update] 04/Feb/2014

Yes, I got it working!

All I did was:
(1) Remove the following line inside "FighterGameScene.m"

  CMMotionManager *_motionManager;

(2) In "FighterGameScene.h" add an import at the top

#import <CoreMotion/CoreMotion.h>

Then add the following line near the end (before @end). That is, basically move the declaration of "motionManager" from  "FighterGameScene.m" to "FighterGameScene.h"

@property (strong, nonatomic) CMMotionManager *motionManager;

(3) Finally, inside "FighterGameScene.m" change the following lines:

        CMMotionManager *motionManager = [[CMMotionManager alloc] init];
        if([motionManager isDeviceMotionAvailable]) {
            [motionManager setAccelerometerUpdateInterval:1.0/30.0];
            [motionManager startDeviceMotionUpdates];

            [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue new] withHandler:^(CMDeviceMotion *motion, NSError *error)

to the followings, note that I also removed the 4th line "[motionManager startDeviceMotionUpdates];" as that seems to be duplicate and I don't see that extra line in other examples on the net and books.

        self.motionManager = [[CMMotionManager alloc] init];
        if([self.motionManager isDeviceMotionAvailable]) {
            [self.motionManager setAccelerometerUpdateInterval:1.0/30.0];

            [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue new] withHandler:^(CMDeviceMotion *motion, NSError *error)

As below, now it works on both my iPhone 5 and iPad 2. Before the fix, can only reach top score of 800 as the hero fighter will die after a few crashes (since it can't move!). Now I can get much higher score than that, yeah!

To be honest, I don't really understand why this fixed the problem. And if you look at Chris Grant's comments on his post, it works on his iPhone 5/5s even without the change!?

Would be really appreciated if any of you can kindly explain why this simple change fixed the problem, why it was working on Chris' devices but not mine before the change? Is there some settings in Xcode or the phone that could cause this issue??

No comments:

Post a Comment