儿童节教大家做一个C#图片匹配小游戏

简介: 儿童节教大家做一个C#图片匹配小游戏

1. 效果展示


(只展示一部分哈)



帮助规则




2. 游戏设计


2.1. 界面设计


首先,见到华丽的界面先不要慌,哈哈哈哈,背景知识个图片而已,无伤大雅。



当然游戏帮助也是背景图片,不过字也是图片的一部分



之后就是给他加一个菜单栏了,简单加一个开始游戏与退出就好



之后是创建16个PictureBox用于显示16个小图片



再有就是三个lable,用于显示游戏过程中的信息





2.2. 逻辑设计


写逻辑之前我们要先建立游戏要用到的各种变量


// 一维数组,与窗体上的每个图片框对应,存放每个图片框对应的图片索引
int[] pictureIds;
int firstIndex;      // 记录点击的第一个图片框
int secondIndex;     // 记录点击的匹配的图片框
int firstPictureId;  // 已经点中的第一个图片框中显示的图片索引  
int secondPictureId; // 已经点中的匹配的图片框中显示的图片索引  
int count;           // 计数,记录点击了几个图片
int gameState;       // 游戏状态:0-进行中,1-新游戏,-1-未开始
int gameTime;        // 游戏时间
int matchNum;        // 配成对的数量
int record;          // 最高记录


2.2.1. 游戏初始化


首先我们要先对一维数组进行重新实例化,再把游戏状态改为未开始(值为-1),最高记录设置为0就OK啦。


功能代码如下:


 this.pictureIds = new int[16];  // 创建一维数组
 gameState = -1;                 // 游戏状态为未开始
 record = 0;                     // 没有最高记录


2.2.2. 开始游戏


首先是设置各个变量的初始状态,这里不一一叙述,再将每张图片随机放到两个box里就行啦


// 随机指定每个图片框显示的动物图片
for (int i = 1; i <= 8; i++)
{
    // 每张图片都放在两个图片框中
    PutIntoBox(i);
    PutIntoBox(i);
}


PutIntoBox是自定义随机图片位置函数


// 将指定索引的图片随机放在一个图片框中,记录在一维数组中
private void PutIntoBox(int pictureIndex)
{
    Random r = new Random();
    int boxId = r.Next(16);   // 随机找到一个图片框
    if (this.pictureIds[boxId] != -1)  // 已经有图片了
    {
        // 找到一个还没有图片的图片框
        while (this.pictureIds[boxId] != -1)
        {
            boxId = r.Next(16);   // 随机找到一个图片框
        }
    }
    this.pictureIds[boxId] = pictureIndex;  // 指定这个图片框对应的图片
}


之后别忘了开启计时器


// 启动计时器
tmrShow.Start();


2.2.3. 玩游戏


图片框单击事件


首先,如果游戏不在进行中,则不能点击图片框


// 
if (gameState != 0)
{
    return;
}


如果在游戏中,就可以判断点击的是第一张图片还是第二张了:


  • 点击的是第一张图片:保存当前图片的相关参数


  • 点击的是第二张图片:保存第二张图片的相关参数,并且调用判断函数进行判断是否匹配。


if (count == 1)  // 点击的是第一张图片
{
    this.firstIndex = newIndex;
    this.firstPictureId = newPictureId;
    ((PictureBox)sender).Image = ilPictures.Images[newPictureId];
    tmrShow.Start();                
}
else if (count == 2)  // 点击了两张图片
{
    this.secondIndex = newIndex;
    this.secondPictureId = newPictureId;
    ((PictureBox)sender).Image = ilPictures.Images[newPictureId];
    tmrShow.Stop();   // 将控制3秒钟显示的定时器停止
    tmrMatch.Start();    // 启动延时0.5s计时器,并判断是否匹配
}             


2.2.3.1. 判断


判断需要判断两个:


  • 是否配对成功进行图片消除


  • 检查是否要停止游戏


而且顺序不能调换,要先判断是否能消除,因为当最后两个图片消除完的时候就是游戏结束的时候。


// 是否配对成功进行图片消除
if (this.firstIndex != this.secondIndex && this.firstPictureId == this.secondPictureId)
{
    // 将图片框置为不可见
    SetInvisible(this.firstIndex);
    SetInvisible(this.secondIndex);
    this.matchNum++;
}
ResetState();     // 重新开始配对
HidePictures();
// 检查是否要停止游戏            
if (this.matchNum == 8)
{
    tmrGame.Stop();
    string message = string.Format("配对完成,用时{0}秒,继续努力哦!",this.gameTime);
    MessageBox.Show(message, "游戏结束", MessageBoxButtons.OK, MessageBoxIcon.Information);
    if (this.gameTime < this.record || this.record ==0)
    {
        lblRecord.Text = this.gameTime.ToString() + "秒";
    }
    this.gameState = -1;   // 游戏变为未开始状态
}            


