千家信息网

如何用SceneForm实现子弹射击并绘制子弹运行轨迹

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇文章为大家展示了如何用SceneForm实现子弹射击并绘制子弹运行轨迹,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。基于 SceneForm 实现的子弹射
千家信息网最后更新 2026年11月02日如何用SceneForm实现子弹射击并绘制子弹运行轨迹

本篇文章为大家展示了如何用SceneForm实现子弹射击并绘制子弹运行轨迹,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

基于 SceneForm 实现的子弹射击(绘制子弹运行轨迹)

Sceneform 框架很强大,不了解 Sceneform 的时候,觉得要想做 3D 场景需要会 OpenGL,而 OpenGL 的学习曲线很陡;接触到这个框架之后觉得小白也可以很快上手,甚至可以实现第一人称射击的效果

注:自己学习 SceneForm 有一段时间了,不过没有发现模拟重力场的接口,不知道是不是自己漏掉了

模拟射击效果的思路其实很简单

1、加载一个子弹模型2、规划子弹由近及远的轨迹3、绘制子弹的运行轨迹

子弹运行轨迹的逻辑代码;代码中涉及的 CleanArFragment 在之前的《ARCore 的 SceneForm 框架在没有 Plane 情况下的绘制 3D 模型》已经给出;另外需要自行提供一个纹理图片,即代码中的 R.drawable.texture。

class MainActivity : AppCompatActivity() { var arFragment : CleanArFragment? = null var camera : Camera? = null var size = Point(); //屏幕尺寸,控制子弹发射的初始位置 var bullet : ModelRenderable? = null var scene : Scene? = null val SHOT = 0x1101 //绘制过程轨迹信号 val SHOT_OVER = 0x1102 //清除子弹模型信号 var handler = object : Handler() { override fun handleMessage(msg : Message) { if (msg.what == SHOT) { //绘制移动过程中的轨迹 var currentStatus = msg.obj as CurrentStatus currentStatus.node.worldPosition = currentStatus.status } else if (msg.what == SHOT_OVER) { //一次射击完成,清除屏幕的子弹 var node = msg.obj as Node scene!!.removeChild(node) } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 获取屏幕尺寸 val display = windowManager.defaultDisplay display.getRealSize(size) arFragment = this.supportFragmentManager.findFragmentById(R.id.arFragment) as CleanArFragment arFragment!!.arSceneView.planeRenderer.isEnabled = false //禁止 sceneform 框架的平面绘制 scene = arFragment!!.arSceneView.scene camera = scene!!.camera initbullet() shootButton.setOnClickListener(listener) } var listener : View.OnClickListener = object : View.OnClickListener{ override fun onClick(v: View?) { shoot() } } @TargetApi(Build.VERSION_CODES.N) //初始化子弹模型 private fun initbullet() { Texture.builder().setSource(this@MainActivity, R.drawable.texture).build() .thenAccept( { texture -> MaterialFactory.makeOpaqueWithTexture(this@MainActivity, texture) .thenAccept { material -> // 设置子弹模型为球体 bullet = ShapeFactory.makeSphere(0.1f, Vector3(0f, 0f, 0f), material) } } ) } private fun shoot() { //从屏幕发出的射线,对应子弹的运行轨迹 var ray = camera!!.screenPointToRay(size.x / 2f, size.y / 2f); var node = Node() //子弹节点 node.renderable = bullet //子弹节点加载子弹模型 scene!!.addChild(node) Thread(object : Runnable{ override fun run() { //子弹射击过程中的轨迹,子线程处理轨迹事件,主线程改变轨迹位置 for (i in 1 .. 200 ) { //子弹射程 20 m var stepLen = i; var currentPoint = ray.getPoint(stepLen * 0.1f) var msg = handler.obtainMessage() msg.what = SHOT msg.obj = CurrentStatus(node, currentPoint) handler.sendMessage(msg) } //子弹超出距离后,从屏幕清除掉 var msg = handler.obtainMessage() msg.what = SHOT_OVER msg.obj = node handler.sendMessage(msg) } }).start() } // 子线程和主线程穿点的数据类 data class CurrentStatus(var node : Node, var status : Vector3)}

界面布局

子弹 轨迹 射击 运行 模型 屏幕 框架 线程 代码 效果 过程 位置 信号 内容 尺寸 技能 知识 节点 学习 强大 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 喔噻互联网科技有限公司 天津市摩尔互联网科技 上海卓越科技互联网 互联网中国科技 北京互联网科技有限公司 无线互联网科技 友谊互联网络科技 湖南洣水互联网科技有限公司扣款 博兴的互联网电子科技公司 千方科技属于互联网企业吗 和信科技工业互联网 互联网科技数字货币 本届互联网大会上的黑科技 工业互联网科技创业 宁波跨境商互联网科技有限公司 萌小萌互联网科技河南有限公司 中国科技和美国互联网 互联网科技职业技能培训学校 科技互联网公司两年变化 互联网高科技绘画 上海挚品互联网科技有限公司 奇酷互联网络科技公司 互联网 科技服务平台 中国互联网金融科技基金 科技伦理 互联网公司 哈尔滨新华互联网科技 济南华为互联网科技产业总部基地 呼和浩特新华互联网科技学院 链环科技传统企业怎么转型互联网 互联网科技手机排行榜
0