Как использовать пиксель-арт в приложении?
У меня есть приложение для iOS, которое использует набор спрайтов, и я готов добавить свои работы. Произведение искусства - пиксель-арт и по своей природе очень мало. Я пытаюсь найти лучший способ отобразить это так:
Все искусство имеет одинаковый размер, что означает, что один пиксель изображения занимает ровно столько же пикселей реального мира, как и все остальные изображения.
При попытке сделать текстуры более плавными, размытие отсутствует, что часто происходит при увеличении масштаба изображения.
Я попытался решить второй так:
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 (что должно работать должным образом), я думаю, вам все равно придется указывать рендереру не интерполировать пиксели, когда он выполняет масштабирование.