关闭

《拼图游戏》技术总结“二” PtView

164人阅读 评论(0) 收藏 举报
分类:

这里先把最关键PtView先讲了,因为这才是这个游戏的核心。

·所用到的知识点

1.画笔  Paint()

setARGB(int a, int r, int g, int b) // 设置 Paint对象颜色,参数一为alpha透明值

setAlpha(int a) // 设置alpha不透明度,范围为0~255

setAntiAlias(boolean aa) // 是否抗锯齿

setColor(int color)  // 设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义

setTextScaleX(float scaleX)  // 设置文本缩放倍数,1.0f为原始

setTextSize(float textSize)  // 设置字体大小

setUnderlineText(booleanunderlineText)  // 设置下划线

...

2.Canvas 类

 .drawBitmap() //绘制图片 传入的参数很多种

.drawLine()//画线

.drawText()//画字

...
3.Bitmap类

.createScaledBitmap()//获取图片资源

.createBitmap()//切割图片资源

4.Rect类 获取矩形区域

5.SharedPreference 类

.getSharedPreferences(A,B); 从文件A中读取文件(B为存储类型)

6.String 类中的常用方法。

View中的:

1.onDraw()方法: 刚开启界面时绘制一次,以后需要调用 invalidate(); 方法才会执行

2.onTouchEvent(); 点击事件在这里处理

3.onSizeChanged() 当屏幕大小改变时调用,数据初始化在这里进行。

·拼图块移动的逻辑

1.获得手势操作:

获得手指点下时的想x,y 以及 手指放开时的x,y 

进行判断是向那个方向滑动。

2.拼图块的移动:

如:获得向有滑动的操作:

即空要与它左边的图片进行交换位置

就是当前 空图片所在位置(changeNum) -1(空图片不能在第0列)

判断结束,进行changeNum的交换,通知onDraw进行重画


上代码:

public class PtGameView extends View {
    private double startX = 0;//触摸点的起点和终点的坐标
    private double startY = 0;
    private double endX = 0;
    private double endY = 0;
    private Bitmap background;
    private Bitmap _background;//_代表缩略图
    private int screamW;//获得屏幕的高宽
    private int screamH;
    private Bitmap mPhoto;//拼图图像
    private Bitmap _mPhoto;
    private Rect ptQuyu;//拼图区域
    private Rect suoLueQuyu;//缩略图区域
    private Paint paint;//设置画笔
    private double ph;// 拼图片的宽度
    private double sL;//缩略图的长
    public int runNum;
    public int level = 3;//设置拼图的难度
    public PtCell[] ptCells;
    private Context mContext;
    public static boolean isContinue = true;
    public PtGameView(Context pContext, int pLevel) {
        super(pContext);
        mContext = pContext;
        level = pLevel;//从构造方法中获得游戏的等级
        ptCells = new PtCell[level * level];//设置画笔的初始状态
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
    }
    //执行画图操作
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //图片资源,坐标
        canvas.drawBitmap(_background, 0, 0, null);
        canvas.drawBitmap(_mPhoto, null, suoLueQuyu, null);
        //画格子线
        for (int i = 0; i <= level; i++) {
            canvas.drawLine(ptQuyu.left, ptQuyu.top + (int) (i * ph), ptQuyu.right, ptQuyu.top + (int) (i * ph), paint);
        }
        for (int i = 0; i <= level; i++) {
            canvas.drawLine(ptQuyu.left + (int) (i * ph), ptQuyu.top, ptQuyu.left + (int) (i * ph), ptQuyu.bottom, paint);
        }

