天天看點

Javaworkers團隊第三周項目總結

第十三、十四周:按照項目設計,逐漸完成各個子產品的代碼,初步完成項目雛形。

基礎知識原理

1.TDD(Test Driven Development, 測試驅動開發),TDD的一般步驟如下:

  • 明确目前要完成的功能,記錄成一個測試清單
  • 快速完成編寫針對此功能的測試用例
  • 測試代碼編譯不通過(沒産品代碼呢)
  • 編寫産品代碼
  • 測試通過
  • 對代碼進行重構,并保證測試通過(重構下次實驗練習)
  • 循環完成所有功能的開發

2.測試類具體操作:把滑鼠放到項目名上,單擊右鍵,在彈出的菜單中標明New->Source Folder建立一個測試目錄test;把滑鼠放到test目錄上,單擊右鍵,在彈出的菜單中標明New->JUnit Test Case建立一個測試用例類。

重要函數及其代碼

1.MainClass函數:繼承JFrame類,調用ControlSnake類;定義視窗大小和位置。

package resource;

 

import java.awt.*;

import javax.swing.*;

 

@SuppressWarnings("serial")//注釋處的所有警告都忽視

public class MainClass extends JFrame {

    ControlSnake control;

 

    Toolkit kit;//所有實際應用的抽象視窗工具包的父類

 

    Dimension dimen;//壓縮了有整數精确度的元件

 

    public static void main(String[] args) {

        new MainClass("my snake");

    }

 

    public MainClass(String s) {

        super(s);

        control = new ControlSnake();//新的ControlSnake類

        control.setFocusable(true);

        kit = Toolkit.getDefaultToolkit();

        dimen = kit.getScreenSize();//擷取螢幕尺寸

 

        add(control);//添加control

        setLayout(new BorderLayout());

        setLocation(dimen.width / 3, dimen.height / 3);// 挪位置,dimen.width/3,dimen.height/3

        setSize(FWIDTH, FHEIGHT);//定格操作視窗大小

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setResizable(false);

        setVisible(true);

    }

 

    public static final int FWIDTH = 315;

 

    public static final int FHEIGHT = 380;

}


           

2.ControlSnake函數:繼承JPanel類;定義貪吃蛇的坐标位置和果實坐标位置,定義随機數發生器等;建立主函數接收鍵盤傳入并轉換成keyCode,執行對應操作;建立Paint函數構造視窗;建立Action函數進行動畫示範(包括調用随機數發生函數産生僞随機序列,确定果實位置)

package resource;

 

import java.util.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.Timer;

import java.util.Random;

 

@SuppressWarnings("serial")

public class ControlSnake extends JPanel implements ActionListener {

    //JPanel類用于為小内容提供簡單視窗,ActionListener為對象提供添加動作的方法

    Random rand;

    //Random,用48bit的種子産生僞随機序列

    ArrayList<Point> list, listBody;

    //ArrayList<Point>,類似于二維數組,聲明了兩個泛型對象

    String str, str1;

   

    static boolean key;

   

    int x, y, dx, dy, fx, fy, flag;

 

    int snakeBody;

    //控制蛇的長度

    int speed;

 

    public ControlSnake()

    {

        snakeBody = 1;

 

        str = "上下左右方向鍵控制 P鍵暫停...";

        str1 = "現在的長度為:" + snakeBody;

        key = true;

        flag = 1;

 

        speed = 700;

        rand = new Random();//創造一個新的随機數産生器

        list = new ArrayList<Point>();//創造一個初始容量為10的數列

        listBody = new ArrayList<Point>();

 

        x = 5;

        y = 5;

        list.add(new Point(x, y));//在坐标空間中建立并初始化一個新的點

        listBody.add(list.get(0));//list.get(0),傳回在list列中0位置的元素

 

        dx = 10;

        dy = 0;

 

        fx = rand.nextInt(30) * 10 + 5;// rand.nextInt(30),傳回一個在0——30内的随機數

        fy = rand.nextInt(30) * 10 + 5;// 2

 

        setBackground(Color.WHITE);//為視窗添加背景色

        setSize(new Dimension(318, 380));//重新定義視窗的高和寬

 

        final Timer time = new Timer(speed, this);

        time.start();

        //timer類,在指定時間間隔觸發一個或多個 ActionEvent

        addKeyListener(new KeyAdapter()

        {

        //KeyAdapter(),用于接收鍵盤傳來的事件的抽象類

            public void keyPressed(KeyEvent e)

            {

                //KeyEvent,使鍵盤輸入轉化成對應對象

                if (e.getKeyCode() == 37) {//getKeyCode(),将鍵盤輸入轉化成對應的整形鍵碼

                    dx = -10;

                    dy = 0;

                } else if (e.getKeyCode() == 38) {

                    dx = 0;

                    dy = -10;

                } else if (e.getKeyCode() == 39) {

                    dx = 10;

                    dy = 0;

                } else if (e.getKeyCode() == 40) {

                    dx = 0;

                    dy = 10;

                } else if (e.getKeyCode() == 80) {

                    if (flag % 2 == 1) {

                        time.stop();

                    }

                    if (flag % 2 == 0) {

                        time.start();

                    }

                    flag++;

                }

            }

        });

 

    }

 

