How do I create an image node in SpriteKit? Swift 4 - swift

Somebody told me in one of my other questions that SpriteKit was easier than UI. I searched online on how to get started with SpriteKit, and I got this: https://www.raywenderlich.com/145318/spritekit-swift-3-tutorial-beginners. I put the images in and everything, I put this code in:
import SpriteKit
class GameScene: SKScene {
// 1
let player = SKSpriteNode(imageNamed: "player")
override func didMove(to view: SKView) {
// 2
backgroundColor = SKColor.white
// 3
player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
// 4
addChild(player)
}
}
(the code they told me to put in), and when I run it, I just see a blank screen. On the tutorial, it had a ninja, but mine is just a blank screen.
Can anyone help with this?

if the screen is white try this :
import SpriteKit
class GameScene: SKScene {
// 1
var player = SKSpriteNode()
override func didMove(to view: SKView) {
// 2
backgroundColor = SKColor.white
// 3
let image = UIImage(named: "player")
let texture = SKTexture(image: image!)
player = SKSpriteNode(texture: texture)
player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
// 4
addChild(player)
}
}
If the screen not white : make sure the scene presented correctly .
If you have the GameScene.sks :
In GameViewController :
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = SKScene(fileNamed: "GameScene")
scene.scaleMode = .aspectFill
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
If you don't have GameScene.sks File
In GameViewController :
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = GameScene(size : view.frame.size)
scene.scaleMode = .aspectFill
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}

Related

Why isn't Xcode showing my nodes overtime the simulator runs?

I have this code in my GameScene swift file:
var background = SKSpriteNode(imageNamed: "background")
let blockImage = SKTexture(imageNamed: "block")
let blockSize = CGSize(width: 64, height: 64)
override func didMove(to view: SKView) {
setUpGame()
}
func setUpGame(){
background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
addChild(background)
let block = SKSpriteNode(texture: blockImage, size: blockSize)
block.position.x = block.frame.width/2
block.position.y = frame.height - block.frame.height/2
addChild(block)
}
This is my code in my GameController file:
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = GameScene(size: self.view.bounds.size)
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
// added to see physics body
view.showsPhysics = true
}
}
why does it take multiple runs for my block node to appear on the simulator except for my background? After the block finally show, it will continue to show after every run until I edit my code. Ive tried removing my background node just in case that might be the issue, but it didn't change anything

My SKTexture is size wrong for my SKSpriteNode

I have a 200 x 100 box-like menu button SKSpriteNode declared below.
menuBtn.size = CGSize(width: scrWidth * 1.5, height: 100)
menuBtn.texture = SKTexture(image: UIImage(named: "menuBtn")!)
The problem is, the hitbox for the button is still right, and the width of the SKTexture is fine, but the height of the SKTexture is around 1/2 the size of the actual menuBtn. It is a png, and I've checked and there's no clear textures around the sprite (just the transparent png ones), what am I doing wrong?
Pic of button: https://imgur.com/a/8BtXGLC
Pic of button in App: https://imgur.com/a/ZfW3xDL
Pic of how I want it to look: https://imgur.com/a/2zlSv8y
The texture's png image size is 1044x1044 if that has any impact.
First of all, make sure you are sending the correct size to your scene from GameViewController to your scene, in this example GameScene.
// without .sks
class GameViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// ...
if let view = self.view as! SKView?
{
let scene = GameScene()
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFit
// Set anchorPoint and pass scene.size
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.size = view.bounds.size
// Present the scene
view.presentScene(scene)
}
// ...
}
// with .sks
class GameViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// ...
if let view = self.view as! SKView?
{
if let scene = SKScene(fileNamed: "GameScene.sks")
{
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFit
// Pass scene.size
scene.size = view.bounds.size
// Present the scene
view.presentScene(scene)
}
}
// ...
}
In your GameScene create the object. I recommend working in screenWidth and screenHeight when you create objects so they scale to all iOS devices.
class GameScene: SKScene
{
override func didMove(to view: SKView)
{
// ...
// scene width / height
let sceneWidth = size.width
let sceneHeight = size.height
// object
let menu : SKSpriteNode = SKSpriteNode()
menu.texture = SKTexture(imageNamed: "menu")
menu.size = CGSize(width: sceneWidth * 0.75, height: 100)
let y_pos : CGFloat = -sceneHeight * 0.5 + menu.size.height * 0.5
menu.position = CGPoint(x: 0, y: y_pos)
menu.zPosition = 1
addChild(menu)
// ...
}
}
The problem I had was that there were extra transparent pixels in my base image, all I had to do was remove them with GIMP.

How to set up an SKScene with an SKNode with a texture in Swift Playgrounds?

I tried copying the template code from a SpriteKit project into a playground, but all I get is a grey screen when I present the Scene. Do I need to create an SKScene and if so how do I assign it to the scene class that I am using.
The following is my code to create and present the scene:
#objc func goToGameScene(){
print("GameView Loaded")
sceneView = SKView(frame: CGRect(x: 0, y: 0, width: 666, height: 500))
sceneView.backgroundColor = UIColor.black
PlaygroundPage.current.liveView = sceneView
if let view = self.sceneView as SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
}
And this is my SKScene class, which has a filename of GameScene.swift.
import Foundation
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var bg = SKSpriteNode()
func didBegin(_ contact: SKPhysicsContact) {
}
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
let bgTexture = SKTexture(image: UIImage(named: "MainScreenBackground.png")!)
let moveBGAnimation = SKAction.move(by: CGVector(dx:-bgTexture.size().width, dy:0), duration: 11)
let shiftBackground = SKAction.move(by: CGVector(dx: bgTexture.size().width, dy:0), duration: 0)
let repeatAnimationBg = SKAction.repeatForever(SKAction.sequence([moveBGAnimation, shiftBackground]))
var q = 0
while(q < 3){
bg = SKSpriteNode(texture: bgTexture)
bg.position = CGPoint(x: bgTexture.size().width * CGFloat(q), y: self.frame.midY)
bg.size.height = self.frame.height
bg.run(repeatAnimationBg)
self.addChild(bg)
q+=1
bg.zPosition = -1
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func update(_ currentTime: TimeInterval) {
}
}
Assuming you have dragged and dropped your MainScreenBackground.png image into you Assets.xcassets folder, you can use the code below to add the image to your scene as a SKSpriteNode.
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
let bgTexture = SKSpriteNode(imageNamed: "MainScreenBackground")
self.addChild(bgTexture)
...