        // 画拼拼图片
        for (int i = 0; i < ptCells.length; i++) {
            int x = ptCells[i].changeNum / level;//求商
            int y = ptCells[i].changeNum % level;//取余
            //画的位置由 changeNum决定
            if (ptCells[i].img != null) {
                canvas.drawBitmap(ptCells[i].img, ptQuyu.left + (int) (y * ph), ptQuyu.top + (int) (ph * x), null);
            }
        }
        //画步数
        paint.setTextSize(40);
        canvas.drawText("步数:" + runNum, (int) (dip2px(40) + sL),
                (int) (dip2px(20) + sL), paint);
        canvas.drawText("检查是否完成", (int) (dip2px(40) + sL),
                (int) (dip2px(20) + sL / 2), paint);
        canvas.drawText("直接归位", (int) (dip2px(40) + sL),
                dip2px(40), paint);
    }
   //尺寸改变时触发
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        screamH = h;
        screamW = w;
        double L = (w - dip2px(40));
        sL = h - L - dip2px(80);
        ph = L / level;//拼图片的高
        ptQuyu = new Rect(dip2px(20), dip2px(40) + (int) (sL), (int) (L) + dip2px(20), dip2px(40) + (int) (L + sL));
        suoLueQuyu = new Rect(dip2px(10), dip2px(20), (int) (sL + dip2px(20)), (int) (sL + dip2px(20)));
        loadBitmap();
        zoomBitmap();
        cutPhotoCell();
        super.onSizeChanged(w, h, oldw, oldh);
    }
    //加载图片
    void loadBitmap() {
        background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        mPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.pt);
    }
    //缩放图片
    void zoomBitmap() {
        _background = Bitmap.createScaledBitmap(background, screamW, screamH, false);
        _mPhoto = Bitmap.createScaledBitmap(mPhoto, ptQuyu.width(), ptQuyu.height(), false);
        background.recycle();
    }
    void cutPhotoCell() {//切割,获得图片cell
        Rect puzzR;
        int k = 0;
        for (int i = 0; i < level; i++) {
            for (int j = 0; j < level; j++) {
                puzzR = new Rect((int) (j * ph), (int) (i * ph),
                        (int) ((j + 1) * ph), (int) ((i + 1) * ph));
                PtCell zy = new PtCell();
                zy.img = Bitmap.createBitmap(_mPhoto, puzzR.left, puzzR.top, puzzR.width(), puzzR.height());
                zy.num = k;
                zy.changeNum = k;
                ptCells[k] = zy;
                k++;
            }
        }
        ptCells[0].img = null;//空的永远都是ptCells[0]
        //打乱图片
        for (int i = 0; i < 50; i++) {
            int k2 = ptCells[0].changeNum;
            int a = k2 / level;
            int b = k2 % level;//取余
            int c = (int) (5 * Math.random());
            //模拟手指上下滑动
            switch (c) {
                case 1:
                    if (b - 1 >= 0) {
                        searchCells(k2 - 1);
                    }
                    break;
                case 2:
                    if (b + 1 < level) {
                        searchCells(k2 + 1);
                    }
                    break;
                case 3:
                    if (a - 1 >= 0) {
                        searchCells(k2 - level);
                    }
                    break;
                case 4:
                    if (a + 1 < level) {
                        searchCells(k2 + level);
                    }
                    break;
            }
        }
        if (isContinue) {
            recover();
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = event.getX();
                startY = event.getY();
                Log.i("===", "startX:" + (int) startX + "startY:" + (int) startY);
                if (startX > (dip2px(40) + sL) && startX < (dip2px(120) + sL) && startY > dip2px(20) && startY < dip2px(50)) {
                    reset();
                }
                if (startX > (dip2px(40) + sL) && startX < (dip2px(200) + sL) && startY > sL / 2 && startY < dip2px(30) + sL / 2) {
                    check();
               }
                return true;
            case MotionEvent.ACTION_UP:
                endX = event.getX();
                endY = event.getY();
                int zy1 = ptCells[0].changeNum;
                int a = zy1 / level;
                int b = zy1 % level;//取余
                Log.i("===", "endX:" + (int) endX + "endY:" + (int) endY);
                if (Math.abs(endX - startX) > Math.abs(endY - startY) && Math.abs(endX - startX) > 30) {
                    if (endX > startX) {
                        Log.i("==", "向右滑动");
                        if (b - 1 >= 0) {
                            searchCells(zy1 - 1);
                            runNum++;
                        }
                    } else {
                        Log.i("==", "向左滑动");
                        if (b + 1 < level) {
                            searchCells(zy1 + 1);
                            runNum++;
                        }
                    }

                } else if (Math.abs(endX - startX) <= Math.abs(endY - startY) && Math.abs(endY - startY) > 30) {
                    if (endY > startY) {
                        Log.i("==", "向下滑动");
                        if (a - 1 >= 0) {
                            searchCells(zy1 - level);
                            runNum++;
                        }
                    } else {
                        Log.i("==", "向上滑动");
                        if (a + 1 < level) {
                            searchCells(zy1 + level);
                            runNum++;
                        }
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    //判断所有的拼图块是否完成
    void check() {
        boolean isOk = true;
        Log.i("==", "你调用了check");
        for (int i = 0; i < ptCells.length; i++) {
            if (ptCells[i].changeNum != ptCells[i].num) {
                Toast.makeText(getContext(), "还有拼图没有完成没有完成", Toast.LENGTH_LONG).show();
                isOk = false;
                break;
            }
        }
        if (isOk) {
            //创建一个对话框
            Intent mIntent = new Intent(mContext, ActivityRankStore.class);
            mIntent.putExtra("runNum", runNum);
            mIntent.putExtra("Level", level);
            mContext.startActivity(mIntent);
            //Toast.makeText(getContext(),"恭喜你完成了所有",Toast.LENGTH_LONG).show();
        }


    }

    //把拼图块全部归位
    void reset() {
        Log.i("===", "调用了reset");
        for (int i = 0; i < ptCells.length; i++) {
            ptCells[i].changeNum = ptCells[i].num;
        }
        invalidate();
    }

    //寻找有没有对应的拼图块
    void searchCells(int k) {
        for (int i = 0; i < ptCells.length; i++) {
            if (ptCells[i].changeNum == k) {
                int c = ptCells[i].changeNum;
                ptCells[i].changeNum = ptCells[0].changeNum;
                ptCells[0].changeNum = c;
                break;
            }
        }
        invalidate();
    }

    //如果是“继续游戏”,则调用这个方法
    void recover() {
        SharedPreferences pref = mContext.getSharedPreferences("data", Context.MODE_PRIVATE);
        String zy = pref.getString("save", "");
        runNum = (int) Double.parseDouble(zy.substring(zy.length() - 3, zy.length() - 2));
        String[] ss = zy.split("!");
        for (int i = 0; i < ptCells.length; i++) {
            ptCells[i].changeNum = (int) Double.parseDouble(ss[i].trim());
        }
    }

    private int dip2px(float dip) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dip * scale + 0.5f);
    }
.
}





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8037次
    • 积分:394
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:5篇
    • 译文:0篇
    • 评论:0条