write string on sprite kit - swift

I am trying to make a game with a goat that walks a small rode and you needs to tap it as many times as its number, but i don't know how to write the string. Does anyone know?
I need a code like this:
var baloonImage = SKSpriteNode(imageNamed: "ballong")
goatImage.position = CGPointMake(CGFloat(startLocGoatX), CGFloat(startLocGoatY))
goatImage.name = goatName
goatImage.text = "5"
self.addChild(goatImage)
Does anyone know how to make the text? And if you know; how can I change it?

you need to add SKLabelNode.
var node = SKLabelNode(fontNamed:"Futura Medium")
node.text = "Hello world!"
node.fontColor = SKColor.whiteColor()
node.fontSize = 20
node.position = CGPointMake(x, y)
self.addChild(node)

Related

ARkit SCNMorpher isn't working for me. No errors, just no shape changes

I'm trying a simple example using SCNMorpher to blend between to poly spheres. They are identical in topology except for the position of the points
Each is stored in a .scn file and I get the shapes like:
sphereNode = SCNReferenceNode(named: "sphere")
sphereNode2 = SCNReferenceNode(named: "sphere2")
sphereNode?.morpher = SCNMorpher()
sphereNode!.morpher?.targets = [(sphereNode2?.childNodes.first!.geometry)!]
sphereNode!.name = "EFFECT"
I'm using the faceAnchor blend shapes to drive it
if let effectNode = sceneView?.scene.rootNode.childNode(withName: "EFFECT", recursively: true) {
let v = faceAnchor?.blendShapes[ARFaceAnchor.BlendShapeLocation.jawOpen]
effectNode.morpher?.setWeight(v as! CGFloat, forTargetNamed: "sphere2")
}
I've also tried:
...
effectNode.morpher?.setWeight(v as! CGFloat, forTargetAt: 0)
...
The code runs.. I can print values for v.. they change as I open/close my jaw and that value is passed to the morpher. I see the base sphere shape but it never deforms toward the sphere2 shape. Am I suppose to do anything else to force it to redraw or calc the deformation?
Hmm. looks like I was attaching the morpher to the parent of the shape, not the actual sphere.. funny how asking a question here sometimes creates that "Ah Ha" moment. Reading in my spheres like this fixed it:
sphereNode = SCNReferenceNode(named: "sphere").childNodes.first
sphereNode2 = SCNReferenceNode(named: "sphere2").childNodes.first
sphereNode?.morpher = SCNMorpher()
sphereNode!.morpher?.targets = [(sphereNode2.geometry)!]
sphereNode!.name = "EFFECT"

Gamescene spriteNodes in array

Getting an error on this pice of code.
I Don't want to go through the spriteNode on GameScene.sks manually (in code) - the for loop must work somehow? Any ideas...
let sprites:[SKSpriteNode] = [block1, block2, block3, block4,
block5, block6, block7, block8, block9, block10, block11,
block12, block13, block14, block15, block16, block17,
block18, block19, block20, block21, block22, block23,
block24, block25, block26, block27, block28, block29,
block30, block31, block32, block33, block34, block35,
block36, block37, block38, block39, block40, block41,
block42, block43, block44, block45, block46, block47,
block48, block49, block50, block51, block52, block53,
block54, block55, block56, block57, block58, block59,
block60, block61, block62, block63, block64, block65,
block66, block67, block68, block69, block70, block71,
block72, block73, block74, block75, block76, block77,
block78, block79, block80, block81, block82, block83, block84]
for sprite in sprites {
self.sprite; in sprites = (self.childNode(withName: sprite.name) as? SKSpriteNode)!
sprite.name = "Green"
sprite.zPosition = 3
}
I'm guessing that from your not very descriptive description that you have a bunch of SKSpriteNodes in your .sks file and you want to loop through them in code to setup them up???
something like this might work better for you, if that is indeed what you are looking for.
let spriteNames: [String] = ["block1", "block2", "block3"]
let sprites = [SKSpriteNode]()
for spriteName in spriteNames {
if let sprite = self.childNode(withName: spriteName) as? SKSpriteNode {
sprite.name = "Green"
sprite.zPosition = 3
sprites.append(sprite)
}
}

Setting up a 3D model on a Marker using Kudan and Swift

