佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 3503|回复: 20

跨入三次元:C# + MDX 3D 射击游戏基本架构

[复制链接]
发表于 1-8-2008 03:13 PM | 显示全部楼层 |阅读模式
最近研究了一下 Direct 3D,终于能够成功的载入 3D 模型和控制显示,移动物件。我把这个程式分成了几个 class, 为了能够在以后的 project 里面再使用这些 class。

语言:Visual C# Express Edition 2005
API: DirectX SDK 9.0c March 2008
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Design;
  4. using System.Windows.Forms;
  5. using Microsoft.DirectX;
  6. using Microsoft.DirectX.Direct3D;
  7. using Microsoft.DirectX.DirectInput;
  8. using Microsoft.DirectX.DirectSound;

  9. namespace Project1
  10. {
  11.     public class D3DGame : Form
  12.     {
  13.         Microsoft.DirectX.Direct3D.Device d3dev = null;
  14.         Microsoft.DirectX.DirectInput.Device keyb = null;        
  15.         PresentParameters pp;

  16.         Sprite titleSprite = null;
  17.         Texture titleTexture = null;
  18.         SizeF titleSize = new SizeF(800f, 600f);
  19.         Point titlePos = new Point(0, 0);
  20.         MyMeshClass groundMesh = null;        
  21.         PlayerClass player = null;

  22.         enum GameStates {gsTitle, gsPlaying, gsQuiting, gsGameEnd};
  23.         GameStates gameState = GameStates.gsTitle;

  24.         public D3DGame()
  25.         {
  26.             this.Size = new Size(800, 600);
  27.             this.Text = "Direct 3D game Framework";
  28.             this.StartPosition = FormStartPosition.CenterScreen;
  29.             this.FormBorderStyle = FormBorderStyle.None;
  30.         }
  31.         //----------------------------------------------------------------------------------------------
  32.         static void Main()
  33.         {
  34.             using(D3DGame MyGame = new D3DGame())
  35.             {
  36.                 if (!MyGame.initGame())
  37.                 {
  38.                     MessageBox.Show("Failed to initialize Game: " +
  39.                         Direct3DXException.GetDirectXErrorString(Direct3DXException.LastError),
  40.                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  41.                     return;
  42.                 }
  43.                 MyGame.Show();

  44.                 while (MyGame.Created)
  45.                 {
  46.                     MyGame.updateGame();
  47.                     Application.DoEvents();
  48.                 }
  49.             }            
  50.         }
  51.         //----------------------------------------------------------------------------------------------
  52.         private bool initGame()
  53.         {
  54.             if (!initD3D())
  55.                 return false;

  56.             if (!initInput())
  57.                 return false;

  58.             try
  59.             {
  60.                 titleSprite = new Sprite(d3dev);
  61.                 titleTexture = TextureLoader.FromFile(d3dev, "Title Screen.png");
  62.                 return true;
  63.             }
  64.             catch (DirectXException)
  65.             {
  66.                 return true;
  67.             }
  68.             
  69.         }
  70.         //----------------------------------------------------------------------------------------------
  71.         private bool initD3D()
  72.         {
  73.             pp = new PresentParameters();
  74.             pp.Windowed = false;
  75.             pp.BackBufferCount = 1;
  76.             pp.BackBufferWidth = 800;
  77.             pp.BackBufferHeight = 600;
  78.             pp.BackBufferFormat = Format.A8R8G8B8;
  79.             pp.SwapEffect = SwapEffect.Discard;                        
  80.             pp.EnableAutoDepthStencil = true;
  81.             pp.AutoDepthStencilFormat = DepthFormat.D16;
  82.             pp.DeviceWindowHandle = this.Handle;            

  83.             try
  84.             {
  85.                 d3dev = new Microsoft.DirectX.Direct3D.Device(0,
  86.                             Microsoft.DirectX.Direct3D.DeviceType.Hardware,
  87.                             this,
  88.                             CreateFlags.MixedVertexProcessing,
  89.                             pp);

  90.                 d3dev.RenderState.ZBufferEnable = true;
  91.                 d3dev.RenderState.Ambient = Color.SkyBlue;
  92.                 d3dev.RenderState.Lighting = true;
  93.                 d3dev.RenderState.NormalizeNormals = true;
  94.                 d3dev.RenderState.FillMode = FillMode.Solid;
  95.                 d3dev.RenderState.CullMode = Cull.CounterClockwise;

  96.                 d3dev.Lights[0].Type = LightType.Directional;
  97.                 d3dev.Lights[0].Direction = new Vector3(0f, 1f, 0f);               
  98.                 d3dev.Lights[0].Ambient = Color.Blue;
  99.                 d3dev.Lights[0].Specular = Color.White;
  100.                 d3dev.Lights[0].Enabled = true;

  101.                 d3dev.Lights[1].Type = LightType.Point;
  102.                 d3dev.Lights[1].Position = new Vector3(0f, 3f, 0f);
  103.                 d3dev.Lights[1].Range = 4f;
  104.                 d3dev.Lights[1].Ambient = Color.Orange;
  105.                 d3dev.Lights[1].Specular = Color.LightYellow;
  106.                 d3dev.Lights[1].Enabled = true;


  107.                 //d3dev.Transform.Projection = Matrix.OrthoLH(25f, 25f, 1f, 60f);
  108.                 d3dev.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4),
  109.                                                                      (float)(this.Width / this.Height),
  110.                                                                      1f, 100f);
  111.                 d3dev.Transform.View = Matrix.LookAtLH(new Vector3(15f, 20f, -15f),
  112.                                                        new Vector3(0f, 0f, 0f),
  113.                                                        new Vector3(0f, 1f, 0f));

  114.                 groundMesh = new MyMeshClass(d3dev);
  115.                 groundMesh.loadFromMeshFromX("ground.x");

  116.                 player = new PlayerClass("ship.x", d3dev);               
  117.                 return true;
  118.             }
  119.             catch (Direct3DXException)
  120.             {               
  121.                 return false;
  122.             }
  123.         }
  124.         //----------------------------------------------------------------------------------------------
  125.         private bool initInput()
  126.         {
  127.             try
  128.             {
  129.                 keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
  130.                 if (keyb != null)
  131.                 {
  132.                     keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
  133.                     keyb.Acquire();
  134.                 }
  135.                 return true;
  136.             }
  137.             catch (Direct3DXException)
  138.             {
  139.                 return false;
  140.             }
  141.         }
  142.         //----------------------------------------------------------------------------------------------
  143.         private void updateGame()
  144.         {
  145.             if (!processInput())
  146.                 return;
  147.             
  148.             renderGame();
  149.         }
  150.         //----------------------------------------------------------------------------------------------
  151.         private bool processInput()
  152.         {
  153.             KeyboardState ks = keyb.GetCurrentKeyboardState();

  154.             if (ks[Key.Escape])
  155.             {
  156.                 this.Close();
  157.                 return false;               
  158.             }
  159.             if (ks[Key.Return])
  160.             {               
  161.                 gameState = GameStates.gsPlaying;
  162.             }

  163.             player.updatePlayer(ks);

  164.             return true;
  165.         }
  166.         //----------------------------------------------------------------------------------------------
  167.         private void renderGame()
  168.         {
  169.             d3dev.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1f, 0);

  170.             d3dev.BeginScene();
  171.             {
  172.                 switch(gameState)
  173.                 {
  174.                     case GameStates.gsTitle:
  175.                         if (titleSprite != null)
  176.                         {
  177.                             titleSprite.Begin(SpriteFlags.AlphaBlend);
  178.                             {
  179.                                 titleSprite.Draw2D(titleTexture, Rectangle.Empty, titleSize, titlePos, Color.White);
  180.                             }
  181.                             titleSprite.End();
  182.                         }
  183.                         break;
  184.                     case GameStates.gsPlaying:
  185.                         if (groundMesh != null)
  186.                         {
  187.                             groundMesh.drawMesh();
  188.                         }
  189.                         if (player != null)
  190.                         {
  191.                             player.actorDraw();
  192.                         }
  193.                         break;
  194.                 }
  195.             }
  196.             d3dev.EndScene();
  197.             d3dev.Present();
  198.         }
  199.     }   
  200. }
