code.club

 找回密碼
 立即註冊
搜索
查看: 3814|回復: 0

memory game ok code

[複製鏈接]
發表於 2021-7-12 11:13:36 | 顯示全部樓層 |閱讀模式
本帖最後由 csharp 於 2021-7-16 13:47 編輯

五十張消消樂,有音效,全代碼,適應各不同大小的螢幕。




  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 memorygame_0
  12. {
  13.     public partial class Form1 : Form
  14.     {
  15.         Rectangle currentScreen = Screen.PrimaryScreen.WorkingArea;//得出所使用螢幕之長寬值
  16.         int w, h;//卡片的長和寬,本例二者是一樣高的,其實可以只用一個變數

  17.         PictureBox[] pImage = new PictureBox[25];
  18.         PictureBox[] pShow = new PictureBox[50];
  19.         PictureBox[] pRandom = new PictureBox[50];
  20.         bool[] matched = new bool[50];//記錄是否已翻之牌已和另一張相符
  21.         bool[] isClicked = new bool[50];
  22.         Random rnd = new Random();
  23.         int[] a = new int[25];//用於亂數之用
  24.         Timer mytimer = new Timer();
  25.         PictureBox temp1 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
  26.         PictureBox temp2 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
  27.         PictureBox pBack = new PictureBox();//存放背卡圖
  28.         int tempN1, tempN2;//用於每輪翻牌時存入該二張牌的格數
  29.         SoundPlayer flip = new SoundPlayer(Properties.Resources.touch);
  30.         SoundPlayer error = new SoundPlayer(Properties.Resources.error);
  31.         SoundPlayer gamewin = new SoundPlayer(Properties.Resources.applaud);
  32.         SoundPlayer correct = new SoundPlayer(Properties.Resources.correct);
  33.         Button reStart = new Button();
  34.         public Form1()
  35.         {
  36.             this.WindowState = FormWindowState.Maximized;//每次都將螢幕開最大
  37.             this.BackgroundImage = Properties.Resources.form_bg;
  38.             this.BackgroundImageLayout = ImageLayout.Stretch;
  39.             InitializeComponent();
  40.             
  41.             master();
  42.         }

  43.         void master()
  44.         {
  45.             setAll();
  46.             randomPicture();
  47.         }

  48.         int t;//計算時間
  49.         int flipCount = 0;//計算每次一輪翻牌次數,最多二次


  50.         void setAll()
  51.         {
  52.             w = currentScreen.Width / 12;//寬度是目前螢幕的十二分之一
  53.             h = currentScreen.Width / 12;
  54.             //重新按鈕
  55.             reStart.Size = new Size(80, 40);
  56.             reStart.Location = new System.Drawing.Point(w * 5 + w / 2 + w / 40 * 5, w * 5 + w / 2 + w / 40 * 6);
  57.             reStart.BackColor = Color.Aqua;
  58.             reStart.Text = "restart";
  59.             reStart.Click += new EventHandler(restart_click);
  60.             Controls.Add(reStart);

  61.             //背卡圖片設定
  62.             pBack.Image = Properties.Resources.bg;

  63.             //計時器間隔和方法
  64.             mytimer.Interval = 100;
  65.             mytimer.Tick += new EventHandler(mytimer_tick);

  66.             void restart_click(object sender, EventArgs e)
  67.             {
  68.                 flip.Play();
  69.                 startOver();
  70.             }

  71.             //重新開始的方法
  72.             void startOver()
  73.             {
  74.                 temp1.Image = null;//以防點開一張未匹配之前就重玩時,會殘留第一張圖像
  75.                 for (int i = 0; i < 50; i++)
  76.                 {
  77.                     pShow[i].Image = pBack.Image;
  78.                     matched[i] = false;
  79.                     isClicked[i] = false;
  80.                 }
  81.                 randomPicture();
  82.             }//重新開始的方法end

  83.             void mytimer_tick(object sender, EventArgs e)
  84.             {
  85.                 t++;//計時開始
  86.                 if (t == 4)
  87.                 {
  88.                     //目前翻開的二張圖格回到背卡
  89.                     pShow[tempN1].Image = pBack.Image;
  90.                     pShow[tempN2].Image = pBack.Image;
  91.                     isClicked[tempN1] = false;
  92.                     isClicked[tempN2] = false;
  93.                     mytimer.Stop();//計時器停止
  94.                     t = 0;//時間歸零
  95.                 }
  96.             }



  97.             for (int i = 0; i < 25; i++)
  98.             {
  99.                 pImage[i] = new PictureBox();
  100.                 pImage[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("a" + i);
  101.                 pImage[i].Size = new Size(w, h);

  102.             }

  103.             for (int i = 0; i < 50; i++)
  104.             {
  105.                 matched[i] = new bool();
  106.                 isClicked[i] = new bool();
  107.                 isClicked[i] = false;
  108.                 pShow[i] = new PictureBox();//主要圖形顯示格位
  109.                 //卡片位置排列是以所用螢幕長寬來決定,w/40是卡片與卡片的間隔空白
  110.                 pShow[i].Location = new System.Drawing.Point(w + i % 10 * (w + w / 40), w / 2 + i / 10 * (h + w / 40));//中間有留白
  111.                 pShow[i].Size = new Size(w, h);//卡片尺寸
  112.                 pShow[i].SizeMode = PictureBoxSizeMode.StretchImage;//卡片依螢幕而放大或縮小
  113.                 pShow[i].Image = pBack.Image;
  114.                 Controls.Add(pShow[i]);
  115.                 pShow[i].Click += new EventHandler(pShow_click);

  116.                 //pRandom用來接納亂序之後的各圖形
  117.                 pRandom[i] = new PictureBox();
  118.                 pRandom[i].Size = new Size(w, h);

  119.             }
  120.         }

  121.         //判定是否贏的方法
  122.         void doYouWin()
  123.         {
  124.             bool win = true;
  125.             //如果中間有任何一個matched不是true,則win就變成false
  126.             foreach (bool b in matched)
  127.             {
  128.                 if (b != true) win = false;
  129.                 //break;
  130.             }

  131.             if (win) gamewin.Play();
  132.         }

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

  143.                 //已翻了二次牌,如果二牌圖形相等,則二個格子所對應數字的matched都變成true
  144.                 if (temp1.Image == temp2.Image)
  145.                 {
  146.                     matched[tempN1] = true;
  147.                     matched[tempN2] = true;
  148.                     correct.Play();

  149.                 }
  150.                 else if (flipCount == 2)//如果不相等而且翻牌的次數已是二次。(如果只有一次自然會不相等)
  151.                 {
  152.                     error.Play();
  153.                     mytimer.Start();//計時開始,好讓被翻開但不相同牌色的二張卡都回到背卡狀態
  154.                 }
  155.             }
  156.             doYouWin();//每次都檢查你贏的條件是否達成,如果是就顯示訊息
  157.         }

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

  168.             if (temp1.Image == null)//如果第一個臨時存圖格是空的
  169.             {
  170.                 flipCount = 1;//翻牌次數算一次
  171.                 isClicked[whichOne] = true;
  172.                 temp1.Image = pShow[whichOne].Image;
  173.                 tempN1 = whichOne;
  174.             }
  175.             else//如果第一個已有圖檔存入,就放進第二個
  176.             {
  177.                 flipCount = 2;//翻牌次數算第二次
  178.                 isClicked[whichOne] = true;
  179.                 temp2.Image = pShow[whichOne].Image;
  180.                 tempN2 = whichOne;
  181.             }
  182.         }
  183.         //翻牌時進行的方法end

  184.         //被點擊的圖片是哪一格位
  185.         int whichOne;
  186.         void whichPic(object sender)
  187.         {
  188.             PictureBox p = (PictureBox)sender;
  189.             for (int i = 0; i < 50; i++)
  190.                 if (p.Location == pShow[i].Location)
  191.                     whichOne = i;
  192.         }
  193.         //被點擊的圖片是哪一格位end

  194.         //將圖片亂排
  195.         void randomPicture()
  196.         {
  197.             void randomPickNoRepeat(int[] a)
  198.             {

  199.                 for (int i = 0; i < a.Length; i++)
  200.                 {
  201.                     a[i] = rnd.Next(a.Length);

  202.                     for (int j = 0; j < i; j++)
  203.                         if (a[j] == a[i])
  204.                         {
  205.                             i--;
  206.                             break;
  207.                         }
  208.                 }
  209.             }

  210.             //第一次亂數,每隔一格子插入一個圖片
  211.             randomPickNoRepeat(a);
  212.             for (int i = 0; i < 25; i++)
  213.             {

  214.                 pRandom[i * 2 + 1].Image = pImage[a[i]].Image;
  215.             }

  216.             //第二次亂數,每隔一格子插入一個圖片
  217.             randomPickNoRepeat(a);
  218.             for (int i = 0; i < 25; i++)
  219.             {

  220.                 pRandom[i * 2].Image = pImage[a[i]].Image;

  221.             }

  222.         }
  223.         //將圖片亂排end
  224.     }
  225. }



複製代碼
回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

小黑屋|手機版|Archiver|code.club  

GMT+8, 2024-3-29 15:08 , Processed in 0.092355 second(s), 18 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表