日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

《Android 应用案例开发大全(第二版)》——2.6节绘制相关类

發(fā)布時(shí)間:2025/3/20 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Android 应用案例开发大全(第二版)》——2.6节绘制相关类 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)書摘來自異步社區(qū)《Android 應(yīng)用案例開發(fā)大全(第二版)》一書中的第2章,第2.6節(jié)繪制相關(guān)類 ,作者 吳亞峰 , 于復(fù)興 , 杜化美,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“異步社區(qū)”公眾號查看

2.6 繪制相關(guān)類
Android 應(yīng)用案例開發(fā)大全(第二版)
上一節(jié)完成了水族館輔助繪制類開發(fā)過程的介紹,這一節(jié)將對本案例中的繪制相關(guān)類進(jìn)行詳細(xì)介紹。主要包括氣泡繪制相關(guān)類、群魚繪制相關(guān)類、魚群繪制相關(guān)類和魚食繪制相關(guān)類,從而使讀者對本案例的開發(fā)有一個(gè)更加深刻的理解。下面就對這些繪制相關(guān)類進(jìn)行詳細(xì)介紹。

2.6.1 繪制氣泡相關(guān)類
真實(shí)的水族館中時(shí)常會冒出一些氣泡,所以,在該壁紙中加入了透明氣泡元素,從而達(dá)到仿真、酷炫的效果。最后本案例的運(yùn)行效果是魚在水族館里面游,透明的氣泡從屏幕下方不斷冒出,上升到一定高度后氣泡突然消失,這樣能使壁紙顯得更加真實(shí),更加具有可觀賞性。

本小節(jié)主要介紹繪制氣泡相關(guān)類,繪制氣泡相關(guān)類分為氣泡控制類BubbleControl,用來控制所有氣泡的繪制和單個(gè)氣泡繪制類SingleBubble,用來對單個(gè)氣泡進(jìn)行繪制,開發(fā)步驟如下所示。

(1) 下面首先對氣泡控制類BubbleControl的開發(fā)進(jìn)行介紹。氣泡控制類中包括創(chuàng)建氣泡對象,創(chuàng)建并啟動氣泡移動線程,繪制氣泡等。具體代碼如下所示。

