01.添加游戏音乐

音乐主要有:Player挥动翅膀上升的声音、撞击障碍物的声音、坠落至地面的声音、过关得分的声音等等。请打开项目看到Resource中的Sounds文件夹,包含了上述所有声音,格式为.wav

SpritKit提供playSoundFileNamed(soundFile:,waitForCompletion wait: )->SKAction方法用于实现音乐的播放,注意播放音乐也是一个Action动作。请定位到GameScene.swift文件,找到GameScene类中的var playableHeight:CGFloat = 0,在其下方添加如下代码:

// MARK: 音乐Action
let dingAction = SKAction.playSoundFileNamed("ding.wav",waitForCompletion: false)
let flapAction = SKAction.playSoundFileNamed("flapping.wav",waitForCompletion: false)
let whackAction = SKAction.playSoundFileNamed("whack.wav",waitForCompletion: false)
let fallingAction = SKAction.playSoundFileNamed("falling.wav",waitForCompletion: false)
let hitGroundAction = SKAction.playSoundFileNamed("hitGround.wav",waitForCompletion: false)
let popAction = SKAction.playSoundFileNamed("pop.wav",waitForCompletion: false)
let coinAction = SKAction.playSoundFileNamed("coin.wav",waitForCompletion: false)

之后在需要音乐播放的时候调用这些已经定义的动作即可。

02.添加Player

通过课程一的代码练习,添加一个Player只需实例化一个SKSpriteNode实例,纹理为Bird0这张照片。由于这个精灵之后将在各个函数调用,因此设定了全局变量,请在var playableHeight: CGFloat = 0下添加如下代码实例化一个名为”Player”的精灵。如下:

let player = SKSpriteNode(imageNamed: "Bird0")

注意到此时我们并未添加该精灵到场景中的worldNode节点中,因此我们需要实现一个名为setupPlayer()的方法,代码如下

func setupPlayer(){
    player.position = CGPointMake(size.width * 0.2,playableHeight * 0.4 + playableStart)
    player.zPosition = Layer.Player.rawValue
    worldNode.addChild(player)
}

函数中仅设置了position以及zPosition属性,而锚点anchorPoint并未设置,采用默认值(0.5,0.5)。找到didMovetoView(view:)中的setupForeground()这行代码,将上述方法添加至其下方。

点击运行程序,Player出现在场景之中。

03.update方法

不知道你有没有玩过翻书动画,先准备一个厚厚的小本子,然后在每一页上描画,最后通过快速翻阅组成最简短的动画。如下:

前文谈及右下角的30fps客官可曾记得?fpsFrame Per Second的缩写,即每秒的帧数,而一帧为一个画面。因此30fps意味着在一秒钟时间内,App要渲染30次左右,平均每隔0.033333秒就要重新绘制一次画面。而渲染(绘制)完毕立刻跳入update(currentTime:)方法中,大约间隔33.33毫秒左右,执行方法内的代码。不妨你在该函数中设个断点感受一下。

注意到左下角的帧数并不是始终保持在30fps,而是不断在上下浮动变化。相邻两帧画面之间的时间并不固定,可能是0.033秒,也可能是0.030秒。不妨测试打印下两帧之间的时间差值,请在player下添加两个全局变量:lastUpdateTime以及dt

var lastUpdateTime :NSTimeInterval = 0  //记录上次更新时间
var dt:NSTimeInterval = 0               //两次时间差值

接着在Update(currenTime:)方法中添加如下方法:

override func update(currentTime: CFTimeInterval) {
   if lastUpdateTime > 0{
       dt = currentTime - lastUpdateTime
   }else{
       dt = 0
   }
   lastUpdateTime = currentTime
   print("时间差值为:\(dt*1000) 毫秒")
}

可以看到打印结果(注意红色框框处):

当应用刚启动时,帧数并不稳定,导致时间间隔略大,不过之后基本稳定在33毫秒左右。

04.Player的下落公式

这里可能要涉及一些高中的物理知识。地球上的重力加速度为9.8g。物体在半空中静止到下落,每隔dt时间。

  • 速度V = V1 + a * dt,即当前速度=初速度 + 加速度 * 时间间隔
  • dt时间内,下落距离d =V * dt,这里采用平均速度 * 时间差得到下落距离。

