码迷,mamicode.com
首页 > 其他好文 > 详细

20162303 实验五 数据结构综合应用

时间:2017-12-17 23:57:25      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:move   out   解决方法   布局   综合   文字   目的   activity   课程   

北京电子科技学院(BESTI)

实 验 报 告

课程:程序设计与数据结构
班级: 1623
姓名: 石亚鑫
学号:20162303

成绩: 2分
指导教师:娄嘉鹏 王志强
实验日期:12月15日

实验密级: 非密级
预习程度: 已预习
实验时间:10:00-12:00

必修/选修: 必修
实验序号: cs_03

实验内容

实验 分析系统架构

首先分析一下各部分代码

card类

card是用来显示2048游戏中的数字卡片,首先设定的是card的背景

/*  
         * LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值: 
    1,一个确定的值; 
    2,FILL_PARENT,即填满(和父容器一样大小); 
    3,WRAP_CONTENT,即包裹住组件就好。
 */

        LayoutParams lp = null;   //传递在子视图中布局的设计

        background = new View(getContext());  //这个是Card的背景设计,是一个View
         //-1代表LayoutParams.MATCH_PARENT,即该布局的尺寸将填满它的父控件;   
        //-2代表LayoutParams.WRAP_CONTENT,即该布局的尺寸将为其自身内容的尺寸;
        lp = new LayoutParams(-1, -1);  
        lp.setMargins(10, 10, 0, 0);   //设置子布局在父布局中的位置
        background.setBackgroundColor(0x33ffffff);   //33表示的是透明度 ffffff是白色    
        addView(background, lp);   //向布局文件中添加一个子布局

        label = new TextView(getContext());//在Card中有一个数字
        label.setTextSize(20);      //数字的大小
        label.setGravity(Gravity.CENTER);   //数字在Card中居中
        lp = new LayoutParams(-1, -1);   //控制数字在Card中width和height
        lp.setMargins(10, 10, 0, 0);   //控制数字在Card中的出现位置
        addView(label, lp);
        setNum(0);  //初始化每一个card的时候都是0
    }

然后根据卡片的数字决定卡片的背景颜色。

        switch (num) {
        case 0:
            label.setBackgroundColor(0x00000000);      //什么也没有的时候是黑色
            break;
        case 2:
            label.setBackgroundColor(0xffeee4da);
            break;
        case 4:
            label.setBackgroundColor(0xffede0c8);
            break;
        case 8:
            label.setBackgroundColor(0xfff2b179);
            break;
        case 16:
            label.setBackgroundColor(0xfff59563);
            break;
        case 32:
            label.setBackgroundColor(0xfff67c5f);
            break;
        case 64:
            label.setBackgroundColor(0xfff65e3b);
            break;
        case 128:
            label.setBackgroundColor(0xffedcf72);
            break;
        case 256:
            label.setBackgroundColor(0xffedcc61);
            break;
        case 512:
            label.setBackgroundColor(0xffedc850);
            break;
        case 1024:
            label.setBackgroundColor(0xffedc53f);
            break;
        case 2048:
            label.setBackgroundColor(0xffedc22e);
            break;
        default:
            label.setBackgroundColor(0xff3c3a32);
            break;
Config类

这个类主要是定义2048的游戏模式,可以选择44或者是66的

GameView类

这部分代码定义向上下左右滑动,首先确定方向为手指最先触碰显示屏时确定一个坐标,手指离开显示屏的时候确定另一个坐标,两坐标之差来确定移动方向。在安卓手机设定中,左上角为原点,x轴正方向为向右,y轴正方向为向下,因此假设x轴的坐标差为负,就是向左滑

            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:   //如果是点击下来,获取点击地点的x和y的坐标
                    startX = event.getX();
                    startY = event.getY();
                    break;
                case MotionEvent.ACTION_UP:     //离开屏幕时的位置,获取离开屏幕时的位置,并获得位移量
                    offsetX = event.getX() - startX;  //手指离开时的X坐标减去按下去时X的坐标
                    offsetY = event.getY() - startY; // 手指离开时 的Y坐标减去按下去时的Y的坐标

                    if (Math.abs(offsetX) > Math.abs(offsetY)) {  //取offsetxX和offsetY的绝对值
                        if (offsetX < -5) {
                            swipeLeft();  //滑动向左
                        } else if (offsetX > 5) {
                            swipeRight();   //向右划
                        }
                    } else {
                        if (offsetY < -5) {
                            swipeUp();    //向上划
                        } else if (offsetY > 5) {
                            swipeDown();   //向下划
                        }
                    }

                    break;
                }
                return true;   //这个地方如果是false的话,手指抬起时是不会得到坐标的
            }
        });
    }

