在 SKSpriteNode 上叠加两个纹理
Superimpose two textures on an SKSpriteNode
我想实现这个动图的效果
目前我使用一系列 ~7 png 图像来执行此操作,这些图像具有红色背景和一条白线,这些图像通过带有 SKAction 的 sprite 进行动画处理。
我还想对 sprite 添加一些其他内容,这些内容会根据情况而变化,而且我想用多种颜色重复这一点。
这导致:6 种颜色、7 种发光效果、5 种边缘效果和 4 种边角效果导致我需要创建和存储 136 种纹理组合。
我觉得在设置 sprite 的纹理时必须有一种方法可以将 png 与透明背景叠加在一起,但我似乎无法在任何地方找到这样做的方法。
这是否可能,以便我可以将资产数量减少到 22 个,或者我是否必须全部制作 136 个并在逻辑中构建 class 来决定使用哪个?
我想要我的游戏有这样的效果,我尝试了很多选项。我尝试使用粒子来提高性能,但甚至无法接近。我知道你可以用着色器来完成它,但我没有走那条路,在 iOS 12 着色器中无论如何都不会支持 Open GL。最后我选择了 CropNodes。
这是我的眩光图像,很难看清,因为它是略微透明的白色图像。
这是我使用 CropNodes 得到的结果
class Glare: SKSpriteNode {
var glare = SKSpriteNode()
private var cropNode = SKCropNode()
init(color: UIColor, size: CGSize) {
super.init(texture: nil, color: color, size: size)
alpha = 0.7
zPosition = 10
setupGlare()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupGlare() {
let buffer: CGFloat = 10
let mask = SKSpriteNode(texture: nil, color: .black, size: self.size)
let texture = SKTextureAtlas(named: "Sprites").textureNamed("glare")
glare = SKSpriteNode(texture: texture)
glare.position = CGPoint(x: 0 - (self.size.width / 2 + buffer), y: self.size.height / 2 + buffer)
glare.setScale(3.50)
glare.zPosition = 1
cropNode.zPosition = 2
cropNode.maskNode = mask
cropNode.addChild(glare)
let random = Double(CGFloat.random(min: 0, max: 1))
let pause = SKAction.wait(forDuration: random)
let move = SKAction.moveBy(x: self.size.width + buffer * 2, y: 0 - (self.size.height + buffer * 2), duration: 0.5)
let wait = SKAction.wait(forDuration: 1.0)
let reset = SKAction.moveBy(x: 0 - (self.size.width + buffer * 2), y: self.size.height + buffer * 2, duration: 0.0)
let seq = SKAction.sequence([move, wait, reset])
let repeater = SKAction.repeatForever(seq)
let repeaterSeq = SKAction.sequence([pause, repeater])
glare.run(repeaterSeq)
}
func showGlare(texture: SKTexture) {
let mask = SKSpriteNode(texture: texture)
cropNode.maskNode = mask
glare.isHidden = false
if cropNode.parent == nil { self.addChild(cropNode)}
}
func hideGlare() {
glare.isHidden = true
//remove cropnode from the node tree
cropNode.removeFromParent()
}
}
然后在我的 GameScene 中...
我将眩光添加到眩光层,但这不是必需的。我也会在游戏加载时进行检查,并提前为所有 15 个插槽创建眩光并将它们放入一个数组中。这样我就不必即时创建它们,我可以随时打开插槽 10,也可以将其关闭。
private var glares = [Glare]()
let glare = Glare(color: .clear, size: CGSize(width: kSymbolSize, height: kSymbolSize))
glare.position = CGPoint(x: (CGFloat(x - 1) * kSymbolSize) + (kSymbolSize / 2), y: 0 - (CGFloat(y) * kSymbolSize) + (kSymbolSize / 2))
glare.zPosition = 100
glareLayer.addChild(glare)
glares.append(glare)
当我想在插槽上显示眩光时
EDIT texture here for you would just be a blank square texture the size of your tile.
glares[index].showGlare(texture: symbol.texture!)
想隐藏的时候
glares[index].hideGlare()
我想实现这个动图的效果
目前我使用一系列 ~7 png 图像来执行此操作,这些图像具有红色背景和一条白线,这些图像通过带有 SKAction 的 sprite 进行动画处理。
我还想对 sprite 添加一些其他内容,这些内容会根据情况而变化,而且我想用多种颜色重复这一点。 这导致:6 种颜色、7 种发光效果、5 种边缘效果和 4 种边角效果导致我需要创建和存储 136 种纹理组合。
我觉得在设置 sprite 的纹理时必须有一种方法可以将 png 与透明背景叠加在一起,但我似乎无法在任何地方找到这样做的方法。
这是否可能,以便我可以将资产数量减少到 22 个,或者我是否必须全部制作 136 个并在逻辑中构建 class 来决定使用哪个?
我想要我的游戏有这样的效果,我尝试了很多选项。我尝试使用粒子来提高性能,但甚至无法接近。我知道你可以用着色器来完成它,但我没有走那条路,在 iOS 12 着色器中无论如何都不会支持 Open GL。最后我选择了 CropNodes。
这是我的眩光图像,很难看清,因为它是略微透明的白色图像。
这是我使用 CropNodes 得到的结果
class Glare: SKSpriteNode {
var glare = SKSpriteNode()
private var cropNode = SKCropNode()
init(color: UIColor, size: CGSize) {
super.init(texture: nil, color: color, size: size)
alpha = 0.7
zPosition = 10
setupGlare()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupGlare() {
let buffer: CGFloat = 10
let mask = SKSpriteNode(texture: nil, color: .black, size: self.size)
let texture = SKTextureAtlas(named: "Sprites").textureNamed("glare")
glare = SKSpriteNode(texture: texture)
glare.position = CGPoint(x: 0 - (self.size.width / 2 + buffer), y: self.size.height / 2 + buffer)
glare.setScale(3.50)
glare.zPosition = 1
cropNode.zPosition = 2
cropNode.maskNode = mask
cropNode.addChild(glare)
let random = Double(CGFloat.random(min: 0, max: 1))
let pause = SKAction.wait(forDuration: random)
let move = SKAction.moveBy(x: self.size.width + buffer * 2, y: 0 - (self.size.height + buffer * 2), duration: 0.5)
let wait = SKAction.wait(forDuration: 1.0)
let reset = SKAction.moveBy(x: 0 - (self.size.width + buffer * 2), y: self.size.height + buffer * 2, duration: 0.0)
let seq = SKAction.sequence([move, wait, reset])
let repeater = SKAction.repeatForever(seq)
let repeaterSeq = SKAction.sequence([pause, repeater])
glare.run(repeaterSeq)
}
func showGlare(texture: SKTexture) {
let mask = SKSpriteNode(texture: texture)
cropNode.maskNode = mask
glare.isHidden = false
if cropNode.parent == nil { self.addChild(cropNode)}
}
func hideGlare() {
glare.isHidden = true
//remove cropnode from the node tree
cropNode.removeFromParent()
}
}
然后在我的 GameScene 中...
我将眩光添加到眩光层,但这不是必需的。我也会在游戏加载时进行检查,并提前为所有 15 个插槽创建眩光并将它们放入一个数组中。这样我就不必即时创建它们,我可以随时打开插槽 10,也可以将其关闭。
private var glares = [Glare]()
let glare = Glare(color: .clear, size: CGSize(width: kSymbolSize, height: kSymbolSize))
glare.position = CGPoint(x: (CGFloat(x - 1) * kSymbolSize) + (kSymbolSize / 2), y: 0 - (CGFloat(y) * kSymbolSize) + (kSymbolSize / 2))
glare.zPosition = 100
glareLayer.addChild(glare)
glares.append(glare)
当我想在插槽上显示眩光时
EDIT texture here for you would just be a blank square texture the size of your tile.
glares[index].showGlare(texture: symbol.texture!)
想隐藏的时候
glares[index].hideGlare()