    public void paint(Graphics g) {//Graphics,所有環境算法基礎類,允許應用在已有元件上進行繪制

        g.setColor(Color.WHITE);

        g.fillRect(0, 0, 400, 400);//指定一個以setColor傳回值為底色的長方形,具體參數為x,y

        g.setColor(Color.DARK_GRAY);

        g.drawLine(3, 3, 305, 3);//在點(3,3)和(305,3)之間用目前色填充一條線

        g.drawLine(3, 3, 3, 305);

        g.drawLine(305, 3, 305, 305);

        g.drawLine(3, 305, 305, 305);

        g.setColor(Color.PINK);

 

        for (int i = 0; i < listBody.size(); i++) {//listBody.size(),傳回目前list的元素個數

            g.fillRect(listBody.get(i).x, listBody.get(i).y, 9, 9);

        }//控制蛇的長度

        g.fillRect(x, y, 9, 9);//蛇的長度最大為9

        g.setColor(Color.ORANGE);

        g.fillRect(fx, fy, 9, 9);//随機顯示果實

 

        g.setColor(Color.DARK_GRAY);

        str1 = "現在的長度為:" + snakeBody;

        g.drawString(str, 10, 320);//在圖形化界面中顯示字元串

        g.drawString(str1, 10, 335);

    }

 

    public void actionPerformed(ActionEvent e) {

        x += dx;

        y += dy;

        if (makeOut() == false) {//見最後的函數,用于排除超出圖形界面的不合法輸出

            JOptionPane.showMessageDialog(null, "重新開始......");

            //跳出對話框,顯示“重新開始”

            speed = 700;

 

            snakeBody = 1;

 

            x = 5;

            y = 5;

 

            list.clear();//清空數列

            list.add(new Point(x, y));//加入新元素

            listBody.clear();

            listBody.add(list.get(0));

 

            dx = 10;

            dy = 0;

 

        }

        addPoint(x, y);

        if (x == fx && y == fy) {//即“蛇吃到果實”

            speed = (int) (speed * 0.8);// 速度增加參數

            if (speed < 200) {

                speed = 100;

            }

            fx = rand.nextInt(30) * 10 + 5;// 2

            fy = rand.nextInt(30) * 10 + 5;// 2

            snakeBody++;// 2

        } // 2

        repaint();//重新進行

    }

 

    public void addPoint(int xx, int yy) {

        // 動态的記錄最新發生的50步以内的移動過的坐标

        // 并畫出最新的snakeBody

        if (list.size() < 100) {// 蛇身長度最長為100

            list.add(new Point(xx, yy));

        } else {

            list.remove(0);

            list.add(new Point(xx, yy));

        }

        if (snakeBody == 1) {

            listBody.remove(0);

            listBody.add(0, list.get(list.size() - 1));

        } else {

            listBody.clear();

            if (list.size() < snakeBody) {

                for (int i = list.size() - 1; i > 0; i--) {

                    listBody.add(list.get(i));

                }

            } else {

                for (int i = list.size() - 1; listBody.size() < snakeBody; i--) {

                    listBody.add(list.get(i));

                }

            }

        }

    }

 

    public boolean makeOut() {

        if ((x < 3 || y < 3) || (x > 305 || y > 305)) {

            return false;

        }

        for (int i = 0; i < listBody.size() - 1; i++) {

            for (int j = i + 1; j < listBody.size(); j++) {

                if (listBody.get(i).equals(listBody.get(j))) {

                    return false;

                }

            }

        }

        return true;

    }

}


           

總結

本周按照項目設計,逐漸完成各個子產品的代碼,初步完成項目雛形。但沒有完全編寫成功,在下一周還要繼續努力。