1、概述

最近开发一个智能项目,项目对象是某智能早教机器人,这个产品主要定位是儿童益智玩的游戏,并且可以从中学习到相关历史知识等相关知识,其中有个游戏关卡就是去到不同国家,可以玩不同的游戏。领导说要用Android原生做游戏,卧槽,我当时就懵逼,原生做游戏,我就试试开撸吧。

好吧,先上个效果图

思路分析

1、水果
2、背景
3、水果篮子
4、分数
5、时间
6、水果刀
7、当用户touch屏幕时,水果刀跟着移动,水果刀碰到水果,被切成两半

3、SurfaceView模板

我先创建一个类为FruitGameSurfaceView 继承SurfaceView,上代码。


/*** @author Tim*/
@SuppressWarnings("ALL")
public class FruitGameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private SurfaceHolder mHolder;private final Surface surface;public Thread getT() {return t;}public void setT(Thread t) {this.t = t;}public Canvas getCanvas() {return canvas;}public void setCanvas(Canvas canvas) {this.canvas = canvas;}public SurfaceHolder getmHolder() {return mHolder;}public void setmHolder(SurfaceHolder mHolder) {this.mHolder = mHolder;}public boolean isRunning() {return isRunning;}public void setRunning(boolean running) {isRunning = running;}/*** 线程控制开关*/private boolean isRunning;private Thread t;private Canvas canvas;public FruitGameSurfaceView(Context context) {super(context);// TODO Auto-generated constructor stubmHolder = getHolder();mHolder.addCallback(this);//可获得焦点setFocusable(true);setFocusableInTouchMode(true);//设置常亮setKeepScreenOn(true);surface = mHolder.getSurface();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isRunning = true;t = new Thread(this);t.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubisRunning=false;}protected void myDraw(Canvas canvas) {}@Overridepublic void run() {//不断绘制while (isRunning){long start = System.currentTimeMillis();draw();long end = System.currentTimeMillis();try{if (end - start < 50){Thread.sleep(50 - (end - start));}} catch (InterruptedException e){e.printStackTrace();}}}private void draw() {if(mHolder != null) {canvas = mHolder.lockCanvas();}try {if (canvas != null && mHolder != null &&surface != null && surface.isValid()) {myDraw(canvas);}} catch (Exception e) {e.printStackTrace();}finally {if (canvas!=null){mHolder.unlockCanvasAndPost(canvas);}}}
}

这个模板类,在HongYang前辈哪里已经学习过来的,可以直接拷贝,在此类基础上编写。

4、绘制相关

我再创建一个类继承我的FruitGameSurfaceView,这个类叫MyGameView专注于刷新绘制。

 //专用于绘制屏幕@Override protected void myDraw(Canvas canvas) {super.myDraw(canvas);//用户画背景drawBg(canvas);//画水果篮子drawFruitBox(canvas);//画刀光drawBlade(canvas);if (isOpen) {//到了计算好的时间就生成精灵if (mNextTime < System.currentTimeMillis()) {generateSpirit();
//          mSoundPool.play(mExplodeSoundId, 1, 1, 1, 0, 1);nextGenTime();}}
//      if(mNextTimeBoom<System.currentTimeMillis()){//          //画炸弹
//          drawBoom();
//          nextGenTimeBoom();
//      }//绘制时间drawTime(canvas);//检查精灵是否还在屏幕内,不在屏幕内则移除checkSpirites();//画水果drawSpirites(canvas);//初始化切到水果isHit();
//      //初始化撞击炸弹
//      isHitBomb();
//      //绘制分数drawGrades(canvas);}

