Obstacle random gap not working [SpriteKit] [Swift] - swift

I have a problem in my code. When I run the game, I have two obstacles (one on the left and one on the right). I coded a gap between each obstacle and it has been working. I have a problem where the gap sometimes spawns off of the screen where the player cannot get to. How can I fix this?
Here's my code:
let gapWidth = square.size.width * 1.5
var movementAmount = arc4random() % UInt32(self.frame.size.width/2)
var obstacleOffset = CGFloat(movementAmount) - self.frame.size.width / 2
var obstacle1 = SKSpriteNode(imageNamed: "Obstacle")
obstacle1.zPosition = 30
obstacle1.size = CGSize(width: self.frame.size.width, height: 300)
obstacle1.position = CGPoint(x: CGRectGetMidX(self.frame) + obstacle1.size.width / 2 + gapWidth / 2 + obstacleOffset, y: CGRectGetMidY(self.frame))
self.addChild(obstacle1)
var obstacle2 = SKSpriteNode(imageNamed: "Obstacle")
obstacle2.zPosition = 30
obstacle2.size = CGSize(width: self.frame.size.width, height: 300)
obstacle2.position = CGPoint(x: CGRectGetMidX(self.frame) - obstacle2.size.width / 2 - gapWidth / 2 + obstacleOffset, y: CGRectGetMidY(self.frame))
self.addChild(obstacle2)

You need to make sure the values of the random positions will always be on the screen. You can do that by using code similar to this:
var height = UInt32(self.frame.size.height)
var randomYPos = CGFloat(arc4random_uniform(UInt32(height)))
You can do the same for the random x value, just use the screen width. You only need to do this for obstacle 1, then set the position of obstacle 2 relative to obstacle 1.

Related

Move nodes by x and by y at the same time

I want to create a game with rectangles which move by x and by y.
My question is: Have I move the view (viewer of the player) or have I move the rectangles by x and by y at the same time?
I tried to move rectangles by x and by y at the same time, with the following code, but the rectangles move only by y.
#objc func addRects() {
rects = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: rects) as! [String]
rect = SKSpriteNode(imageNamed: rects[0])
rect.position = CGPoint(x: self.frame.width / 256 + 320, y: self.frame.height / 256)
rect.size = CGSize(width: 180, height: 120)
rect.zPosition = 1
self.addChild(rect)
moveByX = SKAction.moveTo(x: -500, duration: 2.0)
moveByY = SKAction.moveTo(y: -800, duration: 2.0)
removeRects = SKAction.removeFromParent()
wait = SKAction.wait(forDuration: 2.0)
rect.run(SKAction.sequence([moveByY,moveByY]))
rect.run(SKAction.sequence([wait,removeRects]))
}
How can I resolve this problem ?
Thank you
Don't use a sequence:
rect.run(moveByY)
rect.run(moveByX)
then it should move at the same time "moveByY" and "moveByX"
The other problem is, that you used:
rect.run(SKAction.sequence([moveByY,moveByY]))
I Hope my answer helps!

Swift SpriteKit contain nodes within screen width

