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

基于SceneForm实现子d射击(绘制子d运行轨迹),第1张

概述基于SceneForm实现子d射击(绘制子d运行轨迹) 基于 SceneForm 实现的子d射击(绘制子d运行轨迹) Sceneform 框架很强大,不了解 Sceneform 的时候,觉得要想做 3D 场景需要会 OpenGL,而 OpenGL 的学习曲线很陡:接触到这个框架之后觉得小白也可以很快上手,甚至可以实现第一人称射击的效果 注:自己学习 SceneForm 有一段时间了,不过没有发现模拟重力场的接口,不知道是不是自己漏掉了 模拟射击效果的思路其实很简单 1.加载一个子d模型 2.规划子d由近及远的轨迹 3.绘制子d的运行轨迹 子d运行轨迹

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

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

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

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

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

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

class MainActivity : AppCompatActivity() { var arFragment : CleanArFragment? = null var camera : Camera? = null var size = Point(); //屏幕尺寸,控制子d发射的初始位置 var bullet : ModelRenderable? = null var scene : Scene? = null val SHOT = 0x1101  //绘制过程轨迹信号 val SHOT_OVER = 0x1102 //清除子d模型信号 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) { //一次射击完成,清除屏幕的子d    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) //初始化子d模型 private fun initbullet() {  Texture.builder().setSource(this@MainActivity,R.drawable.texture).build()   .thenAccept(    { texture ->    MaterialFactory.makeOpaqueWithTexture(this@MainActivity,texture)     .thenAccept { material ->      // 设置子d模型为球体      bullet = ShapeFactory.makeSphere(0.1f,Vector3(0f,0f,0f),material) }    }   ) } private fun shoot() {  //从屏幕发出的射线,对应子d的运行轨迹  var ray = camera!!.screenPointToRay(size.x / 2f,size.y / 2f);  var node = Node() //子d节点  node.renderable = bullet //子d节点加载子d模型  scene!!.addChild(node)  Thread(object : Runnable{   overrIDe fun run() {    //子d射击过程中的轨迹,子线程处理轨迹事件,主线程改变轨迹位置    for (i in 1 .. 200 ) { //子d射程 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)    }    //子d超出距离后,从屏幕清除掉    var msg = handler.obtainMessage()    msg.what = SHOT_OVER    msg.obj = node    handler.sendMessage(msg)   }  }).start() } // 子线程和主线程穿点的数据类 data class CurrentStatus(var node : Node,var status : Vector3)}

界面布局

<?xml version="1.0" en@R_419_5563@="utf-8"?><relativeLayout  xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:tools="http://schemas.androID.com/tools"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  tools:context=".MainActivity"> <fragment   androID:layout_wIDth="match_parent"   androID:layout_height="match_parent"   androID:ID="@+ID/arFragment"   androID:name="com.hosh.shootapplication.CleanArFragment"/> <VIEw   androID:layout_wIDth="35dp"   androID:layout_height="2dp"   androID:background="#ff0000"   androID:layout_centerInParent="true" /> <VIEw   androID:layout_wIDth="2dp"   androID:layout_height="35dp"   androID:background="#ff0000"   androID:layout_centerInParent="true" /> <button   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:ID="@+ID/shootbutton"   androID:layout_alignParentBottom="true"   androID:layout_centerHorizontal="true"   androID:layout_marginBottom="8dp"   androID:text="@string/shoot" /></relativeLayout>

实现效果如下,因为动图的偏差,子d不是很清晰,子d由中心的红色十字向远处射击


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

总结

以上是内存溢出为你收集整理的基于SceneForm实现子d射击(绘制子d运行轨迹)全部内容,希望文章能够帮你解决基于SceneForm实现子d射击(绘制子d运行轨迹)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1144271.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存