UWP简单示例:快速开始你的MineCraft
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UWP简单示例:快速开始你的MineCraft相关的知识,希望对你有一定的参考价值。
准备
IDE:Visual Studio 2015
了解并学习:SharpDx官方示例
第一节 世界
在他诞生之初,天地还是一片混沌。
世界坐标系
世界坐标系是一个特殊的坐标系,它建立了描述其他坐标系所需要的参考框架
从另一方面说,不能用更大的、外部的坐标系来描述世界坐标系
关于世界坐标系的典型问题都是关于初始位置和环境的:
- 每个物体的位置和方向
- 摄像机的位置和方向
- 世界中没一点的地形是什么(如山丘、建筑、湖泊等)
- 个物体从哪里来,到哪里去(NPC的运动策略)
左、右手坐标系
所有的2D坐标系是等价的,但3D坐标系有“手性”之分
左、右手坐标系可以互相转换,最简单的方法是只翻转一个轴的符号
传统的计算机图形学使用左手坐标系,而线性代数则倾向于使用右手坐标系
SharpDx采用左手坐标系,即X轴由右向左,Y轴由下至上,Z轴由里至外
SharpDx的世界有多大
首先,这个世界是有限且离散的
描述三维坐标需要使用SharpDx或System.Numerics命名空间下的Vector3类型
Vector3表示一个三维向量,它的x,y,z分量都是float类型(单精度浮点数),我们知道float范围是-3.40E+38 ~ +3.40E+38
而原子的直径是0.1nm级别,若以它作为基本单位,那么这个世界大约是一个边长6.80E+25公里的方盒(约71877亿光年)
这个世界足够大了吗
目前认为银河系直径是10~12万光年,宇宙可视直径是920亿光年
单精度浮点数可精确到小数点后6位,即当前世界最小分辨率是10-6倍原子大小
那么离散的float类型足以描述现实世界了吗?向您介绍计算机图形学第一准则,留给您思考:
- 计算机图形学第一准则:近似原则如果它看上去是对的它就是对的
Imports SharpDX Public Class World ‘‘‘ <summary> ‘‘‘ 当前世界所有的模型 ‘‘‘ </summary> Public RigidBodys As New List(Of IRigidBody) ‘‘‘ <summary> ‘‘‘ 当前世界所有物体的顶点变换矩阵 ‘‘‘ </summary> Public ModelMatrix() As Matrix Public Sub New() ‘这里初始化世界 End Sub ‘‘‘ <summary> ‘‘‘ 更新当前世界所有物体的顶点变换矩阵 ‘‘‘ </summary> Public Sub Update() End Sub End Class
第二节 物体
他在混沌之中孕育着。
有了世界,那么物体该怎么描述呢?
位置Location
一个三维向量,它表示当前物体在世界坐标系中的绝对位置
比例Scale
一个三维向量,表示当前物体x,y,z轴缩放比例
旋转Rotation
通常物体角位移有欧拉角和四元数两种表示方式
欧拉角:
- 欧拉角有三个分量,偏航角Yaw、俯仰角Pitch、横滚角Roll
- 给定方位的表达方式不唯一
- 两个角度间求插值非常困难
- 万向锁是一个底层问题,至今没有简单的解决方案
四元数:
- 四元数(Quaternion)有四个分量,它是一个超复数
- 四元数能够平滑插值,但它比欧拉角多占用33.3%的存储空间
- 多个四元数表示一系列旋转变换时,将它们相乘(而非直接相加)
- 四元数“减法”,一个变换Q1到另一个变换Q2的差△Q等于Q1的逆乘以Q2(而非直接相减)
- 通过标准化四元数确保它为单位大小,否则它将不合法
Imports SharpDX Public Interface IRigidBody ‘‘‘ <summary> ‘‘‘ 子物体 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Children As List(Of IRigidBody) ‘‘‘ <summary> ‘‘‘ 父物体 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Parent As IRigidBody ‘‘‘ <summary> ‘‘‘ 位置 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Location As Vector3 ‘‘‘ <summary> ‘‘‘ 缩放 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Scale As Vector3 ‘‘‘ <summary> ‘‘‘ 旋转 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Qua As Quaternion ‘‘‘ <summary> ‘‘‘ 可见性 ‘‘‘ </summary> ‘‘‘ <returns></returns> Property Visible As Boolean Sub Update() End Interface
Imports SharpDX Public Class World Public MyHuman As Human ‘‘‘ <summary> ‘‘‘ 当前世界所有的模型 ‘‘‘ </summary> Public RigidBodys As New List(Of IRigidBody) ‘‘‘ <summary> ‘‘‘ 当前世界所有物体的模型矩阵 ‘‘‘ </summary> Public ModelMatrix() As Matrix Private MList As New List(Of Matrix) Public Sub New() ‘RigidBodys.Add(New Human) ‘MyHuman = RigidBodys(0) ‘MyHuman.Visible = False For i = 0 To 0 RigidBodys.Add(New Ground With {.Location = New Vector3((i) * 50, 0, 0)}) Next Update() End Sub ‘‘‘ <summary> ‘‘‘ 更新当前世界所有物体的模型矩阵 ‘‘‘ </summary> Public Sub Update() MList.Clear() CalcMatrix(RigidBodys, New Vector3(1, 1, 1), New Quaternion(0, 0, 0, 1), Vector3.Zero) ModelMatrix = MList.ToArray End Sub ‘‘‘ <summary> ‘‘‘ 计算指定物体List(包括它的子物体)的顶点变换矩阵 ‘‘‘ </summary> Public Sub CalcMatrix(bodys As List(Of IRigidBody), scale As Vector3, qua As Quaternion, loc As Vector3) For Each SubBody In bodys If SubBody.Visible Then Dim s = MultiScale(SubBody.Scale, scale) ‘当前对象的比例 Dim q = qua * SubBody.Qua ‘当前对象的旋转 Dim p As Vector3 If SubBody.Parent Is Nothing Then p = loc + SubBody.Location ‘父对象为空,则位置为绝对位置 Else p = loc + (Matrix.Translation(SubBody.Location) * Matrix.RotationQuaternion(q)).TranslationVector ‘旋转变换后的位置 End If Dim tempWorld As Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(p) MList.Add(tempWorld) CalcMatrix(SubBody.Children, s, q, p) End If Next End Sub ‘‘‘ <summary> ‘‘‘ 相乘指定的两个缩放 ‘‘‘ </summary> Private Function MultiScale(v1, v2) As Vector3 Return New Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z) End Function End Class
第三节 矩阵变换
终于,巍峨巨人从沉睡中醒来。
模型与世界空间
物体最开始由物体空间来描述。其中常见的信息包括顶点位置和表面法向量。
可将坐标从物体空间转换到世界空间中,此过程称作模型变换
通常,光照计算使用世界空间,其实光照计算只需确保几何体和光线在同一空间
摄像机空间
通过视变换,顶点从世界空间变换到摄像机空间,此空间也称作眼睛空间
裁剪与屏幕空间
裁剪空间又名标准视体空间,它是为透视投影做准备
一旦用视锥完成了几何体裁剪,即可向屏幕空间投影
ModelMatrix=World*View*Projection
World=ScaleMatrix*RotationMatrix*TranslateMatrix:
- 缩放矩阵 ScaleMatrix=Matrix.Scaling(Object.Scale)
- 旋转矩阵 RotationMatrix=Matrix.RotationQuaternion(Object.Quaternion)
- 平移矩阵 TranslateMatrix=Matrix.Translation(Object.Location)
- 这三者相乘的顺序不能变
View=Matrix.LookAtLH(eye,target,up):
- 眼睛位置 eye=New Vector3(0,0,100),表示当前摄像机位于Z轴100值处
- 视点位置 target=New Vector3(0,0,0),表示当前摄像机看向3D空间的原点
- 向上向量 up=Vector.UnitY,当前摄像机的向上方向
- LH表示左手坐标系,Matrix.LookAtRH是用于右手坐标系
Projection=Matrix.PerspectiveFovLH(fov, aspect, znear, zfar):
- 视椎体水平角 fov=Math.PI/ 3.0F,即水平可视角范围,通常为60度
- 视锥体宽高比 aspect=ScreenWidth/ScreenHeight,通常和屏幕宽高比一致
- 近裁面深度值 znear=1,即最近可视范围,用户可自由设置
- 远裁面深度值 zfar=10000,即最远可视范围,用户可自由设置
- 实际上这是裁剪变换矩阵,投影到屏幕是由API完成的
Imports SharpDX ‘‘‘ <summary> ‘‘‘ 摄像机空间基类 ‘‘‘ </summary> Public MustInherit Class CameraBase ‘‘‘ <summary> ‘‘‘ 摄像机位置 ‘‘‘ </summary> ‘‘‘ <returns></returns> Public Property EyeOfView As Vector3 Get Return mEye End Get Set(value As Vector3) mEye = value ChangeView() End Set End Property ‘‘‘ <summary> ‘‘‘ 目标视点位置 ‘‘‘ </summary> ‘‘‘ <returns></returns> Public Property TargetOfView As Vector3 Get Return mTarget End Get Set(value As Vector3) mTarget = value ChangeView() End Set End Property Protected View As Matrix = Matrix.LookAtLH(New Vector3(0, 50, 200), New Vector3(), Vector3.UnitY) Private mEye As Vector3 Private mTarget As Vector3 Private Sub ChangeView() View = Matrix.LookAtLH(mEye, mTarget, Vector3.UnitY) End Sub End Class ‘‘‘ <summary> ‘‘‘表示一个摄像机空间 ‘‘‘ </summary> Public Class CameraSpace Inherits CameraBase Public Property Width As Integer = 600 Public Property Height As Integer = 400 Public Property World As WorldSpace Public Function GetTransforms() As List(Of CustomMath.Transform) Dim tempTransforms As New List(Of CustomMath.Transform) If World IsNot Nothing Then Dim aspect As Single = CSng(Width) / CSng(Height) Dim projection As Matrix = Matrix.PerspectiveFovLH(CSng(Math.PI) / 2.0F, aspect, 1, 10000) For Each SubMatrix In World.ModelMatrix tempTransforms.Add(New CustomMath.Transform() With {.WVP = SubMatrix * View * projection}) Next End If Return tempTransforms End Function End Class
第四节 三角网格
天地开分,孤独的开辟者化作了万物。
Public Structure Vertex Public Position As Vector3 Public Color As Vector4 Public Sub New(position As Vector3, color As Vector4) Me.Position = position Me.Color = color End Sub End Structure
‘‘‘ <summary> ‘‘‘ 返回一个指定长宽高的六面体的顶点数组 ‘‘‘ </summary> Public Shared Function CreateCube(w As Single, h As Single, d As Single) As Vertex() w = w / 2 h = h / 2 d = d / 2 Dim vertices As Vertex() = New Vertex() { New Vertex(New Vector3(-w, h, d), New Vector4(0, 1, 0, 1)), New Vertex(New Vector3(w, h, d), New Vector4(0, 1, 0, 1)), New Vertex(New Vector3(w, h, -d), New Vector4(0, 1, 0, 1)), New Vertex(New Vector3(-w, h, -d), New Vector4(0, 1, 0, 1)), New Vertex(New Vector3(-w, -h, d), New Vector4(1, 0, 1, 1)), New Vertex(New Vector3(w, -h, d), New Vector4(1, 0, 1, 1)), New Vertex(New Vector3(w, -h, -d), New Vector4(1, 0, 1, 1)), New Vertex(New Vector3(-w, -h, -d), New Vector4(1, 0, 1, 1)), New Vertex(New Vector3(-w, -h, d), New Vector4(1, 0, 0, 1)), New Vertex(New Vector3(-w, h, d), New Vector4(1, 0, 0, 1)), New Vertex(New Vector3(-w, h, -d), New Vector4(1, 0, 0, 1)), New Vertex(New Vector3(-w, -h, -d), New Vector4(1, 0, 0, 1)), New Vertex(New Vector3(w, -h, d), New Vector4(1, 1, 0, 1)), New Vertex(New Vector3(w, h, d), New Vector4(1, 1, 0, 1)), New Vertex(New Vector3(w, h, -d), New Vector4(1, 1, 0, 1)), New Vertex(New Vector3(w, -h, -d), New Vector4(1, 1, 0, 1)), New Vertex(New Vector3(-w, h, d), New Vector4(0, 1, 1, 1)), New Vertex(New Vector3(w, h, d), New Vector4(0, 1, 1, 1)), New Vertex(New Vector3(w, -h, d), New Vector4(0, 1, 1, 1)), New Vertex(New Vector3(-w, -h, d), New Vector4(0, 1, 1, 1)), New Vertex(New Vector3(-w, h, -d), New Vector4(0, 0, 1, 1)), New Vertex(New Vector3(w, h, -d), New Vector4(0, 0, 1, 1)), New Vertex(New Vector3(w, -h, -d), New Vector4(0, 0, 1, 1)), New Vertex(New Vector3(-w, -h, -d), New Vector4(0, 0, 1, 1))} Return vertices End Function
第五节 创建人物
世界一隅,Steve开始了他的MineCraft人生。
Imports SharpDX Public Class Human Inherits RigidBodyBase Public RootBone As Bone Public Sub New() CreateBone() CalcBone(RootBone) End Sub Public Sub UpdateBone(qua As Quaternion, index As Integer) Children(index).Qua = qua CalcBone(RootBone) End Sub Private Sub CalcBone(parent As Bone) For Each SubBone In parent.Children Dim tempLoc = (Matrix.Translation(SubBone.RaletiveLoc) * Matrix.RotationQuaternion(SubBone.Qua)).TranslationVector SubBone.AbsoluteLoc = parent.AbsoluteLoc + tempLoc SubBone.Location = parent.AbsoluteLoc + tempLoc / 2 CalcBone(SubBone) Next End Sub Dim BoneIndexArr() As BoneIndex = { New BoneIndex(New Vector3(0, 0, 0), New Vector3(1, 1, 1), 0, New Integer() {1, 12, 16}),‘腰部0 New BoneIndex(New Vector3(0, 5, 0), New Vector3(2.5, 5, 1), 0, New Integer() {2, 4, 8}),‘胸部1 New BoneIndex(New Vector3(0, 1, 0), New Vector3(0.7, 1, 1), 1, New Integer() {3}),‘颈部2 New BoneIndex(New Vector3(0, 1.5, 0), New Vector3(1.3, 1.5, 1), 2, New Integer() {}),‘头部3 New BoneIndex(New Vector3(-2, 0, 0), New Vector3(2, 1, 1), 1, New Integer() {5}),‘左肩4 New BoneIndex(New Vector3(0, -2.5, 0), New Vector3(1, 2.5, 1), 4, New Integer() {6}),‘左上臂5 New BoneIndex(New Vector3(0, -2.5, 0), New Vector3(1, 2.5, 1), 5, New Integer() {7}),‘左小臂6 New BoneIndex(New Vector3(0, -1, 0), New Vector3(1, 1, 1), 6, New Integer() {}),‘左手7 New BoneIndex(New Vector3(2, 0, 0), New Vector3(2, 1, 1), 1, New Integer() {9}),‘右肩8 New BoneIndex(New Vector3(0, -2.5, 0), New Vector3(1, 2.5, 1), 8, New Integer() {10}),‘右上臂9 New BoneIndex(New Vector3(0, -2.5, 0), New Vector3(1, 2.5, 1), 9, New Integer() {11}),‘右小臂10 New BoneIndex(New Vector3(0, -1, 0), New Vector3(1, 1, 1), 10, New Integer() {}),‘右手11 New BoneIndex(New Vector3(-0.8, 0, 0), New Vector3(0.8, 1, 1), 0, New Integer() {13}),‘左骻12 New BoneIndex(New Vector3(0, -4, 0), New Vector3(1, 4, 1), 12, New Integer() {14}),‘左大腿13 New BoneIndex(New Vector3(0, -4, 0), New Vector3(1, 4, 1), 13, New Integer() {15}),‘左小腿14 New BoneIndex(New Vector3(0, -1, 0), New Vector3(1, 1, 1), 14, New Integer() {}),‘左脚15 New BoneIndex(New Vector3(0.8, 0, 0), New Vector3(0.8, 1, 1), 0, New Integer() {17}),‘右骻16 New BoneIndex(New Vector3(0, -4, 0), New Vector3(1, 4, 1), 16, New Integer() {18}),‘右大腿17 New BoneIndex(New Vector3(0, -4, 0), New Vector3(1, 4, 1), 17, New Integer() {19}),‘右小腿18 New BoneIndex(New Vector3(0, -1, 0), New Vector3(1, 1, 1), 18, New Integer() {})‘右脚19 } Private Sub CreateBone() For i = 0 To BoneIndexArr.Count - 1 Children.Add(New Bone(BoneIndexArr(i).Loc, BoneIndexArr(i).Scale)) Next For i = 0 To BoneIndexArr.Count - 1 Dim tempBone = DirectCast(Children(i), Bone) tempBone.Parent = Children(BoneIndexArr(i).ParentIndex) For Each SubIndex In BoneIndexArr(i).ChildIndexArr tempBone.Children.Add(Children(SubIndex)) Next Next RootBone = DirectCast(Children(0), Bone) End Sub End Class
Imports SharpDX Public Class BoneIndex Public Loc As Vector3 Public Scale As Vector3 Public ParentIndex As Integer Public ChildIndexArr() As Integer Public Sub New(l As Vector3, s As Vector3, p As Integer, c As Integer()) Loc = l Scale = s ParentIndex = p ChildIndexArr = c End Sub End Class
Imports SharpDX ‘‘‘ <summary> ‘‘‘ 表示骨骼结点 ‘‘‘ </summary> Public Class Bone Inherits RigidBodyBase Public Shadows Parent As Bone Public Shadows Children As List(Of Bone) Public AbsoluteLoc As Vector3 Public RaletiveLoc As Vector3 Public rQua As Quaternion Public Overrides Property Qua As Quaternion Set(value As Quaternion) If IsNewQua Then IsNewQua = False rQua = value
以上是关于UWP简单示例:快速开始你的MineCraft的主要内容,如果未能解决你的问题,请参考以下文章
minecraft我的世界找不到server.properties这个文件
买过正版的minecraft JAVA版 兑换码已激活 登录到win10应用商店 安装不了