2017-2018-1 20162307 實驗五
2017-2018-1 20162307 實驗五
北京電子科技學院(BESTI)
實 驗 報 告
課程:程序設計與數據結構
班級:1623
姓名:張韻琪
學號:20162307
指導教師:婁嘉鵬老師、王誌強老師
實驗日期:2017年12月11號
實驗密級:非密級
實驗時間:三天
必修/選修:必修
實驗名稱:團隊項目
實驗儀器:電腦
實驗目的與要求:
目的:
小組合作項目,開發2048
要求:
1.沒有Linux基礎的同學建議先學習《Linux基礎入門(新版)》《Vim編輯器》 課程
2.完成實驗、撰寫實驗報告,實驗報告以博客方式發表在博客園,註意實驗報告重點是運行結果,遇到的問題(工具查找,安裝,使用,程序的編輯,調試,運行等)、解決辦法(空洞的方法如“查網絡”、“問同學”、“看書”等一律得0分)以及分析(從中可以得到什麽啟示,有什麽收獲,教訓等)。報告可以參考範飛龍老師的指導
簡介團隊項目
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、 提交運行過程中的截圖(全屏,要有學號信息)
實驗結果及步驟
1.打開我的終端,進入我所創建的文件夾的目錄中
git clone 小組項目
- 在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-代碼分析
題目要求
分析小組代碼:
- 數據結構的應用情況及相關代碼
- 排序算法的應用情況及相關代碼
- 查找算法的應用情況及相關代碼
- 完成實驗報告
實驗結果及步驟
數據結構的應用情況及相關代碼:見目錄分析代碼這部分
排序算法、查找算法打算在排行榜中應用,但是目前還未完成
2017-2018-1 20162307 實驗五