《Android 应用案例开发大全(第3版)》——第2章,第2.7节线程相关类

2.7 线程相关类
上一节已为读者详细介绍了绘制相关类,在读者进一步了解本案例的基础上,在这一节将对线程相关类的开发进行详细的介绍。前面已经完成了对水族馆背景及水族馆中的鱼、鱼群、鱼食和气泡的绘制开发,只绘制出模型是不够的,还需要让它们动起来,从而产生更加真实的效果。

该壁纸开发中开启了多个线程,使得本案例中的场景更加活灵活现,更加逼真。线程相关类主要包括气泡移动线程类、群鱼游动线程类、鱼群游动线程类、鱼食移动线程类和吸引力线程类,下面将对线程相关类的开发进行详细的介绍。

2.7.1 气泡移动线程类——BubbleThread
前面已经完成了对3D水族馆中气泡的开发,但只开发出一个模型是远远不够的,这就需要让气泡移动起来,并可以让多处位置连续不断地冒出气泡来,这样场景才会更加逼真。这就是本类的作用,本类开启了一个线程定时移动气泡,并在不同位置冒出。其具体代码如下。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/bubble/目录下的BubbleThread.java。

1 package wyf.lxg.bubble;         //声明包名
2 ......//此处省略部分类和包的引入代码,读者可自行查阅随书光盘中的源代码
3 public class BubbleThread extends Thread {
4  float x;           //气泡左右移动标志位
5  float y;           //气泡位置标志位
6  boolean flag = true;         //标志位
7  BubbleControl Bcl;         //气泡的控制类
8  public BubbleThread(BubbleControl Bcl){              //构造方法
9   this.Bcl=Bcl;         //获取气泡控制类对象
10  }
11  public void run(){
12   while (flag) {         // 循环定时移动气泡
13     try {
14    for(int i=0;i<Bcl.BubbleSingle.size();i++){ //遍历气泡列表
15     if((i+3)%3==0){   //将气泡的总数量,切分为3份
16       if(((i+3)/3)%2==0){ //进行奇偶判断,为气泡的x、z轴方向偏移做准备
17      y=1;         //偶数位气泡标志位
18       }else{
19      y=-1;        //奇数位气泡标志位
20       }
21      x=1;         //第一处气泡位置队列
22     }
23    ......//该处省略了与第一个if语句中相似的两个if语句,读者可自行查阅随书光盘中的源代码
24    Bcl.BubbleSingle.get(i).bubbleMove(x,y);  //执行气泡移动方法
25    }} catch (Exception e) {      //进行异常处理
26     e.printStackTrace();      //打印异常
27    }
28    try {
29     Thread.sleep(10);      //线程休眠10ms
30    } catch (Exception e) {      //异常处理
31     e.printStackTrace();      //打印异常
32 }}}}

第1~10行为声明相关成员变量,通过构造器,获取BubbleControl的引用,为后面线程中调用BubbleControl类中的bubbleMove方法做准备。其中省略了部分类和包的引入代码,请读者自行查阅随书光盘中的源代码
第11~32行为该类中气泡移动线程方法,在该方法中遍历气泡列表BubbleSingle。为了能够在场景中出现3处气泡,所以将气泡队列切分成3队,并根据每个队列中气泡的奇偶性来给出y的值,以作为气泡x、z轴移动的扰动变量,并调用气泡移动方法bubbleMove,然后休眠10ms。
2.7.2 群鱼游动线程类——FishGoThread
上小节介绍了气泡移动的线程BubbleThread,本小节将为读者介绍群鱼游动的线程。在线程中有关于群鱼之间的受力算法,以防止两条鱼互穿;还有关于群鱼碰到鱼群的受力变化,以及群鱼和墙壁碰撞时群鱼的受力如何变化。其具体代码如下所示。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fish/目录下的FishGoThread.java。

