Прежде чем сокращать код, надо разобраться что он делает. Ниже программа печатающая что происходит внутри SpriteAnimation
:
#include <iostream>
using namespace std;
int x = 1, y = 1; //номера спрайтов по оси x и y
float spritesheetsize = 0.1152, spritesize = 0.96;
//spritesheetsize - размер спрайтлиста (1152 пикселя в ширину и высоту)
//spritesize - размер одного спрайта (96 пикселей в ширину и высоту)
float scale = spritesize / spritesheetsize * 0.1 * 0.1;
//scale - масштабирование под нужный размер отображение
float tcordLeft,
tcordUp,
tcordRight,
tcordDown;
//текстурные координаты для отображение нужного спрайта из спрайтлиста
void dump() {
cout << ", x = " << x
<< ", y = " << y
<< ", tcordLeft = " << tcordLeft
<< ", tcordUp = " << tcordUp
<< ", tcordRight = " << tcordRight
<< ", tcordDown = " << tcordDown
;
}
int SpriteAnimation()
{
cout << "SpriteAnimation, x = " << x << ", y = " << y;
if (x + y != 2)
{
if (x <= 12)
{
tcordLeft = (x - 1) * scale,
tcordUp = (y - 1) * scale,
tcordRight = x * scale,
tcordDown = y * scale;
dump();
}
else
{
x = 0;
if (y == 12)
{
tcordLeft = (x - 1) * scale,
tcordUp = (y - 1) * scale,
tcordRight = x * scale,
tcordDown = y * scale;
dump();
y = 1;
}
else
{
y++;
}
}
}
else
{
tcordLeft = scale - scale,
tcordUp = scale - scale,
tcordRight = scale,
tcordDown = scale;
dump();
}
x++;
cout << '\n';
return 0;
}
int main() {
for (int i = 0; i < 200; ++i) {
SpriteAnimation();
}
}
Каждый раз функция обновляет координаты спрайта, но иногда пропускает итерацию. В предпоследней строке выдержки координаты спрайта не меняются. Если у нас анимация, она будет заикаться:
SpriteAnimation, x = 1, y = 1, x = 1, y = 1, tcordLeft = 0, tcordUp = 0, tcordRight = 0.0833333, tcordDown = 0.0833333
SpriteAnimation, x = 2, y = 1, x = 2, y = 1, tcordLeft = 0.0833333, tcordUp = 0, tcordRight = 0.166667, tcordDown = 0.0833333
SpriteAnimation, x = 3, y = 1, x = 3, y = 1, tcordLeft = 0.166667, tcordUp = 0, tcordRight = 0.25, tcordDown = 0.0833333
SpriteAnimation, x = 4, y = 1, x = 4, y = 1, tcordLeft = 0.25, tcordUp = 0, tcordRight = 0.333333, tcordDown = 0.0833333
SpriteAnimation, x = 5, y = 1, x = 5, y = 1, tcordLeft = 0.333333, tcordUp = 0, tcordRight = 0.416667, tcordDown = 0.0833333
SpriteAnimation, x = 6, y = 1, x = 6, y = 1, tcordLeft = 0.416667, tcordUp = 0, tcordRight = 0.5, tcordDown = 0.0833333
SpriteAnimation, x = 7, y = 1, x = 7, y = 1, tcordLeft = 0.5, tcordUp = 0, tcordRight = 0.583333, tcordDown = 0.0833333
SpriteAnimation, x = 8, y = 1, x = 8, y = 1, tcordLeft = 0.583333, tcordUp = 0, tcordRight = 0.666667, tcordDown = 0.0833333
SpriteAnimation, x = 9, y = 1, x = 9, y = 1, tcordLeft = 0.666667, tcordUp = 0, tcordRight = 0.75, tcordDown = 0.0833333
SpriteAnimation, x = 10, y = 1, x = 10, y = 1, tcordLeft = 0.75, tcordUp = 0, tcordRight = 0.833333, tcordDown = 0.0833333
SpriteAnimation, x = 11, y = 1, x = 11, y = 1, tcordLeft = 0.833333, tcordUp = 0, tcordRight = 0.916667, tcordDown = 0.0833333
SpriteAnimation, x = 12, y = 1, x = 12, y = 1, tcordLeft = 0.916667, tcordUp = 0, tcordRight = 1, tcordDown = 0.0833333
SpriteAnimation, x = 13, y = 1
SpriteAnimation, x = 1, y = 2, x = 1, y = 2, tcordLeft = 0, tcordUp = 0.0833333, tcordRight = 0.0833333, tcordDown = 0.166667
...
Когда мы добежали до края листа и переходим на его начало, вместо заикания обращение к отрицательным координатам. Средняя строка:
...
SpriteAnimation, x = 11, y = 12, x = 11, y = 12, tcordLeft = 0.833333, tcordUp = 0.916667, tcordRight = 0.916667, tcordDown = 1
SpriteAnimation, x = 12, y = 12, x = 12, y = 12, tcordLeft = 0.916667, tcordUp = 0.916667, tcordRight = 1, tcordDown = 1
SpriteAnimation, x = 13, y = 12, x = 0, y = 12, tcordLeft = -0.0833333, tcordUp = 0.916667, tcordRight = 0, tcordDown = 1
SpriteAnimation, x = 1, y = 1, x = 1, y = 1, tcordLeft = 0, tcordUp = 0, tcordRight = 0.0833333, tcordDown = 0.0833333
SpriteAnimation, x = 2, y = 1, x = 2, y = 1, tcordLeft = 0.0833333, tcordUp = 0, tcordRight = 0.166667, tcordDown = 0.0833333
...
Код пытается перебирать спрайты на атласе и, в общем, делает это довольно успешно. Но есть две ошибки, которые надо исправить. Мне показалось проще не исправлять ваш код, а написать новый. Получилось так:
#include <iostream>
using namespace std;
const int atlas_size = 1152;
const int sprite_size = 96;
const float scale = sprite_size / static_cast<float>(atlas_size);
const int n = atlas_size / sprite_size;
int x = 0; // номер спрайта по горизонтали
int y = 0; // номер спрайта по вертикали
//текстурные координаты для отображения нужного спрайта из спрайтлиста
float tcordLeft;
float tcordUp;
float tcordRight;
float tcordDown;
void dump() {
cout << ", x = " << scale * x
<< ", y = " << scale * y
<< ", tcordLeft = " << tcordLeft
<< ", tcordUp = " << tcordUp
<< ", tcordRight = " << tcordRight
<< ", tcordDown = " << tcordDown
;
}
void SpriteAnimation() {
cout << "SpriteAnimation, x = " << x << ", y = " << y;
tcordLeft = scale * x ;
tcordUp = scale * y ;
tcordRight = scale * (x + 1);
tcordDown = scale * (y + 1);
dump();
++x;
if (x >= n) {
x = 0;
++y;
if (y >= n) {
y = 0;
}
}
cout << '\n';
}
int main() {
for (int i = 0; i < 200; ++i) {
SpriteAnimation();
}
}
Если убрать всю отладку:
const int atlas_size = 1152;
const int sprite_size = 96;
const float scale = sprite_size / static_cast<float>(atlas_size);
const int n = atlas_size / sprite_size;
int x = 0; // номер спрайта по горизонтали
int y = 0; // номер спрайта по вертикали
//текстурные координаты для отображения нужного спрайта из спрайтлиста
float tcordLeft;
float tcordUp;
float tcordRight;
float tcordDown;
void SpriteAnimation() {
tcordLeft = scale * x ;
tcordUp = scale * y ;
tcordRight = scale * (x + 1);
tcordDown = scale * (y + 1);
++x;
if (x >= n) {
x = 0;
++y;
if (y >= n) {
y = 0;
}
}
}
Не удержусь от соблазна показать ещё один короткий код. Он, кажется, довольный быстрый. В среднем 1.08(3) проверки и 0.9930(5) сложений на итерацию:
const int atlas_size = 1152;
const int sprite_size = 96;
const float scale = sprite_size / static_cast<float>(atlas_size);
//текстурные координаты для отображения нужного спрайта из спрайтлиста
float tcordLeft = 0;
float tcordUp = 0;
float tcordRight = scale;
float tcordDown = scale;
void SpriteAnimation() {
if (tcordRight < 1 - scale / 2) {
tcordLeft = tcordRight;
tcordRight += scale;
} else {
tcordLeft = 0;
tcordRight = scale;
if (tcordDown < 1 - scale / 2) {
tcordUp = tcordDown;
tcordDown += scale;
} else {
tcordUp = 0;
tcordDown = scale;
}
}
}