我的雷电游戏(重力感应控制)

    算是第一个写的比较满意的游戏吧,肯定还有很多很多不足,希望高手能指点下,呵。现在在看图灵出版的一本android游戏的书籍,有点难,涉及底层有点多,都是JNI、NDK、linux shell脚本等,主要是将怎么将c(++)平台的游戏移植到android平台下。啥时候俺能移植了就牛X了。

游戏总介

重力感应,480*320分辨率,设计为3关,没用到游戏引擎,含有开始界面(开始、退出、声音、说明),游戏情节设计花费了很长时间,想尽量做到每一关都不同,游戏介绍:

 

游戏素材:玩家——中国歼十战斗机,敌机——日本二战期间飞机(自己PS了半天);

敌机种类1.向玩家飞机移动

        2.随机个数、随机路径(8种)移动

        3.只向Y方向移动,模拟碉堡,散弹,打掉后出现换子弹精灵(2上子弹、3上子弹、5上子弹、螺旋向上子弹);

加血设定:设定加血精灵,每关出现由加血精灵排列而成的CHEnSHIqIAng的字母(ChenShiqiang)即为加血的,每一个加血精灵与玩家碰撞玩家血值加一,满100玩家生命数加一,生命数<=5

关卡设定:每一关背景图片、背景音乐、敌机出现的频率、敌机生命值、敌机路径、boss生命值、加血字母出现频率、boss出现时间等设置不同,以boss死亡为通关标志(boss出现到死亡期间以vibrator模拟心跳效果),每一关通过都显示得分界面再进入下一关;

 

为了便于修改,屏幕分辨率、背景滚动的速度、GameView刷新频率、飞行路径等静态常量都放一个工具类里面。

 

 

 

游戏截图:

0、开始界面:

我的雷电游戏(重力感应控制)_第1张图片我的雷电游戏(重力感应控制)_第2张图片

1、第一关

我的雷电游戏(重力感应控制)_第3张图片  我的雷电游戏(重力感应控制)_第4张图片

我的雷电游戏(重力感应控制)_第5张图片  我的雷电游戏(重力感应控制)_第6张图片

  我的雷电游戏(重力感应控制)_第7张图片

我的雷电游戏(重力感应控制)_第8张图片 

  我的雷电游戏(重力感应控制)_第9张图片

2、第二关

  

我的雷电游戏(重力感应控制)_第10张图片 

我的雷电游戏(重力感应控制)_第11张图片  我的雷电游戏(重力感应控制)_第12张图片

 

3、第三关

我的雷电游戏(重力感应控制)_第13张图片  我的雷电游戏(重力感应控制)_第14张图片

我的雷电游戏(重力感应控制)_第15张图片  我的雷电游戏(重力感应控制)_第16张图片

任务成功的图片就不传了,玩一盘游戏太费时了,玩不起啊玩不起。

游戏模块介绍:

重力感应控制:

SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

注册:

mRegistedSensor = mSensorManager.registerListener(MainActivity.this, mSensor, SensorManager.SENSOR_DELAY_GAME);

取消注册:

if(mRegistedSensor)

{

      mSensorManager.unregisterListener(this);

      mRegistedSensor = false;

}

