暑假实训的一个程序,也是我第一次接触java和android开发,模仿微信的飞机大战,效果图如下:
一:素材整理
素材来自网络,下载地址在此:http://download.csdn.net/detail/bifei8718/7665447
二:遇到的问题
使用Android Suifaceview,之前开发时候遇到很多问题,比如闪屏、按home后再进入黑屏等问题,解决方法在其他转载文章中,
【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的认识更深刻了,也参见了好多大神的文章,在此表示感谢!