Sktexture Nearest Filtering Mode Doesn't Work (Making Pixel Art)

SKTexture nearest filtering mode doesn't work (Making Pixel Art)

UPDATE:
SKTexture nearest filtering mode is now working in Xcode 7 GM. No need to manually scale images as I've suggested below.


I am experiencing this same problem in Xcode 7 beta 5 with beta iOS 9 ; the Nearest filtering mode is seemingly ignored. In my project, scaling with nearest-neighbor scaling was previously working in Xcode 6 on iOS 8.

In the event that the bug is not resolved before the final release of iOS 9 I am pre-scaling images before I place them in their respective atlases.

To do this I wrote a simple python script to recursively find png files and scale them using imagmagick.

If you don’t have imagemagick installed, you can install it using macports like so:

sudo port install ImageMagick

If you have homebrew it looks like this:

brew install imagemagick

I just place this script (below) in a file called imgscaler.py within the directory above my atlas files (which I want to scale by 400% in my case) and kick it off from the terminal:

python imgscaler.py

The script looks like this:

import subprocess
import os
import sys
import fnmatch

def main():
execution_folder_name = os.getcwd()
file_extension_name = "png"

#
# Collect names of files that will be manipulated
matches = []
for root, dirNames, fileNames in os.walk(execution_folder_name):
for filename in fnmatch.filter(fileNames, '*.' + file_extension_name):
full_name = os.path.join(root, filename)
matches.append(full_name)

scale_percentage = "400"

if not __query_yes_no("This script will scale images by " + scale_percentage + "% recursively from directory " + execution_folder_name + ". Proceed?"):
return

#
# Scale the images
for match in matches:
execution_str = "convert " + match + " -interpolate Nearest -filter point -resize " + scale_percentage + "% " + match + "\n"
sys.stdout.write(execution_str)
__run_command(execution_str)

def __run_command(input_cmd):
"""Runs a command on the terminal, and returns the output in a string array.
"""
process = subprocess.Popen(input_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
output = []
while True:
line = process.stdout.readline()
if line != '':
output.append(line)
else:
break

return output

def __query_yes_no(question, default="yes"):
"""Asks a yes or no question, returns a true is answered "yes".
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)

while True:
sys.stdout.write(question + prompt)
sys.stdout.flush()
choice = raw_input().lower()
if default is not None and choice == '':
sys.stdout.write(default)
sys.stdout.write('\n')
sys.stdout.flush()
return valid[default]
elif choice in valid:
sys.stdout.write(choice)
sys.stdout.write('\n')
sys.stdout.flush()
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
sys.stdout.flush()

main()

Change scale_percentage to whatever percentage you want to scale by.

BTW, I am guessing this scaling issue will eventually get resolved. I’m currently updating my code with this assumption in mind. This is just a bandaid in the event the fix to nearest-neighbor scaling in SpriteKit arrives later than iOS 9.0.

How to use pixel art in an app?

I've solved the problem...but its really a hack. I have a SKScene which is the parent node to all of the "trees" (SKSpriteNodes). This scene will be adding multiple trees to itself. At first I thought that this was some sort of problem because if I only added one tree, it would display the image correctly. The answer to this question led me to believe that I would need to programmatically create a SKTextureAtlas singleton in the (the texture is in a SKTextureAtlas) and pass it to the tree class to get the texture from on an init method. I made a property in the SKScene to hold the texture atlas so that I could pass it to the tree class every time I made a new one. I tried loading the texture from texture atlas (in the tree class) using the textureNamed: method. This still did not work. I switched back to loading the texture with SKTexture's textureWithImageNamed: method and it worked. Further more I changed to code back so that the tree subclass would not be sent the SKTextureAtlas singleton at all and it still worked.

In the SKScene I get the texture atlas using:

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

and set the return value to be the SKTextureAtlas property described above. I thought that maybe the atlas just had to initialized at some point in the code, so I tried this:

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

and the following alone on one line:

[SKTextureAtlas atlasNamed:@"Textures"]

but neither worked. Apparently I need to have a property in my tree's parent class which is the SKTextureAtlas which holds the texture which the tree uses without any reference to a SKTextureAtlas whatsoever... Is this a glitch or something? It's working now but it feels like a hack.



Related Topics



Leave a reply



Submit