您的位置:首页 > 移动开发 > Android开发

Android stutio实现飞机大战

2018-05-31 22:35 162 查看

一.飞机大战整体思路

1.选定背景,然后设置背景,实现两张背景的循环,达成背景的循环滚动的效果
2.加上一个玩家飞机,给他赋予初始位置,然后给玩家飞机Touch,实现玩家飞机能按照手指的触摸位置来进行移动的效果
3.加上Boss飞机,在背景的上方给Boss飞机进行判断,实现飞机的左右移动,设置Boss飞机的疯狂状态
4.给飞机加上子弹,玩家飞机和Boss飞机子弹都是一样的,创建一个speed给它赋值,这是子弹的速度,用speed++进行子弹的加速,再定义一个isdead,进行子弹的判断
5.进行判断,判断当子弹撞到飞机的时候的各种不同的反应,自己飞机撞到敌机时候的反应,比如玩家飞机和Boss飞机的血量的减少,以及飞机碰到时候的闪烁状态,然后就是赋予碰撞时的声音
6.给飞机和子弹和游戏整体加上背景音效

二.如何实现背景图片滚动

首先定义图片的x,y,Bitmap,给这三个值赋予构造方法,要有canvas和paint,一定要锁定画板和解锁画板,然后在逻辑方法中进行判断,给x和y进行++实现背景的滚动,当你的第一张图循环结束,把第二张图放在后面继续进行滚动,第一张图立马放到第二张图后面接着循环,在视觉上形成一种循环的效果。
下面是背景这一部分的代码:

/**
* 背景图片
*/

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;

public class BackGroud {
private int x;
private int y;
private  Bitmap bitmap;

public BackGroud(Bitmap bitmap){
this.bitmap = bitmap;
x = 0;
y = x-bitmap.getHeight();

}

public void draw(Canvas canvas){
logic();
Paint paint = new Paint();
canvas.drawBitmap(bitmap,0, x,paint);
canvas.drawBitmap(bitmap,0, y,paint);

}
public void logic(){ //逻辑方法
x+=10;
y+=10;
if(x>=bitmap.getHeight()){
x = y-bitmap.getHeight(); //移动在第二张上面

}
if(y>=bitmap.getHeight()){
y=x-bitmap.getHeight();

}
}

}

三.如何绘制飞机

先给飞机定义一个初始位置,通过定义的属性在屏幕底部的中间,因为屏幕左上角是原点坐标,所以这里的X,Y是飞机和屏幕的左上角的位置,这时候的飞机在中间偏右这个位置,所以你要减去半个飞机的宽度才能到达正中心。

/**
*玩家飞机
*/
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;

public class Myplane {
private Bitmap bitmap;
private Bitmap bitmapHp;
private int x, y;
private int width, height;
private boolean noCollision;
private int noCollisionCount;
private int Hp = 3;

public Myplane(Bitmap bitmap, Bitmap bitmapHp) {
this.bitmapHp = bitmapHp;
this.bitmap = bitmap;
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_start = 3;
}
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);//HP位置
}

}

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;
}
}
}
}
//我方飞机与boss子弹
public boolean isCollision(Bullet bullet) {
if (noCollision) {
return false;
}
if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) {
noCollision = true;
if (Hp > 0) {
Hp--;
}
return true;
}
return false;

}
//我方飞机与boss
public boolean Attack(Bossplane bossplane) {
if (noCollision) {
return false;

}
if(y<bossplane.getY()+bossplane.getFrameH()&&y+height>bossplane.getY() ){

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+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;
}

public int getHeight() {
return height;
}
}

四.如何绘制子弹

首先定义三要素,然后写他们的构造方法。要写一个speed,是给子弹赋予速度。

public void logic() {
switch (type){
//玩家子弹
case 0:
y -= speed;
if (y < 0) {
isDead = true;

}
break;
//boos子弹
case 1:
y += speed;
if (y < 0) {
isDead = true;

}
break;
}

五.如何判断碰撞

1.飞机与子弹碰撞
当飞机的坐标和子弹的坐标重合的时候,我们要实现飞机血量的减少,来达到你的飞机碰撞的效果。我们要对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){
noCollision = true;
if (hp>0){
hp--;
}

return true;
}
}
return false;
}

2.飞机与Boss机碰撞
实现玩家飞机和Boss飞机的碰撞,跟飞机和子弹的碰撞一样,都要判断他的各种状态

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()){
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;
}

六.如何绘制爆炸效果

这里用的是图片的裁剪,因为图片有七张图组成,要用clip方法裁剪,在裁剪前一定要写上save和restore方法。

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;
}
}

七.如何添加音效

现创建一个raw,然后将音乐加入进去。调用this.soundPool,先让他实例化,给他选择音乐和优先级别等。

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class GameSoundPool {
private SoundPool soundPool;
private int s1;
private int s2;
private int s3;

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.bg_logobg,2);
}
public void playSound(int s) {
switch (s){
case 1:
soundPool.play(s1,1,1,1,1,1.0f);
break;
case 2:
soundPool.play(s2,1,1,1,1,1.0f);
break;
case 3:
soundPool.play(s3,1,1,1,1,1.0f);
break;
}
}
}

这是最后的效果图

八.哪些地方用到封装,继承,多态,方法重载,接口等

1.继承和接口主要是在mysurfaceview中体现,mysurfaceview继承了surfaceview中的属性和方法,还要实现SurfaceHolder.Callback,Runnable的接口。

2.用的最多的就是封装每个类定义的变量有public型的还有private型的,讲到这个就不得不说四种范围访问修饰符:当前类访问权限:private,包访问权限:default,子类访问权限:protected,公共类访问权限:public。其中private型的只能通过set和get方法来调用。

3.方法的重载主要体现在飞机类和子弹类中,在飞机和子弹类中,飞机与飞机的碰撞中定义了同一个类名,然而参数列表不一样,调用的时候,就按照里面的参数来进行传参。

九.感悟

这一个月的学习虽然很累,但是真的学到了很多。从一开始的什么都不懂,到现在能自己打代码,我自己觉得进步真的还是可以的。从一开始九九乘法表都不会,到现在封装多态啊学了很多专有名词和快捷方式。刚开始就是很兴奋的那种感觉,但是后来在学File类的时候不会真的一点不会,贼绝望。就想放弃,但是后来又好好打代码,抄了一遍又自己写了一遍,慢慢好像就懂一点。这个时候感觉勤能补拙还是有道理的。通过这一个月的学习我觉得对于一个软件班的人收获还是很大的。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: