csharp 發表於 2021-11-28 11:14:13

多選翻翻樂memory match game

本帖最後由 csharp 於 2021-12-27 13:03 編輯

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 memory_match_game
{
    //This program is made by Sun Ying-Chi 2021/07/30
    public partial class Form1 : Form
    {
      Rectangle currentScreen = Screen.PrimaryScreen.WorkingArea;//得出所使用螢幕之長寬值
      PictureBox play = new PictureBox();
      //底下有static的變數都是為了讓Form2能直接使用的
      public static PictureBox[] pNumberChoiceShow = new PictureBox;
      PictureBox[] pNumberChoice = new PictureBox;
      public static PictureBox[] pNumberChoiceGo = new PictureBox;
      PictureBox[] pImg = new PictureBox;
      PictureBox mySound = new PictureBox();
      public static bool soundON = true;
      public static PictureBox[] pThemeShow = new PictureBox;
      PictureBox[] pThemeChoice = new PictureBox;
      public static PictureBox[] pThemeChoiceGo = new PictureBox;
      public static bool hasClicked2;
      public static bool hasClicked1;
      public static int pChoiceNumber;
      public static int pThemeNumber;
      int w, h;
      public Form1()
      {
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form_FormClosing);
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
            f1AllSetting();
      }

      void Form_FormClosing(object sender, FormClosingEventArgs e)
      {
            Application.Exit();
      }

      void f1AllSetting()
      {
            w = currentScreen.Width / 12;//寬度是目前螢幕的十二分之一
            h = currentScreen.Width / 12;
            this.BackgroundImage = Properties.Resources.form_bg_12;
            this.BackgroundImageLayout = ImageLayout.Stretch;
            //從Form2傳過來的值,以免轉回來時這裡的sound圖案不同步
            if (soundON)
            {
                mySound.Image = Properties.Resources.sound_on;
            }
            else
            {
                mySound.Image = Properties.Resources.sound_off;
            }

            soundON = true;//預設都是開的
            mySound.Size = new Size(currentScreen.Width / 25, currentScreen.Width / 25);
            mySound.SizeMode = PictureBoxSizeMode.StretchImage;
            mySound.BackColor = Color.Transparent;
            mySound.Location = new Point(currentScreen.Width / 2 + w / 2, w * 5 + w / 40 * 6);
            mySound.Click += new EventHandler(mySound_click);
            Controls.Add(mySound);

            play.Image = Properties.Resources.start_blue;
            play.Size = new Size(currentScreen.Width / 25, currentScreen.Width / 25);
            play.SizeMode = PictureBoxSizeMode.StretchImage;
            play.BackColor = Color.Transparent;
            play.Location = new Point(currentScreen.Width / 2 - w * 2, w * 5 + w / 40 * 6);
            Controls.Add(play);
            play.Click += new EventHandler(play_click);

            for (int i = 0; i < pNumberChoiceShow.Length; i++)
            {
                pNumberChoiceShow = new PictureBox();
                pNumberChoice = new PictureBox();
                pNumberChoiceGo = new PictureBox();
                pNumberChoice.Image = (Image)Properties.Resources.ResourceManager.GetObject("c" + i);
                pNumberChoiceGo.Image = (Image)Properties.Resources.ResourceManager.GetObject("g" + i);
                pNumberChoiceShow.Image = pNumberChoice.Image;
                pNumberChoiceShow.Size = new Size(currentScreen.Width / 8, currentScreen.Width / 16);
                pNumberChoiceShow.SizeMode = PictureBoxSizeMode.StretchImage;
                pNumberChoiceShow.Location = new Point(currentScreen.Width / 2, currentScreen.Height / 8 + i * currentScreen.Width / 15);
                pNumberChoiceShow.BackColor = Color.Transparent;
                Controls.Add(pNumberChoiceShow);
                pNumberChoiceShow.Click += new EventHandler(pNumberChoiceShow_click);
            }

            for (int i = 0; i < pThemeShow.Length; i++)
            {
                pThemeChoice = new PictureBox();
                pThemeChoiceGo = new PictureBox();
                pThemeShow = new PictureBox();
                pThemeShow.Size = new Size(currentScreen.Width / 8, currentScreen.Width / 16);
                pThemeShow.SizeMode = PictureBoxSizeMode.StretchImage;
                pThemeShow.Location = new Point(currentScreen.Width / 2 - w * 2, currentScreen.Height / 8 + i * currentScreen.Width / 8);
                pThemeShow.BackColor = Color.Transparent;
                pThemeShow.Click += new EventHandler(pThemeShow_click);
                Controls.Add(pThemeShow);
            }

            pThemeChoice.Image = Properties.Resources.xmas_theme;
            pThemeChoice.Image = Properties.Resources.numbers_theme;
            pThemeChoice.Image = Properties.Resources.food_theme;

            pThemeChoiceGo.Image = Properties.Resources.xmas_theme_go;
            pThemeChoiceGo.Image = Properties.Resources.numbers_theme_go;
            pThemeChoiceGo.Image = Properties.Resources.food_theme_go;

            //先給pThemeShow圖案
            for (int i = 0; i < pThemeShow.Length; i++)
                pThemeShow.Image = pThemeChoice.Image;

            void play_click(object sender, EventArgs e)
            {
                Form2 f2 = new Form2();
                f2.Show();
                this.Hide();
            }

            //sound圖案的選擇方式
            void mySound_click(Object sender, EventArgs e)
            {
                if (soundON == false)
                {
                  soundON = true;
                  mySound.Image = Properties.Resources.sound_on;
                  Form2.soundOn = soundON;
                }
                else if (soundON == true)
                {
                  soundON = false;
                  mySound.Image = Properties.Resources.sound_off;
                  Form2.soundOn = soundON;
                }
            }
            //sound圖案的選擇方式end

      }
      //----f1AllSetting---end


      void pThemeShow_click(Object sender, EventArgs e)
      {
            PictureBox pb = (PictureBox)sender;
            hasClicked1 = true;//如果玩家曾經按過這裡的選項就變成true
            for (int i = 0; i < pThemeShow.Length; i++)
            {
                if (pb.Image == pThemeShow.Image) pThemeNumber = i;//取得被選的號碼是哪個
                pThemeShow.Image = pThemeChoice.Image;//先全都歸成原狀
            }
            pb.Image = pThemeChoiceGo.Image;//再將被選定者給予新值
            if (pThemeNumber == 0) Form2.myImageChoice = 1;
            else if (pThemeNumber == 1) Form2.myImageChoice = 2;
            else if (pThemeNumber == 2) Form2.myImageChoice = 3;
      }



      void pNumberChoiceShow_click(Object sender, EventArgs e)
      {
            PictureBox pb = (PictureBox)sender;
            hasClicked2 = true;//如果玩家曾經按過這裡的選項就變成true
            for (int i = 0; i < pNumberChoiceShow.Length; i++)
            {
                if (pb.Image == pNumberChoice.Image) pChoiceNumber = i;//取得被選的號碼是哪個
                pNumberChoiceShow.Image = pNumberChoice.Image;//先全都歸成原狀
            }
            pb.Image = pNumberChoiceGo.Image;//再將被選定者給予新值
            if (pChoiceNumber == 0) Form2.cardNumber = 4;
            else if (pChoiceNumber == 1) Form2.cardNumber = 8;
            else if (pChoiceNumber == 2) Form2.cardNumber = 12;
            else if (pChoiceNumber == 3) Form2.cardNumber = 18;
            else if (pChoiceNumber == 4) Form2.cardNumber = 24;
      }

    }
}