1 package wyf.lxg.fish;       //声明包名
2 ......//此处省略部分类和包的引入代码,读者可自行查阅随书光盘中的源代码
3 public class FishGoThread extends Thread {
4 ......//该处省略了部分变量与构造方法代码,读者可自行查阅随书光盘中的源代码
5  public void run() {       //定时运动所有群鱼的线程
6   while (flag) {       //循环定时移动鱼类
7    try {        //动态地修改鱼受到的力的大小
8     for (int i = 0; i < fishControl.fishAl.size(); i++) {
     //计算鱼群对该鱼产生力的大小
9      Vector Vwall = null;
10      inside: for (int j=0; j < fishControl.fishAl.size();j++){
11        Vector V3 = null;
12        if (i == j) { continue inside;}//自己不能对自己产生力
13        V3 = fishControl.fishAl.get(i).position.cut(
        //向量减法得到力改变方向
14        fishControl.fishAl.get(j).position,Constant.
        MinDistances);
15        V3.getforce(fishControl.fishAl.get(i).weight);
        //力与质量的比
16        fishControl.fishAl.get(i).force.plus(V3);
        //两条鱼之间的力
17        }
18        if (fishControl.My.fishSchool != null&& fishControl.My.
        fishSchool.fishSchool
19      .size() != 0) {
20       Vector V4 = fishControl.fishAl.get(i).position.
       cut(//力的方向
21         fishControl.My.fishSchool.fishSchool.get(0).
         position, Constant.MinDistances);
22       V4.getforce(fishControl.fishAl.get(i).weight);
23       fishControl.fishAl.get(i).force.plus(V4);
       //两条鱼之间的力
24      }
25      Vwall = new Vector(0, 0, 0);
26      if (fishControl.fishAl.get(i).position.x <= ) {
      //判断鱼和左墙壁的碰撞
27       Vwall.x = ;  //撞上之后产生力的作用
28      }
29      if (fishControl.fishAl.get(i).position.x > ) {
      //判断鱼和右墙壁的碰撞
30       Vwall.x = ; //撞上之后产生力的作用
31      }
32      if (fishControl.fishAl.get(i).position.y >= ) {
      //判断鱼和上墙壁的碰撞
33       Vwall.y = ; //撞上之后产生力的作用
34      }
35      if (fishControl.fishAl.get(i).position.y <= -3) {
      //判断鱼和下墙壁的碰撞
36       Vwall.y = ;  //撞上之后产生力的作用
37      if(fishControl.fishAl.get(i).position.y <= -4){
      //鱼和下墙壁太近
38       Vwall.y =;  //鱼所受到反向力加倍
39      }}
40      if (fishControl.fishAl.get(i).position.z < ) {
      //判断鱼和后墙壁的碰撞
41       Vwall.z = ;  //撞上之后产生力的作用
42      }
43      if (fishControl.fishAl.get(i).position.z > 2) {
      //判断鱼和前墙壁的碰撞
44       Vwall.z = ;  //撞上之后产生力的作用
45      }
46      Vwall.y -= 0.000009;
47      fishControl.fishAl.get(i).force.plus(Vwall);//二力相加
48     }
49     for (int i = 0; i < fishControl.fishAl.size(); i++) {
     //定时修改鱼的速度和位移
50      fishControl.fishAl.get(i).fishMove();//调用鱼游动方法的作用
51   }}
52    ......//该处省略了异常处理与线程休眠代码,读者可自行查阅随书光盘中的源代码
53 }}}

第3~24行首先遍历鱼群、群鱼列表,并计算单条鱼所受到的其他鱼的力和鱼群对该鱼的力。当鱼与其他单条鱼或群鱼之间的距离小于阙值后会产生力的作用,这样计算群鱼中的鱼一直游动,并不会与鱼群发生碰撞。
第25~47行是对碰壁检测处理的代码,这里计算了鱼与上、下、左、右、前、后墙壁的检测,然后判断鱼某个方向的位置是否超过了墙壁的范围,如果超过,则墙壁给一个相反方向的力,然后将鱼所受到的力与墙壁给鱼的力相加求出鱼所受到的合力。
第49~50行遍历所有鱼的速度与位移。遍历所有群鱼中的鱼,调用fishMove方法使之动态地修改鱼的速度与位移,并让线程睡眠后刷新群鱼,这样,群鱼在场景中就会一直的由来游去,非常酷炫。

