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

    代码
    /// <summary>
    /// 自定义的模型组,即便是复杂的人物模型,也可以通过这样的方式组合出来
    /// </summary>
    public class MeshGroup : Balder.Objects.Geometries.Geometry
    {
        
    //计时器
        DispatcherTimer _dispatchertimer = new DispatcherTimer();
        
    public MeshGroup()
        {
            Name 
    = "MeshGroup";
            Game_Axis axis_x 
    = new Game_Axis(new Vertex(-30000), new Vertex(30000), Colors.Red);
            Game_Axis axis_y 
    = new Game_Axis(new Vertex(0-3000), new Vertex(03000), Colors.Blue);
            Game_Axis axis_z 
    = new Game_Axis(new Vertex(00-300), new Vertex(00300), Colors.Green);
            Children.Add(axis_x);
            Children.Add(axis_y);
            Children.Add(axis_z);
            Mesh Teapot 
    = new Mesh();
            Teapot.Position 
    = new Coordinate(000);
            Teapot.AssetName 
    = new Uri("/Balder_Studio;component/Res/teapot.ase", UriKind.Relative);
            Children.Add(Teapot);
            Children.Add(_box);
            Children.Add(
    new Box() { Dimension = new Coordinate(103010), Position = new Coordinate(1010-75) });
            MainPage.MainThis.ToShow.Click 
    += new System.Windows.RoutedEventHandler(ToShow_Click);
            _dispatchertimer.Tick 
    += new EventHandler(_dispatchertimer_Tick);
            _dispatchertimer.Interval 
    = TimeSpan.FromMilliseconds(30);
        }
        
    void ToShow_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            _dispatchertimer.Start();
        }
        Balder.Objects.Geometries.Box _box 
    = new Box() { Dimension = new Coordinate(102030), Position = new Coordinate(75100), Name = "MyBox" };
        
    //旋转角度计数
        float angle = 0;
        
    float speed = 2;
        
    void _dispatchertimer_Tick(object sender, EventArgs e)
        {
            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
    public partial class Lesson06 : UserControl
    {
        
    public Camera _myCamera = new Camera();
        
    public Lesson06()
        {
            InitializeComponent();

            slider_axis_x.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);
            slider_axis_y.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);
            slider_axis_z.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_axis_ValueChanged);           

            slider_axis_x1.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);
            slider_axis_y1.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);
            slider_axis_z1.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);

            slider_perspective.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);
            slider_near_clip.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);
            slider_far_clip.ValueChanged 
    += new System.Windows.RoutedPropertyChangedEventHandler<double>(slider_Target_ValueChanged);

            
    //L3
            Game game = new Game() { Width = 600, Height = 400 };
            game.Camera 
    = _myCamera;
            game.Camera.Position 
    = new Coordinate(100120150);
            game.Camera.Target 
    = new Coordinate(000);            

            game.Children.Add(
    new OmniLight() { Position = new Coordinate(000) });
            game.Children.Add(
    new MeshGroup());
            LayoutRoot.Children.Add(game);
        }
            
        
    void slider_axis_ValueChanged(object sender, 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;            
        }
        
    void slider_Target_ValueChanged(object sender, 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控件控制属性达到效果。

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

    获取 Microsoft Silverlight

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

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

    推荐Silverlight游戏开发博客:深蓝色右手

  • 相关阅读:
    使用fiddler进行app弱网测试
    弱网测试
    Java虚拟机的内存模型
    Junit使用
    python安装numpy和scipy的资源
    HTTP资源合集
    http之post方法 提交数据的四种方法
    计算机编码中的换行 CR与LF
    python Mixin 是个啥?
    python mock的简单使用
  • 原文地址:https://www.cnblogs.com/nowpaper/p/1908289.html
Copyright © 2011-2022 走看看