1.在Andriod Studio中新建Java项目用来做我们的《飞机大战》项目;
2.通过MySurfaceView这个类作为主页面来完成整体布局结构的设计和制作;
3.新建一个类,用来设计战斗时的页面背景,通过draw方法和logic方法形成两张背景图循环播放的效果;
4.新建MyPlane类绘制玩家飞机;
5.新建EnemyPlane来绘制敌方BOSS飞机;
6.新建Bullet类来绘制子弹(敌我双方子弹);
7.新建Boom类绘制飞机爆炸效果;
8.新建GameSoundPool类来添加背景、子弹发射、击中目标等音效;
9.整体结构完成后,具体对各个方面做出完善和修改,如:子弹与飞机碰撞,飞机与敌机碰撞等
下面我们来详细分析一下《飞机大战》这个项目:
首先我们在BackGround中对背景图的坐标,位图进行定义;然后完成它们的构造方法,draw方法和logic方法,方便调用;关于背景图,我采用了两张同样的图片进行循环,对它们的位置进行判断,规定它们的移动速度使它们可以无缝衔合;最后在MySurfaceView中进行实例化调用。
附代码:(关于draw方法和logic方法的片段)
public void draw(Canvas canvas,Paint paint) {
logic();
canvas.drawBitmap(bitmap, 0, y, paint);
canvas.drawBitmap(bitmap, 0, y1, paint);
}
private void logic() {
y += 10;
y1 += 10;
if (y >= MySurfaceView.height) {
y = y1 - bitmap.getHeight();
}
if (y1 >= MySurfaceView.height) {
y1 = y - bitmap.getHeight();
}
}
这是背景图的绘制思路,当然后期会完成对背景图的完善,通过切换背景图实现更换关卡的效果。
刚开始制作时,我为飞机定义了它的坐标,位图,宽度和高度等,并创建了它的构造方法,draw方法;在MySurfaceView中进行附参和实例化,并调用MyPlane的draw方法使飞机在背景图中显示出来。
完善:在几天的学习过程中,我们对玩家飞机进行了完善和修改。完善有如下几点:
1.我们给飞机添加了血量hp
2.我们设计onTouchEvent方法移动飞机,监听屏幕 ,实现手指移动飞机
3.为飞机做出被子弹击中后闪烁无敌效果
附代码:(关于touchEvent和isCollision方法的代码片段)
public void touchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
float ex = event.getX();
float ey = event.getY();
if (ex > x && ex < width + x && ey > y && ey < height + y) {
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) {
x = 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) {
hp--;
noCollision = true;
return true;
}
}
return false;
}
public boolean isCollision(EnemyPlane enemyPlane) {
if (noCollision) {
return false;
} else {
if (enemyPlane.getFrameH() + enemyPlane.getY() < y + height && enemyPlane.getY() + enemyPlane.getFrameH() > y) {
if (x < enemyPlane.getX() && x + width > enemyPlane.getFrameW()) {
noCollision = true;
if (hp >= 0) {
hp--;
}
return true;
}
if (x > enemyPlane.getX() && x + width < enemyPlane.getX() + enemyPlane.getFrameW()) {
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
if (x > enemyPlane.getX() && x < enemyPlane.getX() + enemyPlane.getFrameW()) {
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
与之前一样,我们为子弹定义了自己的坐标,位图,另外添加了子弹的移动轨迹,以及子弹的循环出现,子弹超出屏幕后自动移除等功能。
完善:在这几天的学习过程中,我们又添加了BOSS子弹,以及玩家子弹击打在BOSS身上后自动移除,BOSS子弹击打在玩家飞机身上激发玩家飞机闪烁效果,触发玩家飞机无敌时间
附代码:(附draw和fire方法代码片段)
public void draw(Canvas canvas, Paint paint){
canvas.drawBitmap(bitmap,x,y,paint);
fire();
}
private void fire() {
switch (type){
case 0:
//玩家子弹
y-= speed;
if (y<0){
isDead = true;
}
break;
case 1:
//Boss子弹
y+= speed+5;
if (y<0){
isDead = true;
}
break;
case 2:
//敌机子弹
y+= speed+3;
if (y<0){
isDead = true;
}
break;
default:
break;
}
}
1.在MyPlane中我们为飞机设置了闪烁无敌时间,即玩家飞机被敌方子弹或敌方飞机碰撞后hp减一,随即进入闪烁无敌状态;
2.我们还设计了如何判定玩家子弹碰撞击打到敌方飞机;
3.双方飞机被子弹碰撞到或者双方飞机碰撞到的位置我们进行了判定,以小飞机为例
(代码:
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) {
hp--;
noCollision = true;
return true;
}
}
return false;
}
public boolean isCollision(EnemyPlane enemyPlane) {
if (noCollision) {
return false;
} else {
if (enemyPlane.getFrameH() + enemyPlane.getY() < y + height && enemyPlane.getY() + enemyPlane.getFrameH() > y) {
if (x < enemyPlane.getX() && x + width > enemyPlane.getFrameW()) {
noCollision = true;
if (hp >= 0) {
hp--;
}
return true;
}
if (x > enemyPlane.getX() && x + width < enemyPlane.getX() + enemyPlane.getFrameW()) {
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
if (x > enemyPlane.getX() && x < enemyPlane.getX() + enemyPlane.getFrameW()) {
noCollision = true;
if (hp > 0) {
hp--;
}
return true;
}
}
return false;
}
);
4.后期可以进行进一步完善,比如玩家飞机与场景中随机出现的道具碰撞后产生的效果
和之前一样为Boom定义基本属性,为它定义draw方法和logic方法。在玩家子弹碰撞到Boss身上后我们利用Vector boom = new Vector<>();来实现Boss身上产生的一连串爆炸效果,当然这个爆炸效果是利用七张图片快速裁切转换形成的,当七张图片切换完成后自动删除,以便于下一次的爆炸效果显示。
附代码:(关于draw方法和logic方法的代码片段)
public void draw(Canvas canvas, Paint paint){
canvas.save();
canvas.clipRect(x,y,x+frameW,y+frameH);
canvas.drawBitmap(bitmap,x-cu*frameW,y,paint);
canvas.restore();
logic();
}
public void logic(){
if (cuelse{
isEnd=true;
}
首先我根据老师讲解的过程,学会了基本的SoundPool用法,利用这种方法我为玩家飞机子弹射击和Boss爆炸添加了音效(代码片段: 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.explosion3,1);
s3 = soundPool.load(context,R.raw.bgm_zhuxuanlv,0);
}
public void playSound(int type){
switch (type){
case 1:
soundPool.play(1,1,1,1,1,1.0f);
break;
case 2:
soundPool.play(2,1,1,1,1,1);
break;)
在随后的背景音效设置中,我更换了 MediaPlayer方法来设置背景音效(代码片段:MediaPlayer mediaPlayer = null;
mediaPlayer = MediaPlayer.create(getContext(),R.raw.bgm_zhandou2);
mediaPlayer.start();)
后期改善中会增添更加丰富的音效。
在这次的飞机大战中,所有的类中我们都使用到了封装:private,public等,用来定义变量,写方法。
只有MysurfaceView继承的是SurfaceView,其余部分没有用到继承。
这次的项目中没有使用多态
没有使用
这次项目中在MySurfaceView中存在SurfaceHolder.Callback,与Runnable两个接口
在这一个月的实训学习中,我收获了很多,首先前两个礼拜的学习使我对eclipse有了进一步的了解和学习,老师讲的很详细我们听的也很认真,但是我觉得在编程开发中最重要的还是逻辑思维要清晰,要有自己的创新意识,要敢做敢错。在这次的Android Studio项目《飞机大战》的开发中,我更加深刻的理解了逻辑思维的重要性,以及对编程工具的熟悉的重要性。在编写过程中,我虽说能基本完成该项目的各种要求,但想输入自己的想法时往往因为逻辑问题、编写代码速度问题发生一些错误,导致进度跟不上,我觉得这是我以后需要改善的地方。当然我也为自己能完成此次代码感到由衷的高兴,虽说这一个月有点累但是收获了很多,也让我对Android
开发,Java开发更加感兴趣了,证明了自己当初没选错专业。
期待未来的自己能从Android和Java中学会更多,收获更多。