I created a Sprite Sheet with SpriteHelper. When I created a background in spritehelper (universal app), the picture size was 1920 x 1280. How to make backgrounds for all devices and all screens?
CGSize winSize = [CCDirector sharedDirector].winSize;
CCSpriteBatchNode *sprites_for_game;
sprites_for_game = [CCSpriteBatchNode batchNodeWithFile:#"sprite_UntitledSheet.png"];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:#"sprite_UntitledSheet.plist"];
[self addChild:sprites_for_game];
CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:#"background"];
sprite.position = ccp(winSize.width/2,winSize.height/2);
[sprites_for_game addChild:sprite];
iPhone Retina 3.5 inch http://pixs.ru/showimage/Snimokekra_9096412_10672667.png
iPhone Retina 4.0 inch http://pixs.ru/showimage/Snimokekra_8101239_10672678.png
who can help me?
Thanks
Well, it comes down to two options.
Option 1: Scale the image to fit the screen with the scale property like sprite.scale = 1.5f;. I would NOT recommend this as the image will look like garbage as you scale it up.
Option 2: Re-render the image at the higher resolutions and decide in your code which image to use based on your screen size. This is what I would recommend doing for better quality.
Related
Why does my app look different from the simulator when I run it on my real phone?
I am making a game using spritekit. When I test it in the iPhone 5 simulator, the size of the screen and the size of the images are exactly as I want them, but then when I run the program on my actual iPhone 5, the images show up too big, parts of the top and bottom of the screen are cut off, and the left and right of the screen don't extend all the way to the sides of the phone--there's a letterboxing effect from left to right on the screen.
All my images are named with #2x, so they should work fine with retina screens. Here's the code relating to screen size that I use when I initialize my SKScene:
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
scene.size = self.view.frame.size;
scene.scaleMode = SKSceneScaleModeAspectFill;
I've tried each of the available SKSceneScaleModes and none of them help--they each just give a different outcome that doesn't look right. I'm using AspectFill simply because that mode does work correctly in the simulator.
I've also tried sizing the screen like this, just as something to try, but that didn't help either:
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
CGRect screenRect = [[UIScreen mainScreen] bounds];
scene.size = screenRect.size;
Thanks in advance.
It was indeed due to the fact that the simulator was simulating ios 8 while my device was on ios 7. ios 8 automatically changes the coordinate system when you go into landscape mode (the native mode of my game) while ios 7 does not. The fix was simple once I figured that out--just detect which os the device is running, and, if it's lower than ios 8, swap the height and width dimensions of the screen:
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) {
CGSize fixedSize = CGSizeMake(screenRect.size.height, screenRect.size.width);
scene.size = fixedSize;
}
else
scene.size = self.view.frame.size;
I need to place a sprite at the bottom of the screen independently from resolution using cocos2d for iPhone, so that if a sprite is at the bottom on iPhone 5/5s, it will be at the bottom even on iPhone 4/4s.
The following code works on iPhone5/5s resolution, but not on the previous iPhone model:
ground1 = [CCSprite spriteWithImageNamed:#"ground1.png"];
ground1.position = ccp(self.contentSize.width/2,self.contentSize.height/2-259);
[self addChild:ground1];
What can I do?
CGSize size = [[CCDirector sharedDirector]viewSize];
ground1 = [CCSprite spriteWithImageNamed:#"ground1.png"];
ground1.position = ccp(size.width/2,[ground1 boundingBox].size.height/2);
[self addChild:ground1];
First of all you need the size of the view. In Cocos2D you get that value calling the CCDirector and getting its viewSize.
After that, you create the sprite as you did.
Now the important step is to position the sprite. Now you have your viewSize stored in 'size' so you get the X value by doing: size.width/2.
Now you have your sprite centered on X. Now let's position it over Y.
You want your sprite to be at the bottom. So you need to calculate the point as I show you in this picture:
So the Y value is exactly height/2 of the sprite's size. We can get this value by calling the method:[sprite boundingBox] that returns the size of the sprite.
In conclusion, we have our sprite centered on X (size.width/2) and at the bottom ([sprite boundingBox].size.height/2)
I use this code to make a snapshot of my Cocos2d game on iOs 6:
[CCDirector sharedDirector].nextDeltaTimeZero = YES;
CGSize winSize = [CCDirector sharedDirector].winSize;
CCRenderTexture* rtx;
rtx = [CCRenderTexture renderTextureWithWidth:winSize.width height:winSize.height];
[rtx begin];
[startNode visit];
[rtx end];
It works fine. But on iPhone 4 it returns a picture with size 320x480, whereas the screen is 640x960. How can I get it to return a sharper picture (640x960)?
Any help much appreciated!
Have you tried to log winSize in console ?
Does it display 640x960 ?
Do not mistake Screen pixel size and screen point size. Screen size is 640x960 on retina iPhone, but in point, it will always 320*480.
According to documentation, winSize return size in point.
Try this
CGSize winSize = [CCDirector sharedDirector]. winSizeInPixels;
Regards
I have a ViewController to which I applied the retina 3.5" form factor in the story board. The iOS iPhone 6.1 simulator also has the Retina configured.
When I try to position a UIImageView using SetFrame, its CGRect coordinates are in the non-retina form (i.e. when I position to 320x480, it goes to the bottom right instead of the middle of the screen):
[myImageView setFrame:CGRectMake(320, 480, myImageView.frame.size.width, myImageView.frame.size.height)];
[self.view addSubview:myImageView];
How to have CGRect coordinates for Retina when using SetFrame ?
Thanks.
The reason for this is because iOS uses points instead of pixels. This way, the same code will work on a retina and a non-retina screen. Therefore, when you set the location to (320,480) you are setting it to point (320,480) not pixel (320,480). This way, if the phone is non-retina, that point will end up being pixel (320, 480) and on retina, it will end up being pixel (640,960).
So what it looks like you want is:
[myImageView setFrame:CGRectMake(160, 240, myImageView.frame.size.width, myImageView.frame.size.height)];
[self.view addSubview:myImageView];
which will place the imageView's top-left corner in the same location on both retina and normal display.
To center a view:
CGFloat x = self.view.frame.size.width;
CGFloat h = self.view.frame.size.height;
[myImageView setCenter:CGPointMake(w/2, h/2)];
...
[self.view addSubview:myImageView];
CGRectMake needs a x,y,width,height.. X,y are the topleft of the view, so use 0,0,w,h for full frame views.
This is probably linked to another unsolved mystery of mine.
I'm drawing Orthographic 2d on iPhone, using real device and simulator. I'm trying to color my pixels a given color depending on how far they are from arbitrary point in pixelspace of 'A', which I pass in (hard code). I'm doing everything in Retina 960x640 resolution. I calculate distance from A to gl_FragCoord, and I color based on leaping between 2 colors with the 'max' being 300px distance.
When on simulator (with retina display) I need to give a center point of "460" pixels for screen midpoint X.. Y I give 160px, and I look for distance of '300'px.. to get the same effect on device I need center of 960X and distance of 150 to get the same results (interestingly, px 80 doesn't give the same results I want but 160 could be an overshoot on the original...)
Obviously a retina issue is at play. But where, and how, and how do I find and fix it?
I'm using:
glViewport(0, 0, 960.0f, 640.0f);
and:
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
And:
[self setView:[[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds]];
[(EAGLView *)[self view] setContentScaleFactor:2.0f];
You shouldn't hardcode "glViewport(0, 0, 960.0f, 640.0f);", setup the viewport this way:
glViewport(0, 0, framebufferWidth, framebufferHeight);
Also don't hardcode the content scale, you can findout the content scale with:
float contentScale = 1.0f;
if ([[UIScreen mainScreen] respondsToSelector:#selector(displayLinkWithTarget:selector:)]) {
contentScale = [[UIScreen mainScreen] scale];
}
About the pixel distance, since you want the distance to be the double with retina display, you can add an uniform to your shader with the content scale.
Now iOS devices can have multiple different screens, and a UIWindow can be placed in a non-main screen. In that case, you can use self.view.window.screen.scale to get current screen's scale dynamically.