问题
I have an iPhone game that was first developed for iPhone 6 and when played on the iPhone 5 sim it works fine but when played on the iPhone 4 sim the sides are stretched out?!? and the nodes that I spawn in from the left and the right side spawn on the screen instead of off the screen like on the iPhone 6 and 5. (please don't say this is a duplicate as I have been looking for weeks of how to deal with different iPhones)
I have arrows coming in the from the left and the right that spawn randomly on the y axis. They spawn off screen then slowly move on screen than move quickly across the screen but on the iPhone 4 the arrows spawn on the screen. this is the code for one of the arrows
-(void) leftArrow
{
int randomY = arc4random() % (675 - 175);
int yPoint = randomY + 175;
leftArrow = [SKSpriteNode spriteNodeWithImageNamed:@"arrow"];
leftArrow.size = CGSizeMake(leftArrow.size.width/1.2, self.frame.size.height/22);
leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - 230, yPoint);
leftArrow.zPosition = 50;
leftArrow.alpha = 1;
SKAction* action1 = [SKAction moveToX:leftArrow.position.x + 30 duration:0.5];
SKAction* wait = [SKAction waitForDuration:0.75];
SKAction* action2 = [SKAction moveToX:leftArrow.position.x + 470 duration:1.5];
SKAction* sequence = [SKAction sequence:@[action1,wait,action2,destroy]];
[self addChild:leftArrow];
if (deadDown == 1 || deadUp == 1 || didIntersect == true)
{
[leftArrow runAction:destroy];
}
else
{
[leftArrow runAction:sequence completion:^{
if (ii != 1)
{
if (didIntersect != true)
{
score++;
if (score == 100)
{
backgroundScore.fontSize = 300;
backgroundScore.position = CGPointMake(backgroundScore.position.x, backgroundScore.position.y + 30);
}
strFromInt = [NSString stringWithFormat:@"%d",score];
backgroundScore.text = strFromInt;
}
}
}];
}
}
I am also using this in my didmovetoview function
self.scaleMode = SKSceneScaleModeAspectFill;
回答1:
The main issue is handling the various screen sizes in relation to your image assets and screen object coordinates.
My solution is to write your code as if you are coding for the iPhone 6 plus. Make all your images @3x size and your screen layout coordinates for the iPhone 6 screen size.
With just a bit of code I was able to get an uniform layout for the iPhone 6 plus, 6, 5 and 4 screen sizes. I have included screen shots for each one. The character image is 300x300. The 2 button images are 100x100.
static const float kIphone6PlusScaleFactorX = 1.0;
static const float kIphone6PlusScaleFactorY = 1.0;
static const float kIphone6ScaleFactorX = 0.9;
static const float kIphone6ScaleFactorY = 0.9;
static const float kIphone5ScaleFactorX = 0.772;
static const float kIphone5ScaleFactorY = 0.772;
static const float kIphone4ScaleFactorX = 0.772;
static const float kIphone4ScaleFactorY = 0.652;
#import "GameScene.h"
@implementation GameScene {
float scaleFactorX;
float scaleFactorY;
SKSpriteNode *node0;
SKSpriteNode *node1;
SKSpriteNode *node2;
SKLabelNode *label0;
}
-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [SKColor blackColor];
if(view.frame.size.height == 736) {
NSLog(@"iPhone 6 plus");
scaleFactorX = kIphone6PlusScaleFactorX;
scaleFactorY = kIphone6PlusScaleFactorY;
}
if(view.frame.size.height == 667) {
NSLog(@"iPhone 6");
scaleFactorX = kIphone6ScaleFactorX;
scaleFactorY = kIphone6ScaleFactorY;
}
if(view.frame.size.height == 568) {
NSLog(@"iPhone 5");
scaleFactorX = kIphone5ScaleFactorX;
scaleFactorY = kIphone5ScaleFactorY;
}
if(view.frame.size.height == 480) {
NSLog(@"iPhone 4");
scaleFactorX = kIphone4ScaleFactorX;
scaleFactorY = kIphone4ScaleFactorY;
}
node0 = [SKSpriteNode spriteNodeWithImageNamed:@"Pic"];
node0.position = CGPointMake(self.size.width/2, self.size.height/2);
[node0 setScale:scaleFactorX];
[self addChild:node0];
node1 = [SKSpriteNode spriteNodeWithImageNamed:@"button0"];
node1.position = CGPointMake(100*scaleFactorX, 100*scaleFactorY);
[node1 setScale:scaleFactorX];
[self addChild:node1];
node2 = [SKSpriteNode spriteNodeWithImageNamed:@"button1"];
node2.position = CGPointMake(314*scaleFactorX, 100*scaleFactorY);
[node2 setScale:scaleFactorX];
[self addChild:node2];
label0 = [SKLabelNode labelNodeWithFontNamed:@"HelveticaNeue-Bold"];
label0.text = @"Big Game Menu";
label0.fontSize = 48*scaleFactorX;
label0.fontColor = [SKColor whiteColor];
label0.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
label0.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
label0.position = CGPointMake(207*scaleFactorX,690*scaleFactorY);
[self addChild:label0];
}
iPhone 4

iPhone 5

iPhone 6

iPhone 6 Plus

Notice how even the text label is scaled down correctly not just by font size but also location.
You can use the above logic to also spawn nodes in relation to the screen size.
For your reference, I did use the standard code in my GameViewController because I find it easier to work with a simpler version. This is the code I used to present my SKView:
- (void)viewDidLoad {
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
SKScene *scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
回答2:
In moving from iPhone 5 or 6 to 4 there is a change in screen aspect ratio from 16:9 (5 and 6) to 4:3 (iPhone 4). Your options, without image distortion, are to either use SKSceneScaleModeAspectFill (which you are) or SKSceneScaleModeAspectFit. From Apple docs:
SKSceneScaleModeAspectFill "....This guarantees that the entire area of the view is filled but may cause parts of the scene to be cropped."
SKSceneScaleModeAspectFit "..... This guarantees that the entire scene is visible but may require letterboxing in the view."
I ran into a similar issue and recreated separate images for a 4:3 device (iPhone 4/iPad) because neither of the above 2 options gave me what I wanted.
回答3:
Try using proportions instead of actual sizes. All iOS devices have different widths and height.
Change this
leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - 230, yPoint);
To something like this
leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - self.frame.size.width / 2, yPoint);
I only can guess what it should do, but try changing this
int randomY = arc4random() % (675 - 175);
int yPoint = randomY + 175;
To this:
int randomY = arc4random() % (self.frame.size.height - self.frame.size.height / 4);
int yPoint = randomY + self.frame.size.height / 4;
Also i would recomend you to change these:
change those "30" and "470"
SKAction* action1 = [SKAction moveToX:leftArrow.position.x + 30 duration:0.5];
SKAction* action2 = [SKAction moveToX:leftArrow.position.x + 470 duration:1.5];
来源:https://stackoverflow.com/questions/30161987/dealing-with-different-screen-sizes-in-xcode