复制代码
这是游戏的主程式,包含了初始化Direct3D, DirectInput, 载入游戏资源(一个地面的立体模型,一个战机的立体模型),游戏循环,读取用户输入和作出游戏更新/画面描绘等功能。

[待续]

[ 本帖最后由 geekman 于 1-8-2008 05:03 PM 编辑 ]
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 1-8-2008 03:14 PM | 显示全部楼层
初始化Direct3D和我以前写过的2D游戏的过程相似(请参考使用C# + Managed DIrectX 制作 2D 游戏),只是为了配合3D显示,加入了一些新的设置:
  1. pp = new PresentParameters();
  2. pp.Windowed = false;
  3. pp.BackBufferCount = 1;
  4. pp.BackBufferWidth = 800;
  5. pp.BackBufferHeight = 600;
  6. pp.BackBufferFormat = Format.A8R8G8B8;
  7. pp.SwapEffect = SwapEffect.Discard;                        
  8. pp.EnableAutoDepthStencil = true;
  9. pp.AutoDepthStencilFormat = DepthFormat.D16;
  10. pp.DeviceWindowHandle = this.Handle;
复制代码
在PresentParameters里面,新增的设置是
  1. pp.EnableAutoDepthStencil = true;
  2. pp.AutoDepthStencilFormat = DepthFormat.D16;
复制代码
这两个设置是互相关联的。DepthStencil 是用来计算立体物件的位置的深度,这样才能准确地描绘出物件的前后,不然描绘出来的画面会变得一塌糊涂。你可以尝试把
pp.EnableAutoDepthStencil 设定位 false,就会发现立体物件的前后次序会变得混乱,无法正确的描绘出来。

在正确的建立 Direct3D.Device(也就是和你的显示卡沟通的界面)后,就得进行一系列的设定
  1. d
  2. 3dev.RenderState.ZBufferEnable = true;
  3. d3dev.RenderState.Ambient = Color.SkyBlue;
  4. d3dev.RenderState.Lighting = true;
  5. d3dev.RenderState.NormalizeNormals = true;
  6. d3dev.RenderState.FillMode = FillMode.Solid;
  7. d3dev.RenderState.CullMode = Cull.CounterClockwise;
复制代码
RenderState 是一系列用于控制你的显示卡如何描绘立体场景的设定。

ZBuffer 就是和上面的 DepthStencil 相关的一个设定,所有物件的深浅设定,也就是 z-轴 的数值,就是储存在 ZBuffer 里面的。

Ambient 决定你的场景的默认光线颜色,我选择了天蓝色。

Lighting 决定了渲染引擎是否要计算光源对场景的影响,既然我们要使用光源,当然要设定为 true,不然整个场景就会乌漆抹黑的。

NormalizeNormal 是计算立体模型的 Normal(决定多边形polygon的面对的方向),详细内容我还不大清楚,总之照用就是了。

FillMode 有3种选择:Solid(多边形会以实体形式来描绘),Wireframe(多边形会以线框形式来描绘)和 Point(不描绘多边形,只描绘每个多边形的顶点),有兴趣的自己试验看看吧。

CullMode 决定删除被阻挡的或不面对镜头的多边形,以节省运算。由于我的场景是采用左手式(Left Handed Coordinate)(也就是X-轴右边是正值,左边是负值,Y-轴向上是正值,向下是负值,Z-轴往荧幕里伸延是正值,向荧幕外伸延是负值)(右手式则正好相反,Z-轴会被翻转,向荧幕里面伸延是负值)所以要使用逆时钟方向删减运算,反之就会造成所有立体物件的多边形被里外对调,面对镜头的多边形会被删除。

接下来是设定光源:
  1. d3dev.Lights[0].Type = LightType.Directional;
  2. d3dev.Lights[0].Direction = new Vector3(0f, 1f, 0f);               
  3. d3dev.Lights[0].Ambient = Color.Blue;
  4. d3dev.Lights[0].Specular = Color.White;
  5. d3dev.Lights[0].Enabled = true;

  6. d3dev.Lights[1].Type = LightType.Point;
  7. d3dev.Lights[1].Position = new Vector3(0f, 3f, 0f);
  8. d3dev.Lights[1].Range = 4f;
  9. d3dev.Lights[1].Ambient = Color.Orange;
  10. d3dev.Lights[1].Specular = Color.LightYellow;
  11. d3dev.Lights[1].Enabled = true;
复制代码
我设定了两个光源,一个是Directional, 一个是Point。Directional Light 就是平行光源,可以被理解为太阳光,它没有出发点(Origin), 而是根据某个方向作出平行方向伸延,其来源在理论上是无限远,照射距离也是无限远的。它的 Direction 的设定就是它的方向,这是一个从世界起源点(World Origin,也就是 X=0, Y=0, Z=0)伸延出去的向量矢(vector),我把这个方向设定为从上向下的照射。

另一个光源着被设定为点光源,这是以一个点作为出发点的光源。光线会从这个点以辐射方式向所有方向射出,所以这也是最消耗运算资源的光源,使用时记得谨慎点。它的位置被设定为世界起源点的上面3各单位高度。点光源是有距离限制的,超过它的Range设定距离的物件将不会被它照射到。它也是可以被设定拥有衰退值(Attenuation),这是决定这个光源的强度如根据距离而衰减,我这里没有用到这个设定,也就是说这个光源从出发到结束都是维持相同的强度。

还有另一种光源,探射灯光源(Spotlight),在这里我没使用这种光源,如果有兴趣而又无法自己理解这种光源的,可以提出疑问,我会尝试向你解释。

[待续]

图片:




[ 本帖最后由 geekman 于 1-8-2008 03:56 PM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 1-8-2008 03:48 PM | 显示全部楼层
设定完光源后,就要设定镜头,这也是之前的2D版所没有的:
  1. //d3dev.Transform.Projection = Matrix.OrthoLH(25f, 25f, 1f, 60f);
  2. d3dev.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4),
  3.                                           (float)(this.Width / this.Height),
  4.                                           1f, 100f);
  5. d3dev.Transform.View = Matrix.LookAtLH(new Vector3(15f, 20f, -15f),
  6.                                            new Vector3(0f, 0f, 0f),
  7.                                             new Vector3(0f, 1f, 0f));
