Android SurfaceView实战 带你玩切水果1.0

本文介绍如何使用Android原生开发切水果游戏,通过SurfaceView进行游戏界面绘制,涉及水果生成、切割、触摸手势处理等关键代码实现,提供完整源码供参考。
摘要由CSDN通过智能技术生成

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).
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值