1.整体实现思路
实现飞机大战的简单思路:
①要先建MySurfaceView这个类,在这个类中绘制画布,有画布的高度和宽度,还有画笔,然后在这个建好的画布上开始继续“作画”画布利用了canvas实现,画笔利用paint实现。
②然后将飞机大战的部分闯关背景“画”上画布,实现绘图操作,利用多线程的方法,调用runable方法并用stater启动子线程。记得解锁画布,显示到屏幕上。
③选择背景图片,建立BackGround类,利用两张相同背景图片利用if循环语句实现背景图片的移动。并在MySurfaceView中调用。
④建立Myplane和BossPlane类,利用if语句和for循环和onTouchEvent和isCollision和noisCollision和noisCollisioncount等实现飞机的飞行移动,并可以实现屏幕触摸,还创建hp,来实现飞机血量的减少。还要利用isCrazy,time,count实现boss飞机的疯狂模式时间。并在MySurfaceView中调用。
并在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;
- 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 Bitmap bitmap;
- private int x, y;
- private static int width, height;
- private int fx;