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

简介:

听闻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的组来方便管理,就如我们前面提到的一样,即便是复杂的人物模型,也可以通过这样的方式组合起来:

代码
 
 
  1. /// <summary> 
  2. /// 自定义的模型组,即便是复杂的人物模型,也可以通过这样的方式组合出来  
  3. /// </summary> 
  4. public class MeshGroup : Balder.Objects.Geometries.Geometry  
  5. {  
  6.     //计时器  
  7.     DispatcherTimer _dispatchertimer = new DispatcherTimer();  
  8.     public MeshGroup()  
  9.     {  
  10.         Name = "MeshGroup";  
  11.         Game_Axis axis_x = new Game_Axis(new Vertex(-300, 0, 0), new Vertex(300, 0, 0), Colors.Red);  
  12.         Game_Axis axis_y = new Game_Axis(new Vertex(0, -300, 0), new Vertex(0, 300, 0), Colors.Blue);  
  13.         Game_Axis axis_z = new Game_Axis(new Vertex(0, 0, -300), new Vertex(0, 0, 300), Colors.Green);  
  14.         Children.Add(axis_x);  
  15.         Children.Add(axis_y);  
  16.         Children.Add(axis_z);  
  17.         Mesh Teapot = new Mesh();  
  18.         Teapot.Position = new Coordinate(0, 0, 0);  
  19.         Teapot.AssetName = new Uri("/Balder_Studio;component/Res/teapot.ase", UriKind.Relative);  
  20.         Children.Add(Teapot);  
  21.         Children.Add(_box);  
  22.         Children.Add(new Box() { Dimension = new Coordinate(10, 30, 10), Position = new Coordinate(10, 10, -75) });  
  23.         MainPage.MainThis.ToShow.Click += new System.Windows.RoutedEventHandler(ToShow_Click);  
  24.         _dispatchertimer.Tick += new EventHandler(_dispatchertimer_Tick);  
  25.         _dispatchertimer.Interval = TimeSpan.FromMilliseconds(30);  
  26.     }  
  27.     void ToShow_Click(object sender, System.Windows.RoutedEventArgs e)  
  28.     {  
  29.         _dispatchertimer.Start();  
  30.     }  
  31.     Balder.Objects.Geometries.Box _box = new Box() { Dimension = new Coordinate(10, 20, 30), Position = new Coordinate(75, 10, 0), Name = "MyBox" };  
  32.     //旋转角度计数  
  33.     float angle = 0;  
  34.     float speed = 2;  
  35.     void _dispatchertimer_Tick(object sender, EventArgs e)  
  36.     {  
  37.         World = Balder.Math.Matrix.CreateRotationY(angle++);  
  38.         _box.Position.Y += speed;  
  39.         if (_box.Position.Y >= 50 || _box.Position.Y <= 0)  
  40.             speed = -speed;  
  41.  
  42.     }  
  43. }  
  44. 在这个组里面,在内部实现了一个动画,一块砖头在飘忽,动画参见 L4 模型组和简单的动画  
  45. 我们在Lesson06.xmal.cs文件中加入如下代码:  
  46.  
  47. Lesson06   
  48. public partial class Lesson06 : UserControl  
  49. {  
  50.     public Camera _myCamera = new Camera();  
  51.     public Lesson06()  
  52.     {  
  53.         InitializeComponent();  
  54.  
  55.         slider_axis_x.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  56.         slider_axis_y.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);  
  57.         slider_axis_z.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);             
  58.  
  59.         slider_axis_x1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  60.         slider_axis_y1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  61.         slider_axis_z1.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  62.  
  63.         slider_perspective.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  64.         slider_near_clip.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  65.         slider_far_clip.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);  
  66.  
  67.         //L3  
  68.         Game game = new Game() { Width = 600Height = 400 };  
  69.         game.Camera = _myCamera;  
  70.         game.Camera.Position = new Coordinate(100, 120, 150);  
  71.         game.Camera.Target = new Coordinate(0, 0, 0);              
  72.  
  73.         game.Children.Add(new OmniLight() { Position = new Coordinate(0, 0, 0) });  
  74.         game.Children.Add(new MeshGroup());  
  75.         LayoutRoot.Children.Add(game);  
  76.     }  
  77.           
  78.     void slider_axis_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)  
  79.     {  
  80.         axis_z.Text = ((int)slider_axis_z.Value).ToString();  
  81.         _myCamera.Position.Z = slider_axis_z.Value;  
  82.         axis_y.Text = ((int)slider_axis_y.Value).ToString();  
  83.         _myCamera.Position.Y = slider_axis_y.Value;  
  84.         axis_x.Text = ((int)slider_axis_x.Value).ToString();  
  85.         _myCamera.Position.X = slider_axis_x.Value;              
  86.     }  
  87.     void slider_Target_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)  
  88.     {  
  89.         axis_z1.Text = ((int)slider_axis_z1.Value).ToString();  
  90.         axis_y1.Text = ((int)slider_axis_y1.Value).ToString();  
  91.         axis_x1.Text = ((int)slider_axis_x1.Value).ToString();  
  92.         _myCamera.Target.Z = slider_axis_z1.Value;  
  93.         _myCamera.Target.Y = slider_axis_y1.Value;  
  94.         _myCamera.Target.X = slider_axis_x1.Value;  
  95.  
  96.         text_perspective.Text = ((int)slider_perspective.Value).ToString();  
  97.         text_near_clip.Text = ((int)slider_near_clip.Value).ToString();  
  98.         text_far_clip.Text = ((int)slider_far_clip.Value).ToString();  
  99.         _myCamera.Far = (float)slider_far_clip.Value;  
  100.         _myCamera.Near= (float)slider_near_clip.Value;  
  101.         _myCamera.FieldOfView = slider_perspective.Value;  
  102.  
  103.     }  
  104. }  
  105.    
  106.  
我尽量简单描写,建议不是太明白的朋友参看之前的文章,主要是用Slider控件控制属性达到效果。

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

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

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


本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/711581


相关文章
|
4月前
|
存储 开发框架 .NET
【C#】C# 基础语法与游戏开发
【1月更文挑战第21天】【C#】C# 基础语法与游戏开发
|
1天前
|
存储 运维 BI
基于C#-VC-MSSQL开发的全套PACS系统源码 3D PACS系统源码:可实现医学影像获取、存档、观片、处理、打印多项应用
PACS的功能价值在于通过连接不同的影像设备,存储与管理图像,图像的调用与后处理,实现资源共享,降低成本,达到提高工作效率、提升医疗水平的目地;
7 1
基于C#-VC-MSSQL开发的全套PACS系统源码  3D PACS系统源码:可实现医学影像获取、存档、观片、处理、打印多项应用
|
4月前
|
存储 开发框架 .NET
【C#】认识C# (为了游戏开发 O(≧口≦)O)
【1月更文挑战第26天】【C#】认识C# (为了游戏开发 O(≧口≦)O)
|
5月前
|
存储 C#
【Untiy 3D】C#中文件夹与读写文件操作详解(附测试代码 超详细)
【Untiy 3D】C#中文件夹与读写文件操作详解(附测试代码 超详细)
41 0
|
前端开发 C#
silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发)
原文:silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发) 这篇介绍的是3D导航,点击图标,页面360°翻转的效果!有什么不足的欢迎大家指出来。 1.新建一个usercontrol,命名为menu. 2.按照下图设置一下属性。
1221 0
|
20天前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
20天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。