复制代码
注意我在第一行停用了一行代码,那是和第二行互换的不同显示方式。被停用的那个镜头设定是采用平行镜头(Ortho View, 又称 Isometric view,特点是每个影像投射(Projection)方向都是和三个主轴平行的, 看起来就好像SimCity 2000那样的画面)。

Ok,镜头的设定是通过两个变形(Transform)来完成的:投影(projection)和 视线 (view)。我采用了PerspectiveFovLH 也就是 Perspective Field of View Left Hand (因为我的场景是使用左手式的,还记得吗?),第一个参数是(Math.PI / 4)也就是镜头视线的宽度,设定为90度(以镜头方向为中心,左右各伸延45度), 第二个参数是画面宽度和高度的对比(Aspect Ratio),一般荧幕是4:3,也就是1.3333(640x480,800x600,1024x768依此类推),阔荧幕是16:9(1280x720),或者 16:10(1440x900),第四个参数是近景限制,也就是说距离镜头少过这数值的物体井不会被描绘出来(我设定为一个距离单位),最后的就是远景限制,也就是说和镜头超过这个距离的物体将不会被描绘出来。

第二个镜头设定的是其视线,三个参数分别为 1)镜头所在位置,2)镜头对准的焦点,和 3)镜头向上的方向(决定镜头的那个方向为上 - 你可以旋转镜头的方向的,你知道吗?)