Update all views while UISlider is being changed

Hello I have a SCNScene with a sprite kit overlay. I also have a subview that contains just a UISlider. The Slider controls the value of one of the SKLabel nodes in the sprite kit overlay. However when I am moving the slider the label does not update. It only updates once I touch outside of the slider. So I am guessing that the SCNScene and the overlay don't update while my touches are in the subview and only update once I touch back to the main view. How can I fix this?
Thanks!
My project is in swift, but if you only know objective-c ill still gratefully take your answer and translate on my own.
SceneKit Code:
class MyMarbleScene: UIViewController {
var scene: SCNScene!
var sceneView: SCNView!
var hud : MyMarbleSpriteKit!
var cameraNode: SCNNode!
override func viewDidLoad() {
super.viewDidLoad()
// create a new scene
scene = SCNScene()
sceneView = SCNView()
sceneView.frame = self.view.frame
sceneView.autoresizingMask = UIViewAutoresizing.allZeros
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = false
sceneView.allowsCameraControl = false
sceneView.backgroundColor = UIColor.blackColor()
self.view = sceneView
cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 20, z: 60)
hud = MyMarbleSpriteKit(size: self.view.frame.size, game: self)
sceneView.overlaySKScene = hud
let frame = CGRectMake(10.0, self.view.frame.height*0.5, 180.0, 10.0)
let slider = UISlider(frame: frame)
slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
slider.backgroundColor = UIColor.clearColor()
slider.minimumValue = 1.0
slider.maximumValue = 10.0
slider.continuous = true
slider.value = 5
self.view?.addSubview(slider)
}
func sliderValueChanged(sender: UISlider) {
var currentValue = Int(sender.value)
println("\(currentValue)")
self.hud.updateLabel(currentValue)
}
}
SpriteKit code
class MyMarbleSpriteKit: SKScene {
var myScene: MyMarbleScene!
var SensLabelTwo = SKLabelNode()
override func didMoveToView(view: SKView) {
}
init(size: CGSize, game:MyMarbleScene) {
super.init(size: size)
myScene = game
let SensLabel = SKLabelNode()
SensLabel.text = "Marble Sensitivity:"
SensLabel.fontName = "AvenirNext-HeavyIta"
SensLabel.fontSize = 40
SensLabel.fontColor = UIColor.whiteColor()
SensLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Top
SensLabel.position = CGPoint(x: 170, y: size.height-20)
self.addChild(SensLabel)
SensLabelTwo.text = "5"
SensLabelTwo.fontName = "AvenirNext-HeavyIta"
SensLabelTwo.fontSize = 60
SensLabelTwo.fontColor = UIColor.whiteColor()
SensLabelTwo.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Top
SensLabelTwo.position = CGPoint(x: 100, y: size.height-80)
self.addChild(SensLabelTwo)
}
func updateLabel(text: Int){
println("helllo")
SensLabelTwo.text = String(format:"%i", text)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
the 2D scene is not automatically refreshed when it's modified.
You will have to wait for the 3D scene to be redisplayed first. This happens when 3D animations or actions are running or when playing is set to YES. Alternatively, you can manually request a refresh with -[SCNView setNeedsDisplay].

Issue with positioning SKSpriteNode in SKScene

This is my first project with SpriteKit and I am following THIS tutorial
But when I try to give the position to the Image as he did into that tutorial at 20:10 with this code :
playScene.swift
import SpriteKit
class playScene : SKScene {
let runningBar = SKSpriteNode(imageNamed: "bar")
override func didMoveToView(view: SKView) {
println("We are at the new scene!")
self.backgroundColor = UIColor(hex: 0x80D9FF, alpha: 1)
self.runningBar.anchorPoint = CGPointMake(0.5, 0.5)
self.runningBar.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - (self.runningBar.size.height / 2))
self.addChild(self.runningBar)
}
override func update(currentTime: NSTimeInterval) {
}
}
I want to give position at bottom of the screen but I got this Output:
But the output should be:
GameScene.swift (If needed)
import SpriteKit
class GameScene: SKScene {
let playButton = SKSpriteNode(imageNamed: "play")
override func didMoveToView(view: SKView) {
self.playButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(self.playButton)
self.backgroundColor = UIColor(hex: 0x80D9FF, alpha: 1)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches{
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.playButton{
var scene = playScene(size: size.self)
let skView = self.view as SKView!
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
}
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
Can anybody tell me how can I achieve this?
Thanks In advance.
You need to look at the tutorial properly. You have set the following lines wrong:
self.runningBar.anchorPoint = CGPointMake(0.5, 0.5)
self.runningBar.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - (self.runningBar.size.height / 2))
They should be:
self.runningBar.anchorPoint = CGPointMake(0, 0.5)
self.runningBar.position = CGPointMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame) + (self.runningBar.size.height / 2))
For a better understanding of the coordinate system, have a look at the documentation.