2.7.3 鱼群游动线程类——FishSchoolThread
上一小节为读者介绍了群鱼游动的线程类,本小节将着重介绍鱼群游动的线程类——FishSchoolThread,其中计算了鱼群与群鱼之间的受力,使之不会碰撞,还计算了鱼群中鱼受到从该位置指向相对位置的力,以及鱼群与墙壁碰撞时的受力情况。

(1)首先给出了FishSchoolThread类的整体框架。鱼群中单条鱼受到的向心力以及群鱼碰壁检测等其他算法代码过多,将在后面详细介绍。接下来详细介绍鱼群之间的受力算法,主要是群鱼对鱼群的作用力情况等。具体代码如下所示。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fishschool/目录下的FishSchoolThread.java。

1 package wyf.lxg.fishschool;        //声明包名
2 ......//此处省略部分类和包的引入代码,读者可自行查阅随书光盘中的源代码
3 public class FishschoolThread extends Thread {
4  boolean flag = true;         //线程标志位
5  FishSchoolControl fishschools;       //鱼群控制类对象
6  float Length;          //两条鱼之间的距离
7  public FishschoolThread(FishSchoolControl fishschools) {
8   this.fishschools = fishschools;
9  }
10  public void run() {
11   while (flag) {         //循环定时移动鱼类
12    try {
13     //群鱼对鱼群里面的鱼的作用力
14      outside: for (int i = 1; i < fishschools.fishSchool.size(); i++) {
15       for (int j = 0;j < fishschools.Tr.fishControl.fishAl.size(); j++) {
16     if (Length > Constant.SMinDistaces-0.5) {continue outside; }
     //判定范围
17       Vector V3 = null;
18       V3=.cut(fishschools.Tr.fishControl.fishAl
19        .get(j).position,Constant.SMinDistaces);//获取力的方向
20       V3.getforce(Constant.WeightScals);   //力的缩放比
21       fishschools.fishSchool.get(i).force.plus(V3);//两条鱼之间的力
22        }}
23     Vector Vwall = null;
24     float Cx = fishschools.fishSchool.get(0).position.x;
     //第零条鱼的位置
25     float Cy = fishschools.fishSchool.get(0).position.y;
26     float Cz = fishschools.fishSchool.get(0).position.z;
27     int j=1;       //鱼群里面3条能动的鱼
28     for(int i=-90;i<=90.;i=i+90){
29      fishschools.fishSchool.get(j).ConstantPosition.x=(float)
30          (Cx+Constant.Radius*Math.cos(i));
31      fishschools.fishSchool.get(j).ConstantPosition.y = Cy;
32                          fishschools.fishSchool.get(j).ConstantPosition.z=(float)
33          (Cz+Constant.Radius*Math.sin(i));
34       j++;
35     }
36     ......//该处省略了群鱼需要指向初始位置的力的算法代码,将在下面介绍
37     ......//该处省略群鱼碰壁检测算法代码,将在下面介绍
38     for (int i = 0; i < fishschools.fishSchool.size(); i++) {
39      fishschools.fishSchool.get(i).fishschoolMove();
40    }} catch (Exception e) {       //异常处理
41     e.printStackTrace();       //打印异常
42    }try {
43     Thread.sleep(50);       //线程休眠
44    } catch (Exception e) {       //异常处理
45     e.printStackTrace();       //打印异常
46 }}}}

