## Question about scaling sprites

The Partridge Family were neither partridges nor a family. Discuss.
WilsonHuang
Posts: 22
Joined: February 13th, 2019, 3:23 am

### Question about scaling sprites

After learning Intermediate Tutorial 12 [Animated Sprite Character]. I want to add the scaling effect to the sprite, which you can enlarge or shrink sprites. My code seems okay when enlarge the sprites. However, I have invisible cover when I shrink the sprites. How do I fix it?

Here is my code:

Code: Select all

``````#include "Graphics.h"
#include "Colors.h"
#include <assert.h>
#include <math.h>
namespace SpriteEffect
{
class Scale
{
public:
Scale(float scale = 1.0f)
:scale(scale)
{
assert(scale > 0.0f);
}
void operator()(Color sourceColor, int x, int y, Graphics& gfx)
{
if (sourceColor != chroma)
{
for (int dy = 0; dy < (int)ceil(scale); dy++)
{
for (int dx = 0; dx < (int)ceil(scale); dx++)
{
int resultX = (int)ceil(x * scale + dx);
int resultY = (int)ceil(y * scale + dy);

if (resultX < 0)
{
resultX = 0;
}
if (resultY < 0)
{
resultY = 0;
}

if (resultX >= gfx.ScreenWidth)
{
resultX = gfx.ScreenWidth - 1;
}
if (resultY >= gfx.ScreenHeight)
{
resultY = gfx.ScreenHeight - 1;
}

gfx.PutPixel(resultX, resultY, sourceColor);
}
}
}
}
private:
Color chroma = Colors::Magenta;
float scale;
};
}
``````
Usage:

Code: Select all

``gfx.DrawSprite(position.x, position.y, frames[currentFrame], surface, SpriteEffect::Scale(0.9f));``
Invisible Cover.png

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

Code: Select all

``````scale = .9f;
for (int dy = 0; dy < (int)ceil(.9f); dy++)
{
for (int dx = 0; dx < (int)ceil(.9f); dx++)
``````
Does this help?
Basically, you are only iterating from 0 to 1 ( ceil( .9f ) = 1.f ).

Your code works for scaling up because the ratio for the sprite pixel to screen pixel is 2:1 or something like that, so looping 2x2 for a scale factor of 2.f would work. For minification, you'd need to skip over some sprite pixels for each screen pixel. In order for this to work using an effect, your effect class would need more information. Basically, while magnification works, scaling is more of a transformation than a visual effect.

The 3D Fundamentals tutorials covers transformations.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

AleksiyCODE
Posts: 16
Joined: September 21st, 2019, 8:47 pm

### Re: Question about scaling sprites

Well, i made a quick (shitty) animated sprite tester for my friend, and there is simple scaling built in (arrow keys change animation playback speed and size)
https://gitlab.com/AleksiyCODE/st
you may be able to get some ideas from there (but the code is shit)
I like ass

WilsonHuang
Posts: 22
Joined: February 13th, 2019, 3:23 am

### Re: Question about scaling sprites

AleksiyCODE wrote:
October 9th, 2019, 7:17 pm
Well, i made a quick (shitty) animated sprite tester for my friend, and there is simple scaling built in (arrow keys change animation playback speed and size)
https://gitlab.com/AleksiyCODE/st
you may be able to get some ideas from there (but the code is shit)
Thanks, I'll give it a look!

WilsonHuang
Posts: 22
Joined: February 13th, 2019, 3:23 am

### Re: Question about scaling sprites

albinopapa wrote:
October 9th, 2019, 5:14 am

Code: Select all

``````scale = .9f;
for (int dy = 0; dy < (int)ceil(.9f); dy++)
{
for (int dx = 0; dx < (int)ceil(.9f); dx++)
``````
Does this help?
Basically, you are only iterating from 0 to 1 ( ceil( .9f ) = 1.f ).

Your code works for scaling up because the ratio for the sprite pixel to screen pixel is 2:1 or something like that, so looping 2x2 for a scale factor of 2.f would work. For minification, you'd need to skip over some sprite pixels for each screen pixel. In order for this to work using an effect, your effect class would need more information. Basically, while magnification works, scaling is more of a transformation than a visual effect.

The 3D Fundamentals tutorials covers transformations.
I think I found the problem. The problem is in the DrawSprite function.
In DrawSprite function, there are code to check whether the sprite is outside the screen and clip the sprite.

Code: Select all

``````		//top-left
if (x < clip.left)
{
source.left += clip.left - x;
x = clip.left;
}
if (y < clip.top)
{
source.top += clip.top - y;
y = clip.top;
}

//bottom-right
if (x + source.GetWidth() > clip.right)
{
source.right -= x + source.GetWidth() - clip.right;
}
if (y + source.GetHeight() > clip.bottom)
{
source.bottom -= y + source.GetHeight() - clip.bottom;
}
``````
The original sprite is out of the screen and being clipped. This effects the scale down version (also be clipped)
It seems I need to do some modification to the DrawSprite function to make the transformation works.
Also, just as you said, " scaling is more of a transformation than a visual effect". I may move the transformation code to the other place.

BTW, which episode of 3D Fundamentals tutorials covers transformations? I'll take a look Thanks!

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

Well, whoops, it's the Advanced series.

Transformations/Scaling/Translation
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

Here's my implementation. The clipping algorithm is slightly different than chili's current implementation, but this is how he taught it in the old series, not sure why he changed it.
Spoiler:
I put the scale parameter at the end, so it could be defaulted. This makes it so changes don't have to be made for routines you've already written and don't need scaling.

NOTE: This is just the final DrawSprite function, you'll need to add the float scale parameter to each of the DrawSprite functions to get this to work.

NOTE2: Corrected code in this post.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

sprite_scaling.png
Here's a sample of the Link sprite scaled from 10% to 200% ( incremented by 10% each time ).
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

A more generic solution would be to use the 3D Fundamentals framework and method. In that, you create a quadrangle, apply transforms to the vertices ( translation, rotation, scaling, etc... ) and interpolate between the vertices pixel to pixel.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 3982
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

### Re: Question about scaling sprites

Well, there's an error in my code. It assumes a single sprite, not a sprite sheet.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com