This might be the result of a beginner trying to do something too complex, but I'm trying to use Kudan to model a 3D object on a marker. However, I'm getting the EXC_BAD_ACCESS error. Here is my code as it stands:
func setupModel() {
let trackerMan = ARImageTrackerManager.getInstance()
trackerMan.initialise()
let trackable = trackerMan.findTrackableByName("image1")
let importer = ARModelImporter(bundled: "Horse.armodel") //ERROR IS HERE
let modelNode: ARModelNode = importer.getNode()
let mTexture = ARTexture(UIImage: UIImage(named: "map.jpg"))
let tMaterial = ARTextureMaterial(texture: mTexture)
for i in 0..<modelNode.meshNodes.count {
let meshNode: ARMeshNode = modelNode.meshNodes[i] as! ARMeshNode
meshNode.material = tMaterial
}
modelNode.rotateByDegrees(90, axisX: 1, y: 0, z: 0)
modelNode.scaleByUniform(10)
trackable.world.addChild(modelNode)
}
Here is what the console tells me "(lldb)" (as far as I understand it, nothing), and I get "tMaterial ARTextureMaterial! nil" in the screen next to the console.
Can somebody shed some light?
Thanks!
Check 「Build Phases」 → 「Copy Bundle Resources」.
Is Horse.armodel there?

Pathfinding no longer works after blocking and unblocking path

I have a map with obstacles that can be placed by the user. And sprites that move from the right of the map to the left.
As the user places obstacles they're added to my game's graph (GKObstacleGraph) and each time I check if a path from the start point to the end point is available. If it's not, it means the user has blocked the path entirely, so I remove the placed obstacle.
That should open the path up again, however it doesn't. It's as if the obstacle is still there.
I have a debug function which loops through all the obstacles in my graph node, showing me visually where they are. It runs each time I add an obstacle. And after I place an obstacle that blocks the path (which is then removed immediately) it shows that there is no obstacle there. The path is clear.
func createObstacle(coordinates: CCCordinates) {
let tX = -game.mapSize.widthHalf + (coordinates.x*game.tileSize.value) + (game.tileSize.valueHalf)
let tY = game.mapSize.heightHalf - (coordinates.y*game.tileSize.value) - (game.tileSize.valueHalf)
let obstacle = CCObstacle(color: color.red, size: game.obstacleSize.size)
obstacle.position = CGPoint(x: tX, y: tY)
let polygonObstacle = getPolygonObstacleForSpriteNode(obstacle)
game.graph.addObstacles([polygonObstacle])
let pathClear = checkPath()
print("Path Clear: \(pathClear)")
if pathClear {
let texture = SKTexture(imageNamed: "obstacle")
obstacle.texture = texture
obstacle.coordinates = coordinates
obstacle.name = "obstacle:\(obstacle.coordinates.convertToString())"
obstacle.zPosition = 5
for var i = 0; i < game.sprites.count; i++ {
let sprite = game.sprites[i]
updatePathForSprite(sprite)
}
panels.map.addChild(obstacle)
} else {
game.graph.removeObstacles([polygonObstacle])
print("removedObstacle")
}
drawAllObstacleOutlines()
}
This code works perfectly until pathClear returns false and the code in else runs. Even though the obstacle is removed from the graph (and the drawAllObstacleOutlines() function confirms that) pathClear always returns false afterwards.
Unless I use:
game.graph.removeAllObstacles()
If I replace the removeObstacles([]) line with that line above. It lets me place obstacles again. (It works even if I add back all the obstacles that were removed, excluding the one that blocked the path.)
The function updatePathForSprite basically calls this one below:
func getPathForNodeToEndPoint(startPoint: CGPoint) -> [GKGraphNode] {
let startNode = GKGraphNode2D(point: float2(Float(startPoint.x), Float(startPoint.y)))
let endNode = GKGraphNode2D(point: float2(Float(game.finishPoint.x), Float(game.finishPoint.y)))
game.graph.connectNodeUsingObstacles(startNode, ignoringBufferRadiusOfObstacles: game.outerTileObstacles)
game.graph.connectNodeUsingObstacles(endNode, ignoringBufferRadiusOfObstacles: game.outerTileObstacles)
let path:[GKGraphNode2D] = game.graph.findPathFromNode(startNode, toNode: endNode) as! [GKGraphNode2D]
game.graph.removeNodes([startNode, endNode])
return path
}
Does anyone know what's going on here?
EDIT: I may have found something weird.
When I add the following lines above the drawAllObstacleOutlines() line:
print("Obstacles \(game.graph.obstacles.count)")
print("Nodes \(game.graph.nodes!.count)")
It increases as I add obstacles... In my case, nodes is 404 and obstacles is 101, however when I place the obstacle that blocks the path, the output is: obstacles 101, Nodes 0
For some reason it's removing all the other nodes in the graph, even though I only removed one obstacle.