第4~9行是本类中一些变量的声明还有构造器的初始化。将线程是否开始的标志位设置为true,并获得鱼群控制类对象FishSchoolControl,为下面的算法调用控制类对象中的方法,以及声明两条鱼之间的距离。
第14~35行当鱼群中的某条鱼与鱼群中的距离小于阙值后便对该鱼产生作用力。第一条鱼只受墙壁的力。鱼群中其他3条鱼互相没有力的作用,也没有第一条鱼的力。它们受到从该位置指向相对位置(以鱼群中第一条鱼的位置为中心,以定半径确定的球面上的一个点)的力,并受群鱼的力。
第36~45行为修改鱼群里面所有鱼的速度和位移。调用每条鱼的fishschoolMove方法定时修改鱼群里面鱼的速度和位移。进行异常处理,如果出现异常,则打印出异常。并让线程睡眠50ms后重新刷新鱼群。
(2)上面详细介绍了鱼群碰见群鱼之间的受力算法与鱼群中鱼的受力情况算法。下面将为读者详细介绍(1)中省略的鱼离开鱼群的受到恒力的算法,以及鱼群和墙壁碰撞时的鱼群受力变化的算法。这样鱼群一直是鱼群,不会被冲散。其具体代码如下所示。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fishschool/目录下的FishSchoolThread.java。

1 // 每条鱼受到从当前位置指向应该所在位置(Home)的力(恒力作用)
2 for (int i = 1; i < fishschools.fishSchool.size(); i++){  //遍历鱼类列表
3  Vector VL = null;         //计算恒力的中间变量
4  VL = fishschools.fishSchool.get(i).ConstantPosition
5   .cutGetforce(fishschools.fishSchool.get(i).position);
6  //得到从Position到ConstantPosition的的向量长度
7  Length = VL.Vectormodule();        //计算中间距离
8  if ((Length) >= Constant.SMinDistaces){
9   VL.getforce(Constant.ConstantForceScals / );  //距离远,恒力增加
10  }else if (Length<= 0.3){        //距离<阙值不产生力
11   VL.x = VL.y = VL.z = 0;
12  } else{
13   VL.getforce(Constant.ConstantForceScals);
14  }
15  float MediaLength = fishschools.fishSchool.get(i).force.Vectormodule();
16  if (Math.abs(MediaLength) == 0) {
17   // 把计算得到的恒力赋给恒力ConstantForce.
18   fishschools.fishSchool.get(i).ConstantForce.x = VL.x;  //x方向
19   fishschools.fishSchool.get(i).ConstantForce.y = VL.y;  //y方向
20   fishschools.fishSchool.get(i).ConstantForce.z = VL.z;  //z方向
21  } else {
22   // 把计算得到的恒力赋给恒力ConstantForce.
23   fishschools.fishSchool.get(i).ConstantForce.x = 0;
24   fishschools.fishSchool.get(i).ConstantForce.y = 0;
25   fishschools.fishSchool.get(i).ConstantForce.z = 0;
26 }}
27 //判断鱼和墙壁的碰撞
28 Vwall = new Vector(0, 0, 0);
29 if (fishschools.fishSchool.get(0).position.x <= ){Vwall.x = ;}
 //鱼与左墙壁的碰撞
30 if (fishschools.fishSchool.get(0).position.x >){ Vwall.x = ;}
 //鱼与右墙壁的碰撞
31 if (fishschools.fishSchool.get(0).position.y >= 7){ Vwall.y = ;}
 //鱼与上墙壁的碰撞
32 if (fishschools.fishSchool.get(0).position.y <= ) { Vwall.y = ;}
 //鱼与下墙壁的碰撞
33 if (fishschools.fishSchool.get(0).position.z < -15) { Vwall.z = ;}
 //鱼与后墙壁的碰撞
34 if (fishschools.fishSchool.get(0).position.z > 3) { Vwall.z = ; }
 //鱼与前墙壁的碰撞
35 fishschools.fishSchool.get(0).force.plus(Vwall);

