csharp 發表於 2021-6-25 19:52:46

只用程式碼寫的拼圖

本帖最後由 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;//用label來畫格線

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

      PictureBox[] pbIcon = new PictureBox;//放四個用來點擊選取的大圖案陣列
      
      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 = new PictureBox();

                pb1 = new PictureBox();
                pb2 = new PictureBox();
                pb3 = new PictureBox();
                pb4 = new PictureBox();

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

                pb1.Size = new Size(100, 100);
                pb2.Size = new Size(100, 100);
                pb3.Size = new Size(100, 100);
                pb4.Size = new Size(100, 100);

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

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

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

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

                //將主要圖檔陣列賦予位置
                pb.Location = new System.Drawing.Point(30 + i % 6 * 110, 325 + i / 6 * 103);
               
                                pb.Enabled = false;//防止一開始沒有圖片時不小心被滑鼠移動而誤判已全部符合
                Controls.Add(pb);
                //設定主要圖檔的滑鼠控制事件
                pb.MouseDown += new MouseEventHandler(pb_mousedown);
                pb.MouseMove += new MouseEventHandler(pb_mousemove);
                pb.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.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.Left) < 30 && Math.Abs(p.Top - lbl.Top) < 30)
                {
                  p.Left = lbl.Left;
                  p.Top = lbl.Top;
                  touch.Play();//貼齊格線的音效
                }
            }
      }

      
      //畫格線
      void setTable()
      {
            for (int i = 0; i< 12; i++)
            {
                table = new Label();
                table.Size = new Size(100, 100);
                table.BorderStyle = BorderStyle.FixedSingle;
               
                table.Location = new System.Drawing.Point(100 + i % 4 * 100, 10 + i / 4 * 100);
               
                Controls.Add(table);
            }
      }
      //<----有關icon的設定以及選擇------->
      //設定四個icon
      void setIcon()
      {
            for (int i = 0; i < 4; i++)
            {
                pbIcon = new PictureBox();
                pbIcon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" +i);
                pbIcon.Size = new Size(120, 90);
                pbIcon.SizeMode = PictureBoxSizeMode.StretchImage;
                pbIcon.Location = new System.Drawing.Point(50+Width / 5 * 4, 20 + i * 110 + 10);
                Controls.Add(pbIcon);

                pbIcon.Click += new System.EventHandler(pb_click);//大圖片icon的點擊事件
            }
      }

      //設定icon選擇事件
      void pb_click(object sender, EventArgs e)
      {
            PictureBox p = (PictureBox)sender;
            pbRestart();
            if (p == pbIcon)
            {
                choosePb = 1;
                randomPb(pb, pb1);
            }
            else if (p == pbIcon)
            {
                choosePb = 1;
                randomPb(pb, pb2);
            }
            else if (p == pbIcon)
            {
                choosePb = 1;
                randomPb(pb, pb3);
            }
            else if (p == pbIcon)
            {
                choosePb = 1;
                randomPb(pb, pb4);
            }
      }
      //<----有關icon的設定以及選擇結束------->


      //亂數方法
      int[] ary = new int;
      void randomPickNoRepeat(int[] a)
      {
            Random rnd = new Random();
            for (int i = 0; i < a.Length; i++)
            {
                a = rnd.Next(a.Length);

                for (int j = 0; j < i; j++)
                  if (a == a)
                  {
                        i--;
                        break;
                  }
            }
      }




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

            randomPickNoRepeat(ary);

            for (int i = 0; i < 12; i++)
            {
                pb.Image = p1].Image;

            }
      }
      //亂排結束


      //看用哪個圖陣列去比較,最重要的一個方法
      void whichPbtogo()
      {
         if (choosePb == 1)
            for (int i = 0; i < 12; i++)
                {
                  pb1].Location = pb.Location;//這個位置賦值是最重要的一個步驟。將被選擇的那個圖片陣列的位置對應到主陣列,才能最後去和格線坐標來比對。在randomPb()時,pb1]的image是給了pb,因此此時就要倒過來把pb的location給pb1]。//
                }
         if (choosePb == 2)
                for (int i = 0; i < 12; i++)
                {
                  pb2].Location = pb.Location;
                }
         if (choosePb == 3)
                for (int i = 0; i < 12; i++)
                {
                  pb3].Location = pb.Location;
                }
         if (choosePb == 4)
                for (int i = 0; i < 12; i++)
                {
                  pb4].Location = pb.Location;
                }

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

                }
         elseif (choosePb == 2)
                for (int i = 0; i < 12; i++)
                {
                  if (pb2.Location != table.Location)
                        return false;

                }
            else if (choosePb == 3)
                for (int i = 0; i < 12; i++)
                {
                  if (pb3.Location != table.Location)
                        return false;

                }
            else if (choosePb == 4)
                for (int i = 0; i < 12; i++)
                {
                  if (pb4.Location != table.Location)
                        return false;

                }

            return true;
      }


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

      

    }
}


頁: [1]
查看完整版本: 只用程式碼寫的拼圖