Android2048实战练习小结

从2048学习GridLayout

学习安卓时候,自己做了一个2048的练习,东西都是自己边做边学的。

游戏界面
这款游戏的结构还是十分简单的,核心的逻辑在中间4*4的版面。
我之前写过Web前端,所以我想这个游戏的界面能够适合所有大小的屏幕,所以我决定使用GridLayout的比重特性。(踩坑开始)


向布局添加子项的代码

//实例化子项,因为是练习,想着用动态添加的方法来做。子项是继承自View自己画的,因为很简单就不详细说明了。
cards[i][j] = new Card(this.context);

/**设置子项在父项的属性
*子项动态设置属性需要使用.LayoutParams()方法
*继承的GridLayout有LayoutParams可以帮助设置GridLayout独有的属性
*GridLayout.spec(int start, int size, float weight)这是其中一个方法,不过参数的名字意义是一样的。
start是指你的这个子项是要放在哪一行或者哪一列;size是指子项在这一行(或列)占几个格子的宽度;weight是指子项的比重;
*遇到的一个玄学问题就是,用了权重比的方法分配子项的空间,如果子项宽高没有设置为零就会显示不出来。因为实在是太菜了,实在弄不清这到底是为什么
*还有一个让人头大的事情就是用了权重比之后,如果再设置Margin值,再宽度上还是四等分,但是长度上就会变成math_parent的效果(太菜了也不明白)
GridLayout.Spec row = GridLayout.spec(i , 1, 1f);
GridLayout.Spec column = GridLayout.spec(j , 1, 1f);
GridLayout.LayoutParams params = new GridLayout.LayoutParams(row, column);
params.width = 0;
params.height = 0;
cards[i][j].setLayoutParams(params);
cards[i][j].setNumber(datas[i][j]);
this.addView(cards[i][j]);

监听用户的手势

本来是想在onTouchEven()方法中实现逻辑的,但是没有找到,只好用dispatchTouchEvent()方法来替代。

我是通过监听用户抬起和放下手指的坐标来实现滑动方向的监听的,计算用户行为的代码写的非常劳,大家懂这个意思就行了,不要学。

    enum Direction{
        up, down, left, right, NULL
    }

    //方向集
    Direction direction = Direction.NULL;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //获取触控位置
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
           down_x = ev.getX();
           down_y = ev.getY();
        }

        if (ev.getAction() == MotionEvent.ACTION_UP){
           up_x = ev.getX();
           up_y = ev.getY();
        }
        if (up_x < 1 && up_y <1){
            up_x = down_x;
            up_y = down_y;
        }

        //计算用户行为
        float r_x = down_x - up_x;
        float r_y = down_y - up_y;
        float XorY = Math.abs(r_x) - Math.abs(r_y);
        if (XorY > 0){
            if (r_x > 0){
                direction = Direction.left;

            }else {
                direction = Direction.right;
            }
            mOnDirectionListener();
        }else if (XorY < 0){
            if (r_y > 0){
                direction = Direction.up;
            }else {
                direction = Direction.down;
            }
            mOnDirectionListener();
        }else {
            direction = Direction.NULL;
        }
        up_x=up_y=0;
        return true;
    }

mOnDirectionListener()这个方法就是用来根据不同的滑动方向来计算滑动后的结果,游戏的核心算法在这里,但这并不是这篇教程的核心,百度上有各种实现。


概述设计理念

这个游戏的主题视窗由Field(GridLayout的一个子类),和Card(自定义View)。Field带有根据用户的手势更改数据的逻辑操作能力,这些能力都在dispatchTouchEvent()方法被调用的时候运行。Field中有一组Card,还有对应的一组int型数组,每次逻辑只对数组进行操作,完成后才一次性修改Card对应里的数值。
Field里有一个游戏监听的接口,当游戏获胜(获得2048的卡片),游戏结束(不能再走动了),分数改变时调用。对应的操作时Activity中跳出相应的提升或者修改分数的数值。
总结一下,做2048这游戏练习,学习了自定义布局和控件的写法,了解了监听点击事件的分发和获取的过程,总的来说还是蛮有收获的。


希望有大佬能够在评论里能指出我的不足。

猜你喜欢

转载自blog.csdn.net/a_fish_lost_dream/article/details/79987638