第1~26行给离开鱼群的鱼赋予一个恒力。一旦这条鱼相对脱离了鱼群之后就会受到一个恒力使这条鱼游回鱼群,该条鱼游的距离鱼群越远这个恒力就会越大,从而使鱼群里面的鱼能够快速地回到鱼群,使鱼群一直是鱼群,不会被冲散。
第27~35行是鱼群里面第一条鱼与水族馆中的上墙壁、下墙壁、左墙壁、右墙壁、前墙壁及后墙壁的碰撞检测,碰撞时墙壁会对鱼群里面的第一条鱼产生力的作用,这样鱼群就会一直在鱼缸中游来游去。

2.7.4 鱼食移动线程类——FoodThread
上一小节详细介绍了对鱼群的移动线程控制类,读者已经了解了鱼群的移动方法。本小节将为读者详细介绍鱼食的移动线程类FoodThread,本小节中将着重为读者介绍鱼食的移动方法,以及对鱼食标志位的设置等,具体代码如下。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fishfood/目录下的FoodThread.java。

1 package wyf.lxg.fishfood;        //声明包名
2 ......//此处省略部分类和包的引入代码,读者可自行查阅随书光盘中的源代码
3 public class FoodThread extends Thread {     //定时运动食物的线程
4  public  boolean flag1 = true;      //线程的标志位
5  public boolean Fresit=true;     //食物y是否重置的标志位
6  boolean FxMove=true;       //移动x方向的标志位
7  public boolean Go=false;      //线程里面的算法是否走标志位
8  public  SingleFood SingleF;     //SingleFood对象的引用
9  public FoodThread(SingleFood singleF){
10   this.SingleF=singleF;     //实例化SingleFood对象
11  }
12  public void run(){
13   while (flag1) {
14    try {
15      if(Go){       //如果标志位为true
16        if(FxMove){      //食物晃动的标志位
17      SingleF.mv.Xposition+=Constant.FoodMove_X;
18       FxMove=!FxMove;    //标志位置反
19     }else{
20      SingleF.mv.Xposition-=Constant.FoodMove_X;
21      FxMove=!FxMove;     //标志位置反
22     }
23     SingleF.Ypositon-=Constant.FoodSpeed; //定时的修改Y坐标
24    }}
25    catch (Exception e) {     //异常处理
26     e.printStackTrace();     //打印异常
27    }try {
28     Thread.sleep(100);     //线程休眠
29    } catch (Exception e) {
30     e.printStackTrace();     //打印异常
31 }}}}

第4~11行是本类中一些标志位的初始化与本类中的构造。其中一些标志位的初始化有助于读者更加容易地理解本类中的逻辑关系,其构造器是拿到SingleFood类的引用,为后面调用其中鱼食的坐标做准备。
第12~31行是本类中鱼食移动的线程方法,本案例中的鱼食从上到下匀速运动,并且每次计算失误y轴所在的位置之前,会通过增加或减少食物的x、z坐标来使食物产生轻微的晃动效果,从而增加食物的真实感,让线程休眠100ms后刷新鱼食。

2.7.5 吸引力线程类——AttractThread
上一小节中介绍了食物的移动线程。本小节着重介绍鱼食对群鱼的吸引力线程类AttractThread,本案例中群鱼是可以看到鱼食的,但是鱼群看不到鱼食,所以鱼群不会受到食物吸引力的影响。本节将详细介绍这是如何操作的。

(1)下面将为读者重点介绍本类中鱼食对群鱼的吸引力的算法,并定时对每条鱼的吸引力进行刷新。每当鱼食落下的时候,如果某条鱼看到了鱼食,这条鱼就会朝鱼食游去,将鱼食吃掉,这样使百纳水族馆壁纸更加地真实逼真。具体代码如下。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fishfood/目录下的AttractThread.java。

