項目需求:
使用者可通過目錄,選定要進行拼圖的照片,照片經過處理後,被分割為3*3的小塊;
將其中的小塊放置到3*3的框中,其中的最右下角留白;
按上下左右方向鍵,移動方框中的照片小塊,直到拼接出原始的映像,遊戲結束;
已有資料:
http://blog.sina.com.cn/s/blog_5e3ab00c0100igqh.html
http://blog.sina.com.cn/s/blog_5e3ab00c0100ipz6.html
參考上述的原始碼來完成自己的設計。
任務表:
完成對話方塊定位目錄的功能(優先順序低);
對定位到的圖片進行標準化,分割處理(優先順序高);
將分割後的圖片貼在圖文框中(優先順序高);
添加對鍵盤的監聽,重繪映像,形成移動的效果;每移動一次判斷是否完成拼圖(優先順序高);
如何判斷當前初始的拼圖是否可拼。(優先順序高)
任務2:
需要將圖片進行分割,參考的原始碼目錄如下:
按照代碼的名字,我們可以到Split中去看看是否有我們需要的內容,發現該類中的divid方法,正好完成對圖片的分割工作,該部分代碼可以拿來用。
public BufferedImage[][] divid(int type)
{
try
{
if(filename == null)
return null;
BufferedImage image = ImageIO.read(new File(path));
int len = level[type];
int cal = image.getWidth() / len;
int row = image.getHeight() / len;
BufferedImage [][] subimage = new BufferedImage[row][cal];
for (int i = 0; i < row; i++)
for (int j = 0; j < cal; j++)
subimage[i][j] = image.getSubimage(j*len, i*len, len, len);
return subimage;
}
catch (Exception e)
{
return null;
}
}
}
任務3:將分割後的圖片貼在圖文框中(優先順序高);
此處是要對分割後的image進行處理,暫時我們跟著參考原始碼看看,他是怎麼做的:
public void menuNewClick()
{
Split sp = Split.get();
BufferedImage [][] image;
if(!sp.set(getFilename()) || (image = sp.divid(getType())) == null)
{
JOptionPane.showMessageDialog(null, "File"+getFilename()+" not exists!\nPlease select again~");
return;
}
startGame();
this.setSize(fWidth, fHeight);
this.setVisible(true);
intlen = Split.level[getType()];
introw = image.length;
intcal = image[0].length;
gOver = new GameOver(this);
JButton [][] button = new JButton[row][cal];
Matrix matrix = new Matrix(button, panel[0], len, gOver);
matrix.init(image);
從上述的代碼可見,對於image分割方法的調用在image = sp.divid(getType())),而對於image的進一步處理就落在matrix部分的init方法中。
public void init(BufferedImage [][] image)
{
…
icon = new ImageIcon(image[d/cal][d%cal]);
button[i/cal][i%cal].setIcon(icon);
}
}
從上述的代碼可見,其主要的思路:將分割得到的image轉化成為icon對象,然後再將icon對象設定給button;而在matrix的初始化函數中:
public Matrix(JButton [][] b, JPanel p, intlen, GameOver g){
…
for(int i = 0; i < row; i++)
for (int j = 0; j < cal; j++)
{
button[i][j] = new JButton();
button[i][j].setBounds(j*len, i*len, len, len);
button[i][j].addActionListener(new ButtonClick(button, pint, matrix, i,j, gOver));
panel.add(button[i][j]);
}
}
}
上述的代碼給我們的設計指出大方向:將整個的panel劃分為3*3的地區,其中的依次無縫隙放置9個按鈕;然後再將我們的圖片分割為3*3的小塊,再將每個小塊轉化為icon類型貼在每個按鈕的表面,如此完成遊戲的靜態設定。
任務4:添加對鍵盤的監聽,重繪映像,形成移動的效果;每移動一次判斷是否完成拼圖(優先順序高);
本任務總體可分解得子任務:
如何產生移動的效果。
如何判斷拼圖是否完成。
按照任務3中的總體設計,實現移動的效果:要麼移動按鈕在panel中的位置,要麼重設按鈕上的icon;上述只是粗略的技術路線,還需要具體到:
每條路線的具體實現難度;
該技術路線與後續任務協同上的難易程度;
啟發:技術路線的除了考慮自身的難易程度,還需要考慮與其他技術的協同難度;
先不想動手。那就在腦子裡跑火車,看看上述兩條技術路線的技術難度:
如果採用重設icon的方式,那就是每次沿著按鍵方向,將前者的icon置為空白的即可;而判斷是否已經處於拼圖完成狀態,只需要檢查每個按鈕上的icon是否按順序排列;
如果採用移動按鈕的方式,只不過是帶著icon一起移動而已,因為我們要的只是icon的移動,所以兩者方式的對比,更合理的是第一種方式。