Silverlight C# 游戏开发:L6 3D摄像机

2016-08-20 11:07:40来源:http://nowpaper.blog.51cto.com/3893223/711581作者:nowpaper人点击


听闻Silverlight5将会支持3D的调用甚至控件,非常兴奋,以后Silverlight就可以开发3D游戏了,但是我这个系列的文章才刚刚进行到一半,看来要加快速度,这篇主要介绍关于摄像机的相关开发,游戏离不开摄像机(Camera),Camera相当于眼睛,有了眼睛才看到世界,可是眼睛也有相应的参数,在Balder 3D中创建摄像机相当的简单,在前几篇的代码中就能很容易的看出来,但是如何去控制摄像机达到我们的目的呢,先让我们了解一下3D世界的摄像机。



上图是一个3D世界摄像机的基本属性,它和其他的3D物体一致的部分在于空间坐标表示,但是为了看到世界,它需要一些其他的参数来描述功能,比如Far/Near Clip(近远景裁切)、Target(目标点)、Perspective field of view(视角)等等,这些属性为我们渲染3D游戏世界提供了基础参照。打开Balder 中Camera类就能看到这些属性,下面是简要说明:


Camera.Far:远景裁切,即最远看到的距离


Camera.Near:近景裁切,即最近看到的距离


Camera.FieldOfView:视角,所看范围,例如人类的视角就是60度


Camera.Target:目标点,即所看的目标位置,两点成一向量嘛


而其他的我们如果不做深层的开发一般用不上,例如Forward、Up、DepthDivisor、DepthZero


下面开发一个小程序来控制摄像机的这些属性,预览图如下:






这个只是一个简单的控件控制属性刷新的小小程序,首先要设计和制作一个界面:




但是这一次,我写了一个Mesh的组来方便管理,就如我们前面提到的一样,即便是复杂的人物模型,也可以通过这样的方式组合起来:


代码
///<summary>///自定义的模型组,即便是复杂的人物模型,也可以通过这样的方式组合出来 ///</summary>publicclassMeshGroup:Balder.Objects.Geometries.Geometry { //计时器 DispatcherTimer_dispatchertimer=newDispatcherTimer(); publicMeshGroup() { Name="MeshGroup"; Game_Axisaxis_x=newGame_Axis(newVertex(-300,0,0),newVertex(300,0,0),Colors.Red); Game_Axisaxis_y=newGame_Axis(newVertex(0,-300,0),newVertex(0,300,0),Colors.Blue); Game_Axisaxis_z=newGame_Axis(newVertex(0,0,-300),newVertex(0,0,300),Colors.Green); Children.Add(axis_x); Children.Add(axis_y); Children.Add(axis_z); MeshTeapot=newMesh(); Teapot.Position=newCoordinate(0,0,0); Teapot.AssetName=newUri("/Balder_Studio;component/Res/teapot.ase",UriKind.Relative); Children.Add(Teapot); Children.Add(_box); Children.Add(newBox(){Dimension=newCoordinate(10,30,10),Position=newCoordinate(10,10,-75)}); MainPage.MainThis.ToShow.Click+=newSystem.Windows.RoutedEventHandler(ToShow_Click); _dispatchertimer.Tick+=newEventHandler(_dispatchertimer_Tick); _dispatchertimer.Interval=TimeSpan.FromMilliseconds(30); } voidToShow_Click(objectsender,System.Windows.RoutedEventArgse) { _dispatchertimer.Start(); } Balder.Objects.Geometries.Box_box=newBox(){Dimension=newCoordinate(10,20,30),Position=newCoordinate(75,10,0),Name="MyBox"}; //旋转角度计数 floatangle=0; floatspeed=2; void_dispatchertimer_Tick(objectsender,EventArgse) { World=Balder.Math.Matrix.CreateRotationY(angle++); _box.Position.Y+=speed; if(_box.Position.Y>=50||_box.Position.Y<=0) speed=-speed; } } 在这个组里面,在内部实现了一个动画,一块砖头在飘忽,动画参见L4模型组和简单的动画 我们在Lesson06.xmal.cs文件中加入如下代码: Lesson06 publicpartialclassLesson06:UserControl { publicCamera_myCamera=newCamera(); publicLesson06() { InitializeComponent(); slider_axis_x.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged); slider_axis_y.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged); slider_axis_z.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged); slider_axis_x1.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); slider_axis_y1.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); slider_axis_z1.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); slider_perspective.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); slider_near_clip.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); slider_far_clip.ValueChanged+=newSystem.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged); //L3 Gamegame=newGame(){Width=600,Height=400}; game.Camera=_myCamera; game.Camera.Position=newCoordinate(100,120,150); game.Camera.Target=newCoordinate(0,0,0); game.Children.Add(newOmniLight(){Position=newCoordinate(0,0,0)}); game.Children.Add(newMeshGroup()); LayoutRoot.Children.Add(game); }voidslider_axis_ValueChanged(objectsender,System.Windows.RoutedPropertyChangedEventArgs<double>e) { axis_z.Text=((int)slider_axis_z.Value).ToString(); _myCamera.Position.Z=slider_axis_z.Value; axis_y.Text=((int)slider_axis_y.Value).ToString(); _myCamera.Position.Y=slider_axis_y.Value; axis_x.Text=((int)slider_axis_x.Value).ToString(); _myCamera.Position.X=slider_axis_x.Value; } voidslider_Target_ValueChanged(objectsender,System.Windows.RoutedPropertyChangedEventArgs<double>e) { axis_z1.Text=((int)slider_axis_z1.Value).ToString(); axis_y1.Text=((int)slider_axis_y1.Value).ToString(); axis_x1.Text=((int)slider_axis_x1.Value).ToString(); _myCamera.Target.Z=slider_axis_z1.Value; _myCamera.Target.Y=slider_axis_y1.Value; _myCamera.Target.X=slider_axis_x1.Value; text_perspective.Text=((int)slider_perspective.Value).ToString(); text_near_clip.Text=((int)slider_near_clip.Value).ToString(); text_far_clip.Text=((int)slider_far_clip.Value).ToString(); _myCamera.Far=(float)slider_far_clip.Value; _myCamera.Near=(float)slider_near_clip.Value; _myCamera.FieldOfView=slider_perspective.Value; } }
我尽量简单描写,建议不是太明白的朋友参看之前的文章,主要是用Slider控件控制属性达到效果。

那么最后我们运行一下看看效果吧:


源代码下载地址:点击这里下载工程


工程中如果缺少Balder.dll请在这里快速下载:SL4_Balder.rar


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台