一、飞机大战游戏整体实现思路。
第一步:实现屏幕的背景图片的滚动不出现空白部分
第二步:绘制自己的小飞机,并处在屏幕底部中间,可以移动。
第三步:绘制boss的飞机,处在屏幕顶部中间,可以移动。
第四步:自己的小飞机和boss的飞机可以发射子弹并且射中对方掉血。
第五步:设置自己的几条命,并绘制自己命的图片
第六步:通关图片和失败图片的显示。
二、如何绘制循环滚动的背景图片。
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
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();
}
}
}
先将图片绘制到mysurfaceview上然后,去定义图片的y,x,bitmap.在判定第一张图片背景是否移动超过屏幕底部,然后,第二章背景移动,以此类推,实现屏幕的滚动。
三、如何绘制飞机图片。
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
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.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);
}
}
public void touchEvent(MotionEvent event){
if (event.getAction()==MotionEvent.ACTION_MOVE){
float ex = (int) event.getX();
float ey = (int) 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;
}
}
}
}
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;
}
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;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
}
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=5;//boos飞机的速度
private int crazySpeed=50;//疯狂速度
private int count;//计数器
private int time=500;//疯狂模式间隔
private boolean isCrazy;
private int bossHp = 10000;
public BossPlane(Bitmap bitmap) {
this.bitmap = bitmap;
this.frameW = bitmap.getWidth()/10;
this.frameH = bitmap.getHeight();
x=MySurfaceView.width/2-frameH/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-frameH){
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);
if (bossHp<0){
MySurfaceView.GAME_STATE = 1;
}
return true;
}
return false;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getFrameW() {
return frameW;
}
public int getFrameH() {
return frameH;
}
}
先将飞机图片绘制到画布上,然后判定飞机到(0,0)点的距离,然后用代码表示出来。飞机的图片要减去一半的飞机。因为飞机的中点与飞机有一半飞机的距离。
四、如何绘制子弹。
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Bullet {
private int speed=10;
private int x;
private int y;
private Bitmap bitmap;
private int type;
private boolean isDead;
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 setDead(boolean dead) {
isDead = dead;
}
public Bitmap getBitmap() {
return bitmap;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
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;
}
}
public boolean isDead() {
return isDead;
}
}
定义我的飞机类和boss的飞机类,先是定义一个子弹的类,在画布上画上子弹,然后在子弹类当中实现子弹的效果。并给子弹增加速度,使子弹的速度与屏幕滚动的速度有所区别。
五、如何判断碰撞爆炸效果。
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
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 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;
}
}
六、如何添加音效。
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.bgm_zhandou2,1);
}
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;
}
}
}
七、那些地方用到封装,继承,多态,方法重载,接口等。
运用了接口。接口:接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口支持多继承。
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {
运用了封装。封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。
public static int GAME_STATE = 0
private SurfaceHolder surfaceHolder;
private Canvas canvas;//绘制图形的画布
private boolean isDrawing = true;//标志位
public static int height;
public static int width;
private Myplane plane;
private Vector<Bullet>bulletVector = new Vector <>();
private Vector<Bullet>bossBulletVector = new Vector <>();
private Vector<Bullet>boomVector = new Vector <>();
private int count;
private GameSoundPool gameSoundPool;
运用了继承。继承:继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为
public class Boom extends Bullet
运用了多态。多态:多态是同一个行为具有多个不同表现形式或形态的能力。
Paint paint = new Paint();
BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), R.mipmap.img_bg_level_3));
plane = new Myplane(BitmapFactory.decodeResource(getResources(), R.mipmap.myplane),BitmapFactory.decodeResource(getResources(), R.mipmap.myhp));
BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), R.mipmap.bossplane));
方法的重载:方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。
public boolean isCollision(BossPlane bossPlane) {
public boolean isCollision(Bullet bullet){
八、我的收获与感悟。
时间 如白驹过隙一般,转眼之间为期30天的java实训 已步入尾声,还没来得及挥手,就 已划上圆满的句号。这次的实训主要是培训我们对java基础的理解和巩固。第一天对江哥的陌生到最后的依依不舍。这个在我心中像神一样男人,给我造成了巨大的伤害,上java实训课感到就是紧张与害怕。因为,自己就像一个毫无经验的小兵立刻被推上战场。到今天我还是有很多不是很懂的地方,我知道这个是我理解能力比较差而已,不过,江哥老对我们说:“师傅领进门,修行靠个人”。我还是要多去看人家优秀的代码,去分析人家的思路。江哥也对我们说了生活哲理。让我们有了除了知识之外的其他收获。我佩服我们班的那些理解能力强的,但是我不会因为他们影响自己的节奏,去强求自己,先打好基础,才能去更好的进行下一阶段的学习。到了大学,什么都是自己的,学习不会有人去管你,谈恋爱也不会有人去管你,不过,你应该有自己的主见,什么事情自己可以去做,什么事情自己不要该去做,不要害怕失败,一次不会就再来一次。总会成功的。男生要不拥有爱情要不拥有自己的事业。大学这个小社会中我们如何去实现自己的事业就是好好去完成自己的学业,我知道自己有时候会自我放弃,但是,好在自己能去弥补。时刻是有限的,人生总得离离合合,幸好文字能够记录历史,让我们的记忆得以长存。此次的实训是我深入社会的起点,让我了解到在社会中生存就应具备的各种潜质,然给我学到了许多知识和经验,这是在课本中所学不到的。透过此次实训,让我能够更好的了解自我的不足,了解这个社会的各个方面。从而让我意识到我以后还就应多学些什么,也为自我以后的工作和生活积累了更多的丰富的知识和宝贵经验。让我能够更早的为自我做好职业规划,设定人生目标,向成功迈进一大步。我也向未来的自己说一句“加油,我一定会变成我想变成的样子的”。