如何强制从字典创建的 SKTextureAtlas 不修改纹理大小?
How to force SKTextureAtlas created from a dictionary to not modify textures size?
在我的项目中,纹理 是通过 PaintCode (paint-code).[=33= 提供的方法程序生成的]
然后我从使用这些方法生成的 UIImage
归档的字典中创建一个 SKTextureAtlas
:
myAtlas = SKTextureAtlas(dictionary: myTextures)
最后,使用 textureNamed
从 atlas 检索 textures:
var sprite1 = SKSpriteNode(texture:myAtlas.textureNamed("texture1"))
但显示的 节点 在 iPhone4S 模拟器上是双倍大小。在 iPhone 6 Plus 模拟器上大小为三倍。
似乎在初始化时,atlas 以设备分辨率计算图像。
但是生成的图像已经具有正确的大小,不需要更改。请参阅下面的绘制方法。
生成图片的说明如下:
<UIImage: 0x7f86cae56cd0>, {52, 52}
以及图集中对应贴图的描述:
<SKTexture> 'image1' (156 x 156)
此为 iPhone6 Plus,使用@3x 图片,这就是尺寸为 x3 的原因。
并且对于 iPhone 4S,使用 @2x 图像,如预期的那样:
<UIImage: 0x7d55dde0>, {52, 52}
<SKTexture> 'image1' (156 x 156)
最后,生成的 UIImage
的 scale
属性 设置为正确的设备分辨率:@2x (iPhone 4S) 为 2.0,@ 为 3.0 3x(iPhone 6 加)。
问题
那么如何避免图集调整图片大小呢?
绘制方法
PaintCode生成的绘图方法如下:
public class func imageOfCell(#frame: CGRect) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
StyleKit.drawCell(frame: frame)
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
更新 1
比较两种生成方法SKTextureAtlas
// Some test image
let testImage:UIImage...
// Atlas creation
var myTextures = [String:UIImage]()
myTextures["texture1"] = testImage
myAtlas = SKTextureAtlas(dictionary: myTextures)
// Create two textures from the same image
let texture1 = myAtlas.textureNamed("texture1")
let texture2 = SKTexture(image:testImage)
// Wrong display : node is oversized
var sprite1 = SKSpriteNode(texture:texture1)
// Correct display
var sprite2 = SKSpriteNode(texture:texture2)
似乎问题出在 SKTextureAtlas
来自字典,因为 SKSpriteNode
初始化不使用 scale 属性 来自 UIImage
正确调整节点大小。
控制台的描述如下:
- 纹理 1:''(84 x 84)
- 纹理 2:'texture1' (84 x 84)
texture2
想念一些data
!这可以解释为什么缺少 scale 信息来正确调整节点大小:
节点大小 = 纹理大小除以纹理比例。
更新 2
当 UIImage
的比例 属性 与 1 不同时出现问题。
所以可以使用下面的方法生成图片:
func imageOfCell(frame: CGRect, color:SKColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
var bezierPath = UIBezierPath(rect: frame)
color.setFill()
bezierPath.fill()
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
来自 UIGraphicsBeginImageContextWithOptions
、
的 scale
参数的文档
The scale factor to apply to the bitmap. If you specify a value of
0.0, the scale factor is set to the scale factor of the device’s main screen.
因此,如果您希望纹理在所有设备上都相同 "size",请将此值设置为 1.0。
编辑:
override func didMoveToView(view: SKView) {
let image = imageOfCell(CGRectMake(0, 0, 10, 10),scale:0)
let dict:[String:UIImage] = ["t1":image]
let texture = SKTextureAtlas(dictionary: dict)
let sprite1 = SKSpriteNode(texture: texture.textureNamed("t1"))
sprite1.position = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
addChild(sprite1)
println(sprite1.size)
// prints (30.0, 30.0) if scale = 0
// prints (10,0, 10,0) if scale = 1
}
func imageOfCell(frame: CGRect, scale:CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
var bezierPath = UIBezierPath(rect: frame)
UIColor.whiteColor().setFill()
bezierPath.fill()
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
问题来自使用 SKTextureAtlas(dictionary:)
初始化图集。
使用此方法创建的 SKTexture 不嵌入与图像的 scale 属性 相关的数据。因此,在 init(texture:)
创建 SKSpriteNode
期间,纹理中缺少比例信息导致选择纹理大小而不是图像大小。
纠正它的一种方法是在 SKSpriteNode
创建期间提供节点的大小:init(texture:size:)
在我的项目中,纹理 是通过 PaintCode (paint-code).[=33= 提供的方法程序生成的]
然后我从使用这些方法生成的 UIImage
归档的字典中创建一个 SKTextureAtlas
:
myAtlas = SKTextureAtlas(dictionary: myTextures)
最后,使用 textureNamed
从 atlas 检索 textures:
var sprite1 = SKSpriteNode(texture:myAtlas.textureNamed("texture1"))
但显示的 节点 在 iPhone4S 模拟器上是双倍大小。在 iPhone 6 Plus 模拟器上大小为三倍。
似乎在初始化时,atlas 以设备分辨率计算图像。 但是生成的图像已经具有正确的大小,不需要更改。请参阅下面的绘制方法。
生成图片的说明如下:
<UIImage: 0x7f86cae56cd0>, {52, 52}
以及图集中对应贴图的描述:
<SKTexture> 'image1' (156 x 156)
此为 iPhone6 Plus,使用@3x 图片,这就是尺寸为 x3 的原因。
并且对于 iPhone 4S,使用 @2x 图像,如预期的那样:
<UIImage: 0x7d55dde0>, {52, 52}
<SKTexture> 'image1' (156 x 156)
最后,生成的 UIImage
的 scale
属性 设置为正确的设备分辨率:@2x (iPhone 4S) 为 2.0,@ 为 3.0 3x(iPhone 6 加)。
问题
那么如何避免图集调整图片大小呢?
绘制方法
PaintCode生成的绘图方法如下:
public class func imageOfCell(#frame: CGRect) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
StyleKit.drawCell(frame: frame)
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
更新 1
比较两种生成方法SKTextureAtlas
// Some test image
let testImage:UIImage...
// Atlas creation
var myTextures = [String:UIImage]()
myTextures["texture1"] = testImage
myAtlas = SKTextureAtlas(dictionary: myTextures)
// Create two textures from the same image
let texture1 = myAtlas.textureNamed("texture1")
let texture2 = SKTexture(image:testImage)
// Wrong display : node is oversized
var sprite1 = SKSpriteNode(texture:texture1)
// Correct display
var sprite2 = SKSpriteNode(texture:texture2)
似乎问题出在 SKTextureAtlas
来自字典,因为 SKSpriteNode
初始化不使用 scale 属性 来自 UIImage
正确调整节点大小。
控制台的描述如下: - 纹理 1:''(84 x 84) - 纹理 2:'texture1' (84 x 84)
texture2
想念一些data
!这可以解释为什么缺少 scale 信息来正确调整节点大小:
节点大小 = 纹理大小除以纹理比例。
更新 2
当 UIImage
的比例 属性 与 1 不同时出现问题。
所以可以使用下面的方法生成图片:
func imageOfCell(frame: CGRect, color:SKColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
var bezierPath = UIBezierPath(rect: frame)
color.setFill()
bezierPath.fill()
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
来自 UIGraphicsBeginImageContextWithOptions
、
scale
参数的文档
The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
因此,如果您希望纹理在所有设备上都相同 "size",请将此值设置为 1.0。
编辑:
override func didMoveToView(view: SKView) {
let image = imageOfCell(CGRectMake(0, 0, 10, 10),scale:0)
let dict:[String:UIImage] = ["t1":image]
let texture = SKTextureAtlas(dictionary: dict)
let sprite1 = SKSpriteNode(texture: texture.textureNamed("t1"))
sprite1.position = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
addChild(sprite1)
println(sprite1.size)
// prints (30.0, 30.0) if scale = 0
// prints (10,0, 10,0) if scale = 1
}
func imageOfCell(frame: CGRect, scale:CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
var bezierPath = UIBezierPath(rect: frame)
UIColor.whiteColor().setFill()
bezierPath.fill()
let imageOfCell = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return imageOfCell
}
问题来自使用 SKTextureAtlas(dictionary:)
初始化图集。
使用此方法创建的 SKTexture 不嵌入与图像的 scale 属性 相关的数据。因此,在 init(texture:)
创建 SKSpriteNode
期间,纹理中缺少比例信息导致选择纹理大小而不是图像大小。
纠正它的一种方法是在 SKSpriteNode
创建期间提供节点的大小:init(texture:size:)