5
\$\begingroup\$

This question already has an answer here:

I made this game. Right now the game supports all iOS devices except iPhone 5.

The definition of each level of the game is kept in a plist. The creation of each level is done through a graphical level editor. Each device family has its own plists. So, right now the game has 100 levels and 200 plists; 100 plists for the iPhone family and 100 plists for the iPad family.

In order to support the iPhone 5 I need to create 100 new plists and adjust the plists accordingly, which is time consuming, not to mention the creation of new levels...

The editor for creating and editing the levels is solely based on the manipulation of UIViews that describe the game elements. So, this is the code that I wrote to save and restore the state of each UIView in one level of the game.

- (void)encodeWithCoder:(NSCoder *)aCoder {
    // Save the screen size of the device that the view was saved on
    [aCoder encodeCGSize:self.gameView.bounds.size forKey:@"saveDeviceGameViewSize"];

    // ****************
    // ALL properties are saved in normalized coords
    // ****************

    // Save the center of the view
    CGPoint normCenter = CGPointMake(self.center.x / self.gameView.bounds.size.width, self.center.y / self.gameView.bounds.size.height);
    [aCoder encodeCGPoint:normCenter forKey:@"center"];

     // I rely on view bounds NOT frame
    CGRect normBounds = CGRectMake(0, 0, self.bounds.size.width / self.gameView.bounds.size.width, self.bounds.size.height / self.gameView.bounds.size.height);
    [aCoder encodeCGRect:normBounds forKey:@"bounds"];

     // Here I save the transformation of the view, it has ONLY rotation info, not translation or scalings
    [aCoder encodeCGAffineTransform:self.transform forKey:@"transform"];
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {

        // Restore the screen size of the device that the view was saved on
        saveDeviceGameViewSize = [aDecoder decodeCGSizeForKey:@"saveDeviceGameViewSize"];

        // Adjust the view center
        CGPoint tmpCenter = [aDecoder decodeCGPointForKey:@"center"];
        tmpCenter.x *= self.gameView.bounds.size.width;
        tmpCenter.y *= self.gameView.bounds.size.height;
        self.center = tmpCenter;

        // Restore the transform
        self.transform = [aDecoder decodeCGAffineTransformForKey:@"transform"];

        // Restore the bounds
        CGRect tmpBounds = [aDecoder decodeCGRectForKey:@"bounds"];
        CGFloat ratio = self.gameView.bounds.size.height / saveDeviceGameViewSize.height;
        tmpBounds.size.width *= (saveDeviceGameViewSize.width * ratio);
        tmpBounds.size.height *= self.gameView.bounds.size.height;
        self.bounds = tmpBounds;
    }
    return self;
}

I am really stuck here. I cannot explain what is wrong with this code. The UIViews are correctly positioned when restored on the same device. This is not true when the level is opened on another device. There are slightly misplaced elements and distortions.

Here are two pairs of screenshots demostrating the issues:

enter image description here enter image description here

enter image description here enter image description here

What is the correct approach to handle the scaling of the levels on different screens? Should I rely on AutoResizingMasks (I need to support iOS 4 and later)? In any case I would like to give a solid paradigm on how to achieve this.

\$\endgroup\$

marked as duplicate by Josh Jan 31 '14 at 22:07

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • \$\begingroup\$ How does a plist entry for one level look like for iphone and ipad? Can you add 2 screenshots with ok/misplaced looks? \$\endgroup\$ – ott-- Feb 26 '13 at 14:38
  • \$\begingroup\$ @ott-- Just added two pair of images as you suggested \$\endgroup\$ – Summon Feb 26 '13 at 20:53
  • \$\begingroup\$ You already have a grid there, can't you use that to place the objects? You don't need scaling then. \$\endgroup\$ – ott-- Feb 26 '13 at 21:03
  • \$\begingroup\$ @ott-- What I want to achieve is create the level once and the same plist file to work exactly the same on all devices independently of the screen size and ratio. Otherwise it takes lots of time to evaluate and test each level for each device and keep separate files. The grid is there in order to help the creation of the levels but it does not eliminate the issue. Thx anyway ;) \$\endgroup\$ – Summon Feb 26 '13 at 21:14
  • \$\begingroup\$ You haven't shown a plist entry for iphone and ipad tho. \$\endgroup\$ – ott-- Feb 26 '13 at 21:18

Browse other questions tagged or ask your own question.