整体实现思路:
1.创建BackGround绘制循环滚动图片
2.创建Myplane绘制飞机
3.创建Bullet绘制子弹
4.在Myplane中构造isCollision绘制飞机与boss飞机的碰撞,飞机与子弹的碰撞
5.创建boom绘制爆炸效果
6.创建GameSoundpool添加飞机发射子弹的音效和爆炸音效
如何绘制循环滚动背景图片:
创建一个Background类,并实现构造方法,用draw方法和logic方法使两张图片紧密连接在一起,当第一张图片小于MySurfaceView高度时另一张图片接着循环
package com.example.a29148.myapplication;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
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){
logic();
Paint paint = new Paint();
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();
}
}
}
如何绘制飞机:
创建Myplane,实现它的构造方法,draw方法并在MySurfaceView传递参数,在后面还定义了飞机的血量,还定义了一个布尔型的noCollision使手指可以拖动飞机,并判断飞机是否被boss飞机发射的子弹击中和被boss飞机的疯狂模式撞到减少血量;当飞机的血量小于等于零时,判定游戏失败
package com.example.a29148.myapplication;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
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){
logic();
Paint paint = new Paint();
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();
}
}
}
case 2:
RectF rectF = new RectF(0,0,getWidth(),getHeight());
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.gamelost),null,rectF,paint);
break;
如何绘制子弹:
创建一个Bulle类,并完成它的构造方法,定义speed方法给子弹飞行速度赋值,用switch语句把子弹分为玩家子弹和boss子弹,并定义一个布尔型方法isOut,移除飞出屏幕的子弹
package com.example.a29148.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=20;
private boolean isOut;
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);
lg();
}
private void lg(){
switch (type){
//玩家子弹
case 0:
y-=speed;
if(y<0){
isOut = true;
}
break;
case 1:
//Boss子弹
y+=speed;
if (y<0){
isOut = true;
}
break;
default:
break;
}
}
public boolean isOut() {
return isOut;
}
public Bitmap getBitmap() {
return bitmap;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setOut(boolean out) {
isOut = out;
}
}
如何判断碰撞:
在Myplane类和bossplane定义一个isCollision方法并定义布尔型noCollision变量,判断子弹的位置是否落在飞机所在的xy轴位置,如果是就移除子弹并减少血量
public boolean isCollision(BossPlane bossPlane) {
if (noCollision) {
return false;
} else {
if (bossPlane.getY() + bossPlane.getH() > y && bossPlane.getY() + bossPlane.getH() < y + height) {
if (x < bossPlane.getX() && x + width > bossPlane.getX()) {
noCollision = true;
if (hp >= 0) {
hp--;
}
return true;
}
if (x>bossPlane.getX()&&x+width 0) {
hp--;
}
return true;
}
if(xbossPlane.getX()+bossPlane.getW()){
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
}
public boolean isCollison(Bullet bullet){
if(bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()y&&bullet.getY()
如何绘制爆炸效果:
创建一个Boom类,实现它的构造方法,定义两个int型变量crrentFrame和totalFrame,和一个布尔型变量isOut并想MySurfaceView里面传递参数用canvas.clipRect剪切图片,在用canvas.clipRect时要用canvas.save和canvas.restore当currentFrame小于totalFrame时产生爆炸效果
package com.example.a29148.myapplication;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Boom {
private Bitmap bitmap;
private int x,y;
private int currentFrame;//当前显示的第几副画面
private int totalFrame;
private int frameW,frameH;
private boolean isOut;
public Boom(Bitmap bitmap, int x, int y, int totalFrame) {
this.bitmap = bitmap;
this.x = x;
this.y = y;
this.totalFrame = totalFrame;
frameH = bitmap.getHeight();
frameW = bitmap.getWidth()/totalFrame;
}
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();
lg();
}
public void lg(){
if(currentFrame
如何添加音效:
创建一个GameSoundpool类,实现构造方法,创建一个palySound方法在里面使用switch语句实现音效的快慢并传参到MySurfaceView类中
package com;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import com.example.a29148.myapplication.R;
public class GameSoundpool {
private SoundPool soundPool;
private int s1;
private int s2;
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);
}
public void playSound(int s){
switch (s){
case 1:
soundPool.play(s1,1,1,0,1,1.0f);
break;
case 2:
soundPool.play(s2,1,1,0,1,1.0f);
break;
}
}
}
if(count%20==0){
gameSoundpool.playSound(1);
Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(),R.mipmap.t),plane.getX(),plane.getY(),0);
bulletVector.add(bullet);
}
if(bossPlane.isCollison(bulletVector.elementAt(i))){
gameSoundpool.playSound(2);
Boom boom = new Boom(BitmapFactory.decodeResource(getResources(),R.mipmap.boom),bossPlane.getX()+bossPlane.getX()/2,bossPlane.getY(),7);
boomVector.add(boom);
}
用到的方法:
封装:
飞机的x和y坐标,boss的坐标MySurfaceView中的canvas等都是用到了封装
继承:
MySurfaceView继承了SurfaceView
方法重载:
Myplane中的碰撞类中存在两碰撞就是方法的重载,一个是飞机和子弹的碰撞,一个是飞机和boss飞机的碰撞
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("AAA", "isCollision: .................................");
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
public boolean isCollision(BossPlane bossPlane) {
if (noCollision) {
return false;
} else {
if (bossPlane.getY() + bossPlane.getH() > y && bossPlane.getY() + bossPlane.getH() < y + height) {
if (x < bossPlane.getX() && x + width > bossPlane.getX()) {
noCollision = true;
if (hp >= 0) {
hp--;
}
return true;
}
if (x>bossPlane.getX()&&x+width 0) {
hp--;
}
return true;
}
if(xbossPlane.getX()+bossPlane.getW()){
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
}
接口:
MySurfaceView中的SurfaceHolder.Callback和Rnnable都是接口
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder surfaceHolder;
private Canvas canvas;//绘制图形的画布
private boolean isDrawing = true;
public static int Height;
public static int Wide;
private MyPlane plane;
private Vector bulletVector = new Vector<>();//Vector是线程安全的,ArrayList是非线程安全的
private Vector boosBulletVector = new Vector<>();
private VectorboomVector = new Vector<>();
private int count;
private GameSoundpool gameSoundpool;
public static int Game_STATE=3;
收获与感悟:
没上实训课之前辉哥,曾经说过我们上实训课会收获很大,当时我不信,因为去年的c语言的并不好,导致今年的java就有点跟不上节奏,今年java课的老师可能以为我们班的c语言的学的很好,所以课就讲的很快,我许多概念没弄明白就讲完了,上课讲的东西下课就忘了。
但是上了实训课老师又从头开始讲起,许多我没弄懂的概念和代码老师讲的很仔细,很容易明白,而且老师上课也不是只讲理论性的东西,大多数时间都留给我们自己打代码,让我们练习,这都是我们以前课堂上没有的东西,虽然只有短短的一个月时间,但是我感觉比前两个月学到的东西都多,比以前的不理解,只死记硬背的好太多了,这一个月让我重拾了信心,而且最后的一个飞机大战的项目我很感兴趣,因为我学习软件有很大一部分原因是我想自己编写一个游戏,这次的实训课让我感受到了不少压力,原来编写一个游戏需要这么多精力,但是丝毫没降低我的兴趣,我会一直向着我的目标前进的