1.整体实现思路
答:实现飞机大战的简单思路:
①要先建MySurfaceView这个类,在这个类中绘制画布,有画布的高度和宽度,还有画笔,然后在这个建好的画布上开始继续“作画”画布利用了canvas实现,画笔利用paint实现。
②然后将飞机大战的部分闯关背景“画”上画布,实现绘图操作,利用多线程的方法,调用runable方法并用stater启动子线程。记得解锁画布,显示到屏幕上。
③选择背景图片,建立BackGround类,利用两张相同背景图片利用if循环语句实现背景图片的移动。并在MySurfaceView中调用。
④建立Myplane和BossPlane类,利用if语句和for循环和onTouchEvent和isCollision和noisCollision和noisCollisioncount等实现飞机的飞行移动,并可以实现屏幕触摸,还创建hp,来实现飞机血量的减少。还要利用isCrazy,time,count实现boss飞机的疯狂模式时间。并在MySurfaceView中调用。
⑤创建子弹Bullet的类,利用get set方法,以及if语句实现子弹的移动速度和击中飞机范围。最后要移除子弹,减少内存负荷。并在MySurfaceView中调用。
⑥创建Boom类,利用clipRect裁剪图片以及totalFrame来实现爆炸现象,currenFrame用来显示当前显示的第几幅画。最后记得结束爆炸。并在MySurfaceView中调用。
⑦添加结束游戏输赢的图片,利用SoundPool,switch语句实现,利用RectF完成图片的大小与屏幕吻合,还有调用GAEM_STATE和switch在MySurfaceView中调用实现图片的运用。
2.如何实现循环滚动的背景图片
答:利用两张相同背景图片,画好背景图片的坐标即大小,利用if语句判断实现两张图片的循环滚动。
代码:
package com.example.jinxin.myapplication; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; /** * Created by lenovo64 */ public class BackGround { private int y1; private int y2; private Bitmap bitmap ; public BackGround( Bitmap bitmap){ this.bitmap = bitmap; y1 = 0; y2 = y1 - bitmap.getHeight(); } public void draw(Canvas canvas,Paint paint){ logic(); canvas.drawBitmap(bitmap,0,y1,paint); canvas.drawBitmap(bitmap,0,y2,paint); } public void logic(){ y1+=5; y2+=5; if (y1>MySurfaceView.height){ y1 = y2 - bitmap.getHeight();//移动到第二张图片的顶部 } if (y2>MySurfaceView.height){ y2 = y1 - bitmap.getHeight(); } } }
3.如何绘制飞机
答:建立Myplane和BossPlane类,利用if语句和for循环和onTouchEvent和isCollision和noisCollision和noisCollisioncount等实现飞机的飞行移动,并可以实现屏幕触摸,还创建hp,来实现飞机血量的减少。还要利用isCrazy,time,count实现boss飞机的疯狂模式时间。并在MySurfaceView中调用。
代码:
MyPlane:
package com.example.jinxin.myapplication; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.YuvImage; import android.util.Log; import android.view.MotionEvent; public class MyPlane { private Bitmap bitmap; private int x, y; private static int width, height; private int fx; private boolean noCollision; private int noCollisionCount;//碰撞计数器 private Bitmap bitmapHp; private int hp = 3; public MyPlane(Bitmap bitmap, Bitmap bitmapHp) { this.bitmap = bitmap; x = MySurfaceView.width / 2 - bitmap.getWidth() / 2; y = MySurfaceView.height - bitmap.getHeight(); width = bitmap.getWidth(); height = bitmap.getHeight(); this.bitmapHp = bitmapHp; } public void draw(Canvas canvas, Paint paint) { if (hp<=0){ MySurfaceView.GAME_STATE =3; } if (noCollision) { noCollisionCount++; if (noCollisionCount % 10 == 0) { Log.e("&&&&&", "****"); canvas.drawBitmap(bitmap, x, y, paint);//飞机闪烁 } if (noCollisionCount > 100) {//无敌时间 noCollision = false; noCollisionCount = 0; } } else { //非无敌状态 canvas.drawBitmap(bitmap, x, y, paint); } for (int i = 0; i < hp; i++) { canvas.drawBitmap(bitmapHp, i * bitmapHp.getWidth(), MySurfaceView.height - bitmapHp.getHeight(), paint); } } public void touchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_MOVE) { float ex = event.getX(); float ey = event.getY(); if (ex > x && ex < x + width && ey > y && ey < y + height) { x = (int) ex - width / 2; y = (int) ey - height / 2; if (y < 0) { y = 0; } if (y + height > MySurfaceView.height) { y = MySurfaceView.height - height; } } if (x < 0) { x = 0; } if (x + width > MySurfaceView.width) { y = MySurfaceView.width - width; } } } public boolean isCollision(Bullet bullet) { if (noCollision) { return false; } else { if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) { Log.e("***", "------------------"); noCollision = true; if (hp > 0) { hp--; } return true; } } return false; } public boolean isCollision(BossPlane bossPlane) { if (noCollision) { return false; } else { if (bossPlane.getY() + bossPlane.getFrameH() > y && bossPlane.getY() + bossPlane.getFrameH() < y + height) { if (x < bossPlane.getX() && x + width > bossPlane.getX()) { Log.e("AAAAAAAAAa", "isCollision: ..................................."); noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width < bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width > bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } } } return false; } public int getX() { return x; } public int getY() { return y; } public int getWidth() { return width; } }
BossPlane:
package com.example.jinxin.myapplication; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.util.Log; public class BossPlane { private Bitmap bitmap; private int x, y; private int frameW, frameH; private int speed = 10; private int count;//计数器 private int time = 100;//疯狂模式间隔时间 private boolean isCrazy; private int crazySpeed = 50; private int bossHp = 10; public BossPlane(Bitmap bitmap) { this.bitmap = bitmap; this.frameW = bitmap.getWidth() / 10; this.frameH = bitmap.getHeight(); x = MySurfaceView.width / 2 - frameW / 2; } public void draw(Canvas canvas, Paint paint) { canvas.save(); canvas.clipRect(x, y, x + frameW, y + frameH); canvas.drawBitmap(bitmap, x, y, paint); canvas.restore(); logic(); } public void logic() { count++; //疯狂模式 if (isCrazy) { y = y + crazySpeed; crazySpeed--; if (y == 0) { isCrazy = false; crazySpeed = 50; } } else { if (count % time == 0) { isCrazy = true; } x = x + speed; if (x > MySurfaceView.width - frameW) { speed = -speed; } if (x < 0) { speed = -speed; } } } public boolean isCollision(Bullet bullet) { if (bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()<x+frameW&&bullet.getY()>y&&bullet.getY()<y+frameH){ bossHp--; bullet.setDead(true);//设置子弹状态,碰撞后修改子弹状态为dead,从数组中移除 if (bossHp<0){ MySurfaceView.GAME_STATE =2; } return true; } return false; } public int getX() { return x; } public int getY() { return y; } public int getFrameW() { return frameW; } public int getFrameH() { return frameH; } }
4.如何绘制子弹
答:创建子弹Bullet的类,利用get set方法,以及if语句实现子弹的移动速度和击中飞机范围。最后要移除子弹,减少内存负荷。
代码:
package com.example.jinxin.myapplication; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; public class Bullet { private Bitmap bitmap; private int x,y; private int speed =10; public boolean isDead; private int type; public Bullet(Bitmap bitmap,int x,int y,int type){ this.bitmap = bitmap; this.x = x; this.y = y; this.type = type; } public void draw(Canvas canvas, Paint paint){ canvas.drawBitmap(bitmap,x,y,paint); logic(); } public void logic(){ switch (type){ case 0: y-=speed; if (y<0){ isDead = true; } break; case 1: y+=speed+5; if (y>MySurfaceView.height){ isDead = true; } break; } } public int getX() { return x; } public int getY() { return y; } public boolean isDead() { return isDead; } public void setDead(boolean dead) { isDead = dead; } public Bitmap getBitmap() { return bitmap; } }
5.如何判断碰撞
飞机与子弹的碰撞
public boolean isCollision(Bullet bullet) { if (noCollision) { return false; } else { if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) { Log.e("***", "------------------"); noCollision = true; if (hp > 0) { hp--; } return true; } } return false; }
飞机与飞机的碰撞:
public boolean isCollision(BossPlane bossPlane) { if (noCollision) { return false; } else { if (bossPlane.getY() + bossPlane.getFrameH() > y && bossPlane.getY() + bossPlane.getFrameH() < y + height) { if (x < bossPlane.getX() && x + width > bossPlane.getX()) { Log.e("AAAAAAAAAa", "isCollision: ..................................."); noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width < bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width > bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } } } return false; }
6.如何绘制爆炸效果:
答:创建Boom类,利用clipRect裁剪图片以及totalFrame来实现爆炸现象,currenFrame用来显示当前显示的第几幅画。最后记得结束爆炸。
代码:
package com.example.jinxin.myapplication; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; public class Boom { private int totalFrame; private Bitmap bitmap; private int x,y; private int currenFrame;//当前显示的第几幅画面 private int frameW; private int frameH; private boolean isEnd; public Boom(Bitmap bitmap, int x, int y,int totalFrame) { this.bitmap = bitmap; this.x = x; this.y = y; this.totalFrame = totalFrame; frameW = bitmap.getWidth()/totalFrame; frameH = bitmap.getHeight(); } public void draw(Canvas canvas, Paint paint){ canvas.save(); canvas.clipRect(x,y,x+frameW,y+frameH); canvas.drawBitmap(bitmap,x-currenFrame*frameW,y,paint); canvas.restore(); logic(); } public void logic(){ if (currenFrame<totalFrame){ currenFrame++; }else { isEnd = true; } } public boolean isEnd(){ return isEnd; } }
7.如何添加音效:
利用MediaPlayer来实现
MediaPlayer mediaPlayer = null; mediaPlayer = MediaPlayer.create(getContext(),R.raw.bgm_zhuxuanlv); mediaPlayer.setLooping(true); mediaPlayer.start(); Paint paint = new Paint();
8.哪些地方用到封装,继续,多态,方法的重载,接口等。
运用到封装的地方为(代码):
封装就是把对象的信息和内部逻辑的结构隐藏起来。在MySurfaceView,Bullet,MyPlane,BossPlane,Boom,GameSounPool几个类中都用到了,如下:
MySurfaceView
public static int height; private SurfaceHolder surfaceHolder; private Canvas canvas;//绘制图形的画布 private boolean isDrawing = true;//标志位 public static int width; private MyPlane plane; //Vector是线程安全的,ArrayList是非线程安全的 private Vector<Bullet> bulletVector = new Vector<>(); private Vector<Bullet> bossbulletVector = new Vector<>(); private Vector<Boom>boomVector = new Vector<>(); private int count; private BossPlane bossPlane; private GameSoundPool gameSoundPool; public static int GAME_STATE = 4; private MediaPlayer mediaPlayer;BossPlane
private Bitmap bitmap; private int x, y; private int frameW, frameH; private int speed = 10; private int count;//计数器 private int time = 100;//疯狂模式间隔时间 private boolean isCrazy; private int crazySpeed = 50;MyPlane
private Bitmap bitmap; private int x, y; private static int width, height; private int fx; private boolean noCollision; private int noCollisionCount;//碰撞计数器 private Bitmap bitmapHp; private int hp = 3;Bullet
private Bitmap bitmap; private int x,y; private int speed =10; public boolean isDead; private int type;GameSounPool
private SoundPool soundPool; private int s1; private int s2;
Boom
private int totalFrame; private Bitmap bitmap; private int x,y; private int currenFrame;//当前显示的第几幅画面 private int frameW; private int frameH; private boolean isEnd;
方法的重载:两个或多个方法名一样,参数列表不一样。(代码)
MySurfaceView
@Override public void surfaceCreated(SurfaceHolder holder) { new Thread(this).start();//启动子线程 height = getHeight(); width = getWidth(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { isDrawing = false; }
BossPlane
public BossPlane(Bitmap bitmap) { this.bitmap = bitmap; this.frameW = bitmap.getWidth() / 10; this.frameH = bitmap.getHeight(); x = MySurfaceView.width / 2 - frameW / 2; } public boolean isCollision(Bullet bullet) { if (bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()<x+frameW&&bullet.getY()>y&&bullet.getY()<y+frameH){ bossHp--; bullet.setDead(true);//设置子弹状态,碰撞后修改子弹状态为dead,从数组中移除 if (bossHp<0){ MySurfaceView.GAME_STATE =2; } return true; } return false;
public void draw(Canvas canvas, Paint paint) { canvas.save(); canvas.clipRect(x, y, x + frameW, y + frameH); canvas.drawBitmap(bitmap, x, y, paint); canvas.restore(); logic(); }
MyPlane
public void draw(Canvas canvas, Paint paint) { if (hp<=0){ MySurfaceView.GAME_STATE =3; } if (noCollision) { noCollisionCount++; if (noCollisionCount % 10 == 0) { Log.e("&&&&&", "****"); canvas.drawBitmap(bitmap, x, y, paint);//飞机闪烁 } if (noCollisionCount > 100) {//无敌时间 noCollision = false; noCollisionCount = 0; } } else { //非无敌状态 canvas.drawBitmap(bitmap, x, y, paint); } for (int i = 0; i < hp; i++) { canvas.drawBitmap(bitmapHp, i * bitmapHp.getWidth(), MySurfaceView.height - bitmapHp.getHeight(), paint); } } public void touchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_MOVE) { float ex = event.getX(); float ey = event.getY(); if (ex > x && ex < x + width && ey > y && ey < y + height) { x = (int) ex - width / 2; y = (int) ey - height / 2; if (y < 0) { y = 0; } if (y + height > MySurfaceView.height) { y = MySurfaceView.height - height; } } if (x < 0) { x = 0; } if (x + width > MySurfaceView.width) { y = MySurfaceView.width - width; } } } public boolean isCollision(Bullet bullet) { if (noCollision) { return false; } else { if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) { Log.e("***", "------------------"); noCollision = true; if (hp > 0) { hp--; } return true; } } return false; } public boolean isCollision(BossPlane bossPlane) { if (noCollision) { return false; } else { if (bossPlane.getY() + bossPlane.getFrameH() > y && bossPlane.getY() + bossPlane.getFrameH() < y + height) { if (x < bossPlane.getX() && x + width > bossPlane.getX()) { Log.e("AAAAAAAAAa", "isCollision: ..................................."); noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width < bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } if (x > bossPlane.getX() && x + width > bossPlane.getX() + bossPlane.getFrameW()) { noCollision = true; if (hp > 0) { hp--; } return true; } } } return false; }
Boom
public void draw(Canvas canvas, Paint paint){ canvas.save(); canvas.clipRect(x,y,x+frameW,y+frameH); canvas.drawBitmap(bitmap,x-currenFrame*frameW,y,paint); canvas.restore(); logic(); } public void logic(){ if (currenFrame<totalFrame){ currenFrame++; }else { isEnd = true; } } public boolean isEnd(){ return isEnd; } }
Bullet
public void draw(Canvas canvas, Paint paint){ canvas.drawBitmap(bitmap,x,y,paint); logic(); } public void logic(){ switch (type){ case 0: y-=speed; if (y<0){ isDead = true; } break; case 1: y+=speed+5; if (y>MySurfaceView.height){ isDead = true; } break; } }
多态:两个或多个属于不同类的对象,对于同一个消息(方法调用)做出不同响应的方式。
在飞机大战中,我的理解是MySurView里的private修饰的bitmap,height ,width,count等在bossplane,myplane,bullet,boom等中,都做出了不同的反应,比如高度,MySurfaceView中定义好了高度,在bossplane中的高度和myplane中的高度是不同的,都做出了各自的响应,hight在bossplane是指boosplane的高度,在myplane中指myplane的的高度,以此类推.。
接口:接口是一种特殊的抽象类,特点是不被interface修饰,接口也有抽象类,但不被abstr修饰,实现接口需要用implements。
代码:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {
public static int height;
private SurfaceHolder surfaceHolder;
private Canvas canvas;//绘制图形的画布
private boolean isDrawing = true;//标志位
public static int width;
private MyPlane plane;
//Vector是线程安全的,ArrayList是非线程安全的
private Vector<Bullet> bulletVector = new Vector<>();
private Vector<Bullet> bossbulletVector = new Vector<>();
private Vector<Boom>boomVector = new Vector<>();
private int count;
private BossPlane bossPlane;
private GameSoundPool gameSoundPool;
public static int GAME_STATE = 4;
private MediaPlayer mediaPlayer;
public MySurfaceView(Context context) {
super(context);
gameSoundPool = new GameSoundPool(getContext());
init();
}
/**
* 初始化操作
*/
private void init() {
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);//添加回调事件监听
setFocusable(true);//设置可聚焦
setKeepScreenOn(true);//设置屏幕常亮
setFocusableInTouchMode(true);//设置触摸模式
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
new Thread(this).start();//启动子线程
height = getHeight();
width = getWidth();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isDrawing = false;
}
/**
* 实现绘图操作
*/
@Override
public void run() {
MediaPlayer mediaPlayer = null;
mediaPlayer = MediaPlayer.create(getContext(),R.raw.bgm_zhuxuanlv);
mediaPlayer.setLooping(true);
mediaPlayer.start();
Paint paint = new Paint();
// BackGround1 backGround1= new BackGround1(BitmapFactory.decodeResource(getResources(), mipmap.mainmenu));
BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), mipmap.bk));
plane = new MyPlane(BitmapFactory.decodeResource(getResources(), mipmap.myplane),BitmapFactory.decodeResource(getResources(), mipmap.myhp));
BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), mipmap.bossplane));
while (isDrawing) {
count++;
try {
canvas = surfaceHolder.lockCanvas();//锁定(选定)画布
canvas.drawColor(Color.WHITE);
switch (GAME_STATE){
case 1:
backGround.draw(canvas, paint);
plane.draw(canvas, paint);
bossPlane.draw(canvas, paint);
if(count%30==0){
Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.mybullet), plane.getX() , plane.getY(),0);
Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.mybullet), plane.getX()+ plane.getWidth(), plane.getY(),0);
bulletVector.add(bullet);
bulletVector.add(bullet1);
gameSoundPool.playSound(1);
}
//移除消失的子弹
for (int i = 0; i < bulletVector.size(); i++) {
if (bulletVector.elementAt(i).isDead()) {
bulletVector.remove(i);
}
}
//绘制玩家子弹
for (int i = 0; i < bulletVector.size(); i++){
bulletVector.elementAt(i).draw(canvas, paint);
if (bossPlane.isCollision(bulletVector.elementAt(i))){
gameSoundPool.playSound(2);
Boom boom = new Boom(BitmapFactory.decodeResource(getResources(),R.mipmap.boom),bossPlane.getX(),bossPlane.getY(),7);
boomVector.add(boom);
}
}
for (int i =0;i<boomVector.size();i++){
if (boomVector.elementAt(i).isEnd()){
boomVector.remove(i);
}else {
boomVector.elementAt(i).draw(canvas,paint);
//Log.e("..","....");
}
}
if(count%30==0){
Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.bossbullet), bossPlane.getX() , bossPlane.getY()+bossPlane.getFrameH(),1);
Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.bossbullet), bossPlane.getX()+ bossPlane.getFrameW(), bossPlane.getY()+bossPlane.getFrameH(),1);
bossbulletVector.add(bullet);
bossbulletVector.add(bullet1);
}
//移除boss的子弹
for (int i = 0; i < bossbulletVector.size(); i++) {
if (bossbulletVector.elementAt(i).isDead()) {
bossbulletVector.remove(i);
}
}
//绘制boss子弹
for (int i = 0; i < bossbulletVector.size(); i++) {
bossbulletVector.elementAt(i).draw(canvas, paint);
plane.isCollision(bossbulletVector.elementAt(i));
}
plane.isCollision(bossPlane);//一定不要忘了调用这个方法
break;
case 2://RectF矩形
RectF rectF0 = new RectF(0,0,getWidth(),getHeight());
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.gamewin),null,rectF0,paint);
break;
case 3:
RectF rectF = new RectF(0,0,getWidth(),getHeight());
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.gamelost),null,rectF,paint);
break;
case 4:
RectF rectF1 = new RectF(0,0,getWidth(),getHeight());
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.mainmenu),null,rectF1,paint);
RectF rectF2 = new RectF(0,getHeight()*2/5,getWidth(),getHeight()*3/5);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.logo),null,rectF2,paint);
if(count>20){
MySurfaceView.GAME_STATE = 1;
}
break;
}
} catch(Exception e){
e.printStackTrace();
} finally{
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,显示到屏幕上
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// if (event.getAction()==MotionEvent.ACTION_MOVE){
// Log.e("MySurfaceView","onTouchEvent:"+event.getX());
// }else if (event.getAction() == MotionEvent.ACTION_UP){
// Log.d("MySurfaceView","手指按起");
// }else if (event.getAction() == MotionEvent.ACTION_DOWN){
// Log.d("MySurfaceView","手指按下");
plane.touchEvent(event);
return true;//永远监听屏幕触摸事件
}
}
继承:继承是从已有的类中派生出新类,新的类能吸收已有类的数据属性和行为并能扩展新的能力。
代码:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable { public static int height; private SurfaceHolder surfaceHolder; private Canvas canvas;//绘制图形的画布 private boolean isDrawing = true;//标志位 public static int width; private MyPlane plane; //Vector是线程安全的,ArrayList是非线程安全的 private Vector<Bullet> bulletVector = new Vector<>(); private Vector<Bullet> bossbulletVector = new Vector<>(); private Vector<Boom>boomVector = new Vector<>(); private int count; private BossPlane bossPlane; private GameSoundPool gameSoundPool; public static int GAME_STATE = 4; private MediaPlayer mediaPlayer; public MySurfaceView(Context context) { super(context); gameSoundPool = new GameSoundPool(getContext()); init(); } /** * 初始化操作 */ private void init() { surfaceHolder = getHolder(); surfaceHolder.addCallback(this);//添加回调事件监听 setFocusable(true);//设置可聚焦 setKeepScreenOn(true);//设置屏幕常亮 setFocusableInTouchMode(true);//设置触摸模式 } @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(this).start();//启动子线程 height = getHeight(); width = getWidth(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { isDrawing = false; } /** * 实现绘图操作 */ @Override public void run() { MediaPlayer mediaPlayer = null; mediaPlayer = MediaPlayer.create(getContext(),R.raw.bgm_zhuxuanlv); mediaPlayer.setLooping(true); mediaPlayer.start(); Paint paint = new Paint(); // BackGround1 backGround1= new BackGround1(BitmapFactory.decodeResource(getResources(), mipmap.mainmenu)); BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), mipmap.bk)); plane = new MyPlane(BitmapFactory.decodeResource(getResources(), mipmap.myplane),BitmapFactory.decodeResource(getResources(), mipmap.myhp)); BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), mipmap.bossplane)); while (isDrawing) { count++; try { canvas = surfaceHolder.lockCanvas();//锁定(选定)画布 canvas.drawColor(Color.WHITE); switch (GAME_STATE){ case 1: backGround.draw(canvas, paint); plane.draw(canvas, paint); bossPlane.draw(canvas, paint); if(count%30==0){ Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.mybullet), plane.getX() , plane.getY(),0); Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.mybullet), plane.getX()+ plane.getWidth(), plane.getY(),0); bulletVector.add(bullet); bulletVector.add(bullet1); gameSoundPool.playSound(1); } //移除消失的子弹 for (int i = 0; i < bulletVector.size(); i++) { if (bulletVector.elementAt(i).isDead()) { bulletVector.remove(i); } } //绘制玩家子弹 for (int i = 0; i < bulletVector.size(); i++){ bulletVector.elementAt(i).draw(canvas, paint); if (bossPlane.isCollision(bulletVector.elementAt(i))){ gameSoundPool.playSound(2); Boom boom = new Boom(BitmapFactory.decodeResource(getResources(),R.mipmap.boom),bossPlane.getX(),bossPlane.getY(),7); boomVector.add(boom); } } for (int i =0;i<boomVector.size();i++){ if (boomVector.elementAt(i).isEnd()){ boomVector.remove(i); }else { boomVector.elementAt(i).draw(canvas,paint); //Log.e("..","...."); } } if(count%30==0){ Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.bossbullet), bossPlane.getX() , bossPlane.getY()+bossPlane.getFrameH(),1); Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), mipmap.bossbullet), bossPlane.getX()+ bossPlane.getFrameW(), bossPlane.getY()+bossPlane.getFrameH(),1); bossbulletVector.add(bullet); bossbulletVector.add(bullet1); } //移除boss的子弹 for (int i = 0; i < bossbulletVector.size(); i++) { if (bossbulletVector.elementAt(i).isDead()) { bossbulletVector.remove(i); } } //绘制boss子弹 for (int i = 0; i < bossbulletVector.size(); i++) { bossbulletVector.elementAt(i).draw(canvas, paint); plane.isCollision(bossbulletVector.elementAt(i)); } plane.isCollision(bossPlane);//一定不要忘了调用这个方法 break; case 2://RectF矩形 RectF rectF0 = new RectF(0,0,getWidth(),getHeight()); canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.gamewin),null,rectF0,paint); break; case 3: RectF rectF = new RectF(0,0,getWidth(),getHeight()); canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.gamelost),null,rectF,paint); break; case 4: RectF rectF1 = new RectF(0,0,getWidth(),getHeight()); canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.mainmenu),null,rectF1,paint); RectF rectF2 = new RectF(0,getHeight()*2/5,getWidth(),getHeight()*3/5); canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), mipmap.logo),null,rectF2,paint); if(count>20){ MySurfaceView.GAME_STATE = 1; } break; } } catch(Exception e){ e.printStackTrace(); } finally{ if (canvas != null) { surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,显示到屏幕上 } } } } @Override public boolean onTouchEvent(MotionEvent event) { // if (event.getAction()==MotionEvent.ACTION_MOVE){ // Log.e("MySurfaceView","onTouchEvent:"+event.getX()); // }else if (event.getAction() == MotionEvent.ACTION_UP){ // Log.d("MySurfaceView","手指按起"); // }else if (event.getAction() == MotionEvent.ACTION_DOWN){ // Log.d("MySurfaceView","手指按下"); plane.touchEvent(event); return true;//永远监听屏幕触摸事件 } }
我的收获与感悟:
五月是我学习编程以来最累的一个月,但是也是收获最多的一
个月,这一个月是真正意义的开始接触Java和Android
Studio.我开始知道什么是类什么是对象,理解了封装,多态,
继承,方法的重载,方法的重写,接口的概念等等。我做出了
第一个游戏程序,虽然不算自己亲自编程出来了的,但是通过
飞机大战这个游戏我对Java的概念又进一步的理解和运用,在
游戏运行出来的时候,心里压抑不住的欢喜,特别想把这个游
戏继续优化下去,想让他变得更加完美,我自知我现在的知识
还不够,但是我会继续努力,巩固这个月所学习的知识,并继
续学习更多的知识,为亲自做出属于自己的编程。非常感谢江
哥在五月教授我们那么的知识,在我遇到困难时候耐心的为我
解决问题,我一定会继续好好学习,向*提出更多的问题,
成为优秀的程序员。