csharp 發表於 2021-11-28 11:14:48

本帖最後由 csharp 於 2021-11-28 11:32 編輯

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 memory_match_game
{
    //This program is made by Sun Ying-Chi 2021/07/30
    public partial class Form2 : Form
    {
      //先給預設值,以免直接按入時出錯
      //底下有static的變數都是為了讓Form1能直接使用的
      public static int cardNumber = 8;//真正不重覆的牌數
      public static int myImageChoice = 3;//選擇哪個牌色
      public static bool musicOn = true;//設定音樂開關
      public static bool soundOn = true;//設定音效開關

      public Form2()
      {
            InitializeComponent();

            //表單關閉全程式
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form_FormClosing);

            //主體程式               
            f2allSetting();

      }

      //設定表單關閉全程式的方式
      void Form_FormClosing(object sender, FormClosingEventArgs e)
      {
            Application.Exit();
      }

      void f2allSetting()
      {
            this.WindowState = FormWindowState.Maximized;//每次都將螢幕開最大
            this.BackgroundImage = Properties.Resources.form_bg_12;
            this.BackgroundImageLayout = ImageLayout.Stretch;
            //this.BackgroundImageLayout = ImageLayout.Tile;
            Rectangle currentScreen = Screen.PrimaryScreen.WorkingArea;//得出所使用螢幕之長寬值
            int w, h;//卡片的長和寬,本例二者是一樣高的,其實可以只用一個變數

            PictureBox[] pImage = new PictureBox;//真正的牌的數目
            PictureBox[] pShow = new PictureBox;//真正有位置而會顯示的圖陣列
            PictureBox[] pRandom = new PictureBox;//存放已亂數之後的牌卡
            bool[] matched = new bool;//記錄是否已翻之牌已和另一張相符
            bool[] isClicked = new bool;//記錄是否已翻之牌
            Random rnd = new Random();
            int[] array4random = new int;//用於亂數之用

            int whichOne = 0;//選擇到哪個數字
            PictureBox temp1 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
            PictureBox temp2 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
            PictureBox pBack = new PictureBox();//存放背卡圖,若要給不同花色之牌不同背卡,就需要pBack陣列
            int tempN1 = 0;//用於每輪翻牌時存入該二張牌的格數
            int tempN2 = 0;//用於每輪翻牌時存入該二張牌的格數

            SoundPlayer flip = new SoundPlayer(Properties.Resources.flip_0);//翻牌音效
            SoundPlayer error = new SoundPlayer(Properties.Resources.error);//配對不成功
            SoundPlayer gamewin = new SoundPlayer(Properties.Resources.applaud_0);//全部成功之結尾
            SoundPlayer correct = new SoundPlayer(Properties.Resources.correct);//配對成功
            PictureBox reStart = new PictureBox();
            PictureBox home = new PictureBox();
            PictureBox youWin = new PictureBox();//當靜音時才會出現awesome字樣的圖案表示贏了
            Timer mytimer = new Timer();//翻牌不配對之後回復背卡之計時器
            int time = 0;//計算時間//回復計時
            int flipCount = 0;//計算每次一輪翻牌次數,最多二次
            int row = 2;//多少張牌一列

            //主要是setAll和亂排牌卡

            setAll();
            randomPicture();

            //-----------主要牌卡設定以及被執行的功能------------
            void setAll()
            {
                tempN1 = 0;
                tempN2 = 0;
                w = currentScreen.Width / 12;//寬度是目前螢幕的十二分之一
                h = currentScreen.Width / 12;

                //you win shows
                youWin.Size = new Size(currentScreen.Width / 2, currentScreen.Width / 8);
                youWin.Location = new System.Drawing.Point(currentScreen.Width / 4, currentScreen.Height / 3);
                youWin.Image = Properties.Resources.awesome;
                youWin.SizeMode = PictureBoxSizeMode.StretchImage;
                youWin.BackColor = Color.Transparent;
               
                //you win end

                //重新按鈕
                reStart.Size = new Size(currentScreen.Width / 25, currentScreen.Width / 25);
                reStart.Location = new System.Drawing.Point(currentScreen.Width / 2 + w / 2, w * 5 + w / 40 * 6);
                reStart.Image = Properties.Resources.restart;
                reStart.SizeMode = PictureBoxSizeMode.StretchImage;
                reStart.BackColor = Color.Transparent;
                reStart.Click += new EventHandler(restart_click);
                Controls.Add(reStart);
                //回首頁按鈕

                home.Size = new Size(currentScreen.Width / 25, currentScreen.Width / 25);
                home.SizeMode = PictureBoxSizeMode.StretchImage;
                home.BackColor = Color.Transparent;
                home.Image = Properties.Resources.home;
                home.Location = new System.Drawing.Point(currentScreen.Width / 2 - w * 2, w * 5 + w / 40 * 6);
                home.Click += new EventHandler(home_click);
                Controls.Add(home);

                void home_click(Object sender, EventArgs e)
                {
                  gamewin.Stop();
                  Form1 f1 = new Form1();//這個要放前面,不然下一行的功效會慢一拍
                  Form1.soundON = soundOn;//讓Form1的音效選擇圖案同步
                  f1.Show();
                  if (Form1.hasClicked2)//如果Form1已經有點選過張數,這裡再把傳過來的結果再傳回去,好讓那裡的張數選擇圖案繼續保持
                  {
                        if (cardNumber == 4) Form1.pNumberChoiceShow.Image = Form1.pNumberChoiceGo.Image;
                        else if (cardNumber == 8) Form1.pNumberChoiceShow.Image = Form1.pNumberChoiceGo.Image;
                        else if (cardNumber == 12) Form1.pNumberChoiceShow.Image = Form1.pNumberChoiceGo.Image;
                        else if (cardNumber == 18) Form1.pNumberChoiceShow.Image = Form1.pNumberChoiceGo.Image;
                        else if (cardNumber == 24) Form1.pNumberChoiceShow.Image = Form1.pNumberChoiceGo.Image;
                  }
                  if (Form1.hasClicked1)//如果Form1已經有點選過牌色,這裡再把傳過來的結果再傳回去,好讓那裡的牌色選擇圖案繼續保持
                  {
                        if (myImageChoice == 1) Form1.pThemeShow.Image = Form1.pThemeChoiceGo.Image;
                        else if (myImageChoice == 2) Form1.pThemeShow.Image = Form1.pThemeChoiceGo.Image;
                        else if (myImageChoice == 3) Form1.pThemeShow.Image = Form1.pThemeChoiceGo.Image;
                  }

                  Hide();
                }
                //--------回首頁按鈕end-----

                rowSetting();
                //---------設置牌尺寸及每列牌數------------
                void rowSetting()
                {
                  if (cardNumber == 4)
                  {
                        w = currentScreen.Width / 8;
                        h = currentScreen.Width / 8;
                        row = 4;//每4張牌換列
                  }
                  else if (cardNumber == 8)
                  {
                        w = currentScreen.Width / 10;
                        h = currentScreen.Width / 10;
                        row = 8;//每8張牌換列
                  }
                  else if (cardNumber == 12)
                  {
                        w = currentScreen.Width / 10;
                        h = currentScreen.Width / 10;
                        row = 8;//每8張牌換列
                  }
                  else if (cardNumber == 18)
                  {
                        w = currentScreen.Width / 11;
                        h = currentScreen.Width / 11;
                        row = 9;//每9張牌換列
                  }
                  else if (cardNumber == 24)
                  {
                        w = currentScreen.Width / 14;
                        h = currentScreen.Width / 14;
                        row = 12;
                  }
                }
                //---------設置牌尺寸及每列牌數 end------------


                //-------選擇牌色以及背卡的圖案------
                void imageChoice()
                {
                  if (myImageChoice == 1)
                  {
                        pBack.Image = Properties.Resources.xmas_back;
                        for (int i = 0; i < cardNumber; i++)
                        {
                            pImage = new PictureBox();
                            pImage.Image = (Image)Properties.Resources.ResourceManager.GetObject("x" + i);
                        }
                  }
                  else if (myImageChoice == 2)
                  {
                        pBack.Image = Properties.Resources.number_back;
                        for (int i = 0; i < cardNumber; i++)
                        {
                            pImage = new PictureBox();
                            pImage.Image = (Image)Properties.Resources.ResourceManager.GetObject("n" + i);
                        }
                  }

                  else if (myImageChoice == 3)
                  {
                        pBack.Image = Properties.Resources.food_back;
                        for (int i = 0; i < cardNumber; i++)
                        {
                            pImage = new PictureBox();
                            pImage.Image = (Image)Properties.Resources.ResourceManager.GetObject("f" + i);
                        }
                  }
                }
                //-------選擇牌色以及背卡的圖案 end------

                //計時器間隔和方法
                mytimer.Interval = 100;
                mytimer.Tick += new EventHandler(mytimer_tick);
                //----重新按鈕方法-----
                void restart_click(object sender, EventArgs e)
                {
                  if (soundOn == true)
                        flip.Play();
                  gamewin.Stop();
                  startOver();
                }

                //重新開始的方法
                void startOver()
                {
                  Controls.Remove(youWin);
                  temp1.Image = null;//以防點開一張未匹配之前就重玩時,會殘留圖像
                  temp2.Image = null;//不加這個,如果連按二次restart後,翻開的前二張不符合也不會翻回去
                  for (int i = 0; i < cardNumber * 2; i++)
                  {
                        pShow.Image = pBack.Image;
                        matched = false;
                        isClicked = false;
                  }
                  randomPicture();
                }//重新開始的方法end

                void mytimer_tick(object sender, EventArgs e)
                {
                  time++;//計時開始
                  if (time == 4)
                  {
                        //目前翻開的二張圖格回到背卡
                        pShow.Image = pBack.Image;
                        pShow.Image = pBack.Image;
                        isClicked = false;
                        isClicked = false;
                        mytimer.Stop();//計時器停止
                        time = 0;//時間歸零
                  }
                }

                imageChoice();//選擇牌色以及背卡的圖案


                for (int i = 0; i < cardNumber * 2; i++)
                {
                  matched = new bool();
                  isClicked = new bool();
                  isClicked = false;
                  pShow = new PictureBox();//主要圖形顯示格位
                  //卡片位置排列是以所用螢幕長寬來決定,w/40是卡片與卡片的間隔空白,並由列數來決定上面空白長度
                  if (row == 4)
                        pShow.Location = new System.Drawing.Point(w * 2 + i % row * (w + w / 40), w / 2 + i / row * (h + w / 40));//中間有留白
                  else if (row == 8)
                        pShow.Location = new System.Drawing.Point(w + i % row * (w + w / 40), w + i / row * (h + w / 40));//中間有留白
                  else if (row == 9)
                        pShow.Location = new System.Drawing.Point(w + i % row * (w + w / 40), w / 2 + i / row * (h + w / 40));//中間有留白
                  else if (row == 12)
                        pShow.Location = new System.Drawing.Point(w + i % row * (w + w / 40), w * 5 / 4 + i / row * (h + w / 40));//中間有留白

                  pShow.Size = new Size(w, h);//卡片尺寸
                  pShow.SizeMode = PictureBoxSizeMode.StretchImage;//卡片依螢幕而放大或縮小
                  pShow.Image = pBack.Image;
                  Controls.Add(pShow);
                  pShow.Click += new EventHandler(pShow_click);

                  //pRandom用來接納亂序之後的各圖形
                  pRandom = new PictureBox();
                  pRandom.Size = new Size(w, h);
                }
            }
            //----------------主要牌卡設定以及被執行的功能 end-------------------

            //判定是否贏的方法
            void doYouWin()
            {
                bool win = true;
                //如果中間有任何一個matched不是true,則win就變成false
                foreach (bool b in matched)
                {
                  if (b != true) win = false;
                  //break;
                }

                if (win)
                {
                  
                  if (soundOn == true)
                        gamewin.Play();
                  else
                  {
                        Controls.Add(youWin);
                        youWin.BringToFront();
                  }
                }
            }

            //主顯示圖形陣列被點擊時的方法
            void pShow_click(object sender, EventArgs e)
            {
                PictureBox p = (PictureBox)sender;
                whichPic(sender);//取得目前滑鼠點擊的格子是幾號格
                if (matched != true && time == 0 && isClicked == false)//如果點到圖格還未被matched,而且計時器的t已歸零,才能進行本次的翻牌
                {
                  pShow.Image = pRandom.Image;//將原本的背卡圖換成本圖
                  if (soundOn == true)
                        flip.Play();

                  temp();//進行翻牌後的方法

                  //已翻了二次牌,如果二牌圖形相等,則二個格子所對應數字的matched都變成true
                  if (temp1.Image == temp2.Image)
                  {
                        matched = true;
                        matched = true;

                        if (soundOn == true)
                            correct.Play();

                  }
                  else if (flipCount == 2)//如果不相等而且翻牌的次數已是二次。(如果只有一次自然會不相等)
                  {
                        if (soundOn == true)
                            error.Play();

                        mytimer.Start();//計時開始,好讓被翻開但不相同牌色的二張卡都回到背卡狀態
                  }
                }
                doYouWin();//每次都檢查你贏的條件是否達成,如果是就顯示訊息
            }

            //翻牌時進行的方法
            void temp()
            {
                if (temp1.Image != null && temp2.Image != null)//如果二個臨時圖都已有放圖了
                {
                  //將翻牌次數以及二個臨時存放的圖格歸零
                  flipCount = 0;
                  temp1.Image = null;
                  temp2.Image = null;
                }

                if (temp1.Image == null)//如果第一個臨時存圖格是空的
                {
                  flipCount = 1;//翻牌次數算一次
                  isClicked = true;
                  temp1.Image = pShow.Image;
                  tempN1 = whichOne;
                }
                else//如果第一個已有圖檔存入,就放進第二個
                {
                  flipCount = 2;//翻牌次數算第二次
                  isClicked = true;
                  temp2.Image = pShow.Image;
                  tempN2 = whichOne;
                }
            }
            //翻牌時進行的方法end

            //被點擊的圖片是哪一格位

            void whichPic(object sender)
            {
                PictureBox p = (PictureBox)sender;
                for (int i = 0; i < cardNumber * 2; i++)
                  if (p.Location == pShow.Location)
                        whichOne = i;
            }
            //被點擊的圖片是哪一格位end

            //---------------將圖片亂排 begin ---------------
            void randomPicture()//先設立一個函數
            {
                void randomPickNoRepeat(int[] array)
                {
                  for (int i = 0; i < array.Length; i++)
                  {
                        array = rnd.Next(array.Length);

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

                //第一次亂數,每隔一格子插入一個圖片
                randomPickNoRepeat(array4random);
                for (int i = 0; i < cardNumber; i++)
                {
                  pRandom.Image = pImage].Image;
                }

                //第二次亂數,每隔一格子插入一個圖片
                randomPickNoRepeat(array4random);
                for (int i = 0; i < cardNumber; i++)
                {
                  pRandom.Image = pImage].Image;
                }
            }
            //----------將圖片亂排end-------------

      }

    }//---------public Form2() end ---------
}
頁: [1]
查看完整版本: 多選翻翻樂memory match game