这两项设定都是使用矩阵(Matrix)来进行的,如果你不熟悉矩阵的运作和原理,请询问你的数学老师(正确来书应该是Matematik Tambahan的老师,一般的数学老师可能不会懂这些的。。。

接下来是载入游戏使用的立体模型和初始化资源设定:
  1. groundMesh = new MyMeshClass(d3dev);
  2. groundMesh.loadFromMeshFromX("ground.x");
  3. player = new PlayerClass("ship.x", d3dev);
复制代码
这些模型我都是采用Direct X 专用的 .X 档案格式,关于如何设计立体模型,如何导出X档案等等,并不属于这个教学的范围,如有兴趣请另外提出讨论。

载入X档案我是使用了另外一个档案里的Class MyMeshClass,C# 允许你把各个Class储存在不同的档案 (class file) 里面以方便管理和再循环使用。关于 MyMeshClass 和 PlayerClass 以及其 base class 的 ActorClass,我会在以后慢慢讲解。

[待续]

[ 本帖最后由 geekman 于 1-8-2008 03:52 PM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 1-8-2008 04:21 PM | 显示全部楼层
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using Microsoft.DirectX;
  6. using Microsoft.DirectX.Direct3D;


  7. namespace Project1
  8. {
  9.     class MyMeshClass
  10.     {
  11.         Device device;
  12.         Mesh mesh;
  13.         Material[] material;
  14.         Texture[] texture;
  15.         ExtendedMaterial[] extmaterial;
  16.         Matrix matrix;
  17.         
  18.         public MyMeshClass(Device dev)
  19.         {
  20.             device = dev;
  21.             mesh = null;
  22.             material = null;
  23.             texture = null;
  24.             extmaterial = null;
  25.             matrix = Matrix.Translation(0f, 0f, 0f);
  26.         }

  27.         public bool loadFromMeshFromX(string filename)
  28.         {
  29.             try
  30.             {               
  31.                 mesh = Mesh.FromFile(filename, MeshFlags.SystemMemory, device, out extmaterial);
  32.                 if (texture == null)
  33.                 {
  34.                     texture = new Texture[extmaterial.Length];
  35.                     material = new Material[extmaterial.Length];
  36.                     for (int i = 0; i < extmaterial.Length; i++)
  37.                     {
  38.                         material[i] = extmaterial[i].Material3D;
  39.                         material[i].Ambient = material[i].Diffuse;
  40.                         if (extmaterial[i].TextureFilename != null && extmaterial[i].TextureFilename.Length > 0)
  41.                         {                           
  42.                            texture[i] = TextureLoader.FromFile(device, extmaterial[i].TextureFilename);                        
  43.                         }
  44.                     }                    
  45.                 }               
  46.                 return true;
  47.             }
  48.             catch (Direct3DXException)
  49.             {
  50.                 return false;
  51.             }
  52.         }

  53.         public void setMatrix(Vector3 vector)
  54.         {
  55.             matrix.Translate(vector);
  56.         }

  57.         public void drawMesh()
  58.         {
  59.             device.SetTransform(TransformType.World, matrix);           
  60.             for (int i = 0; i < extmaterial.Length; i++)
  61.             {
  62.                 device.Material = material[i];
  63.                 device.SetTexture(0, texture[i]);               
  64.                 mesh.DrawSubset(i);
  65.             }
  66.         }

  67.         public void drawMesh(Matrix newMatrix)
  68.         {
  69.             device.SetTransform(TransformType.World, newMatrix);
  70.             for (int i = 0; i < extmaterial.Length; i++)
  71.             {
  72.                 device.Material = material[i];
  73.                 device.SetTexture(0, texture[i]);
  74.                 mesh.DrawSubset(i);
  75.             }
  76.         }
  77.     }
  78. }
复制代码
这是 MyMeshClass 的源代码,它的作用就是根据用户提供的X档案名称载入立体模型,以及在接受到请求时把模型给描绘出来。载入的模型会自动的被放在其原始位置,也就是说当你在3D模型软件里面把模型的中心点放在(10, 10, 10), 那么这个模型被载入时也是会在(10, 10, 10)的位置,所以当你把模型导出到X档案时记得要先把模型的中心点设定在(0,0, 0)这样会比较容易控制模型的位置。为了把模型放置在想要的位置,你必须使用一个移位矩阵(Translate Matrix)把模型从其原始位置变形(Transform)到适当的位置。如果你的模型的原始位置不是(0,0, 0),你就得再额外多做一次移位变形才能得到正确的位置。

drawMesh()这个函式我提供了两种 overload 版本,一个会接受一个 Matrix 作为Argument,另一个则不接受任何 argument (使用其内部的 matrix ),这是为了配合不同的情况(PlayerClass 需要提供 Matrix 以作变形之用,以后的另一个一 ActorClass 为基础的 EnemyClass 将不需要提供 matrix, 它会使用自己内部的 matrix 做运算)。

[待续]
回复

使用道具 举报

 楼主| 发表于 2-8-2008 10:38 AM | 显示全部楼层
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using Microsoft.DirectX;
  6. using Microsoft.DirectX.Direct3D;
  7. using Microsoft.DirectX.DirectInput;
  8. using Microsoft.DirectX.DirectSound;

  9. namespace Project1
  10. {
  11.     class ActorClass
  12.     {
  13.         Vector3 pos;        
  14.         Matrix matrix;        
  15.         Microsoft.DirectX.Direct3D.Device device;
  16.         MyMeshClass actorMesh;        
  17.         
  18.         public ActorClass(string meshfile, Microsoft.DirectX.Direct3D.Device dev)
  19.         {
  20.             pos = new Vector3(0f, 0f, 0f);

  21.             device = dev;

  22.             actorMesh = new MyMeshClass(dev);
  23.             actorMesh.loadFromMeshFromX(meshfile);
  24.         }

  25.         public void setPos(Vector3 newPos)
  26.         {
  27.             pos = newPos;
  28.         }

  29.         public void setPos(float newX, float newY, float newZ)
  30.         {
  31.             pos.X = newX;
  32.             pos.Y = newY;
  33.             pos.Z = newZ;
  34.         }
  35.                
  36.         public void moveX(float delta)
  37.         {
  38.             pos.X += delta;
  39.         }
  40.         public void moveY(float delta)
  41.         {
  42.             pos.Y += delta;
  43.         }
  44.         public void moveZ(float delta)
  45.         {
  46.             pos.Z += delta;
  47.         }

  48.         public void actorUpdate()
  49.         {            
  50.             matrix.Translate(pos);
  51.         }

  52.         public void actorDraw()
  53.         {            
  54.             actorMesh.drawMesh(matrix);
  55.         }      
  56.     }
  57. }
复制代码
ActorClass 是所有在游戏里代表任何角色(玩家,敌人,NPC)的物件的基础 (base class),它包含了管理物件的模型,位置,更新(目前只有更新位置功能,将来会加入更多更新功能,例如AI运算,状态更新,动画效果等等)(当然如果这篇文章没人看而让我心灰意冷而腰斩,那就什么都是白说),和描绘功能。几乎所有功能都是通过 ActorUpdate() 来诱发。

[待续]
回复

使用道具 举报

 楼主| 发表于 2-8-2008 10:54 AM | 显示全部楼层
这就是用 ActorClass 做出来的 PlayerClass, 由于多数的功能已经由 ActorClass 包办了,所以 PlayerCalss 看来空荡荡的,只是增加了读取键盘输入和根据输入来移动玩家控制的战机。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using Microsoft.DirectX;
  6. using Microsoft.DirectX.Direct3D;
  7. using Microsoft.DirectX.DirectInput;
  8. using Microsoft.DirectX.DirectSound;

  9. namespace Project1
  10. {
  11.     class PlayerClass : ActorClass
  12.     {
  13.         float velocity;

  14.         public PlayerClass(string meshfile, Microsoft.DirectX.Direct3D.Device dev) : base(meshfile, dev)
  15.         {
  16.             velocity = 0.1f;
  17.             setPos(0f, 5f, 0f);
  18.         }

  19.         public void updatePlayer(KeyboardState ks)
  20.         {
  21.             if (ks[Key.A])
  22.                 moveX(-velocity);            

  23.             if (ks[Key.D])
  24.                 moveX(velocity);
  25.             
  26.             if (ks[Key.W])
  27.                 moveZ(velocity);            

  28.             if (ks[Key.S])
  29.                 moveZ(-velocity);            
  30.             
  31.             actorUpdate();
  32.         }
  33.     }
  34. }
复制代码
这就是我到目前的进度,会不会继续?天知道。没人看就代表我在浪费时间,浪费时间的事情会让我觉得没有更新动力,有心想学得就别潜水了,给点意见或什么的,就当是学费吧。

其实悟性高的人只需凭到目前的程度就已经可以开始制作自己的游戏了。

[待续??]
回复

使用道具 举报

Follow Us
 楼主| 发表于 2-8-2008 11:18 AM | 显示全部楼层
顺便一提我在这个 Project 用过的软件:

1)Blender    一个免费的 3D 模型制作软件,不过使用过 3D Studio Max 的我觉得这个 blender 的制作者应该是来自300万光年外的外星人,不,并不是因为 blender 先进到超越地球科技 300万光年,而是这个软件的使用界面和操作方式实在和许多大家已经熟悉的软件(甚至与3D 软件无关的,泛指操作上的普遍性,也就是 Common Sense 啦)南轩北辙,根本让人无所适从,我只是用它作为 3DS 档案处理器,用于调整模型位置和导出 3DS 档案。

网址:www.blender.org

2)Anim8tor    另一款很受欢迎的免费 3D 模型制作软件,单看界面觉得会比 blender 较接近地球科技,但是可以肯定在建模方面会较死板,不过在制作动画方面的功能蛮不错的(不然哪敢叫Animator?),同样的我只是用它来调整模型的位置和导出 3DS 档案。这个软件有一个我很喜欢的功能,就是可以自动把模型的位置对准世界起源点(World Origin)。

