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 stub
mHolder = getHolder();
mHolder.addCallback(this);
//可获得焦点
setFocusable(true);
setFocusableInTouchMode(true);
//设置常亮
setKeepScreenOn(true);
surface = mHolder.getSurface();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isRunning = true;
t = new Thread(this);
t.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
isRunning=false;
}
protected void myDraw(Canvas canvas) {
}
@Override
public 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 stub
mContext = 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、初始化尺寸相关
/**
* 初始化尺寸相关
*/
@Override
protected 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
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (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 stub
mContext = 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);
}
/**
* 初始化尺寸相关
*/
@Override
protected 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());
}
//专用于绘制屏幕
@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);
}
/**
* 画水果篮子
*
* @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);
}
//开始和停止背景音乐
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
super.surfaceCreated(holder);
// mPlayer.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
super.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
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (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跑起来,根据思路来结合代码来研究会理解得比较快。