资讯专栏INFORMATION COLUMN

[原创]Swift+Sprite Kit中文教程第二篇

piapia / 2419人阅读

摘要:添加子弹为了节省时间,这里用代替。再来一发只有一发不太爽将子弹的所有逻辑,从中搬移到中,这样每帧都会执行突突突好密集,吓尿了。下面增加一个发射间隔。

添加子弹

为了节省时间,这里用Shape代替。
在load中,创建一个shape精灵:

var bullet = SKShapeNode(rectOfSize: CGSizeMake(10, 10))
bullet.position = CGPointMake(plane.position.x, plane.position.y + 50)
bullet.strokeColor = UIColor.clearColor()
bullet.fillColor = UIColor.greenColor()
addChild(bullet)

设置坐标到飞机上面一点,免得被挡住,然后设置边框颜色为透明,填充色绿色,最后添加到场景节点。

让子弹飞一会

在创建子弹的时候,为其附加一个动作序列:

bullet.runAction(SKAction.sequence([SKAction.moveByX(0, y:size.height, duration: 2), SKAction.removeFromParent()]))

序列中两个动作,一个是竖向位移场景高度那么长的距离,正值向上负值向下,保证子弹至少能打到屏幕以外才会消失,第二个动作则是将其从场景里移除,同时也就被销毁了。

再来一发!

只有一发不太爽!将子弹的所有逻辑,从load中搬移到update中,这样每帧都会执行……突突突好密集,吓尿了。
下面增加一个发射间隔。我们留意到update函数里有一个参数,会传递系统时间,这个怎么能利用一下呢?
定义两个类成员变量在isTouched属性下面:

var bulletTime:NSTimeInterval = 0.2//子弹发射间隔
var lastBullet:NSTimeInterval = 0//上次发射的时间点

然后在update中添加if条件

if(currentTime >= lastBullet + bulletTime){
    //创建子弹....
    lastBullet = currentTime
}

若当前时间大于上次发射时间+发射间隔,那么发射一次,然后更新上次发射时间为当前时间
so,跑一下吧,效果还不错~

改进操作

因为飞机比较小,在手机端很难安逸的点击到,改进办法是只要点击屏幕,飞机就会沿着你手指移动方向移动,下面我们实现这个功能。
首先在类变量里添加一个变量:var toucheGap = CGPoint(x: 0, y: 0),然后将touchesBegan/touchesMoved/touchesEnded修改为:

override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
    /* Called when a touch begins */
    let location:CGPoint! = touches.first?.locationInNode(self)
    toucheGap = CGPoint(x: location.x - plane.position.x, y: location.y - plane.position.y)
}

override func touchesMoved(touches: Set, withEvent event: UIEvent?) {
    let location:CGPoint! = touches.first?.locationInNode(self)
    plane.position = CGPoint(x: location.x - toucheGap.x, y: location.y - toucheGap.y)
}

override func touchesEnded(touches: Set, withEvent event: UIEvent?) {

}

点击的时候,记录下手指和飞机的距离,然后手指移动的时候,将位移坐标等量应用到飞机的位移上。这下操作起来舒服多了!

限定边界

可是现在飞机能飞到屏幕外了,这个怎么破!
飞的时候限制一下边界就行啦~
首先我们写一个限定范围的函数,方便以后用。(之后可以开发你自己的math库)

func clamp(x: CGFloat, min: CGFloat, max: CGFloat) -> CGFloat{
    if x <= min{
        return min
    }else if x >= max{
        return max
    }else{
        return x
    }
}

之后我们在GameViewController中,将场景大小改为
let scene = GameScene(size: CGSizeMake(750, 1334))
因为iPhone5和6、6+都是相同的分辨率比例,所以经过自适应后能完美适配这三种屏幕。
然后将touchesMoved作如下修改:

override func touchesMoved(touches: Set, withEvent event: UIEvent?) {
    let location:CGPoint! = touches.first?.locationInNode(self)
    let xDir = clamp(location.x - toucheGap.x, min: 0, max: size.width)
    let yDir = clamp(location.y - toucheGap.y, min: 0, max: size.height)
    plane.position = CGPoint(x: xDir, y: yDir)
}

在每次设置飞机坐标的时候,预先判断是否超出了屏幕边界,如果超过边界,clamp函数会返回边界位置。现在把游戏运行起来,就发现飞机已经飞不出去了~

