SKCropNode and sizing, SpriteKit Adventures pt2
In the first post I found a nice way to add my fuelGauge in the upper left section of the screen. Now let's try to animate that fuel so it reflects our consumption.
History
If you are interested in how we got here, go here to check out theFirst Post.If you are however up to speed, let's get to it!
Our journey begins!
Like I mentioned in the description, my idea is to add theSKCropNodeso I can "animate" fuel consumption by moving it up and down. I found this post byPaul Hudsonwhich explains it really well.
So, I will place a base gauge first, then on top if that, anSKCropNodewhich will crop the fuel amount.
// MARK: Fuel Gauge Base (this is basically the gauge without the bright green fuel texture)-------------------------------
letfuelGaugeBase=SKSpriteNode()
fuelGaugeBase.size=CGSize(width:fuelGaugeHeight/23,height:fuelGaugeHeight)
fuelGaugeBase.position=CGPoint(x:16,y:playableArea.maxY-fuelGaugeHeight/1.5)
fuelGaugeBase.texture=SKTexture(imageNamed:"fuelGaugeBase")
addChild(fuelGaugeBase)
// ------------------------------------------------------------------------------------
// MARK: Fuel Gauge -------------------------------
fuelGauge=SKSpriteNode()
// We are using 0's here since its positioned in regards to the parent, or SKCropNode
fuelGauge.position=CGPoint(x:0,y:0)
fuelGauge.texture=SKTexture(imageNamed:"fuelGauge")
fuelGauge.size=CGSize(width:5,height:fuelGaugeHeight*0.97)
// ------------------------------------------------------------------------------------
// MARK: Crop Node -------------------------------
letcropNode=SKCropNode()
cropNode.position=CGPoint(x:16,y:playableArea.maxY-fuelGaugeHeight/1.5)
cropNode.maskNode=SKSpriteNode(imageNamed:"fuelGaugeMask")
cropNode.addChild(fuelGauge)
cropNode.zPosition=1
addChild(cropNode)
// ------------------------------------------------------------------------------------
So far so good, positioning seems to be ok and the sizes are great.
Next, I want to move the fuelGauge up and down, therefore masking the fuel amount. I think I can do that by moving the baseSKSpriteNodewhich is a child of theSKCropNode
All I need to do is change the Y position of the node.-100should give us an ok result.
//...
fuelGauge.position=CGPoint(x:0,y:-100)
//...
F*k me...that is not looking good at all. It does mask the gauge, but the size of the mask is not at all close the the size of the *fuelGaugenode we added. It just picks up the size of the sprite which we defined here:
cropNode.maskNode=SKSpriteNode(imageNamed:"fuelGauge")
Time to look around and see if I can make that SKCropNode size the same as the fuelGauge. I do have other options I can use here, but IREALLYwant to crop it. Because reasons.
The Solution 🏆
I haven't found anyone with similar issues so that only meant that I am the issue 😁 I took a short break over the weekend (🍻🍻🍻) and believe it or not, five minutes after I sat down and looked at the code again, and it hit me!
It was actually quite obvious, it just never occurred to me to tryNOTusing a sprite for the mask at all.
Our.maskNodeis picking up the sprite size and it doesn't care that we changed all our sizes depending on the playable area. All it needs to know is theSIZEwe are using now!
Let's give this one a go ⬇️
//...
cropNode.maskNode=SKSpriteNode(color:.green,size:CGSize(width:fuelGauge.size.width,height:fuelGauge.size.height*0.97))
//...
NowTHAT'S WHAT I AM TALKIN' 'BOUT!🤜💥🤛
Let's Polish this up 🇵🇱
Now that size works, let's animate the usage of the fuel by moving the sprite inside the mask upwards. Just as an extra "thing" I will make theLanderconsume more fuel while both thrusters are engaged.
First, we will declare a globalVariable to hold theYposition of the sprite.
varfuelConsumption:CGFloat=0
.
.
.
fuelGauge.position=CGPoint(x:0,y:fuelConsumption)
And place out consumption logic inside a newly createdupdateFuel()method:
funcupdateFuel(){
// Determine consumption
switchtouchCount{
case1:
fuelConsumption+=0.3
case2:
fuelConsumption+=0.45
default:
fuelConsumption-=(isTouching&&fuelConsumption>0)?0.8:0.0
}
// Update sprite position
fuelGauge.position.y=fuelConsumption
}
Which of course we will then add to the very beginning of our defaultupdate()method
overridefuncupdate(_currentTime:TimeInterval){
updateFuel()
.
.
.
Done'zo Washington!
And here is the final product (for now) Our Lander can now spend fuel as well as re-fuel.
Not sure how much this would cost IRL but hey, that's the drivers problem, now mine 😉.
Also, as a kind of a dumb joke I made the fuel consumption move UP since...we are in SPACE 🛰.
This has been an experiment post, and I am really interested if you liked it...or not!
I would really appreciate if you let me know onTwitter.
Even if you just send me a message "It sucks dude", it would mean the world to me 🌎.
No hard feelings, I appreciate honesty more than you can imagine.