抖音的潜水艇小游戏只能玩一会儿,不尽兴,于是想着自己开发一个。

ARKit的各种入门介绍这里就不说了,网上一堆都是,自己注意甄别。

第一步,创建一个具有增强现实功能AR的项目:

选择语言Swift, SpriteKit是2D游戏引擎开发框架,考虑到游戏还是以2D画面为主,所以选择了SpriteKit,SceneKit是3D开发引擎。

第二步,在ViewController中可以开打已经默认导入了ARKit和SpriteKit两个框架,而且SB中也添加了一个ARSKView实例sceneView,ARSKView可以渲染摄像头捕捉到的画面和画面中添加的每一个节点node,它把ARSession和Spritekit结合了起来,具体代码:

override func viewDidLoad() {super.viewDidLoad()sceneView.delegate = selfsceneView.showsPhysics = truesceneView.showsFPS = truesceneView.showsNodeCount = true//检测手机能不能用人脸追踪功能guard ARFaceTrackingConfiguration.isSupported else {fatalError("Face tracking is not supported on this device")}if let view = self.view as! SKView? {//通过代码创建一个GameScene类的实例对象 不用项目中自带的scene.size = view.bounds.sizesceneView.presentScene(scene)}}

在视图即将出现和即将消失的时候打开和关闭ARSession

override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)let configuration = ARFaceTrackingConfiguration()sceneView.session.delegate = selfsceneView.session.run(configuration)}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)sceneView.session.pause()}

sceneView.delegate = self 代理方法提供了添加节点、节点即将更新、已经更新的方法:

这里我们先添加一个简单的图片上去看下效果

// MARK: - ARSKViewDelegatefunc view(_ view: ARSKView, didAdd node: SKNode, for anchor: ARAnchor) {let image = SKSpriteNode(imageNamed: "速抠图")image.size = CGSize(width: 20, height: 20)image.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "速抠图"), size: CGSize(width: 20, height: 20))image.position = CGPoint(x: -60, y: 0)node.addChild(image)}

运行可以看到摄像头识别人脸并让图片跟随人脸移动,当前image默认是以识别到的人脸中心位置为锚点,所以image.position = CGPoint(x: -60, y: 0)修改了当前节点的位置,偏脸人脸到左边

到这里人脸识别追踪的简单功能就完成了,接下来就是添加各种2D的模型,潜水艇和柱子,潜水艇的位置跟随识别到的人脸的位置,再给模型添加物理属性。

第三步,在Scene中添加潜水艇和柱子模型

        image = SKSpriteNode(imageNamed: "速抠图")image.size = CGSize(width: 60, height: 60)image.physicsBody = SKPhysicsBody(rectangleOf:image.size)image.physicsBody?.affectedByGravity = falseimage.physicsBody?.categoryBitMask = birdCategoryimage.physicsBody?.contactTestBitMask = pipeCategoryimage.position = CGPoint(x: 50, y: 50)addChild(image)

image位置随便指一个,我喜欢先看效果再处理

创建柱子节点,柱子节点是多个而且成对出现,上下各一个,隔一段时间出现一对,隔一段时间再出现一对,如此循环

所以这可以看做是一个创建+等待+创建+等待的循环过程