1 package wyf.lxg.fishfood;       //声明包名
2 ......//此处省略部分类和包的引入代码,读者可自行查阅随书光盘中的源代码
3 public class AttractThread extends Thread {
4  ......//该处省略了部分变量与构造方法代码,读者可自行查阅随书光盘中的源代码
5  public void run() {
6    while (Feeding) {       //Feeding为永真
7      try {
8        if (Go) {        //添加能看到食物的鱼类列表
9      if (Fforcefish) {      //每次在点击喂食时要把列表清空
10     fl.clear();      //清空列表
11     Fforcefish = false;     //只清空一次
12       }
13       if (fl != null ) {
14          for (int i = 0; i < Sf.mv.fishAl.size(); i++) {//寻找满足条件的鱼
15     if (Sf.mv.fishAl.get(i).position.x > Sf.mv.Xposition
16      && Sf.mv.fishAl.get(i).speed.x < 0) {
17      if(!fl.contains(Sf.mv.fishAl.get(i))){//判断是否满足条件
18         fl.add(Sf.mv.fishAl.get(i));       //添加进列表
19      }}
20      else if (Sf.mv.fishAl.get(i).position.x < Sf.mv.Xposition
21           && Sf.mv.fishAl.get(i).speed.x > 0) {
22      if (!fl.contains(Sf.mv.fishAl.get(i))) {
23         fl.add(Sf.mv.fishAl.get(i));  //添加进列表
24     }}}}
25    if (fl.size() != 0) {    //给能看到食物的鱼加力的作用
26      for (int i = 0; i < fl.size(); i++) {
27     Vector VL = null;     //计算诱惑力的中间变量
28     Vector Vl2 = null;     //食物的位置信息
29     Vl2 = new Vector(Sf.mv.Xposition,
30         Sf.mv.singlefood.Ypositon, Sf.mv.Zposition);
31     VL = Vl2.cutPc(fl.get(i).position); //获取需要的向量
32     Length = VL.Vectormodule();   //吸引力的模长
33     if (Length != 0){VL.ChangeStep(Length);} //将力的大小规格化
34     if (Length <= Constant.FoodFeedDistance || Sf.Ypositon
35      < Constant.FoodPositionMin_Y) { //吃掉或者超过阈值
36      StopAllThread();
37     }
38     VL.getforce(Constant.AttractForceScals); //诱惑力的比例
39     fl.get(i).attractforce.x = VL.x;   //给诱惑恒力
40     fl.get(i).attractforce.y = VL.y;
41     fl.get(i).attractforce.z = VL.z;
42    }}}
43       if (Sf.Ypositon < Constant.FoodPositionMin_Y) {
44          StopAllThread();      //调用方法
45     }}
46    ......//该处省略了异常处理与线程休眠代码,读者可自行查阅随书光盘中的源代码
47  }}
48  ......//该处省略了StopAllThread()的 方法,将在下面介绍
49 }

第4行为省略掉的部分变量与构造方法代码。此代码中部分变量主要是设置线程标志位、设置清空标志位(每次喂食之前会清空列表f1)、是否计算食物吸引力的标志位。并创建受到食物吸引力的鱼列表。
第5~24行首先判断是否需要喂食。开启喂食后寻找能看到鱼食的鱼,每喂食一次清空受到吸引力的鱼列表f1,然后在喂食的时候重新寻找满足条件的鱼,如果满足条件把该条鱼添加到受到吸引力的鱼列表f1中。
第25~45行是开始喂食后,计算f1里面鱼受到食物吸引力的算法。能看到鱼食的鱼受到一个由该条鱼当前位置指向食物的吸引力的作用。这样当开始喂食时,一条鱼看到鱼食会自动地向鱼食游去,并将鱼食吃掉。
(2)上面介绍了当开始喂食时,如何寻找能够看到鱼食的鱼的算法,并介绍了如何操作当鱼看到鱼食后的游动问题。下面将为读者介绍如果鱼食被吃掉或者鱼食位置超过地面后,如何对鱼食进行操作的方法StopAllThread()。

代码位置:见随书光盘源代码/第2章/MyWallPaper/src/wyf/lxg/fishfood/目录下的AttractThread.java。

