How to add a border to a health bar in SpriteKit? - swift

I have a health bar I created in SpriteKit.
I have a function that creates the health bar and attaches it to an SKSpriteNode(dragonNode)
The health bar I current have implemented is simply a SKSpriteNode with a rectangular shape.
Here is the code
func dragonHealth(dragonNode: SKSpriteNode) -> SKSpriteNode{
healthbar = SKSpriteNode(color: UIColor.greenColor(), size: CGSizeMake(self.frame.size.width * 0.5, self.frame.size.height * 0.015))
healthbar.anchorPoint = CGPointMake(0, 0.5)
healthbar.position = CGPointMake(self.frame.size.width * -0.23, self.frame.size.height * 0.3)
healthbar.runAction(SKAction.resizeToWidth(self.frame.size.width * 0.1, duration: 3))
dragonNode.addChild(healthbar)
return dragonNode
}
Can someone share a way to implement a border to my current health bar. I think it will look better that way.

Why don't you simply add another sprite underneath your healthbar sprite that is slightly bigger and in a different colour. (Make it parent of your main healthbar so they stay/move together).
There also is this tutorial on Ray Wenderlich where they are using health bars, its about half way through the page.
https://www.raywenderlich.com/90520/trigonometry-games-sprite-kit-swift-tutorial-part-1
Hope this helps

Related

How to add a ripple effect in Swift & SpriteKit

In SpriteKit I have a starting button
startButton = SKSpriteNode(color: UIColor.red, size: CGSize(width: 130, height: 130))
startButton.name = "startButton"
startButton.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
self.addChild(startButton)
and around this node I want to add a ring that will expand and come back in again sort of like a rippling effect, so how would I add this effect?
Because it is in SpriteKit you have a few options, you could create a sprite that is the same shape as your button but only has an outline but no fill. Place this below your button and then when you want to do the ripple effect apply some actions to below image (repeat3times(sequence[scaleUp, fadeOut]))
Or you could take the same stroked image and create an effect in the particle editor, and then apply that particle effect to your button
You can check out my similar solution here How To Create a Pulse Effect On an SKSpriteNode?

SpriteKit: using SKView in UIView instead of initializing a Game project

Completely new to SpriteKit. Currently I have a UIView, and I want to add a sprite node to it (like a small UIImageView, but I want animation for it so using SpriteKit). Therefore I didn't initialize my project to be a game project, as found in almost all of tutorials for SpriteKit. I've found a note here: link and what I have now is sth like:
func initializeImage() {
let imageView = SKView()
imageView.frame = CGRect(x: self.frame.width / 2 - Constants.imageWidth / 2, y: self.frame.height - Constants.imageHeight, width: Constants.imageWidth, height: Constants.imageHeight)
// so place it somewhere in the bottom middle of the whole frame
let sheet = SpriteSheet(texture: ...)
let sprite = SKSpriteNode(texture: sheet.itemFor(column: 0, row: 0))
sprite.position = imageView.center //basically the same position as the imageView.frame's x and y value
let scene = SKScene(size: imageView.frame.size)
scene.backgroundColor = SKColor.clear
scene.addChild(sprite)
imageView.presentScene(scene)
self.frame.addSubview(imageView)
}
The SpriteSheet is similar to this: sprite sheet; it's essentially cutting an image atlas and divide it into smaller images. I tracked the process and this step is indeed giving the smaller image (the var 'sprite'). But if running I only have a black square now (should be the size as defined by Constants). If I set scene.backgroundColor to be white then it's white. May I know how I should proceed from here, as how should I make the sprite showing up?
All of your code looks good except for this:
sprite.position = imageView.center // basically the same position as the imageView.frame's x and y value
That is basically not the position you think it is. The coordinate system in SpriteKit is a) relative to the (SK)scene, not to whatever view the SKView is contained in, and b) flipped vertically relative to the UIKit coordinate system. If you want a sprite centered in the scene, you probably want to set its position based on the scene's size:
sprite.position = CGPoint(x: scene.size.width / 2, y: scene.size.height / 2)
By the way, the external SpriteSheet code might not be needed (and you're more likely to benefit from Apple's optimizations) if you slice up your sprite sheet and put it in an Xcode asset catalog.

Swift 3 Beginner - Position Assets in Scene

