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的概念又进一步的理解和运用,在
游戏运行出来的时候,心里压抑不住的欢喜,特别想把这个游
戏继续优化下去,想让他变得更加完美,我自知我现在的知识
还不够,但是我会继续努力,巩固这个月所学习的知识,并继
续学习更多的知识,为亲自做出属于自己的编程。非常感谢江
哥在五月教授我们那么的知识,在我遇到困难时候耐心的为我
解决问题,我一定会继续好好学习,向江哥提出更多的问题,
成为优秀的程序员。