1、绘制相关代码

  /*** 绘制背景*/private void drawBg(Canvas canvas) {//初始化图片canvas.drawBitmap(mBg, null, mGamePanelRect, null);}
/*** 画水果篮子** @param canvas*/private void drawFruitBox(Canvas canvas) {canvas.drawBitmap(mIcon_fruit_all, null, mRectFFruitAll, null);}
/*** 画刀光到画布上,可以扩展** @param canvas*/private void drawBlade(Canvas canvas) {synchronized (mTrack) {Path path = new Path();Float startX, startY;Float controlX, controlY;Float endX, endY;int strokeWidth = 1;if (mTrack.size() > 1) {endX = mTrack.get(0).x;endY = mTrack.get(0).y;for (int i = 0; i < mTrack.size() - 1; i++) {startX = endX;startY = endY;controlX = mTrack.get(i).x;controlY = mTrack.get(i).y;endX = (controlX + mTrack.get(i + 1).x) / 2;endY = (controlY + mTrack.get(i + 1).y) / 2;path.moveTo(startX, startY);path.quadTo(controlX, controlY, endX, endY);paintBlade.setColor(mBladeColor);paintBlade.setStrokeWidth(strokeWidth++);canvas.drawPath(path, paintBlade);path.reset();}startX = endX;startY = endY;endX = mTrack.get(mTrack.size() - 1).x;endY = mTrack.get(mTrack.size() - 1).y;path.moveTo(startX, startY);path.lineTo(endX, endY);paintBlade.setStrokeWidth(strokeWidth++);paintBlade.setColor(mBladeColor);canvas.drawPath(path, paintBlade);mTrack.remove(0);}}}
/*** 倒计时,右上角时间和页面判断跳转** @param canvas*/private void drawTime(Canvas canvas) {if (System.currentTimeMillis() - mTimeCount > 1000) {mTimeCount = System.currentTimeMillis();count--;if (count == 0) {isOpen = false;
//              Intent intent = new Intent(mContext, GameStopActivity.class);
//              intent.putExtra("Score", ""+ scroe);
//              mContext.startActivity(intent);} else {}}if (count <= 0) {canvas.drawText("Time:" + 0, width - 250, 130, timePaint);} else {canvas.drawText("Time:" + count, width - 250, 120, timePaint);}}
/*** 画精灵到画布上** @param canvas*/private void drawSpirites(Canvas canvas) {for (int i = 0; i < mSpirits.size(); i++) {mSpirits.get(i).draw(canvas);}
//      for(int i=0;i<mBooms.size();i++){//          mBooms.get(i).draw(canvas);
//      }}
 /*** 初始化切到水果的时候*/private void isHit() {synchronized (mTrack) {for (int i = 0; i < mTrack.size(); i++) {for (int z = 0; z < mSpirits.size(); z++) {if (mTrack.get(i).x > mSpirits.get(z).mCoord.x && mTrack.get(i).x < mSpirits.get(z).mCoord.x + mSpirits.get(z).mDimention.x) {if (mTrack.get(i).y > mSpirits.get(z).mCoord.y && mTrack.get(i).y < mSpirits.get(z).mCoord.y + mSpirits.get(z).mDimention.y) {switch (mSpirits.get(z).getmType()) {case R.drawable.icon_orange:initCutCake(mIcon_orange1, mIcon_orange2, z);Log.e("m", "icon_orange");scroe += 1;break;case R.drawable.icon_pineapple:Log.e("m", "icon_pineapple");initCutCake(mIcon_pineapple2, mIcon_pineapple1, z);scroe += 1;break;case R.drawable.icon_banana:Log.e("m", "icon_banana");initCutCake(mIcon_banana2, mIcon_banana1, z);scroe += 1;break;case R.drawable.icon_lemon:Log.e("m", "icon_lemon");initCutCake(mIcon_lemon1, mIcon_lemon2, z);scroe += 1;break;case R.drawable.icon_mango:Log.e("m", "icon_mango");initCutCake(mIcon_mango1, mIcon_mango2, z);scroe += 1;break;case R.drawable.icon_watermelon:Log.e("m", "icon_watermelon");initCutCake(mIcon_watermelon2, mIcon_watermelon1, z);scroe += 1;break;default:break;}}}}}}}
  /*** 绘制分数2*/@SuppressLint("WrongConstant")private void drawGrades(Canvas canvas) {String grade = scroe + "";canvas.save(Canvas.MATRIX_SAVE_FLAG);
//        canvas.translate(width / 2 - grade.length() * mSingleGradeWidth / 2,
//                1f / 8 * height);canvas.translate(mIcon_fruit_all.getWidth() / 2 - 40, mIcon_fruit_all.getHeight() + 50);// 一个一个地画一个数字for (int i = 0; i < grade.length(); i++) {String numStr = grade.substring(i, i + 1);int num = Integer.valueOf(numStr);canvas.drawBitmap(mNumBitmap[num], null, mSingleNumRectF, null);canvas.translate(mSingleGradeWidth, 0);}canvas.restore();}

2、构造函数初始化相关

   public MyGameView(Context context) {super(context);// TODO Auto-generated constructor stubmContext = context;initSomeObjectList();initTimePaint();initScorePaint();initBladePaint();initBitmaps();initPlayer(context);initSoundPool(context);}

初始化相关水果对象、炸弹和点容器List

   private void initSomeObjectList() {mTrack = new ArrayList<PointF>();//实例化容纳精灵的列表,请自行做好管理精灵的工作mSpirits = new ArrayList<Spirite>();mBooms = new ArrayList<Spirite>();}

初始化声音

  private void initSoundPool(Context context) {SoundPool mSoundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100);mExplodeSoundId = mSoundPool.load(context, R.raw.bomb_explode, 1);}private void initPlayer(Context context) {MediaPlayer mPlayer = MediaPlayer.create(context, R.raw.music_menu);mPlayer.setLooping(true);}

初始化一堆画笔

    private void initBladePaint() {paintBlade = new Paint();paintBlade.setColor(Color.WHITE);paintBlade.setStyle(Style.STROKE);}private void initScorePaint() {paintScore = new Paint();paintScore.setColor(Color.WHITE);paintScore.setTextSize(60);}private void initTimePaint() {timePaint = new Paint();timePaint.setColor(Color.WHITE);timePaint.setTextSize(60);}

初始化图片

 /*** 初始化图片*/private void initBitmaps() {//背景mBg = loadImageByResId(R.drawable.icon_fruit_bg1);//切掉后水果图片mIcon_orange1 = loadImageByResId(R.drawable.icon_orange1);mIcon_orange2 = loadImageByResId(R.drawable.icon_orange2);mIcon_pineapple2 = loadImageByResId(R.drawable.icon_pineapple2);mIcon_pineapple1 = loadImageByResId(R.drawable.icon_pineapple1);mIcon_banana1 = loadImageByResId(R.drawable.icon_banana1);mIcon_banana2 = loadImageByResId(R.drawable.icon_banana2);mIcon_lemon2 = loadImageByResId(R.drawable.icon_lemon2);mIcon_lemon1 = loadImageByResId(R.drawable.icon_lemon1);mIcon_mango1 = loadImageByResId(R.drawable.icon_mango1);mIcon_mango2 = loadImageByResId(R.drawable.icon_mango2);mIcon_orange = loadImageByResId(R.drawable.icon_orange);mIcon_pineapple = loadImageByResId(R.drawable.icon_pineapple);mIcon_banana = loadImageByResId(R.drawable.icon_banana);mIcon_lemon = loadImageByResId(R.drawable.icon_lemon);mIcon_mango = loadImageByResId(R.drawable.icon_mango);mBoom = loadImageByResId(R.drawable.boom);mIcon_watermelon = loadImageByResId(R.drawable.icon_watermelon);mIcon_watermelon1 = loadImageByResId(R.drawable.icon_watermelon1);mIcon_watermelon2 = loadImageByResId(R.drawable.icon_watermelon2);mIcon_fruit_all = loadImageByResId(R.drawable.icon_fruit_all);mNumBitmap = new Bitmap[mNums.length];for (int i = 0; i < mNumBitmap.length; i++) {mNumBitmap[i] = loadImageByResId(mNums[i]);}}

3、生成水果对象

   if (isOpen) {//到了计算好的时间就生成水果精灵if (mNextTime < System.currentTimeMillis()) {generateSpirit();
//          mSoundPool.play(mExplodeSoundId, 1, 1, 1, 0, 1);nextGenTime();}}
 /*** 生成精灵,并添加到精灵管理列表*/private void generateSpirit() {//请修改此方法,使精灵从更多方向抛出Spirite spirite = new Spirite(mContext);
//      spirite.loadBitmap(R.drawable.ic_launcher);Random rand = new Random();int randNum = 1 + rand.nextInt(6);int cakeId;switch (randNum) {case 1:cakeId = R.drawable.icon_orange;spirite.loadBitmap(mIcon_orange);spirite.setmType(cakeId);//t_num=randNum;break;case 2:cakeId = R.drawable.icon_pineapple;spirite.loadBitmap(mIcon_pineapple);spirite.setmType(cakeId);//t_num=randNum;break;case 3:cakeId = R.drawable.icon_banana;spirite.loadBitmap(mIcon_banana);spirite.setmType(cakeId);//t_num=randNum;break;case 4:cakeId = R.drawable.icon_lemon;spirite.loadBitmap(mIcon_lemon);spirite.setmType(cakeId);//t_num=randNum;break;case 5:cakeId = R.drawable.icon_mango;spirite.loadBitmap(mIcon_mango);spirite.setmType(cakeId);//t_num=randNum;break;case 6:cakeId = R.drawable.icon_watermelon;spirite.loadBitmap(mIcon_watermelon);spirite.setmType(cakeId);//t_num=randNum;break;default:}Random r = new Random();//随机坐标spirite.mCoord.x = width / (35 / 10) + r.nextInt(width / (35 / 10)) - 30;spirite.mCoord.y = r.nextInt(100);//设置抛物线向下速度
//      spirite.mV.x = 5+r.nextInt(5);
//      spirite.mV.y = -(30 + (r.nextInt(20)+10));//添加向上抛spirite.mV.y = -(30 + (r.nextInt(20) + 10));/*mSpirits.get(0).setmType(mType);*/mSpirits.add(spirite);}

4、切到水果

/*** 初始化切到水果的时候*/private void isHit() {synchronized (mTrack) {for (int i = 0; i < mTrack.size(); i++) {for (int z = 0; z < mSpirits.size(); z++) {if (mTrack.get(i).x > mSpirits.get(z).mCoord.x && mTrack.get(i).x < mSpirits.get(z).mCoord.x + mSpirits.get(z).mDimention.x) {if (mTrack.get(i).y > mSpirits.get(z).mCoord.y && mTrack.get(i).y < mSpirits.get(z).mCoord.y + mSpirits.get(z).mDimention.y) {switch (mSpirits.get(z).getmType()) {case R.drawable.icon_orange:initCutCake(mIcon_orange1, mIcon_orange2, z);Log.e("m", "icon_orange");scroe += 1;break;case R.drawable.icon_pineapple:Log.e("m", "icon_pineapple");initCutCake(mIcon_pineapple2, mIcon_pineapple1, z);scroe += 1;break;case R.drawable.icon_banana:Log.e("m", "icon_banana");initCutCake(mIcon_banana2, mIcon_banana1, z);scroe += 1;break;case R.drawable.icon_lemon:Log.e("m", "icon_lemon");initCutCake(mIcon_lemon1, mIcon_lemon2, z);scroe += 1;break;case R.drawable.icon_mango:Log.e("m", "icon_mango");initCutCake(mIcon_mango1, mIcon_mango2, z);scroe += 1;break;case R.drawable.icon_watermelon:Log.e("m", "icon_watermelon");initCutCake(mIcon_watermelon2, mIcon_watermelon1, z);scroe += 1;break;default:break;}}}}}}}
  /*** 切到水果后加载2个图片** @param bitmap1* @param bitmap2* @param z*/private void initCutCake(Bitmap bitmap1, Bitmap bitmap2, int z) {Spirite spirite_left = new Spirite(mContext);Spirite spirite_right = new Spirite(mContext);spirite_left.loadBitmap(bitmap1);spirite_left.mCoord.x = mSpirits.get(z).mCoord.x + 60;spirite_left.mCoord.y = mSpirits.get(z).mCoord.y;mSpirits.add(spirite_left);spirite_right.loadBitmap(bitmap2);spirite_right.mCoord.x = mSpirits.get(z).mCoord.x - 60;spirite_right.mCoord.y = mSpirits.get(z).mCoord.y;mSpirits.add(spirite_right);mSpirits.remove(z);}

5、初始化尺寸相关

 /*** 初始化尺寸相关*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = getWidth();height = getHeight();mGamePanelRect.set(0, 0, width, height);// 初始化分数mSingleGradeHeight = (int) (h * RADIO_SINGLE_NUM_HEIGHT);mSingleGradeWidth = (int) (mSingleGradeHeight * 1.0f/ mNumBitmap[0].getHeight() * mNumBitmap[0].getWidth());mSingleNumRectF = new RectF(0, 0, mSingleGradeWidth, mSingleGradeHeight);//初始化水果篮子mRectFFruitAll = new RectF(50, 50, mIcon_fruit_all.getWidth(), mIcon_fruit_all.getHeight());}

6、手势触摸处理

  /*** 屏幕点击事件的响应方法** @param event* @return*/@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif (event.getAction() == MotionEvent.ACTION_DOWN) {handleActionDown(event);} else if (event.getAction() == MotionEvent.ACTION_MOVE) {handleActionMove(event);} else if (event.getAction() == MotionEvent.ACTION_UP) {handleActionUp();}return true;}//手指按下的响应方法private void handleActionDown(MotionEvent event) {PointF point = new PointF(event.getX(), event.getY());synchronized (mTrack) {if (mTrack.size() >= POINT_LIMIT) {mTrack.remove(0);}mTrack.add(point);}}//手指拖动的响应方法private void handleActionMove(MotionEvent event) {PointF point = new PointF(event.getX(), event.getY());synchronized (mTrack) {if (mTrack.size() >= POINT_LIMIT) {mTrack.remove(0);}mTrack.add(point);}}//手指抬起的响应方法private void handleActionUp() {synchronized (mTrack) {mTrack.clear();}}

所有源码

package com.example.tim.myapplication;import java.util.ArrayList;
import java.util.Random;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;public class MyGameView extends FruitGameSurfaceView {private Context mContext;private ArrayList<PointF> mTrack;private final static int POINT_LIMIT = 5;private int scroe = 0;//此变量用于修改刀光的颜色private int mBladeColor = 0xFFFFFFFF;//用于容纳精灵private ArrayList<Spirite> mSpirits;private ArrayList<Spirite> mBooms;//计算下次生成精灵的时间private long mNextTime = 0L;private long mNextTimeBoom = 0L;//显示右上角时间private long mTimeCount;public int count = 30;//声明播放器private int mExplodeSoundId;private int width;private int height;private Paint timePaint;private Paint paintScore;private Paint paintBlade;//背景private Bitmap mBg;private boolean isOpen = true;/*** 当前View的尺寸*/private RectF mGamePanelRect = new RectF();/*** 分数*/private final int[] mNums = new int[]{R.drawable.n0, R.drawable.n1,R.drawable.n2, R.drawable.n3, R.drawable.n4, R.drawable.n5,R.drawable.n6, R.drawable.n7, R.drawable.n8, R.drawable.n9};private Bitmap[] mNumBitmap;private int mGrade = 0;private int mRemovedPipe = 0;private static final float RADIO_SINGLE_NUM_HEIGHT = 1 / 15f;private int mSingleGradeWidth;private int mSingleGradeHeight;private RectF mSingleNumRectF;/*** 水果图片*/private Bitmap mIcon_orange;private Bitmap mIcon_pineapple;private Bitmap mIcon_banana;private Bitmap mIcon_lemon;private Bitmap mIcon_mango;private Bitmap mIcon_watermelon;/*** 水果被切后效果*/private Bitmap mIcon_orange1;private Bitmap mIcon_orange2;private Bitmap mIcon_pineapple2;private Bitmap mIcon_pineapple1;private Bitmap mIcon_banana1;private Bitmap mIcon_banana2;private Bitmap mIcon_lemon2;private Bitmap mIcon_lemon1;private Bitmap mIcon_mango1;private Bitmap mIcon_mango2;private Bitmap mIcon_watermelon1;private Bitmap mIcon_watermelon2;/*** 炸弹*/private Bitmap mBoom;private Bitmap mIcon_fruit_all;private RectF mRectFFruitAll;public MyGameView(Context context) {super(context);// TODO Auto-generated constructor stubmContext = context;initSomeObjectList();initTimePaint();initScorePaint();initBladePaint();initBitmaps();initPlayer(context);initSoundPool(context);}private void initSomeObjectList() {mTrack = new ArrayList<PointF>();//实例化容纳精灵的列表,请自行做好管理精灵的工作mSpirits = new ArrayList<Spirite>();mBooms = new ArrayList<Spirite>();}private void initSoundPool(Context context) {SoundPool mSoundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100);mExplodeSoundId = mSoundPool.load(context, R.raw.bomb_explode, 1);}private void initPlayer(Context context) {MediaPlayer mPlayer = MediaPlayer.create(context, R.raw.music_menu);mPlayer.setLooping(true);}private void initBladePaint() {paintBlade = new Paint();paintBlade.setColor(Color.WHITE);paintBlade.setStyle(Style.STROKE);}private void initScorePaint() {paintScore = new Paint();paintScore.setColor(Color.WHITE);paintScore.setTextSize(60);}private void initTimePaint() {timePaint = new Paint();timePaint.setColor(Color.WHITE);timePaint.setTextSize(60);}/*** 初始化尺寸相关*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = getWidth();height = getHeight();mGamePanelRect.set(0, 0, width, height);// 初始化分数mSingleGradeHeight = (int) (h * RADIO_SINGLE_NUM_HEIGHT);mSingleGradeWidth = (int) (mSingleGradeHeight * 1.0f/ mNumBitmap[0].getHeight() * mNumBitmap[0].getWidth());mSingleNumRectF = new RectF(0, 0, mSingleGradeWidth, mSingleGradeHeight);//初始化水果篮子mRectFFruitAll = new RectF(50, 50, mIcon_fruit_all.getWidth(), mIcon_fruit_all.getHeight());}//专用于绘制屏幕@Overrideprotected void myDraw(Canvas canvas) {super.myDraw(canvas);//用户画背景drawBg(canvas);//画水果篮子drawFruitBox(canvas);//画刀光drawBlade(canvas);if (isOpen) {//到了计算好的时间就生成水果精灵if (mNextTime < System.currentTimeMillis()) {generateSpirit();
//          mSoundPool.play(mExplodeSoundId, 1, 1, 1, 0, 1);nextGenTime();}}
//      if(mNextTimeBoom<System.currentTimeMillis()){//          //画炸弹
//          drawBoom();
//          nextGenTimeBoom();
//      }//绘制时间drawTime(canvas);//检查精灵是否还在屏幕内,不在屏幕内则移除checkSpirites();//画水果drawSpirites(canvas);//初始化切到水果isHit();
//      //初始化撞击炸弹
//      isHitBomb();
//      //绘制分数drawGrades(canvas);}/*** 画水果篮子** @param canvas*/private void drawFruitBox(Canvas canvas) {canvas.drawBitmap(mIcon_fruit_all, null, mRectFFruitAll, null);}/*** 下一次生成精灵的时间*/private void nextGenTime() {mNextTime = System.currentTimeMillis();Random r = new Random();int interval = 700 + r.nextInt(100);mNextTime += interval;}private void nextGenTimeBoom() {mNextTimeBoom = System.currentTimeMillis() + 1000;Random r = new Random();int interval = 3000 + r.nextInt(2000);mNextTimeBoom += interval;}/*** 生成精灵,并添加到精灵管理列表*/private void generateSpirit() {//请修改此方法,使精灵从更多方向抛出Spirite spirite = new Spirite(mContext);
//      spirite.loadBitmap(R.drawable.ic_launcher);Random rand = new Random();int randNum = 1 + rand.nextInt(6);int cakeId;switch (randNum) {case 1:cakeId = R.drawable.icon_orange;spirite.loadBitmap(mIcon_orange);spirite.setmType(cakeId);//t_num=randNum;break;case 2:cakeId = R.drawable.icon_pineapple;spirite.loadBitmap(mIcon_pineapple);spirite.setmType(cakeId);//t_num=randNum;break;case 3:cakeId = R.drawable.icon_banana;spirite.loadBitmap(mIcon_banana);spirite.setmType(cakeId);//t_num=randNum;break;case 4:cakeId = R.drawable.icon_lemon;spirite.loadBitmap(mIcon_lemon);spirite.setmType(cakeId);//t_num=randNum;break;case 5:cakeId = R.drawable.icon_mango;spirite.loadBitmap(mIcon_mango);spirite.setmType(cakeId);//t_num=randNum;break;case 6:cakeId = R.drawable.icon_watermelon;spirite.loadBitmap(mIcon_watermelon);spirite.setmType(cakeId);//t_num=randNum;break;default:}Random r = new Random();//随机坐标spirite.mCoord.x = width / (35 / 10) + r.nextInt(width / (35 / 10)) - 30;spirite.mCoord.y = r.nextInt(100);//设置抛物线向下速度
//      spirite.mV.x = 5+r.nextInt(5);
//      spirite.mV.y = -(30 + (r.nextInt(20)+10));//添加向上抛spirite.mV.y = -(30 + (r.nextInt(20) + 10));/*mSpirits.get(0).setmType(mType);*/mSpirits.add(spirite);}/*** 画炸弹*/private void drawBoom() {Spirite spirite = new Spirite(mContext);spirite.loadBitmap(mBoom);Random r = new Random();spirite.mCoord.x = 50 + r.nextInt(300);spirite.mCoord.y = 480;spirite.mV.x = 5 + r.nextInt(5);spirite.mV.y = -(30 + (r.nextInt(20) + 10));/*mSpirits.get(0).setmType(mType);*/mBooms.add(spirite);}//开始和停止背景音乐@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubsuper.surfaceCreated(holder);
//      mPlayer.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubsuper.surfaceDestroyed(holder);
//      mPlayer.stop();
//      mSoundPool.release();}/*** 画精灵到画布上** @param canvas*/private void drawSpirites(Canvas canvas) {for (int i = 0; i < mSpirits.size(); i++) {mSpirits.get(i).draw(canvas);}
//      for(int i=0;i<mBooms.size();i++){//          mBooms.get(i).draw(canvas);
//      }}/*** 检查精灵是否还在屏幕内,不在屏幕内则移除*/private void checkSpirites() {for (int i = 0; i < mSpirits.size(); i++) {if (isSpiriteValidate(i)) {mSpirits.remove(i);i -= 1;}}}//具体检查精灵是否在屏幕内的方法private boolean isSpiriteValidate(int i) {PointF coord = mSpirits.get(i).mCoord;if (coord.x < -mSpirits.get(i).mDimention.x || coord.x > width || coord.y > height) {return true;}return false;}/*** 绘制分数1* @param canvas*/private void drawScore(Canvas canvas) {canvas.drawText("Score:" + scroe, 50, 50, paintScore);}/*** 初始化切到水果的时候*/private void isHit() {synchronized (mTrack) {for (int i = 0; i < mTrack.size(); i++) {for (int z = 0; z < mSpirits.size(); z++) {if (mTrack.get(i).x > mSpirits.get(z).mCoord.x && mTrack.get(i).x < mSpirits.get(z).mCoord.x + mSpirits.get(z).mDimention.x) {if (mTrack.get(i).y > mSpirits.get(z).mCoord.y && mTrack.get(i).y < mSpirits.get(z).mCoord.y + mSpirits.get(z).mDimention.y) {switch (mSpirits.get(z).getmType()) {case R.drawable.icon_orange:initCutCake(mIcon_orange1, mIcon_orange2, z);Log.e("m", "icon_orange");scroe += 1;break;case R.drawable.icon_pineapple:Log.e("m", "icon_pineapple");initCutCake(mIcon_pineapple2, mIcon_pineapple1, z);scroe += 1;break;case R.drawable.icon_banana:Log.e("m", "icon_banana");initCutCake(mIcon_banana2, mIcon_banana1, z);scroe += 1;break;case R.drawable.icon_lemon:Log.e("m", "icon_lemon");initCutCake(mIcon_lemon1, mIcon_lemon2, z);scroe += 1;break;case R.drawable.icon_mango:Log.e("m", "icon_mango");initCutCake(mIcon_mango1, mIcon_mango2, z);scroe += 1;break;case R.drawable.icon_watermelon:Log.e("m", "icon_watermelon");initCutCake(mIcon_watermelon2, mIcon_watermelon1, z);scroe += 1;break;default:break;}}}}}}}/*** 切到炸弹的时候*/private void isHitBomb() {synchronized (mTrack) {for (int i = 0; i < mTrack.size(); i++) {for (int z = 0; z < mBooms.size(); z++) {if (mTrack.get(i).x > mBooms.get(z).mCoord.x && mTrack.get(i).x < mBooms.get(z).mCoord.x + mBooms.get(z).mDimention.x) {if (mTrack.get(i).y > mBooms.get(z).mCoord.y && mTrack.get(i).y < mBooms.get(z).mCoord.y + mBooms.get(z).mDimention.y) {if (scroe >= 10) {scroe -= 10;} else {scroe = 0;}mBooms.remove(z);mSpirits.removeAll(mSpirits);}}}}}}/*** 切到水果后加载2个图片** @param bitmap1* @param bitmap2* @param z*/private void initCutCake(Bitmap bitmap1, Bitmap bitmap2, int z) {Spirite spirite_left = new Spirite(mContext);Spirite spirite_right = new Spirite(mContext);spirite_left.loadBitmap(bitmap1);spirite_left.mCoord.x = mSpirits.get(z).mCoord.x + 60;spirite_left.mCoord.y = mSpirits.get(z).mCoord.y;mSpirits.add(spirite_left);spirite_right.loadBitmap(bitmap2);spirite_right.mCoord.x = mSpirits.get(z).mCoord.x - 60;spirite_right.mCoord.y = mSpirits.get(z).mCoord.y;mSpirits.add(spirite_right);mSpirits.remove(z);}/*** 画刀光到画布上,可以扩展** @param canvas*/private void drawBlade(Canvas canvas) {synchronized (mTrack) {Path path = new Path();Float startX, startY;Float controlX, controlY;Float endX, endY;int strokeWidth = 1;if (mTrack.size() > 1) {endX = mTrack.get(0).x;endY = mTrack.get(0).y;for (int i = 0; i < mTrack.size() - 1; i++) {startX = endX;startY = endY;controlX = mTrack.get(i).x;controlY = mTrack.get(i).y;endX = (controlX + mTrack.get(i + 1).x) / 2;endY = (controlY + mTrack.get(i + 1).y) / 2;path.moveTo(startX, startY);path.quadTo(controlX, controlY, endX, endY);paintBlade.setColor(mBladeColor);paintBlade.setStrokeWidth(strokeWidth++);canvas.drawPath(path, paintBlade);path.reset();}startX = endX;startY = endY;endX = mTrack.get(mTrack.size() - 1).x;endY = mTrack.get(mTrack.size() - 1).y;path.moveTo(startX, startY);path.lineTo(endX, endY);paintBlade.setStrokeWidth(strokeWidth++);paintBlade.setColor(mBladeColor);canvas.drawPath(path, paintBlade);mTrack.remove(0);}}}/*** 倒计时,右上角时间和页面判断跳转** @param canvas*/private void drawTime(Canvas canvas) {if (System.currentTimeMillis() - mTimeCount > 1000) {mTimeCount = System.currentTimeMillis();count--;if (count == 0) {isOpen = false;
//              Intent intent = new Intent(mContext, GameStopActivity.class);
//              intent.putExtra("Score", ""+ scroe);
//              mContext.startActivity(intent);} else {}}if (count <= 0) {canvas.drawText("Time:" + 0, width - 250, 130, timePaint);} else {canvas.drawText("Time:" + count, width - 250, 120, timePaint);}}/*** 屏幕点击事件的响应方法** @param event* @return*/@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif (event.getAction() == MotionEvent.ACTION_DOWN) {handleActionDown(event);} else if (event.getAction() == MotionEvent.ACTION_MOVE) {handleActionMove(event);} else if (event.getAction() == MotionEvent.ACTION_UP) {handleActionUp();}return true;}//手指按下的响应方法private void handleActionDown(MotionEvent event) {PointF point = new PointF(event.getX(), event.getY());synchronized (mTrack) {if (mTrack.size() >= POINT_LIMIT) {mTrack.remove(0);}mTrack.add(point);}}//手指拖动的响应方法private void handleActionMove(MotionEvent event) {PointF point = new PointF(event.getX(), event.getY());synchronized (mTrack) {if (mTrack.size() >= POINT_LIMIT) {mTrack.remove(0);}mTrack.add(point);}}//手指抬起的响应方法private void handleActionUp() {synchronized (mTrack) {mTrack.clear();}}/*** 根据resId加载图片** @param resId* @return*/private Bitmap loadImageByResId(int resId) {BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;return BitmapFactory.decodeResource(getResources(), resId);}/*** 绘制背景*/private void drawBg(Canvas canvas) {//初始化图片canvas.drawBitmap(mBg, null, mGamePanelRect, null);}/*** 初始化图片*/private void initBitmaps() {//背景mBg = loadImageByResId(R.drawable.icon_fruit_bg1);//切掉后水果图片mIcon_orange1 = loadImageByResId(R.drawable.icon_orange1);mIcon_orange2 = loadImageByResId(R.drawable.icon_orange2);mIcon_pineapple2 = loadImageByResId(R.drawable.icon_pineapple2);mIcon_pineapple1 = loadImageByResId(R.drawable.icon_pineapple1);mIcon_banana1 = loadImageByResId(R.drawable.icon_banana1);mIcon_banana2 = loadImageByResId(R.drawable.icon_banana2);mIcon_lemon2 = loadImageByResId(R.drawable.icon_lemon2);mIcon_lemon1 = loadImageByResId(R.drawable.icon_lemon1);mIcon_mango1 = loadImageByResId(R.drawable.icon_mango1);mIcon_mango2 = loadImageByResId(R.drawable.icon_mango2);mIcon_orange = loadImageByResId(R.drawable.icon_orange);mIcon_pineapple = loadImageByResId(R.drawable.icon_pineapple);mIcon_banana = loadImageByResId(R.drawable.icon_banana);mIcon_lemon = loadImageByResId(R.drawable.icon_lemon);mIcon_mango = loadImageByResId(R.drawable.icon_mango);mBoom = loadImageByResId(R.drawable.boom);mIcon_watermelon = loadImageByResId(R.drawable.icon_watermelon);mIcon_watermelon1 = loadImageByResId(R.drawable.icon_watermelon1);mIcon_watermelon2 = loadImageByResId(R.drawable.icon_watermelon2);mIcon_fruit_all = loadImageByResId(R.drawable.icon_fruit_all);mNumBitmap = new Bitmap[mNums.length];for (int i = 0; i < mNumBitmap.length; i++) {mNumBitmap[i] = loadImageByResId(mNums[i]);}}/*** 绘制分数2*/@SuppressLint("WrongConstant")private void drawGrades(Canvas canvas) {String grade = scroe + "";canvas.save(Canvas.MATRIX_SAVE_FLAG);
//        canvas.translate(width / 2 - grade.length() * mSingleGradeWidth / 2,
//                1f / 8 * height);canvas.translate(mIcon_fruit_all.getWidth() / 2 - 40, mIcon_fruit_all.getHeight() + 50);// 一个一个地画一个数字for (int i = 0; i < grade.length(); i++) {String numStr = grade.substring(i, i + 1);int num = Integer.valueOf(numStr);canvas.drawBitmap(mNumBitmap[num], null, mSingleNumRectF, null);canvas.translate(mSingleGradeWidth, 0);}canvas.restore();}
}

到这里了可能会看得比较懵逼,但是我觉得把demo跑起来,根据思路来结合代码来研究会理解得比较快。

Android SurfaceView实战 带你玩切水果1.0相关推荐

  1. Android SurfaceView实战 带你玩转flabby bird (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43063331,本文出自:[张鸿洋的博客] 1.概述 在Android Surfa ...

  2. Android SurfaceView实战 带你玩转flabby bird (上)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转载请标 ...

  3. Android SurfaceView实战 带你玩转flabby bird

    分析 仔细观察游戏,需要绘制的有:背景.地板.鸟.管道.分数: 游戏开始时: 地板给人一种想左移动的感觉: 管道与地板同样的速度向左移动: 鸟默认下落: 当用户touch屏幕时,鸟上升一段距离后,下落 ...

  4. 详解与重构hyman《Android SurfaceView实战 打造抽奖转盘》

    详解与重构hyman<Android SurfaceView实战 打造抽奖转盘> 作者:邵励治 一.概述--关于SurfaceView您不得不知道的二三事 1.SurfaceView是干什 ...

  5. Android SurfaceView实战 打造抽奖转盘

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41722441 ,本文出自:[张鸿洋的博客] 1.概述 今天给大家带来Surfac ...

  6. Android:手把手带你深入剖析 Retrofit 2.0 源码

    前言 在Andrroid开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库 今天,我将手把手带你深入剖析Retrofit v2.0的源码,希望你们会喜 ...

  7. 12个真实项目实战带你玩转Java并发编程

    这篇博客,我会总结如下内容,满满的干货,篇幅可能会很长,做好心理准备 Immutable Object:不可变对象模式:在不引入锁的条件下,能保证访问共享变量时是线程安全的,缺点是会频繁的创建变量. ...

  8. 视频教程| 3D版切水果游戏开发实战:认识水果

    本周,很多Egret 老铁看到了我们的3D实战内容并积极给予了回应:要与我们一起实战开发3D版切水果游戏!看完后很是感动,在此谢谢老铁们对我们的支持,你们的认可与鼓励是我们不断前行的动力! Egret ...

  9. 神奇的手指——可以取代”切水果“的清屏小软件

    今天是感恩节,首先感谢峰哥,强哥和曾哥,是你们给我入的安卓的门. 这是学习安卓两个星期的第一个感觉成型的小小软件,在自己的手机上运行感觉还是很好的,毕竟这是自己用代码敲出来的东西,下面和大家分享一下一 ...

最新文章

  1. NOIP2005普及组第4题 循环
  2. Win32汇编数据对齐相关的伪指令(ALIGN、EVEN、ORG)
  3. ORA-19573: cannot obtain exclusive enqueue for datafile 1
  4. idea生成方法注释的正确方法
  5. java wcf_尝试将WCF映射到Java术语
  6. react-router的使用(一)——URL的hash、HTML5的history、Router的基本使用
  7. LeetCode 1411. 给 N x 3 网格图涂色的方案数(数学)
  8. 护航Lazada双11购物节 阿里云CDN全球化火力全开
  9. C语言编程基础 打印图形
  10. 03 使用T-SQL语句实现数据的添加、更新、删除测试分析 1214
  11. Python操作MySQL(二) ORM篇
  12. 前端学习 -- HtmlCss -- 表单
  13. 解决MATLAB无法读取笔记本内置摄像头
  14. pr如何跳到关键帧_PR制作短视频(二):30分钟制作一个短视频
  15. **一些常用的字体英文名**
  16. C#打开文件夹加载图片
  17. RS485通信的学习以及思考
  18. 《From Captions to Visual Concepts and Back》阅读笔记
  19. 常见编码介绍。一个字符在不同编码中分别占几个字节(新手向)
  20. 软件压力测试的手段有注入错误吗,软件错误注入测试技术研究_陈锦富.pdf

热门文章

  1. ABP应用开发(Step by Step)-下篇
  2. mysql中in的参数有限制_数据库 in 可以包含的参数个数
  3. 操盘建议----全球顶尖交易员的成功实践和心路历程(三)
  4. 《实用C++》第8课:赋值运算符和赋值表达式
  5. 一次悲惨的被挖矿经历
  6. 2020-05-25
  7. 年轻人不讲武德,离职理由各显神通,硬气辞职原来是这样……
  8. ljmp指令_51单片机主要汇编指令集
  9. SwiftUI系列教程第1章第3节:Text的段落属性
  10. 关于帮助他人,别跟自己较劲