GameplayKit Pathfinding with obstacles and agents

I've been searching for days about this new framework and trying to make usage of some of it's funcionalities,
but... there're some things that are not fitting together for me, the demobot source code isn't helping at some points,
I miss some kind of simple tutorial but here goes my main doubts:
let obstacles = scene["obstacle"]
polygonObstacles = SKNode.obstaclesFromNodePhysicsBodies(obstacles)
graph = GKObstacleGraph(obstacles: polygonObstacles, bufferRadius: 60.0)
func drawGraph() {
for node in graph.nodes as! [GKGraphNode2D] {
for destination in node.connectedNodes as! [GKGraphNode2D] {
let points = [CGPoint(node.position), CGPoint(destination.position)]
let shapeNode = SKShapeNode(points: UnsafeMutablePointer<CGPoint>(points), count: 2)
shapeNode.strokeColor = SKColor(white: 1.0, alpha: 0.5)
shapeNode.lineWidth = 5.0
shapeNode.zPosition = 3
scene.addChild(shapeNode)
}
}
}
So, when I try to draw this graph and see the connections, I get this: http://i.imgur.com/EZ3dx5v.jpg
I find it really weird, anywhere I put my obstacles, even in low numbers, the left-corner portion of the screen have always more connections(the radius don't have influence on that)
I don't use GKComponents on my game, but I tried to run some GKAgents2D to hunt the player, like this:
func calculateBehaviorForAgents(){
let mainCharacterPosition = float2(scene.mainCharacter.position)
let mainCharacterGraphNode = GKGraphNode2D(point: mainCharacterPosition)
graph.connectNodeUsingObstacles(mainCharacterGraphNode)
for i in 0...monsters.count-1{
let monster = monsters[i]
let agent = agents[i]
let behavior = GKBehavior()
let monsterPosition = float2(monster.position)
let monsterGraphNode = GKGraphNode2D(point: monsterPosition)
graph.connectNodeUsingObstacles(monsterGraphNode)
let pathNodes = graph.findPathFromNode(monsterGraphNode, toNode: mainCharacterGraphNode) as! [GKGraphNode2D]
let path = GKPath(graphNodes: pathNodes, radius: 00.0)
let followPathGoal = GKGoal(toFollowPath: path, maxPredictionTime: 1.0, forward: true)
behavior.setWeight(1.0, forGoal: followPathGoal)
let stayOnPathGoal = GKGoal(toStayOnPath: path, maxPredictionTime: 1.0)
behavior.setWeight(1.0, forGoal: stayOnPathGoal)
agent.behavior = behavior
graph.removeNodes([monsterGraphNode])
}
graph.removeNodes([mainCharacterGraphNode])
}
Now when I call the updateWithDeltaTime method, his delegate methods:
func agentWillUpdate(agent: GKAgent){}
func agentDidUpdate(agent: GKAgent){}
give me unexpected values for the agents, it's position doesn't make any sense, with giant numbers that leads to outside of the battlefield
But I saw that the his velocity vector were making sense, so I matched it to my monster and updated the agent to the monster's position
func updateWithDeltaTime(currentTime : CFTimeInterval){
for i in 0...monsters.count-1{
let agent = agents[i]
let monster = monsters[i]
monster.physicsBody?.velocity = CGVectorMake(CGFloat(agent.velocity.x), CGFloat(agent.velocity.y))
agent.updateWithDeltaTime(currentTime)
agent.position = float2(monster.position)
monster.gameSceneUpdate(currentTime)
}
Now I was getting some results, but it's far away from what I want:
The monsters are not following the character to the edges or the right-top portion of screen, I remove their points from the graph but after make a path for them to follow (the image doesn't have this points, but they exists).
Apparently because there was no path leading to there, remember the image?
The question is: how to make this agent system to work?
Maybe I'm totally wrong at the usage of agents, goals and even the graphs! I read the documentation but I still can't make it right
And more...
At first, the monster were not avoid obstacles, even with GKGoals like "avoidObstacles", passing the same PolygonObstacles,
but when I change
graph.connectNodeUsingObstacles(mainCharacterGraphNode)
graph.connectNodeUsingObstacles(monsterGraphNode)
to
graph.connectNodeUsingObstacles(mainCharacterGraphNode, ignoringObstacles: polygonObstacles)
graph.connectNodeUsingObstacles(monsterGraphNode, ignoringObstacles: polygonObstacles)
it worked! o.O
I really need some help, thank you all :D!