LayaAir2.0 自定義Mesh-畫扇形


  2019.7.24 09:49更新

  之前計算繪制頂點數的時候,代碼如下

// 封邊頂點
let edgeVertex = sectorAngle < 360 ? 6 : 0
let edgeIndex = sectorAngle < 360 ? 4 : 0
// 需要畫的頂點
let drawVertex = slices * (sectorAngle / 360).toFixed(1)

  使用toFixed(1),想將數量位數控制一下,我在后文還提到說不能出現小數。其實應該是要在這里將結果轉為Number類型,保留整數就行。如果這里的頂點數不夠,會導致繪制出來的度數不夠。

// 需要畫的頂點
let drawVertex = Number(slices * (sectorAngle / 360).toFixed(0))

  --------------------------------------------------  

  2019.7.17 18:12更新

  之前畫封邊的時候,共用了內徑的上下頂點,后來在加入貼圖的時候,UV坐標導入之后,會使得貼圖在兩個封邊上成鏡像效果,所以改成不共用頂點。

// 內徑上頂點
vertices[vc++] = 0
vertices[vc++] = halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
// 內徑下頂點
vertices[vc++] = 0
vertices[vc++] = -halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 1
// 外徑上頂點 起點邊
vertices[vc++] = radius
vertices[vc++] = halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 0
// 外徑下頂點 起點邊
vertices[vc++] = radius
vertices[vc++] = -halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1 // 這個會影響光照
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
// 畫兩個三角形(內上、內下、外上, 外下、外上、內下) 起點封邊
indices[ic++] = verticeCount + 0
indices[ic++] = verticeCount + 1
indices[ic++] = verticeCount + 2
indices[ic++] = verticeCount + 3
indices[ic++] = verticeCount + 2
indices[ic++] = verticeCount + 1

// 內徑上頂點
vertices[vc++] = 0
vertices[vc++] = halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 0
// 內徑下頂點
vertices[vc++] = 0
vertices[vc++] = -halfHeight
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 0
vertices[vc++] = 1
// 外徑上頂點 結束邊
vertices[vc++] = posX
vertices[vc++] = halfHeight
vertices[vc++] = posZ
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 0
// 外徑下頂點 結束邊
vertices[vc++] = posX
vertices[vc++] = -halfHeight
vertices[vc++] = posZ
vertices[vc++] = 0
vertices[vc++] = 1 // 這個會影響光照
vertices[vc++] = 0
vertices[vc++] = 1
vertices[vc++] = 1
// 畫兩個三角形(內上、內下、外上, 外下、外上、內下) 結束封邊
indices[ic++] = verticeCount + 4
indices[ic++] = verticeCount + 6
indices[ic++] = verticeCount + 5
indices[ic++] = verticeCount + 7
indices[ic++] = verticeCount + 5
indices[ic++] = verticeCount + 6
verticeCount += edgeVertex

  上述代碼標紅的地方,就是新增的加入UV坐標,這樣封邊就能正常的顯示貼圖了。另外,Laya中UV坐標系好像是以右上角為原點的,表現在UV的坐標原點,需要是右上角的頂點,比如上述代碼中外徑上頂點的UV坐標就是(0,0).

  --------------------------------------------------

 

  2019.7.17 14:34更新

// 索引數量
let indexCount = 3 * drawVertex + edgeIndex + 6 * drawVertex + 3 * drawVertex

  上述關於計算索引總數,需要 edgeIndex * 3,具體為什么要 * 3這個還需要再了解,但是不*3,會導致最后畫底部圓面/扇面,缺少幾個三角形。

  --------------------------------------------------

 

  2019.7.16 21:30更新

  再理解了一下這篇文章中提到的,三個點在一條直線上,畫出來的三角形看不到,需要跳到下一行的第一個點,關鍵代碼:

triangles[0] = 0;
triangles[1] = 1;
triangles[2] = xSize + 1;

  之前一直沒理解triangles[2] = xSize + 1,為啥是這么寫。再想一下,這里的頂點數據是在一個一維數組中,然后一行xSize個頂點,第一行的第一個數據下標是0,那么下一行第一個數據的下標就是xSize+1了。。。

  --------------------------------------------------

 

  最近想用Laya模仿微信小游戲《歡樂球球》,做為學習3D引擎的一個項目。做這個項目之前,先用2D做了另外一款簡單的小游戲,簡單熟悉了一下Laya的IDE,及引擎的一些基本知識。之前的3D知識基本為零,只照着網上的教程試着用過幾天unity3d,但是都是皮毛的東西。

  《歡樂球球》這款游戲,核心玩法就是旋轉圓柱,讓小球通過圓柱上的扇狀環,且不掉落在特定的標記為紅色的環塊上,通過一層環得分,最終根據得分進行排名。

  最開始接觸這款游戲的時候,就大概知道核心點在於扇狀環的形成。之前沒有接觸3D引擎的時候,以為引擎有現成的api來生成這樣的3D物體,覺得做這款小游戲應該不復雜,后來發現沒這么簡單。Laya引擎里面提供的api能畫Box,膠囊體,圓錐,圓柱,平面,四邊形,球體,沒有現成的畫扇狀體的api,而且在論壇搜索,谷歌/百度搜索除了在論壇找到一個說要修改底層,並且提到了一個關鍵詞Mesh編程,就沒有再找到有網友提供相關的教程,或許是我檢索的關鍵詞不對吧。

  但是檢索“自定義扇形”這樣的關鍵詞,就找到了關於Unity3D自定義扇形相關的教程,而且還是針對《歡樂球球》這款游戲,而且還就是針對生成里面的扇形環3D物體的教程。大致看了一下,也是涉及到上面提到的一個關鍵詞Mesh編程,並且分享了一篇專門講Mesh編程的文章,里面有幾個關鍵詞:頂點,三角形,索引,vertices,triangles,uv。一開始覺得挺難的,unity3d的接口laya能用?相關的術語、api等相通?但是沒辦法,找了很久就是沒有找到Laya相關的,只能硬着頭皮上!

  先是再認真看一下Laya官方創建簡單網格的api,Laya.PrimitiveMesh.createXXXX,注意到這里有個關鍵詞Mesh,感覺有戲,繼續追蹤進去看(這里看的是laya.d3.js,這個是ide中集成的基礎類庫,需要手動導入),隨便拿了一個api,createBox,看看源碼:

var vertexCount=24;
var indexCount=36;
var vertexDeclaration=VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");

上面簡單的摘了一段代碼下來,主要是看到了幾個關鍵詞:vertexCount,indexCount,UV,感覺跟unity3d那篇講Mesh編程里面涉及到的關鍵詞相似,再一次感覺有戲!聯想到在laya的論壇有看到說涉及到底層編程,自己寫mesh代碼之類的,然后看了官方提供的api,覺得應該是可以自己參考着寫的,所以花了點時間來試試。

  首先扇形狀3D物體,跟圓柱體類似,是圓柱體的一部分,所以我直接拿官方生成圓柱體的代碼改一下。首先看一下官方的代碼:

(radius === void 0) && (radius = 0.5);
(height === void 0) && (height = 2);
(slices === void 0) && (slices = 32);
var vertexCount = (slices + 1 + 1) + (slices + 1) * 2 + (slices + 1 + 1);
var indexCount = 3 * slices + 6 * slices + 3 * slices;
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var indices = new Uint16Array(indexCount);
var sliceAngle = (Math.PI * 2.0) / slices;
var halfHeight = height / 2;
var curAngle = 0;
var verticeCount = 0;
var posX = 0;
var posY = 0;
var posZ = 0;
var vc = 0;
var ic = 0;

// 部分一
for (var tv = 0; tv <= slices; tv++) {
    if (tv === 0) {
        vertices[vc++] = 0;
        vertices[vc++] = halfHeight;
        vertices[vc++] = 0;
        vertices[vc++] = 0;
        vertices[vc++] = 1;
        vertices[vc++] = 0;
        vertices[vc++] = 0.5;
        vertices[vc++] = 0.5;
    }
    curAngle = tv * sliceAngle;
    posX = Math.cos(curAngle) * radius;
    posY = halfHeight;
    posZ = Math.sin(curAngle) * radius;
    vertices[vc++] = posX;
    vertices[vc++] = posY;
    vertices[vc++] = posZ;
    vertices[vc++] = 0;
    vertices[vc++] = 1;
    vertices[vc++] = 0;
    vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5;
    vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5;
}
for (var ti = 0; ti < slices; ti++) {
    indices[ic++] = 0;
    indices[ic++] = ti + 1;
    indices[ic++] = ti + 2;
}
verticeCount += slices + 1 + 1;

