基于C#的2048小游戏

这篇具有很好参考价值的文章主要介绍了基于C#的2048小游戏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在玩过2048这个小游戏后感觉很有意思,想着正在学C#的winfrom的我能不能自己写一个2048游戏呢?于是就有了这个:

基于C#的2048小游戏

 

目录

1.实现思路;

2.代码实现;

1.初始化地图表示的数组;

2.绘制游戏的边框;

3.设置每个数值对应的颜色(可省略);

4.添加控件;

5.四个方向的移动;

6.生成新数字

7.更新地图显示

8.按键控制


1.实现思路;

首先2048的操作比较简单,玩家只需要控制“上下左右”四个方向就可以让框内的图片往一个方向移动,在移动过程中相邻的两个图片的数字如果相等则可以合并成更大的数字最大为2048,另外需要注意的是多个相同数字相邻时只能两两相互合并,合并的方向要根据此时的移动方向来判断,合并后数字需要下一次移动时再判断需不需要继续合并;

然后是主程序的设计思路,由于2048游戏的大小固定在一个确定的空间中,每个图片占据一个方形的控件,那么我们可以用一个二维的数组来表示整个控件和控件的位置关系,数组里的元素值就是需要表示的图片数字;

2.代码实现;

1.初始化地图表示的数组;

这里我们先按照思路给数组赋值,先定义一个二维的数组map大小为5*5,另外定义一个长度等于25的数组由于存放生成的随机数,初始值只有2和4;

        int[] map_s = new int[25];
        private long[,] map;
        private void chushi_map()
        {
            map = new long[5, 5]
            {
                {0,0,0,0,0 },
                {0,0,0,0,0 },
                {0,0,0,0,0 },
                {0,0,0,0,0 },
                {0,0,0,0,0 },
            };
            Random r = new Random();
            for (int i = 0; i < 25; i++)
            {
                int s;
                while (true)
                {
                    s = r.Next(2, 5);
                    if (s == 2 || s == 4)
                    {
                        break;
                    }
                }
                map_s[i] = s;
            }
           
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    map[i, j] = map_s[i * 5 + j];
                }
            }
        }//初始化数据和地图;

2.绘制游戏的边框;

利用OnPaint函数绘制游戏需要的边框;

        private int bianjie_x;
        private int bianjie_y;
        private int fangkuang_width;
        private int fangkuang_height;

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Width = 500;
            this.Height = 500;
            fangkuang_width = 300;
            fangkuang_height = 300;
            color_fenpei();
            bianjie_x = (this.ClientSize.Width - fangkuang_width) / 2 ;
            bianjie_y = (this.ClientSize.Height - fangkuang_height) / 2 ;
            chushi_map();
            map_show();

        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics g = this.CreateGraphics();
            Pen bluePen = new Pen(Color.Black, 4);
            g.Clear(Color.White);
            g.DrawRectangle(bluePen, bianjie_x-2, bianjie_y-2, fangkuang_width + 4, fangkuang_height + 4);

        }//绘制显示的边框;

为方便调试,边框的大小都是可以调整的;

3.设置每个数值对应的颜色(可省略);

设置颜色能便于判断数值的大小,提升游戏档次;

        private Color color_fore_0, color_fore_2, color_fore_4, color_fore_8, color_fore_16, color_fore_32, color_fore_64, color_fore_128, color_fore_256, color_fore_512, color_fore_1024, color_fore_2048;
        private Color color_back_0, color_back_2, color_back_4, color_back_8, color_back_16, color_back_32, color_back_64, color_back_128, color_back_256, color_back_512, color_back_1024, color_back_2048;
        private void color_fenpei()
        {
            
            color_fore_0 = Color.LightGray;
            color_fore_2 = Color.Brown;
            color_fore_4 = Color.Sienna;
            color_fore_8 = Color.SeaGreen;
            color_fore_16 = Color.LimeGreen;
            color_fore_32 = Color.MediumAquamarine;
            color_fore_64 = Color.BlueViolet;
            color_fore_128 = Color.DarkOrchid;
            color_fore_256 = Color.Blue;
            color_fore_512 = Color.Magenta;
            color_fore_1024 = Color.Crimson;
            color_fore_2048 = Color.White;
            ///
            color_back_0 = Color.LightGray;
            color_back_2 = Color.PaleGreen;
            color_back_4 = Color.LawnGreen;
            color_back_8 = Color.DarkKhaki;
            color_back_16 = Color.PaleGoldenrod;
            color_back_32 = Color.Khaki;
            color_back_64 = Color.Gold;
            color_back_128 = Color.MediumAquamarine;
            color_back_256 = Color.DarkTurquoise;
            color_back_512 = Color.DeepSkyBlue;
            color_back_1024 = Color.Pink;
            color_back_2048 = Color.Red;
        }//设置颜色;

