ARKit實(shí)戰(zhàn)---點(diǎn)擊屏幕擊打方塊游戲

看到一個(gè)大牛的blog,點(diǎn)擊屏幕擊打物品饶号,做了一點(diǎn)研究,和大家分享一下唇聘,屏幕截圖如下:


image.png

首先版姑,需要一個(gè)被擊打?qū)ο?/h2>

暫時(shí)先用一個(gè)BOX吧(就是因?yàn)楹?jiǎn)單),給這個(gè)BOX設(shè)置屬性,具體可以參看基本碰撞測(cè)試,有幾個(gè)需要注意的點(diǎn):

  • isAffectedByGravity表示當(dāng)前物體不受重力影響迟郎。
  • categoryBitMask標(biāo)示自己剥险。
  • contactTestBitMask標(biāo)示可以和自己碰撞的物體。
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
self.geometry = box
let shape = SCNPhysicsShape(geometry: box, options: nil)
self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
self.physicsBody?.isAffectedByGravity = false
//標(biāo)識(shí)自己和碰撞的對(duì)方    
self.physicsBody?.categoryBitMask = CollisionCategory.ship.rawValue
self.physicsBody?.contactTestBitMask = CollisionCategory.bullets.rawValue
//加上紋理
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: "galaxy")
self.geometry?.materials  = [material, material, material, material, material, material]

為了放在正前方宪肖,x,y軸在(-0.5~0.5)之間表制,z軸為-1。

let posX = floatBetween(-0.5, and: 0.5)
let posY = floatBetween(-0.5, and: 0.5  )
cubeNode.position = SCNVector3(posX, posY, -1) // SceneKit/AR coordinates 
image.png

其次控乾,點(diǎn)擊屏幕么介,新建一枚子彈

增加點(diǎn)擊事件

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTapGesture))
        //設(shè)置手勢(shì)點(diǎn)擊數(shù),雙擊:點(diǎn)1下
tapGesture.numberOfTapsRequired = 1
self.view.addGestureRecognizer(tapGesture)

新建一枚子彈,和被打擊對(duì)象差不多蜕衡,唯一的區(qū)別是categoryBitMask和contactTestBitMask剛好相反壤短。

let sphere = SCNSphere(radius: 0.025)
        self.geometry = sphere
        let shape = SCNPhysicsShape(geometry: sphere, options: nil)
        self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
        self.physicsBody?.isAffectedByGravity = false
        
        // see http://texnotes.me/post/5/ for details on collisions and bit masks
        self.physicsBody?.categoryBitMask = CollisionCategory.bullets.rawValue
        self.physicsBody?.contactTestBitMask = CollisionCategory.ship.rawValue
        
        // add texture
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "bullet_texture")
        self.geometry?.materials  = [material]

發(fā)射子彈

首先需要知道當(dāng)前攝像頭的位置,根據(jù)ARCamera的位置可以計(jì)算出從攝像頭發(fā)射子彈的位置和方向:
位置比較好理解:就是 SCNVector3(mat.m41, mat.m42, mat.m43)慨仿,這個(gè)是世界坐標(biāo)系的位置久脯。
方向就需要好好理解一下,其實(shí)是原點(diǎn)(0,0,0)到攝像頭點(diǎn)的方向镰吆。

func getUserVector() -> (SCNVector3, SCNVector3) { // (direction, position)
if let frame = self.sceneView.session.currentFrame {
let mat = SCNMatrix4FromMat4(frame.camera.transform) // 4x4 transform matrix describing camera in world space
let dir = SCNVector3(-1 * mat.m31, -1 * mat.m32, -1 * mat.m33) // orientation of camera in world space
let pos = SCNVector3(mat.m41, mat.m42, mat.m43) // location of camera in world space
        return (dir, pos)
}
return (SCNVector3(0, 0, -1), SCNVector3(0, 0, -0.2))
}

發(fā)射子彈帘撰,其實(shí)就是對(duì)子彈作用力,力的位置就是攝像頭的位置万皿,方向就是攝像頭的方向摧找。

let (direction, position) = self.getUserVector()
bulletsNode.position = position // SceneKit/AR coordinates are in meters
let bulletDirection = direction
 bulletsNode.physicsBody?.applyForce(bulletDirection, asImpulse: true)
 sceneView.scene.rootNode.addChildNode(bulletsNode)

子彈擊中方塊效果

基本碰撞測(cè)試里介紹過(guò)可以用代理處理碰撞的過(guò)程。

 func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
 if contact.nodeA.physicsBody?.categoryBitMask == CollisionCategory.ship.rawValue || contact.nodeB.physicsBody?.categoryBitMask == CollisionCategory.ship.rawValue { 
 print("Hit ship!")
//移除子彈
self.removeNodeWithAnimation(contact.nodeB, explosion: false) 
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
    //移除方塊牢硅,帶爆炸效果
    self.removeNodeWithAnimation(contact.nodeA, explosion: true)
    //新的方塊
    self.addNewShip()
            })       
        }
}

爆炸效果的實(shí)現(xiàn)如下,這里通過(guò)一個(gè)SCNP文件new一個(gè)SCNParticleSystem對(duì)象蹬耘,該對(duì)象負(fù)責(zé)SCNNode的動(dòng)畫效果。

func removeNodeWithAnimation(_ node: SCNNode, explosion: Bool) {
        if explosion {
            let particleSystem = SCNParticleSystem(named: "explosion", inDirectory: nil)
            let systemNode = SCNNode()
            systemNode.addParticleSystem(particleSystem!)
            // place explosion where node is
            systemNode.position = node.position
            sceneView.scene.rootNode.addChildNode(systemNode)
        }
        
        // remove node
        node.removeFromParentNode()
    }

廢話不說(shuō)了,直接看代碼,希望喜歡的人star支持一下减余。
demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婆赠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子佳励,更是在濱河造成了極大的恐慌,老刑警劉巖蛆挫,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赃承,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡悴侵,警方通過(guò)查閱死者的電腦和手機(jī)瞧剖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人抓于,你說(shuō)我怎么就攤上這事做粤。” “怎么了捉撮?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵怕品,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我巾遭,道長(zhǎng)肉康,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任灼舍,我火速辦了婚禮吼和,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘骑素。我一直安慰自己炫乓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布献丑。 她就那樣靜靜地躺著末捣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阳距。 梳的紋絲不亂的頭發(fā)上塔粒,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音筐摘,去河邊找鬼卒茬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咖熟,可吹牛的內(nèi)容都是我干的圃酵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼馍管,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼郭赐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起确沸,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捌锭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后罗捎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體观谦,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年桨菜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豁状。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捉偏。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖泻红,靈堂內(nèi)的尸體忽然破棺而出夭禽,到底是詐尸還是另有隱情,我是刑警寧澤谊路,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布讹躯,位于F島的核電站,受9級(jí)特大地震影響凶异,放射性物質(zhì)發(fā)生泄漏蜀撑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一剩彬、第九天 我趴在偏房一處隱蔽的房頂上張望酷麦。 院中可真熱鬧,春花似錦喉恋、人聲如沸沃饶。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)糊肤。三九已至,卻和暖如春氓鄙,著一層夾襖步出監(jiān)牢的瞬間馆揉,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工抖拦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留升酣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓态罪,卻偏偏與公主長(zhǎng)得像噩茄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子复颈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容