于是:

    //MARK:开始重复创建水管func startCreateRandomPipesAction() {//创建一个等待的action,等待时间的平均值为秒,变化范围为1秒let waitAct = SKAction.wait(forDuration: 1.5)//创建一个产生随机水管的action,这个action实际上就是我们下面新添加的那个createRandomPipes()方法let generatePipeAct = SKAction.run {self.createRandomPipes()}//让场景开始重复循环执行“等待->创建->等待->创建...”//并且给这个循环的动作设置一个叫做createPipe的key类标识它run(SKAction.repeatForever(SKAction.sequence([waitAct,generatePipeAct])), withKey: "createPipe")}
    //MARK:具体某一次创建一对水管func createRandomPipes() {let height = self.size.heightlet pipeGap = CGFloat(arc4random_uniform(60)) + image.size.width*2let pipeWidth:CGFloat = 60let topHeight = CGFloat(arc4random_uniform(UInt32(height/2))) + height/4let bottomPipeHeight = height - pipeGap - topHeightaddPipes(topSize: CGSize(width: pipeWidth, height: topHeight), bottomSize: CGSize(width: pipeWidth, height: bottomPipeHeight))}//MARK:添加水管到场景里func addPipes(topSize:CGSize,bottomSize:CGSize) {//创建上水管guard let image = UIImage(named: "topPipe") else { return }let topTextture = SKTexture(image: image)//利用上水管图片创建一个上水管纹理对象let topPipe = SKSpriteNode(texture: topTextture, size: topSize)//利用上水管纹理对象和传入的上水管大小参数创建一个上水管对象topPipe.name = "pipe" //给这个水管取个名字叫pipetopPipe.position = CGPoint(x: self.size.width + topPipe.size.width * 0.5, y: self.size.height - topPipe.size.height * 0.5)//创建下水管let bottomTexture = SKTexture(imageNamed: "bottomPipe")let bottomPipe = SKSpriteNode(texture: bottomTexture, size: bottomSize)bottomPipe.name = "pipe"bottomPipe.position = CGPoint(x: self.size.width + bottomPipe.size.width * 0.5, y: bottomPipe.size.height * 0.5)//将上下水管天骄到场景中addChild(topPipe)addChild(bottomPipe)}

让柱子移动:

    //MARK:移动和移除func moveScene() {//make pipe movefor pipeNode in self.children where pipeNode.name == "pipe" {//因为我们要用到水管的size,但是SKNode没有size属性,所以我们要把它转成SKSpriteNodeif let pipeSprite = pipeNode as? SKSpriteNode {//将水管左移2pipeSprite.position = CGPoint(x: pipeSprite.position.x - 2, y: pipeSprite.position.y)//检查水管是否完全超出屏幕左侧了,如果是则将它从场景里移除掉if pipeSprite.position.x < -pipeSprite.size.width * 0.5 {pipeSprite.removeFromParent()}}}}

添加物理属性:

self.physicsWorld.contactDelegate = self

各个节点添加物理属性

        image.physicsBody = SKPhysicsBody(rectangleOf:image.size)image.physicsBody?.affectedByGravity = falseimage.physicsBody?.categoryBitMask = imageCategoryimage.physicsBody?.contactTestBitMask = pipeCategory

实现节点碰撞的代理事件:func didBegin(_ contact: SKPhysicsContact)

    func didBegin(_ contact: SKPhysicsContact) {print("发生碰撞")}

到这里,还需要把潜水艇节点的位置和人脸识别位置联系起来,这里我在ARSKViewDelegate里面获取到node的识别位置,然后用闭包回调,暂时没想到其他好方法。

//Scene中添加闭包
var positionCallBack:((_ point:CGPoint)->())?//didMove方法中处理闭包返回的位置
positionCallBack = {point inself.image.position = CGPoint(x: point.x-60, y: point.y)}
//ViewController中 回调位置func view(_ view: ARSKView, didUpdate node: SKNode, for anchor: ARAnchor) {scene.positionCallBack?(node.position)}

运行可以看到image节点跟随人脸移动,与移动的柱子接触后出发碰撞方法,在此方法中做游戏结束的处理。

源码地址:地址