2.2.4. 退出


DialogResult result = MessageBox.Show("确实要退出吗?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
    Application.Exit();
}  


3. 代码实现


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MatchBox
{
    public partial class BoxesForm : Form
    {
        // 一维数组,与窗体上的每个图片框对应,存放每个图片框对应的图片索引
        int[] pictureIds;
        int firstIndex;      // 记录点击的第一个图片框
        int secondIndex;     // 记录点击的匹配的图片框
        int firstPictureId;  // 已经点中的第一个图片框中显示的图片索引  
        int secondPictureId; // 已经点中的匹配的图片框中显示的图片索引  
        int count;           // 计数,记录点击了几个图片
        int gameState;       // 游戏状态:0-进行中,1-新游戏,-1-未开始
        int gameTime;        // 游戏时间
        int matchNum;        // 配成对的数量
        int record;          // 最高记录
        public BoxesForm()
        {
            InitializeComponent();
        }
        // 窗体加载时,每个picturebox关联到一个动物图片
        private void BoxesForm_Load(object sender, EventArgs e)
        {
            this.pictureIds = new int[16];  // 创建一维数组
            gameState = -1;                 // 游戏状态为未开始
            record = 0;                     // 没有最高记录
        }
        // 开始游戏
        private void StartGame()
        {
            gameState = 1;      // 标志为新游戏
            this.gameTime = 0;  // 游戏时间
            this.matchNum = 0;  // 配对的数量
            // 设置各个变量的初始状态
            ResetState();
            // 将计时器都停止
            tmrGame.Stop();
            tmrShow.Stop();
            tmrMatch.Stop();
            lblCostTime.Text = "0秒";
            // 将记录图片框显示的图片的数组都置为-1            
            for (int i = 0; i < this.pictureIds.Length; i++)
            {
                this.pictureIds[i] = -1;
            } 
            // 随机指定每个图片框显示的动物图片
            for (int i = 1; i <= 8; i++)
            {
                // 每张图片都放在两个图片框中
                PutIntoBox(i);
                PutIntoBox(i);
            }
            // 显示所有图片
            foreach (Control item in this.Controls)
            {
                if (item is PictureBox)
                {
                    int index = Convert.ToInt32(((PictureBox)item).Tag);
                    int pictureIndex = this.pictureIds[index];
                    ((PictureBox)item).Visible = true;
                    ((PictureBox)item).Image = ilPictures.Images[pictureIndex];
                }
            }
            // 启动计时器
            tmrShow.Start();
        }
        // 将指定索引的图片随机放在一个图片框中,记录在一维数组中
        private void PutIntoBox(int pictureIndex)
        {
            Random r = new Random();
            int boxId = r.Next(16);   // 随机找到一个图片框
            if (this.pictureIds[boxId] != -1)  // 已经有图片了
            {
                // 找到一个还没有图片的图片框
                while (this.pictureIds[boxId] != -1)
                {
                    boxId = r.Next(16);   // 随机找到一个图片框
                }
            }
            this.pictureIds[boxId] = pictureIndex;  // 指定这个图片框对应的图片
        }
        // 图片框单击事件
        private void picBox_Click(object sender, EventArgs e)
        {
            // 如果游戏不在进行中,则不能点击图片框
            if (gameState != 0)
            {
                return;
            }
            int newIndex = Convert.ToInt32(((PictureBox)sender).Tag);   // 当前点中的图片框在数组中的索引
            int newPictureId = this.pictureIds[newIndex];               // 当前点中的图片框显示的图片的索引            
            count++;  // 计数
            if (count == 1)  // 点击的是第一张图片
            {
                this.firstIndex = newIndex;
                this.firstPictureId = newPictureId;
                ((PictureBox)sender).Image = ilPictures.Images[newPictureId];
                tmrShow.Start();                
            }
            else if (count == 2)  // 点击了两张图片
            {
                this.secondIndex = newIndex;
                this.secondPictureId = newPictureId;
                ((PictureBox)sender).Image = ilPictures.Images[newPictureId];
                tmrShow.Stop();   // 将控制3秒钟显示的定时器停止
                tmrMatch.Start();    // 启动延时0.5s计时器,并判断是否匹配
            }                      
        }
        // 恢复状态
        private void ResetState()
        {
            this.firstIndex = -1;
            this.secondIndex = -1;
            this.firstPictureId = -1;
            this.secondPictureId = -1;
            this.count = 0;   
        }
        // 控制图片最多显示3秒
        private void tmrShow_Tick(object sender, EventArgs e)
        {
            tmrShow.Stop();  // 停止计时器            
            if (gameState == 1)  // 如果是新游戏
            {
                gameState = 0;   // 将游戏状态变为进行中                
                tmrGame.Start(); // 开始计时
            }
            ResetState();      // 清除记录
            HidePictures();   // 隐藏图片           
        }
        // 隐藏所有图片
        private void HidePictures()
        {
            // 将所有图片都翻过去            
            foreach (Control item in this.Controls)
            {
                if (item is PictureBox)
                {
                    ((PictureBox)item).Image = ilPictures.Images[0];
                }
            }            
        }
        // 将指定索引的图片框置为不可见
        private void SetInvisible(int index)
        {
            foreach (Control item in this.Controls)
            {
                if (item is PictureBox)
                {
                    if (Convert.ToInt32(((PictureBox)item).Tag) == index)
                    {
                        ((PictureBox)item).Visible = false;
                    }                    
                }
            }
        }
        // 显示0.5秒
        private void tmrMatch_Tick(object sender, EventArgs e)
        {
            tmrMatch.Stop();
            if (this.firstIndex != this.secondIndex && this.firstPictureId == this.secondPictureId)
            {
                // 将图片框置为不可见
                SetInvisible(this.firstIndex);
                SetInvisible(this.secondIndex);
                this.matchNum++;
            }
            ResetState();     // 重新开始配对
            HidePictures();
            // 检查是否要停止游戏            
            if (this.matchNum == 8)
            {
                tmrGame.Stop();
                string message = string.Format("配对完成,用时{0}秒,继续努力哦!",this.gameTime);
                MessageBox.Show(message, "游戏结束", MessageBoxButtons.OK, MessageBoxIcon.Information);
                if (this.gameTime < this.record || this.record ==0)
                {
                    lblRecord.Text = this.gameTime.ToString() + "秒";
                }
                this.gameState = -1;   // 游戏变为未开始状态
            }            
        }
        // 开始新游戏
        private void tsmiNewGame_Click(object sender, EventArgs e)
        {
            StartGame();
        }
        // 退出
        private void tsmiExit_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("确实要退出吗?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);
            if (result == DialogResult.Yes)
            {
                Application.Exit();
            }            
        }
        // 游戏计时
        private void tmrGame_Tick(object sender, EventArgs e)
        {
            this.gameTime++;  // 将时间增加1s
            lblCostTime.Text = gameTime.ToString() + "秒";                     
        }
        private void tsmiRule_Click(object sender, EventArgs e)
        {
            GameRuleForm ruleForm = new GameRuleForm();
            ruleForm.ShowDialog();
        }
    }
}