I have randomly spawning nodes moving vertically down the view.
Here is the code for doing this:
let meteTexture = SKTexture(imageNamed: "redmete.png")
let movementAmount = arc4random() % UInt32(self.frame.width)
let meteOffset = CGFloat(movementAmount) - self.frame.width / 2
let meteTime = arc4random_uniform(4) + 3;
let moveMete = SKAction.move(by: CGVector(dx: 0, dy: -2 * self.frame.height), duration: TimeInterval(meteTime))
redmete = SKSpriteNode(texture: meteTexture)
redmete.position = CGPoint(x: self.frame.midX + meteOffset, y: self.frame.midY + self.frame.height / 2)
My only problem is that as the meteOffset uses the centre of the sprite therefore it can occasionally spawn so 50% or so is out of the view.
I have tried
let movementAmount = arc4random() % UInt32(self.frame.width - meteTexture.size().width / 2)
I've also tried
let meteOffset = CGFloat(movementAmount) - meteTexture.size().width / 2 - self.frame.width / 2
But neither keep the whole of the sprite within the view. How can I do this?
You will want the initial position to be between the sub range of your frame height that is inset by half the height of the meteor.
You would need to have :
let meteorHeight = meteTexture.size().height
let verticalRange = self.frame.height - meteorHeight
let randomXPosition = meteorHeight/2 + arc4random() % verticalRange
Same goes for the horizontal position (if you want that to be random as well) :
let meteorWidth = meteTexture.size().width
let horizontalRange = self.frame.width - meteorWidth
let randomYPosition = meteorWidth/2 + arc4random() % horizontalRange
You can then set the position directly with the random XY coordinates
redmete.position = CGPoint(x:randomXPosition, y:randomYPosition)
If you don't want the meteor to appear too close to the edges, you can reduce the value of the verticalRange and horizontalRange further by subtracting a fixed offset or multiplying by a fraction.
SOLVED:
let meteTexture = SKTexture(imageNamed: "redmete.png")
let movementAmount = arc4random() % UInt32(self.frame.width / 2)
let meteOffset = CGFloat(movementAmount) + meteTexture.size().width/2 - self.frame.width / 2
let meteTime = arc4random_uniform(4) + 3;
let moveMete = SKAction.move(by: CGVector(dx: 0, dy: -2 * self.frame.height), duration: TimeInterval(meteTime))
redmete = SKSpriteNode(texture: meteTexture)
redmete.position = CGPoint(x: self.frame.midX + meteOffset, y: self.frame.midY + self.frame.height / 2)

Sprite positioning at wrong points in y axis

