making sprite move on swift using spritekit - ios

I am very new to using swift and Xcode in general. I wish to create a very simple game and I am trying to figure out why my ball only goes down once rather than go up and down twice when the screen is touched
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let actionUp = SKAction.moveTo(y: 1330, duration: 0.5)
let actionDown = SKAction.moveTo(y: 50, duration: 0.5)
ball?.run(actionUp)
ball?.run(actionDown)
ball?.run(actionUp)
ball?.run(actionDown)
}

Just after the ball is told to move up, before it can do anything, it is told to move down, and then up again, and then down. Only the last action moveDown is seen because there are no other actions after it.
You need SKAction.sequence, otherwise the four actions will be run immediately one after another, before the previous one even finishes.
let sequenceOfActions = SKAction.sequence([moveUp, moveDown, moveUp, moveDown])
ball?.run(sequenceOfActions)

Related

Create a new sprite every time a touch ends

I am playing around trying to learn swift and I am trying to have a brick sprite placed every time a person's touch ends. I'm new and not quite sure of if or how this is possible with spriteKit. I would like to have the brick interact with physics so if there is another way to do this without creating new sprites that would work as well
Just add the method touchesEnded to your class, create a new SpriteNode and add it to your scene. Something like this:
func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let yourNode = SKSpriteNode(imageNamed: "brick.png") //or the name of the brick texture file, if you have one
yourNode.position = CGPoint(x: 100, y: 100)
self.addChild(yourNode)
}
Here we added the node to (100,100), but you could add it to the location of the touch, adding this inside the method:
for touch in touches {
let location = touch.location(in: self)
yourNode.position = location
}
Remember to import SpriteKit to your class.

Defining my spaceship movement in spritekit game in Swift

Hi I am new to Xcode and Swift, right now I am trying to design a game that involves a spaceship as player with alien spaceships.
I ran into a little problem where I am trying to differentiate the movement of the spaceship from the firing of the spaceship.
Basically I used touchesBegan() function to run the function which my spaceship fires, and touchesMoved() function to move the spaceship's x-position.
These are the code:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
pShoot()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
spaceship.run(SKAction.moveTo(x: location.x, duration: 0.5))
}
}
What I am trying to do is to differentiate the clicking or touching indicator and pressed and move indicator, in other words I dont want the spaceship to fire when I am pressed and move on the screen, and I do not want the spaceship to move when I am clicking constantly but at different position. ( touchesMoved() detects changes in touch positions so if I am clicking at different positions spaceship will move which I dont want)
I would like to know what would be the best way of implementing this, thank you.
You could try checking the area that the user pressed and deciding whether or not to move the spaceship depending on the origin of the touch.

Drop ball down screen at location of touch,

I am new to Xcode and I am making an app that lets you drop a ball and hit blocks on the bottom. So far I am able to get the ball to drop when I touch anywhere on the screen however it only drops from the middle (probably because I have BALL.position = CGPoint (x: self.size.width * 0.5, y: self.size.height). how would I be able to get the ball to drop from the exact location of where I touch on the screen. Thank you!
also to get the ball to drop I used
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
Thanks again

How to keep track of animation in Sprite Kit

I need to keep track of animation with texture. I am animating power bar and when user clicks the screen it should stop and save the power. I can not figure out how to save power. So far I have this: on first touch power bar animates, but on the second touch it only stops but does not save power.
This is how I create animation:
textureAtlas = SKTextureAtlas(named:"images")
for i in 1...textureAtlas.textureNames.count{
let name = "\(i).png"
textureArray.append(SKTexture(imageNamed: name))
}
let animateForward = SKAction.animate(with: textureArray, timePerFrame: 0.1)
let animateBackward = SKAction.reversed(animateForward)
let sequence = SKAction.sequence([animateForward,animateBackward()])
This is how I detect touches:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let firstTouchStorage = touches.first{ // after first touch
let animateForward = SKAction.animate(with: textureArray, timePerFrame: 0.1)
let animateBackward = SKAction.reversed(animateForward)
let sequence = SKAction.sequence([animateForward,animateBackward()])
arrow.removeAllActions()
arrow.run(SKAction.repeatForever(sequence))
firstTouch = firstTouchStorage
}
for touch in touches{
if touch == firstTouch{
touchesArray.append(touch)
let angle = arrow.zRotation
if touchesArray.count == 2{
arrow.removeAllActions()
arrow.removeFromParent()
}
}
}
I am trying to solve this problem for too long, but I can not figure it out. I hope you will help me.
As #KnightOfDragon suggested : animateWithTextures has a restore: parameter, if you set that to false, when you stop animating the last texture should stay on the sprite. If you go ahead and read the textures description, then you will know what texture it stopped on, and could plan accordingly

Swift, Spritekit Rotating sprites swift 3

I am trying to rotate a sprite using swift, IOS 10 and the touchesmoved function, the code I have works in the fact it moves the sprite but in not the right way, the wrong directions etc.
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
guard let touch=touches.first{
return
}
let touchLocation = touch.location(in: self)
self.zRotation=CGFloat(atan2(Double(touchLocation.y), Double(touchLocation.x)))
}
does anyone know the correct way to rotate a sprite using zRotation and touchesMoved?
Thank you
I think you've probably overlooked the wonderful power of constraints in SpriteKit. Easy enough to do, Apple does a terrible job of promoting, presenting and educating those considering using SpriteKit.
Constraints allow you to say "go here", or "look at this".
In your case, the "look at this" is ideal, from the docs:
Orientation Constraints
A common use for orientation constraints is to make a look-at
constraint. For example, you may create a look-at constraint to make a
pair of eyes follow a moving object or to have a rocket point in the
direction of its target.
More specifically, you can use these in your touchesMoved:
https://developer.apple.com/reference/spritekit/skconstraint/1519627-orient
thanks for all the suggestions. Yes my explanation of the problem was not too great. so will add the full code here and it seems to be working apart from occasionally moving by 90 degrees on its own when i stop dragging and start dragging again
What I was trying to do was rotate a sprite around another sprite for example a cannon barrel around its wheel... When the wheel is loaded from the scene it calls this class and adds a child node (the barrel) which should be able to be moved around its wheel
import SpriteKit
class WheelNode: SKSpriteNode, CustomNodeEvent{
private var tubeNode=SKSpriteNode(imageNamed: "cannon-barrel")
var previousPoint:CGPoint!
var touchLocation:CGPoint!
func didMoveToScene() {
guard let scene=scene else{
return
}
isUserInteractionEnabled=true
tubeNode.anchorPoint=CGPoint(x:0, y:0)
tubeNode.position=position
self.addChild(tubeNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch=touches.first{
previousPoint=touch.location(in: scene!)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if let touch=touches.first{
touchLocation=touch.location(in: scene!)
var angle=atan2(touchLocation.y-previousPoint.y, touchLocation.x-previousPoint.x)
self.zRotation=angle
}
}
}

Resources