Swift基于ARKit的仿抖音潜水艇小游戏相关推荐

  1. 仿抖音滑动小短剧影视微信小程序源码带支付收益等模式

    项目功能介绍:支持无限滑动 高性能滑动 预加载 视频预览 支持剧情介绍,集合壁纸另外仿抖音滑动效果 支持会员模式,支持用户单独购买等等多功能 丰富的后台设置,具体大家可以看小编的后台演示图 具体小编也 ...

  2. 微信小程序 短剧开发技术踩坑指南 仿抖音快手小视频

    1.Video组件 微信官方文档地址: https://developers.weixin.qq.com/miniprogram/dev/component/video.html uniapp官方文档 ...

  3. 抖音国庆小游戏是如何实现的?带你走近 Cocos

    作者简介:唐文城,来自抖音互动技术团队,21 年毕业后持续探索互动技术,参与过若干个抖音活动业务,国庆项目互动玩法与动效核心开发者,喜欢做"可以看见"的事情. 前言 经过若干个月的 ...

  4. cocos creator上架字节跳动(抖音)小游戏注意事项(匿名登录、录屏、分享等踩坑记录)

    常见拒绝原因1:小游戏无录屏功能,不符合平台要求 2:小游戏录屏时间小于3S,分享按钮点击无反应或提示错误文案,不符合平台要求 3:小游戏录屏时间大于300S,分享按钮点击无反应或无法正常分享录屏,不 ...

  5. cocos creator对接字节跳动(抖音)小游戏激励视频广告注意事项(审核不通过,次数不一致和重复获得奖励等)

    首先是官方文档里的对接方式:(https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/open-inter ...

  6. 仿抖音 快手 小火山等短视频APP

    1. 开发环境及工具  安卓    Android studio 3.3.   Java 1.8  IOS    Xcode 11  服务端  基础环境LAMP(linux ,apache,mysql ...

  7. ReactTaro仿抖音小程序H5(一)

    仿抖音 h5 & 小程序 React hooks + Taro 3 + Taro UI 目前还在开发中,暂时实现了一部分逻辑,源码已发布github在文章最下边 h5端效果预览,在线预览地址: ...

  8. 基于Uni-APP多端「h5+小程序+App」高仿抖音小视频|直播|聊天实例

    uni-ttLive 基于uni-app+uView-ui跨端开发短视频+直播聊天实例. 全新研发的一款多端仿制抖音短视频+直播+聊天项目,基于uniApp+Vue.js+Vuex+Nvue+uVie ...

  9. 基于android的防抖音直播,基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能...

    一.项目简介 uni-liveShow是一个基于vue+uni-app技术开发的集小视频/IM聊天/直播等功能于一体的微直播项目.界面仿制抖音|火山小视频/陌陌直播,支持编译到多端(H5.小程序.Ap ...

最新文章

  1. python isdigit()
  2. Android之 AndroidManifest.xml 文件解析
  3. git idea 分支合并到另一个分支_idea如何在Git上将分支代码合并到主分支
  4. 前方车辆检测的常用方法
  5. new star program
  6. Verilog中的UDP
  7. AtomicIntegerArray类详解
  8. java exec 关闭_如何正确关闭java ExecutorService
  9. 信息学奥赛一本通(1135:配对碱基链)
  10. oracle 12c cdb/pdb tnsnames.ora设置
  11. 押错宝!一次性将百万行代码从 Flow 迁移至 TypeScript
  12. IQA+不懂︱图像清洗:图像质量评估(评估指标、传统检测方法)
  13. Scrapy-豆瓣电影Top250
  14. 全球及中国坚果产业发展现状及趋势分析,市场发展潜力巨大「图」
  15. 有没有中文域名SSL证书?如何申请
  16. STM32L476入坑-3-新建工程并点亮LED灯
  17. BGP高防服务器与普通高防服务器有什么区别?
  18. 2022年度“十大基础研究关键词”在深发布
  19. VBScript的中ByRef和ByVal的不同
  20. 仅通过蓝牙HID将安卓手机模拟成鼠标和键盘

热门文章

  1. 很多人问网站运营到什么时候才能够盈利?问题在这里
  2. 想要在PDF文件中添加便贴,不妨用迅捷PDF编辑器
  3. 菜鸟要飞分享的视频教程
  4. Hanson的趣味题
  5. 药店管理系统(C语言课程设计)(3月1日—3月8日)
  6. Bitbake Cheat Sheet
  7. OpenGL学习笔记 1.前期准备工作 (freegult+GLTools配置及导入)
  8. unittest用法
  9. 实验十六 matplotlib数据可视化
  10. 看完刘未鹏的暗时间之后的感悟