memory game ok code
本帖最後由 csharp 於 2021-7-16 13:47 編輯五十張消消樂,有音效,全代碼,適應各不同大小的螢幕。
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 memorygame_0
{
public partial class Form1 : Form
{
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[] a = new int;//用於亂數之用
Timer mytimer = new Timer();
PictureBox temp1 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
PictureBox temp2 = new PictureBox();//可以不要有其他設定,但一定要有實體化設定
PictureBox pBack = new PictureBox();//存放背卡圖
int tempN1, tempN2;//用於每輪翻牌時存入該二張牌的格數
SoundPlayer flip = new SoundPlayer(Properties.Resources.touch);
SoundPlayer error = new SoundPlayer(Properties.Resources.error);
SoundPlayer gamewin = new SoundPlayer(Properties.Resources.applaud);
SoundPlayer correct = new SoundPlayer(Properties.Resources.correct);
Button reStart = new Button();
public Form1()
{
this.WindowState = FormWindowState.Maximized;//每次都將螢幕開最大
this.BackgroundImage = Properties.Resources.form_bg;
this.BackgroundImageLayout = ImageLayout.Stretch;
InitializeComponent();
master();
}
void master()
{
setAll();
randomPicture();
}
int t;//計算時間
int flipCount = 0;//計算每次一輪翻牌次數,最多二次
void setAll()
{
w = currentScreen.Width / 12;//寬度是目前螢幕的十二分之一
h = currentScreen.Width / 12;
//重新按鈕
reStart.Size = new Size(80, 40);
reStart.Location = new System.Drawing.Point(w * 5 + w / 2 + w / 40 * 5, w * 5 + w / 2 + w / 40 * 6);
reStart.BackColor = Color.Aqua;
reStart.Text = "restart";
reStart.Click += new EventHandler(restart_click);
Controls.Add(reStart);
//背卡圖片設定
pBack.Image = Properties.Resources.bg;
//計時器間隔和方法
mytimer.Interval = 100;
mytimer.Tick += new EventHandler(mytimer_tick);
void restart_click(object sender, EventArgs e)
{
flip.Play();
startOver();
}
//重新開始的方法
void startOver()
{
temp1.Image = null;//以防點開一張未匹配之前就重玩時,會殘留第一張圖像
for (int i = 0; i < 50; i++)
{
pShow.Image = pBack.Image;
matched = false;
isClicked = false;
}
randomPicture();
}//重新開始的方法end
void mytimer_tick(object sender, EventArgs e)
{
t++;//計時開始
if (t == 4)
{
//目前翻開的二張圖格回到背卡
pShow.Image = pBack.Image;
pShow.Image = pBack.Image;
isClicked = false;
isClicked = false;
mytimer.Stop();//計時器停止
t = 0;//時間歸零
}
}
for (int i = 0; i < 25; i++)
{
pImage = new PictureBox();
pImage.Image = (Image)Properties.Resources.ResourceManager.GetObject("a" + i);
pImage.Size = new Size(w, h);
}
for (int i = 0; i < 50; i++)
{
matched = new bool();
isClicked = new bool();
isClicked = false;
pShow = new PictureBox();//主要圖形顯示格位
//卡片位置排列是以所用螢幕長寬來決定,w/40是卡片與卡片的間隔空白
pShow.Location = new System.Drawing.Point(w + i % 10 * (w + w / 40), w / 2 + i / 10 * (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);
}
}
//判定是否贏的方法
void doYouWin()
{
bool win = true;
//如果中間有任何一個matched不是true,則win就變成false
foreach (bool b in matched)
{
if (b != true) win = false;
//break;
}
if (win) gamewin.Play();
}
//主顯示圖形陣列被點擊時的方法
void pShow_click(object sender, EventArgs e)
{
PictureBox p = (PictureBox)sender;
whichPic(sender);//取得目前滑鼠點擊的格子是幾號格
if (matched != true && t == 0 && isClicked == false)//如果點到圖格還未被matched,而且計時器的t已歸零,才能進行本次的翻牌
{
pShow.Image = pRandom.Image;//將原本的背卡圖換成本圖
flip.Play();
temp();//進行翻牌後的方法
//已翻了二次牌,如果二牌圖形相等,則二個格子所對應數字的matched都變成true
if (temp1.Image == temp2.Image)
{
matched = true;
matched = true;
correct.Play();
}
else if (flipCount == 2)//如果不相等而且翻牌的次數已是二次。(如果只有一次自然會不相等)
{
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
//被點擊的圖片是哪一格位
int whichOne;
void whichPic(object sender)
{
PictureBox p = (PictureBox)sender;
for (int i = 0; i < 50; i++)
if (p.Location == pShow.Location)
whichOne = i;
}
//被點擊的圖片是哪一格位end
//將圖片亂排
void randomPicture()
{
void randomPickNoRepeat(int[] a)
{
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;
}
}
}
//第一次亂數,每隔一格子插入一個圖片
randomPickNoRepeat(a);
for (int i = 0; i < 25; i++)
{
pRandom.Image = pImage].Image;
}
//第二次亂數,每隔一格子插入一個圖片
randomPickNoRepeat(a);
for (int i = 0; i < 25; i++)
{
pRandom.Image = pImage].Image;
}
}
//將圖片亂排end
}
}
頁:
[1]