Swift - 跳跃吃苹果游戏开发(SpriteKit游戏开发)
(本文代码已升级至Swift3)
1,样例说明
(1)屏幕从右到左不断地生成苹果飞过来(苹果高度随机)
(2)点击屏幕可以让熊猫跳跃
(3)熊猫碰到苹果,苹果消失
2,运行效果

3,样例代码
苹果工厂类 AppleFactory.swift
import SpriteKit
class AppleFactory:SKNode{
//定义苹果纹理
let appleTexture = SKTexture(imageNamed: "apple")
//游戏场景的宽度
var sceneWidth :CGFloat = 0.0
//定义苹果数组
var arrApple = [SKSpriteNode]()
//定时器
var timer = Timer()
func onInit(_ width:CGFloat) {
self.sceneWidth = width
//启动的定时器
timer = Timer.scheduledTimer( timeInterval: 0.2, target: self,
selector: #selector(AppleFactory.createApple), userInfo: nil, repeats: true)
}
//创建苹果类
func createApple(){
//通过随机数来随机生成苹果
//算法是,随机生成0-9的数,当随机数大于8的时候声称苹果
//也就是说,有1/10的几率生成苹果
//这样游戏场景中的苹果就不会整整齐齐以相同间隔出现了
let random = arc4random() % 10
if random > 8 {
//生成苹果
let apple = SKSpriteNode(texture: appleTexture)
//设置物理体
apple.physicsBody = SKPhysicsBody(rectangleOf: apple.size)
//弹性设为0
apple.physicsBody?.restitution = 0
//物理体标识
apple.physicsBody?.categoryBitMask = BitMaskType.apple
//不受物理效果影响
apple.physicsBody?.isDynamic = false
//设置中心点
apple.anchorPoint = CGPoint(x: 0, y: 0)
//z轴深度
apple.zPosition = 40
//设定位置
let theY = CGFloat(arc4random()%200 + 200)
apple.position = CGPoint(x: sceneWidth+apple.frame.width , y: theY)
//加入数组
arrApple.append(apple)
//加入场景
self.addChild(apple)
}
}
//苹果移动方法
func move(_ speed:CGFloat){
for apple in arrApple {
apple.position.x -= speed
}
//移出屏幕外时移除苹果
if arrApple.count > 0 && arrApple[0].position.x < -20{
arrApple[0].removeFromParent()
arrApple.remove(at: 0)
}
}
//重置方法
func reSet(){
//移除所有子对象
self.removeAllChildren()
//清空苹果数组
arrApple.removeAll(keepingCapacity: false)
}
}
熊猫类 Panda.swift
import SpriteKit
class Panda: SKSpriteNode {
//定义纹理
let pandaTexture = SKTexture(imageNamed: "panda")
init() {
//执行父类的构造方法
super.init(texture:pandaTexture,color:SKColor.white,size:pandaTexture.size())
//设置中心点
self.anchorPoint = CGPoint(x: 0, y: 0)
self.physicsBody = SKPhysicsBody(rectangleOf:pandaTexture.size())
self.physicsBody?.isDynamic = true
self.physicsBody?.allowsRotation = false
//弹性
self.physicsBody?.restitution = 0
self.physicsBody?.categoryBitMask = BitMaskType.panda
self.physicsBody?.contactTestBitMask = BitMaskType.scene|BitMaskType.apple
self.physicsBody?.collisionBitMask = BitMaskType.scene
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//跳
func jump (){
//施加一个向上的力,让小人跳起来
self.physicsBody?.velocity = CGVector(dx: 0, dy: 700)
}
}
碰撞标识类 - BitMaskType.swift
class BitMaskType {
class var panda:UInt32{
return 1<<0
}
class var apple:UInt32{
return 1<<1
}
class var scene:UInt32{
return 1<<2
}
}
主场景 - GameScene.swift
import SpriteKit
class GameScene: SKScene,SKPhysicsContactDelegate {
lazy var appleFactory = AppleFactory()
lazy var panda = Panda()
//移动速度
var moveSpeed:CGFloat = 15
//吃到的苹果数
var appleNum = 0
override func didMove(to view: SKView) {
//物理世界代理
self.physicsWorld.contactDelegate = self
//重力设置
self.physicsWorld.gravity = CGVector(dx: 0, dy: -5)
//设置物理体
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
//设置种类标示
self.physicsBody?.categoryBitMask = BitMaskType.scene
//是否响应物理效果
self.physicsBody?.isDynamic = false
//场景的背景颜色
let skyColor = SKColor(red:113/255,green:197/255,blue:207/255,alpha:1)
self.backgroundColor = skyColor
//给小人定一个初始位置
panda.position = CGPoint(x: 200, y: 400)
//将小人显示在场景中
self.addChild(panda)
//苹果工厂
appleFactory.onInit(self.frame.width)
self.addChild( appleFactory )
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
panda.jump()
}
override func update(_ currentTime: TimeInterval) {
appleFactory.move(moveSpeed)
}
//碰撞检测方法
func didBegin(_ contact: SKPhysicsContact) {
//熊猫和苹果碰撞
if (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)
== (BitMaskType.apple | BitMaskType.panda){
//苹果计数加1
self.appleNum += 1
//如果碰撞体A是苹果,隐藏碰撞体A,反之隐藏碰撞体B
//(因为苹果出了屏幕都会被移除,所以这里隐藏就可以了)
if contact.bodyA.categoryBitMask == BitMaskType.apple {
contact.bodyA.node?.isHidden = true
}else{
contact.bodyB.node?.isHidden = true
}
}
}
}
源码下载:

碰撞标识类为什么要设为UInt32?而且左位移运算新手也不好理解~~
游戏场景的宽度不是狂赌~~
假如程序开始开始生成100个苹果,然后点击屏幕将100个移除。。。 请问怎么才能移除干净,释放内存。