標籤:c# 圖片 拼圖
與第一篇一樣,同屬簡單Demo,這個在開始做的時候,想的是將PictureBox拖動到另一個PictureBox上,如果PictureBox沒圖片,就將Image傳遞,但想法是簡單的,事實是複雜的:首先PictureBox不支援DragEnter和DragDrop事件,所以後面將圖片的載體換成了Panel;其次圖片全隨機打亂不行,第一行的最後一張圖片是不能隨機的,必須為特定圖片(當然這是因為這個Demo是所有小圖都存在的,其實也可以做成隨機取消一塊圖片的拼圖遊戲,只要在此Demo上做些調整);最後還有如何確認Panel是否允許拖動的問題。遊戲玩法就是在小圖片上按住滑鼠拖動到空白地區(只有臨近空白的幾個方塊允許拖動,只要將源碼中一行代碼取消登出掉,就可以取消掉這個限制),下面是運行時的,同樣弄了個妹子賞眼點
與前一篇Demo相比,現在分割出來的小圖片載體Panel既要接受MouseDown事件,又要接受DragEnter以及DragDrop事件,在MouseDown事件中確認該圖片是否允許拖動,而是否允許拖動的判斷邏輯就是:當前點擊的Panel的Tag是否不為null(這裡用Tag來判斷是否空白地區),並且該Panel的上下左右四塊地區是否有空白地區或為邊界,至於索引如何換算成二維數組位置與第一篇中的規則一樣,下面即為MouseDown事件執行的代碼
private void panel_MouseDown(object sender, MouseEventArgs e) { Panel panel = (Panel)sender; if (panel.Tag != null) { bool allowed; if (panel.Name.Contains('_')) {//非emptyPanel int idx = int.Parse(panel.Name.Split('_')[1]); int x = idx % this.ImgNumbers;//換算成x方向上第幾塊 int y = idx / this.ImgNumbers;//換算成y方向上第幾塊 //只要上下左右四個方向上是否有一個Panel是允許拖動的,就可以拖動 allowed = this.AllowDragDrop(x - 1, y) || this.AllowDragDrop(x + 1, y) || this.AllowDragDrop(x, y - 1) || this.AllowDragDrop(x, y + 1); } else {//emptyPanel只需要判斷第N-1塊是不是為空白 allowed = this._splitPanels[this.SpecialIndex].Tag == null; } //allowed = true;//取消注釋可以任意位置調整拼圖 if (allowed) { this._dragPanel = panel; panel.DoDragDrop(this._dragPanel.Tag, DragDropEffects.Move | DragDropEffects.Copy); } } }對於AllowDragDrop,這裡單獨說明:if判斷該x,y是否能夠擷取到對應Panel,如果擷取不到,則代表已出了臨界範圍,肯定不能拖動;如果能取到Panel,這裡又分兩種情況,一種是第一行額外增加的專用於顯示特定圖片的Panel,還有就是正常分割出來的Panel,如果Panel對應的Tag為null,則代表該Panel為空白地區
/// <summary> /// 判斷特定的panel是否允許拖動 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private bool AllowDragDrop(int x, int y) { bool allowed = true; if (x < 0 || y < 0 || y >= this.ImgNumbers || (x >= this.ImgNumbers && y > 0)) {//不存在panel allowed = false; } else { if (x >= this.ImgNumbers && y == 0) { allowed = this._emptyPanel.Tag == null; } else { allowed = this._splitPanels[x + y * this.ImgNumbers].Tag == null; } } return allowed; }最後的DragDrop事件這裡就不多說了,跟文章開頭說的一樣,直接傳遞Image並修正Tag,同時修正AllowDrop屬性
void panel_DragDrop(object sender, DragEventArgs e) { Panel panel = (Panel)sender; panel.Tag = this._dragPanel.Tag; panel.BackgroundImage = this._splitImages[(int)panel.Tag]; panel.AllowDrop = false; this._dragPanel.Tag = null; this._dragPanel.AllowDrop = true; this._dragPanel.BackgroundImage = null; if (this._emptyPanel.Tag == null && !this._splitPanels.Any((p) => string.Format("pnl_{0}", p.Tag) != p.Name)) {//空Panel不再包含tag,並且Panel對應Tag順序正確 this._emptyPanel.AllowDrop = false; MessageBox.Show("恭喜你,圖片拼好了"); } }源碼下載,在Program.cs裡面Application.Run(new RandomPictureForm2())運行即為此部落格對應Demo
【Demo】拼圖小遊戲 winform (二) 只能在空格地區移動的拼圖