1 package com.bn.ld.Bubbles; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class BubbleControl { 4 public ArrayList<SingleBubble> bubbleSingle = new ArrayList<SingleBubble>(); // 氣泡類的列表 5 int texld; // 氣泡的紋理ID 6 public BubbleControl(int texld) { 7 this.texld = texld; // 拿到ID 8 for (int i = 0; i < Constant.BUBBLE_NUM; i++) { // 創(chuàng)建多個(gè)氣泡 9 bubbleSingle.add(new SingleBubble(this.texld)); // 將氣泡加入氣泡列表 10 } 11 BubbleThread Bgt = new BubbleThread(this); // 創(chuàng)建氣泡移動線程 12 Bgt.start(); // 啟動氣泡移動線程 13 } 14 public void drawSelf(GL10 gl) { 15 try { 16 Collections.sort(this.BubbleSingle); // 對氣泡排序 17 for (int i = 0; i < this.BubbleSingle.size(); i++) { // 繪制氣泡 18 gl.glPushMatrix(); // 保護(hù)矩陣 19 BubbleSingle.get(i).drawSelf(gl); // 繪制氣泡 20 gl.glPopMatrix(); // 恢復(fù)矩陣 21 }} catch (Exception e) { // 異常處理 22 e.printStackTrace(); 23 }}}

此處包括創(chuàng)建氣泡類列表用來存放氣泡對象,創(chuàng)建氣泡移動線程并啟動,從而控制氣泡的移動。繪制氣泡時(shí)要先保護(hù)矩陣,然后再繪制氣泡,最后恢復(fù)矩陣。

(2)上面已經(jīng)對氣泡控制類BubbleControl進(jìn)行了詳細(xì)介紹,接下來就應(yīng)該進(jìn)入到對單個(gè)氣泡繪制類SingleBubble的介紹。在單個(gè)氣泡繪制類中隨機(jī)設(shè)置了氣泡的初始位置、上升的最大高度等。繪制氣泡時(shí)用到了混合技術(shù),如果采用了混合技術(shù),對對象的繪制順序是有嚴(yán)格要求的,即繪制順序是由遠(yuǎn)及近,所以,在繪制氣泡之前要根據(jù)氣泡的位置對氣泡列表中的氣泡對象進(jìn)行排序,具體代碼如下所示。

1 package com.bn.ld.Bubbles; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class SingleBubble { 4 float cuerrentX; // 氣泡當(dāng)前_x_位置 5 float cuerrentY; // 氣泡當(dāng)前_y_位置 6 float cuerrentZ; // 氣泡當(dāng)前_z_位置 7 float border; // 氣泡的最大高度 8 int texld; // 紋理ID 9 Bubble bubbles; // 氣泡對象 10 public SingleBubble(int texld) { 11 newPosition(); // 初始?xì)馀莸奈恢?12 this.texld = texld; 13 bubbles = new Bubble(texld); // 創(chuàng)建氣泡 14 } 15 public void drawSelf(GL10 gl) { 16 gl.glPushMatrix(); // 保護(hù)矩陣 17 gl.glTranslatef(cuerrentX, cuerrentY, cuerrentZ); // 移動 18 bubbles.drawSelf(gl,texld); // 繪制氣泡 19 gl.glPopMatrix(); // 恢復(fù)矩陣 20 } 21 public void bubbleMove() { 22 this.cuerrentY += Constant.BubbleMoveDistance; // 氣泡移動 23 if (this.cuerrentY > border) { 24 newPosition(); // 重置氣泡的位置 25 }} 26 public void newPosition() { 27 cuerrentX = (float) ((Math.random() - 0.5) * 10);// 隨機(jī)改變氣泡的x位置 28 cuerrentY = (float) (Math.random() - 4); // 隨機(jī)改變氣泡的y位置 29 cuerrentZ = (float) ((Math.random() - 1) * 3.5f);// 隨機(jī)改變氣泡的z位置 30 border = (float) (2 * Math.random() + 3); // 氣泡上升的最大高度 31 }} 32 public int compareTo(SingleBubble another) { 33 return ((this.cuerrentZ-another.cuerrentZ)==0)?0:((this.cuerrentZ-another. cuerrentZ)>0)?1:-1; 34 }

第1~14行為相關(guān)變量的聲明,包括氣泡位置、紋理ID等,在構(gòu)造器中會調(diào)用一次newPosition方法,從而指定氣泡的初始位置和最大高度。
第15~34行為根據(jù)氣泡當(dāng)前位置繪制氣泡,設(shè)置氣泡移動速度,并修改氣泡位移,同時(shí)判斷氣泡位置是否大于氣泡的最大高度border,如果大于border則調(diào)用newPosition方法重新指定氣泡的初始位置和最大高度,需要注意的是,氣泡位置和最大高度都是在一定范圍內(nèi)隨機(jī)產(chǎn)生的。最后重寫compareTo方法根據(jù)氣泡位置對氣泡進(jìn)行排序。
2.6.2 繪制群魚相關(guān)類
上一小節(jié)介紹了繪制氣泡相關(guān)類,本小節(jié)主要介紹繪制群魚相關(guān)類,繪制群魚相關(guān)類分為群魚控制類FishControl,用來控制群魚里所有魚的繪制,和單個(gè)魚繪制類SingleFish,用來對單個(gè)魚進(jìn)行繪制,開發(fā)步驟如下所示。

(1)首先進(jìn)行的是群魚控制類FishControl的開發(fā)介紹。該類中將創(chuàng)建群魚列表,創(chuàng)建群魚的游動線程并啟動,遍歷群魚列表繪制群魚。具體代碼如下所示。

1 package com.bn.ld.Fishs; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class FishControl { 4 public ArrayList<SingleFish> fishAl; // 魚列表 5 FishGoThread fgt; // 魚移動線程 6 public TDRender Tr; // 渲染器 7 public FishControl(ArrayList<SingleFish> fishAl,TDRender tr){ 8 this.fishAl = fishAl; 9 this.Tr=tr; 10 fgt= new FishGoThread(this); // 創(chuàng)建魚游動線程 11 fgt.start(); // 啟動魚游動線程 12 } 13 public void drawSelf(GL10 gl) { 14 try { 15 for(int i=0;i<this.fishAl.size();i++){ // 循環(huán)繪制每一條魚 16 gl.glPushMatrix(); // 保護(hù)矩陣 17 fishAl.get(i).drawSelf(gl); // 繪制魚 18 gl.glPopMatrix(); // 恢復(fù)矩陣 19 }} 20 catch (Exception e) { // 異常處理 21 e.printStackTrace(); 22 }}}

此處是創(chuàng)建群魚列表,獲得渲染器TDRender、創(chuàng)建群魚游動線程并啟動。繪制時(shí)先保護(hù)矩陣,遍歷群魚列表繪制每一條魚,然后恢復(fù)矩陣,最后進(jìn)行異常處理。

(2)上面已經(jīng)對群魚控制類FishControl進(jìn)行了介紹,下面將進(jìn)行單條魚繪制類SingleFish的開發(fā)介紹。在該類中設(shè)置了群魚中每個(gè)魚的位置、速度、質(zhì)量(力的縮放比)、受到的外力、魚食對魚的吸引力、魚的旋轉(zhuǎn)角度等。具體代碼如下所示。

1 package com.bn.ld.Fishs; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class SingleFish { 4 ……//此處省略相關(guān)成員變量的聲明代碼,讀者可自行查閱光盤中的源代碼 5 LoadedObjectVertexNormalTexture lovn; // 初始化魚類對象 6 public SingleFish(int fish, TDRender TDRender, String name, 7 Vector3f Position, Vector3f Speed, Vector3f force, 8 Vector3f attractforce, float weight) { 9 this.texld=fish; // 魚的紋理ID 10 this.position = Position; // 魚的位置 11 this.speed = Speed; // 魚的速度 12 this.force = force; // 魚受到的外力 13 this.attractforce = attractforce; // 魚受到的吸引力 14 this.weight = weight; // 魚的質(zhì)量 15 lovn = LoadUtil.loadFromFileVertexOnly(name, 16 TDRender.getResources()); // 加載魚模型 17 } 18 public void drawSelf(GL10 gl) { 19 gl.glPushMatrix(); // 保護(hù)矩陣 20 gl.glTranslatef(this.position.x, this.position.y, this.position.z); // 平移 21 gl.glRotatef(yAngle, 0, 1, 0); // 繞_y_軸旋轉(zhuǎn) 22 gl.glRotatef(zAngle, 0, 0, 1); // 繞_z_軸旋轉(zhuǎn) 23 if (lovn != null) { // 魚對象不為空就繪制 24 lovn.drawSelf(gl,this.texld); // 繪制魚 25 } 26 gl.glPopMatrix(); // 恢復(fù)矩陣 27 } 28 public void fishMove() { // 魚的游動方法 29 float fz = (speed.x * speed.x + speed.y * 0 + speed.z * speed.z); // zAngle的計(jì)算 30 float fm = (float) (Math.sqrt(speed.x * speed.x + speed.y * speed.y 31 + speed.z * speed.z) * Math.sqrt(speed.x * speed.x + speed.z* speed.z)); 32 float angle = fz / fm; 33 tempZ = (float) (180f / Math.PI) * (float) Math.acos(angle); // 繞_z_軸的旋轉(zhuǎn)角度 34 fz = (speed.x * Constant.initialize.x + speed.z * Constant.initialize.z); // yAngle的計(jì)算 35 fm = (float) (Math.sqrt(Constant.initialize.x * Constant.initialize.x 36 + Constant.initialize.z * Constant.initialize.z) 37 * Math.sqrt(speed.x * speed.x + speed.z * speed.z)); 38 angle = fz / fm; 39 tempY = (float) (180f / Math.PI) * (float) Math.acos(angle); // 繞_y_軸的旋轉(zhuǎn)角度 40 if (speed.y <= 0) { // 獲取夾角根據(jù)Speed.y的正負(fù)性來確定夾角的正負(fù)性 41 zAngle = tempZ; // 上面求的角度都是正的 42 } else { 43 zAngle = -tempZ; 44 } 45 if (speed.z > 0) { // 獲取夾角根據(jù)Speed.z的正負(fù)性來確定夾角的正負(fù)性 46 yAngle = tempY; // 上面求的角度都是正的 47 } else { 48 yAngle = -tempY; 49 } 50 if (Math.abs(speed.x + force.x) < Constant.MaxSpeed){ // 動態(tài)的修改魚x方向的速度 51 speed.x += force.x; 52 } 53 if (Math.abs(speed.y + force.y) < Constant.MaxSpeed){ // 動態(tài)的修改魚y方向的速度 54 speed.y += force.y; 55 } 56 if (Math.abs(speed.z + force.z) < Constant.MaxSpeed) { // 動態(tài)的修改魚z方向的速度 57 speed.z += force.z; 58 } 59 if (Math.abs(speed.x + attractforce.x) < Constant.MaxSpeed){ //動態(tài)的修改魚x方向的速度 60 speed.x += attractforce.x; 61 } 62 if (Math.abs(speed.y + attractforce.y) < Constant.MaxSpeed) { //動態(tài)的修改魚y方向的速度 63 speed.y += attractforce.y; 64 } 65 if (Math.abs(speed.z + attractforce.z) < Constant.MaxSpeed) { //動態(tài)的修改魚z方向的速度 66 speed.z += attractforce.z; 67 } 68 position.plus(speed); // 改變魚的位置 69 this.force.x = 0; // 每次計(jì)算完每條魚的受力 70 this.force.y = 0; // 把所受的外力置零 71 this.force.z = 0; 72 attractforce.x = 0; // 把魚食對魚的吸引力置零 73 attractforce.y = 0; 74 attractforce.z = 0; 75 }}

第1~17行引入部分類和包,聲明相關(guān)成員變量,這些代碼在這里省略,讀者可自行查閱光盤中的源代碼,其中第6~17行通過構(gòu)造器接收傳過來的魚的各種參數(shù)的信息,然后通過工具類加載魚模型。
第18~27行為繪制時(shí)先保護(hù)變換矩陣再將魚平移到指定位置,并讓坐標(biāo)軸旋轉(zhuǎn)相應(yīng)的角度,從而使魚能以一個(gè)正確的姿態(tài)顯示在屏幕上,然后繪制魚,最后恢復(fù)變換矩陣。
第28~49 行為坐標(biāo)軸旋轉(zhuǎn)角度的計(jì)算方法,具體計(jì)算是根據(jù)魚的速度矢量確定出魚的朝向,利用初等函數(shù)計(jì)算出坐標(biāo)軸相應(yīng)的旋轉(zhuǎn)角度。
第50~68行為動態(tài)修改魚速度的方法,魚可能會受到外力(排斥力)和食物吸引力的作用,力會改變魚的速度,當(dāng)魚的速度超過閾值時(shí),速度不再增加。將魚的速度矢量和位移矢量相加得到魚新的位移矢量。
第69~75行是將力置零,因?yàn)槊看味家匦掠?jì)算魚的受力,當(dāng)魚不受到力的作用時(shí),魚的速度不會改變,魚將沿著當(dāng)前的速度方向游動。

2.6.3 繪制魚群相關(guān)類
上一小節(jié)已經(jīng)對繪制群魚相關(guān)類進(jìn)行了詳細(xì)介紹,這一小節(jié)對繪制魚群相關(guān)類的開發(fā)進(jìn)行詳細(xì)介紹。繪制魚群相關(guān)類分為魚群控制類FishSchoolControl,用來控制魚群里所有魚的繪制,和單個(gè)魚繪制類SingleFishSchool,用來對魚群中單個(gè)魚進(jìn)行繪制,開發(fā)步驟如下所示。

(1)首先進(jìn)行魚群控制類FishSchoolControl的開發(fā)介紹。在魚群控制類中創(chuàng)建了魚群列表和魚對象,同時(shí)創(chuàng)建了魚群游動線程并啟動。具體代碼如下所示。

1 package com.bn.ld. FishSchool; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class FishSchoolControl { 4 public ArrayList<FishSchooldSingleFish> fishSchool = new ArrayList <FishSchooldSingleFish>(); 5 public TDRender Tr; 6 FishschoolThread Thread; // 魚群的移動線程 7 public FishSchoolControl(int texld, TDRender tr) { // 添加魚群,共4條魚 8 this.Tr = tr; 9 fishSchool.add(new FishSchooldSingleFish(texld, Tr, "fish3.obj", // 魚的ID、渲染器、模型 10 new Vector3f(0, 0, 0), // 初始位置 11 new Vector3f(-0.05f, 0.00f, -0.05f),new Vector3f(0, 0, 0), // 初始速度和力 12 new Vector3f(0, 0, 0), 50)); // 吸引力、質(zhì)量 13 fishSchool.add(new FishSchooldSingleFish(texld, Tr, "fish3.obj", //魚的ID、渲染器、模型 14 new Vector3f(0, 0, -Constant.Radius), // 初始位置 15 new Vector3f(-0.04f,0.00f, -0.04f), new Vector3f(0, 0, 0), // 初始速度和力 16 new Vector3f(0,0, 0), 50)); // 吸引力、質(zhì)量 17 fishSchool.add(new FishSchooldSingleFish(texld, Tr, "fish3.obj", //魚的ID、渲染器、模型 18 new Vector3f(Constant.Radius, 0, 0), // 初始位置 19 new Vector3f(-0.04f,0.00f, -0.04f), new Vector3f(0, 0, 0), // 初始速度和力 20 new Vector3f(0,0, 0), 50)); // 吸引力、質(zhì)量 21 fishSchool.add(new FishSchooldSingleFish(texld, Tr, "fish3.obj", // 魚的ID、渲染器、模型 22 new Vector3f(0, 0, Constant.Radius), // 初始位置 23 new Vector3f(-0.04f,0.00f, -0.04f), new Vector3f(0, 0, 0), // 初始速度和力 24 new Vector3f(0,0, 0), 50)); // 吸引力、質(zhì)量 25 Thread = new FishschoolThread(this); // 定義魚群游動線程 26 Thread.start(); // 啟動魚群游動線程 27 } 28 public void drawSelf(GL10 gl) { 29 try { 30 for (int i = 0; i < this.fishSchool.size(); i++){ 31 gl.glPushMatrix(); // 保護(hù)矩陣 32 fishSchool.get(i).drawSelf(gl); // 繪制魚群 33 gl.glPopMatrix(); // 恢復(fù)矩陣 34 }} 35 catch (Exception e){ // 異常處理 36 e.printStackTrace(); 37 }}}}

第1~27行為創(chuàng)建魚群游動線程,并向魚群列表中添加魚對象,同時(shí)啟動魚群游動線程從而實(shí)現(xiàn)魚的游動。魚群列表里的第一條魚不受到其他任何魚的作用力,只受墻壁的作用力,并且魚群里面的魚(不包括第一條魚)在特定的條件下受到從該魚本身指向某個(gè)位置(以魚群中第一條魚所在的位置為球心,以定長半徑確定的球面上的一個(gè)點(diǎn))的向心力作用。
第28~37行為繪制方法。首先循環(huán)遍歷fishSchool列表,繪制魚群里面的魚。在繪制前要先保護(hù)矩陣,然后繪制魚群,恢復(fù)矩陣,最后進(jìn)行異常處理。
(2)上面已經(jīng)完成了對魚群控制類的詳細(xì)介紹,下面將對單個(gè)魚繪制類SingleFishSchool的開發(fā)進(jìn)行詳細(xì)介紹。在單個(gè)魚繪制類中設(shè)置魚的位置、速度、質(zhì)量、受到的外力、受到的向心力(第一條魚不受到向心力作用),魚的旋轉(zhuǎn)角度,具體代碼如下所示。

1 package com.bn.ld.FishSchool; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class SingleFishSchool { 4 ……//此處省略相關(guān)成員變量的聲明代碼,讀者可自行查閱光盤中的源代碼 5 LoadedObjectVertexNormalTexture fishSchool; // 創(chuàng)建魚對象 6 public SingleFishSchool(int texld, TDRender TDRender, String fname, 7 Vector3f Position, Vector3f Speed, Vector3f force, 8 Vector3f ConstantForce, float weight) { 9 this.position = Position; // 魚的初始位置 10 this.speed = Speed; // 魚的初始速度 11 this.force = force; // 魚的初始受力 12 this.weight = weight; // 魚的質(zhì)量 13 this.ConstantPosition.x = Position.x; // 不動魚的_x_位置 14 this.ConstantPosition.y = Position.y; // 不動魚的_y_位置 15 this.ConstantPosition.z = Position.z; // 不動魚的_z_位置 16 this.ConstantForce = ConstantForce; // 魚受到的向心力 17 fishSchool = LoadUtil.loadFromFileVertexOnly("fish3.obj", 18 TDRender.getResources()); // 加載魚模型 19 } 20 public void drawSelf(GL10 gl) { 21 gl.glPushMatrix(); // 保護(hù)矩陣 22 gl.glTranslatef(position.x, position.y, position.z); // 平移 23 gl.glRotatef(yAngle, 0, 1, 0); // 繞_y_軸旋轉(zhuǎn) 24 gl.glRotatef(zAngle, 0, 0, 1); // 繞_z_軸旋轉(zhuǎn) 25 if (fishSchool != null) { // 繪制魚群 26 fishSchool.drawSelf(gl,texld); 27 } 28 gl.glPopMatrix(); // 恢復(fù)矩陣 29 } 30 public void fishschoolMove() { // 根據(jù)魚類位置以及速度來計(jì)算魚的下一個(gè)位置 31 if (speed.x == 0 && speed.z == 0 && speed.y > 0) { // _y_軸速度大于0 32 tempZ = -90; 33 tempY = 0; 34 } else if (speed.x == 0 && speed.z == 0 && speed.y < 0) { // _y_軸速度小于0 35 tempZ = 90; 36 tempY = 0; 37 } else if (speed.x == 0 && speed.z == 0 && speed.y == 0) { // _y_軸速度等于0 38 tempZ = 90; 39 tempY = 0; 40 } else { 41 float fz = (speed.x * speed.x + speed.y * 0 + speed.z * speed.z); //分子 42 float fm = (float) (Math.sqrt(speed.x * speed.x + speed.y * speed.y 43 + speed.z * speed.z) * Math.sqrt(speed.x * speed.x 44 + speed.z * speed.z)); // 分母 45 float zhi = fz / fm; // cos值 46 tempZ = (float) (180f / Math.PI) * (float) Math.acos(zhi); // 反三角函數(shù)求得旋轉(zhuǎn)角度 47 fz = (speed.x * Constant.initialize.x + speed.z 48 * Constant.initialize.z); //分子 49 fm = (float) (Math.sqrt(Constant.initialize.x 50 * Constant.initialize.x + Constant.initialize.z 51 * Constant.initialize.z) * Math.sqrt(speed.x * speed.x 52 + speed.z * speed.z)); // 分母 53 zhi = fz / fm; // cos值 54 tempY = (float) (180f / Math.PI) * (float) Math.acos(zhi); // 反三角函數(shù)求得旋轉(zhuǎn)角度 55 } 56 if (speed.y <= 0) { // 獲取夾角根據(jù)speed.y的正負(fù)性來確定夾角的正負(fù)性 57 zAngle = tempZ; 58 } else{ 59 zAngle = -tempZ; //_z_軸旋轉(zhuǎn)角度 60 } 61 if (speed.z > 0){ // 獲取夾角根據(jù)speed.z的正負(fù)性來確定夾角的正負(fù)性 62 yAngle = tempY; 63 } else { 64 yAngle = -tempY; // _y_軸旋轉(zhuǎn)角度 65 } 66 if (Math.abs(speed.x + force.x) <Constant.SchoolMaxspeed) { // 動態(tài)修改魚的速度 67 speed.x += force.x; // 外力作用下_x_軸上的速度 68 } 69 if (Math.abs(speed.y + force.y) <Constant.SchoolMaxspeed){ 70 speed.y += force.y; // 外力作用下_y_軸上的速度 71 } 72 if (Math.abs(speed.z + force.z) < Constant.SchoolMaxspeed){ 73 speed.z += force.z; // 外力作用下_z_軸上的速度 74 } 75 if (Math.abs(speed.x + ConstantForce.x) < Constant.SchoolMaxspeed){ // 恒力的作用 76 speed.x += ConstantForce.x; // 恒力作用下_x_軸上的速度 77 } 78 if (Math.abs(speed.y + ConstantForce.y) < Constant.SchoolMaxspeed){ 79 speed.y += ConstantForce.y; // 恒力作用下_y_軸上的速度 80 } 81 if (Math.abs(speed.z + ConstantForce.z) < Constant.SchoolMaxspeed) { 82 speed.z += ConstantForce.z; // 恒力作用下_z_軸上的速度 83 } 84 position.plus(speed); // 魚群里面魚的新位移 85 this.force.x = 0; // 將受到的外力置為零 86 this.force.y = 0; 87 this.force.z = 0; 88 }}

第1~19行定義了魚群的位置信息、速度信息、受到的外力信息和魚受到的向心力信息等代碼在此處省略,讀者可自行查閱光盤中的源代碼。
第20~29行為繪制時(shí)先保護(hù)變換矩陣,將魚群平移到指定位置,讓坐標(biāo)軸旋轉(zhuǎn)相應(yīng)的角度,然后繪制魚群,最后恢復(fù)變換矩陣。
第30~65行為坐標(biāo)軸旋轉(zhuǎn)角度的計(jì)算方法,具體角度的計(jì)算是根據(jù)魚的速度矢量確定出魚的朝向,利用初等函數(shù)計(jì)算出坐標(biāo)系中的y軸和z軸的旋轉(zhuǎn)角度。
第66~88行為改變魚速度的方法,魚可能受到外力(排斥力)和食物吸引力(本案例中魚群里面的魚并沒有受到食物吸引力的作用),通過力的作用來改變魚的速度,當(dāng)速度超過閾值時(shí),速度不再增加。同時(shí)魚的速度矢量和位移矢量相加得到魚的新位移矢量,然后將外力置為零。

2.6.4 繪制魚食相關(guān)類
上一小節(jié)已經(jīng)完成了繪制魚群相關(guān)類的介紹,這一小節(jié)將要完成繪制魚食相關(guān)類的開發(fā),這樣在本案例中就可以對游動的魚進(jìn)行喂食了。給魚喂食要對屏幕進(jìn)行觸控操作,本案例采用了屏幕拾取技術(shù),讀者在運(yùn)行本程序時(shí)可以感受到,點(diǎn)擊地面遠(yuǎn)點(diǎn)時(shí)食物會相對小一些,點(diǎn)擊地面近點(diǎn)時(shí)食物會相對大一些,從而產(chǎn)生近大遠(yuǎn)小的效果,當(dāng)然,如果點(diǎn)擊地面過遠(yuǎn),則不產(chǎn)生喂食效果。屏幕觸控事件的介紹在前面已經(jīng)給出,在此就不再介紹,只介紹魚食的繪制。

本小節(jié)主要介紹繪制魚食相關(guān)類,繪制魚食相關(guān)類分為魚食控制類FeedFish,用來控制魚食的繪制,和魚食繪制類SingleFood,用來繪制魚食,開發(fā)步驟如下所示。

(1)首先將進(jìn)行喂食控制類FeedFish的開發(fā)工作,具體包括設(shè)置魚食的初始位置,更改線程的標(biāo)志位等,具體代碼如下所示。

1 package com.bn.ld.FeedFood; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class FeedFish { 4 ……//此處省略相關(guān)成員變量的聲明代碼,讀者可自行查閱光盤中的源代碼 5 public FeedFish (TDRender tr) { 6 start = true; 7 this.Tr = tr; 8 } 9 public void startFeed(Vector3f Start,Vector3f End) { 10 Vector3f dv=End.cutPc(Start); // 喂食的位置 11 float t=( Constant.Y_HEIGHT -Start.y)/dv.y; // 根據(jù)地面的高度算出_t_值 12 float xd=Start.x+t*dv.x; // 根據(jù)_t_計(jì)算出交點(diǎn)的_x_坐標(biāo)值 13 float zd=Start.z+t*dv.z; // 根據(jù)_t_計(jì)算出交點(diǎn)的_z_坐標(biāo)值 14 if(zd<= Constant.ZTouch_Min ||zd> Constant.ZTouch_Max) {// 點(diǎn)擊超出范圍不喂食 15 Constant.isFeed=true; // 標(biāo)志位變?yōu)閠rue,能繼續(xù)點(diǎn)擊 16 return; 17 } 18 Tr.Xposition = xd; // 食物的_x_位置 19 Tr.Zposition = zd; // 食物的_z_位置 20 Tr.Fooddraw = true; // 繪制食物的標(biāo)志位 21 Tr.singleFood.Ft.Fresit = true; // 重置的線程變?yōu)閠ure 22 Tr.singleFood.At.Go = true; // 吸引力線程的添加,看到魚食的標(biāo)志位設(shè)為True 23 Tr.singleFood.Ft.Go = true; // 將喂食線程的標(biāo)志位設(shè)為true 24 if (start) { // 調(diào)用此方法開始移動食物的方法 25 Tr.singleFood.startFeed(); // 開始喂食 26 start = false; // 把標(biāo)志位變?yōu)閒alse,表示不能再調(diào)用此方法 27 }}}

第2~13行為計(jì)算屏幕觸控位置的算法,是根據(jù)地面高度算出遠(yuǎn)近平面上兩點(diǎn)與該平面的交點(diǎn)(根據(jù)3點(diǎn)共線求出與地面平面交點(diǎn))。
第14~27行先判斷點(diǎn)擊位置是否在規(guī)定范圍內(nèi),如果在規(guī)定的范圍內(nèi)將計(jì)算的位置賦給Xposition和Zposition,并把食物移動線程和吸引力線程計(jì)算的標(biāo)志位設(shè)置為true。如果是第一次點(diǎn)擊地面喂食還會調(diào)用singleFood中的startFeed方法,開啟線程,開始喂食,再次點(diǎn)擊的時(shí)候此方法不會再被調(diào)用,只是不斷地修改線程標(biāo)志位。
(2)上面已經(jīng)完成了魚食控制類的詳細(xì)介紹,下面將對單個(gè)魚食繪制類SingleFood的開發(fā)進(jìn)行介紹,具體包括實(shí)例化食物移動線程和食物吸引力線程,設(shè)置食物的Yposition以及啟動線程的方法和食物的繪制等,具體代碼如下所示。

1 package com.bn.ld.FeedFood; 2 ……//此處省略部分類和包的引入代碼,讀者可自行查閱光盤中的源代碼 3 public class SingleFood { 4 public FoodThread Ft; // 食物移動線程 5 public AttractThread At; // 吸引力線程 6 public TDRender Tr; 7 public float Ypositon = Constant.FoodPositionMax_Y; // 獲取Yposition 8 LoadedObjectVertexNormalTexture fishFoods; // 創(chuàng)建魚食的對象 9 public SingleFood (LoadedObjectVertexNormalTexture fishfoods, TDRender Tr) { 10 this.Tr = Tr; 11 fishFoods = fishfoods; // 實(shí)例化食物 12 Ft = new FoodThread(this); // 實(shí)例化線程 13 At = new AttractThread(this); // 實(shí)例化線程 14 } 15 public void startFeed() { // 觸控之后就調(diào)用這個(gè)方法開始線程,食物的位置開始變化 16 Ft.start(); // 啟動魚食移動線程 17 At.start(); // 啟動吸引力線程 18 } 19 public void drawSelf(GL10 gl){ 20 gl.glPushMatrix(); // 保護(hù)矩陣 21 gl.glTranslatef(Tr.Xposition,this.Ypositon, Tr.Zposition); // 平移 22 fishFoods.drawSelf(gl,this.texld); // 繪制 23 gl.glPopMatrix(); // 恢復(fù)矩陣 24 }}

說明
此類主要作用是初始化魚食的Yposition,創(chuàng)建魚食移動線程和吸引力線程,當(dāng)調(diào)用此類的startFeed方法時(shí)會啟動這兩個(gè)線程,最后對魚食進(jìn)行繪制。

總結(jié)

以上是生活随笔為你收集整理的《Android 应用案例开发大全(第二版)》——2.6节绘制相关类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。