重力感应,480*320分辨率,设计为3关,没用到游戏引擎,含有开始界面(开始、退出、声音、说明),游戏情节设计花费了很长时间,想尽量做到每一关都不同,游戏介绍:
游戏素材:玩家——中国歼十战斗机,敌机——日本二战期间飞机(自己PS了半天);
敌机种类:1.向玩家飞机移动
2.随机个数、随机路径(8种)移动
3.只向Y方向移动,模拟碉堡,散弹,打掉后出现换子弹精灵(2上子弹、3上子弹、5上子弹、螺旋向上子弹);
加血设定:设定加血精灵,每关出现由加血精灵排列而成的C、H、E、n、S、H、I、q、I、A、n、g的字母(ChenShiqiang)即为加血的,每一个加血精灵与玩家碰撞玩家血值加一,满100玩家生命数加一,生命数<=5;
关卡设定:每一关背景图片、背景音乐、敌机出现的频率、敌机生命值、敌机路径、boss生命值、加血字母出现频率、boss出现时间等设置不同,以boss死亡为通关标志(boss出现到死亡期间以vibrator模拟心跳效果),每一关通过都显示得分界面再进入下一关;
为了便于修改,屏幕分辨率、背景滚动的速度、GameView刷新频率、飞行路径等静态常量都放一个工具类里面。
游戏截图:
0、开始界面:
1、第一关
2、第二关
3、第三关
任务成功的图片就不传了,玩一盘游戏太费时了,玩不起啊玩不起。
背景音乐用MediaPlayer,
游戏各种音效用SoundPool(小容量(<1M),多个音频同时播放)
背景图片绘制:
int hight1 = 0;
int hight2 = -ConstantUtil.screenheight;
int w = ConstantUtil.screenweith;
int h = ConstantUtil.screenheight;
//背景循环显示,在GameView的Draw()方法里,不断刷新移动
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;
}
螺旋子弹实现:定义一段路径,轨迹片段通过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构造函数中有指定第几种敌机、指定路径和路径中起始点的参数。
算了,其余的程序全部贴上吧:
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; } }