Android游戏之仿 微信飞机大战

暑假实训的一个程序,也是我第一次接触java和android开发,模仿微信的飞机大战,效果图如下:

         

     

一:素材整理

素材来自网络,下载地址在此:http://download.csdn.net/detail/bifei8718/7665447

二:遇到的问题

使用Android Suifaceview,之前开发时候遇到很多问题,比如闪屏、按home后再进入黑屏等问题,解决方法在其他转载文章中,

SurfaceView屏幕闪烁与双缓冲

surfaceview 双缓冲

【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!

三:java继承、派生和多态的使用

由于有很多种敌机,所以可以抽象出一个基类,我定义了一个Things的基类。

(1)Things的基类

package com.swust.gamedeom;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RectF;

public abstract class Things {
	
	public float x ;
	public float y ;
	public float r; //物体的right
	public float b;//物体的buttom
	
	public float speed ;
	public float width;
	public float hight;
	
	public Bitmap  Image;
	public Resources res;
	public int  lifeValue;
	private int Sorces;
	
	public int getLifeValue() {
		return lifeValue;
	}

	public void setLifeValue(int lifeValue) {
		this.lifeValue = lifeValue;
	}

	public void lifeReduce(){
		lifeValue--;
	}
	public float getR() {
		return r;
	}
	public void setR(float r) {
		this.r = r;
	}
	public float getB() {
		return b;
	}
	public void setB(float b) {
		this.b = b;
	}
	public float getX() {
		return x;
	}
	public void setX(float x) {
		this.x = x;
	}
	public float getY() {
		return y;
	}
	public void setY(float y) {
		this.y = y;
	}
	public float getWidth() {
		return width;
	}
	public void setWidth(float width) {
		this.width = width;
	}
	public float getHight() {
		return hight;
	}
	public void setHight(float hight) {
		this.hight = hight;
	}
	public void SetSpeed(float speed){
		this.speed = speed;
	}
	public RectF getrectf(){
		return new RectF(x, y, x+width, y+hight);
	}
	public int getSorces() {
		return Sorces;
	}
	public void setSorces(int sorces) {
		Sorces = sorces;
	}	

	public abstract void Draw(Canvas canvas);//绘图
	public abstract void Move();//物体移动
	public abstract int check();//物体状态检查
	public abstract void playsound(MainActivity act);//播放物体被销毁时的音效

}
然后 分别派生出

自身飞机---Plane

package com.swust.gamedeom;
import java.util.ArrayList;

import com.swust.gamedeom.R;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;


public class Plane extends Things{

	private Bitmap Image1;
	private Bitmap Image2;
	private Bitmap Image3;
	private Bitmap Image4;
	private int  num;
	public Plane(Resources r,float Swidth,float Sheight){
		res = r;
		Image = BitmapFactory.decodeResource(res, R.drawable.hero1);
		width = Image.getWidth();
		hight = Image.getHeight();
		setX((Swidth-width)/2);
		setY(Sheight-hight);
		setR(x+width);
		setB(y+hight);
		SetSpeed(10);
		setLifeValue(1);
		Init();
	}
	/**
	 * 记载图片资源
	 */
	public void Init(){
		Image1 = BitmapFactory.decodeResource(res, R.drawable.hero_blowup_n1);
		Image2 = BitmapFactory.decodeResource(res, R.drawable.hero_blowup_n2);
		Image3 = BitmapFactory.decodeResource(res, R.drawable.hero_blowup_n3);
		Image4 = BitmapFactory.decodeResource(res, R.drawable.hero_blowup_n4);
		num=0;
	}
	/**
	 * 绘制飞机
	 */
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(getLifeValue()==1){
			canvas.drawBitmap(Image, x, y,null);
		}
		else {
			num++;
			if(num==1){
				canvas.drawBitmap(Image1, x, y,null);
			}
			else if(num==2){
				canvas.drawBitmap(Image2, x, y,null);
			}
			else if(num==3){
				canvas.drawBitmap(Image3, x, y,null);
			}
			else if(num==4){
				canvas.drawBitmap(Image4, x, y,null);
			}
		}
		//Move();
	}
	@Override
	public void Move() {
		// TODO Auto-generated method stub
	}
	/**
	 * 检查飞机状态
	 */
	public int check(){
		if(num>=4){
			return 1;
		}
		else {
			return 0;
		}
	}
	/**
	 * 碰撞检测
	 * @param EmPlanelist  敌方飞机集合
	 * @param act	声音控制
	 */
	public void hitenemy( ArrayList<Things> EmPlanelist,MainActivity act){
		RectF rect1 = new RectF(x+15,y+15,x+width-15,y+hight-15);
		RectF rect2;
		for (int i = 0; i < EmPlanelist.size(); i++) {
			 Things emPlane = EmPlanelist.get(i);
			 rect2 = emPlane.getrectf();
			if(rect1.intersect(rect2)&& emPlane.getLifeValue()!=0&&this.getLifeValue()!=0){
				this.lifeReduce();
				emPlane.lifeReduce();
				act.stopSound();
				act.playSound(7, 0);
			}
		}
	}
	/**
	 * 
	 * @param ufo 道具
	 * @param act 声音
	 * @return 如果拾取到道具,返回true,否则false
	 */
	public boolean GetUfo(Ufo ufo,MainActivity act){
		RectF rect1 = this.getrectf();
		RectF rect2 = ufo.getrectf();
		if(rect1.intersect(rect2)){
			ufo.lifeReduce();
			act.playSound(8, 0);
			return true;
		}
		return false;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
		act.playSound(7, 0);
	}
}

背景绘制---BackGround

package com.swust.gamedeom;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Typeface;

public  class BackGround extends Things{

	private Bitmap ImageStart;//开始游戏图片
	private Bitmap bitmap1;//游戏背景运行图
	private Bitmap bitmap2;
	private Bitmap ImageOver;//游戏结束小图
	private Bitmap ImageAgain;//重新开始游戏图
	private Bitmap ImageContinue;//继续游戏图
	private Bitmap ImagePassue;//暂停游戏图
	private Bitmap bitmapover;//游戏结束背景图
	private Bitmap LoadImage1;//游戏加载图
	private Bitmap LoadImage2;
	private Bitmap LoadImage3;
	private Bitmap LoadImage4;
	private Bitmap titleImage;
	private Bitmap ImageMusicClose;//音乐开关图
	private Bitmap ImageMusicOpen;
	private float top = 0;
	private int Statue;//游戏状态
	private int Score;//游戏分数
	private Paint paint;
	private int num = 0;
	private MainActivity act;
	private boolean flag;
	private int highScore;//最高分
	private boolean isplay;
	private Paint sorcePaint;
	
	public void setAct(MainActivity act) {
		this.act = act;
	}
	public void setSources(int Score) {
		this.Score = Score;
	}
	public int getStatue() {
		return Statue;
	}
	public void setStatue(int statue,boolean isplay) {
		Statue = statue;
		this.isplay = isplay;
	}
	public BackGround(Resources r,float SWidth,float SHeight,Paint paint){
		res =r;
		ImageAgain = BitmapFactory.decodeResource(res,R.drawable.game_again);
		ImageStart = BitmapFactory.decodeResource(res,R.drawable.game_start);
		ImageContinue = BitmapFactory.decodeResource(res,R.drawable.game_continue);
		ImageOver = BitmapFactory.decodeResource(res,R.drawable.game_over);
		ImagePassue = BitmapFactory.decodeResource(res,R.drawable.game_pause_nor);
		
		bitmap1 = CreatBitmap(SWidth, SHeight,R.drawable.background);
		bitmap2 = CreatBitmap(SWidth, SHeight,R.drawable.background);
		bitmapover = CreatBitmap(SWidth, SHeight,R.drawable.gameover);
		
		LoadImage1 = BitmapFactory.decodeResource(res,R.drawable.game_loading1);
		LoadImage2 = BitmapFactory.decodeResource(res,R.drawable.game_loading2);
		LoadImage3 = BitmapFactory.decodeResource(res,R.drawable.game_loading3);
		LoadImage4 = BitmapFactory.decodeResource(res,R.drawable.game_loading4);
		titleImage = BitmapFactory.decodeResource(res,R.drawable.shoot_copyright);
		
		ImageMusicClose = BitmapFactory.decodeResource(res,R.drawable.bkmusic_close);
		ImageMusicOpen = BitmapFactory.decodeResource(res,R.drawable.bkmusic_play);
		
		this.hight = SHeight;
		this.width = SWidth;
		this.paint = paint;
		
		flag = true;
		SetSpeed(3);
		isplay = true;
		
		sorcePaint = new Paint();
		Typeface font = Typeface.create(Typeface.SANS_SERIF,Typeface.BOLD);
		sorcePaint.setTypeface(font);
		sorcePaint.setColor(0xff949694);
		sorcePaint.setTextSize(75);	
	}
	/**
	 * 根据屏幕尺寸动态调整背景图片大小
	 * @param SWidth  屏幕宽度
	 * @param SHeight 屏幕高度
	 * @param ID  图片ID
	 * @return  调整后的图片
	 */
	
	public Bitmap CreatBitmap(float SWidth,float SHeight,int ID){
		Bitmap bitMap = BitmapFactory.decodeResource(res,ID);
		int widtht = bitMap.getWidth();
		int height = bitMap.getHeight();
		
		int newWidth = (int)SWidth;
		int newHeight =(int)SHeight;
		
		float scaleWidth = ((float) newWidth) / widtht;
		float scaleHeight = ((float) newHeight) / height;
		
		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);
		
		bitMap = Bitmap.createBitmap(bitMap, 0, 0, widtht, height, matrix, true);
		return bitMap;
	}
	/**
	 * 根据游戏状态绘制相应图片
	 */
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(Statue == 1){
			canvas.drawBitmap(bitmap1, 0, top - hight, null);
			canvas.drawBitmap(bitmap2, 0, top, null);
			canvas.drawBitmap(ImagePassue, 0, 0, null);
			canvas.drawText(""+Score,ImagePassue.getWidth()+10, 45, paint);
			Move();
			flag = true;
		}
		else if(Statue == 2){
			 canvas.drawBitmap(bitmap1, 0, 0, null);
			 if(isplay){
				 canvas.drawBitmap(ImageMusicOpen, width-ImageMusicOpen.getWidth(), 0, null);
			 }
			 else{
				 canvas.drawBitmap(ImageMusicClose, width-ImageMusicClose.getWidth(), 0, null);
			 }
			 canvas.drawBitmap(ImageContinue, (width-ImageContinue.getWidth())/2,hight/2-150, null);
			 canvas.drawBitmap(ImageAgain, (width-ImageAgain.getWidth())/2,hight/2, null);
			 canvas.drawBitmap(ImageOver, (width-ImageOver.getWidth())/2,hight/2+150, null);
		}
		else if(Statue == 3){
			if(flag){	
				flag = false;	
				String string = SDcardData.ReadDate();
				highScore = Integer.valueOf(string).intValue();
				if(highScore<Score){
					highScore = Score;
				}	
				SDcardData.WriteData(String.valueOf(highScore));
			}
			canvas.drawBitmap(bitmapover, 0, 0, null);
			canvas.drawText(""+highScore, width/4+20, 80, paint);
			canvas.drawText(""+Score, width/2-80, hight/2, sorcePaint);
			canvas.drawBitmap(ImageAgain, (width-ImageAgain.getWidth())/2,hight-200, null);
			
		}
		else if(Statue ==0){
			 canvas.drawBitmap(bitmap1, 0, 0, null);
			 canvas.drawBitmap(titleImage, (width-titleImage.getWidth())-100, hight/4-50, null);
			 if(act.Loadflag == true){
				 canvas.drawBitmap(ImageStart, (width-ImageStart.getWidth())/2,hight-200, null);
			 }
			 num++;
			 if(num<10){
				 canvas.drawBitmap(LoadImage1, (width-LoadImage1.getWidth())/2, hight/2+50, null);
			 }
			 else if(num>=10 && num<20){
				 canvas.drawBitmap(LoadImage2, (width-LoadImage2.getWidth())/2, hight/2+50, null);
			 }
			 else if(num>=20&& num<30){
				 canvas.drawBitmap(LoadImage3, (width-LoadImage3.getWidth())/2, hight/2+50, null);
			 }
			 else if(num==30){
				 canvas.drawBitmap(LoadImage4, (width-LoadImage4.getWidth())/2, hight/2+50, null);
				 num = 0;
			 }
		}
	}
	/**
	 * 背景图片移动
	 */
	@Override
	public void Move() {
		// TODO Auto-generated method stub
		top += speed;
		if (top >= (hight + speed))
			top = 0;
	}
	@Override
	public int check() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
	}
}

敌机---EmptyPlane

package com.swust.gamedeom;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class EmptyPlane extends Things{

	private float Height;
	private int num;
	private Bitmap Image1;
	private Bitmap Image2;
	private Bitmap Image3;
	private Bitmap Image4;
	
	public EmptyPlane(Resources r,Float SWidth,float SHeight){
		this.res = r;
		Image = BitmapFactory.decodeResource(r, R.drawable.enemy1);
		width = Image.getWidth();
		hight = Image.getHeight();
		setX((float)(Math.random()*(SWidth-width)));
		setY(0);
		SetSpeed(7);//15
		this.Height = SHeight;
		setLifeValue(1);
		Init();
		setSorces(10);
	}
	public void Init(){
		Image1 = BitmapFactory.decodeResource(res, R.drawable.enemy1_down1);
		Image2 = BitmapFactory.decodeResource(res, R.drawable.enemy1_down2);
		Image3 = BitmapFactory.decodeResource(res, R.drawable.enemy1_down3);
		Image4 = BitmapFactory.decodeResource(res, R.drawable.enemy1_down4);
		num=0;
	}
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(getLifeValue()==1){
			canvas.drawBitmap(Image, x, y,null);
			Move();
		}
		else {
			switch (num/3) {
			case 0:
				canvas.drawBitmap(Image1, x, y,null);
				break;
			case 1:
				canvas.drawBitmap(Image2, x, y,null);
				break;
			case 2:
				canvas.drawBitmap(Image3, x, y,null);
				break;
			case 3:
				canvas.drawBitmap(Image4, x, y,null);
				break;
			default:
				break;
			}
			num++;
		}
	}
	@Override
	public void Move() {
		// TODO Auto-generated method stub
		y += speed;
	}
	@Override
	public int check(){
		if(num>=12){
			return 1;
		}
		if(y>Height){
			return 2;
		}
		return 0;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
		act.playSound(3, 0);
	}
}

敌机大飞机-- EmBigPlane

package com.swust.gamedeom;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class EmBigPlane extends Things{
	
	private float Height;
	private int num;
	private Bitmap Image1;
	private Bitmap Image2;
	private Bitmap Image3;
	private Bitmap Image4;
	private Bitmap ImageHit;
	public EmBigPlane(Resources r,Float SWidth,float SHeight){
		this.res = r;
		Image = BitmapFactory.decodeResource(r, R.drawable.enemy2);
		ImageHit = BitmapFactory.decodeResource(r, R.drawable.enemy2_hit);
		width = Image.getWidth();
		hight = Image.getHeight();
		setX((float)(Math.random()*(SWidth-width)));
		setY(0);
		SetSpeed(5);//13
		this.Height = SHeight;
		setLifeValue(10);
		Init();
		setSorces(50);
	}
	public void Init(){
		Image1 = BitmapFactory.decodeResource(res, R.drawable.enemy2_down1);
		Image2 = BitmapFactory.decodeResource(res, R.drawable.enemy2_down2);
		Image3 = BitmapFactory.decodeResource(res, R.drawable.enemy2_down3);
		Image4 = BitmapFactory.decodeResource(res, R.drawable.enemy2_down4);
		num=0;
	}
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(getLifeValue()<=10 && getLifeValue()>=5){
			canvas.drawBitmap(Image, x, y,null);
			Move();
		}
		else if(getLifeValue()<5&& getLifeValue()>=1){
			canvas.drawBitmap(ImageHit, x, y,null);
			Move();
		}
		else {
			switch (num/3) {
			case 0:
				canvas.drawBitmap(Image1, x, y,null);
				break;
			case 1:
				canvas.drawBitmap(Image2, x, y,null);
				break;
			case 2:
				canvas.drawBitmap(Image3, x, y,null);
				break;
			case 3:
				canvas.drawBitmap(Image4, x, y,null);
				break;
			default:
				break;
			}
			num++;
		}
	}
	@Override
	public void Move() {
		// TODO Auto-generated method stub
		y+=speed;
	}
	@Override
	public int check(){
		if(num>=12){
			return 1;
		}
		if(y>Height){
			return 2;
		}
		return 0;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
		act.playSound(4, 0);
	}
	
}

敌机Boss--EmBoss

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import com.swust.gamedeom.R;

public class EmBoss extends Things{

	private float Height;
	private float Width;
	private int num;
	
	private Bitmap Image1;
	private Bitmap Image2;
	private Bitmap Image3;
	private Bitmap Image4;
	private Bitmap Image5;
	private Bitmap Image6;
	private Bitmap ImageHit;
	
	public EmBoss(Resources r,float SWidth,float SHeight){
		this.res = r;
		Image = BitmapFactory.decodeResource(r, R.drawable.enemy3_n1);
		ImageHit = BitmapFactory.decodeResource(r, R.drawable.enemy3_hit);
		width = Image.getWidth();
		hight = Image.getHeight();
		setX((float)(Math.random()*(SWidth-width)));
		setY(-hight);
		SetSpeed(2);
		this.Height = SHeight;
		this.Width = SWidth;
		setLifeValue(60);
		Init();
		setSorces(300);
	}
	public void Init(){
		Image1 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down1);
		Image2 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down2);
		Image3 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down3);
		Image4 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down4);
		Image5 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down5);
		Image6 = BitmapFactory.decodeResource(res, R.drawable.enemy3_down6);
		num=0;
	}
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(getLifeValue()<=60 && getLifeValue()>=30){
			canvas.drawBitmap(Image, x, y,null);
			Move();
		}
		else if(getLifeValue()<30&& getLifeValue()>=1){
			canvas.drawBitmap(ImageHit, x, y,null);
			Move();
		}
		else {
			switch (num/3) {
			case 0:
				canvas.drawBitmap(Image1, x, y,null);
				break;
			case 1:
				canvas.drawBitmap(Image2, x, y,null);
				break;
			case 2:
				canvas.drawBitmap(Image3, x, y,null);
				break;
			case 3:
				canvas.drawBitmap(Image4, x, y,null);
				break;
			case 4:
				canvas.drawBitmap(Image5, x, y,null);
				break;
			case 5:
				canvas.drawBitmap(Image6, x, y,null);
				break;
			default:
				break;
			}
			num++;
		}
	}
	@Override
	public void Move() {
		// TODO Auto-generated method stub 
		 if(y>=(Height/2-hight)){
			y-=speed;
		}
		 else{
			 y+=speed;
		 }
	}
	@Override
	public int check(){
		if(num>=18){
			return 1;
		}
		return 0;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
		act.playSound(5, 0);
	}
}

道具---Ufo

package com.swust.gamedeom;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class Ufo extends Things{
	private Bitmap Image2;
	private float Height;
	private int  UfoFlag = 0;
	
	public int getUfoFlag() {
		return UfoFlag;
	}
	public void setUfoFlag(int ufoFlag) {
		UfoFlag = ufoFlag;
	}
	public Ufo(Resources r,int flag,float SWidth,float SHeight){
			res = r;
			Image = BitmapFactory.decodeResource(res, R.drawable.ufo1);
			Image2 = BitmapFactory.decodeResource(res, R.drawable.ufo2);
			width = Image.getWidth();
			hight = Image.getHeight();
			Height = SHeight;
			SetSpeed(4);//10
			setUfoFlag(flag);
			setLifeValue(1);
			if(UfoFlag ==1){
				setX(SWidth-width-50);
			}
			else if(UfoFlag == 2){
				setX(50);
			}
	}
	public int check(){
		if(getLifeValue()==0){
			return 1;
		}
		if(y>Height){
			return 2;
		}
		return 0;
	}
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(UfoFlag ==1){
			canvas.drawBitmap(Image, x, y,null);
		}
		else if(UfoFlag ==2){
			canvas.drawBitmap(Image2, x, y,null);
		}
		Move();
	}

	@Override
	public void Move() {
		// TODO Auto-generated method stub
		y+=speed;
	}
	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
		act.playSound(8, 0);
	}

}

子弹---Bullet

package com.swust.gamedeom;

import java.util.ArrayList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;

public class Bullet extends Things{
	
	private Bitmap Image2;
	private Bitmap Image3;
	private int SuperBullet;

	public void setSuperBullet(int superBullet) {
		SuperBullet = superBullet;
	}

	public Bullet(Resources r){
		res = r;
		Image = BitmapFactory.decodeResource(res, R.drawable.bullet1);
		Image2 = BitmapFactory.decodeResource(res, R.drawable.bullet2);
		Image3 = BitmapFactory.decodeResource(res, R.drawable.bomb);
		width = Image.getWidth();
		hight = Image.getHeight();
		SetSpeed(60);
		setLifeValue(1);
		SuperBullet = 0;
	}
	
	@Override
	public void Draw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(SuperBullet == 0){
			canvas.drawBitmap(Image, x, y,null);
		}
		else if(SuperBullet == 1){
			canvas.drawBitmap(Image2, x, y,null);
		}
		else if(SuperBullet ==2){
			canvas.drawBitmap(Image3, x, y,null);
		}
		Move();
	}
	@Override
	public void Move() {
		// TODO Auto-generated method stub
		y-=speed;
	}
	@Override
	public int check() {
		if(getLifeValue()==0){
			return 1;
		}
		if(this.y<0){
			return 2;
		}
		return 0;
	}
	/**
	 * 子弹和敌机的碰撞检测
	 * @param EmPlanelist  敌机集合
	 * @param act  声音控制
	 */
	public void hitenemy( ArrayList<Things>EmPlanelist,MainActivity act){
		RectF rect1 = this.getrectf();
		RectF rect2;
		for (int i = 0; i < EmPlanelist.size(); i++) {
			 Things emPlane = EmPlanelist.get(i);
			 rect2 = emPlane.getrectf();
			if(rect1.intersect(rect2)&& emPlane.getLifeValue()!=0){
				this.lifeReduce();
				emPlane.lifeReduce();
			}
		}
	}

	@Override
	public void playsound(MainActivity act) {
		// TODO Auto-generated method stub
	}
}

四:简单工厂模式的使用

package com.swust.gamedeom;

import android.content.res.Resources;

public class EmPlaneFactory {
	
	private EmPlaneFactory(){
		
	}
	public static Things getEmPlane(int x,Resources r,Float SWidth,float SHeight){
		Things emPlane = null;
		switch (x) {
		case 1:
			emPlane = new EmptyPlane(r,SWidth,SHeight);
			break;
		case 2:
			emPlane = new EmBigPlane(r,SWidth,SHeight);
			break;
		case 3:
			emPlane = new EmBoss(r,SWidth,SHeight);
			break;
		}
		return emPlane;
	}	
}

五:主程序和音频加载

package com.swust.gamedeom;

import java.io.IOException;
import java.util.HashMap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;


@SuppressLint("UseSparseArrays")
public class MainActivity extends Activity implements Runnable {
	
    private MySuifaceView view;
    private MediaPlayer mMediaPlayer;  
	private SoundPool sp;
    private HashMap<Integer, Integer> spMap;
    public boolean Loadflag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE); 		
	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  // 隐藏状态栏
	DisplayMetrics metric = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metric);
        
        Paint paint = new Paint();
	Typeface font = Typeface.create(Typeface.SANS_SERIF,Typeface.BOLD);
	paint.setTypeface(font);
	paint.setColor(0xff949694);
	paint.setTextSize(55);
        
        float width = (float)metric.widthPixels;
        float height = (float) metric.heightPixels;
        Loadflag = false;
		view = new MySuifaceView(this,width,height,this,paint);
        setContentView(view); 
        new Thread(this).start();
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    public void InitSound() {
    	
    	mMediaPlayer = MediaPlayer.create(this, R.raw.game_music); 
        sp = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
        spMap = new HashMap<Integer, Integer>();
        spMap.put(2, sp.load(this, R.raw.bullet, 1));
        spMap.put(3, sp.load(this, R.raw.enemy1_down,1));
        spMap.put(4, sp.load(this, R.raw.enemy2_down,1));
        spMap.put(5, sp.load(this, R.raw.enemy3_down,1));
        spMap.put(6, sp.load(this, R.raw.use_bomb,1));
        spMap.put(7, sp.load(this, R.raw.game_over,1));
        spMap.put(8, sp.load(this, R.raw.get_bomb,1));
        Loadflag = true;
    }

    public void playSound(int sound, int number) {
    	
    	if(sound==1){
    	     if (!mMediaPlayer.isPlaying()) {  
                mMediaPlayer.start();  
            }  
    	}
    	else{
    		AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
    		float audioMaxVolumn = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    		float volumnCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC);
    		float volumnRatio = volumnCurrent / audioMaxVolumn;
    		sp.play(spMap.get(sound), volumnRatio, volumnRatio, 1, number,  1f);
    	}  
    }
    public void stopSound(){
    	
    	if (mMediaPlayer.isPlaying()){  
            mMediaPlayer.pause();  
        }  
    }
    @Override
    protected void onResume() {
    	// TODO Auto-generated method stub
    	setContentView( view );
    	super.onResume();
    }

	@Override
	public void run() {
		// TODO Auto-generated method stub
		 InitSound();
		 try {
			mMediaPlayer.prepare();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	  
}
这里通过一个线程来单独加载音频,使用音频池。

六:Suifaceview 类(核心)

package com.swust.gamedeom;

import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MySuifaceView extends SurfaceView implements Callback, Runnable {

	private ArrayList<Bullet> bulletlist = new ArrayList<Bullet>();
	private ArrayList<Things> EmPlanelist = new ArrayList<Things>();
	
	private ArrayList<Bomb> bomblist = new ArrayList<Bomb>();
	private Ufo ufo_double;
	private Ufo ufo_super;
	private Plane plane;
	private SurfaceHolder mSurfaceHolder = null;
	private boolean mbloop = false;
	private BackGround bk;
	private MainActivity activity;
	
	private Point point = new Point();
	private Rect rect;
	private boolean canDrag = false;
	private int offsetX = 0, offsetY = 0;
	private int Count = 0;
	private int bossCount = 0;
	private float SWidth;
	private float SHeight;
	private int Score;
	private int statue;
	private Rect rectbtn;
	private Canvas canvas=null;
	private int Emcreat;
	private int EmBicreat;
	private int EmBosscreat;
	
	private Rect rectMusic;
	private Rect rectPassue;
	private Rect rectAgain;
	private Rect rectContinue;
	private Rect rectOver;
	
	private boolean bullet_double;
	private boolean bullet_super;
	private boolean bombScreen;
	private int bulletTime;
	private int bulletcreat;
	private Rect rectbomb;
	private boolean isPlay;
	
	@TargetApi(19)
	@SuppressLint("NewApi")
	public MySuifaceView(Context context, float width, float height,MainActivity act,Paint paint) {
		super(context);
		// TODO Auto-generated constructor stub
		// 添加回调函数
		mSurfaceHolder = this.getHolder();
		mSurfaceHolder.addCallback(this);
		this.setFocusable(true);
		this.setKeepScreenOn(true);
		this.activity = act;
		Init(width,height);
		bk = new BackGround(getResources(),width, height,paint);
		SWidth = width;
		SHeight = height;
		isPlay = true;
		statue =0;
		
		rectbtn = new Rect((int)(width-300)/2,(int)(height-200),(int)(width/2+150),(int)(height-150));
		rectPassue = new Rect(0,0,150,150);
		rectContinue = new Rect((int)(width-300)/2,(int)(height/2-150),(int)(width/2+150),(int)(height/2-90));
		rectAgain =  new Rect((int)(width-300)/2,(int)(height/2),(int)(width/2+150),(int)(height/2+60));
		rectOver = new Rect((int)(width-300)/2,(int)(height/2+150),(int)(width/2+150),(int)(height/2+210));
		rectbomb = new Rect(20,(int)(height-100),160,(int)(height));
		rectMusic = new Rect((int)width-50,0,(int)width,50);
	}
	public void Init(float width, float height){
		plane = new com.swust.gamedeom.Plane(getResources(), width, height);
		rect = new Rect((int) plane.getX(), (int) plane.getY(),
				(int) plane.getR(), (int) plane.getB());
		
		bulletcreat = 7;
		Emcreat = 15;
		EmBicreat = 150;
		EmBosscreat = 3379;
		
		Score = 0;
		Count = 0;
		bullet_double = false;
		bullet_super = false;
		bulletTime = 0;
		bombScreen = false;
		bossCount = 0;
		
		
		bulletlist.clear();
		EmPlanelist.clear();
		bomblist.clear();
		ufo_double = null;
		ufo_super = null;
		
		
	}
	public void DrawBitmap(){
		bk.setAct(activity);
		bk.setSources(Score);
		bk.setStatue(statue,isPlay);
		bk.Draw(canvas);
		if(statue == 1){
			plane.Draw(canvas);
			if(plane.check()!=0){
				statue = 3;
				activity.stopSound();
			}
			plane.hitenemy(EmPlanelist,activity);
			if(ufo_double!=null){
				ufo_double.Draw(canvas);
				bullet_double = plane.GetUfo(ufo_double,activity);
				if(ufo_double.check()!=0){
					ufo_double=null;
				}
			}
			if(ufo_super!=null){
				ufo_super.Draw(canvas);
				bullet_super = plane.GetUfo(ufo_super,activity);
				if(ufo_super.check()!=0){
					ufo_super=null;
				}
			}
			for (int i = 0; i < bulletlist.size(); i++) {
				Bullet bullet = bulletlist.get(i);
				bullet.Draw(canvas);
				bullet.hitenemy(EmPlanelist,activity);
				if (bullet.check()!=0) {
					bulletlist.remove(bullet);
					i--;
				}
			}
			for (int i = 0; i < EmPlanelist.size(); i++) {
				Things emPlane = EmPlanelist.get(i);
				if(emPlane.check()==1){
					Score+=emPlane.getSorces();
					emPlane.playsound(activity);
					EmPlanelist.remove(emPlane);
					i--;
				}
				else if(emPlane.check()==2){
					EmPlanelist.remove(emPlane);
					i--;
				}
				else{
					emPlane.Draw(canvas);
				}
			}
			for (int m = 0; m < bomblist.size(); m++) {
					Bomb bomb = bomblist.get(m);
					if(bombScreen){
						bomb.lifeReduce();
						ScreenBomb();
						bombScreen = false;
					}
					if(bomb.check()!=0){
						bomblist.remove(bomb);
						m--;
					}
					else{
						bomb.setBombnum(bomblist.size());
						bomb.Draw(canvas);
					}
			}
		}
	}
	public  void Draw() {
		try {
			 canvas = mSurfaceHolder.lockCanvas();
			 if(canvas!=null){
				 DrawBitmap();
			 }
		} catch (Exception e) {
			// TODO: handle exception
		}
		finally{
			if(canvas!=null)
				mSurfaceHolder.unlockCanvasAndPost(canvas);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		mbloop = true;
		new Thread(this).start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		mbloop = false;
		activity.stopSound();
		isPlay = false;
		statue =2;
	}
	
	@Override
	public void run() {  
        // TODO Auto-generated method stub  
        int SLEEP_TIME=15;  
        while (mbloop) {  
            long start=System.currentTimeMillis();  
            Draw();
            if(statue == 1){
            	Count++;
            	//Adjust();
            	AddEmBigPlane();
            	Addbuilt();
            	AddEmplane();
            	AddEmBoss();
            	AddUfo();
            	Addbomb();
            	if(bullet_double){
            		checktime();
            	}
            }
            long end=System.currentTimeMillis();    
            if((end-start)<SLEEP_TIME){  
                try {    
                    Thread.sleep(SLEEP_TIME-(end-start));    
                } catch (InterruptedException e) {    
                    // TODO Auto-generated catch block    
                    e.printStackTrace();    
                }    
            }    
        }  
	}
	public void ScreenBomb(){
		for (int i = 0; i < EmPlanelist.size(); i++) {
			 Things emPlane = EmPlanelist.get(i);
			    emPlane.setLifeValue(0);
		}
	}
	public void Addbomb(){
		if(bullet_super){
			Bomb bomb = new Bomb(getResources(), SWidth, SHeight);
			bomblist.add(bomb);
			bullet_super = false;
		}
	}
	public void Adjust(){
		if((Score+10)%1000 == 0){
			Emcreat-=1;
			EmBicreat-=5;
		}
	}
	public void checktime(){
		bulletTime++;
		if(bulletTime % 299==0){
			bullet_double = false;
			bulletTime = 0;
		}
	}
	public void AddUfo(){
		
		if(Count%579==0){
			int num = (int) (Math.random()*9+1);
			if(num%3==0){
				ufo_super = new Ufo(getResources(), 2, SWidth, SHeight);
			}
			else {
				ufo_double = new Ufo(getResources(), 1, SWidth, SHeight);
			}
		}
		
	}
	public void Addbuilt() {
		
		if (Count % bulletcreat== 0 ) {
			if(!bullet_double){
				Bullet bullet = BulletFactory.getBullet(getResources(),
						plane.getX()+plane.getWidth()/2-5, plane.getY()-10);
				bulletlist.add(bullet);
				activity.playSound(2, 0);
			}
			else {
				Bullet bullet1 = BulletFactory.getBullet(getResources(),
						plane.getX()+plane.getWidth()/2-30, plane.getY()-10);
				bullet1.setSuperBullet(1);
				Bullet bullet2 = BulletFactory.getBullet(getResources(),
						plane.getX()+plane.getWidth()/2+30, plane.getY()-10);
				bullet2.setSuperBullet(1);
				bulletlist.add(bullet1);
				bulletlist.add(bullet2);
				activity.playSound(2, 0);
			}
		}
	}
	public void AddEmplane(){
		if(Count%Emcreat==0 ){
			Things emPlane = EmPlaneFactory.getEmPlane(1,getResources(), SWidth, SHeight);
			EmPlanelist.add(emPlane);
		}
	}
	public void AddEmBigPlane(){
		if(Count%EmBicreat==0){
			Things emPlane = EmPlaneFactory.getEmPlane(2,getResources(), SWidth, SHeight);
			EmPlanelist.add(emPlane);
		}
	}
	public void AddEmBoss(){
		if(Count%EmBosscreat==0){
			Things emPlane = EmPlaneFactory.getEmPlane(3,getResources(), SWidth, SHeight);
			EmPlanelist.add(emPlane);
			Count = 0;
		}
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		
		case MotionEvent.ACTION_DOWN:
			point.x = (int) event.getX();
			point.y = (int) event.getY();
			if(statue == 3|| statue == 0){
				if(rectbtn.contains(point.x, point.y)){
					Init(SWidth, SHeight);
					if(isPlay){
						activity.playSound(1, -1);
					}
					statue=1;
				}
			}
			if(statue == 1){
				if(rectPassue.contains(point.x,point.y)){
					statue = 2;
				}
				if(rectbomb.contains(point.x,point.y)&& bomblist.size()>0){
					bombScreen = true;
				}
			}
			if(statue == 2){
				if(rectContinue.contains(point.x,point.y)){
					statue=1;
				}
				else if(rectAgain.contains(point.x,point.y)){
					Init(SWidth, SHeight);
					statue=1;	
				}
				else if(rectOver.contains(point.x,point.y)){
					activity.finish();
				}
				else if(rectMusic.contains(point.x, point.y)){
					if(isPlay){
						activity.stopSound();
						isPlay = false;
					}
					else{
						activity.playSound(1, -1);
						isPlay = true;
					}
				}
			}
			if (rect.contains(point.x, point.y)) {
				canDrag = true;
				offsetX = point.x - rect.left;
				offsetY = point.y - rect.top;
			}
			break;
		case MotionEvent.ACTION_MOVE:
			if(canDrag){
			rect.left = (int) event.getX() - offsetX;
			rect.top = (int) event.getY() - offsetY;
			rect.right = rect.left + (int) plane.getWidth();
			rect.bottom = rect.top + (int) plane.getHight();
			if (rect.left < 0) {
				rect.left = 0;
				rect.right = rect.left + (int) plane.getWidth();
			}
			if (rect.right > getMeasuredWidth()) {
				rect.right = getMeasuredWidth();
				rect.left = rect.right - (int) plane.getWidth();
			}
			if (rect.top < 0) {
				rect.top = 0;
				rect.bottom = rect.top + (int) plane.getHight();
			}
			if (rect.bottom > getMeasuredHeight()) {
				rect.bottom = getMeasuredHeight();
				rect.top = rect.bottom - (int) plane.getHight();
			}
			plane.setX((float) rect.left);
			plane.setY((float) rect.top);
			break;
			}
		case MotionEvent.ACTION_UP:
			canDrag = false;
			break;
		default:
			break;
		}
		return true;
	}

}
核心就是DrawBitmap()函数,线程每隔15ms刷屏一次,每次都会调用DrawBitmap()函数去绘制各个物体,这样就会显示出游戏的效果了。

七:总结

总体来说,用了2周的时间,从什么都不会到能做出一个小游戏,学到了很多东西,Surfaceview的认识更深刻了,也参见了好多大神的文章,在此表示感谢!




  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值