so I know this is a dumb question, but maybe it'll help other people like me out too. Basically, I'm making a sprite appear at the top of the screen and then move to the bottom but in a random x position. There's nothing wrong with moving to the random x position, the problem is that it doesn't start out at the top of the screen. Here is my code:
let sprite = SKSpriteNode(imageNamed: "comet")
sprite.size = CGSize(width: 150, height: 100)
sprite.position = CGPoint(x: self.frame.size.width/2, y: 0)
sprite.zPosition = 100
self.addChild(sprite) `
let randomNum = CGPoint(x:Int (arc4random() % 1000), y: 1)
let actionMove = SKAction.moveTo(randomNum, duration: 1)
let actionComet = SKAction(actionMove)
sprite.runAction(actionComet)
Any help is appreciated.
You are placing your sprite at location (0,0) which is left bottom of the screen. If you want to place the sprite at the top use:
sprite.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height + sprite.size.height / 2.0)

Swift - SKAction moveByX, How to get my node to move from the top/down

please forgive me as I'm a bit of a Swift noob and am creating my first game :D
Ok, so I have two nodes... one is Guava and the other is Pepper. Guava moves from the bottom of the screen to the top. I want the Pepper to move from the top of the screen to the bottom. Here's the code I have, which works fine for the Guava.
// movement of guavas
let guavaToMove = CGFloat(self.frame.size.width + 2.0 * guavaNodeTexture.size().width)
let moveGuava = SKAction.moveByX(-guavaToMove, y: self.frame.size.width, duration: NSTimeInterval(0.01 * guavaToMove))
let removeGuava = SKAction.removeFromParent()
// movement of peppers
let pepperToMove = CGFloat(self.frame.size.width + 2.0 * pepperNodeTexture.size().width)
let movePepper = SKAction.moveByX(-pepperToMove, y: self.frame.size.width, duration: NSTimeInterval(0.01 * pepperToMove))
let removePepper = SKAction.removeFromParent()
GuavaMoveAndRemove = SKAction.sequence([moveGuava,removeGuava])
PepperMoveAndRemove = SKAction.sequence([movePepper,removePepper])
Now I have the Guava Node anchored to the bottom of the screen and it floats up perfectly. I have the Pepper Node anchored to the top of the screen and am trying to get it to float down in a similar fashion.
Here is the code for both functions, spawnGuava and spawnPepper where both nodes/textures are anchored:
func spawnPepper(){
//The way the Guava spawn and move
let pepperNode = SKNode()
let pepper = SKSpriteNode(texture: pepperNodeTexture)
pepper.setScale(0.30)
pepper.position = CGPointMake (self.size.width + 140, self.size.height * 0.75)
pepper.alpha = 0.75
pepper.physicsBody = SKPhysicsBody(rectangleOfSize: pepper.size)
pepper.physicsBody?.affectedByGravity = false
pepper.physicsBody?.dynamic = true
pepper.physicsBody?.categoryBitMask = PhysicsCatagory.Guava
pepper.physicsBody?.collisionBitMask = 1
pepper.physicsBody?.contactTestBitMask = PhysicsCatagory.Boognish
pepper.zPosition = 50
pepperNode.addChild(pepper)
pepper.runAction(PepperMoveAndRemove)
self.addChild(pepperNode)
if scoreIncreased == true {
}
//the way the pepper collide
}
func spawnGuava(){
//The way the Guava spawn and move
let guavaNode = SKNode()
let guava = SKSpriteNode(texture: guavaNodeTexture)
guava.setScale(0.75)
guava.position = CGPointMake (self.size.width - 40, self.size.height * 0.05)
guava.physicsBody = SKPhysicsBody(rectangleOfSize: guava.size)
guava.physicsBody?.affectedByGravity = false
guava.physicsBody?.dynamic = true
guava.alpha = 0.75
guava.physicsBody?.categoryBitMask = PhysicsCatagory.Guava
guava.physicsBody?.collisionBitMask = 1
guava.physicsBody?.contactTestBitMask = PhysicsCatagory.Boognish
guava.zPosition = 0
guavaNode.addChild(guava)
guava.runAction(GuavaMoveAndRemove)
self.addChild(guavaNode)
if scoreIncreased == true {
}
//the way the guava collide
}
Please help me configure this code accordingly so that the peppers fall from the sky :)
THANKS in advance. First post :)
FYI: I have tried modifying the code many times myself to no avail, so I have reverted it to the baseline you see now. IF I anchored the pepper to where the Guava is anchored then both would float up at the same time.
You're trying to move guavas and peppers in the opposite direction, but it seems like you are moving them in the same direction. Try removing or adding negative signs in movePepper:
let movePepper = SKAction.moveByX(-pepperToMove, y: -self.frame.size.width, duration: NSTimeInterval(0.01 * pepperToMove))
// movement of peppers
let pepperToMove = CGFloat(self.frame.size.width + 2.0 * pepperNodeTexture.size().width)
let movePepper = SKAction.moveByX(-pepperToMove, y: self.frame.size.height / -1, duration: NSTimeInterval(0.01 * pepperToMove))
let removePepper = SKAction.removeFromParent()
just has to divide the y value by a negative, derp... :D

Swift - sprite kit - make SKPhysicsJointPin have less motion

I'm trying to create a snake with multiple body parts that moves left and right. Im using a pin, but upon the snake stopping, the body keeps moving and doesn't stop. I've messed around with the max and min angles, and the torque, but nothing seems to work. Should I use a different type of joint?
Sorry i cant log into my other account, but heres the code. Basically the second part just wobbles a lot. I wish to add 7-8 parts, but they just keep on wobbling, especially after moving "head". i would like a fluid "swoop" motion when i move the snake.
self.physicsWorld.gravity = CGVectorMake(0, -100)
self.physicsWorld.contactDelegate = self
head.size = CGSize(width: 25,height: 25)
head.physicsBody = SKPhysicsBody(texture: head.texture, size: head.size)
head.position = CGPointMake(100,400)
head.anchorPoint = CGPoint(x: 0.5, y: 1)
head.physicsBody!.dynamic = false
head.zPosition = 3
self.addChild(head)
var p1 = SKSpriteNode(imageNamed: "snakeBodyPart.png")
p1.size = CGSize(width: 25,height: 25)
p1.physicsBody = SKPhysicsBody(texture: p1.texture, size: p1.size)
p1.position = CGPointMake(100,380)
p1.anchorPoint = CGPoint(x: 0.5, y: 1)
p1.physicsBody!.dynamic = true
addChild(p1)
var joint = SKPhysicsJointPin.jointWithBodyA(head.physicsBody, bodyB: p1.physicsBody, anchor: CGPoint(x: CGRectGetMidX(head.frame), y: CGRectGetMinY(head.frame) + 10))
joint.upperAngleLimit = 0.1
joint.rotationSpeed = 0.1
self.physicsWorld.addJoint(joint)