4. 资源链接


CSDN下载:https://mp-new.csdn.net/mp_download/manage/download/UpDetailed


百度网盘:


链接:https://pan.baidu.com/s/1gxe1EVFLz5Lki2kVUyjHlA


提取码:y2j1


相关文章
C#窗体连连看小游戏(超详细)(下)
C#窗体连连看小游戏(超详细)
357 0
|
2月前
|
数据采集 JavaScript C#
C#图像爬虫实战:从Walmart网站下载图片
C#图像爬虫实战:从Walmart网站下载图片
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
445 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
5月前
|
人工智能 缓存 Java
技术经验解读:【转】详细解析用C#写的小游戏《彩色连珠》(附源代码)
技术经验解读:【转】详细解析用C#写的小游戏《彩色连珠》(附源代码)
25 0
|
6月前
|
存储 算法 C#
C# 生成指定图片的缩略图
C# 生成指定图片的缩略图
|
6月前
|
C# 开发工具 数据安全/隐私保护
C# 给图片添加文字水印
C# 给图片添加文字水印
|
6月前
|
开发框架 .NET C#
C# 自动填充文字内容到指定图片
C# 自动填充文字内容到指定图片
|
6月前
|
API C# 数据安全/隐私保护
C# 实现网页内容保存为图片并生成压缩包
C# 实现网页内容保存为图片并生成压缩包
|
11月前
|
API C#
C# 调用系统“API“设置图片为“桌面壁纸“
C# 调用系统“API“设置图片为“桌面壁纸“
下一篇
无影云桌面