下面贴出GameScene类全部代码:

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    let planeTexture = SKTexture(imageNamed: "Spaceship")
    var plane:SKSpriteNode!
    var isTouched = false
    
    var bulletTime:NSTimeInterval = 0.2//子弹发射间隔
    var lastBullet:NSTimeInterval = 0//上次发射的时间点
    var toucheGap = CGPoint(x: 0, y: 0)
    
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        
        plane = SKSpriteNode(texture: planeTexture)
        plane.position = CGPointMake(size.width * 0.5, size.height * 0.5)
        plane.setScale(0.5)
        plane.name = "plane"
        addChild(plane)
    }
    
    override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
        /* Called when a touch begins */
        let location:CGPoint! = touches.first?.locationInNode(self)
        toucheGap = CGPoint(x: location.x - plane.position.x, y: location.y - plane.position.y)
    }
    
    override func touchesMoved(touches: Set, withEvent event: UIEvent?) {
        let location:CGPoint! = touches.first?.locationInNode(self)
        let xDir = clamp(location.x - toucheGap.x, min: 0, max: size.width)
        let yDir = clamp(location.y - toucheGap.y, min: 0, max: size.height)
        plane.position = CGPoint(x: xDir, y: yDir)
    }
    
    override func touchesEnded(touches: Set, withEvent event: UIEvent?) {

    }
    
    func didBeginContact(contact: SKPhysicsContact) {
        
    }
    
    func didEndContact(contact: SKPhysicsContact) {
        
    }
   
    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
        
        if currentTime >= lastBullet + bulletTime{
            let bullet = SKShapeNode(rectOfSize: CGSizeMake(10, 10))
            bullet.position = CGPointMake(plane.position.x, plane.position.y + 50)
            bullet.strokeColor = UIColor.clearColor()
            bullet.fillColor = UIColor.greenColor()
            addChild(bullet)
            
            bullet.runAction(SKAction.sequence([SKAction.moveByX(0, y: size.height, duration: 2), SKAction.removeFromParent()]))
            lastBullet = currentTime
        }
        
    }
    
    func clamp(x: CGFloat, min: CGFloat, max: CGFloat) -> CGFloat{
        if x <= min{
            return min
        }else if x >= max{
            return max
        }else{
            return x
        }
    }
}

下一篇

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15570.html

相关文章

  • [原创]Swift+Sprite Kit中文教程第三篇

    摘要:目前用到的标记有三个我方飞机子弹敌方飞机。然后在类中任意地方添加一个函数用来在碰撞发生时进行操作,首先进行判断,碰撞涉及的两个标记,是否是子弹和敌人标记。如果是,就杀死一个敌人,移除相关的子弹和击中的敌人。 拖了好久的第三篇终于开始了……ps:由于Xcode7不支持iOS8.4,我最终换回了Yosemite和Xcode6.4,所以语法如果有所出入引起问题,可以谷歌解决或者在下面留言。 ...

    adam1q84 评论0 收藏0
  • [原创]Swift+Sprite Kit中文教程第一篇

    摘要:本教程将使用纯进行开发,所以最好有一点点这两种技术的基础。清理干净删除文件,目前我建议使用纯代码实现。创建精灵进入文件,干掉和里的所有代码。处理操作我们要开始控制飞机飞行了。不过我们暂时只关心单点触摸,也就是只处理集合中的第一个点的数据。 本教程适用于入门开发者,我将会告诉你如何最快开发出小游戏,但所使用的未必是最佳方案。本教程将使用纯swift+storyboard进行开发,所以最好...

    lindroid 评论0 收藏0
  • [原创]Swift+Sprite Kit中文教程第四篇

    摘要:很幸运也很开心受到官方微博推荐,所以继续努力更新,逐渐完善这个小游戏。类的属性列表中添加然后添加一个标签,用来显示分数。这几秒钟里,子弹和敌人停止出现。将函数中的两个条件,填上条件,就大功告成啦。 很幸运也很开心受到官方微博推荐,所以继续努力更新,逐渐完善这个小游戏。 添加分数 既然能够击杀敌人了,下面我们计算玩家获得的分数。类的属性列表中添加var score:UInt32 = 0然...

    archieyang 评论0 收藏0
  • 【译】iPhone 编程教程

    摘要:尽情享受吧从开始你用编写程序程序。这些教程会教你如何处理崩溃的消息和日志,并且在崩溃之前为了提前截获它们你需要些什么工具。教程想要些教程我们早就猜到了中最令人兴奋的添加之一就是苹果公司全新的游戏框架。 这篇教程很长,但很有用(这只是冰山一角,后面还有很多暂时还没有翻译完抱歉),对于新手或是有经验的开发者来说都值得收藏。 原文地址:http://www.raywenderlic...

    DataPipeline 评论0 收藏0
  • 一起学SpriteKit游戏开发[ 1 ]创建一个SpriteKit项目

    摘要:介绍是苹果平台上独有的游戏框架,可以在上方便的开发游戏应用,其上手简单对语言支持良好。输入我们的游戏名,编程语言选择,游戏技术选择,设备选择。 介绍 SpriteKit是苹果平台上独有的游戏框架,可以在Mac OS X、iOS、tvOS上方便的开发2D游戏应用,其上手简单、对Swift语言支持良好。尽管在跨平台方面不如人气颇高的Cocos2D、Unity等跨平台游戏框架,但是如果只是在...

    cod7ce 评论0 收藏0

发表评论

0条评论

piapia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<