How to make two sides edges with keeping scale mode Aspect fill? - ios

I am trying to make edges for the two sides in the scene by using this code
let leftEdge : SKNode = SKNode()
leftEdge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero , toPoint:CGPointMake(0.0, self.frame.size.height + 100))
leftEdge.position = CGPointZero;
leftEdge.physicsBody!.categoryBitMask = EdgeCategory;
leftEdge.physicsBody!.collisionBitMask = BubblesCategory;
self.addChild(leftEdge)
// right edge
let rightEdge : SKNode = SKNode()
rightEdge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero , toPoint:CGPointMake(0.0, self.frame.size.height + 100))
rightEdge.position = CGPointMake(self.frame.size.width, 0.0);
rightEdge.physicsBody!.categoryBitMask = EdgeCategory;
rightEdge.physicsBody!.collisionBitMask = BubblesCategory;
self.addChild(rightEdge)
It works fine if i use ResizeFill scale mode but i want to make the mode AspectFill so how i can make the edges with keeping the mode AspectFill?

Related

Use an SKShapeNode for the mask of an SKCropNode (Swift)

How can I use an SKShapeNode for the mask of an SKCropNode? My code currently creates an SKShapeNode circle and then sets the crop node mask to it
shapeNode = SKShapeNode(circleOfRadius: 50)
shapeNode.fillColor = UIColor.red
shapeNode.lineWidth = 1
shapeNode.position = CGPoint(x: 0, y: 0)
shapeNode.zPosition = 4
cropNode = SKCropNode()
cropNode.maskNode = shapeNode
cropNode.addChild(Node)
But when I add the Node as a child of the cropNode it doesnt draw anything but a red circle (exactly as i set it to do)
Is there any way to use an SKShapeNode as the mask of an SKCropNode?
-Update-
I figured out how to make an SKSpriteNode drawn from the SKShapeNode
shapeNode = SKShapeNode(circleOfRadius: 60)
shapeNode.fillColor = UIColor.red
let shapeTexture = view.texture(from: shapeNode)
textureNode = SKSpriteNode(texture: shapeTexture)
textureNode.position = CGPoint(x: 0, y: 0)
textureNode.zPosition = 3
cropNode.maskNode = textureNode
cropNode.addChild(tileMap2)
self.addChild(cropNode)
But now the SKCropNode isnt working when applied to the SKSpriteNode how do I fix this?

Positioning SKSpriteNodes in GameScene

I am having a little bit of trouble positioning two SKSpriteNodes correctly in my GameScene. My nodes appear in the scene, but they are zoomed in and take up most of the entire scene. I would to have the output similar to this:
Here is my current code:
let size = CGRect(x: 100, y:98, width:200, hight:271)
bottomRectangle = SKSpriteNode(imageNamed: "bottomRectangle")
bottomRectangle.zPosition = 3
bottomRectangle.size.height = self.size.height
bottomRectangle.size.width = self.size.width
bottomRectangle.position = CGPoint(x: 200, y:271)
bottomRectangle.physicsBody = SKPhysicsBody(edgeLoopFromRect: size)
self.addChild(bottomRectangle)
topRectangle = SKSpriteNode(imageNamed: "topRectangle")
topRectangle.physicsBody = SKPhysicsBody(edgeLoopFromRect: size)
topRectangle.zPosition = 4
topRectangle.size.height = self.size.height
topRectangle.size.width = self.size.width
topRectangle.position = CGPoint(x: 100, y: 98)
self.addChild(topRectangle)
You are using the size of the scene, because of:
self.size.height
You have to use you local variable:
size.height

Scaling Node boundaries properly across all screen sizes Swift

I am trying to set two SKSpriteNodes as boundaries(top / bottom) and anchor them to specific coordinates on the screen, so that when I switch from the iPhone 5 to the 6+, the boundaries are still in the same position. I also seem to be having a little trouble getting the node images to display properly. They are either zoomed in, or nonexistent on the screen.
Here is the code that I have so far:
let size = CGRect(x: 100, y: 98, width:200, height:271)
bottomRectangle = SKSpriteNode(imageNamed: "bottomRectangle")
bottomRectangle.anchorPoint = CGPointMake(0.5, 0.3) // bottom center anchor points
bottomRectangle = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
bottomRectangle.zPosition = 3
bottomRectangle.size.height = self.size.height
bottomRectangle.size.width = self.size.width
bottomRectangle.position = CGPoint(x: 0.5, y: 0.3)
bottomRectangle.physicsBody = SKPhysicsBody(edgeLoopFromRect: size)
self.addChild(bottomRectangle)
topRectangle = SKSpriteNode(imageNamed: "topRectangle")
topRectangle.anchorPoint = CGPoint(x:0.5,y:0.8) // top center anchor points
topRectangle.physicsBody = SKPhysicsBody(edgeLoopFromRect: size)
topRectangle.zPosition = 4
topRectangle.size.height = self.size.height
topRectangle.size.width = self.size.width
topRectangle.position = CGPoint(x: 0.5, y: 0.8)
self.addChild(topRectangle)
if let scene = GameScene(fileNamed:"GameScene"){
let skView = self.view as! SKView
scene.scaleMode = SKSceneScaleMode.ResizeFill
// Configure the view.
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = false
/* Set the scale mode to scale to fit the window */
scene.size = skView.bounds.size
skView.presentScene(scene)
}

How to make border for a scene in SpriteKit