1 public void StopAllThread() {
2 Sf.Ypositon = Constant.FoodPositionMax_Y; //重置SingleY
3 this.Fforcefish = true; //清空受到吸引力的鱼列表
4 this.Go = false; //吸引力算法的标志位
5 Sf.Ft.Go = false; //食物移动的标志位
6 Constant.isFeed = true; //喂食的标志位
7 Sf.mv.Fooddraw = false; //绘制的标志位
8 }
第1~8行为StopAllThread方法,若鱼食位置超过地面,或者鱼食被鱼吃掉后,就会调用此方法,把鱼食移动线程里面的计算标志位和计算群鱼是否受到的食物吸引力标志位变为false,同时点击喂食的标志位设置为true,从而能点击屏幕在此喂食。

时间: 2024-09-14 23:39:13

《Android 应用案例开发大全(第3版)》——第2章,第2.7节线程相关类的相关文章

《Android 应用案例开发大全(第二版)》——2.7节线程相关类

2.7 线程相关类 Android 应用案例开发大全(第二版) 上一节详细介绍了绘制相关类,使读者对本案例的开发有了进一步的理解,在这一节将对线程相关类的开发进行详细介绍.前面已经完成了对水族馆背景及水族馆中鱼.鱼群和气泡绘制的开发,但是只是将鱼.鱼群.气泡绘制出来是远远不够的,还要让它们动起来,从而产生更加真实的效果. 本案例中启动了多个线程来定时刷新它们的位置.线程相关类主要包括气泡移动线程类.群鱼游动线程类.鱼群游动线程类.鱼食游动线程类和吸引力线程类,下面就对线程相关类的开发进行详细介绍

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

2.6 绘制相关类 Android 应用案例开发大全(第二版) 上一节完成了水族馆辅助绘制类开发过程的介绍,这一节将对本案例中的绘制相关类进行详细介绍.主要包括气泡绘制相关类.群鱼绘制相关类.鱼群绘制相关类和鱼食绘制相关类,从而使读者对本案例的开发有一个更加深刻的理解.下面就对这些绘制相关类进行详细介绍. 2.6.1 绘制气泡相关类 真实的水族馆中时常会冒出一些气泡,所以,在该壁纸中加入了透明气泡元素,从而达到仿真.酷炫的效果.最后本案例的运行效果是鱼在水族馆里面游,透明的气泡从屏幕下方不断冒出

《Android 应用案例开发大全(第二版)》——2.9节壁纸的优化与改进

2.9 壁纸的优化与改进 Android 应用案例开发大全(第二版) 本章对3D水族馆动态壁纸的开发进行了详细介绍,在学习过程中,重点掌握鱼游动过程中鱼旋转角度的算法,并掌握鱼和鱼之间作用力变化规律,鱼受到的墙壁作用力变化规律等. 动态壁纸界面的优化 没有哪一个案例的运行界面是不可以更加完美和绚丽的,所以,对本案例的界面.风格,读者可以自行根据自己的想法进行改进,使其更加完美,如水族馆地面.背景壁纸.水草类等的纹理图都可以进一步完善,从而达到一个更加理想的效果. 动态壁纸物理碰撞的优化 本案例物

《Android 应用案例开发大全(第二版)》——1.8节本章小结

1.8 本章小结Android 应用案例开发大全(第二版)本章首先介绍了Android的诞生及其特点,相信读者对Android开发平台已有所了解.本章中还介绍了Android开发环境的搭建以及用Android创建的第一个应用程序--Hello Android,通过该程序,读者应该对Android应用程序的开发步骤有所了解. 本章重点为读者介绍的是Android应用程序的详细调试方法.项目结构和系统架构,这些能够帮助读者进一步更深层次地了解Android.对于理论性的知识,读者只要先暂时有些概念,

《Android 应用案例开发大全(第二版)》——1.6节本书案例项目的导入

