Moving Sprites Across Screen In Sprite Kit - swift

I am trying to move a sprite that is a red ball from left and right to the screen. I hear I can do this by using the velocity property maybe or another way would be ok too but here is my code.
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let redBall = SKSpriteNode(imageNamed: "redball")
override func didMoveToView(view: SKView) {
let thrust = CGFloat(0.12)
let thrustDirection = Float()
//RedBall Properties
redBall.physicsBody = SKPhysicsBody(circleOfRadius: redBall.size.width/2)
redBall.physicsBody?.velocity
addChild(redBall)
//World Phyisics Properties
let worldBorder = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody?.friction = 1
self.physicsBody = worldBorder
self.physicsWorld.gravity = CGVectorMake(0, 0)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
}
}
Thanks!

You may want to use an SKAction assuming you want it to slide across the screen as opposed to simply moving from point a to point b. You could do something like this:
let move = SKAction.moveToX(self.frame.size.width, duration: 1.0)
redBall.runAction(move)
This creates an SKAction called move that moves a node to the right side of the screen and then runs that action on a node, in this case the redBall.
To move to the left, you just change the x value in the move action to this:
let move = SKAction.moveToX(0, duration: 1.0)

Related

sprite nodes on touch first one only takes physics body

I am using Xcode 8.1 Swift 3 to make small bouncing game.
The player is supposed to create walls around a bouncing ball and this ball is supposed to bounce on each wall.
On touch down, I move to point and on touch ended, I create a line share node between the two touches began and end.
I added the physics that were needed to my node, then I added child to this node (see my node below).
What happens is that for each touches began and touches ends, 'Swift' draws the line node and attaches it to self but only the first node bounces the ball.
All lines (walls) after the first one is not affecting the ball.
Here is my code the GameScene Swift file:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
// vars lets and nodes
let startingBall = SKShapeNode(circleOfRadius: 10)
let myPath = CGMutablePath()
let ballCategory : UInt32 = 1
let wallCategory : UInt32 = 2
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
myPath.move(to: t.location(in: self))
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
myPath.addLine(to: t.location(in: self))
let wallNode = SKShapeNode(path: myPath)
wallNode.lineWidth = 5.0
wallNode.fillColor = SKColor.green
wallNode.strokeColor = SKColor.green
wallNode.physicsBody = SKPhysicsBody(edgeLoopFrom: myPath)
wallNode.physicsBody?.categoryBitMask = wallCategory
self.addChild(wallNode)
}
}
override func didMove(to view: SKView) {
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
self.physicsBody?.categoryBitMask = wallCategory
startingBall.fillColor = SKColor.red
startingBall.position = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
startingBall.physicsBody = SKPhysicsBody(circleOfRadius: 10)
startingBall.physicsBody?.affectedByGravity = false
startingBall.physicsBody?.isDynamic = true
startingBall.physicsBody?.restitution = 1.0
startingBall.physicsBody?.friction = 0.0
startingBall.physicsBody?.linearDamping = 0.0
startingBall.physicsBody?.angularDamping = 0.0
self.addChild(startingBall)
startingBall.physicsBody?.applyImpulse(CGVector(dx: 3.0, dy: 3.0))
}
}
thanks all i've fixed it
actually mutable path myPath defines line between touch begin and touch end lines to draw shape node only ... while physics edge created for each touch series from node to node ...
in steps
1- i added start point and end point variables
2- pick up start node in touch begin and end node in touch end
3- i set physical body for from point to point start node and end node
1-
var startPoint : CGPoint = CGPoint.zero
var endPoint : CGPoint = CGPoint.zero
2- ..
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
startPoint = t.location(in: self)
myPath.move(to: t.location(in: self))
}
}
endPoint = t.location(in: self)
3- ..
wallNode.physicsBody = SKPhysicsBody(edgeFrom: startPoint, to: endPoint)
for help you can set show physics to true in skiver
skview.showsPhysics = true
thanks

Scale SpriteNode from a Specific Point

When scaling a spriteNode to a smaller size (or larger size), the spriteNode by default scales from the centre, which is usually fine. However, I need my sprite to scale from the very left of it's body. Is there any way of changing the spriteNode's centre point so that I can achieved this?
I tried adjusting the anchor point of the spriteNode (below), which does scale from the left of the body, but it also repositions the spriteNode, which I do not want.
import SpriteKit
var mySprite: SKSpriteNode!
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
anchorPoint = CGPointMake(0.5, 0.5)
backgroundColor = UIColor.greenColor()
mySprite = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(100, 50))
mySprite.anchorPoint = CGPointMake(0.0, 0.5)
addChild(mySprite)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
mySprite.runAction(SKAction.scaleTo(0.5, duration: 1))
}
I was hoping for something like the below (which doesn't exist):
mySprite.centerPoint.x = -mySprite.size.width/2
Also, the below gets the result I want, but I don't really want to have to adjust the spriteNode position everytime I adjust the anchorPoint:
var mySprite: SKSpriteNode!
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
anchorPoint = CGPointMake(0.5, 0.5)
backgroundColor = UIColor.greenColor()
mySprite = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(100, 50))
mySprite.anchorPoint = CGPointMake(0.0, 0.5)
mySprite.position.x = -mySprite.size.width/2
addChild(mySprite)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
mySprite.runAction(SKAction.scaleTo(0.5, duration: 1))
}
Try to delete mySprite.anchorPoint = CGPointMake(0.0, 0.5) in didload and in touchesBegan:
mySprite.anchorPoint = CGPointMake(0.0, 0.5)
func repositionAncorPoint() {
mySprite.anchorPoint = CGPointMake(0.5, 0.5)
}
let resetAncor = SKAction.runBlock({ repositionAncorPoint() })
let rescale = SKAction.scaleTo(0.5, duration: 1)
let sequence = [rescale,resetAncor]
mySprite.runAction(SKAction.sequence(sequence))
I've not test it... :)

