Project 11 Pachinko
SpriteKit 的point 0,0 表示某一个node的水平、竖直的中心点,Y坐标起始于底部,Y越大,在屏幕的位置越靠上。
didMoveToView() 类似于 viewDidLoad()1
2
3
4
5let background = SKSpriteNode(imageNamed: "background.jpg")
background.zPosition = -1 // behind everything else
background.blendMode = .Replace // just draw it, ignoring any alpha values
addChild(background)
physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) //给整个屏幕添加PhysicsBody在屏幕点击处绘制一个box,包括颜色、大小、physicsBody
1
2
3
4
5
6
7
8
9override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
let location = touch.locationInNode(self)
let box = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 64, height: 64))
box.position = location
box.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 64, height: 64))
addChild(box)
}
}被碰撞后不会被移动
1
bouncer.physicsBody!.dynamic = false
设置旋转动作,包括弧度、时间间隔。
1
2
3let spin = SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10) // 每隔10秒旋转90°
let spinForever = SKAction.repeatActionForever(spin) // 永不停止
slotGlow.runAction(spinForever)physicsBody的 contactTestBitMask 赋值给 collisionBitMask
1
2physicsWorld.contactDelegate = self
ball.physicsBody!.collisionBitMask = ball.physicsBody!.contactTestBitMask将一个node移除
SKNode.removeFromParent()
判断接触的bodyA和bodyB
1
2
3
4
5
6
7func didBeginContact(contact: SKPhysicsContact) { //override
if contact.bodyA.node!.name == "ball" {
collisionBetweenBall(contact.bodyA.node!, object: contact.bodyB.node!)
} else if contact.bodyB.node!.name == "ball" {
collisionBetweenBall(contact.bodyB.node!, object: contact.bodyA.node!)
}
}使用 didSet 属性观察器
1
2
3
4
5
6
7var scoreLabel: SKLabelNode!
var score: Int = 0 {
didSet {
scoreLabel.text = "Score: \(score)"
}
}
let objects = nodesAtPoint(location) as [SKNode] // 获取到location的nodes使用 GKRandomDistribution 方法设置随机数的上限、下限
1
2let size = CGSize(width: GKRandomDistribution(lowestValue: 16, highestValue: 128).nextInt(), height: 16) //生成16-128的Int类型随机数
box.zRotation = RandomCGFloat(0, max: 3) //随机的旋转,0-3的范围使用 SKEmitterNode 方法,火焰粒子效果
1
2
3
4if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
fireParticles.position = ball.position
addChild(fireParticles)
}
Project 12 NSUserDefaults
as? 和 ?? 的用法
1
let array = defaults.objectForKey("SavedArray") as? [String] ?? [String]()
使用 NSUserDefault 需要遵守 NSCoding 协议
1
2
3
4
5
6
7
8
9required init(coder aDecoder: NSCoder) { // required表示必须要实现这个方法
name = aDecoder.decodeObjectForKey("name") as! String // 解密
image = aDecoder.decodeObjectForKey("image") as! String
}
// 加密
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: "name")
aCoder.encodeObject(name, forKey: "image")
}将 array 类型转换为 NSData 类型。
1
2
3
4
5
6func save() {
// converts array into an NSData object
let savedData = NSKeyedArchiver.archivedDataWithRootObject(people)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savedData, forKey: "people")
}取出optional NSData,convert it back to an object graph
1
2
3
4let defaults = NSUserDefaults.standardUserDefaults()
if let savedPeople = defaults.objectForKey("people") as? NSData {
people = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [Person]
}NSUserDefaults是不安全的,如果涉及私密信息,可以用keychain替代.
Project 13 Instafilter
使用 CIContext CIFilter
1
2context = CIContext(options: nil)
currentFilter = CIFilter(name: “CISepiaTone")使用 CIImage
1
2let beginImage = CIImage(image: currentImage)
currentFilter.setValue(beginImage, forKey: kCIInputImageKey)将 CGImage 转换为 UIImage
1
2
3
4
5
6func applyProcessing() {
currentFilter.setValue(intensity.value, forKey: kCIInputIntensityKey)
let cgimg = context.createCGImage(currentFilter.outputImage!, fromRect: currentFilter.outputImage!.extent)
let processedImage = UIImage(CGImage: cgimg)
imageView.image = processedImage
}presentViewController(xxxxx, animated: true, completion: nil)
把其中的xxxxx写成self导致运行时错误。- UIImagePickerControllerEditedImage 少写Picker导致import图片后,无法继续操作。
先判断input keys 是否存在,然后判断是否包括 kCIInputIntensityKey
1
2
3
4let inputKeys = currentFilter.inputKeys
if inputKeys.contains(kCIInputIntensityKey) {
currentFilter.setValue(intensity.value, forKey: kCIInputIntensityKey)
}将 imageView 写入图片库
1
UIImageWriteToSavedPhotosAlbum(imageView.image!, self, "image:didFinishSavingWithError:contextInfo:", nil)
写入图片库时的错误处理,使用 NSError,localizedDescription 显示具体的错误信息。
1
2
3
4
5
6func image(image: UIImage!, didFinishSavingWithError error: NSError?, contextInfo: UnsafePointer<Void>) {
let ac = UIAlertController(title: "Save error!", message: error?.localizedDescription, preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
}