本帖最後由 csharp 於 2021-7-1 18:01 編輯
只用程式碼,不拉元件。
拉圖片靠近任一格線時會自動吸上去貼齊,並發出碰撞的音效。
全對時會有音效出現。
按左邊的大圖可立即從頭開始。
直接用resources的圖檔自動編入陣列。
只要把相關的圖檔和音效檔放入資源中,可以copy以下所有code貼上去就可以完成這個遊戲程式。
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Media;
- namespace puzzle_game_2_20210630
- {
- public partial class Form1 : Form
- {
- Label[] table = new Label[12];//用label來畫格線
- PictureBox[] pb = new PictureBox[12];//主要的picturebox陣列,用來移動
- //以下四個picturebox陣列用來容納不同圖片之用,本身不先賦予location
- PictureBox[] pb1 = new PictureBox[12];
- PictureBox[] pb2 = new PictureBox[12];
- PictureBox[] pb3 = new PictureBox[12];
- PictureBox[] pb4 = new PictureBox[12];
- PictureBox[] pbIcon = new PictureBox[4];//放四個用來點擊選取的大圖案陣列
-
- static int oldX, oldY;//滑鼠移動時的前一個xy座標
- static int choosePb;//判定是選了哪一個主要圖案,攸關往後一切的比對動作
- bool isDown;//判斷移動圖片時滑鼠是否按下的狀態
- SoundPlayer correct = new SoundPlayer(Properties.Resources.correct);//全部符合時的勝利音效
- SoundPlayer touch = new SoundPlayer(Properties.Resources.quick000);//圖片貼齊格線時的音效
- public Form1()
- {
- InitializeComponent();
- setIcon();//設定大圖案
- setPicturebox();//設定所有圖案列
- setTable();//設定格線
-
-
- }
- //設立全部圖格陣列
- void setPicturebox()
- {
- for (int i = 0; i < 12; i++)
- {
- //先將物件陣列實體化
- pb[i] = new PictureBox();
- pb1[i] = new PictureBox();
- pb2[i] = new PictureBox();
- pb3[i] = new PictureBox();
- pb4[i] = new PictureBox();
- //將各圖檔尺寸定出來
- pb[i].Size = new Size(100, 100);
- pb1[i].Size = new Size(100, 100);
- pb2[i].Size = new Size(100, 100);
- pb3[i].Size = new Size(100, 100);
- pb4[i].Size = new Size(100, 100);
- //除掉主要的陣列之外,將其它陣列給予圖片
- pb1[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("a" + i);
- pb2[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("b" + i);
- pb3[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("c" + i);
- pb4[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("d" + i);
- //將主要圖檔陣列賦予位置
- pb[i].Location = new System.Drawing.Point(30 + i % 6 * 110, 325 + i / 6 * 103);
-
- pb[i].Enabled = false;//防止一開始沒有圖片時不小心被滑鼠移動而誤判已全部符合
- Controls.Add(pb[i]);
- //設定主要圖檔的滑鼠控制事件
- pb[i].MouseDown += new MouseEventHandler(pb_mousedown);
- pb[i].MouseMove += new MouseEventHandler(pb_mousemove);
- pb[i].MouseUp += new MouseEventHandler(pb_mouseup);
- }
- }
- //設定三個mouse事件內容
- void pb_mousedown(object sender, MouseEventArgs e)
- {
- isDown = true;
- oldX = e.X;
- oldY = e.Y;
- }
- void pb_mousemove(object sender, MouseEventArgs e)
- {
- PictureBox pb = (PictureBox)sender;
- if (isDown)
- {
- pb.Left += e.X - oldX;
- pb.Top += e.Y - oldY;
- pb.BringToFront();//將目前移動的圖片調到視窗最前面
- }
- }
- void pb_mouseup(object sender, MouseEventArgs e)
- {
- isDown = false;
- closeToBorder(sender, table);//一旦圖片接近格線時自動會貼齊格線,並發出音效
- whichPbtogo();//
-
- if (allmatch())
- {
- for (int i = 0; i < 12; i++)
- {
- pb[i].Enabled = false;////如果所有圖片位置都符合要求立即凍結格線內所有圖片
- }
- correct.Play(); //如果所有圖片位置都符合要求則出現勝利音效
- }
- }
- //三個滑鼠事件結束
- //自動對齊格線
- void closeToBorder(object sender, Label[] lbl)
- {
- PictureBox p = (PictureBox)sender;
- for (int i = 0; i < 12; i++)
- {
- if (Math.Abs(p.Left - lbl[i].Left) < 30 && Math.Abs(p.Top - lbl[i].Top) < 30)
- {
- p.Left = lbl[i].Left;
- p.Top = lbl[i].Top;
- touch.Play();//貼齊格線的音效
- }
- }
- }
-
- //畫格線
- void setTable()
- {
- for (int i = 0; i< 12; i++)
- {
- table[i] = new Label();
- table[i].Size = new Size(100, 100);
- table[i].BorderStyle = BorderStyle.FixedSingle;
-
- table[i].Location = new System.Drawing.Point(100 + i % 4 * 100, 10 + i / 4 * 100);
-
- Controls.Add(table[i]);
- }
- }
- //<----有關icon的設定以及選擇------->
- //設定四個icon
- void setIcon()
- {
- for (int i = 0; i < 4; i++)
- {
- pbIcon[i] = new PictureBox();
- pbIcon[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" +i);
- pbIcon[i].Size = new Size(120, 90);
- pbIcon[i].SizeMode = PictureBoxSizeMode.StretchImage;
- pbIcon[i].Location = new System.Drawing.Point(50+Width / 5 * 4, 20 + i * 110 + 10);
- Controls.Add(pbIcon[i]);
- pbIcon[i].Click += new System.EventHandler(pb_click);//大圖片icon的點擊事件
- }
- }
- //設定icon選擇事件
- void pb_click(object sender, EventArgs e)
- {
- PictureBox p = (PictureBox)sender;
- pbRestart();
- if (p == pbIcon[0])
- {
- choosePb = 1;
- randomPb(pb, pb1);
- }
- else if (p == pbIcon[1])
- {
- choosePb = 1;
- randomPb(pb, pb2);
- }
- else if (p == pbIcon[2])
- {
- choosePb = 1;
- randomPb(pb, pb3);
- }
- else if (p == pbIcon[3])
- {
- choosePb = 1;
- randomPb(pb, pb4);
- }
- }
- //<----有關icon的設定以及選擇結束------->
- //亂數方法
- int[] ary = new int[12];
- void randomPickNoRepeat(int[] a)
- {
- Random rnd = new Random();
- for (int i = 0; i < a.Length; i++)
- {
- a[i] = rnd.Next(a.Length);
- for (int j = 0; j < i; j++)
- if (a[j] == a[i])
- {
- i--;
- break;
- }
- }
- }
- //設定主圖陣列的亂排方法
- void randomPb(PictureBox[] pb, PictureBox[] p1)
- {
- randomPickNoRepeat(ary);
- for (int i = 0; i < 12; i++)
- {
- pb[i].Image = p1[ary[i]].Image;
- }
- }
- //亂排結束
- //看用哪個圖陣列去比較,最重要的一個方法
- void whichPbtogo()
- {
- if (choosePb == 1)
- for (int i = 0; i < 12; i++)
- {
- pb1[ary[i]].Location = pb[i].Location;//這個位置賦值是最重要的一個步驟。將被選擇的那個圖片陣列的位置對應到主陣列,才能最後去和格線坐標來比對。在randomPb()時,pb1[ary[i]]的image是給了pb[i],因此此時就要倒過來把pb[i]的location給pb1[ary[i]]。//
- }
- if (choosePb == 2)
- for (int i = 0; i < 12; i++)
- {
- pb2[ary[i]].Location = pb[i].Location;
- }
- if (choosePb == 3)
- for (int i = 0; i < 12; i++)
- {
- pb3[ary[i]].Location = pb[i].Location;
- }
- if (choosePb == 4)
- for (int i = 0; i < 12; i++)
- {
- pb4[ary[i]].Location = pb[i].Location;
- }
- }
- ///////
- //設定檢查是否全部符合圖片位置的方法
- bool allmatch()
- {
- if (choosePb == 1)//表示此時是用第一陣列的圖
- for (int i = 0; i < 12; i++)
- {
- if (pb1[i].Location != table[i].Location)//一開始要將圖片依順序對應數字放入陣列,如此才能剛好用picturebox[]的順序比對label[]的順序,來判定是否所有的圖片都在它應該在的格子內//
- return false;
- }
- else if (choosePb == 2)
- for (int i = 0; i < 12; i++)
- {
- if (pb2[i].Location != table[i].Location)
- return false;
- }
- else if (choosePb == 3)
- for (int i = 0; i < 12; i++)
- {
- if (pb3[i].Location != table[i].Location)
- return false;
- }
- else if (choosePb == 4)
- for (int i = 0; i < 12; i++)
- {
- if (pb4[i].Location != table[i].Location)
- return false;
- }
- return true;
- }
- //////
- //重新開始方法
- void pbRestart()
- {
- for (int i = 0; i < 12; i++)
- {
- pb[i].Enabled = true;//因為勝利後會凍結主陣列
- pb[i].Location = new System.Drawing.Point(30 + i % 6 * 110, 325 + i / 6 * 103);//再讓主陣列回到原本的位置
- }
- }
-
- }
- }
複製代碼
|