So far, I have written the following code. Right now, it fills the screen because I set the width and height to specific values. This method, however, will not make the image the correct size on every other device. I am wondering if there is any way to change the size of an image so it automatically fills up the screen every time, on whatever device.
func backgroundScene() {
let constructionSite = SKSpriteNode(imageNamed: "Background Image")
constructionSite.size = CGSize(width: 425, height: 900)
constructionSite.position = CGPoint(x: frame.midX, y: frame.midY)
constructionSite.zPosition = -1
addChild(constructionSite)
}
Related
I want to modify the size of SKScene but I have figure out how to do it. I have figure out how change the size but it square taking the smallest size of the screen:
func makeScene() -> SKScene {
let minimumDimension = min(view.frame.width, view.frame.height)
let size = CGSize(width: minimumDimension, height: minimumDimension)
let scene = SKScene(size: size)
scene.backgroundColor = .white
return scene
}
Any of you knows how can I modify SKScene size (frame) programmatically ?
I'll really appreciate your help.
To modify the GameScene screen size, you can set go to GameScene.swift, and set the values.
self.size = CGSize(width: 100, height: 100)
Over here I have set the GameScene size to be 100 X 100. You can also change these values in the GameScene.sks, but the value stated in the code would over write it.
Ok, so I've been trying to position a line on my iPhone 6s+ and my iPad 2. The line was added in an SKCamera (I don't know if that effects it or not). Here is the code for the line:
var leftWall = SKSpriteNode()
leftWall.size = CGSize(width: 1, height: 10000)
leftWall.position = CGPoint(x: 0, y: 0)
leftWall.color = UIColor.red
leftWall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: leftWall.size.width, height: leftWall.size.height))
leftWall.physicsBody?.affectedByGravity = false
leftWall.physicsBody?.isDynamic = false
leftWall.physicsBody?.categoryBitMask = groundGroup
leftWall.physicsBody?.collisionBitMask = ballGroup
leftWall.physicsBody?.contactTestBitMask = 0
theCamera.addChild(leftWall)
Okay, so the x position is 0,0 right? Here is how it looks on my iPhone 6s+:
As you see, the line is in the middle?
Here is how it looks on my iPad 2:
I just don't understand why the position of the line is completely different.. Please help me!
You are not taking into account the cropping that happens on the iPad, or your scaleMode is all wrong
What you need to do is set all nodes anchor points (Including the scene) to (0.5,0.5), make sure your GameScene has a static size and not based on view.frame (750,1334 is a good one) and that your scale mode is set to .aspectFill. This makes (0,0) the center of the screen, and you will notice everything line up on all devices
Im making a small boxing app. This whole week iv been trying to work out how to solve my current problem above, with no luck :(.
Summary
Basically Its a 1 v 1 game. Each time the user hits the other player I want to make a tiny number pop up near him and float up and dissappear.
Its sort of like when you play MMORPG's and when you do dmg you see how much you did. See image below for an example!
So basically everytime the user hits the other player I want a little number to pop up on the screen to show the dmg and then float up and disappear.
Details
I am building the game on a simple UIView
The label is a UILabel
Anywhere How I can achieve this?
Thank you!
Create a label, then use UIView.animateWithDuration to animate it.
let label = UILabel(frame: CGRect(origin: point/*The point where you want to add your label*/, size: CGSize(width: 50, height: 50)))
label.text = "+1"
label.font = UIFont()//Your font
label.textColor = UIColor.blueColor()
label.alpha = 1
self.view.addSubview(label)
UIView.animateWithDuration(1) {
label.center = CGPoint()//The point where you want your label to end up
label.alpha = 0
}
Edit: As mentioned in the comments, you asked for how to create the label at a random point. Try this:
let screenWidth = self.view.frame.width
let screenHeight = self.view.frame.height
let randomX = CGFloat(arc4random_uniform(UInt32(screenWidth)))
let randomY = CGFloat(arc4random_uniform(UInt32(screenHeight)))
let point = CGPoint(x: randomX, y: randomY)
As you will notice, for the width and height, I use the view's frame's width and height. You may want to use the view's bounds. For more on this, check out this SO Post.
I want to constrain and position a game center button to the top left and make it constrained for every device, how do I do this. I am really new to sprite kit.
let gameCenterBtn = SKSpriteNode(imageNamed: "Game-Center-icon.png")
gameCenterBtn.size = CGSize(width: 60, height: 60)
gameCenterBtn.name = "gameCenterButton"
gameCenterBtn.position = CGPointMake(320, 730)
gameCenterBtn.position = CGPoint(x: self.frame.width , y: self.frame.height )
For example how do I make a position a node and make it work for any device?
I figured it out. The code below works.
gameCenterBtn.position = CGPoint(x: CGRectGetMidX(self.frame) - 188 , y: CGRectGetMaxY(self.frame) - 25)
Scene cropping is still happening as I said in my old answer I deleted.
Open a brand new Xcode game template and paste your code with a position like this
gameCenterBtn.position = CGPoint(x: CGRectGetMaxX(self.frame) - (gameCenterButton.size.width / 2) , y: CGRectGetMidY(self.frame))
and run on all the simulators to see what happens.
On iPads you see half the image on the right and on iPhones you only see 1/4.
Now go the the GameViewController and change the scene scale mode to ResizeFill and see what happens. You sprits will be at the same spot on all devices but you will have to readjust the image size.
This is how you set the scene size.
How to change SKscene size
I originally created my game with iOS 8 and tested on my iPhone 6S. The game looks fine in the 5, 5S, 6, 6 Plus, 6S, and 6S Plus (since all devices have the same ratio of 16:9). As you can see from the image, the music button is offset from the top right corner. The image is offset by this code:
muteButton.position = CGPoint(x: CGRectGetMidX(self.frame) + 920, y: CGRectGetMidY(self.frame) + 480)
The problem I have is if someone tried this game on an iPad, it will display this. As you can see, the bottom graphic and the mute button are offset from the sides by a lot.
I want to make it so that the objects will always stay close to the sides of the frame/view. Making the app "universal" on xCode does not fix it either. Or do I just make a completely new project built for the iPad?
Don't forget about the 4s, you will get the same problems as iPad. SpriteKit does not have constraints like in the UI builder, so you are going to have to accommodate for the 4:3 and the 16:9 devices by applying some math, or force the 4:3 to be 16:9 with black borders using the .AspectFit scaling method.
Now I am not sure where 920, and 480 are coming from, but those numbers may have to be tweaked in this code when detecting the device. Simplest way to determine your aspect ration is to do UIScreen.mainScreen().bounds.width/UIScreen.mainScreen().bounds.height, then work from there.
Solution! I figured it out! For those who come from the future and also might need help with this. This works with landscape orientation and portrait orientation.
Note: You must have your scene.scaleMode set to .AspectFill for this to work on all scenes and the scene size has to be 2048x1536 or 1536x2048. This will make it scaleable for iPad too.
I have declared the following variable on the top of my class.
class StartScene: SKScene {
let playableArea: CGRect
}
Then, I have the following code inside the override init() function.
override init(size: CGSize) {
//1. Get the aspect ratio of the device
let deviceWidth = UIScreen.mainScreen().bounds.width
let deviceHeight = UIScreen.mainScreen().bounds.height
let maxAspectRatio: CGFloat = deviceWidth / deviceHeight
//2. For landscape orientation, use this*****
let playableHeight = size.width / maxAspectRatio
let playableMargin = (size.height - playableHeight) / 2.0
playableArea = CGRect(x: 0, y: playableMargin, width: size.width, height: playableHeight)
//3. For portrait orientation, use this*****
let playableWidth = size.height / maxAspectRatio
let playableMargin = (size.width - playableWidth) / 2.0
playableArea = CGRect(x: playableMargin, y: 0, width: playableWidth, height: size.height)
super.init(size: size)
}
From here, I then use the variable playableArea to position my objects.
titleChild.position = CGPoint(x: CGRectGetMidX(playableArea), y: CGRectGetMaxY(playableArea) - (titleChild.size.height * 0.90))
Works amazing. Looks good in the iPhone 4S, 5, 5S, 6, 6 Plus, 6S, 6S Plus, and iPads.
If you want to see the box in the app to make sure you did it right, use the following function.
func drawPlayableArea() {
let shape = SKShapeNode()
let path = CGPathCreateMutable()
CGPathAddRect(path, nil, playableArea)
shape.path = path
shape.strokeColor = SKColor.redColor()
shape.lineWidth = 8
addChild(shape)
}
Then just call the function in the didMoveToView() function to view the red frame to make sure you did the code right. This will create a red frame the size of the view that is viewable to the user. Now that you have playableArea to hold the frame that the user can see, you can use it for other things such as making sure objects don't or can't leave the bounds, etc. For this screenshot, I use it to prevent the user from moving the spaceship outside the device.