// 部分二
for (var rv = 0; rv <= slices; rv++) {
    curAngle = rv * sliceAngle;
    posX = Math.cos(curAngle + Math.PI) * radius;
    posY = halfHeight;
    posZ = Math.sin(curAngle + Math.PI) * radius;
    vertices[vc++] = posX;
    vertices[vc + (slices + 1) * 8 - 1] = posX;
    vertices[vc++] = posY;
    vertices[vc + (slices + 1) * 8 - 1] = -posY;
    vertices[vc++] = posZ;
    vertices[vc + (slices + 1) * 8 - 1] = posZ;
    vertices[vc++] = posX;
    vertices[vc + (slices + 1) * 8 - 1] = posX;
    vertices[vc++] = 0;
    vertices[vc + (slices + 1) * 8 - 1] = 0;
    vertices[vc++] = posZ;
    vertices[vc + (slices + 1) * 8 - 1] = posZ;
    vertices[vc++] = 1 - rv * 1 / slices;
    vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices;
    vertices[vc++] = 0;
    vertices[vc + (slices + 1) * 8 - 1] = 1;
}
vc += (slices + 1) * 8;
for (var ri = 0; ri < slices; ri++) {
    indices[ic++] = ri + verticeCount + (slices + 1);
    indices[ic++] = ri + verticeCount + 1;
    indices[ic++] = ri + verticeCount;
    indices[ic++] = ri + verticeCount + (slices + 1);
    indices[ic++] = ri + verticeCount + (slices + 1) + 1;
    indices[ic++] = ri + verticeCount + 1;
}
verticeCount += 2 * (slices + 1);

// 部分三
for (var bv = 0; bv <= slices; bv++) {
    if (bv === 0) {
        vertices[vc++] = 0;
        vertices[vc++] = -halfHeight;
        vertices[vc++] = 0;
        vertices[vc++] = 0;
        vertices[vc++] = -1;
        vertices[vc++] = 0;
        vertices[vc++] = 0.5;
        vertices[vc++] = 0.5;
    }
    curAngle = bv * sliceAngle;
    posX = Math.cos(curAngle + Math.PI) * radius;
    posY = -halfHeight;
    posZ = Math.sin(curAngle + Math.PI) * radius;
    vertices[vc++] = posX;
    vertices[vc++] = posY;
    vertices[vc++] = posZ;
    vertices[vc++] = 0;
    vertices[vc++] = -1;
    vertices[vc++] = 0;
    vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5;
    vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5;
}
for (var bi = 0; bi < slices; bi++) {
    indices[ic++] = 0 + verticeCount;
    indices[ic++] = bi + 2 + verticeCount;
    indices[ic++] = bi + 1 + verticeCount;
}
verticeCount += slices + 1 + 1;
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);

  這段代碼有點長,我剛看的時候也是一臉懵逼,因為這段代碼沒有注釋,對於沒有3D知識的我來說內容全靠猜。我最初是一部分一部分注釋,看看注釋之后的效果是什么,才慢慢理解了這段代碼。我將代碼主要分為三個部分,兩個for循環為一部分。根據變量的命名,我最終理解的是,每部分兩個for循環,第一個for循環是生成頂點數據,第二個for循環是生成頂點序號。三個部分,第一個部分畫出圓柱的上部圓面,第二個部分畫出圓柱的柱包圍,第三個部分畫出圓柱的下部圓面,所以我要扣出扇狀物體,就是要從這三個部分中去扣。

  首先,我試着將每個for循環的限制條件值slices改到原來的0.7,試着看看效果:

  嗯。。。有點樣子了,不過旋轉看下發現有缺陷,缺口部分沒有封起來,空空的。然后開始了折騰的過程了。

  回看上面提到的Mesh編程教程里面的內容,3D世界中的物體都是通過無數個三角形組成的,所以這兩個缺口應該是需要畫三角形來填好。然后再想一下,缺口其實就是兩個矩形,不就是畫4個三角形就填好了么,挺簡單的嘛。。。但是怎么畫呢?之前可從來沒玩過這個。

  依葫蘆畫瓢,我先畫一個三角形看看:

// 內徑上頂點
vertices[vc++] = 0;
vertices[vc++] = halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = 1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
// 內徑下頂點
vertices[vc++] = 0;
vertices[vc++] = -halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = 1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
// 外徑上頂點 起點邊
vertices[vc++] = radius;
vertices[vc++] = halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = 1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
// 畫三角形
indices[ic++] = verticeCount + 0;
indices[ic++] = verticeCount + 1;
indices[ic++] = verticeCount + 2;

  找到三個點是挺簡單的。但是一開始我不知道在Laya中應該怎么描述出來,后來反反復復的看官方的例子,大概猜了一下,一個頂點由8位數據描述,前三個是坐標,最后兩個影響貼圖,中間三個不確定,依葫蘆畫瓢先找三個點再說。。。然后是頂點索引,前面的教程有提到頂點索引的順時針、逆時針順序,會影響最終顯示出來的三角形,一直不理解是什么意思,一直改來改去的看效果,最終理解的是:0,1,2,表示先第一個頂點,再第二個,再第三個為順時針方向,如果0,2,1,則表示先第一個,再第三個,再第二個為逆時針方向,會影響顯示面(前面教程中提到0,1,2為直線,會導致看不見,第三個點需要到下一行的第一個。這句話還是沒理解透)。最終摸索出上述代碼,畫出來一個三角形。然后再折騰好久,兩個封邊都畫出來了,上最終代碼:

radius = radius === undefined ? 0.5 : radius
height = height === undefined ? 2 : height
slices = slices === undefined ? 32 : slices
sectorAngle = sectorAngle === undefined ? 360 : sectorAngle

// 封邊頂點
let edgeVertex = sectorAngle < 360 ? 6 : 0
let edgeIndex = sectorAngle < 360 ? 4 : 0
// 需要畫的頂點
let drawVertex = slices * (sectorAngle / 360).toFixed(1)

// 頂點數量(上圓面,前后封邊,中間厚度,下圓面)
let vertexCount = (drawVertex + 1 + 1) + edgeVertex + (drawVertex + 1) * 2 + (drawVertex + 1 + 1)
// 索引數量
let indexCount = 3 * drawVertex + edgeIndex * 3 + 6 * drawVertex + 3 * drawVertex
// 頂點聲明
let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV")
let vertexFloatStride = vertexDeclaration.vertexStride / 4
// 申請數據
let vertices = new Float32Array(vertexCount * vertexFloatStride)
let indices = new Uint16Array(indexCount)
// 切片角度
let sliceAngle = (Math.PI * 2.0) / slices
// 半高(模型處於坐標中心點)
let halfHeight = height * 0.5
// 
let curAngle = 0
// 當前頂點數量
let verticeCount = 0
// 坐標位置
let posX = 0
let posY = 0
let posZ = 0
// 數組索引
let vc = 0
let ic = 0

// 調整切片總數
//slices *= (sectorAngle / 360).toFixed(1)
// 這個值如果是個小數,會出現問題
slices = drawVertex

// 每8個數據,描述一個點信息:前三個為坐標,中間三個好像是影響光照效果,后兩個不確定
// 上圓面頂點數據
for (let tv = 0; tv <= slices; tv++) {
    if (tv === 0) {
        vertices[vc++] = 0
        vertices[vc++] = halfHeight
        vertices[vc++] = 0
        vertices[vc++] = 0
        vertices[vc++] = 1
        vertices[vc++] = 0
        vertices[vc++] = 0.5
        vertices[vc++] = 0.5
    }
    curAngle = tv * sliceAngle
    posX = Math.cos(curAngle) * radius
    posY = halfHeight
    posZ = Math.sin(curAngle) * radius
    vertices[vc++] = posX
    vertices[vc++] = posY
    vertices[vc++] = posZ
    vertices[vc++] = 0
    vertices[vc++] = 1
    vertices[vc++] = 0
    vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5
    vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5
}
// 上部圓面三角索引數據
for (var ti = 0; ti < slices; ti++) {
    indices[ic++] = 0
    indices[ic++] = ti + 1
    indices[ic++] = ti + 2
}
verticeCount += slices + 1 + 1