4.添加控件;

这里我选用label标签来表示,label.text即数值的大小;

private Label[] txt_boxs = new Label[25];
private void map_show()
        {
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    Label h = new Label();
                    h.Text = Convert.ToString(map[i, j]);
                    h.Anchor = AnchorStyles.None;
                    h.AutoSize = false;
                    h.Size = new Size(60, 60);
                    h.TextAlign = ContentAlignment.MiddleCenter;
                    h.Font = new Font("Siemens AD Sans", 13.8F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
                    h.Location = new Point(j * 60 + bianjie_x, i * 60 + bianjie_y);
                    switch (map[i, j])
                    {
                        case 0:
                            h.BorderStyle = BorderStyle.None;
                            h.ForeColor = color_fore_0;
                            h.BackColor = color_back_0;
                            break;
                        case 2:
                            h.BorderStyle = BorderStyle.Fixed3D;
                            h.ForeColor = color_fore_2;
                            h.BackColor = color_back_2;
                            break;
                        case 4:
                            h.BorderStyle = BorderStyle.Fixed3D;
                            h.ForeColor = color_fore_4;
                            h.BackColor = color_back_4;
                            break;
                    }
                    //this.Controls.Add(h);
                    txt_boxs[i * 5 + j] = h;
                    this.Controls.Add(txt_boxs[i * 5 + j]);
                }
            }
        }//显示初始地图;

由于初始地图只有0、2、4三个值类型,所以只需要判断这三个值就行;

5.四个方向的移动;

四个方向的移动方法大致都是一样的,以右移为例:我们需要将每一行中的“非零”元素都移动到右侧,再去判断移动后的相邻项并从右往左合并相同的项,被合并的置0,然后再执行一遍右移清零;

        enum move_player
        {
            up,
            down,
            left,
            right
        }
        private bool move_zhongjianbiangliang;
        private move_player move_key;
        private void move()
        {
            int cs = 0;
            switch (move_key)
            {
                case move_player.up:
                    for (int y = 0; y < 5; y++)
                    {
                        for (int x = 0; x < 5; x++)
                        {
                            while (map[x, y] == 0 && cs < 5)
                            {
                                for (int i = x; i < 5; i++)
                                {
                                    if (i == 4) map[i, y] = 0;
                                    else map[i, y] = map[i + 1, y];
                                }
                                cs++;
                            }
                            if (cs > 4) { cs = 0; break; }
                            else cs = 0;
                        }
                    }
                    break;
                case move_player.down:
                    for (int y = 0; y < 5; y++)
                    {
                        for (int x = 4; x >= 0; x--)
                        {
                            while (map[x, y] == 0 && cs < 5)
                            {
                                for (int i = x; i >= 0; i--)
                                {
                                    if (i == 0) map[i, y] = 0;
                                    else map[i, y] = map[i - 1, y];
                                }
                                cs++;
                            }
                            if (cs > 5) { cs = 0; break; }
                            else cs = 0;
                        }
                    }
                    break;
                case move_player.left:
                    for (int x = 0; x < 5; x++)
                    {
                        for (int y = 0; y < 5; y++)
                        {
                            while (map[x, y] == 0 && cs < 5)
                            {
                                for (int i = y; i < 5; i++)
                                {
                                    if (i == 4) map[x, i] = 0;
                                    else map[x, i] = map[x, i + 1];
                                }
                                cs++;
                            }
                            if (cs > 4) { cs = 0; break; }
                            else cs = 0;
                        }
                    }
                    break;
                case move_player.right:
                    for (int x = 0; x < 5; x++)
                    {
                        for (int y = 4; y >= 0; y--)
                        {
                            while (map[x, y] == 0 && cs < 5)
                            {
                                for (int i = y; i >= 0; i--)
                                {
                                    if (i == 0) map[x, i] = 0;
                                    else map[x, i] = map[x, i - 1];
                                }
                                cs++;
                            }
                            if (cs > 4) { cs = 0; break; }
                            else cs = 0;
                        }
                    }
                    break;
            }
            if (move_zhongjianbiangliang == false)
            {
                move_add();
            }
            else
            {
                move_zhongjianbiangliang = false;
                map_add();
            }
        }//移动地图;
        private void move_add()
        {
            switch (move_key)
            {
                case move_player.up:
                    for (int y = 0; y < 5; y++)
                    {
                        for (int x = 0; x < 4; x++)
                        {

                            if (map[x, y] == map[x + 1, y] && map[x, y] < 2048)
                            {
                                map[x, y] += map[x + 1, y];
                                map[x + 1, y] = 0;
                            }

                        }
                    }
                    break;
                case move_player.down:
                    for (int y = 0; y < 5; y++)
                    {
                        for (int x = 4; x > 0; x--)
                        {
                            if (map[x, y] == map[x - 1, y] && map[x, y] < 2048)
                            {
                                map[x, y] += map[x - 1, y];
                                map[x - 1, y] = 0;
                            }
                        }
                    }
                    break;
                case move_player.left:
                    for (int x = 0; x < 5; x++)
                    {
                        for (int y = 0; y < 4; y++)
                        {

                            if (map[x, y] == map[x, y + 1] && map[x, y] < 2048)
                            {
                                map[x, y] += map[x, y + 1];
                                map[x, y + 1] = 0;
                            }

                        }
                    }
                    break;
                case move_player.right:
                    for (int x = 0; x < 5; x++)
                    {
                        for (int y = 4; y > 0; y--)
                        {
                            if (map[x, y] == map[x, y - 1] && map[x, y] < 2048)
                            {
                                map[x, y] += map[x, y - 1];
                                map[x, y - 1] = 0;
                            }
                        }
                    }
                    break;
            }
            move_zhongjianbiangliang = true;
            move();
        }//合并相同项;

