code.club
標題:
memory game ok code
[打印本頁]
作者:
csharp
時間:
2021-7-12 11:13
標題:
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[25];
PictureBox[] pShow = new PictureBox[50];
PictureBox[] pRandom = new PictureBox[50];
bool[] matched = new bool[50];//記錄是否已翻之牌已和另一張相符
bool[] isClicked = new bool[50];
Random rnd = new Random();
int[] a = new int[25];//用於亂數之用
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[i].Image = pBack.Image;
matched[i] = false;
isClicked[i] = false;
}
randomPicture();
}//重新開始的方法end
void mytimer_tick(object sender, EventArgs e)
{
t++;//計時開始
if (t == 4)
{
//目前翻開的二張圖格回到背卡
pShow[tempN1].Image = pBack.Image;
pShow[tempN2].Image = pBack.Image;
isClicked[tempN1] = false;
isClicked[tempN2] = false;
mytimer.Stop();//計時器停止
t = 0;//時間歸零
}
}
for (int i = 0; i < 25; i++)
{
pImage[i] = new PictureBox();
pImage[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("a" + i);
pImage[i].Size = new Size(w, h);
}
for (int i = 0; i < 50; i++)
{
matched[i] = new bool();
isClicked[i] = new bool();
isClicked[i] = false;
pShow[i] = new PictureBox();//主要圖形顯示格位
//卡片位置排列是以所用螢幕長寬來決定,w/40是卡片與卡片的間隔空白
pShow[i].Location = new System.Drawing.Point(w + i % 10 * (w + w / 40), w / 2 + i / 10 * (h + w / 40));//中間有留白
pShow[i].Size = new Size(w, h);//卡片尺寸
pShow[i].SizeMode = PictureBoxSizeMode.StretchImage;//卡片依螢幕而放大或縮小
pShow[i].Image = pBack.Image;
Controls.Add(pShow[i]);
pShow[i].Click += new EventHandler(pShow_click);
//pRandom用來接納亂序之後的各圖形
pRandom[i] = new PictureBox();
pRandom[i].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[whichOne] != true && t == 0 && isClicked[whichOne] == false)//如果點到圖格還未被matched,而且計時器的t已歸零,才能進行本次的翻牌
{
pShow[whichOne].Image = pRandom[whichOne].Image;//將原本的背卡圖換成本圖
flip.Play();
temp();//進行翻牌後的方法
//已翻了二次牌,如果二牌圖形相等,則二個格子所對應數字的matched都變成true
if (temp1.Image == temp2.Image)
{
matched[tempN1] = true;
matched[tempN2] = 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[whichOne] = true;
temp1.Image = pShow[whichOne].Image;
tempN1 = whichOne;
}
else//如果第一個已有圖檔存入,就放進第二個
{
flipCount = 2;//翻牌次數算第二次
isClicked[whichOne] = true;
temp2.Image = pShow[whichOne].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[i].Location)
whichOne = i;
}
//被點擊的圖片是哪一格位end
//將圖片亂排
void randomPicture()
{
void randomPickNoRepeat(int[] a)
{
for (int i = 0; i < a.Length; i++)
{
a[i] = rnd.Next(a.Length);
for (int j = 0; j < i; j++)
if (a[j] == a[i])
{
i--;
break;
}
}
}
//第一次亂數,每隔一格子插入一個圖片
randomPickNoRepeat(a);
for (int i = 0; i < 25; i++)
{
pRandom[i * 2 + 1].Image = pImage[a[i]].Image;
}
//第二次亂數,每隔一格子插入一個圖片
randomPickNoRepeat(a);
for (int i = 0; i < 25; i++)
{
pRandom[i * 2].Image = pImage[a[i]].Image;
}
}
//將圖片亂排end
}
}
複製代碼
歡迎光臨 code.club (https://code.club/)
Powered by Discuz! X3.2