2017-2018-1 20162307 实验五
北京电子科技学院(BESTI)
实 验 报 告
课程:程序设计与数据结构
班级:1623
姓名:张韵琪
学号:20162307
指导教师:娄嘉鹏老师、王志强老师
实验日期:2017年12月11号
实验密级:非密级
实验时间:三天
必修/选修:必修
实验名称:团队项目
实验仪器:电脑
实验目的与要求:
目的:
小组合作项目,开发2048
要求:
1.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程
2.完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
简介团队项目
2048:这款游戏的玩法很简单
每次可以选择上下左右滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢
系统会在空白的地方乱数出现一个数字方块
相同数字的方块在靠拢、相撞时会相加
不断的叠加最终拼凑出2048这个数字就算成功。
分析代码
主要类为 AnimaLayer.java、Card.java、Config.java、GameView.java
还有控制界面的类:developer.java、First_page.java、WelcomActivity.java、moshijieshao.java
-设定card:
public Card(Context context) {
super(context);
LayoutParams lp = null;
background = new View(getContext()); //这个是Card的背景设计,是一个View
lp = new LayoutParams(-1, -1);
lp.setMargins(10, 10, 0, 0); //设置子布局在父布局中的位置
background.setBackgroundColor(0x33ffffff);
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
}
手机的坐标事以左上角为原点o,右边是x轴,下边是y轴
创造卡片的移动动画:
public void createMoveAnim(final Card from, final Card to, int fromX, int toX, int fromY, int toY) { final Card c = getCard(from.getNum()); //将要移动的Card从原来的地方消失 LayoutParams lp = new LayoutParams(Config.CARD_WIDTH, Config.CARD_WIDTH); //CARD_WIDTH=0 lp.leftMargin = fromX * Config.CARD_WIDTH; //将card里面的布局的宽和高变成0; lp.topMargin = fromY * Config.CARD_WIDTH; c.setLayoutParams(lp); //c在执行这个方法之后,view的大小将发生改变 if (to.getNum() <= 0) { //如果移动到的位置的Card为0,则将此Card的TextView隐藏。 to.getLabel().setVisibility(View.INVISIBLE); } TranslateAnimation ta = new TranslateAnimation(0, Config.CARD_WIDTH * (toX - fromX), 0, Config.CARD_WIDTH * (toY - fromY)); ta.setDuration(100); //动画持续的时间0.5s ta.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override////动画停止,将姑且卡片收受接管 public void onAnimationEnd(Animation animation) { to.getLabel().setVisibility(View.VISIBLE); //将移过去的布局再打开 recycleCard(c); } }); c.startAnimation(ta); }
创建卡片(创建卡片时,若是cards不为空,则从cards队首取出一张姑且卡片):
private Card getCard(int num) { Card c; if (cards.size() > 0) { c = cards.remove(0); } else { c = new Card(getContext()); addView(c); } c.setVisibility(View.VISIBLE); c.setNum(num); return c; }
收受接管卡片:
private void recycleCard(Card c) { //因为原来要移动的Card已经移走了,剩下的地方就是空了,将剩下的地方添加到list中,list是专门存储空的card的 c.setVisibility(View.INVISIBLE); c.setAnimation(null); cards.add(c); }
对卡片进行缩放:
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控件添加动画 } }
手势辨认,用于操控格子的移动:
private void initGameView() { setOrientation(LinearLayout.VERTICAL); setBackgroundColor(0xff9B30FF); setOnTouchListener(new View.OnTouchListener() { //控制界面的点击事件 private float startX, startY, offsetX, offsetY; @Override public boolean onTouch(View v, MotionEvent event) { //应用了View.OnTouchListener来侦听触摸事务:策画按下和抬起来时offsetX和offsetY,猜测手势的移动。 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //如果是点击下来,获取点击地点的x和y的坐标 startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: //离开屏幕时的位置,获取离开屏幕时的位置,并获得位移量 offsetX = event.getX() - startX; offsetY = event.getY() - startY; 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的话,手指抬起时是不会得到坐标的 } }); }
滑动手势(以左滑为例):
private void swipeLeft() { boolean merge = false; //是否归并卡片, 1、空卡片和已有卡片归并 2、两个数字雷同的卡片归并 for (int y = 0; y < Config.LINES; y++) { //LINES=4 for (int x = 0; x < Config.LINES; x++) { //搜检当前点的右侧是否有非空卡片(非空:num>=2) for (int x1 = x + 1; x1 < Config.LINES; x1++) {//向左滑动时,将全部的数组遍历一遍,如果找到不为0的,且其左边为0时 if (cardsMap[x1][y].getNum() > 0) { ////若是右边有非空卡片 if (cardsMap[x][y].getNum() <= 0) { ////当前坐标上没有格子(空卡片和已有卡片归并) 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(); }
}
本次实验
实验五-1-编译、运行、测试
题目要求
1、 git clone 小组项目
2、 编译项目,提交编译成功截图(全屏,要有学号信息)
3、 提交运行过程中的截图(全屏,要有学号信息)
实验结果及步骤
- 在AndroidStudio中运行项目
实验五-2-代码修改
题目要求
- 在小组项目中,找一个合适的地方添加一个按钮,点击显示自己的学号
- 提交运行截图(全屏,要有学号信息)
- 在项目中找一个界面,自己复制一份命名为XXXbak,修改代码,替换原来的部分
- 提交运行截图(全屏,要有学号信息)
实验结果及步骤
- 在First_page中,添加一个button
button4 = (Button)findViewById(R.id.zyq);
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(First_page.this)
.setTitle("实验二")
.setMessage("20162307张韵琪")
.setPositiveButton("确定", null)
.show();
}
});
- 在模式介绍中,修改代码
button3 = (Button)findViewById(R.id.zyq);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(moshijieshao.this)
.setTitle("更改")
.setMessage("20162307 张韵琪")
.setPositiveButton("确定", null)
.show();
}
实验五-3-代码分析
题目要求
分析小组代码:
- 数据结构的应用情况及相关代码
- 排序算法的应用情况及相关代码
- 查找算法的应用情况及相关代码
- 完成实验报告
实验结果及步骤
数据结构的应用情况及相关代码:见目录分析代码这部分
排序算法、查找算法打算在排行榜中应用,但是目前还未完成