// 畫封邊 起點封邊和結束封邊,總共6個點,要畫4個三角形
if (edgeVertex > 0) {
    // 內徑上頂點
    vertices[vc++] = 0
    vertices[vc++] = halfHeight
    vertices[vc++] = 0
    vertices[vc++] = 0
    vertices[vc++] = 1
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 內徑下頂點
    vertices[vc++] = 0
    vertices[vc++] = -halfHeight
    vertices[vc++] = 0
    vertices[vc++] = 0
    vertices[vc++] = 1
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 外徑上頂點 起點邊
    vertices[vc++] = radius
    vertices[vc++] = halfHeight
    vertices[vc++] = 0
    vertices[vc++] = 0
    vertices[vc++] = 1
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 外徑下頂點 起點邊
    vertices[vc++] = radius
    vertices[vc++] = -halfHeight
    vertices[vc++] = 0
    vertices[vc++] = 0
    vertices[vc++] = 1 // 這個會影響光照
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 外徑上頂點 結束邊
    vertices[vc++] = posX
    vertices[vc++] = halfHeight
    vertices[vc++] = posZ
    vertices[vc++] = 0
    vertices[vc++] = 1
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 外徑下頂點 結束邊
    vertices[vc++] = posX
    vertices[vc++] = -halfHeight
    vertices[vc++] = posZ
    vertices[vc++] = 0
    vertices[vc++] = 1 // 這個會影響光照
    vertices[vc++] = 0
    vertices[vc++] = 0.5
    vertices[vc++] = 0.5
    // 畫兩個三角形(內上、內下、外上, 外下、外上、內下) 起點封邊
    indices[ic++] = verticeCount + 0
    indices[ic++] = verticeCount + 1
    indices[ic++] = verticeCount + 2
    indices[ic++] = verticeCount + 3
    indices[ic++] = verticeCount + 2
    indices[ic++] = verticeCount + 1
    // 畫兩個三角形(內上、內下、外上, 外下、外上、內下) 結束封邊
    indices[ic++] = verticeCount + 0
    indices[ic++] = verticeCount + 4
    indices[ic++] = verticeCount + 1
    indices[ic++] = verticeCount + 5
    indices[ic++] = verticeCount + 1
    indices[ic++] = verticeCount + 4
    verticeCount += edgeVertex
}

// 畫出厚度外圈
for (let rv = 0; rv <= slices; rv++) {
    curAngle = rv * sliceAngle
    posX = Math.cos(curAngle) * radius
    posY = halfHeight
    posZ = Math.sin(curAngle) * radius

    vertices[vc++] = posX
    vertices[vc + (slices + 1) * 8 - 1] = posX

    vertices[vc++] = posY
    vertices[vc + (slices + 1) * 8 - 1] = -posY

    vertices[vc++] = posZ
    vertices[vc + (slices + 1) * 8 - 1] = posZ

    vertices[vc++] = posX
    vertices[vc + (slices + 1) * 8 - 1] = posX

    vertices[vc++] = 0
    vertices[vc + (slices + 1) * 8 - 1] = 0

    vertices[vc++] = posZ
    vertices[vc + (slices + 1) * 8 - 1] = posZ

    vertices[vc++] = 1 - rv * 1 / slices
    vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices

    vertices[vc++] = 0
    vertices[vc + (slices + 1) * 8 - 1] = 1
}
vc += (slices + 1) * 8
// z軸三角
for (let ri = 0; ri < slices; ri++) {
    indices[ic++] = ri + verticeCount + (slices + 1)
    indices[ic++] = ri + verticeCount + 1
    indices[ic++] = ri + verticeCount
    indices[ic++] = ri + verticeCount + (slices + 1)
    indices[ic++] = ri + verticeCount + (slices + 1) + 1
    indices[ic++] = ri + verticeCount + 1
}
verticeCount += 2 * (slices + 1)

// 畫出下圓面
for (let bv = 0; bv <= slices; bv++) {
    if (bv === 0) {
        vertices[vc++] = 0
        vertices[vc++] = -halfHeight
        vertices[vc++] = 0
        vertices[vc++] = 0
        vertices[vc++] = -1
        vertices[vc++] = 0
        vertices[vc++] = 0.5
        vertices[vc++] = 0.5
    }
    curAngle = bv * sliceAngle
    posX = Math.cos(curAngle) * radius
    posY = -halfHeight
    posZ = Math.sin(curAngle) * radius
    vertices[vc++] = posX
    vertices[vc++] = posY
    vertices[vc++] = posZ
    vertices[vc++] = 0
    vertices[vc++] = -1
    vertices[vc++] = 0
    vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5
    vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5
}
for (let bi = 0; bi < slices; bi++) {
    indices[ic++] = 0 + verticeCount
    indices[ic++] = bi + 2 + verticeCount
    indices[ic++] = bi + 1 + verticeCount
}
verticeCount += slices + 1 + 1

return Laya.PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices)

  上述代碼是在官方生成圓柱體的基礎上改的,加了一部分我理解的注釋,可能有誤。核心的地方在第一部分for循環后,加入的封邊操作,最終畫出來的基本上達到了效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM