I want to create a sprite from a image with different dimensions from the image. For example image.png is 200x200, and I want to create a sprite of 100x100 with the same image resized.
I don’t want to use setScale (0.5);
I want the sprite with size 100x100 and scale 1.0;
No problem if I use setScale in the middle of the process to resize my Image/Sprite. But the final sprite I want scale 1.0, and the image in memory is 100x100, to avoid scaling.
Hi hzlov, thanks for the answer. But this doesn’t solve my problem.
What I want is the real image in a different size, Avoiding scaling the image, and therefore improving the performance.
If you have an image scaled as as child of another node, the image is still scaled.
To clarify. What I want is as if I had read a 100x100 image of the disk. And not a 200x200 and scaling it. Because in this second way you lose performance.
Problem solved. I’ve used RenderTexture to create a new Sprite from the original resized.
In this way, my game has all the final images in the perfect size to fit any screen, without scaling them, and the performance has been improved a lot. And I don’t need different sizes of the images, only one with big resolution.
RenderTexture can also be used to solve problem if anyone is having problem of performance when rotating big images, or other kind of slow rendering.
Here an example for background image, of course you have to create a class to automate this, not implementing in each image:
// Screen real dimensions
auto vSize = Director::getInstance()->getVisibleSize();
auto vWidth = vSize.width;
auto vHeight = vSize.height;
// Original image
auto backOrig = Sprite::create( “back_3200x2000.png” );
auto oWidth = backOrig->getContentSize().width;
auto oHeight = backOrig->getContentSize().height;
backOrig->setFlippedY( true );
backOrig->setScale( vWidth / oWidth, vHeight / oHeight ); // backOrig scaled to screen size
backOrig->setPosition( vWidth / 2, vHeight / 2 );
// Create new texture with background in the exact size of the screen
auto renderTexture = RenderTexture::create( vWidth, vHeight, Texture2D::PixelFormat::RGBA8888 );
renderTexture->begin();
backOrig->visit();
renderTexture->end();
// Create new Sprite without scale, which perfoms much better
auto backOk = Sprite::createWithTexture( renderTexture->getSprite()->getTexture() );
backOk->setPosition( vWidth / 2, vHeight / 2 );
addChild( backOk );
so?
Why doing this resize in real time? if you know that you will need to scale down an art asset, just do it offline in the “cooking” stage. It makes no sense to ship a game with an asset which you will always process in the same way (scaling down) instead of shipping it with an already scaled down asset…
“I do not understand why are you doing this in real time. Why not give directly an image of 100x100 in your case?”
Because. I would have to have one image for each screen size, or some image sizes, scale them, and lose performance.
“So instead of setScale and drawing directly to screen, you setScale and draw it to RenderTexture, does this profit any performance?”
If you use set scale in the Sprite that is added to scene, it is scaled In every frame rendering, so it take more time to render. I’ve tested in a S3 mini and the difference is enormous.
“Why doing this resize in real time? if you know that you will need to scale down an art asset, just do it offline in the “cooking” stage. It makes no sense to ship a game with an asset which you will always process in the same way (scaling down) instead of shipping it with an already scaled down asset…”
The scale down, is to scale to the EXACT size of the device. And devices have different sizes…
Yes. To gain performance I don’t use it. I resize all the images proportionally to visibleSize. This method is only useful if you are having problems with performance. For example, big images with alpha in slow devices.
Of course, I also have methods to position the images proportionally.