code.club

標題: 只用程式碼寫的拼圖 [打印本頁]

作者: csharp    時間: 2021-6-25 19:52
標題: 只用程式碼寫的拼圖
本帖最後由 csharp 於 2021-7-1 18:01 編輯

只用程式碼,不拉元件。
拉圖片靠近任一格線時會自動吸上去貼齊,並發出碰撞的音效。
全對時會有音效出現。
按左邊的大圖可立即從頭開始。
直接用resources的圖檔自動編入陣列。
只要把相關的圖檔和音效檔放入資源中,可以copy以下所有code貼上去就可以完成這個遊戲程式。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Media;

  11. namespace puzzle_game_2_20210630
  12. {
  13.     public partial class Form1 : Form
  14.     {

  15.         Label[] table = new Label[12];//用label來畫格線

  16.         PictureBox[] pb = new PictureBox[12];//主要的picturebox陣列,用來移動
  17.                 //以下四個picturebox陣列用來容納不同圖片之用,本身不先賦予location
  18.         PictureBox[] pb1 = new PictureBox[12];
  19.         PictureBox[] pb2 = new PictureBox[12];
  20.         PictureBox[] pb3 = new PictureBox[12];
  21.         PictureBox[] pb4 = new PictureBox[12];

  22.         PictureBox[] pbIcon = new PictureBox[4];//放四個用來點擊選取的大圖案陣列
  23.         
  24.         static int oldX, oldY;//滑鼠移動時的前一個xy座標
  25.                 static int choosePb;//判定是選了哪一個主要圖案,攸關往後一切的比對動作
  26.         bool isDown;//判斷移動圖片時滑鼠是否按下的狀態
  27.         SoundPlayer correct = new SoundPlayer(Properties.Resources.correct);//全部符合時的勝利音效
  28.         SoundPlayer touch = new SoundPlayer(Properties.Resources.quick000);//圖片貼齊格線時的音效



  29.         public Form1()
  30.         {
  31.             InitializeComponent();
  32.             setIcon();//設定大圖案
  33.             setPicturebox();//設定所有圖案列
  34.             setTable();//設定格線
  35.             
  36.             
  37.         }

  38. //設立全部圖格陣列
  39.         void setPicturebox()
  40.         {
  41.             for (int i = 0; i < 12; i++)
  42.             {
  43.                 //先將物件陣列實體化
  44.                 pb[i] = new PictureBox();

  45.                 pb1[i] = new PictureBox();
  46.                 pb2[i] = new PictureBox();
  47.                 pb3[i] = new PictureBox();
  48.                 pb4[i] = new PictureBox();

  49.                 //將各圖檔尺寸定出來
  50.                 pb[i].Size = new Size(100, 100);

  51.                 pb1[i].Size = new Size(100, 100);
  52.                 pb2[i].Size = new Size(100, 100);
  53.                 pb3[i].Size = new Size(100, 100);
  54.                 pb4[i].Size = new Size(100, 100);

  55.                 //除掉主要的陣列之外,將其它陣列給予圖片
  56.                 pb1[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("a" + i);

  57.                 pb2[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("b" + i);

  58.                 pb3[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("c" + i);

  59.                 pb4[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("d" + i);

  60.                 //將主要圖檔陣列賦予位置
  61.                 pb[i].Location = new System.Drawing.Point(30 + i % 6 * 110, 325 + i / 6 * 103);
  62.                
  63.                                 pb[i].Enabled = false;//防止一開始沒有圖片時不小心被滑鼠移動而誤判已全部符合
  64.                 Controls.Add(pb[i]);
  65.                 //設定主要圖檔的滑鼠控制事件
  66.                 pb[i].MouseDown += new MouseEventHandler(pb_mousedown);
  67.                 pb[i].MouseMove += new MouseEventHandler(pb_mousemove);
  68.                 pb[i].MouseUp += new MouseEventHandler(pb_mouseup);

  69.             }
  70.         }

  71.         //設定三個mouse事件內容
  72.         void pb_mousedown(object sender, MouseEventArgs e)
  73.         {
  74.             isDown = true;
  75.             oldX = e.X;
  76.             oldY = e.Y;
  77.         }

  78.         void pb_mousemove(object sender, MouseEventArgs e)
  79.         {
  80.             PictureBox pb = (PictureBox)sender;
  81.             if (isDown)
  82.             {
  83.                 pb.Left += e.X - oldX;
  84.                 pb.Top += e.Y - oldY;
  85.                 pb.BringToFront();//將目前移動的圖片調到視窗最前面
  86.             }
  87.         }

  88.         void pb_mouseup(object sender, MouseEventArgs e)
  89.         {
  90.             isDown = false;

  91.             closeToBorder(sender, table);//一旦圖片接近格線時自動會貼齊格線,並發出音效
  92.             whichPbtogo();//
  93.                          
  94.             if (allmatch())
  95.             {
  96.                 for (int i = 0; i < 12; i++)
  97.                 {
  98.                     pb[i].Enabled = false;////如果所有圖片位置都符合要求立即凍結格線內所有圖片
  99.                 }
  100.                 correct.Play(); //如果所有圖片位置都符合要求則出現勝利音效
  101.             }

  102.         }
  103.         //三個滑鼠事件結束



  104.         //自動對齊格線
  105.         void closeToBorder(object sender, Label[] lbl)
  106.         {
  107.             PictureBox p = (PictureBox)sender;
  108.             for (int i = 0; i < 12; i++)
  109.             {
  110.                 if (Math.Abs(p.Left - lbl[i].Left) < 30 && Math.Abs(p.Top - lbl[i].Top) < 30)
  111.                 {
  112.                     p.Left = lbl[i].Left;
  113.                     p.Top = lbl[i].Top;
  114.                     touch.Play();//貼齊格線的音效
  115.                 }
  116.             }
  117.         }

  118.       
  119.         //畫格線
  120.         void setTable()
  121.         {
  122.             for (int i = 0; i< 12; i++)
  123.             {
  124.                 table[i] = new Label();
  125.                 table[i].Size = new Size(100, 100);
  126.                 table[i].BorderStyle = BorderStyle.FixedSingle;
  127.                
  128.                 table[i].Location = new System.Drawing.Point(100 + i % 4 * 100, 10 + i / 4 * 100);
  129.                
  130.                 Controls.Add(table[i]);
  131.             }
  132.         }
  133.         //<----有關icon的設定以及選擇------->
  134.         //設定四個icon
  135.         void setIcon()
  136.         {
  137.             for (int i = 0; i < 4; i++)
  138.             {
  139.                 pbIcon[i] = new PictureBox();
  140.                 pbIcon[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" +i);
  141.                 pbIcon[i].Size = new Size(120, 90);
  142.                 pbIcon[i].SizeMode = PictureBoxSizeMode.StretchImage;
  143.                 pbIcon[i].Location = new System.Drawing.Point(50+Width / 5 * 4, 20 + i * 110 + 10);
  144.                 Controls.Add(pbIcon[i]);

  145.                 pbIcon[i].Click += new System.EventHandler(pb_click);//大圖片icon的點擊事件
  146.             }
  147.         }

  148.         //設定icon選擇事件
  149.         void pb_click(object sender, EventArgs e)
  150.         {
  151.             PictureBox p = (PictureBox)sender;
  152.             pbRestart();
  153.             if (p == pbIcon[0])
  154.             {
  155.                 choosePb = 1;
  156.                 randomPb(pb, pb1);
  157.             }
  158.             else if (p == pbIcon[1])
  159.             {
  160.                 choosePb = 1;
  161.                 randomPb(pb, pb2);
  162.             }
  163.             else if (p == pbIcon[2])
  164.             {
  165.                 choosePb = 1;
  166.                 randomPb(pb, pb3);
  167.             }
  168.             else if (p == pbIcon[3])
  169.             {
  170.                 choosePb = 1;
  171.                 randomPb(pb, pb4);
  172.             }
  173.         }
  174.         //<----有關icon的設定以及選擇結束------->


  175.         //亂數方法
  176.         int[] ary = new int[12];
  177.         void randomPickNoRepeat(int[] a)
  178.         {
  179.             Random rnd = new Random();
  180.             for (int i = 0; i < a.Length; i++)
  181.             {
  182.                 a[i] = rnd.Next(a.Length);

  183.                 for (int j = 0; j < i; j++)
  184.                     if (a[j] == a[i])
  185.                     {
  186.                         i--;
  187.                         break;
  188.                     }
  189.             }
  190.         }




  191.         //設定主圖陣列的亂排方法
  192.         void randomPb(PictureBox[] pb, PictureBox[] p1)
  193.         {

  194.             randomPickNoRepeat(ary);

  195.             for (int i = 0; i < 12; i++)
  196.             {
  197.                 pb[i].Image = p1[ary[i]].Image;

  198.             }
  199.         }
  200.         //亂排結束


  201.         //看用哪個圖陣列去比較,最重要的一個方法
  202.         void whichPbtogo()
  203.         {
  204.            if (choosePb == 1)
  205.               for (int i = 0; i < 12; i++)
  206.                 {
  207.                     pb1[ary[i]].Location = pb[i].Location;//這個位置賦值是最重要的一個步驟。將被選擇的那個圖片陣列的位置對應到主陣列,才能最後去和格線坐標來比對。在randomPb()時,pb1[ary[i]]的image是給了pb[i],因此此時就要倒過來把pb[i]的location給pb1[ary[i]]。//
  208.                 }
  209.            if (choosePb == 2)
  210.                 for (int i = 0; i < 12; i++)
  211.                 {
  212.                     pb2[ary[i]].Location = pb[i].Location;
  213.                 }
  214.            if (choosePb == 3)
  215.                 for (int i = 0; i < 12; i++)
  216.                 {
  217.                     pb3[ary[i]].Location = pb[i].Location;
  218.                 }
  219.            if (choosePb == 4)
  220.                 for (int i = 0; i < 12; i++)
  221.                 {
  222.                     pb4[ary[i]].Location = pb[i].Location;
  223.                 }

  224.         }
  225.         ///////
  226.         //設定檢查是否全部符合圖片位置的方法
  227.         bool allmatch()
  228.         {
  229.             if (choosePb == 1)//表示此時是用第一陣列的圖
  230.                 for (int i = 0; i < 12; i++)
  231.                 {
  232.                     if (pb1[i].Location != table[i].Location)//一開始要將圖片依順序對應數字放入陣列,如此才能剛好用picturebox[]的順序比對label[]的順序,來判定是否所有的圖片都在它應該在的格子內//
  233.                         return false;

  234.                 }
  235.            else  if (choosePb == 2)
  236.                 for (int i = 0; i < 12; i++)
  237.                 {
  238.                     if (pb2[i].Location != table[i].Location)
  239.                         return false;

  240.                 }
  241.             else if (choosePb == 3)
  242.                 for (int i = 0; i < 12; i++)
  243.                 {
  244.                     if (pb3[i].Location != table[i].Location)
  245.                         return false;

  246.                 }
  247.             else if (choosePb == 4)
  248.                 for (int i = 0; i < 12; i++)
  249.                 {
  250.                     if (pb4[i].Location != table[i].Location)
  251.                         return false;

  252.                 }

  253.             return true;
  254.         }


  255.         //////
  256.         //重新開始方法
  257.         void pbRestart()
  258.         {
  259.             for (int i = 0; i < 12; i++)
  260.             {
  261.                 pb[i].Enabled = true;//因為勝利後會凍結主陣列
  262.                 pb[i].Location = new System.Drawing.Point(30 + i % 6 * 110, 325 + i / 6 * 103);//再讓主陣列回到原本的位置
  263.             }
  264.         }

  265.       

  266.     }
  267. }

複製代碼






歡迎光臨 code.club (https://code.club/) Powered by Discuz! X3.2