游戏中设定且只有Y轴方向上的重力加速度kGravity = -1500,这个值是可调节的,我觉得恰到好处;此外每次玩家点击屏幕,对Player要有一个向上的拉力,不妨设为kImpulse = 400;最后声明一个变量playerVeLocity追踪当前Player的速度。请添加上述三个全局变量的声明,现在GameScene类中的全局变量有以下这些:

// MARK: - 常量
let kGravity:CGFloat = -1500.0  //重力
let kImpulse:CGFloat = 400      //上升力

let worldNode = SKNode()
var playableStart:CGFloat = 0
var playableHeight:CGFloat = 0
let player = SKSpriteNode(imageNamed: "Bird0")
var lastUpdateTime :NSTimeInterval = 0
var dt:NSTimeInterval = 0
var playerVeLocity = CGPoint.zero   //速度 注意变量类型为一个点
//...其他内容

请在GameScene类中添加一个方法,将先前公式用swift实现更新playerposition

func updatePlayer(){
    // 只有Y轴上的重力加速度为-1500
    let gravity = CGPoint(x: 0,y: kGravity)
    let gravityStep = gravity * CGFloat(dt) //计算dt时间下速度的增量
    playerVeLocity += gravityStep           //计算当前速度

    // 位置计算
    let veLocityStep = playerVeLocity * CGFloat(dt) //计算dt时间中下落或上升距离
    player.position += veLocityStep                 //计算player的位置

    // 倘若Player的Y坐标位置在地面上了就不能再下落了 直接设置其位置的y值为地面的表层坐标
    if player.position.y - player.size.height/2 < playableStart {
        player.position = CGPoint(x: player.position.x,y: playableStart + player.size.height/2)
    }
}

将该方法添加至update(currentTime)方法中的最下面。意味着每隔33.3毫秒左右就要更新一次Player的位置。

点击运行,Player自由落地至地面,不错吧!

05.让Player动起来

游戏中我们点击一次屏幕,Player会获得一个向上的牵引力,挥动翅膀向上飞一段距离,倘若之后没有持续的力,则开始自由落体。怎么实现呢?实现机制不难,只需每次玩家点击屏幕,使得Player获得向上的速度,具体为先前设定的400即可。

因此,添加一个方法到GameScene类中,用于每次用户点击屏幕时调用,作用是让Player获得向上的速度!

func flapPlayer(){
    // 发出一次煽动翅膀的声音
    runAction(flapAction)
    // 重新设定player的速度!!
    playerVeLocity  = CGPointMake(0,kImpulse)
}

正如前面谈到的,方法中主要做两件事:1.发出一次挥动翅膀的声音。2.重新设定player的速度。

而用户每次点击都会调用touchesBegan(touches: Set<UITouch>,withEvent event: UIEvent?)方法。不用我多说了吧,把flapPlayer()方法添加进去吧。

运行工程,player坠落,点击几下,哇靠,飞起来了!

用Swift做个游戏Lecture02 —— Player的诞生的更多相关文章

  1. 用canvas做一个DVD待机动画的实现代码

    这篇文章主要介绍了用canvas做一个DVD待机动画的实现代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. HTML5自定义视频播放器源码

    这篇文章主要介绍了HTML5自定义视频播放器源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  3. Html5 滚动穿透的方法

    这篇文章主要介绍了Html5 滚动穿透的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. HTML5自定义mp3播放器源码

    这篇文章主要介绍了HTML5自定义mp3播放器源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  5. CSS中实现动画效果-附案例

    这篇文章主要介绍了 CSS中实现动画效果并附上案例代码及实现效果,就是CSS动画样式处理,动画声明需要使用@keyframes name,后面的name是人为定义的动画名称,下面我们来看看文章的具体实现内容吧,需要的小伙伴可以参考一下

  6. html5默认气泡修改的代码详解

    这篇文章主要介绍了html5默认气泡修改的代码详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. Html5移动端适配IphoneX等机型的方法

    这篇文章主要介绍了Html5移动端适配IphoneX等机型的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. 小程序瀑布流解决左右两边高度差距过大的问题

    这篇文章主要介绍了小程序瀑布流解决左右两边高度差距过大的问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5自定义元素播放焦点图动画的实现

    这篇文章主要介绍了HTML5自定义元素播放焦点图动画的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. CSS position属性和实例应用演示

    这篇文章主要介绍了CSS position属性和实例应用演示,absolute(绝对定位),relative(相对定位),relative与absolute的结合使用以及fixed(固定定位),需要的朋友可以参考下

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部