导入UIKit导入AudioToolbox //播放音效import AVFoundation //播放音乐让 SCREEN_SIZE = UIScreen.main.bounds类ViewController：UIViewController，CAAnimationDelegate {var timerBg：计时器？var timerTube：计时器？var bird:UIImageView！var cloud:UIImageView！var cloudAnimation:CAKeyframeAnimation！var timerBird：计时器？var t:Float = 0.0var isFlyUpward = falsevar bgMusic：AVAudioPlayer！覆盖func viewDidLoad() {super.viewDidLoad（）self.creatBackgroundView（）self.creatTube（）self.creatTimer（）self.creatBird（）self.creatCloud（）self.playOrPauseBgMusic（）}func creatBackgroundView(){//创建城市背景let imageCity = UIImage（命名：“bg-city.png”）let viewCity = UIImageView（图像：imageCity）let viewCity2 = UIImageView（图像：imageCity）viewCity.frame = CGRect（x：0，y：0，宽度：SCREEN_SIZE.width，高度：SCREEN_SIZE.height）viewCity2.frame = CGRect（x：SCREEN_SIZE.width，y：0，宽度：SCREEN_SIZE.width + 1，高度：SCREEN_SIZE.height）self.view.addSubview（viewCity）self.view.addSubview（viewCity2）viewCity.tag = 101viewCity2.tag = 102// 创建大地背景let viewGround = UIImageView（帧：CGRect（x：0，y：SCREEN_SIZE.height - 100，宽度：SCREEN_SIZE.width，高度：100））let viewGround2 = UIImageView（框架：CGRect（x：SCREEN_SIZE.width，y：SCREEN_SIZE.height - 100，宽度：SCREEN_SIZE.width + 2，高度：100））let imageGround = UIImage（名称：“bg-ground.png”）viewGround.image = imageGroundviewGround2.image = imageGroundself.view.addSubview（viewGround）self.view.addSubview（viewGround2）viewGround.tag = 103viewGround2.tag = 104}func creatTube(){让imageTubeUp = UIImage（命名：“tube-up.png”）let imageTubeDown = UIImage（名称：“tube-down.png”）//第一对水管let viewTubePairOneUp = UIImageView（框架：CGRect（x：0，y：-SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））让viewTubePairOneDown = UIImageView（框架：CGRect（x：0，y：SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））viewTubePairOneUp.image = imageTubeUpviewTubePairOneDown.image = imageTubeDownviewTubePairOneUp.tag = 201viewTubePairOneDown.tag = 202//第二对水管let viewTubePairTwoUp = UIImageView（框架：CGRect（x：SCREEN_SIZE.width/2，y：-SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））let viewTubePairTwoDown = UIImageView（框架：CGRect（x：SCREEN_SIZE.width/2，y：SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））viewTubePairTwoUp.image = imageTubeUpviewTubePairTwoDown.image = imageTubeDownviewTubePairTwoUp.tag = 203viewTubePairTwoDown.tag = 204//第三对水管让viewTubePairThreeUp = UIImageView（框架：CGRect（x：SCREEN_SIZE.width，y：-SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））let viewTubePairThreeDown = UIImageView（框架：CGRect（x：SCREEN_SIZE.width，y：SCREEN_SIZE.height，宽度：54，高度：SCREEN_SIZE.height））viewTubePairThreeUp.image = imageTubeUpviewTubePairThreeDown.image = imageTubeDownviewTubePairThreeUp.tag = 205viewTubePairThreeDown.tag = 206//添加水管到第一个大地背景视图下方让viewGroud = self.view.viewWithTag（103）！self.view.insertSubview（viewTubePairOneUp， belowSubview：viewGroud）self.view.insertSubview（viewTubePairOneDown，以下Subview：viewGroud）self.view.insertSubview（viewTubePairTwoUp，以下Subview：viewGroud）self.view.insertSubview（viewTubePairTwoDown，下面Subview：viewGroud）self.view.insertSubview（viewTubePairThreeUp，以下Subview：viewGroud）self.view.insertSubview（viewTubePairThreeDown，以下Subview：viewGroud）}func creatTimer(){timerBg = Timer.scheduledTimer（timeInterval：0.02，目标：self，选择器：#selector（self.backgroundMove），用户信息：零，重复：真）timerTube = Timer.scheduledTimer（timeInterval：0.02，目标：self，选择器：#selector（self.tubeMove），用户信息：nil，重复：true）timerBird = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(self.birdMove), userInfo: nil, repeats: true)}@objc func backgroundMove(){let viewCity = self.view.viewWithTag（101）让viewCity2 = self.view.viewWithTag（102）let viewGround = self.view.viewWithTag（103）让viewGround2 = self.view.viewWithTag（104）如果（viewCity?.frame.origin.x）！> -SCREEN_SIZE.width{viewCity?.frame.origin.x -= 1}其他{viewCity?.frame.origin.x=SCREEN_SIZE.width}如果（viewCity2?.frame.origin.x）！> -SCREEN_SIZE.width{viewCity2?.frame.origin.x -= 1}其他{viewCity2?.frame.origin.x = SCREEN_SIZE.width}如果（viewGround?.frame.origin.x）！> -SCREEN_SIZE.width{viewGround?.frame.origin.x -= 2}其他{viewGround?.frame.origin.x = SCREEN_SIZE.width}如果（viewGround2?.frame.origin.x）！> -SCREEN_SIZE.width{viewGround2?.frame.origin.x -= 2}其他{viewGround2?.frame.origin.x = SCREEN_SIZE.width}}@objc func tubeMove(){//通过间隔Tag取值，获取图像视图对于我跨步（从：201，到：206，通过：2）{//水管移出左边屏幕一半的距离时就添加到屏幕最右边if self.view.viewWithTag(i)!.frame.origin.x > -SCREEN_SIZE.width/2 {self.view.viewWithTag(i)?.frame.origin.x -= 2self.view.viewWithTag(i + 1)?.frame.origin.x -= 2}其他{self.view.viewWithTag(i)?.frame.origin.x = SCREEN_SIZE.widthself.view.viewWithTag(i + 1)?.frame.origin.x = SCREEN_SIZE.width// 调整水管y轴坐标值，即高度self.getPosition（viewUp：self.view.viewWithTag（i）作为！UIImageView，viewDown：self.view.viewWithTag（i + 1）作为！UIImageView）}}}func getPosition（viewUp：UIImageView，viewDown：UIImageView）{//产生随机数，范围[30,330)，范围越大小鸟越不容易通过让高度 = arc4random()%300 + 30//设置上下水管的y轴坐标值viewUp.frame.origin.y = (CGFloat)(-SCREEN_SIZE.height)+(CGFloat)(height)//上下水管之间的间隙设置为150,间隙越大小鸟越容易通过viewDown.frame.origin.y = (CGFloat)(高度) + 150.0}func creatBird(){var images = [UIImage]()for i in 1...3 { //3张鸟动作图片let image = UIImage（命名：NSString（格式：“bird%d.png”，i）作为字符串）images.append（图像！）}bird = UIImageView（框架：CGRect（x：50，y：200，宽度：35，高度：35））bird.animationImages = 图像bird.animationRepeatCount = 0bird.animation持续时间= 0.3bird.startAnimating（）self.view.addSubview（鸟）}func creatCloud(){云= UIImageView（帧：CGRect（x：450，y：60，宽度：80，高度：30））cloud.image = UIImage（名称：“cloud.png”）让viewTube = self.view.viewWithTag（201）！self.view.insertSubview（云，以下Subview：viewTube）//使用便利构造器创建动画实例cloudAnimation = CAKeyframeAnimation（keyPath：“位置”）//云朵视图矩形的中心点let point1 = CGPoint（x：450，y：60）let point2 = CGPoint（x：300，y：100）let point3 = CGPoint（x：150，y：60）let point4 = CGPoint（x：-50，y：150）cloudAnimation.values = [NSValue(cgPoint: point1), NSValue(cgPoint: point2), NSValue(cgPoint: point3), NSValue(cgPoint: point4)]cloudAnimation.keyTimes = [NSNumber（值：0.0），NSNumber（值：0.2），NSNumber（值：0.8），NSNumber（值：1.0）]cloudAnimation.duration = 5.0//添加CAAnimationDelegate协议代理来获得结束事件的回调cloudAnimation.delegate = 自我//开始动画cloud.layer.add（cloudAnimation，forKey：“云”）}func animationDidStop(_ anim: CAAnimation, finished flag: Bool){如果标志 == true {cloud.layer.add（cloudAnimation，forKey：“云”）}}@objc func birdMove(){if isFlyUpward == false {//自由落体运动if bird.frame.origin.y < SCREEN_SIZE.height - 140 {bird.frame.origin.y += (CGFloat)(9.8*(t*t/2) - 9.8*(t-0.02)*(t-0.02)/2)*30t += 0.02}}其他{// 竖直上抛运动如果t < 0.2 {bird.frame.origin.y -= (CGFloat)((10.0*t-9.8*t*t/2) - (10.0*(t-0.02)-9.8*(t-0.02)*(t-0.02)/2))*30t += 0.02}其他{//超出10个节拍后，不管是否到达最高点，都直接转为自由落体运动isFlyUpward = 假}}self.hitDetectionAndGameOver（）}override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){//若小鸟动画进行中表示游戏没有结束if bird.isAnimating == true {//屏幕触摸动作后，小鸟改为竖直上抛运动isFlyUpward = truet = 0self.playScreenTouchSound（）}其他{//重新加载游戏self.reloadGame（）}}func playScreenTouchSound（）{var mySoundId：SystemSoundID = 0//获得文件目录let myPath = Bundle.main.path（forResource：“sound-touch”，ofType：“wav”）//文件目录path转换为URL形式，更有普遍性让mySoundURL = URL（fileURLWithPath：myPath！）//生成音效的SoundIDAudioServicesCreateSystemSoundID（mySoundURL作为CFURL，&mySoundId）//通过SoundID播放结束，结束后调用闭包一次AudioServicesPlaySystemSoundWithCompletion(mySoundId){ () -> 无效//print("点击了屏幕!", mySoundId)// 单次播放音效//AudioServicesPlaySystemSoundWithCompletion（mySoundId，nil）}}func playOrPauseBgMusic(){如果 bgMusic == nil {// 只会进入这里一次让myPath = Bundle.main.path（forResource：“bg-music”，类型：“mp3”）让mySoundURL = URL（fileURLWithPath：myPath！）做{尝试bgMusic = AVAudioPlayer（内容：mySoundURL）//设置音量最大，范围0.0-1.0bgMusic.volume = 1.0//设置-1表示无限循环，0表示1次，1表示2次bgMusic.numberOfLoops = -1//若要获得播放结束等状态信息，可以设置代理//bgMusic.delegate = self} catch{print("音乐配置出错",error)}}//切换音乐播放和暂停如果 bgMusic.isPlaying {bgMusic.pause（）}其他{bgMusic.play（）}}func hitDetectionAndGameOver(){对于我在201...206 {//若小鸟矩形区域与任意水管矩形区域相交，就认为游戏结束if bird.frame.intersects(self.view.viewWithTag(i)!.frame) {//碰撞发生，就停止相关运动timerBg!.fireDate = Date.distantFuture as Date //停止城市和大地背景运动timerTube!.fireDate = Date.distantFuture as Date //停止水管运动timerBird!.fireDate = Date.distantFuture as Date //停止小鸟运动bird.stopAnimating() //停止小鸟动画cloud.layer.removeAnimation(forKey: "cloud") //停止云朵漂浮self.playOrPauseBgMusic() //关闭背景音乐//播放碰撞水管音效var mySoundId：SystemSoundID = 0let myPath = Bundle.main.path(forResource: "sound-hit", ofType: "wav")AudioServicesCreateSystemSoundID（URL（fileURLWithPath：myPath！）作为CFURL，&mySoundId）AudioServicesPlaySystemSoundWithCompletion（mySoundId，nil）//显示游戏结束横条let showGameOverBanner = UIImageView（框架：CGRect（x：30，y：100，宽度：SCREEN_SIZE.width-60，高度：60））showGameOverBanner.image = UIImage（名称：“gameover.png”）showGameOverBanner.tag = 301self.view.addSubview（showGameOverBanner）}}}func reloadGame(){//水管从初始位置开始对于我跨步（从：201，到：206，通过：2）{self.view.viewWithTag(i)?.frame = CGRect(x: SCREEN_SIZE.width*(CGFloat(i)-201)/4, y: -SCREEN_SIZE.height, width: 54, height: SCREEN_SIZE.height)self.view.viewWithTag(i+1)?.frame = CGRect(x: SCREEN_SIZE.width*(CGFloat(i)-201)/4, y: SCREEN_SIZE.height, width: 54, height: SCREEN_SIZE.height)}//小鸟从初始位置开始开启动画bird.frame = CGRect（x：50，y：200，宽度：35，高度：35）bird.startAnimating（）//恢复云朵动画cloud.layer.add（cloudAnimation，forKey：“云”）// 开启背景音乐self.playOrPauseBgMusic（）//移走gameover横幅让showGameOverBanner = self.view.viewWithTag（301）showGameOverBanner?.removeFromSuperview()// 重新开始时t = 0// 开启定时器timerBg!.fireDate = Date.distantPast as DatetimerTube!.fireDate = Date.distantPast as DatetimerBird!.fireDate = Date.distantPast as Date}}帮我用swiftui改写