控制:(倾斜角度为ConstantUtil.accuracy有效)

 public void onSensorChanged(SensorEvent event) { if(event.sensor.getType()==Sensor.TYPE_ORIENTATION) { float ay = event.values[1];//正前负后 float az = event.values[2];//正左负右 if(ay>ConstantUtil.accuracy) { action = action | ConstantUtil.dir_up; Log.i("plane", "up "+ay+" "+az); } if(ay<-ConstantUtil.accuracy) { action = action | ConstantUtil.dir_down; Log.i("plane", "down "+ay+" "+az); } if(az>ConstantUtil.accuracy) { action = action | ConstantUtil.dir_left; Log.i("plane", "left "+ay+" "+az); } if(az<-ConstantUtil.accuracy) { action = action | ConstantUtil.dir_right; Log.i("plane", "right "+ay+" "+az); } if(ay<=ConstantUtil.accuracy & ay>=-ConstantUtil.accuracy & az<=ConstantUtil.accuracy & az>=-ConstantUtil.accuracy) { action = ConstantUtil.horizon; } } }

心跳效果:

Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);

long[] pattern = {800, 40,400, 30}; // OFF/ON/OFF/ON...

vibrator.vibrate(pattern, 2);//-1不重复,非-1为从pattern的指定下标开始重复

取消:

if(null!=vibrator)

{

       vibrator.cancel();

}

界面切换:ActivityonCreate方法里定义一个Handler来接受界面变换消息。

myhandler = new Handler() { public void handleMessage(android.os.Message msg) { switch(msg.what) { case 0://游戏失败 ContentView = null; System.gc(); ContentView = new FailView(MainActivity.this,MainActivity.this); setContentView(ContentView); break; case 1://进入第一关 ContentView = null; System.gc(); ContentView = new GameView(MainActivity.this, MainActivity.this, 1); setContentView(ContentView); mRegistedSensor = mSensorManager.registerListener(MainActivity.this, mSensor, SensorManager.SENSOR_DELAY_GAME); Log.i("plane", "mRegistedSensor "+mRegistedSensor); break; case 2://进入第二关 ContentView = null; System.gc(); ContentView = new GameView(MainActivity.this, MainActivity.this, 2); setContentView(ContentView); mRegistedSensor = mSensorManager.registerListener(MainActivity.this, mSensor, SensorManager.SENSOR_DELAY_GAME); break; case 3://进入第三关 ContentView = null; System.gc(); ContentView = new GameView(MainActivity.this, MainActivity.this, 3); setContentView(ContentView); mRegistedSensor = mSensorManager.registerListener(MainActivity.this, mSensor, SensorManager.SENSOR_DELAY_GAME); break; case 10://第一关结束 if(null!=vibrator){ vibrator.cancel(); } ContentView = null; System.gc(); ContentView = new LevelView(MainActivity.this, 1, msg.arg1, MainActivity.this); setContentView(ContentView); break; case 20://第二关结束 if(null!=vibrator){ vibrator.cancel(); } ContentView = null; System.gc(); ContentView = new LevelView(MainActivity.this, 2, msg.arg1, MainActivity.this); setContentView(ContentView); break; case 30://第三关结束 if(null!=vibrator){ vibrator.cancel(); } ContentView = null; System.gc(); ContentView = new LevelView(MainActivity.this, 3, msg.arg1, MainActivity.this); setContentView(ContentView); break; case 4://心跳效果 vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); long[] pattern = {800, 40,400, 30}; // OFF/ON/OFF/ON... vibrator.vibrate(pattern, 2);//-1不重复,非-1为从pattern的指定下标开始重复 break; case 5://欢迎,重新开始 ContentView = null; System.gc(); ContentView = new WelcomeView(MainActivity.this,MainActivity.this); setContentView(ContentView); break; default: break; } }; };

游戏声音:

背景音乐用MediaPlayer

游戏各种音效用SoundPool(小容量(<1M),多个音频同时播放)

 背景图片绘制:

int hight1 = 0;

int hight2 = -ConstantUtil.screenheight;

int w = ConstantUtil.screenweith;

int h = ConstantUtil.screenheight;

 

//背景循环显示,在GameViewDraw()方法里,不断刷新移动

Rect rectsrc = new Rect(0, 0, w, h);

Rect rectdst1 = new Rect(0, hight1, w, h+hight1);

Rect rectdst2 = new Rect(0, hight2, w, h+hight2);

canvas.drawBitmap(background, rectsrc, rectdst1, null);

canvas.drawBitmap(background, rectsrc, rectdst2, null);

hight1+=ConstantUtil.bgspan;

hight2+=ConstantUtil.bgspan;

if(hight1>h)

{

   hight1=-h;

}

if(hight2>h)

{

   hight2=-h;

}

碰撞检测:

//判断两个矩形是否碰撞,根据矩形重叠来判断

   private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight){//判断两个矩形是否碰撞

      int xd = 0;//大的x

      int yd = 0;//大大y

      int xx = 0;//小的x

      int yx = 0;//小的y

      int width = 0;

      int height = 0;

      boolean xFlag = true;//玩家飞机x是否在前

      boolean yFlag = true;//玩家飞机y是否在前

      if(this.x >= otherX){

        xd = this.x;

        xx = otherX;

        xFlag = false;

      }else{

        xd = otherX;

        xx = this.x;

        xFlag = true;

      }

      if(this.y >= otherY){

        yd = this.y;

        yx = otherY;

        yFlag = false;

      }else{

        yd = otherY;

        yx = this.y;

        yFlag = true;

      }

      if(xFlag == true){

        width = this.bitmap.getWidth();

      }else {

        width = otherWidth;

      }

      if(yFlag == true){

        height = this.bitmap.getHeight();

      }else{

        height = otherHeight;

      }

      if(xd>=xx&&xd<=xx+width-1&&

           yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠

          double Dwidth=width-xd+xx;   //重叠区域宽度   

        double Dheight=height-yd+yx; //重叠区域高度

        if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞

           return true;

        }

      }

      return false;

   } 

 

例:判断玩家是否与敌机碰撞

public boolean contain(EnemyPlane ep)   //敌机

   {

      if(isContain(ep.x, ep.y, ep.bitmap.getWidth(), ep.bitmap.getHeight()))

      {//检测成功

        blood-=20;//自己的生命减20

        return true;

      }

      return false;

   }

 

子弹类:构造函数里包含x位置, y位置, 子弹的类型,图片type, 子弹方向dir,以构造所有子弹

public class Bullet { int x,y;//子弹的坐标 int srcx,srcy; int dir;//子弹的方向,0静止,1上,2右上,3右,4右下,5下,6左下,7左,8左上,9左斜上,10右斜上,11旋转向上,12旋转向下 int type;//子弹的类型,图片 Bitmap bitmap;//当前子弹的图片 GameView gameView;//gameView的引用 int moveSpan = 15;//移动的像素 private boolean isAlive = true;//是否显示 int arcPathCount = 0; public Bullet(int x, int y, int type, int dir,GameView gameView) { this.x = x; this.y = y; this.srcx = x; this.srcy = y; this.type = type; this.dir = dir; this.gameView = gameView; initBitmap(); } public void initBitmap() { if(type == 1){//当类型为1时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.mybullet1); } else if(type == 2){//类型为2时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.mybullet2); } else if(type == 3){//类型为3时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.mybullet3); } else if(type == 4){//类型为4时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.ebullet1); } else if(type == 5){//类型为5时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.ebullet2); } else if(type == 6){//类型为6时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.ebullet3); } else if(type == 7){//类型为7时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.ebullet4); } else if(type == 8){//类型为8时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.bossbullet); } else if(type == 9){//类型为9时 bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.bossbullet2); } } public void draw(Canvas canvas)//绘制的方法 { canvas.drawBitmap(bitmap, x, y,null); } public void move()//移动的方法 { if(dir == 3){//向右移动 x += moveSpan; } if(dir == 7){//向左移动 x -= moveSpan; } if(dir == 1){//向上移动 y -= moveSpan; } if(dir == 5){//向下移动 y += moveSpan; } if(dir == 6){//向左下移动 x -= moveSpan; y += moveSpan; } if(dir == 8){//向左上移动 x -= moveSpan; y -= moveSpan; } if(dir == 2){//右上移动 x += moveSpan; y -= moveSpan; } if(dir == 4){//右下移动 x += moveSpan; y += moveSpan; } if(dir == 9){//左斜上移动 y -= moveSpan; x -=moveSpan/2; } if(dir == 10){//右斜上移动 y -= moveSpan; x +=moveSpan/2; } if(dir == 11){//旋转移动 if(arcPathCount==24) arcPathCount=0; x=(int) (srcx+ConstantUtil.arcpath[0][arcPathCount]); y=(int) (y-ConstantUtil.arcpath[1][arcPathCount]); arcPathCount++; } if(dir == 12){//旋转移动 if(arcPathCount==24) arcPathCount=0; x=(int) (srcx+ConstantUtil.arcpath[0][arcPathCount]); y=(int) (y+ConstantUtil.arcpath[1][arcPathCount]); arcPathCount++; } if(x<-20 | x>ConstantUtil.screenweith+20 | y<0 | y>ConstantUtil.screenheight) { this.setAlive(false); } } public boolean isAlive() { return isAlive; } public void setAlive(boolean isAlive) { this.isAlive = isAlive; } }

 

螺旋子弹实现:定义一段路径,轨迹片段通过sin(x)实现。想了半天,似乎没有回旋的函数,只能这样了。

public static double[][] arcpath =

{     {Math.sin(Math.PI/16)*50,Math.sin(Math.PI*2/16)*50,Math.sin(Math.PI*3/16)*50,Math.sin(Math.PI*4/16)*50,Math.sin(Math.PI*5/16)*50,Math.sin(Math.PI*6/16)*50,Math.sin(Math.PI*7/16)*50,Math.sin(Math.PI*8/16)*50,Math.sin(Math.PI*9/16)*50,Math.sin(Math.PI*10/16)*50,Math.sin(Math.PI*11/16)*50,Math.sin(Math.PI*12/16)*50,Math.sin(Math.PI*13/16)*50,Math.sin(Math.PI*14/16)*50,Math.sin(Math.PI*15/16)*50,Math.sin(Math.PI*16/16)*50,Math.sin(Math.PI*18/16)*50,Math.sin(Math.PI*20/16)*50,Math.sin(Math.PI*22/16)*50,Math.sin(Math.PI*24/16)*50,Math.sin(Math.PI*26/16)*50,Math.sin(Math.PI*28/16)*50,Math.sin(Math.PI*30/16)*50,Math.sin(Math.PI*32/16)*50},

   {10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,-10,-10,-10,-10,-10,-10,-10,-10},

};

 

加血模块:思路是定义各个字母数组以存储各个加血精灵的位置,到指定时间生成字母加血精灵组,然后整体向下移动。

敌机随机路径实现:定义数组存储路径,数组中存放路径中每个“站点”的步数,生成第二种敌机时可指定敌机从第几点开始移动。

//飞行路径

   public static int[][] pathA =         //右左

   {  

      {-120,-80, -40,   0, 320, -30},//路径中每个点的X坐标

      {-10, 0 ,  30,  30, 200, 350},//路径中每个点的Y坐标

      {7  , 7 ,   7,  40,  40,   0},//路径中两点间的步数

   };

  

   public static int[][] pathB =         //左右

   {

      {420,400, 360, 320, -20, 350},//路径中每个点的X坐标

      {-10,0 ,  15,  30, 200, 350},//路径中每个点的Y坐标

      {7  , 7 ,   7,  40,  40,   0},//路径中两点间的步数

   };

  

   public static int[][] pathC =         //

   {

      {420,400, 360, 320, -20},//路径中每个点的X坐标

      {-10, 0 ,  15,  30, 450},//路径中每个点的Y坐标

      {7  , 7 ,   7,  80,  0},//路径中两点间的步数

   };

  

   public static int[][] pathD =         //

   {

      {-50 ,-40, -30, -20, 320},//路径中每个点的X坐标

      {-10 , 0 ,  15,  30, 450},//路径中每个点的Y坐标

      {7   , 7 ,  7 ,  80,  0 },//路径中两点间的步数

   };

  

   public static int[][] pathE =         //右左右

   {  

      {-100,-80, -40,   0, 320, -30 ,320},//路径中每个点的X坐标

      { -10 ,0 ,  30,  30, 245, 245 ,400},//路径中每个点的Y坐标

      { 7   ,7 ,   7,  40,  40,  40 , 0 },//路径中两点间的步数

   };

  

   public static int[][] pathF =         //左右左

   {  

      {400 ,360, 340,  320, -20, 320 ,-20},//路径中每个点的X坐标

      {-10 , 0 ,  30,   30, 245, 245 ,400},//路径中每个点的Y坐标

      {7   , 7 ,   7,  40,  40,   40 , 0 },//路径中两点间的步数

   };

 

在敌机EnemyPlane构造函数中有指定第几种敌机、指定路径和路径中起始点的参数。

 

算了,其余的程序全部贴上吧:

我的雷电游戏(重力感应控制)_第17张图片

ConstantUtil.java

public class ConstantUtil { //屏幕分辨率 public static final int screenheight = 480; public static final int screenweith = 320; //背景滚动的速度 public static final int bgspan = 5; //重力感应方向 public static final int dir_up = 0x1; public static final int dir_down = 0x2; public static final int dir_left = 0x4; public static final int dir_right = 0x8; public static final int horizon = 0x10; //方向判定的精度,倾斜10度 public static final float accuracy = 10.0f; //玩家子弹发射频率,GameView循环几次发一次子弹 public static final int fireSet = 4; //玩家飞机走一步的像素 public static final int myplanespan = 10; //GameView刷新频率,毫秒 public static final int gameviewRefresh = 100; //敌机出现的频率,gameviewRefresh的倍数 public static final int Enemy1fre1 = 30;//第一关 //无路径 3s 3s 2s public static final int Enemy2fre1 = 60; //有路径 6 5 5 public static final int Enemy3fre1 = 150; //Y移动 15 21 27 public static final int Enemy1fre2 = 30;//第二关 public static final int Enemy2fre2 = 50; public static final int Enemy3fre2 = 210; public static final int Enemy1fre3 = 20;//第三关 public static final int Enemy2fre3 = 50; public static final int Enemy3fre3 = 270; //每关3种敌机的生命值 public static final int Enemy1life1 = 6;//第一关 public static final int Enemy2life1 = 4; public static final int Enemy3life1 = 8; public static final int Enemy1life2 = 8;//第二关 public static final int Enemy2life2 = 6; public static final int Enemy3life2 = 10; public static final int Enemy1life3 = 10;//第三关 public static final int Enemy2life3 = 8; public static final int Enemy3life3 = 12; //加血字母出现频率 public static final int addBloodFre1 = 100;//10s public static final int addBloodFre2 = 170;//17s public static final int addBloodFre3 = 220;//22s //boss出现时间,及各关通关时间,单位秒 public static final int time1 = 150; //2.5分钟 public static final int time2 = 210; //3.5分钟 public static final int time3 = 270; //4.5分钟 //每一关boss生命值 public static final int bosslife1 = 200; public static final int bosslife2 = 300; public static final int bosslife3 = 500; //飞行路径 public static int[][] pathA = //右左 { {-120,-80, -40, 0, 320, -30},//路径中每个点的X坐标 {-10, 0 , 30, 30, 200, 350},//路径中每个点的Y坐标 {7 , 7 , 7, 40, 40, 0},//路径中两点间的步数 }; public static int[][] pathB = //左右 { {420,400, 360, 320, -20, 350},//路径中每个点的X坐标 {-10,0 , 15, 30, 200, 350},//路径中每个点的Y坐标 {7 , 7 , 7, 40, 40, 0},//路径中两点间的步数 }; public static int[][] pathC = //左 { {420,400, 360, 320, -20},//路径中每个点的X坐标 {-10, 0 , 15, 30, 450},//路径中每个点的Y坐标 {7 , 7 , 7, 80, 0},//路径中两点间的步数 }; public static int[][] pathD = //右 { {-50 ,-40, -30, -20, 320},//路径中每个点的X坐标 {-10 , 0 , 15, 30, 450},//路径中每个点的Y坐标 {7 , 7 , 7 , 80, 0 },//路径中两点间的步数 }; public static int[][] pathE = //右左右 { {-100,-80, -40, 0, 320, -30 ,320},//路径中每个点的X坐标 { -10 ,0 , 30, 30, 245, 245 ,400},//路径中每个点的Y坐标 { 7 ,7 , 7, 40, 40, 40 , 0 },//路径中两点间的步数 }; public static int[][] pathF = //左右左 { {400 ,360, 340, 320, -20, 320 ,-20},//路径中每个点的X坐标 {-10 , 0 , 30, 30, 245, 245 ,400},//路径中每个点的Y坐标 {7 , 7 , 7, 40, 40, 40 , 0 },//路径中两点间的步数 }; public static double[][] arcpath = { {Math.sin(Math.PI/16)*50,Math.sin(Math.PI*2/16)*50,Math.sin(Math.PI*3/16)*50,Math.sin(Math.PI*4/16)*50,Math.sin(Math.PI*5/16)*50,Math.sin(Math.PI*6/16)*50,Math.sin(Math.PI*7/16)*50,Math.sin(Math.PI*8/16)*50, Math.sin(Math.PI*9/16)*50,Math.sin(Math.PI*10/16)*50,Math.sin(Math.PI*11/16)*50,Math.sin(Math.PI*12/16)*50,Math.sin(Math.PI*13/16)*50,Math.sin(Math.PI*14/16)*50,Math.sin(Math.PI*15/16)*50,Math.sin(Math.PI*16/16)*50, Math.sin(Math.PI*18/16)*50,Math.sin(Math.PI*20/16)*50,Math.sin(Math.PI*22/16)*50,Math.sin(Math.PI*24/16)*50,Math.sin(Math.PI*26/16)*50,Math.sin(Math.PI*28/16)*50,Math.sin(Math.PI*30/16)*50,Math.sin(Math.PI*32/16)*50}, {10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,-10,-10,-10,-10,-10,-10,-10,-10}, }; public static int[][] addbloodsCpath = { { 100,110,120,130,140,150,160,170,180,190,200,210,220, //1,17 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,100,100,100,100,100,100,100,100,100,100,100,100,//5 100,110,120,130,140,150,160,170,180,190,200,210,220 //4 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//5 0,0,0,0,0,0,0,0,0,0,0,0,0//4 }, }; public static int[][] addbloodsHpath = { { 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,100,100,100,100,100,100,100,100,100,100,100,100,//5 100,110,120,130,140,150,160,170,180,190,200,210,220, //7 220,220,220,220,220,220,220,220,220,220,220,220,220, //2 220,220,220,220,220,220,220,220,220,220,220,220,220 //3 }, { -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//5 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,//7 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//2 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0//3 }, }; public static int[][] addbloodsEpath = { { 100,110,120,130,140,150,160,170,180,190,200,210,220, //1 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,100,100,100,100,100,100,100,100,100,100,100,100,//5 100,110,120,130,140,150,160,170,180,190,200,210,220, //4 100,110,120,130,140,150,160,170,180,190,200,210,220 //7 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//5 0,0,0,0,0,0,0,0,0,0,0,0,0//4 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120//7 }, }; public static int[][] addbloodsNpath = { { 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,100,100,100,100,100,100,100,100,100,100,100,100,//5 100,110,120,130,140,150,160,170,180,190,200,210,220, //1 220,220,220,220,220,220,220,220,220,220,220,220,220, //2 220,220,220,220,220,220,220,220,220,220,220,220,220 //3 }, { -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//5 -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//2 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0//3 }, }; public static int[][] addbloodsSpath = //1,6,7,3,4 { { 100,110,120,130,140,150,160,170,180,190,200,210,220,//1 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,110,120,130,140,150,160,170,180,190,200,210,220, //7 220,220,220,220,220,220,220,220,220,220,220,220,220, //3 100,110,120,130,140,150,160,170,180,190,200,210,220 //4 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,//7 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//3 0,0,0,0,0,0,0,0,0,0,0,0,0//4 }, }; public static int[][] addbloodsIpath = //5,6 { { 160,160,160,160,160,160,160,160,160,160,160,160,160, 160,160,160,160,160,160,160,160,160,160,160,160,160 }, { -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120, -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0 }, }; public static int[][] addbloodsQpath = //1,2,3,6,7, { { 100,110,120,130,140,150,160,170,180,190,200,210,220,//1 220,220,220,220,220,220,220,220,220,220,220,220,220, //2 220,220,220,220,220,220,220,220,220,220,220,220,220, //3 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,110,120,130,140,150,160,170,180,190,200,210,220 //7 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//2 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//3 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120//7 }, }; public static int[][] addbloodsApath = //1,2,3,5,6,7 { { 100,110,120,130,140,150,160,170,180,190,200,210,220,//1 220,220,220,220,220,220,220,220,220,220,220,220,220, //2 220,220,220,220,220,220,220,220,220,220,220,220,220, //3 100,100,100,100,100,100,100,100,100,100,100,100,100,//5 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,110,120,130,140,150,160,170,180,190,200,210,220 //7 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//2 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//3 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//5 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120//7 }, }; public static int[][] addbloodsGpath = //1,2,3,4,6,7 { { 100,110,120,130,140,150,160,170,180,190,200,210,220,//1 220,220,220,220,220,220,220,220,220,220,220,220,220, //2 220,220,220,220,220,220,220,220,220,220,220,220,220, //3 100,110,120,130,140,150,160,170,180,190,200,210,220, //4 100,100,100,100,100,100,100,100,100,100,100,100,100,//6 100,110,120,130,140,150,160,170,180,190,200,210,220 //7 }, { -240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,-240,//1 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//2 -120,-110,-100,-90,-80,-70,-60,-50,-40,-30,-20,-10,0,//3 0,0,0,0,0,0,0,0,0,0,0,0,0//4 -240,-230,-220,-210,-200,-190,-180,-170,-160,-150,-140,-130,-120,//6 -120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120,-120//7 }, }; }

WelcomeView.java

public class WelcomeView extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener { Context context; MainActivity mainactivity; boolean loop = true; Bitmap startbg; Bitmap startgame; Bitmap exit; Bitmap sound; Bitmap opensound; Bitmap closesound; Bitmap help; int w,h; SurfaceHolder sh; int sdir = ConstantUtil.screenheight; int span = ConstantUtil.screenheight/96; SoundPool soundpool; int soundstart; Paint paint; public WelcomeView(Context context,MainActivity mainactivity) { super(context); this.context = context; this.mainactivity = mainactivity; sh = getHolder(); sh.addCallback(this); soundpool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100); paint = new Paint(); paint.setColor(Color.RED); paint.setTextSize(24); paint.setAntiAlias(true); setFocusable(true); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { Log.i("welcome", "welcome surfaceCreated"); new Thread(this).start(); } public void surfaceDestroyed(SurfaceHolder holder) { } public void Draw() { Log.i("welcome", "welcome "+sdir); Canvas canvas = sh.lockCanvas(); Rect src = null,dst = null; if(sdir==0) { sdir = -1; soundpool.stop(soundstart); soundpool.release(); soundpool = null; System.gc(); canvas.drawBitmap(startgame,40,40,null); canvas.drawBitmap(exit,ConstantUtil.screenweith-40-exit.getWidth(),40,null); canvas.drawBitmap(sound,40,ConstantUtil.screenheight-40-sound.getHeight(),null); canvas.drawBitmap(help,ConstantUtil.screenweith-40-help.getWidth(),ConstantUtil.screenheight-40-help.getHeight(),null); this.setOnTouchListener(this); } else if(sdir == -1) { canvas.drawBitmap(startbg, new Rect(0, 0, w, h), new Rect(0, 0, ConstantUtil.screenweith, ConstantUtil.screenheight), null); canvas.drawBitmap(startgame,40,40,null); canvas.drawBitmap(exit,ConstantUtil.screenweith-40-exit.getWidth(),40,null); canvas.drawBitmap(sound,40,ConstantUtil.screenheight-40-sound.getHeight(),null); canvas.drawBitmap(help,ConstantUtil.screenweith-40-help.getWidth(),ConstantUtil.screenheight-40-help.getHeight(),null); canvas.drawText("游戏作者:陈士强", 50, 200, paint); canvas.drawText("2011年6月于深圳尚观", 40, 240, paint); canvas.drawText("作者联系方式:", 10, 280, paint); canvas.drawText("QQ 1565184212", 45, 320, paint); } else if(sdir>0) { src = new Rect(0, 0, w, h); dst = new Rect(0, sdir, ConstantUtil.screenweith, sdir+ConstantUtil.screenheight); canvas.drawBitmap(startbg, src, dst, paint); sdir-=span; } sh.unlockCanvasAndPost(canvas); } public void run() { startbg = BitmapFactory.decodeResource(getResources(), R.drawable.startbg); w = startbg.getWidth(); h = startbg.getHeight(); startgame = BitmapFactory.decodeResource(getResources(), R.drawable.startgame); exit = BitmapFactory.decodeResource(getResources(), R.drawable.exit); opensound = BitmapFactory.decodeResource(getResources(), R.drawable.opensound); sound = opensound; closesound = BitmapFactory.decodeResource(getResources(), R.drawable.closesound); help = BitmapFactory.decodeResource(getResources(), R.drawable.help); soundstart = soundpool.load(getContext(), R.raw.gamestart, 1); try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } AudioManager mgr = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE); float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC); float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC); float volume = streamVolumeCurrent / streamVolumeMax; soundpool.play(soundstart, volume/2, volume/2, 1, 0, 2.0f); while(loop) { try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Draw(); } } public boolean onTouch(View v, MotionEvent event) { if(event.getX()>40 & event.getX()<40+startgame.getWidth() & event.getY()>40 & event.getY()<40+startgame.getHeight()) { Log.i("welcome", "onTouch start"); this.loop = false; try { Thread.sleep(60); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Message message = new Message(); message.what = 1; mainactivity.myhandler.sendMessage(message); } if(event.getX()>ConstantUtil.screenweith-40-exit.getWidth() & event.getX()<ConstantUtil.screenweith-40 & event.getY()>40 & event.getY()<40+exit.getHeight()) { Log.i("welcome", "onTouch exit"); this.loop = false; try { Thread.sleep(60); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mainactivity.finish(); } if(event.getX()>40 & event.getX()<40+sound.getWidth() & event.getY()>ConstantUtil.screenheight-40-sound.getHeight() & event.getY()<ConstantUtil.screenheight-40) { Log.i("welcome", "onTouch sound"); if(sound.equals(opensound)) { sound = closesound; mainactivity.sound = false; } else { sound = opensound; mainactivity.sound = true; } } if(event.getX()>ConstantUtil.screenweith-40-help.getWidth() & event.getX()<ConstantUtil.screenweith-40 & event.getY()>ConstantUtil.screenheight-40-help.getHeight() & event.getY()<ConstantUtil.screenheight-40) { Log.i("welcome", "onTouch help"); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("游戏说明:") .setMessage("重力感应游戏:/n手机前、后、左、右倾斜(>10度),对应飞机前、后、左、右移动"); builder.create().show(); } return true; } }

GameView.java

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable { MyPlane myplane; MainActivity mainactivity; SurfaceHolder sh; boolean loop = true; int loopNum = 0;//循环计数 int time =0;//时间,单位秒 float volume; SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);//小容量(<1M)多个音频同时播放 //时间图片 Bitmap[] timeBitmap = new Bitmap[10]; //显示生命数的图片 Bitmap lifeBitmap = BitmapFactory .decodeResource(this.getResources(), R.drawable.life); //爆炸图片 Bitmap exploredBitmap = BitmapFactory .decodeResource(this.getResources(), R.drawable.explored); Paint paint; int level;//关数 //每关都需设置的参数 Bitmap background; //背景图片 int sounddead,soundbossfire;//soundID MediaPlayer soundbg;//背景音乐 int enemy1fre,enemy2fre,enemy3fre;//敌机出现的频率 int enemy1life,enemy2life,enemy3life;//敌机生命值 int[][] path1,path2,path3,path4;//敌机路径 int bosslife;//boss生命值 int addBloodFre;//加血字母出现频率 int bosstime;//boss出现时间 Boss boss = null; //集合 ArrayList<Bullet> enemyBullets = new ArrayList<Bullet>(); ArrayList<Bullet> myBullets = new ArrayList<Bullet>(); ArrayList<EnemyPlane> EnemyPlanes = new ArrayList<EnemyPlane>(); ArrayList<ChangeBullet> changeBullets = new ArrayList<ChangeBullet>(); ArrayList<Addblood> addbloods = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsC = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsH = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsE = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsN = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsS = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsI = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsQ = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsA = new ArrayList<Addblood>(); ArrayList<Addblood> addbloodsG = new ArrayList<Addblood>(); //随机数 Random rand = new Random(); public GameView(Context context,MainActivity mainactivity,int level) { super(context); sh = this.getHolder(); sh.addCallback(this); this.mainactivity = mainactivity; this.level = level; } public void surfaceCreated(SurfaceHolder holder) { init(); myplane = new MyPlane(mainactivity,this); new Thread(this).start(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceDestroyed(SurfaceHolder holder) { myplane.setLoop(false); this.loop = false; try { Thread.sleep(110); } catch (InterruptedException e) { e.printStackTrace(); } mainactivity.getmSensorManager().unregisterListener(mainactivity); mainactivity.setmRegistedSensor(false); } //根据关数初始化 public void init() { switch(level) { case 1: //背景 background = BitmapFactory .decodeResource(this.getResources(), R.drawable.back_img1); soundbg = MediaPlayer.create(getContext(), R.raw.bg1); //敌机出现频率 enemy1fre = ConstantUtil.Enemy1fre1; enemy2fre = ConstantUtil.Enemy2fre1; enemy3fre = ConstantUtil.Enemy3fre1; //敌机生命值 enemy1life=ConstantUtil.Enemy1life1; enemy2life=ConstantUtil.Enemy2life1; enemy3life=ConstantUtil.Enemy3life1; //敌机路径 path1 = ConstantUtil.pathA; path2 = ConstantUtil.pathB; path3 = ConstantUtil.pathC; path4 = ConstantUtil.pathD; //boss生命值 bosslife = ConstantUtil.bosslife1; //加血字母出现频率 addBloodFre = ConstantUtil.addBloodFre1; //boss出现时间 bosstime = ConstantUtil.time1; break; case 2: //背景 background = BitmapFactory .decodeResource(this.getResources(), R.drawable.back_img2); soundbg = MediaPlayer.create(mainactivity, R.raw.bg2); //敌机出现频率 enemy1fre = ConstantUtil.Enemy1fre2; enemy2fre = ConstantUtil.Enemy2fre2; enemy3fre = ConstantUtil.Enemy3fre2; //敌机生命值 enemy1life=ConstantUtil.Enemy1life2; enemy2life=ConstantUtil.Enemy2life2; enemy3life=ConstantUtil.Enemy3life2; //敌机路径 path1 = ConstantUtil.pathA; path2 = ConstantUtil.pathB; path3 = ConstantUtil.pathC; path4 = ConstantUtil.pathD; //boss生命值 bosslife = ConstantUtil.bosslife2; //加血字母出现频率 addBloodFre = ConstantUtil.addBloodFre2; //boss出现时间 bosstime = ConstantUtil.time2; break; case 3: //背景 background = BitmapFactory .decodeResource(this.getResources(), R.drawable.back_img3); soundbg = MediaPlayer.create(mainactivity, R.raw.bg3); //敌机出现频率 enemy1fre = ConstantUtil.Enemy1fre3; enemy2fre = ConstantUtil.Enemy2fre3; enemy3fre = ConstantUtil.Enemy3fre3; //敌机生命值 enemy1life=ConstantUtil.Enemy1life3; enemy2life=ConstantUtil.Enemy2life3; enemy3life=ConstantUtil.Enemy3life3; //敌机路径 path1 = ConstantUtil.pathC; path2 = ConstantUtil.pathD; path3 = ConstantUtil.pathE; path4 = ConstantUtil.pathF; //boss生命值 bosslife = ConstantUtil.bosslife3; //加血字母出现频率 addBloodFre = ConstantUtil.addBloodFre3; //boss出现时间 bosstime = ConstantUtil.time3; break; default: break; } } int hight1 = 0; int hight2 = -ConstantUtil.screenheight; int w = ConstantUtil.screenweith; int h = ConstantUtil.screenheight; public void Draw() { Canvas canvas = sh.lockCanvas(); //判断是否产生敌机 if(time < bosstime & loopNum%enemy1fre==0) { EnemyPlanes.add(new EnemyPlane(rand.nextInt(300), 0, 0, null, 1, enemy1life, 12, this)); } if(time < bosstime & loopNum%enemy2fre==0) { int whichpath = rand.nextInt(4)+1; switch(whichpath) //随机路径1-4 { case 1: for(int i = rand.nextInt(4)+1;i>0;--i) //随机个数1-4 { EnemyPlanes.add(new EnemyPlane(0, 0, i, path1, 2, enemy2life, 14, this)); } break; case 2: for(int i = rand.nextInt(4)+1;i>0;--i) //随机个数1-4 { EnemyPlanes.add(new EnemyPlane(0, 0, i, path2, 2, enemy2life, 14, this)); } break; case 3: for(int i = rand.nextInt(4)+1;i>0;--i) //随机个数1-4 { EnemyPlanes.add(new EnemyPlane(0, 0, i, path3, 2, enemy2life, 14, this)); } break; case 4: for(int i = rand.nextInt(4)+1;i>0;--i) //随机个数1-4 { EnemyPlanes.add(new EnemyPlane(0, 0, i, path4, 2, enemy2life, 16, this)); } break; } } if(time < bosstime & loopNum%enemy3fre==0) { EnemyPlanes.add(new EnemyPlane(rand.nextInt(300), 0, 0, null, 3, enemy3life, 12, this)); } //是否产生boss if(time > bosstime & boss == null) { boss = new Boss(60, -100, level, this); Message ms = new Message(); ms.what = 4; mainactivity.myhandler.sendMessage(ms); } //判断是否产生加血字母 switch(loopNum/addBloodFre) { case 0: addbloods=addbloodsC; break; case 1: addbloods=addbloodsH; break; case 2: addbloods=addbloodsE; break; case 3: addbloods=addbloodsN; break; case 4: addbloods=addbloodsS; break; case 5: addbloods=addbloodsH; break; case 6: addbloods=addbloodsI; break; case 7: addbloods=addbloodsQ; break; case 8: addbloods=addbloodsI; break; case 9: addbloods=addbloodsA; break; case 10: addbloods=addbloodsN; break; case 11: addbloods=addbloodsG; break; default: break; } if(myplane.blood<0) {//当血值小于0时 if(mainactivity.lifes>0) { mainactivity.lifes--; myplane.blood=100; myplane.setX(ConstantUtil.screenweith/2-myplane.bitmap.getWidth()/2); myplane.setY(ConstantUtil.screenheight-30); } else { Message ms = new Message(); ms.what = 0;//游戏失败 mainactivity.myhandler.sendMessage(ms); } } if(myplane.blood>100) {//当血值大于100时 myplane.blood=myplane.blood-100; if(mainactivity.lifes<5) mainactivity.lifes++; } //背景循环显示 Rect rectsrc = new Rect(0, 0, w, h); Rect rectdst1 = new Rect(0, hight1, w, h+hight1); Rect rectdst2 = new Rect(0, hight2, w, h+hight2); canvas.drawBitmap(background, rectsrc, rectdst1, null); canvas.drawBitmap(background, rectsrc, rectdst2, null); hight1+=ConstantUtil.bgspan; hight2+=ConstantUtil.bgspan; if(hight1>h) { hight1=-h; } if(hight2>h) { hight2=-h; } //画关数、得分、玩家生命值、血值、时间等 canvas.drawText("level : "+level, 10, 15, paint); canvas.drawText("score: "+myplane.score, 10, 35, paint); int h = time/100; int t = time%100/10; int o = time%10; canvas.drawBitmap(timeBitmap[h], 100, 10, null); canvas.drawBitmap(timeBitmap[t], 115, 10, null); canvas.drawBitmap(timeBitmap[o], 130, 10, null); canvas.drawText("lifes :", 180, 15, paint); int dir = 220; for(int i = 0;i<mainactivity.lifes;++i) { canvas.drawBitmap(lifeBitmap, dir, 5, null); dir+=15; } canvas.drawText("blood:", 180, 35, paint); paint.setColor(Color.YELLOW); canvas.drawRect(220, 26, 320, 34, paint); paint.setColor(Color.RED); canvas.drawLine(220, 30, 220+myplane.blood, 30, paint); //画加血字母 for(int i = addbloods.size()-1;i>=0;--i) { if(!addbloods.get(i).isAlive()) addbloods.remove(i); else { addbloods.get(i).draw(canvas); addbloods.get(i).move(); } } //画敌机 for(int x = EnemyPlanes.size()-1;x>=0;x--) { Log.i("life", ""+EnemyPlanes.get(x).life); if(EnemyPlanes.get(x).life<=0) //生命值<=0,不存活 { EnemyPlanes.get(x).setAlive(false); myplane.score++; soundPool.play(sounddead, volume/5, volume/5, 1, 0, 1f);//播放 if(EnemyPlanes.get(x).type==3) changeBullets.add(new ChangeBullet(EnemyPlanes.get(x).x, EnemyPlanes.get(x).y, rand.nextInt(3)+2, this)); } if(EnemyPlanes.get(x).isAlive)//是否存活 { EnemyPlanes.get(x).draw(canvas); //是否发子弹 if(EnemyPlanes.get(x).fireCount==EnemyPlanes.get(x).firefre) { EnemyPlanes.get(x).fire(); EnemyPlanes.get(x).fireCount=0; } //是否与子弹碰撞 for(int y = myBullets.size()-1;y>=0;y--) { if(EnemyPlanes.get(x).contain(myBullets.get(y), this)) { myBullets.get(y).setAlive(false); EnemyPlanes.get(x).life--; canvas.drawBitmap(exploredBitmap, myBullets.get(y).x-exploredBitmap.getWidth()/2, myBullets.get(y).y-exploredBitmap.getHeight()/2, paint); } } EnemyPlanes.get(x).fireCount++; EnemyPlanes.get(x).move(); } else { EnemyPlanes.remove(x); } } //画玩家 if(myplane!=null) { myplane.draw(canvas); //是否发子弹 if(loopNum%ConstantUtil.fireSet==0) myplane.fire(); //碰撞,加血 for(int j = addbloods.size()-1;j>=0;j--) { if(myplane.contain(addbloods.get(j))) { addbloods.get(j).setAlive(false); myplane.blood++; } } //碰撞,敌机子弹 for(int i = enemyBullets.size()-1;i>=0;i--) { if(myplane.contain(enemyBullets.get(i))) { enemyBullets.get(i).setAlive(false); myplane.blood-=10; canvas.drawBitmap(exploredBitmap, enemyBullets.get(i).x-exploredBitmap.getWidth()/2, enemyBullets.get(i).y-exploredBitmap.getHeight()/2, paint); } } //碰撞,敌机 for(int i = EnemyPlanes.size()-1;i>=0;i--) { if(myplane.contain(EnemyPlanes.get(i))) { EnemyPlanes.get(i).setAlive(false); myplane.blood-=20; canvas.drawBitmap(exploredBitmap, EnemyPlanes.get(i).x, EnemyPlanes.get(i).y, paint); } } //碰撞,变子弹 for(int i = changeBullets.size()-1;i>=0;i--) { if(myplane.contain(changeBullets.get(i))) { changeBullets.get(i).setAlive(false); myplane.bulletstyle = changeBullets.get(i).type; } } } //画boss if(boss !=null) { paint.setColor(Color.GRAY); canvas.drawRect(310, 120, 318, 320, paint); paint.setColor(Color.RED); canvas.drawLine(314, 120, 314, 120+200*boss.life/bosslife, paint); boss.draw(canvas); boss.fire(); boss.move(); for(int i = myBullets.size()-1;i>=0;--i) //中弹 { if(boss.contain(myBullets.get(i), this)) { myBullets.get(i).setAlive(false); boss.life--; canvas.drawBitmap(exploredBitmap, myBullets.get(i).x-exploredBitmap.getWidth()/2, myBullets.get(i).y-exploredBitmap.getHeight()/2, paint); } } if(boss.life<0) { soundbg.setLooping(false); soundbg.stop(); Message ms = new Message(); switch (level) { case 1: ms.what = 10; break; case 2: ms.what = 20; break; case 3: ms.what = 30; break; default: break; } ms.arg1 = myplane.score; mainactivity.myhandler.sendMessage(ms); myplane.score+=100; } } //画子弹 for(int i = myBullets.size()-1;i>0;--i) { if(!myBullets.get(i).isAlive()) myBullets.remove(i); else { myBullets.get(i).draw(canvas); myBullets.get(i).move(); } //Log.i("myBullets.size()", ""+myBullets.size()); } for(int i = enemyBullets.size()-1;i>0;--i) { if(!enemyBullets.get(i).isAlive()) enemyBullets.remove(i); else { enemyBullets.get(i).draw(canvas); enemyBullets.get(i).move(); } //Log.i("enemyBullets.size()", ""+enemyBullets.size()); } //画加血字母 for(int i = changeBullets.size()-1;i>=0;--i) { if(!changeBullets.get(i).isAlive()) changeBullets.remove(i); else { changeBullets.get(i).draw(canvas); changeBullets.get(i).move(); } } sh.unlockCanvasAndPost(canvas); } public void run() { timeBitmap[0] = BitmapFactory.decodeResource(getResources(), R.drawable.number0); timeBitmap[1] = BitmapFactory.decodeResource(getResources(), R.drawable.number1); timeBitmap[2] = BitmapFactory.decodeResource(getResources(), R.drawable.number2); timeBitmap[3] = BitmapFactory.decodeResource(getResources(), R.drawable.number3); timeBitmap[4] = BitmapFactory.decodeResource(getResources(), R.drawable.number4); timeBitmap[5] = BitmapFactory.decodeResource(getResources(), R.drawable.number5); timeBitmap[6] = BitmapFactory.decodeResource(getResources(), R.drawable.number6); timeBitmap[7] = BitmapFactory.decodeResource(getResources(), R.drawable.number7); timeBitmap[8] = BitmapFactory.decodeResource(getResources(), R.drawable.number8); timeBitmap[9] = BitmapFactory.decodeResource(getResources(), R.drawable.number9); sounddead = soundPool.load(getContext(), R.raw.dead, 1); soundbossfire = soundPool.load(getContext(), R.raw.bossball, 1); try { Thread.sleep(200); } catch (InterruptedException e2) { e2.printStackTrace(); } AudioManager mgr = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE); float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC); float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);//设置最大音量 volume = streamVolumeCurrent/streamVolumeMax; //设备的音量 for(int i=0;i<ConstantUtil.addbloodsCpath[0].length;++i) { addbloodsC.add(new Addblood(ConstantUtil.addbloodsCpath[0][i], ConstantUtil.addbloodsCpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsHpath[0].length;++i) { addbloodsH.add(new Addblood(ConstantUtil.addbloodsHpath[0][i], ConstantUtil.addbloodsHpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsEpath[0].length-1;++i)//?????????????????-1 { addbloodsE.add(new Addblood(ConstantUtil.addbloodsEpath[0][i], ConstantUtil.addbloodsEpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsNpath[0].length;++i) { addbloodsN.add(new Addblood(ConstantUtil.addbloodsNpath[0][i], ConstantUtil.addbloodsNpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsSpath[0].length;++i) { addbloodsS.add(new Addblood(ConstantUtil.addbloodsSpath[0][i], ConstantUtil.addbloodsSpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsIpath[0].length;++i) { addbloodsI.add(new Addblood(ConstantUtil.addbloodsIpath[0][i], ConstantUtil.addbloodsIpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsQpath[0].length;++i) { addbloodsQ.add(new Addblood(ConstantUtil.addbloodsQpath[0][i], ConstantUtil.addbloodsQpath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsApath[0].length;++i) { addbloodsA.add(new Addblood(ConstantUtil.addbloodsApath[0][i], ConstantUtil.addbloodsApath[1][i], this)); } for(int i=0;i<ConstantUtil.addbloodsGpath[0].length-1;++i)//?????????????????? { addbloodsG.add(new Addblood(ConstantUtil.addbloodsGpath[0][i], ConstantUtil.addbloodsGpath[1][i], this)); } paint = new Paint(); paint.setColor(Color.RED); paint.setAntiAlias(true); new Thread(myplane).start(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } soundbg.setVolume(volume, volume); soundbg.setLooping(true); try { soundbg.prepare(); } catch (IllegalStateException e1) { e1.printStackTrace(); } catch (IOException e1) { } soundbg.start(); while(loop) { try { Thread.sleep(ConstantUtil.gameviewRefresh); } catch (InterruptedException e) { e.printStackTrace(); } Draw(); loopNum++; time=loopNum/10; } } }

LevelView.java

public class LevelView extends View implements Runnable,OnTouchListener { int level;//第几关的 int score;//得分 MainActivity mainactivity; Bitmap bitmap; Paint paint; public LevelView(Context context, int level, int score, MainActivity mainactivity) { super(context); this.level = level; this.score = score; this.mainactivity = mainactivity; paint = new Paint(); paint.setColor(Color.RED); paint.setTextSize(20); paint.setAntiAlias(true); switch(level) { case 1: bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.level1); break; case 2: bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.level2); break; case 3: bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.level3); break; } new Thread(this).start(); setFocusable(true); } boolean loop = true; int i = 0; protected void onDraw(Canvas canvas) { if(level==1 | level==2) { if(i<=score) { canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText("得分: "+i, 100, 240, paint); } else if(i<=score+30 & i>score) { canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText("得分: "+score, 100, 240, paint); canvas.drawText("即将进入下一关...... ", 80, 330, paint); } else { loop = false; Message ms = new Message(); ms.what = level+1; mainactivity.myhandler.sendMessage(ms); } } else { if(i<=score) { canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText("得分: "+i, 100, 240, paint); } else { canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText("得分: "+score, 100, 240, paint); canvas.drawLine(0, 430, 320, 430, paint); canvas.drawLine(160, 430, 160, 480, paint); canvas.drawText("重新开始 ", 35, 460, paint); canvas.drawText("退出程序 ", 205, 460, paint); loop=false; try { Thread.sleep(100); } catch (InterruptedException e) { } this.setOnTouchListener(this); } } super.onDraw(canvas); } public void run() { while(loop) { postInvalidate(); if(i<=score) { try { Thread.sleep(10); } catch (InterruptedException e) { } } else { try { Thread.sleep(100); } catch (InterruptedException e) { } } ++i; } } public boolean onTouch(View v, MotionEvent event) { if(event.getX()>0 & event.getX()<150 & event.getY()>430 & event.getY()<480) { Message message = new Message(); message.what = 5; mainactivity.myhandler.sendMessage(message); } if(event.getX()>170 & event.getX()<320 & event.getY()>430 & event.getY()<480) { mainactivity.finish(); } return true; } }

FailView.java

public class FailView extends View implements Runnable { Paint paint; MainActivity mainactivity; int n = 5; public FailView(Context context,MainActivity mainactivity) { super(context); this.mainactivity = mainactivity; paint = new Paint(); paint.setColor(Color.RED); paint.setTextSize(20); paint.setAntiAlias(true); new Thread(this).start(); } protected void onDraw(Canvas canvas) { canvas.drawText("任务失败!", 120, 200, paint); canvas.drawText(""+n, 150, 240, paint); canvas.drawText("即将回到开始界面", 80, 280, paint); } public void run() { while(n>0) { n--; postInvalidate(); try { Thread.sleep(1000); } catch (InterruptedException e) { } } Message message = new Message(); message.what = 5; mainactivity.myhandler.sendMessage(message); } }

MyPlane.java

public class MyPlane extends Thread { MainActivity mainactivity; private int x,y;//坐标 private int w,h;//宽高 int blood = 100;//生命值100 Bitmap bitmap;//飞机图片 private int span = ConstantUtil.myplanespan;//飞机走一步的像素 GameView gameView; private boolean loop; int bulletstyle;//子弹类型 boolean alive; int score = 0;//得分 public MyPlane( MainActivity mainactivity,GameView gameView) { this.gameView = gameView; this.mainactivity = mainactivity; bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.myplane); this.x = ConstantUtil.screenweith/2-bitmap.getWidth()/2; this.y = ConstantUtil.screenheight-150; this.w = bitmap.getWidth(); this.h = bitmap.getHeight(); alive = true; loop = true; bulletstyle = 1; } public void draw(Canvas canvas) { canvas.drawBitmap(bitmap, x, y, null); } //移动 public void move(int dx,int dy) { x+=dx; y+=dy; } //打子弹的方法 public void fire() { switch(bulletstyle) { case 1: gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-9, y-bitmap.getHeight(), 2, 1, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+3, y-bitmap.getHeight(), 2, 1, gameView)); break; case 2: gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-11, y-bitmap.getHeight(), 3, 1, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+5, y-bitmap.getHeight(), 3, 1, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-11, y-bitmap.getHeight(), 3, 9, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+5, y-bitmap.getHeight(), 3, 10, gameView)); break; case 3: gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-11, y-bitmap.getHeight(), 3, 1, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+5, y-bitmap.getHeight(), 3, 1, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-11, y-bitmap.getHeight(), 3, 8, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+5, y-bitmap.getHeight(), 3, 2, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-11, y-bitmap.getHeight(), 3, 9, gameView)); gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2+5, y-bitmap.getHeight(), 3, 10, gameView)); break; case 4: gameView.myBullets.add(new Bullet(x+bitmap.getWidth()/2-9, y-bitmap.getHeight(), 3, 11, gameView)); break; default: break; } } //判定碰撞 public boolean contain(Bullet b) //子弹 { if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())) {//检测成功 blood-=10;;//自己的血值减10 return true; } return false; } public boolean contain(ChangeBullet b) //变子弹 { if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())) {//检测成功 return true; } return false; } public boolean contain(Addblood b) //加血 { if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())) {//检测成功 blood+=1;;//自己的血值加1 return true; } return false; } public boolean contain(EnemyPlane ep) //敌机 { if(isContain(ep.x, ep.y, ep.bitmap.getWidth(), ep.bitmap.getHeight())) {//检测成功 blood-=20;//自己的生命减20 return true; } return false; } //判断两个矩形是否碰撞 private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight){//判断两个矩形是否碰撞 int xd = 0;//大的x int yd = 0;//大大y int xx = 0;//小的x int yx = 0;//小的y int width = 0; int height = 0; boolean xFlag = true;//玩家飞机x是否在前 boolean yFlag = true;//玩家飞机y是否在前 if(this.x >= otherX){ xd = this.x; xx = otherX; xFlag = false; }else{ xd = otherX; xx = this.x; xFlag = true; } if(this.y >= otherY){ yd = this.y; yx = otherY; yFlag = false; }else{ yd = otherY; yx = this.y; yFlag = true; } if(xFlag == true){ width = this.bitmap.getWidth(); }else { width = otherWidth; } if(yFlag == true){ height = this.bitmap.getHeight(); }else{ height = otherHeight; } if(xd>=xx&&xd<=xx+width-1&& yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠 double Dwidth=width-xd+xx; //重叠区域宽度 double Dheight=height-yd+yx; //重叠区域高度 if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞 return true; } } return false; } //线程 public void run() { while(loop) { if((mainactivity.getAction()&ConstantUtil.dir_left)==ConstantUtil.dir_left) { if(x>=-w/2+span) this.move(-span, 0); } if((mainactivity.getAction()&ConstantUtil.dir_right) == ConstantUtil.dir_right) { if(x<=ConstantUtil.screenweith-w/2-span) this.move(+span, 0); } if((mainactivity.getAction()&ConstantUtil.dir_up) == ConstantUtil.dir_up) { if(y>=span) this.move(0, -span); } if((mainactivity.getAction()&ConstantUtil.dir_down) == ConstantUtil.dir_down) { if(y<=ConstantUtil.screenheight-h-span) this.move(0, +span); } if(mainactivity.getAction() == ConstantUtil.horizon) { } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //getter and setter public boolean isLoop() { return loop; } public void setLoop(boolean loop) { this.loop = loop; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }

EnemyPlane.java

public class EnemyPlane { int x,y;//坐标 int start;//在路径的第几点 int[][] path;//运行路径 int step;//步数 int type;//敌机类型,图片 1:跟着敌机走,单子弹 2:随机路径,随机多少,单子弹 3:X轴不变,3子弹,出变子弹 GameView gameView;//gameView的引用 Bitmap bitmap; int life;//生命值 int firefre;//发子弹频率 int fireCount = 0;//发子弹计数 boolean isAlive = true; public EnemyPlane(int x, int y, int start,int[][] path, int type, int life ,int firefre ,GameView gameView) { this.start = start; this.path = path; this.type = type; this.life = life; this.firefre = firefre; this.gameView = gameView; if(path!=null) { this.x = path[0][start-1]; this.y = path[1][start-1]; this.step = path[2][start-1]; }else { this.x = x; this.y = y; } switch(type) { case 1: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.e1); break; case 2: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.e2); break; case 3: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.e3); break; default: break; } } public void draw(Canvas canvas) { canvas.drawBitmap(bitmap, x, y, null); } public void move() { if(path!=null) { if(step==0)//一段路径走完 { if(start<path[0].length-1) { start++; step = path[2][start-1]; } else { this.setAlive(false); } } else//一段路径未走完 { int xSpan=(path[0][start]-path[0][start-1])/path[2][start-1]; int ySpan=(path[1][start]-path[1][start-1])/path[2][start-1]; x+=xSpan; y+=ySpan; step--; } }else { if(type==1) { if(x<gameView.myplane.getX()) x+=3; //未设置路径的X位移 else x-=3; y+=10; //未设置路径的Y位移 } else if(type==3) { y+=4; } if(y>ConstantUtil.screenheight) this.setAlive(false); } } public void fire()//打子弹的方法 { if(fireCount==firefre) { fireCount=0; if(type==3)//第三种敌机,散弹 { gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 7, 5, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 7, 4, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 7, 6, gameView)); } else if(type==2)//其余,单子弹 { gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 5, 5, gameView)); } else if(type==1) { gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 6, 5, gameView)); } } } //判断两个矩形是否碰撞 private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight) { int xd = 0;//大的x int yd = 0;//大大y int xx = 0;//小的x int yx = 0;//小的y int width = 0; int height = 0; boolean xFlag = true;//玩家飞机x是否在前 boolean yFlag = true;//玩家飞机y是否在前 if(this.x >= otherX){ xd = this.x; xx = otherX; xFlag = false; }else{ xd = otherX; xx = this.x; xFlag = true; } if(this.y >= otherY){ yd = this.y; yx = otherY; yFlag = false; }else{ yd = otherY; yx = this.y; yFlag = true; } if(xFlag == true){ width = this.bitmap.getWidth(); }else{ width = otherWidth; } if(yFlag == true){ height = this.bitmap.getHeight(); }else{ height = otherHeight; } if(xd>=xx&&xd<=xx+width-1&& yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠 double Dwidth=width-xd+xx; //重叠区域宽度 double Dheight=height-yd+yx; //重叠区域高度 if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞 return true; } } return false; } public boolean contain(Bullet b,GameView gameView) {//判断子弹是否打中敌机 if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())) { this.life--;//自己的生命减1 return true; } return false; } public boolean isAlive() { return isAlive; } public void setAlive(boolean isAlive) { this.isAlive = isAlive; } }

ChangeBullet.java

public class ChangeBullet { int x,y;//子弹的坐标 int type;//子弹的类型,图片 Bitmap bitmap;//当前子弹的图片 GameView gameView;//gameView的引用 private boolean isAlive = true;//是否显示 Random rand = new Random(); public ChangeBullet(int x, int y, int type, GameView gameView) { this.x = x; this.y = y; this.type = type; this.gameView = gameView; switch(type) { case 2: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.change3); break; case 3: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.change5); break; case 4: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.change8); break; } } public void draw(Canvas canvas)//绘制的方法 { canvas.drawBitmap(bitmap, x, y,null); } public void move()//移动的方法 { x+=rand.nextInt()%10; y+=rand.nextInt()%15; if(x<0 | x>ConstantUtil.screenweith | y<0 | y>ConstantUtil.screenheight) { this.setAlive(false); } } public boolean isAlive() { return isAlive; } public void setAlive(boolean isAlive) { this.isAlive = isAlive; } }

Addblood.java

public class Addblood { int x,y;//坐标 Bitmap bitmap;//图片 GameView gameView;//gameView的引用 int moveSpan = 8;//移动的像素 private boolean isAlive = true;//是否显示 public Addblood(int x, int y, GameView gameView) { this.x = x; this.y = y; this.gameView = gameView; bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.addlife); } public void draw(Canvas canvas)//绘制的方法 { canvas.drawBitmap(bitmap, x, y,null); } public void move()//移动的方法 { y+=moveSpan; if(y>ConstantUtil.screenheight) this.setAlive(false); } public boolean isAlive() { return isAlive; } public void setAlive(boolean isAlive) { this.isAlive = isAlive; } }

Boss.java

public class Boss { int x,y;//坐标 int level;//第几关 Bitmap bitmap;//图片 int life;//生命值 float firefre;//发子弹频率 GameView gameView;//gameView的引用 public Boss(int x, int y, int level, GameView gameView) { this.x = x; this.y = y; this.level = level; this.gameView = gameView; switch(level) { case 1: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.boss1); life = ConstantUtil.bosslife1; firefre = 0.1f; break; case 2: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.boss2); life = ConstantUtil.bosslife2; firefre = 0.2f; break; case 3: bitmap = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.boss3); life = ConstantUtil.bosslife3; firefre = 0.3f; break; default: break; } } public void draw(Canvas canvas) { canvas.drawBitmap(bitmap, x, y, null); } public void fire()//打子弹的方法 { switch(level) { case 1: if(Math.random()<firefre) { gameView.soundPool.play(gameView.soundbossfire, gameView.volume, gameView.volume, 1, 0, 1f);//播放 gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 4, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 5, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 6, gameView)); } break; case 2: if(Math.random()<firefre) { gameView.soundPool.play(gameView.soundbossfire, gameView.volume, gameView.volume, 1, 0, 1f);//播放 gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 4, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 5, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 6, gameView)); } break; case 3: if(Math.random()<firefre) { gameView.soundPool.play(gameView.soundbossfire, gameView.volume, gameView.volume, 1, 0, 1f);//播放 gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 4, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 5, gameView)); gameView.enemyBullets.add(new Bullet(x+bitmap.getWidth()/2, y+bitmap.getHeight(), 8, 6, gameView)); } break; default: break; } } public void move() { if(x+bitmap.getWidth()/2>gameView.myplane.getX()) { x-=2; } else { x+=2; } if(y<100) { y+=3; } } //判断两个矩形是否碰撞 private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight) { int xd = 0;//大的x int yd = 0;//大大y int xx = 0;//小的x int yx = 0;//小的y int width = 0; int height = 0; boolean xFlag = true;//玩家飞机x是否在前 boolean yFlag = true;//玩家飞机y是否在前 if(this.x >= otherX){ xd = this.x; xx = otherX; xFlag = false; }else{ xd = otherX; xx = this.x; xFlag = true; } if(this.y >= otherY){ yd = this.y; yx = otherY; yFlag = false; }else{ yd = otherY; yx = this.y; yFlag = true; } if(xFlag == true){ width = this.bitmap.getWidth(); }else{ width = otherWidth; } if(yFlag == true){ height = this.bitmap.getHeight(); }else{ height = otherHeight; } if(xd>=xx&&xd<=xx+width-1&& yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠 double Dwidth=width-xd+xx; //重叠区域宽度 double Dheight=height-yd+yx; //重叠区域高度 if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞 return true; } } return false; } public boolean contain(Bullet b,GameView gameView) {//判断子弹是否打中敌机 if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())) { this.life--;//自己的生命减1 return true; } return false; } }

 

你可能感兴趣的:(游戏,null,Class,action,Path,float)