6.生成新数字

移动操作结束后需要在空白处随机生成一个新的数字,新生成的数字只包含2或4且被设定在移动方向的最后一行或是最后一列;

        private void map_add()
        {
            Random r = new Random();
            int s = r.Next(0, 5);
            switch (move_key)
            {

                case move_player.up:
                    while (map[4, s] != 0)
                    {
                        s = r.Next(0, 5);
                    }
                    map[4, s] = map_s[s];
                    break;
                case move_player.down:
                    while (map[0, s] != 0)
                    {
                        s = r.Next(0, 5);
                    }
                    map[0, s] = map_s[s];
                    break;
                case move_player.left:
                    while (map[s, 4] != 0)
                    {
                        s = r.Next(0, 5);
                    }
                    map[s, 4] = map_s[s];
                    break;
                case move_player.right:
                    while (map[s, 0] != 0)
                    {
                        s = r.Next(0, 5);
                    }
                    map[s, 0] = map_s[s];
                    break;
            }
            map_genxin();
        }//填补移动空缺;

7.更新地图显示

以上都是对数组map进行的操作,操作结束后还需要打印在窗体中显示出来,当然我们只需要更新对应的标签文本和颜色就行了;

        private void map_genxin()
        {
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    txt_boxs[i * 5 + j].Text = Convert.ToString(map[i, j]);
                    switch (map[i, j])
                    {
                        case 0:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.None;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_0;
                            txt_boxs[i * 5 + j].BackColor = color_back_0;
                            break;
                        case 2:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_2;
                            txt_boxs[i * 5 + j].BackColor = color_back_2;
                            break;
                        case 4:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_4;
                            txt_boxs[i * 5 + j].BackColor = color_back_4;
                            break;
                        case 8:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_8;
                            txt_boxs[i * 5 + j].BackColor = color_back_8;
                            break;
                        case 16:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_16;
                            txt_boxs[i * 5 + j].BackColor = color_back_16;
                            break;
                        case 32:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_32;
                            txt_boxs[i * 5 + j].BackColor = color_back_32;
                            break;
                        case 64:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_64;
                            txt_boxs[i * 5 + j].BackColor = color_back_64;
                            break;
                        case 128:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_128;
                            txt_boxs[i * 5 + j].BackColor = color_back_128;
                            break;
                        case 256:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_256;
                            txt_boxs[i * 5 + j].BackColor = color_back_256;
                            break;
                        case 512:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_512;
                            txt_boxs[i * 5 + j].BackColor = color_back_512;
                            break;
                        case 1024:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_1024;
                            txt_boxs[i * 5 + j].BackColor = color_back_1024;
                            break;
                        case 2048:
                            txt_boxs[i * 5 + j].BorderStyle = BorderStyle.Fixed3D;
                            txt_boxs[i * 5 + j].ForeColor = color_fore_2048;
                            txt_boxs[i * 5 + j].BackColor = color_back_2048;
                            break;
                    }
                }
            }
        }//更新地图显示;

8.按键控制