产生随机数,先确定整个界面有几个空格,通过Math.random()产生一个0-1的数,在乘以空格数,随机产生一个数来使对应卡片的数字换成2或者4,比例为9比1

    private void addRandomNum() {
        emptyPoints.clear();
        for (int y = 0; y < Config.LINES; y++) {
            for (int x = 0; x < Config.LINES; x++) {
                if (cardsMap[x][y].getNum() <= 0) {   //如果Card为空的话,则将这个card记录下来
                    emptyPoints.add(new Point(x, y));
                }
            }
        }
        if (emptyPoints.size() > 0) {
            /*
             * Math.random()会随机产生一个0-1之间的小数,假如emptyPoints.size()等于16
             * (int) (Math.random() * emptyPoints.size())会产生一个0到16之间的数。
             *
             * */
            Point p = emptyPoints.remove((int) (Math.random() * emptyPoints.size()));  //从Card为0的卡片中随机移除一个
            cardsMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4);    //被移除的card被2或者4替换,且出现2的几率更大一些
            MainActivity.getMainActivity().getAnimLayer()
                    .createScaleTo1(cardsMap[p.x][p.y]);    //给新生成的Card添加动画效果
        }
    }

定义滑动运算,选定一个不为零卡片如果左边为0,那将这个卡片与左边合并,同时左边的卡片数字由这个卡片替代,如果左边的卡片数字不为0,如果数字和这个卡片相等,那么左边卡片数字乘2,这个卡片设为0,如果不相等,不移动,依次遍历。其他方向等同向左滑动运算。

    //滑动向左移动运算
    private void swipeLeft() {

        boolean merge = false;

        for (int y = 0; y < Config.LINES; y++) {  //LINES=4
            for (int x = 0; x < Config.LINES; x++) {

                for (int x1 = x + 1; x1 < Config.LINES; x1++) {//向左滑动时,将全部的数组遍历一遍,如果找到不为0的,且其左边为0时
                    if (cardsMap[x1][y].getNum() > 0) {

                        if (cardsMap[x][y].getNum() <= 0) {   //cardsMap[x][y].getNum()获取card上面的数字

                            MainActivity
                                    .getMainActivity()
                                    .getAnimLayer()
                                    .createMoveAnim(cardsMap[x1][y],
                                            cardsMap[x][y], x1, x, y, y);

                            cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
                            cardsMap[x1][y].setNum(0);

                            x--;
                            merge = true;

                        } else if (cardsMap[x][y].equals(cardsMap[x1][y])) {
                            MainActivity
                                    .getMainActivity()
                                    .getAnimLayer()
                                    .createMoveAnim(cardsMap[x1][y],
                                            cardsMap[x][y], x1, x, y, y);   //使用这个方法之后,在效果上可以表示成移动了
                            cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);//这个地方可以修改数字的增加原本是2
                            cardsMap[x1][y].setNum(0);

                            MainActivity.getMainActivity().addScore(
                                    cardsMap[x][y].getNum());
                            merge = true;
                        }

                        break;
                    }
                }
            }
        }

        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

判断是否满,如果所有卡片的上下左右都没有和自己相同的卡片的数字时,游戏结束,跳出提示。

    private void checkComplete() {

        boolean complete = true;

        ALL: for (int y = 0; y < Config.LINES; y++) {
            for (int x = 0; x < Config.LINES; x++) {
                /*
                   1.卡片的数字为0时
                   3.卡片的数字不为0时,x在0-3之间,且x卡片的数字和左右相邻的卡片的数字相同时
                   4.卡片的数字不为0时,  0<y<3,且y的卡片的数字和上下相邻的卡片的数字相同时
                */
                if (cardsMap[x][y].getNum() == 0
                        || (x > 0 && cardsMap[x][y].equals(cardsMap[x - 1][y]))
                        || (x < Config.LINES - 1 && cardsMap[x][y]
                                .equals(cardsMap[x + 1][y]))
                        || (y > 0 && cardsMap[x][y].equals(cardsMap[x][y - 1]))
                        || (y < Config.LINES - 1 && cardsMap[x][y]
                                .equals(cardsMap[x][y + 1]))) {
                    complete = false;
                    break ALL;   //跳出循环
                }
            }
        }

        if (complete) {  //给出错误提示信息
            new AlertDialog.Builder(getContext())
                    .setTitle(R.string.tishi)
                    .setMessage(R.string.falses)
                    .setPositiveButton(R.string.queding,
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    startGame();
                                }
                            }).show();
        }
    }
AnimaLayer类

这个类主要是用来定义动画效果

    /*
     * ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 
     *
     *float fromX 动画起始时 X坐标上的伸缩尺寸 
      float toX 动画结束时 X坐标上的伸缩尺寸 
      float fromY 动画起始时Y坐标上的伸缩尺寸 
      float toY 动画结束时Y坐标上的伸缩尺寸 
      int pivotXType 动画在X轴相对于物件位置类型 
      float pivotXValue 动画相对于物件的X坐标的开始位置 
      int pivotYType 动画在Y轴相对于物件位置类型 
      float pivotYValue 动画相对于物件的Y坐标的开始位置 
      
      
      Animation.RELATIVE_TO_SELF为相对于自身
      Animation.RELATIVE_TO_PARENT为相对于父控件
     *
    */

    public void createScaleTo1(Card target) {
        ScaleAnimation sa = new ScaleAnimation(0.1f, 1, 0.1f, 1,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,    //相对于Card自身的0.5f就是Card的中心
                0.5f);
        sa.setDuration(100);  //持续时间为0.5s
        target.setAnimation(null);
        target.getLabel().startAnimation(sa);   //给Card对应的TextView控件添加动画
    }

实验一

1 git clone 小组项目
2 编译项目,提交编译成功截图(全屏,要有学号信息)
3 提交运行过程中的截图(全屏,要有学号信息)

实验二

  1. 在小组项目中,找一个合适的地方添加一个按钮,点击显示自己的学号
  2. 提交运行截图(全屏,要有学号信息)
  3. 在项目中找一个界面,自己复制一份命名为XXXbak,修改代码,替换原来的部分
  4. 提交运行截图(全屏,要有学号信息)

实验三

分析小组代码:

  1. 数据结构的应用情况及相关代码
  2. 排序算法的应用情况及相关代码
  3. 查找算法的应用情况及相关代码
  4. 完成实验报告

实验步骤

(1) 实验一

1.首先,新建一个名为20162303syxexp5的文件夹,在这个文件夹中打开git bash,然后输入命令行git clong + 项目地址。
成功clone:下面为截图。
技术分享图片
2.编译运行
由于gradle的版本不一致,
技术分享图片
技术分享图片
可以看出来,拉下来的项目的gradle的版本是3.3,而我本地的是4.1
因为现场下载3.3版本的压缩包需要一定时间,所以我把拉下来的项目的gradle和.gradle文件夹换成自己本地的gradle和.gradle文件夹,还有一种解决方法就是把拉下来的项目的gradle-wrapper.properties中的最后一行的版本改成自己本地的版本,
技术分享图片
路径见下图。
技术分享图片
由此就可以正常的编译运行了:
技术分享图片
技术分享图片

(2) 实验二

1.在小组项目中,我选择在模式接受页面添加一个按钮,点击显示自己的学号,按钮文字设置为自己名字 ,给按钮设置监听器 ,点击按钮时发出一条Tost消息显示学号20162303

        button3 = (Button)findViewById(R.id.syx);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(moshijieshao.this)
                        .setTitle("syx")
                        .setMessage("20162303石亚鑫")
                        .setPositiveButton("确定", null)
                        .show();
            }
        });

技术分享图片
技术分享图片

  1. 在项目中模式介绍界面,自己复制一份命名为moshijieshaobak,修改代码,替换原来的部分

    public class moshijieshaobak extends AppCompatActivity {
    private Button button1, button2, button3;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.moshijieshao);
        button3 = (Button)findViewById(R.id.syx);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(moshijieshaobak.this)
                        .setTitle("syx")
                        .setMessage("20162303石亚鑫")
                        .setPositiveButton("确定", null)
                        .show();
            }
        });
    }
    }

    把原有的按钮去掉。
    把AndroidManifest中标签改为20162303

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="20162303"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".WelcomActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".First_page"></activity>
        <activity android:name=".MainActivity"></activity>
        <activity android:name=".HardGameActivity"></activity>
        <activity android:name=".developer"></activity>
        <activity android:name=".moshijieshao"></activity>
    </application>

    技术分享图片

(3) 实验三

数据结构

card是用来显示2048游戏中的数字卡片,通过一个二维数组来设定,是每一个数字卡片的布局类
AnimLayer类是用来控制动画效果的类
GameView类,就是玩游戏的地方,它里面“装”了多个Card,还调用AnimaLayer类来实现动画效果
Config类,就是用来定义 44 还是 66
GameView类是自定义的LinerLayout,Card和GameView是自定义的Fragment
代码见博客开头

查找算法和排序算法

计划用二叉树查找和排序作出一个排行榜界面,但是目前还没有实现。

20162303 实验五 数据结构综合应用

标签:move   out   解决方法   布局   综合   文字   目的   activity   课程   

原文地址:http://www.cnblogs.com/syx390234975/p/8052722.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!