1.6 本书案例项目的导入 Android 应用案例开发大全(第二版) 1.6.1 导入并运行Android程序 前面已经对手机如何与Eclipse连接进行了详细讲解,本小节将介绍如何在Eclipse中导入项目,并在手机上运行已经写好的Android程序.本节将以导入本书第9章百纳理财专家为例进行详细讲解,具体步骤如下. 1.在Eclipse中导入项目 (1)启动Eclipse,依次选择"File/Import"将弹出导入项目的窗口Import,选择Existing Projects

《Android 应用案例开发大全(第二版)》——1.3节Android开发环境的搭建

1.3 Android开发环境的搭建 Android 应用案例开发大全(第二版) 本节主要讲解基于Eclipse的Android开发环境的搭建,模拟器的创建和运行,以及如何应用DDMS进行程序的调试. 1.3.1 Android SDK的安装及环境变量的配置 Android使用的编程语言是时下最流行的Java高级语言,Java的跨平台性和开源性,极大地促进了Android平台的发展. 首先要安装Java的JDK,并且正确地配置系统的环境变量(基于Windows操作系统).具体步骤如下. (1)

《Android 应用案例开发大全(第二版)》——2.1节案例背景及功能概述

2.1 案例背景及功能概述 Android 应用案例开发大全(第二版) 这一节将会对本案例背景及其基本功能进行简单介绍,通过本节学习,读者将会对本案例的具体功能及相应开发过程有一个整体了解,为读者进行以后的学习打下基础. 2.1.1 水族馆动态壁纸背景概述 壁纸是用户在手机屏幕上用来替代原先单一颜色背景的一张图片,有了这样一张图片可以使手机屏幕变得好看.漂亮.而随着移动手持设备功能的不断强大,静态壁纸已经不能再满足用户对酷炫壁纸的需求了,所以产生了动态壁纸. 动态壁纸是将手机屏幕所使用的壁纸以动

《Android 应用案例开发大全(第二版)》——2.2节壁纸策划及准备工作

2.2 壁纸策划及准备工作 Android 应用案例开发大全(第二版) 上一节介绍了本案例的背景及功能,本节将要介绍动态水族馆的策划以及开发前的准备工作.读者要认真阅读这一节,这对理解壁纸的开发有着很大的作用. 2.2.1 3D水族馆动态壁纸的策划 接下来将要对本案例的策划进行介绍,在以后的实际项目开发中,对项目的策划还需要更加地细致.具体.全面,该壁纸的策划如下所示. 动态水族馆. 本案例为3D水族馆动态壁纸,在该壁纸中有许多可以自由游动的鱼,点击该壁纸的地面可以给鱼喂食,壁纸前面还有透明的气

《Android 应用案例开发大全(第二版)》——2.4节壁纸的实现

2.4 壁纸的实现 Android 应用案例开发大全(第二版) 上一节介绍了壁纸的框架,让读者对壁纸的整体框架有了初步认识,本节将要对壁纸实现服务类GLWallpaperService.动态壁纸类LiveWallpaper.自定义渲染器类TDRender的开发进行详细介绍. 2.4.1 壁纸服务类--GLWallpaperService 该类是本项目中最基础的一个类,没有这个类就不可能使用壁纸这个功能.这个类为开发人员提供了壁纸服务,开发人员可以通过继承该类,重写此类中的方法来实现壁纸的后续开发

《Android 应用案例开发大全(第二版)》——1.4节 DDMS的灵活应用

1.4 DDMS的灵活应用 Android 应用案例开发大全(第二版) 作为一名合格的软件开发人员,必须要学会怎样去调试程序.因为调试是一个程序员最基本的技能,其重要性甚至超过学好一门语言.可以这样说,不会调试的程序员肯定不会有很好的发展. 那么什么是调试呢?所谓程序调试,是在软件投入实际使用前,用手工或编译程序等方法进行测试,修正语法错误和逻辑错误的过程.这是保证软件系统正确性的必不可少的步骤. Android为开发人员提供了一个强大的调试工具--DDMS,通过DDMS可以调试并监控程序的运行