整体实现思路
1.运行代码,出现背景滚动,飞机往上飞,发出子弹,敌机向下发射子弹。
2.飞机击中敌机发生爆炸,消耗敌机血量,血量为零时胜利。
3.敌机击中我方飞机发生爆炸,消耗我方飞机血量,血量为零是失败。
如何绘制循环滚动的背景图片
在MySurfaceView中创建run方法
public void run() {
Paint paint = new Paint();
BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), (Integer) R.mipmap.img_bg_level_2));
调用mipmap中的背景图片
再创建BackGround类
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+=10;
y2+=10;
if (y1>=MySurfaceView.height){
y1=y2-bitmap.getHeight();//移动到第二张图片的顶部
}
if (y2>=MySurfaceView.height){
y2=y1-bitmap.getHeight();
}
}
}
效果如下
如何绘制飞机
在run方法中
plane = new Myplane(BitmapFactory.decodeResource(getResources(), R.mipmap.myplan),BitmapFactory.decodeResource(getResources(), R.mipmap.myhp));
再创建一个飞机类 MyPlane 添加击中闪烁 、无敌时间效果。
public Myplane(Bitmap bitmap, Bitmap bitmapHp){
this.bitmap = bitmap;
this.bitmapHp = bitmapHp;
x = MySurfaceView.width/2-bitmap.getWidth()/2;
y = MySurfaceView.height-bitmap.getHeight();
width = bitmap.getWidth();
height = bitmap.getHeight();
}
public void draw(Canvas canvas,Paint paint){
if(hp<=0){
MySurfaceView.GAME_STATE = 2;
}
if (noCollision){
noCollisionCount++;
if (noCollisionCount%10==0){
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);
}
}
如何绘制子弹
创建个子弹类Bullet
并加入BossBullet创建方法
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;
private 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 Bullet() {
}
public void draw(Canvas canvas, Paint paint) {
canvas.drawBitmap(bitmap, x, y, paint);
logic();
}
public void logic() {
switch (type){
//玩家子弹
case 0:
y -= speed+5;
if (y < 0) {
isDead = true;
}
break;
//Boss子弹
case 1:
y += speed+8;
if (y < 0) {
isDead = true;
}
break;
default:
break;
}
}
如何判断碰撞(子弹与飞机碰撞,飞机与飞机碰撞)
子弹与Boss碰撞
public boolean isCollison(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 =1;
}
return true;
}
return false;
飞机与Boss碰撞
public boolean isColliseion(Bullet bullet) {
if (noCollision) {
return false;
} else {
if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) {
// Log.e("a", "isColliseion: ......................." );测试
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
public boolean isColliseion(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()) {
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 < bossPlane.getX() + bossPlane.getFrameW()) {
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
}
return false;
如何绘制爆炸效果
创建爆炸Boom类
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Boom {
private Bitmap bitmap;
private int x,y;
private int totalFrame;
private int currentFrame;
private int frameW,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-currentFrame*frameW,y,paint);
canvas.restore();
logic();
}
public void logic(){
if (currentFrame<totalFrame){
currentFrame++;
}else{
isEnd = true;
}
}
public boolean isEnd() {
return isEnd;
}
如何添加音效
在 GameSoundPool 类中 加入如下代码
开火音效
战斗背景音效
public GameSoundPool(Context context){
this.soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC,0);
s1 = soundPool.load(context,R.raw.shoot,1);
s2 = soundPool.load(context,R.raw.explosion2,1);
s3 = soundPool.load(context,R.raw.bgm_zhandou2,1);
}
哪些地方用到封装,继承,多态,方法重载,接口等
封装
每一个类中的属性基本都用到了封装方法如
public class Bullet {
private Bitmap bitmap;
private int x, y;
private int speed = 10;
private boolean isDead;
private int type;
继承
MySurfaceView 类中
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {
public static int GAME_STATE = 0;
Boom类中
public class Boom extends Bullet {
private Bitmap bitmap;
private int x,y;
private int totalFrame;
多态
public class Boom extends Bullet {
private Bitmap bitmap;
private int x,y;
private int totalFrame;
private int currentFrame;
private int frameW,frameH;
private boolean isEnd;
public Boom(Bitmap bitmap, int x, int y, int totalFrame) {
super();
this.bitmap = bitmap;
this.x = x;
this.y = y;
this.totalFrame = totalFrame;
frameW = bitmap.getWidth()/totalFrame;
frameH = bitmap.getHeight();
方法重载
方法名相同,形参列表不同
如下
public void surfaceCreated(SurfaceHolder holder) {
new Thread(this).start();//启动子线程
height = getHeight();//把getHeight(获取height的方法)的返回值赋给height
width = getWidth();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
我的收获与感悟
经过四周的实训课,感悟良多。Java编程是一项很严谨的工作:一定要细心,一点点的不严谨,就会出现问题,也可能导致整个项目出错,所谓:千里之堤,毁于蚁穴。
这四周,很辛苦,很累。但是回头想想,却又很开心,收获很多,学到很多。总之,这次实训为我提供了与众不同的学习方法和学习体会,为以后走上社会,踏上工作岗位打下了扎实的基础。有了能力,到时候才会是“车到山前必有路“。
相信再不久的未来,会属于我自己的一片天空。