swift 2: Sprite tilting effect

Looking for a method to tilt a sprite upwards on the right side when tapping the screen (like in flappy bird) Like a start of a rotation that returns to the place it were. I will use this as an effect of going faster then the sprite normally does.
I'll add the code I got so far below:
var player = SKSpriteNode()
override func didMoveToView(view: SKView) {
let playerTexture = SKTexture(imageNamed: "player")
player = SKSpriteNode(texture: playerTexture)
player.position = CGPoint(x: 200, y: 80)
player.physicsBody = SKPhysicsBody(texture: playerTexture, size: playerTexture.size())
player.physicsBody!.affectedByGravity = true
self.addChild(player)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
}

Swift detecting if a SKNode is a property of custom class

Hi I have a custom class, Ship, that has a property 'Parrent' that is an SKNode. When the class is initialized a bunch of nodes are added to that 'Parrent' making up the appearance of the class ship. 'Ship' has a method 'Explode' that shoots all of the nodes in different directions. This part works great, on to my issue.
I am trying to get the Ships to explode when I touch them, but I am having trouble passing which 'Ship' is to explode. Right now when I touch I use nodeAtPoint but this only gets me one of the appearance nodes. From there I need a way to go up a parent to 'Parrent' node and then from there up to Ship object as a whole.
AKA touch->nodeAtPoint->Appearance node->.parrent->'Parrent'->(get stuck here)->Ship->Ship.explode
I hope what is I am trying to accomplish makes sense, thanks for any help.
Ship class:
class Ship: NSObject {
var Position: CGPoint!
var Scene: SKNode!
var Parrent = SKNode();
let Parts = [
SKSpriteNode(imageNamed: "Ship/Ship1.png"),
SKSpriteNode(imageNamed: "Ship/Ship2.png"),
SKSpriteNode(imageNamed: "Ship/Ship3.png"),
SKSpriteNode(imageNamed: "Ship/Ship4.png"),
SKSpriteNode(imageNamed: "Ship/Ship5.png"),
SKSpriteNode(imageNamed: "Ship/Ship6.png"),
];
init(position : CGPoint, parrent : SKNode, scaleFactor: CGFloat) {
self.Position = position;
self.Scene = parrent;
self.Parrent.position = self.Position
var x = 0;
for part in Parts {
x++;
part.xScale = scaleFactor
part.yScale = abs(scaleFactor)
part.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Ship/Ship\(x).png"), size: part.size)
part.physicsBody?.collisionBitMask = PhysicsCategory.Ship
part.physicsBody?.categoryBitMask = PhysicsCategory.Something
part.position = CGPoint(x: 0, y: 0)
self.Parrent.addChild(part)
}
self.Scene.addChild(self.Parrent)
}
//other functions including explode
}
Touches began in SKScene
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let targetShip = nodeAtPoint(location)
let targetParrent = targetShip.parent
//decide if it is a 'Ship' here
}
}
Thanks! Id greatly appreciate any help!
This is what finally worked. I changed the ship class to inherit from SKNode and edited touches began as such:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let targetShip = nodeAtPoint(location)
if targetShip.isMemberOfClass(Ship){
print("Ship")
Ship1.shootLazer(targetShip as! Ship)
}else if targetShip.parent!.isMemberOfClass(Ship){
print("Ship parrent")
Ship1.shootLazer(targetShip.parent! as! Ship)
}
}
}

How to detect GameScene touches from another file using swift

I am currently making a game in sprite kit. In the game, there are random shapes and objects on the ground that you can pick up and rotate and stack on to one another to build up to a target height. Once the target height is reached you move on to the next level. Each object and shape is created in a swift file separate from the GameScene under the SKNode class. I am able to pick the object up and move it around on the screen using the touchesBegan, moved, and ended methods in the node. While I'm holding on to the object I would like to be able to tap and hold the screen with a second finger anywhere on the screen that rotates the object until the finger is let go, so, the first finger grabs and hold the object while the other finger rotates it. The problem is that I have found it almost impossible for the SKNode to detect a touch outside of the actual node. Below is the code I have used for the SKNode. Any advice or suggestions would be greatly appreciated, thank you.
import UIKit
import SpriteKit
class GameObjects: SKNode {
var object: SKSpriteNode
var action: () -> Void
init(objectImage: String, buttonAction: () -> Void ){
object = SKSpriteNode(imageNamed: objectImage)
action = buttonAction
let object1Texture = SKTexture(imageNamed: "object1")
object1Texture.filteringMode = SKTextureFilteringMode.Nearest
let size = CGSize(width: 100, height: 100)
object.physicsBody = SKPhysicsBody(texture: object1Texture, size: size)
object.physicsBody?.dynamic = true
object.physicsBody?.allowsRotation = true
object.physicsBody?.affectedByGravity = true
super.init()
userInteractionEnabled = true
addChild(object)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in (touches ) {
let location: CGPoint = touch.locationInNode(self)
let moveUp = SKAction.moveToY(location.y + 200, duration: 0.05)
object.runAction( moveUp)
}
object.physicsBody?.dynamic = false
object.physicsBody?.affectedByGravity = false
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in (touches ) {
let location: CGPoint = touch.locationInNode(self)
object.physicsBody?.allowsRotation = true
object.physicsBody?.dynamic = true
object.position.x = location.x
object.position.y = location.y + 200
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
object.physicsBody?.dynamic = true
object.physicsBody?.affectedByGravity = true
}
}