Как использовать пиксель-арт в приложении?

У меня есть приложение для iOS, которое использует набор спрайтов, и я готов добавить свои работы. Произведение искусства - пиксель-арт и по своей природе очень мало. Я пытаюсь найти лучший способ отобразить это так:

  1. Все искусство имеет одинаковый размер, что означает, что один пиксель изображения занимает ровно столько же пикселей реального мира, как и все остальные изображения.

  2. При попытке сделать текстуры более плавными, размытие отсутствует, что часто происходит при увеличении масштаба изображения.

Я попытался решить второй так:

self = [super init];
if(self){
    self.size=size;
    self.texture = [SKTexture textureWithImageNamed:@"ForestTree1.png"];
    self.texture.filteringMode = SKTextureFilteringNearest;

    [self.texture size];
}
return self; 

Приведенный выше код находится в инициализации SKSpriteNode, который будет иметь текстуру.

Это мое оригинальное изображение (увеличено для удобства):

Проблема в том, что мой результат всегда выглядит так:

это размыто

(Нижняя часть ствола со смещением не является частью этого вопроса.) Я не использую размытие в движении или что-то подобное. Я не уверен, почему это не отображается правильно.

Правка 1: я не упомянул выше, что деревья постоянно анимировались, когда делались скриншоты. Когда они еще, они выглядят так:

На изображении выше два дерева перекрываются с одним переворачиванием, вызванным из-за ошибки, которая будет исправлена ​​позже. Мой вопрос сейчас, как я могу предотвратить размывание изображения во время анимации?

Изменить 2:

Я добавляю несколько экземпляров дерева, каждый из которых загружает одну и ту же текстуру. Я знаю, что это не имеет ничего общего с анимацией, потому что я изменил код, добавив только одно дерево и анимировав его, и он был идеально пикселизирован.

4 ответа

Решение

Я решил проблему... но это действительно взломать. у меня есть SKScene который является родительским узлом для всех "деревьев" (SKSpriteNodes). Эта сцена будет добавлять несколько деревьев к себе. Сначала я подумал, что это какая-то проблема, потому что, если я добавлю только одно дерево, оно будет правильно отображать изображение. Ответ на этот вопрос заставил меня поверить, что мне нужно будет программно создать SKTextureAtlas синглтон в (текстура находится в SKTextureAtlas) и передайте его классу дерева для получения текстуры из метода init. Я сделал собственность в SKScene держать атлас текстуры, чтобы я мог передавать его классу дерева каждый раз, когда создавал новый. Я попытался загрузить текстуру из текстурного атласа (в классе дерева) с помощью метода textureNamed:. Это все еще не сработало. Я переключился обратно на загрузку текстуры с помощью метода SKTexture textureWithImageNamed: и все заработало . Более того, я изменил код обратно, чтобы подкласс дерева не был отправлен SKTextureAtlas Синглтон вообще, и он все еще работал.

в SKScene Я получаю атлас текстуры используя:

[SKTextureAtlas atlasNamed:@"Textures"]; //Textures is the atlas name.

и установите возвращаемое значение, чтобы быть SKTextureAtlas свойство описано выше. Я подумал, что, возможно, атлас просто нужно было инициализировать в какой-то момент в коде, поэтому я попробовал это:

SKTextureAtlas *myAtlas = [SKTextureAtlas atlasNamed:@"Textures"];

и только одно на одной строке:

[SKTextureAtlas atlasNamed:@"Textures"]

но ни один не работал. Очевидно, мне нужно иметь свойство в родительском классе моего дерева, которое является SKTextureAtlas которая содержит текстуру, которую использует дерево без какой-либо ссылки на SKTextureAtlas что бы там ни было... Это глюк или что-то? Это работает сейчас, но похоже на взлом.

Вам необходимо использовать "ближайшую" фильтрацию:

self.texture.filteringMode = SKTextureFilteringNearest;
[self setScaleMode:SKSceneScaleModeAspectFill];

SKTexture* texture = [SKTexture textureWithImageNamed:@"image"];
[texture setFilteringMode:SKTextureFilteringNearest];

SKSpriteNode* imageNode = [SKSpriteNode spriteNodeWithTexture:texture];
[self addChild:imageNode];

Отлично работает для меня Там нет размытия с анимацией

Пиксели на вашем изображении должны идеально соответствовать пикселям на экране.

Если ваше изображение имеет размер 100x100 и вы выводите его на весь экран размером 105x105, оно выполнит интерполяцию, чтобы выяснить, как это сделать.

Если вы отображаете его с масштабированным разрешением, кратным 2 (что должно работать должным образом), я думаю, вам все равно придется указывать рендереру не интерполировать пиксели, когда он выполняет масштабирование.

Другие вопросы по тегам