I initialized SKRenderer in my project to use it alongside of metal. Although I'm not sure that I did it correctly, I need to know how I can render a simple 2D text with it?
For example, here is how we can draw a text with SKLabelNode, do we have anything like it for SKRenderer?
thank you so much
let winner = SKLabelNode(fontNamed: "Chalkduster")
winner.text = "You Win!"
winner.fontSize = 65
winner.fontColor = SKColor.red
winner.position = CGPoint(x: 100, y: 100)
view.addChild(winner)
The first thing you need to do is initialize the scene.
var renderer: SKRenderer
var skScene: SKScene
in your init function:
renderer = SKRenderer(device: device)
// iphone 11 portrait
skScene = SKScene(size: CGSize(width: 1125, height: 2436))
renderer.scene = skScene
let winner = SKLabelNode(fontNamed: "Chalkduster")
winner.text = "You Win!"
winner.fontSize = 65
winner.fontColor = SKColor.red
winner.position = CGPoint(x: 1125 / 2, y: 2436 / 2)
skScene.addChild(winner)
and finally in your render function:
renderer.render(withViewport: viewport, renderCommandEncoder: renderEncoder, renderPassDescriptor: renderPassDescriptor, commandQueue: commandQueue)
renderEncoder.endEncoding()
but keep in mind ui layer (SKRenderer) should be rendered in the last pass.
Related
I can't get SKCropNode to cooperate. I've played with this for HOURS I've copied verbatim hackingwithswifts guide and the only difference being my image and it will not work. So then I dumbed it down for myself with the code below and it still doesn't work.
I've tried the guide directly from hacking with swift and it didn't work. I copied code directly from apple documentation that also didn't work. I've wasted wayyyy too much time on the simple task of cropping an image.
import SpriteKit
import GameplayKit
import UIKit
class ProcGenPlanet: SKScene{
//Background
//let background = SKSpriteNode()
var square = SKSpriteNode()
override func didMove(to view: SKView) {
square = SKSpriteNode(imageNamed: "redSquare")
square.size = CGSize(width: 1000, height: 1000)
square.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
let mask = SKSpriteNode(color: SKColor.black, size: CGSize(width: 100, height: 100))
let cropNode = SKCropNode()
cropNode.maskNode = mask
cropNode.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
cropNode.addChild(square)
}
}
I am creating 1000x1000 red square. The whole image is red. Then I am trying to crop it to 100x100 with the following code but instead NOTHING shows up.
Currently, when running this code, a colored ball runs from the top of the screen to the bottom. When it reaches the bottom it respawns at the top and drops again. I need the ball to change to a random color each time it spawns again. I have a colorChange action but it still doesn't change the color of the ball when it runs.
import SpriteKit
class GameScene: SKScene {
let ball = SKShapeNode(circleOfRadius: 20)
let label = SKLabelNode(fontNamed: "Futura")
let colorChange = SKAction.colorizeWithColor(.blueColor(), colorBlendFactor: 1, duration: 1)
let randomRed = Int(arc4random_uniform(255))
let randomGreen = Int(arc4random_uniform(255))
let randomBlue = Int(arc4random_uniform(255))
override func didMoveToView(view: SKView) {
let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = sceneBody
//Ball Transition
let ballTransition = SKAction.sequence([SKAction.fadeInWithDuration(1)])
ball.runAction(ballTransition)
ball.fillColor = UIColor(red: 100, green: 100, blue: 0, alpha: 1)
ball.physicsBody = SKPhysicsBody(circleOfRadius: 25)
ball.physicsBody?.affectedByGravity = false
ball.position = CGPoint(x: self.frame.size.width/2, y: CGFloat(self.frame.size.height*1))
ballMovement()
self.addChild(ball)
self.addChild(label)
}
func ballMovement() {
let moveBall = SKAction.moveToY(0, duration: 3)
let goBackUp = SKAction.moveToY(self.frame.size.height, duration:0)
let keepFalling = SKAction.sequence([moveBall, goBackUp, colorChange])
ball.runAction(SKAction.repeatActionForever(keepFalling))
//Label Sprite
label.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
label.fontColor = SKColor.redColor()
label.fontSize = 30
}
override func update(currentTime: CFTimeInterval) {
label.text = "\(ball.position.y)"
if ball.position.y < 26 {
ball.position = CGPoint(x: self.frame.size.width/2, y: CGFloat(self.frame.size.height*1))
}
}
}
Instead of using an SKAction to change the color, just do
ball.color = UIColor...
To generate a random color check this out: How to make a random background color with Swift
and use that to generate a random color
ball.color = .randomColor()
I suggest you don't use an SKShape for an important piece that moves because I find that they can slow down the app and cause problems. I would use an SKSpritenode instead for the ball. If you then make the ball default as all white, you can change the colour by doing this:
ball.colorBlendFactor = 1
ball.color = SKColor(hue: randomNumberFunctionBetweenZeroAndOne(), saturation: 0.75, contrast: 0.5)
The hue should be a random value between 0 and 1.
If you put this inside a function, you could call the function to change the colour of the ball inside and SKAction or anywhere else.
I have a ship that moves based on the direction of gravity which is changed by the accelerometer, but I want it to only move along the width of the screen (I already know how to do that), but I do not know how to keep it on a fixed horizontal line. Here's my code
class GameScene: SKScene {
var manager = CMMotionManager()
var ship = SKSpriteNode()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let shipTexture = SKTexture(imageNamed: "EvadersShipVert2.png")
ship = SKSpriteNode(texture: shipTexture)
ship.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) - 250)
ship.size = CGSize(width: 90, height: 115)
shipTexture.filteringMode = SKTextureFilteringMode.Nearest
ship.zPosition = 2
ship.physicsBody = SKPhysicsBody(texture: shipTexture, size: CGSize(width: 90, height: 115))
ship.physicsBody?.dynamic = true
self.addChild(ship)
manager.startAccelerometerUpdates()
manager.accelerometerUpdateInterval = 0.1
manager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
(data, error) in
self.physicsWorld.gravity = CGVectorMake(CGFloat((data?.acceleration.x)!), CGFloat((data?.acceleration.y)!))
}
}
thanks in advance!
Replace
self.physicsWorld.gravity = CGVectorMake(CGFloat((data?.acceleration.x)!), CGFloat((data?.acceleration.y)!))
With
self.physicsWorld.gravity = CGVectorMake(0.0, CGFloat((data?.acceleration.y)!)
So you're not affecting the x position
So, i am creating a game and I'm trying to code physics boundaries for the hero so he doesn't just fall through the floor on launch lol, So i implemented my scene and I'm trying to create an alpha mask texture physics body on my "desertForeground" and i don't get any errors, however it keeps crashing and i get this error and the debugging doesn't tell me much, it just basically says invalid instruction but doesn't tell me why is wrong. Can anybody help me out? I'm pretty new to coding physics bodies in swift
import SpriteKit
enum BodyType:UInt32 {
case hero = 01
case bullet1 = 010
case enemy1 = 0100
case enemy2 = 01000
case enemy3 = 010000
case desertForegroundCase = 02
}
class GameScene: SKScene, SKPhysicsContactDelegate {
let desertBackground = SKSpriteNode (imageNamed: "RZ-
DesertBackground.png")
let desertForeground = SKSpriteNode (imageNamed: "RZ-
DesertForeground.png")
let desertgully = SKSpriteNode (imageNamed: "RZ-DesertGully.png")
override func didMoveToView(view: SKView) {
CreateScene()
}
func CreateScene (){
desertForeground.position = CGPoint(x: 570 , y: 102)
desertForeground.size = CGSize (width: 1136, height: 200)
desertForeground.zPosition = 1
let desertForegroundTexture = SKTexture()
let desertForegroundBody = SKPhysicsBody(texture:
desertForegroundTexture, size: CGSize(width: 1136, height: 200))
desertForeground.texture = desertForegroundTexture
desertForegroundBody.dynamic = true
desertForegroundBody.affectedByGravity = false
desertForegroundBody.allowsRotation = false
desertForegroundBody.categoryBitMask =
BodyType.desertForegroundCase.rawValue
desertForegroundBody.contactTestBitMask = BodyType.enemy1.rawValue
| BodyType.enemy2.rawValue | BodyType.enemy3.rawValue |
BodyType.soldierL.rawValue | BodyType.soldierT.rawValue
desertForeground.physicsBody = desertForegroundBody
}
}
The problem is how you populate desertForegroundTexture.
Replace this
let desertForegroundTexture = SKTexture()
with this
let desertForegroundTexture = SKTexture(imageNamed: "YOUR_IMAGE_NAME")
Your issue come when you try to create a physicBody from an empty texture:
/**
Creates a body from the alpha values in the supplied texture.
#param texture the texture to be interpreted
#param size of the generated physics body
*/
#available(iOS 8.0, *)
public /*not inherited*/ init(texture: SKTexture, size: CGSize)
In fact, for example this kind of thing don't happened if your try to create a SKSpriteNode like this:
let desertForegroundTexture = SKTexture()
desertForeground = SKSpriteNode(texture: desertForegroundTexture, size:CGSize(width: 1136, height: 200))
I'm trying to create a rectangle using swift on Sprite kit, since the rectangle needs to be used as an object in the scene, i assumed that i needed to create a SkSpriteNode, and them give it a size, but it did not worked, this is how i did it:
var barra = SKSpriteNode()
barra.name = "bar"
barra.size = CGSizeMake(300, 100)
barra.color = SKColor.whiteColor()
barra.position = CGPoint(x: 100, y: 100)
self.addChild(barra)
Adding barra to the screen does not change the node counting.
Any help will be appreciated!
You may want to use a SKShapeNode, like this:
var barra = SKShapeNode(rectOfSize: CGSize(width: 300, height: 100))
barra.name = "bar"
barra.fillColor = SKColor.whiteColor()
barra.position = location
self.addChild(barra)
Here's Apple's documentation on SKShapeNode.
The way I was creating the rectangle was not the best, but the problem was the position I was inserting it on the game. This is how I've fixed it:
var barra = SKSpriteNode(color: SKColor.blackColor(), size: CGSizeMake(200, 200))
barra.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
barra.zPosition = 9 // zPosition to change in which layer the barra appears.
self.addChild(barra)