<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Vector Function [TOC] 下面兩部分解釋了什么是**向量(vectors)**和**歸一化向量(normalised vectors)**,并且簡要的介紹了如何在你的游戲中使用它們。 ## 1. What Is A Vector? 當某些時刻,你創造的游戲非常復雜的時候,你不得不使用向量。它被用于物理學、AI、三角形學(trigonometry)和其他各種情況,但是什么是向量?簡單的說,向量是有指向(方向)的量。我們從**一維向量(1 dimensional vector)**開始看,它是一個帶有數字的箭頭,從數字0指向5。這是向量a,它的大小等于5,并且我們畫另一個向量b,它從5開始到8結束,向量b等于3。 ![1D Vector](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/1d_vector_image.png) 你應該注意到了,向量的開始并不重要,重要的是它的長度和方向。所以向量b從5開始、3個單位長并指向x軸(假設只有x軸)正方向和從0開始、長度為3并指向x+方向的向量是一樣的。向量還可以相加,向量a加向量b結果是長為8的向量c。如果是負數呢?向量看得是方向和大小,而不是位置。 ![2D Vector](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/2d_vector_image_1.png "2D Vector") 如上是,二維向量。三維向量如下圖,z軸定義是**深度(depth)** ![3D Vector](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/3d_vector_image.png "3D Version") ## 2. Normalised Vectors 通常,向量可以在很多情況下使用,但是有時你想要約束它們的值(就像處理角度),這就是為什么我們將它們歸一化。這里使用了一個數學技巧,把向量的長度從n轉化為1,這些轉化過的向量被稱為**單位向量**。 ![Unit Vector](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/1d_norm_vector_image.png "Unit") 計算單位向量,我們首先得畫出這個向量x、y軸的分量,并且計算出向量的長度(模)。接下來是計算過程。 ![normal vector](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/2d_norm_vector_image_1.png) 首先根據坐標求出x、y邊的長度: ```javascript vx = (x2 - x1) = (7 - 1) = 6 vy = (y2 - y1) = (4 - 1) = 3 ``` 接著求出向量長: ```javascript len = sqr(vx2 + vy2) = sqr(36 + 9) = sqr(45) = 6.708203932499369 ``` 最后,轉化為單位長度: ```javascript vx = (vx/len) = (6 / 6.708203932499369) = 0.8944271909999159 vy = (vy/len) = (3 / 6.708203932499369) = 0.4472135954999579 a = 1 ``` 現在我們歸一化了向量,那么我們如何在GMS2中使用它呢? **例:**假設你在設計一個設計游戲,角色必須射擊敵軍,你需要知道子彈在每一個step沿著x、y軸走多遠才能擊中目標: ![Game](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/2d_norm_vector_image_2.png "Game") 為了這個你必須把角色和敵軍的坐標歸一化,并且得到x、y分量轉化的小數值,這些數值將乘以子彈在每一個step中移動的速度,并在最后存儲起來,作為下一步的初始坐標。讓我們看看例子(數值已經四舍五入) ```javascript px = 100; py = 425; ex = 356; ey = 83; bullet_speed = 5; vx = (ex - px) = 256 vy = (ey - py) = -342 len = sqrt(vx2 + vy2) = sqrt(65536 + 116964) = 427.2 vx = vx / len = 0.6 vy = vy / len = 0.8 speed_x = vx * bullet_speed = 3 speed_y = vy * bullet_speed = 4 ``` 所以,為了達到目標,我們應該在每一步在子彈的x軸加3,y軸加4。 ## 3. Function GMS2也擁有一些基于向量的函數,下面是介紹使用方法 ### point_direction **語法** `point_direction(x1, y1, x2, y2)` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| **返回類型:** Real **描述** 這個函數返回由指定的組件[x1,y1]和[x2,y2]形成的向量的方向,與房間的固定x/y坐標有關。如圖,如果我們要讓導彈朝著敵人的方向前進,就可以使用下面例子的代碼。 ![point_direction](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/point_direction.png "point_direction") **舉例** ```javascript var ex, ey; ex = instance_nearest(x, y, enemy).x; ey = instance_nearest(x, y, enemy).y; with (instance_create_layer(x, y, "Bullets", obj_Missile)) { direction = point_direction(x, y, ex, ey); } ``` **理解** 多次試驗之后我發現這個函數返回的結果是度數,設向量與x軸正半軸的夾角為α。 例如: 1. 初始坐標[0, 0] ----》 [1, 1] 得到結果315 2. 初始坐標[0, 0] ----》 [1, 0] 得到結果270 3. 初始坐標[0, 0] ----》 [0,-1] 得到結果90 4. 初始坐標[0, 0] ----》 [-1,0] 得到結果180 5. 初始坐標[0, 0] ----》 [1,-1] 得到結果45 ![my](http://www.showdoc.cc/server/api/common/visitfile/sign/667a5c7d5775664d345affeec4276ffb?showdoc=.jpg "my") 如果把這些結果做成圖形我們會清晰的發現,返回的度數是`360-α` ------------ ### point_distance **語法** `point_distance(x1, y1, x2, y2);` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| **返回類型:**Real **描述** 返回向量的長度 ![length](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/point_distance.png "length") **舉例** ```javascript var ex, ey; ex = instance_nearest(x, y, enemy).x; ey = instance_nearest(x, y, enemy).y; if point_distance(x, y, ex, ey) < 200 { instance_create_layer(x, y, "Bullets", obj_Missile) } ``` 上面代碼自動檢測最近的敵軍的位置,如果角色與敵軍的距離小于200,就會自動生成導彈。 ------------ ### point_distance_3d **語法** `point_distance_3d(x1, y1, z1, x2, y2, z2);` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |z1 | 向量的第一個分量的z坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| |z2 | 向量的第二個分量的z坐標| **返回類型:**Real **描述** 這個方法使用方式和point_distance一樣。加上了z軸用于3D空間。 **舉例** ```javascript var inst, ex, ey, ez; inst = instance_nearest(x, y, enemy); if inst { ex = inst.x; ey = inst.y; ez = inst.z; if point_distance_3d(x, y, z, ex, ey, ez) < 200 { instance_create_layer(x, y, "Bullets", obj_Missile) } } ``` 上面代碼自動檢測最近的敵軍的位置,如果角色與敵軍的距離小于200,就會自動生成導彈。 ------------ ### distance_to_object **語法** `distance_to_object( obj );` |參數|描述| |:----|------ | |obj |要檢查的對象 | **返回類型:**Real **描述** 這個函數計算兩個實例包圍盒(邊框)間的距離:你在哪個obj使用這個函數---》輸入的obj間的距離。輸入的obj的內容可以是它的索引或者ID,也可以是關鍵字**other**,并且返回的距離以像素為單位。請注意,如果兩個obj的任意一個都沒有使用精靈(sprite)或者遮罩(mask),那么返回結果是不正確的。 **舉例** ```javascript if distance_to_object(obj_Player) < range { canshoot = true; } ``` 上面的代碼檢查到player對象的距離,如果它小于在變量“range”中存儲的值,那么變量“canshoot”將被設置為true。 ------------ ### distance_to_point **語法** `distance_to_point(x, y);` |參數|描述| |:----|------ | |x |要檢查位置的x坐標 | |y |要檢查位置的y坐標 | **返回類型:**Real **描述** 這個函數計算調用實例的包圍盒到指定x、y坐標的距離,返回值為像素。請注意,如果調用實例沒有使用精靈(sprite)或者遮罩(mask),那么返回結果是不正確的。 **舉例** ```javascript if distance_to_point(obj_Player.x, obj_Player.y) < range { canshoot = true; } ``` 上面的代碼檢查到player對象當前坐標的距離,如果它小于在變量“range”中存儲的值,那么變量“canshoot”將被設置為true。 ------------ ### dot_product **語法** `dot_product(x1, y1, x2, y2)` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| **返回類型:**Real **描述** 點積(dot product)是表示兩個向量間角度的關系的值,通過取兩個向量,將他們相乘然后相加。"點積"這個名字由來是從中心點"·",它經常被用來指代這個運算(替代名稱“標量積”強調結果的標量而不是向量性質) 實際的數學公式可以寫成這樣: ![dot product](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image.png "dot product") 因此,在2D中,向量a[x1,y1]和b[x2,y2]的點積結果是x1x2+y1y2,在GMS2中計算 ```javascript a · b = (x1*x2)+(y1*y2); ``` 點積的奇怪之處在于它的輸入向量與向量形成的角度間的關系,可以表示為: ```javascript a · b = (length of a) * (length of b) * cos(angle) ``` 即,點積等于兩個向量的模乘以向量夾角的余弦,如下圖 ![angle](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image_2.png "angle") 我們可以從向量點積的結果得出如下結論 - 向量a與向量b垂直,點積為0,因為cos90為0 - 向量a與向量b間的夾角小于90度,點積將是正的(大于零),因為cos(ang)是正的。 - 向量a與向量b間的夾角大于90度,點積將為負(小于零),因為cos(ang)將為負。 所以我們如何將其運用到游戲中呢?這種數學關系能夠運用到相當多種情況,但最好的方式是你自己建立一個實際的場景,看看會發生什么。簡單的例子,角色位于敵人正前方90度之內就會被發現。 ![dot product Use](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image_1.png "dot product Use") 基本上,我們要得到敵人的法線(包括方向和視線距離),之后我們需要得到角色和敵人間的向量。并且得到這些向量的點積,若結果為正,角色會被看到,負則不會。實際的代碼如下 **舉例** ```javascript var x1, y1, x2, y2; x1 = lengthdir_x(1, image_angle); y1 = lengthdir_y(1, image_angle); x2 = o_Player.x - x; y2 = o_Player.y - y; if dot_product(x1, y1, x2, y2) > 0 seen=true else seen=false; ``` 上面的代碼在敵人中用實例圖像的角度創建向量,接著得到角色和自己本身的距離。最后,計算出這兩個向量的點積,如果大于可以被看見,否則不行。 ------------ ### dot_product_3d **語法** `dot_product_3d(x1, y1, z1, x2, y2, z2)` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |z1 | 向量的第一個分量的z坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| |z2 | 向量的第二個分量的z坐標| **返回類型:**Real **描述** 點積(dot product)是表示兩個向量間角度的關系的值,通過取兩個向量,將他們相乘然后相加。"點積"這個名字由來是從中心點"·",它經常被用來指代這個運算(替代名稱“標量積”強調結果的標量而不是向量性質) 實際的數學公式可以寫成這樣: ![dot product](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image.png "dot product") 因此,在2D中,向量a[x1,y1]和b[x2,y2]的點積結果是x1x2+y1y2,在GMS2中計算 ```javascript a · b = (x1*x2)+(y1*y2); ``` 點積的奇怪之處在于它的輸入向量與向量形成的角度間的關系,可以表示為: ```javascript a · b = (length of a) * (length of b) * cos(angle) ``` 即,點積等于兩個向量的模乘以向量夾角的余弦,如下圖 ![angle](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image_2.png "angle") 我們可以從向量點積的結果得出如下結論 - 向量a與向量b垂直,點積為0,因為cos90為0 - 向量a與向量b間的夾角小于90度,點積將是正的(大于零),因為cos(ang)是正的。 - 向量a與向量b間的夾角大于90度,點積將為負(小于零),因為cos(ang)將為負。 所以這對我們做游戲的人來說意味著什么呢?這個數學關系式能在許多種情況下運用,但是最好的方法是你親自建立一個模擬的場景,并且看看會發生什么。最簡單的方法是為視野內的敵人生成一個簡單的“高度”檢測,敵人將會看到角色,如果敵人建立在法線和3d平面上。 ![](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_3d_image.png) 基本上,我們根據敵人和地板的角度得到法向量,并且還得到角色到敵人的向量。我們接著可以得到這些向量的點積。根據前面的推論,如果結果為正(夾角小于90°),角色在敵人平面之上;如果為負,則在其之下。實際代碼示例如下: **舉例** ```javascript //在enemy中 var x1, y1, x2, y2; x1 = 0; y1 = 1; z1 = 0; x2 = o_Player.x - x; y2 = o_Player.y - y; z2 = o_Player.z - z; if dot_product_3d(x1, y1, z1, x2, y2, z2) > 0 above=true else above=false; ``` 上面的代碼沿著實例y(上半)軸創建了一個向量1(法向量),接著根據o_Player到自身又創建了向量2。最后計算這兩個向量的點積,并判斷是否大于0。 ------------ ### dot_product_normalised **語法** `dot_product_normalised(x1, y1, x2, y2)` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| **返回類型:**Real **描述** 點積(dot product)是表示兩個向量間角度的關系的值,通過取兩個向量,將他們相乘然后相加。"點積"這個名字由來是從中心點"·",它經常被用來指代這個運算(替代名稱“標量積”強調結果的標量而不是向量性質) 實際的數學公式可以寫成這樣: ![dot product](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image.png "dot product") 因此,在2D中,向量a[x1,y1]和b[x2,y2]的點積結果是x1x2+y1y2,在GMS2中計算 ```javascript a · b = (x1*x2)+(y1*y2); ``` 那么標準化點積呢?標準化點積得到修正,返回值在-1~1間(詳情見Normalised Vectors),在很多情況下是非常有用的,特別是在處理照明和其他3D功能時。 **舉例** ```javascript var x1, y1, x2, y2; x1 = lengthdir_x(1, image_angle); y1 = lengthdir_y(1, image_angle); x2 = o_Player.x - x; y2 = o_Player.y - y; if dot_product_normalised(x1, y1, x2, y2) > 0 seen=true else seen=false; ``` 上面的代碼在敵人中用實例圖像的角度創建向量,接著得到角色和自己本身的距離。最后,計算出這兩個向量的點積,如果大于可以被看見,否則不行。 ------------ ### dot_product_3d_normalised **語法** `dot_product_3d(x1, y1, z1, x2, y2, z2)` |參數|描述| |:----|------ | |x1 | 向量的第一個分量的x坐標| |y1 | 向量的第一個分量的y坐標| |z1 | 向量的第一個分量的z坐標| |x2 | 向量的第二個分量的x坐標| |y2 | 向量的第二個分量的y坐標| |z2 | 向量的第二個分量的z坐標| **返回類型:**Real **描述** 點積(dot product)是表示兩個向量間角度的關系的值,通過取兩個向量,將他們相乘然后相加。"點積"這個名字由來是從中心點"·",它經常被用來指代這個運算(替代名稱“標量積”強調結果的標量而不是向量性質) 實際的數學公式可以寫成這樣: ![dot product](http://mimoe.cc/hj_gms2_f1/source/_build/3_scripting/4_gml_reference/maths/vector%20functions/images/dot_product_image.png "dot product") 因此,在2D中,向量a[x1,y1]和b[x2,y2]的點積結果是x1x2+y1y2,在GMS2中計算 ```javascript a · b = (x1*x2)+(y1*y2); ``` 那么標準化點積呢?標準化點積得到修正,返回值在-1~1間(詳情見Normalised Vectors),在很多情況下是非常有用的,特別是在處理照明和其他3D功能時。 **舉例** ```javascript var x1, y1, x2, y2; x1 = 0; y1 = 1; z1 = 0; x2 = o_Player.x - x; y2 = o_Player.y - y; z2 = o_Player.z - z; if dot_product_3d_normalised(x1, y1, z1, x2, y2, z2) > 0 above=true else above=false; ``` 上面的代碼沿著實例y(上半)軸創建了一個向量1(法向量),接著根據o_Player到自身又創建了向量2。最后計算這兩個向量的點積,并判斷是否大于0。 ------------ ### angle_difference **語法** `angle_difference(ang1, ang2)` |參數|描述| |:----|------ | |ang1 | 第一個角度| |y1 | 第二個角度| **返回類型:**Real **描述** 這個函數將返回兩個角度之間最小的角度差值,在-180度和180度之間(正角是逆時針,負角是順時針)。 **舉例** ```javascript var pd = point_direction(x, y, mouse_x, mouse_y); var dd = angle_difference(image_angle, pd); image_angle -= min(abs(dd), 10) * sign(dd); ``` pd為當前位置到鼠標位置與x(正半)軸間的角度,dd為當前image_angle與pd的差別度數。功能為可以讓圖片緩慢朝著鼠標位置旋轉。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看