游戏需要使用到的键盘操作;文章来源地址https://www.toymoban.com/news/detail-472363.html

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Up:
                    move_key = move_player.up;
                    move();
                    return true;
                case Keys.W:
                    move_key = move_player.up;
                    move();
                    return true;
                case Keys.Down:
                    move_key = move_player.down;
                    move();
                    return true;
                case Keys.S:
                    move_key = move_player.down;
                    move();
                    return true;
                case Keys.Left:
                    move_key = move_player.left;
                    move();
                    return true;
                case Keys.A:
                    move_key = move_player.left;
                    move();
                    return true;
                case Keys.Right:
                    move_key = move_player.right;
                    move();
                    return true;
                case Keys.D:
                    move_key = move_player.right;
                    move();
                    return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

到了这里,关于基于C#的2048小游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt--2048小游戏

    2048 1.功能 上下左右控制数字格子的移动 WASD 4*4 格子移动操作,加操作 开始游戏的按钮,重新游戏按钮 得分计算 判断游戏是否结束 2.源程序 代码如下(示例): MainWindow.h Main.cpp MainWindow.cpp 5.结果 以上是今天要讲的内容,练习了2048小游戏。

    2024年01月25日
    浏览(47)
  • 2048小游戏成品源码

    2048小游戏,可以自选背景颜色,方框颜色,音乐播放。 还可以展示当前玩家的排名,动态排名,及历史玩家的排名。 前期需求: 使用pygame加载目录音乐。MP3文件: 看下运行后的效果图: =========参数设置: =========背景设置: =========方块设置: ==========源码分享:

    2024年02月16日
    浏览(44)
  • c++制作小游戏2048

    完整代码来自于爱编程的柚子《【C语言/C++游戏项目】:2048小游戏,超详细教程教会你写这个小游戏。》 这个游戏用到了#include graphics.h,思路比较简单。 首先做出游戏页面,然后画出4*4的格子,利用map二维数组,依据数字{0,2,4,8,16,32,64,128,256,512,1024,2048}找到对应颜色在固定位

    2024年02月13日
    浏览(44)
  • Android期末项目2048小游戏

    Android期末项目2048小游戏。 2048属于益智类小游戏,它做到了娱乐性、趣味性、教育性相统一。益智类的游戏即是需要去开动大脑去思考从而获得游戏的胜利。简单的益智类游戏可以使玩家在娱乐中不断的开发大脑。这样一来就实现了在娱乐中学习。每次可以选择上下左右其中

    2024年02月06日
    浏览(57)
  • python快速实现2048小游戏

    《2048》是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。 操作指南: 每次可以选择上下左右其中一个方向去滑动,每滑动

    2024年02月11日
    浏览(40)
  • 【Android Studio】图形化数字游戏,小游戏2048。

    手机中的小游戏是一种在日常生活中应用广泛的休闲软件,无论是在超市商店,还是在办公室,或是家庭都有着它的身影。随着移动互联网和智能手机的不断发展和进步,当今市场上已经出现了多种简单轻松的小游戏,几乎每一位智能手机的使用者都会在种类繁多的App网站上

    2024年02月03日
    浏览(43)
  • 2048小游戏 java版(代码+注释)

            一个纯纯小白,想写点什么,也想学习一下怎么在这里写东西,就简单的写个2048小游戏。写的不好,大佬就不用看了,希望和大家交流学习,有写的不好或有更好的建议也欢迎提出来。(需要用的可直接粘贴复制)(轻喷) 目录 游戏展示 讲解  代码        

    2024年02月09日
    浏览(49)
  • 【C语言】2048小游戏【附源码】

    欢迎来到英杰社区 https://bbs.csdn.net/topics/617804998         2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现“2048”的目标。         每次移动操作,所有数字方块会朝着指定方向同时滑动,并在靠近边

    2024年04月15日
    浏览(38)
  • 用Python做一个2048小游戏

    2048的逻辑无非是操作 4 × 4 4times4 4 × 4 的方格,每个方格中有一个数,这些数可以移动,如果两个相同的数字在移动时相撞了,就可以彼此合并。 而这个 4 × 4 4times4 4 × 4 的方格,无非是一个矩阵。只需设计好移动逻辑,再用PyGame将这个方格表现出来就算大功告成。 2048只有

    2024年01月17日
    浏览(45)
  • 用JAVA写一个2048的小游戏。

    如图所示: 使用软件:eclipse2021-12版 JDK版本:JDK15.0.1 链接:https://pan.baidu.com/s/1NVWaklg9K2wRmBOLew6iMQ 提取码:ts08 1. Client.java: 2.Constant.java 3.Block.java 4.BlockLoader.java 5.Drawable.java 6.Moveable.java 7.MyFrame.java 提示:代码写的有些臃肿,其中也有一些BUG,理解源码以后可以修正。 链接:

    2024年02月10日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包