I want to create a Sprite that has an alpha value and sits on top of some other nodes.
let objects = SKSpriteNode(imageNamed: "objects")
let blurredOverlay = SKSpriteNode(imageNamed: "overlay")
addChild(objects)
addChild(blurredOverlay)
My intention is to add a visual effect to the 'blurredOverlay' Node so that only the nodes that are overlapped by this node show the blurred effect?
Anyone with an idea?
This answer take and modify code from: Add glowing effect to an SKSpriteNode
For you solution:
Swift 3
let objects = SKSpriteNode(imageNamed: "objects")
let blurredOverlay = SKSpriteNode(imageNamed: "overlay")
let effectNode = SKEffectNode()
effectNode.shouldRasterize = true
effectNode.zPosition = 1
effectNode.alpha = 0.5
effectNode.addChild(SKSpriteNode(texture: blurredOverlay.texture))
effectNode.filter = CIFilter(name: "CIGaussianBlur", withInputParameters: ["inputRadius":30])
objects.addChild(effectNode)
addChild(objects)
Example: (Up tree have a blurredOverlay)
On the example images "objects" and "overlay" are the same image.
Related
I am trying to make an MKPolyline for a SwiftUI map where it shows a persons location for a day and I want a gradient changing from blue to green from the first point in their location to the last point in blue. I have this code
renderer.strokeColor = NSGradient(colors: [NSColor.blue, NSColor.green])
I have also tried
renderer.strokeColor = NSColor(NSGradient(colors: [NSColor.blue, NSColor.green]))
and
renderer.strokeColor = NSColor(Color(Gradient(colors: [Color.blue, Color.green])))
but these all return errors about turning Gradients into colors. Thanks!
Thanks to #vadian I did this
if let routePolyline = overlay as? MKPolyline {
let renderer = MKGradientPolylineRenderer(polyline: routePolyline)
renderer.setColors([NSColor.blue, NSColor.green], locations: [])
renderer.lineWidth = 2
return renderer
}
I have created a ball node, and applied the texture images from my 3d model. I have captured totally 6 images, 3 images (with having 120deg) for rolling around x axis, and other 3 images for rolling around y axis. I want sprite kit to simulate it with following code below.When i apply impulse, it starts sliding instead rolling and when it collides to sides, then it starts turning but again not rolling. Normally, depending on the impulse on the ball, it should turn and roll together sometimes. The effect on "8 ball pool game" balls can be an example which i want to get a result.
var ball = SKSpriteNode()
var textureAtlas = SKTextureAtlas()
var textureArray = [SKTexture]()
override func didMove(to view: SKView) {
textureAtlas = SKTextureAtlas(named: "white")
for i in 0... textureAtlas.textureNames.count {
let name = "ball_\(i).png"
textureArray.append(SKTexture(imageNamed: name))
}
ball = SKSpriteNode(imageNamed: textureAtlas.textureNames[0])
ball.size = CGSize(width: ballRadius*2, height: ballRadius*2)
ball.position = CGPoint(x: -ballRadius/2-20, y: -ballRadius-20)
ball.zPosition = 0
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballRadius)
ball.physicsBody?.isDynamic = true
ball.physicsBody?.restitution = 0.3
ball.physicsBody?.linearDamping = 0
ball.physicsBody?.allowsRotation = true
addChild(ball)}
You need to apply angular impulse to get it to rotate
node.physicsBody!.applyAngularImpulse(1.0)
I ask this question because i didn't found any solution for this kind of issues. In fact Hex map support are not very popular.
I'am making a game with the SpriteKit Framework. I use SktileMapNode with an Hexagonal map, with 1 set of 4 groups tiles.
The playernode moves on each tiles, what i wan't it's when he move on a specifics tiles some event can be triggered ( print , function , Sktransition) but for the moment i'm stuck on just detecting those tiles.
I setup the user data ( as bool ) and apply them in the code , but nothing happened, even with a touch event on a tile.
extension GameScene {
func move(theXAmount:CGFloat , theYAmount:CGFloat, theAnimation:String ) {
let wait:SKAction = SKAction.wait(forDuration: 0.05)
let walkAnimation:SKAction = SKAction(named: theAnimation, duration: moveSpeed )!
let moveAction:SKAction = SKAction.moveBy(x: theXAmount, y: theYAmount, duration: moveSpeed )
let group:SKAction = SKAction.group( [ walkAnimation, moveAction ] )
let finish:SKAction = SKAction.run {
let position = self.thePlayer.position
let column = self.galaxieMapnode.tileColumnIndex(fromPosition: position)
let row = self.galaxieMapnode.tileRowIndex(fromPosition: position)
if let tile:SKTileDefinition = self.galaxieMapnode.tileDefinition(atColumn: column, row: row) {
if let tileBoolData = tile.userData?["wormholeTile"] as? Bool {
if (tileBoolData == true) {
print("Wormhole touched")
}
}
} else {
print("different tile")
}
}
Only the "different tile " output is fired.
Any help are welcome.
Link for image example : the thing I want
I think you want to run your finish block after the other actions have completed? You can do this as a sequence.
var sequence = [SKAction]()
let action = SKAction.move(to: location, duration: 1)
let completionHandler = SKAction.run({
// Check tile info here
})
sequence += [action, completionHandler]
self.player.run(SKAction.sequence(sequence))
Typically in a hexagonal map you would move the player to an adjacent tile and check the tiles attributes, then continue with the next move action. This requires the graph and pathfinding functionality from GameplayKit.
How can I attach a video input to a SCNProgram in SceneKit?
Without using a custom program, I could do:
func set(video player: AVPlayer, on node: SCNNode) {
let size = player.currentItem!.asset.tracks(
withMediaType: AVMediaTypeVideo).first!.naturalSize
let videoNode = SKVideoNode(avPlayer: player)
videoNode.position = CGPoint(x: size.width/2, y: size.height/2)
videoNode.size = size
let canvasScene = SKScene()
canvasScene.size = size
canvasScene.addChild(videoNode)
let material = SCNMaterial()
material.diffuse.contents = canvasScene
node.geometry?.materials = [material]
}
which renders the video to a SKScene and uses it as an input for a SCNMaterial.
I'd like to use a SCNProgram on the node, but I could not figure out to attach the player input. I don't mind if the solution doesn't uses a SKScene intermediate rendering. It actually sounds even better if it's possible to do without.
Have you tried using AVPlayerLayer, which is a subclass of CALayer ? You can feed a CALayer to the contents property of an SCNMaterialProperty.
I'm having issues with creating a subpath on a path that has been transformed. It seems that the subpath is generated with the original position of the path in reference rather than the post transform location of the path. How do I get around this?
var paper = new Raphael("canvas");
var lineParams = {
fill: "#ff0",
gradient: "90-#526c7a-#64a0c1",
stroke: "#3b4449",
"stroke-width": 2
};
var line1 = paper.path("M 0 50 h 200").attr(lineParams);
line1.transform("T100,100");
if (line1 != null) {
var lineBBox = line1.getBBox()
var lineEnd = lineBBox.x2 - lineBBox.x;
var lineTipStart = lineEnd - 10;
var lineTipString = line1.getSubpath(lineTipStart, lineEnd);
var lineTip = paper.path(lineTipString);
lineTip.attr({
"stroke-width": 2,
stroke: '#FF0000'
});
}
http://jsfiddle.net/nzwthkmo/1/
Its not so much a case of getting around it, as realising what its doing, and deciding how you want to approach it.
The original path has a transform applied to it, the path is still exactly the same. So do you want the same thing (maybe your code will be expecting that), or do you want a new modified path with new baked coordinates with the transform in place.
So depending on what you will do in the future with it, you could either
a) Simply apply the same transform to the subpath...
var lineTip = paper.path(lineTipString).transform("T100,100");
or
b) create a new path where the coordinates are all permanently transformed...
var lineTip = paper.path( Raphael.transformPath(lineTipString, "T100,100") )
fiddle with both examples (one commented out).