实验3 --俄罗斯方块 with 20135335郝爽
一、?? 實驗內容
(一)敏捷開發(fā)與XP
內容:1.敏捷開發(fā)(Agile Development)是一種以人為核心、迭代、循序漸進的開發(fā)方法。
2.極限編程(eXtreme Programming,XP)是一種全新而快捷的軟件開發(fā)方法。
要點: 1. XP軟件開發(fā)的基石是XP的活動,包括:編碼、測試、傾聽、設計。
2. 我們關注其中的編碼標準,結對編程,代碼集體所有,測試,重構等實踐。(如實驗二中的TDD)
?
(二)編碼標準
內容:編程標準使代碼更容易閱讀和理解,甚至可以保證其中的錯誤更少。編程標準包含:具有說明性的名字、清晰的表達式、直截了當?shù)目刂屏鳌⒖勺x的代碼和注釋,以及在追求這些內容時一致地使用某些規(guī)則和慣用法的重要性。
學習:
1. 軟件輔助修改:在eclipse中,用source->Format進行格式規(guī)范;
2. 自己命名:包名全部小寫,如: io ;類名第一個字母要大寫,如:HelloWorldApp;等
(三)結對編程
內容:在結對編程模式下,一對程序員肩并肩、平等地、互補地進行開發(fā)工作。其中的角色分配為駕駛員(控制鍵盤輸入),領航人(起到領航、提醒作用)。
(四)版本控制
摘要:版本控制提供項目級的 undo(撤銷) 功能;??? 版本控制允許多人在同一代碼上工作;?? 版本控制系統(tǒng)保存了過去所作的修改的歷史記錄;具體步驟如下——
# 添加修改文件
$ git add 所有修改的文件
# 提交到環(huán)境中本地代碼倉庫
$ git commit -m '本次修改的描述'
# push到git.shiyanlou.com,無需輸入密碼
$ git push
學習:按照要求指導,逐步在實驗樓中完成,截圖如下:
(五)重構
摘要:重構(Refactor),就是在不改變軟件外部行為的基礎上,改變軟件內部的結構,使其更加易于閱讀、易于維護和易于變更 。學習:嘗試Encapsulate Field(封裝)功能:
原圖:
(六)實踐項目
同伴郝爽20135335博客地址http://www.cnblogs.com/20135335hs
1.綜述
我們采取“先學習,后操作;邊操作,邊變通”的實驗思路。具體方法是:研讀要求—學習代碼要素—復習TDD內容—構建測試程序—檢查測試程序—測試產品代碼—修改產品代碼—重新檢查產品代碼—完成實驗報告。在這一過程中,我們對各方面內容都進行了詳細記錄(未在實驗樓中進行托管和git)
團隊由兩名成員組成,詳細分工為:
20135335郝爽:負責前期學習的整理工作,將java代碼進行必要注釋,并對TDD內容進行補充;進行后期測試
20135233楊光:負責中期的測試代碼開發(fā);進行后期測試
?
2.研讀要求與自我學習(20135211)
1.TDD(Test Driven Development, 測試驅動開發(fā)),
TDD的一般步驟如下:
- 明確當前要完成的功能,記錄成一個測試列表
- 快速完成編寫針對此功能的測試用例
- 測試代碼編譯不通過(沒產品代碼呢)
- 編寫產品代碼
- 測試通過
- 對代碼進行重構,并保證測試通過(重構下次實驗練習)
- 循環(huán)完成所有功能的開發(fā)
2. 測試類具體操作:把鼠標放到項目名上,單擊右鍵,在彈出的菜單中選定New->Source Folder新建一個測試目錄test;把鼠標放到test目錄上,單擊右鍵,在彈出的菜單中選定New->JUnit Test Case新建一個測試用例類
3.實驗要求要點為:程序要有GUI界面,參考用戶界面和用戶體驗;記錄TDD和重構的過程,測試代碼不要少于業(yè)務代碼
??
package game;
?
import java.awt.Button;?
import java.awt.Canvas;?
import java.awt.Color;?
import java.awt.Dimension;?
import java.awt.Frame;?
import java.awt.Graphics;?
import java.awt.GridLayout;?
import java.awt.Insets;?
import java.awt.Label;?
import java.awt.Panel;?
import java.awt.TextField;?
import java.awt.event.ActionEvent;?
import java.awt.event.ActionListener;?
import java.awt.event.KeyEvent;?
import java.awt.event.KeyListener;?
import java.awt.event.WindowAdapter;?
import java.awt.event.WindowEvent;?
import java.awt.event.WindowListener;
?
//俄羅斯方塊類??
public class ERS_Block extends Frame {?
??? public static boolean isPlay = false;?
??? public static int level = 1, score = 0;?
??? public static TextField scoreField, levelField;?
??? public static MyTimer timer;?
??? GameCanvas gameScr;?
??? public static void main(String[] argus) {?
??????? ERS_Block ers = new ERS_Block(?
??????????????? "俄羅斯方塊游戲? V1.0?????????????????? Author:Vincent");?
??????? WindowListener win_listener = new WinListener();?
??????? ers.addWindowListener(win_listener);?
??? }?
??? // 俄羅斯方塊類的構造方法?
??? ERS_Block(String title) {?
???? ???super(title);?
??????? setSize(600, 480);?
??????? setLayout(new GridLayout(1, 2));?
??????? gameScr = new GameCanvas();?
??????? gameScr.addKeyListener(gameScr);?
??????? timer = new MyTimer(gameScr);?
??????? timer.setDaemon(true);?
??????? timer.start();?
??????? timer.suspend();?
??????? add(gameScr);?
??????? Panel rightScr = new Panel();?
??????? rightScr.setLayout(new GridLayout(2, 1, 0, 30));?
??????? rightScr.setSize(120, 500);?
??????? add(rightScr);?
??????? // 右邊信息窗體的布局?
?? ?????MyPanel infoScr = new MyPanel();?
??????? infoScr.setLayout(new GridLayout(4, 1, 0, 5));?
??????? infoScr.setSize(120, 300);?
??????? rightScr.add(infoScr);?
??????? // 定義標簽和初始值?
??????? Label scorep = new Label("分數(shù):", Label.LEFT);?
??????? Label levelp = new Label("級數(shù):", Label.LEFT);?
??????? scoreField = new TextField(8);?
??????? levelField = new TextField(8);?
??????? scoreField.setEditable(false);?
??????? levelField.setEditable(false);?
??????? infoScr.add(scorep);?
??????? infoScr.add(scoreField);?
??????? infoScr.add(levelp);?
??????? infoScr.add(levelField);?
??????? scorep.setSize(new Dimension(20, 60));?
??????? scoreField.setSize(new Dimension(20, 60));?
??????? levelp.setSize(new Dimension(20, 60));?
??????? levelField.setSize(new Dimension(20, 60));?
??????? scoreField.setText("0");?
??????? levelField.setText("1");?
??????? // 右邊控制按鈕窗體的布局?
??????? MyPanel controlScr = new MyPanel();?
??????? controlScr.setLayout(new GridLayout(5, 1, 0, 5));?
??????? rightScr.add(controlScr);?
??????? // 定義按鈕play?
??????? Button play_b = new Button("開始游戲");?
??????? play_b.setSize(new Dimension(50, 200));?
??????? play_b.addActionListener(new Command(Command.button_play, gameScr));?
??????? // 定義按鈕Level UP?
??????? Button level_up_b = new Button("提高級數(shù)");?
??????? level_up_b.setSize(new Dimension(50, 200));?
??????? level_up_b.addActionListener(new Command(Command.button_levelup,?
??????????????? gameScr));?
??????? // 定義按鈕Level Down?
??????? Button level_down_b = new Button("降低級數(shù)");?
??????? level_down_b.setSize(new Dimension(50, 200));?
??????? level_down_b.addActionListener(new Command(Command.button_leveldown,?
??????????????? gameScr));?
??????? // 定義按鈕Level Pause?
??????? Button pause_b = new Button("游戲暫停");?
? ??????pause_b.setSize(new Dimension(50, 200));?
??????? pause_b.addActionListener(new Command(Command.button_pause, gameScr));?
??????? // 定義按鈕Quit?
??????? Button quit_b = new Button("退出游戲");?
??????? quit_b.setSize(new Dimension(50, 200));?
??????? quit_b.addActionListener(new Command(Command.button_quit, gameScr));?
??????? controlScr.add(play_b);?
??????? controlScr.add(level_up_b);?
??????? controlScr.add(level_down_b);?
??????? controlScr.add(pause_b);?
??????? controlScr.add(quit_b);?
??????? setVisible(true);?
??????? gameScr.requestFocus();?
??? }?
}?
// 重寫MyPanel類,使Panel的四周留空間?
class MyPanel extends Panel {?
??? public Insets getInsets() {?
??????? return new Insets(30, 50, 30, 50);?
??? }?
}?
// 游戲畫布類?
class GameCanvas extends Canvas implements KeyListener {?
??? final int unitSize = 30; // 小方塊邊長?
??? int rowNum; // 正方格的行數(shù)?
??? int columnNum; // 正方格的列數(shù)?
??? int maxAllowRowNum; // 允許有多少行未削?
??? int blockInitRow; // 新出現(xiàn)塊的起始行坐標?
??? int blockInitCol; // 新出現(xiàn)塊的起始列坐標?
?? ?int[][] scrArr; // 屏幕數(shù)組?
??? Block b; // 對方快的引用?
??? // 畫布類的構造方法?
??? GameCanvas() {?
??????? rowNum = 15;?
??????? columnNum = 10;?
??????? maxAllowRowNum = rowNum - 2;?
??????? b = new Block(this);?
??????? blockInitRow = rowNum - 1;?
??????? blockInitCol = columnNum / 2 - 2;?
??????? scrArr = new int[32][32];?
??? }?
??? // 初始化屏幕,并將屏幕數(shù)組清零的方法?
??? void initScr() {?
??????? for (int i = 0; i < rowNum; i++)?
??????????? for (int j = 0; j < columnNum; j++)?
??????????????? scrArr[i][j] = 0;?
??????? b.reset();?
??????? repaint();?
??? }?
??? // 重新刷新畫布方法?
??? public void paint(Graphics g) {?
??????? for (int i = 0; i < rowNum; i++)?
??????????? for (int j = 0; j < columnNum; j++)?
??????????????? drawUnit(i, j, scrArr[i][j]);?
??? } ?
??? // 畫方塊的方法?
??? public void drawUnit(int row, int col, int type) {?
??????? scrArr[row][col] = type;?
??????? Graphics g = getGraphics();?
??????? switch (type) { // 表示畫方快的方法?
??????? case 0:?
??????????? g.setColor(Color.black);?
??????????? break; // 以背景為顏色畫?
??????? case 1:?
??????????? g.setColor(Color.blue);?
??????????? break; // 畫正在下落的方塊?
??????? case 2:?
??????????? g.setColor(Color.magenta);?
??????????? break; // 畫已經(jīng)落下的方法?
??????? }?
??????? g.fill3DRect(col * unitSize, getSize().height - (row + 1) * unitSize,?
??????????????? unitSize, unitSize, true);?
??????? g.dispose();?
??? }?
??? public Block getBlock() {?
??????? return b; // 返回block實例的引用?
??? }?
??? // 返回屏幕數(shù)組中(row,col)位置的屬性值?
??? public int getScrArrXY(int row, int col) {?
??????? if (row < 0 || row >= rowNum || col < 0 || col >= columnNum)?
??????????? return (-1);?
??????? else?
??????????? return (scrArr[row][col]);?
??? }?
??? // 返回新塊的初始行坐標方法?
??? public int getInitRow() {?
??????? return (blockInitRow); // 返回新塊的初始行坐標?
??? }?
??? // 返回新塊的初始列坐標方法?
??? public int getInitCol() {?
??????? return (blockInitCol); // 返回新塊的初始列坐標?
??? }?
??? // 滿行刪除方法?
??? void deleteFullLine() {?
??????? int full_line_num = 0;?
??????? int k = 0;?
??????? for (int i = 0; i < rowNum; i++) {?
??????????? boolean isfull = true;?
??????????? L1: for (int j = 0; j < columnNum; j++)?
??????????????? if (scrArr[i][j] == 0) {?
??????????????????? k++;?
??????????????????? isfull = false;?
??????????????????? break L1; ?
??????????????? }?
??????????? if (isfull)?
??????????????? full_line_num++;?
??????????? if (k != 0 && k - 1 != i && !isfull)?
??????????????? for (int j = 0; j < columnNum; j++) {?
??????????????????? if (scrArr[i][j] == 0)?
???????????????????? ???drawUnit(k - 1, j, 0);?
??????????????????? else?
??????????????????????? drawUnit(k - 1, j, 2);?
??????????????????? scrArr[k - 1][j] = scrArr[i][j];?
??????????????? }?
??????? }?
??????? for (int i = k - 1; i < rowNum; i++) {?
??????????? for (int j = 0; j < columnNum; j++) {?
??????????????? drawUnit(i, j, 0);?
??????????????? scrArr[i][j] = 0;?
??????????? }?
??????? }?
??????? ERS_Block.score += full_line_num;?
??????? ERS_Block.scoreField.setText("" + ERS_Block.score);?
??? }?
??? // 判斷游戲是否結束方法?
??? boolean isGameEnd() {?
??????? for (int col = 0; col < columnNum; col++) {?
??????????? if (scrArr[maxAllowRowNum][col] != 0)?
??????????????? return true;?
??????? }?
??????? return false;?
??? }?
??? public void keyTyped(KeyEvent e) {?
??? }?
??? public void keyReleased(KeyEvent e) {?
??? }?
??? // 處理鍵盤輸入的方法?
??? public void keyPressed(KeyEvent e) {?
??????? if (!ERS_Block.isPlay)?
??????????? return;?
??????? switch (e.getKeyCode()) {?
??????? case KeyEvent.VK_DOWN:?
??????????? b.fallDown();?
??????????? break;?
??????? case KeyEvent.VK_LEFT:?
??????????? b.leftMove();?
??????????? break;?
??????? case KeyEvent.VK_RIGHT:?
??????????? b.rightMove();?
??????????? break;?
??????? case KeyEvent.VK_SPACE:?
?? ?????????b.leftTurn();?
??????????? break;?
??????? }?
??? }?
}?
// 處理控制類?
class Command implements ActionListener {?
??? static final int button_play = 1; // 給按鈕分配編號?
??? static final int button_levelup = 2;?
??? static final int button_leveldown = 3;?
??? static final int button_quit = 4;?
??? static final int button_pause = 5;?
??? static boolean pause_resume = true;?
??? int curButton; // 當前按鈕?
??? GameCanvas scr;?
??? // 控制按鈕類的構造方法?
??? Command(int button, GameCanvas scr) {?
??????? curButton = button;?
??????? this.scr = scr;?
??? }?
??? // 按鈕執(zhí)行方法?
??? public void actionPerformed(ActionEvent e) {?
??????? switch (curButton) {?
??????? case button_play:?
??????????? if (!ERS_Block.isPlay) {?
??????????????? scr.initScr();?
??? ????????????ERS_Block.isPlay = true;?
??????????????? ERS_Block.score = 0;?
??????????????? ERS_Block.scoreField.setText("0");?
??????????????? ERS_Block.timer.resume();?
??????????? }?
??????????? scr.requestFocus();?
??????????? break;?
??????? case button_levelup:?
??????????? if (ERS_Block.level < 10) {?
??????????????? ERS_Block.level++;?
??????????????? ERS_Block.levelField.setText("" + ERS_Block.level);?
??????????????? ERS_Block.score = 0;?
??????????????? ERS_Block.scoreField.setText("" + ERS_Block.score);?
??????????? }?
??????????? scr.requestFocus();?
??????????? break;?
??????? case button_leveldown:?
??????????? if (ERS_Block.level > 1) {?
??????????????? ERS_Block.level--;?
??????????????? ERS_Block.levelField.setText("" + ERS_Block.level);?
??????????????? ERS_Block.score = 0;?
??????????????? ERS_Block.scoreField.setText("" + ERS_Block.score);?
??????????? }?
??????????? scr.requestFocus();?
??????????? break;?
??????? case button_pause:?
??????????? if (pause_resume) {?
??????????????? ERS_Block.timer.suspend();?
??????????????? pause_resume = false;?
??????????? } else {?
??????????????? ERS_Block.timer.resume();?
??????????????? pause_resume = true;?
??????????? }?
??????????? scr.requestFocus();?
??????????? break;?
??????? case button_quit:?
??????????? System.exit(0);?
??????? }?
??? }?
}?
// 方塊類?
class Block {?
??? static int[][] pattern = {?
??????????? { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 用十六進至表示,本行表示長條四種狀態(tài)?
??????????? { 0x04e0, 0x0464, 0x00e4, 0x04c4 },?
??????????? { 0x4620, 0x6c00, 0x4620, 0x6c00 },?
??????????? { 0x2640, 0xc600, 0x2640, 0xc600 },?
??????????? { 0x6220, 0x1700, 0x2230, 0x0740 },?
??????????? { 0x6440, 0x0e20, 0x44c0, 0x8e00 },?
??????????? { 0x0660, 0x0660, 0x0660, 0x0660 } };?
??? int blockType; // 塊的模式號(0-6)?
??? int turnState; // 塊的翻轉狀態(tài)(0-3)?
??? int blockState; // 快的下落狀態(tài)?
??? int row, col; // 塊在畫布上的坐標?
??? GameCanvas scr;?
??? // 塊類的構造方法?
??? Block(GameCanvas scr) {?
??????? this.scr = scr;?
??? ????blockType = (int) (Math.random() * 1000) % 7;?
??????? turnState = (int) (Math.random() * 1000) % 4;?
??????? blockState = 1;?
??????? row = scr.getInitRow();?
??????? col = scr.getInitCol();?
??? }?
??? // 重新初始化塊,并顯示新塊?
??? public void reset() {?
??????? blockType = (int) (Math.random() * 1000) % 7;?
??????? turnState = (int) (Math.random() * 1000) % 4;?
??????? blockState = 1;?
??????? row = scr.getInitRow();?
??????? col = scr.getInitCol();?
??????? dispBlock(1);?
??? }?
??? // 實現(xiàn)“塊”翻轉的方法?
??? public void leftTurn() {?
??????? if (assertValid(blockType, (turnState + 1) % 4, row, col)) {?
??????????? dispBlock(0);?
??????????? turnState = (turnState + 1) % 4;?
??????????? dispBlock(1);?
??????? }?
??? }?
??? // 實現(xiàn)“塊”的左移的方法?
??? public void leftMove() {?
??????? if (assertValid(blockType, turnState, row, col - 1)) {?
??????????? dispBlock(0);?
??????????? col--;?
??????????? dispBlock(1);?
??????? }?
??? }?
??? // 實現(xiàn)塊的右移?
??? public void rightMove() {?
???? ???if (assertValid(blockType, turnState, row, col + 1)) {?
??????????? dispBlock(0);?
??????????? col++;?
??????????? dispBlock(1);?
??????? }?
??? }?
??? // 實現(xiàn)塊落下的操作的方法?
??? public boolean fallDown() {?
??????? if (blockState == 2)?
??????????? return (false);?
??????? if (assertValid(blockType, turnState, row - 1, col)) {?
??????????? dispBlock(0);?
??????????? row--;?
??????????? dispBlock(1);?
??????????? return (true);?
??????? } else {?
??????????? blockState = 2;?
??????????? dispBlock(2);?
??????????? return (false);?
??????? }?
??? }?
??? // 判斷是否正確的方法?
??? boolean assertValid(int t, int s, int row, int col) {?
??????? int k = 0x8000;?
??????? for (int i = 0; i < 4; i++) {?
??????????? for (int j = 0; j < 4; j++) {?
?????? ?????????if ((int) (pattern[t][s] & k) != 0) {?
??????????????????? int temp = scr.getScrArrXY(row - i, col + j);?
??????????????????? if (temp < 0 || temp == 2)?
??????????????????????? return false;?
??????????????? }?
??????????????? k = k >> 1;?
??????????? }?
??????? }?
??????? return true;?
??? }?
??? // 同步顯示的方法?
??? public synchronized void dispBlock(int s) {?
??????? int k = 0x8000;?
??????? for (int i = 0; i < 4; i++) {?
??????????? for (int j = 0; j < 4; j++) {?
??????????????? if (((int) pattern[blockType][turnState] & k) != 0) {?
??????????????????? scr.drawUnit(row - i, col + j, s);?
??????????????? }?
??????????????? k = k >> 1;?
??????????? }?
??????? }?
??? }?
}?
// 定時線程?
class MyTimer extends Thread {?
??? GameCanvas scr;?
??? public MyTimer(GameCanvas scr) {?
??????? this.scr = scr;?
??? }?
??? public void run() {?
??????? while (true) {?
??????????? try {?
??????????????? sleep((10 - ERS_Block.level + 1) * 100);?
??????????? } catch (InterruptedException e) {?
??????????? }?
??????????? if (!scr.getBlock().fallDown()) {?
??????????????? scr.deleteFullLine();?
??????????????? if (scr.isGameEnd()) {?
??????????????????? ERS_Block.isPlay = false;?
??????????????????? suspend();?
??????????????? } else?
??????????????????? scr.getBlock().reset();?
??????????? }?
??????? }?
??? }?
}?
class WinListener extends WindowAdapter {?
??? public void windowClosing(WindowEvent l) {?
??????? System.exit(0);?
??? }?
}
?
?
?
6.實驗感悟
本次實驗,我們沒有進入實驗樓完成,自己在電腦上自主做實驗,在游戲設計的時候并不是一帆風順,有許多問題都咨詢了學長與同學。
在實驗中我們也有查閱網(wǎng)上有關的游戲資料,增長了許多知識與見識,對我的程序設計有很大的幫助。
?
轉載于:https://www.cnblogs.com/yg137565645/p/4567753.html
總結
以上是生活随笔為你收集整理的实验3 --俄罗斯方块 with 20135335郝爽的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 动态属性
- 下一篇: 两个服务之间的调用请求