I'm new to iOS and trying to practice falling animation like Yolo app.
What Yolo app has is on sign up page, it has bunch of falling emojis at different velocity seamlessly.
So if I want to implement the falling animation for each emojis and without using storyboard and SwiftUI(so with Appkit), what's the common practice here.
Is there any library I can use?
let emitterLayer = CAEmitterLayer()
emitterLayer.emitterPosition = CGPoint(x: 200, y: 200)
let cell = CAEmitterCell()
cell.birthRate = 10
cell.lifetime = 1
cell.velocity = 100
cell.scale = 0.1
cell.emissionRange = CGFloat.pi * 2.0
cell.contents = UIImage(named: "yes")!.cgImage
emitterLayer.emitterCells = [cell]
view.layer.addSublayer(emitterLayer)
Related
I'm currently making a game with Spritekit and struggling to figure out why my normalized Textures are not being applied properly when rendering on device, while they seem to be fine in the simulator.
Here is the code that adds the normal textures to the tile definitions, among other things:
self.wallTileMap = self.scene?.childNode(withName: "Walls") as? SKTileMapNode
let textureAtlas = SKTextureAtlas(named: "Wall Normal Maps")
if let tileMap = self.wallTileMap {
let startingLocation:CGPoint = tileMap.position
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
let rows = tileMap.numberOfRows
let columns = tileMap.numberOfColumns
for column in 0..<columns {
for row in 0..<rows {
let x = CGFloat(column) * tileSize.width - halfWidth + (tileSize.width / 2)
let y = CGFloat(row) * tileSize.height - halfHeight + (tileSize.height / 2)
if let tileDefinition = tileMap.tileDefinition(atColumn: column, row: row) {
if let name = tileDefinition.name {
let normalTexture = textureAtlas.textureNamed("\(name)_n")
tileDefinition.normalTextures = [normalTexture]
}
if (tileDefinition.userData?["shouldKill"] as? Bool ?? false) {
let newNode = SKShapeNode(rectOf: tileDefinition.size)
newNode.position = CGPoint(x: x, y: y)
newNode.isHidden = true
newNode.physicsBody = SKPhysicsBody(texture: tileDefinition.textures[0], size: tileDefinition.size)
newNode.physicsBody?.isDynamic = false
newNode.physicsBody?.affectedByGravity = false
newNode.physicsBody?.categoryBitMask = CollisionTypes.wall.rawValue
newNode.physicsBody?.collisionBitMask = CollisionTypes.dynamicComponents.rawValue
newNode.physicsBody?.contactTestBitMask = CollisionTypes.dynamicComponents.rawValue
self.addChild(newNode)
newNode.position = CGPoint(x: newNode.position.x + startingLocation.x, y: newNode.position.y + startingLocation.y)
}
}
}
}
}
The result for simulator--which is expected:
The result on device--which is incorrect:
I tried multiple simulators, it worked on them all. I've also tried multiple physical devices and it was broken on all of them.
The only thing that I could find while debugging is that the normal images on device seemed to be off by one pixel in size occasionally. So the normal size is 128 x 128 and occasionally the size on device would be 128 x 127 or 127 x 127. No clue what could cause this, nor if that is the actual problem.
Does anyone have any ideas as to why the normal maps would be rendered properly in the simulator, but not on device?
How can I make an arrow swing like in this video?
So far, I can rotate my node back and forth like in this video using the following code in didMove(to:) in my SKScene:
// Ball
let ballNode = SKSpriteNode(imageNamed: "Ball")
let offsetFromCorner: CGFloat = 20
ballNode.position = CGPoint(x: frame.minX + ballNode.size.width / 2 + offsetFromCorner, y: frame.minY + ballNode.size.height / 2 + offsetFromCorner)
addChild(ballNode)
/* ... */
// Aim arrow
let aimArrowNode = SKSpriteNode(imageNamed: "AimArrow")
aimArrowNode.position.y += aimArrowNode.size.height / 2
ballNode.addChild(aimArrowNode)
ballNode.zRotation = -.pi / 18 * 8
let rotateUp = SKAction.rotate(toAngle: -.pi / 18, duration: 1)
let rotateDown = SKAction.rotate(toAngle: -.pi / 18 * 8, duration: 1)
let combinedActions = SKAction.sequence([rotateUp, rotateDown])
ballNode.run(SKAction.repeatForever(combinedActions))
However, I want the arrow to appear to "slow down" as it gets nearer to the edge. How can I achieve this?
If you have any questions, please ask!
Luckily, the answer is actually built into SKAction.
Just add these after you create the actions:
rotateUp.timingMode = .easeInEaseOut
rotateDown.timingMode = .easeInEaseOut
Now you get the effect I was looking for! :)
I have created measure demo which allow to put multiple points and show distance between them. which works fine
I want to show preview that what so far has been drawn in real world to the UIView using UIBezierPath . Just like http://armeasure.com/
I have tried many things to achieve this but I couldn't find any right way to do it.
if self.linkList.count == 1 {
bezierPath.removeAllPoints()
bezierPath.move(to: CGPoint(x: 10,y: 10))
} else {
guard self.linkList.count > 1 ,let object2 = self.linkList.lastNode, let object1 = self.linkList.lastNode?.previous else {return}
let value = self.getMeasurementXandYBetween(vector1: object1.node.mainNode.position, and: object2.node.mainNode.position)
print(value)
let x = Double((object1.node.mainNode.position.x + value ) * 377.9527559055 )
let y = Double((object1.node.mainNode.position.y + value) * 377.9527559055)
let pointCoordinates = CGPoint(x: x , y: y)
print("x : Y ",x,y)
bezierPath.addLine(to: pointCoordinates)
}
shapeLayer.removeFromSuperlayer()
shapeLayer.path = bezierPath.cgPath
shapeLayer.lineWidth = 0.5
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.position = CGPoint(x: 0, y: 0)
self.viewToDraw.layer.addSublayer(shapeLayer)
func getMeasurementXandYBetween(vector1:SCNVector3, and vector2:SCNVector3) -> Float {
return sqrtf((vector1.x - vector2.x) * (vector1.x - vector2.x) + (vector1.y - vector2.y) * (vector1.y - vector2.y))
}
The logic I used (which is not working is) Location of previous node + distance I got from getMeasurementXandYBetween multiply by 377.
Please suggest a hint or any other solution
You can get the coordinates of any point in screen-space by using the projectPoint() on your SCNSceneRenderer.
This will give you a vector with 3 elements, build your CGPoint using the first two and build your shape from those points.
After my game ends, I added a PNG file with custom font and tried adding score in front of it, but when the game is over, the PNG file gets added and instead of putting the score in front of it, it prints out the details of the PNG file like this, 'ScoreText' (150 x 50 ) position:(465.4356789)....
All of this is happening in my didBeginContact method:
let score = SKSpriteNode(imageNamed: "ScoreText")
score.position = CGPoint(x: size.width / 2.2, y: size.height / 1.9)
self.addChild(score)
let scoreTextNode = SKLabelNode(fontNamed: "Copperplate")
scoreTextNode.text = "\(score)"
scoreTextNode.fontSize = 12
scoreTextNode.fontColor = SKColor.whiteColor()
scoreTextNode.position = CGPoint(x: size.width / 1.1, y: size.height / 1.9)
addChild(scoreTextNode)
I'm building a 2D game and I'm looking to direct a node in a particular clockwise curve from the sky to the ground (like a bird would swoop down to the ground) in a clockwise motion with some friction to give the effect of a bird landing.
I've been playing around with 'physicsBody' but i cant seem to get the right curve, can anyone help... here is a picture of the curve I'm trying to achieve. http://www.theluxuryteam.com/uploads/shared/images/curved_arrow-black.png
Thank you
func addCrow() {
var crow = SKSpriteNode(imageNamed: "crow")
crow.physicsBody = SKPhysicsBody(rectangleOfSize: crow.size)
crow.physicsBody?.dynamic = true
crow.physicsBody?.collisionBitMask = 0
crow.physicsBody?.velocity = CGVector(dx: -200, dy: 0)
crow.physicsBody?.angularVelocity = 100
crow.physicsBody?.linearDamping = 0
crow.physicsBody?.angularDamping = 100
var random : CGFloat = CGFloat(arc4random_uniform(300))
crow.position = CGPoint(x: self.frame.size.width / 1.4, y: self.frame.size.height / 1.2 ) // 1.4 0.8
self.addChild(crow)
}