网址:www.anim8or.com

3)3DSConv.exe    不管是 blender 还是 anim8tor,都无法正确的导出 X档案,甚至连DX SDK 附送的 XViewer 也无法开启它们导出的 X档案。我相信这是 DX SDK March 2008 又再改了什么设定而导致它们的 exporter 输出的 X档案格式无效了。因此,为了能够把 3DS 档案转换成 X档案,你必须使用这个软件,它能把 3DS 格式的模型档案转换成 X格式。

网址:由于这是一个很旧的软件(2005年左右),新的DX SDK 也没有再提供这个软件,所以你得自己去 www.google.com 搜寻。记得要找2005年的版本,更早期的版本可能无法输出正确的 X档案格式。

[ 本帖最后由 geekman 于 2-8-2008 11:21 AM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 5-8-2008 11:32 AM | 显示全部楼层
有兴趣更进一步学习MDX的人, 可以到这个网站去看看:

http://www.mdxinfo.com/

我有可能要转去玩XNA了,始终要制作更高影像素质还是得靠Shader,既然如此,就干脆用XNA吧。
回复

使用道具 举报


ADVERTISEMENT

发表于 6-8-2008 09:45 AM | 显示全部楼层

回复 8# geekman 的帖子

正確的選則
現在有support shading的gpu到處都是
是時候用它的了
雖然我本身並不是很喜歡xna
(因為是xbox360的control啊)
回复

使用道具 举报

发表于 6-8-2008 10:01 AM | 显示全部楼层
做 3D的话, 我会选择用 OPENGL 。
回复

使用道具 举报

 楼主| 发表于 6-8-2008 10:43 AM | 显示全部楼层

回复 9# Squall_Chua 的帖子

嗯,我还是决定坚持使用Keyboard+Mouse,毕竟在电脑游戏里面,K+M才是王道啊啊啊!

@tensai x2j:

个人喜好吧。我已经习惯在Windows上编程,也已经习惯使用DirectX了,也没有需要支援Windows平台以外的系统,所以使用能够和Windows紧密契合的DirectX是最自然的选择。反正两者的功能和表现也相差无几,选择哪一个都不是问题,只是我选择了X君。。。
回复

使用道具 举报

发表于 6-8-2008 10:52 AM | 显示全部楼层
给楼主按个好
回复

使用道具 举报

 楼主| 发表于 6-8-2008 10:54 AM | 显示全部楼层

回复 12# cristiano~7 的帖子

谢谢您的支持

如果有谁要这个program的Source code + exe + model + graphics,可以PM 我你的e-mail,不过压缩了的档案大小是220KB,so你得先确定你的信箱能够接受至少220KB的attachment哦。

新的画面,关闭了太阳光,调低了环境光度,就变成这样的诡异画面。。。很想用它来制作一个灵异恐怖游戏呢。。。


[ 本帖最后由 geekman 于 6-8-2008 11:09 AM 编辑 ]
回复

使用道具 举报

发表于 6-8-2008 12:17 PM | 显示全部楼层
原帖由 tensaix2j 于 6-8-2008 10:01 AM 发表
做 3D的话, 我会选择用 OPENGL 。


是我的話
我會選則用ogre



原帖由 geekman 于 6-8-2008 10:43 AM 发表
嗯,我还是决定坚持使用Keyboard+Mouse,毕竟在电脑游戏里面,K+M才是王道啊啊啊!

@tensai x2j:

个人喜好吧。我已经习惯在Windows上编程,也已经习惯使用DirectX了,也没有需要支援Windows平台以外的系 ...


說得沒錯
所以我都沒怎麼去碰過xna
當我發現它的control居然不是keyboard和mouse之後

directx好難學啊
不過從你在上面放的那個mdx的url
我發現到有slimdx這東東
可以考慮玩這個
回复

使用道具 举报

发表于 6-8-2008 12:20 PM | 显示全部楼层
squall 做了 什么 游戏, 怎么 没有放上来。。。
回复

使用道具 举报

 楼主| 发表于 6-8-2008 01:05 PM | 显示全部楼层

回复 14# Squall_Chua 的帖子

Ogre 是个渲染引擎,底子里还是使用 DX 或者 OGL 的,目前我是打算使用能够给我最大自由度的 API,作为学习用途,等掌握了足够的知识再来决定要采用哪一个 Middle ware。

XNA 也是有支援 K+M 的,只是你得自己控制它的一切设定和读取/处理,基本和 MDX 差不多。SlimDX 是一群 MDX 支持者在微软放弃了 MDX 之后自行开发的替代品,以 MDX 为基础,修改了一些 bug,wrap 了一些麻烦的界面等等,的确是一个不错的 MDX 替代品。

其实 MDX 已经很容易上手了,C++ + DX 才真的要人命!我之前就是用 C++ 做这个 Project 的,但是要记忆和弄明白那些 COM 界面就有够头痛的,MDX 就会帮你提议可能使用的 Method 和 variables,十分方便,这就是为什么我一上手 MDX 就爱不释手。

顺带一提,由于我一开始作这个 C# project 是以我已经做过的 C++ 版本移植过去的,所以一开始两个版本几乎大同小异,但是执行起来却发现 C++ 版本竟然比 C# 版本快了超过4倍!这当场让我想放弃 C#,可是一看到 C++ 里面那些 COM 界面,我又决定不放弃 C# + MDX 了。。。
回复

使用道具 举报


ADVERTISEMENT

发表于 6-8-2008 02:06 PM | 显示全部楼层

回复 16# geekman 的帖子

ogre的api基本上已經很stable了
而且也能夠做出AAA class的遊戲
也滿好用下的
有不少的公司都使用它來做real-time rendering
要說performance的話
其實就是看underlying的rendering system的performance而已
所以我的打算是用一堆的free tools來做出個engine來用
醬子會比較好
選擇性多

到時候我就是要醬開始做我的project了
祝我好運吧
回复

使用道具 举报

 楼主| 发表于 7-8-2008 12:22 PM | 显示全部楼层

回复 17# Squall_Chua 的帖子

说到游戏引擎,我现在也正在计划和学习制造自己的引擎。目前的参考材料是这本我已经买了5年的书:
http://www.amazon.com/Tricks-Pro ... ation/dp/0672318350

虽然已经是5年书龄,但至少还是dx9的,而且里面的引擎事实上是 software based 的,学会之后再自己根据喜好选择跟 O君(OGL)发展关系还是跟 X君(DX)共结连理吧。  

作者 André LaMothe 所出的关于游戏开发的书我买了几本,从DOS 时代的 Teach Yourself Game Programming in 21 Days 到 Windows 的 Tricks of the Windows Game Programming Gurus 到这本 3D 的,内容都蛮丰富的。我本身对于Graphics Programming 的兴趣远高于 Game Programing,所以都只是学习里面的 Graphics 技巧,到现在还没真正的写出一个游戏来。。。

祝你好运啊!希望你能早日和我们分享你的作品。
回复

使用道具 举报

发表于 7-8-2008 01:53 PM | 显示全部楼层

回复 18# geekman 的帖子

那本書我有看到過
不過沒仔細翻過它的內容
我最近的興趣不只在graphics上面
還有玩physics的東西
現在其實還滿流行physics的說

對了
方便給我你的聯絡方式嗎
有機會可以討論下這些東西
回复

使用道具 举报

 楼主| 发表于 7-8-2008 02:04 PM | 显示全部楼层

回复 19# Squall_Chua 的帖子

呃,发短消息给你的时候好像出了问题,不知道有没有送出去,还是直接放在这里了:

MSN/E-Mail: (公开期已过)

[ 本帖最后由 geekman 于 8-8-2008 11:01 AM 编辑 ]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 23-12-2025 03:56 PM , Processed in 0.127094 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表