I am a complete beginner at Swift 3 and programming in general so this will be an incredibly basic question.
I have been following tutorials and am currently positioning a SpriteNode using CGPoint. The tutorial recommends the following to position the Node centrally at the bottom of the screen:
Ground.position = CGPoint(x: self.frame.width / 2, y: 0)
However, that causes it to stick to the top-right of the screen.
When I use the following code:
Ground.position = CGPoint(x: 0 - self.frame.width / 2, y: 0 - self.frame.height / 2)
It positions at the bottom-centre as intended.
I do not understand why this happens as there is very little else done in the tutorial at this point to cause the error.
Set the anchorPoint of the scene to the bottom left corner at the beginning of your didMove(toView: SKView) (or in GameViewController):
scene.anchorPoint = CGPoint(x: 0, y: 0)
Keep in mind that everything you place on the scene is placed based on the anchorPoint. So with this anchorPoint, the origin of your scene is the bottom left corner.
Also note that if you're using .AspectFill as your sceneScaleMode, you don't have to use self.frame and instead set the scene size to 768x1024 (portrait)/ 1024x768 (landscape) then just use number values within the scene size.
Additionally, there are advantages of setting your scenes anchorPoint to the centre:
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
This makes it easier to fit the scene into iPad size as well as iPhone, and also simplifies centering nodes.
See this link for more info on making your app universal: iOS Universal Device App with SpriteKit, how to scale nodes for all views?

SKLabelNode Not Showing [SpriteKit]

I created a SKShapeNode called smallScreen and an SKLabelNode with the name screenLabel.
I later attempted to display screenLabel in smallScreen. When I ran the code however, it didn't work. I tried adding screenLabel as a child to self, and that seemed to allow the text to display. Whenever I added screenLabel as a child node to smallScreen, it wouldn't display. Please help, much thanks.
self.smallScreen = (self.childNodeWithName("screen") as? SKShapeNode)!
self.smallScreen.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height * 2/3)
screenLabel.text = "Screen"
screenLabel.fontSize = 30
screenLabel.fontColor = UIColor.redColor()
screenLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height * 2/3)
screenLabel.hidden = false
self.smallScreen.addChild(screenLabel)
In Sprite-kit by default, a scene’s origin is placed in the lower-left corner of the view. Its default value is CGPointZero and you can’t change it. (source).
A sprite’s (SKSpriteNode) anchor point defaults to (0.5,0.5), which corresponds to the center of the frame (source).
SKShapeNode does not have an anchorPoint.
LearnCocos2D answered on this issue:
When you use an image you may need to align it on its node's position.
There's no other way to do so but through anchorPoint because the
image itself can't be modified (not easily anyway).
When you create a shape you have full control over the alignment of
the shape through CGPath. You can simply translate the path to change
the shape's alignment relative to the node's position.
This is my interpretation, not fact.
So , what happened to your code?
I don't know how you have initialized your shape, I make just an example:
/* Create a Shape Node representing a rect centered at the Node's origin. */
#available(iOS 8.0, *)
public convenience init(rectOfSize size: CGSize)
So we create the shape like this:
self.smallScreen = SKShapeNode.init(rectOfSize: CGSizeMake(200,200))
First, you place your SKShapeNode to the X center of the screen for the X coordinates, and Y = self.frame.size.height * 2/3. In fact, your smallScreen is visible.
Speaking about your label, you have add it to the smallScreen, so screenLabel must respect the alignment of his parent.
In fact you can see your label simply by making this change:
From:
screenLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height * 2/3)
To:
screenLabel.position = CGPointZero
and your label is positioned to the center of the smallScreen according to the alignment of his parent.

Swift- UI Progress Bar not showing up

Here's what I have so far in my didMoveToView() function:
backgroundLayer.zPosition = -1
hudLayer.zPosition = 100
addChild(backgroundLayer)
addChild(hudLayer)
backgroundColor = SKColor.whiteColor()
let healthBar: SKSpriteNode = SKSpriteNode(imageNamed: "Healthbar")
healthBar.position = CGPoint(x: 0, y: 0)
healthBar.anchorPoint = CGPoint(x: 0, y: 1.0)
hudLayer.addChild(healthBar)
My background shows up fine, and I have both a backgroundLayer and a hudLayer. I even made the zposition much higher for the hudLayer to make sure it's in front. As for the positioning, I think I have the anchor point to be at the top-left of the sprite, and tried various ways to position it- it seems to only show up when I use something like:
healthBar.position = CGPoint(x: 0, y: size.width/2)
My question is why? size.width/2 isn't working for when I test on different screen sizes (on an iphone4, the health bar is further down).
Doesn't size take the current size of the screen? I thought using size would make it somewhat 'responsive' but I can't get the behavior to work right. Therefore, I thought maybe the CGPoint coordinate system (0-1.0) would work better, but it's not showing up at all with that.
Thanks for reading, I don't understand why it won't show up :(