I am trying to make border for the two sides in a scene but there is some kind of error the here is the code i used
let leftEdge : SKNode = SKNode()
leftEdge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero, toPoint: CGPointMake(0.0, self.size.height + 100))
leftEdge.position = CGPointZero;
self.addChild(leftEdge)
let rightEdge : SKNode = SKNode()
rightEdge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero, toPoint: CGPointMake(0.0, self.size.height + 100))
rightEdge.position = CGPointMake(self.size.width, 0.0);
self.addChild(rightEdge)
but the top border and bottom border get the borders and the two sides its seems like they have border outside the the scene cause i shoot object toward them it goes out of the scene and get back so the question how i make borders only for the two sides the left and the right
try this
let border = SKPhysicsBody(edgeLoopFrom: self.frame)
border.friction = 0
border.restitution = 1
self.physicsBody = border
obviously you can add your own physics to your border.

Swift Spritekit Scrolling Background

I am trying to find the best method to do a vertically scrolling background in Swift,
without using the Update Method. The Background is 1 Image that should loop infinite.
The Image should be in the middle of the screen (full-size), moving down, and on top of that image should always be another image spawned.
However, mine doesn't work quite right, it spawns 2 images, and than after a delay they pop up and start the Actions again.
Also, it breaks sometimes down from 30 FPS to 26, which I want to avoid.
I hope somebody, who is more into Swift can help me.
let Background = SKTexture(imageNamed: "Background.png")
Background.filteringMode = .Nearest
let BackgroundMove = SKAction.moveByX(0, y: -self.frame.size.height, duration: 10)
let BackgroundReset = SKAction.moveByX(0, y: self.frame.size.height, duration: 0.0)
let BackgroundMoveAndResetForever = SKAction.repeatActionForever(SKAction.sequence([BackgroundMove,BackgroundReset]))
for var i:CGFloat = 0; i < 2.0 + self.frame.size.height / (Background.size().height * 2); ++i {
let sprite = SKSpriteNode(texture: Background)
sprite.size = CGSize(width: self.frame.size.width / 2, height: self.frame.size.height)
sprite.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2 * i)
sprite.zPosition = 1
sprite.runAction(BackgroundMoveAndResetForever)
self.addChild(sprite)
}
This is the code I used to make a background that moves right to left across the screen. It used a loop to generate three backgrounds, all of which formed a line which passed through the screen and returned to their original position when they were done. To convert it to a screen that moves top to bottom, you would have to replace the moveByX SKActions to moveToY, and exchange changing x values with changing y values. Hope this helps!
func makeBackground() {
var backgroundTexture = SKTexture(imageNamed: "img/bg.png")
//move background right to left; replace
var shiftBackground = SKAction.moveByX(-backgroundTexture.size().width, y: 0, duration: 9)
var replaceBackground = SKAction.moveByX(backgroundTexture.size().width, y:0, duration: 0)
var movingAndReplacingBackground = SKAction.repeatActionForever(SKAction.sequence([shiftBackground,replaceBackground]))
for var i:CGFloat = 0; i<3; i++ {
//defining background; giving it height and moving width
background=SKSpriteNode(texture:backgroundTexture)
background.position = CGPoint(x: backgroundTexture.size().width/2 + (backgroundTexture.size().width * i), y: CGRectGetMidY(self.frame))
background.size.height = self.frame.height
background.runAction(movingAndReplacingBackground)
self.addChild(background)
}
}
I wrote this one... It's probably not as short as it could be, but it only uses 2 copies of the image, unlike the one posted above as best-answer. It also allows you to specify a direction (true to scroll right, false to scroll left) and a speed (indicates how many seconds it takes for an image to scroll across the screen, lower numbers = faster). It requires you to specify the view as well, and I haven't tested it with images that aren't the same size as the desired output (although I included scaling, so it probably works)
func scrollingBackground (view: SKView, rightward: Bool, speed: CGFloat) {
let background = SKSpriteNode(imageNamed: "space")
let background2 = SKSpriteNode(imageNamed: "space")
// variables to manage x position, will be set based on which
// direction this will be moving
var b1startX, b2startX, destination, resetPos: CGFloat
// Set values based on desired direction
if(rightward){
b1startX = frame.size.width * -0.5 // value to start offscreen
b2startX = frame.size.width * 0.5 // value to start on screen
destination = frame.size.width * 1.5 // position where image will disappear
resetPos = frame.size.width * -0.5 // position where image will reappear
}
else{
b1startX = frame.size.width * 1.5
b2startX = frame.size.width * 0.5
destination = frame.size.width * -0.5
resetPos = frame.size.width * 1.5
}
background.position = CGPoint(x: b1startX, y: frame.size.height / 2)
background.scale(to: view.bounds.size)
background.zPosition = -1
background2.position = CGPoint(x: b2startX, y: frame.size.height / 2)
background2.scale(to: view.bounds.size)
background2.zPosition = -1
// Define actions based on desired direction
let scrollFromMid = SKAction.moveTo(x: destination, duration: TimeInterval(speed))
let scrollFromLeft = SKAction.moveTo(x: destination, duration: TimeInterval(speed * 2.0))
let resetPosition = SKAction.moveTo(x: resetPos, duration: 0)
//background starts in the default starting position, totally offscreen
background.run(SKAction.repeatForever(SKAction.sequence([scrollFromLeft, resetPosition])))
// background2 starts fully displayed, moves offscreen, then into default loop
background2.run(SKAction.sequence([scrollFromMid, resetPosition,
SKAction.repeatForever(
SKAction.sequence([scrollFromLeft, resetPosition]))
]))
addChild(background)
addChild(background2)
}
when you create the BackgroundReset action you set the y change to a negative value, this will move the background further down the screen. Remove the minus sign to move the background back up the screen.
let BackgroundReset =
SKAction.moveByX(0, y: /* removed minus sign here */ self.frame.size.height * 2, duration: 0.0)

Resources