最近在玩过2048这个小游戏后感觉很有意思,想着正在学C#的winfrom的我能不能自己写一个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.按键控制

游戏需要使用到的键盘操作;

        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小游戏相关推荐

  1. 全志V853开发板移植基于 LVGL 的 2048 小游戏

    LVGL 开发实战 移植基于 LVGL 的 2048 小游戏 这一节将以一个已经编写好的 lvgl 小游戏 2048 描述如何将已经编写完成的 lvgl 程序移植到开发板上. 这里使用的 2048 小 ...

  2. java 2048游戏_JAVA2048游戏 本课程设计是基于java语言的2048小游戏设计 联合开发网 - pudn.com...

    JAVA2048游戏 所属分类:游戏 开发工具:Java 文件大小:789KB 下载次数:4 上传日期:2020-11-23 10:57:11 上 传 者:滴滴滴大萌 说明:  本课程设计是基于jav ...

  3. python里graphics的使用_使用graphics.py实现2048小游戏

    1.过年的时候在手机上下载了2048玩了几天,心血来潮决定用py写一个,刚开始的时候想用QT实现,发现依赖有点大.正好看到graphics.py是基于tkinter做的封装就拿来练手,并借用了CSDN ...

  4. ​.NET手撸2048小游戏

    前言 2048是一款益智小游戏,得益于其规则简单,又和 2的倍数有关,因此广为人知,特别是广受程序员的喜爱. 本文将再次使用我自制的"准游戏引擎" FlysEngine,从空白窗口 ...

  5. c语言2048代码linux,C语言2048小游戏课设(附源码).doc

    PAGE PAGE 1 C语言2048小游戏课设 项目说明 本系统基于C语言开发,适用于刚入门的C语言新手项目课设,开发软件采用VC++6.0开发,VS,DEV C++等均可运行.(书生) 项目运行截 ...

  6. 用App Designer 制作2048小游戏

    用App Designer 制作2048小游戏 用App Designer制作的2048,MATLAB版本是2020b.记录下创作思路,以免日后忘记. APP界面设计 APP界面如下,为了好玩,还加入 ...

  7. 从全球最大同性交友网站抄了一份不一样的2048小游戏

    大家好,我是"前端点线面",一位新生代农民工,欢迎关注我获取最新前端知识和<前端百题斩>pdf版(包括JS基础篇.浏览器篇.网络篇共计50个章节,5万多字),此外有喜欢 ...

  8. Swift实战之2048小游戏

    上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完 ...

  9. Java课设 2048小游戏

    题目:2048小游戏 目录 1. 引言 2. 主要模块设计 1)游戏面板 2)移动 3)失败 4)新游戏 5)退出 3. 系统实现 1)游戏面板 2)移动 3)失败 4)新游戏 5)退出 4. 结论 ...

最新文章

  1. oracle 条件查询,比较运算符,逻辑运算符,特殊运算符,判断空值,大小写敏感,多行,多列子查询...
  2. ifstream 打开中文路径乱码问题处理
  3. 问题 F: 积木大赛(模拟)
  4. 随便玩玩之PostgreSQL(第一章)PostgreSQL简介
  5. Linux驱动(3)--单片机驱动与Linux驱动的区别
  6. 计算机 图论基础知识,计算机基础知识
  7. 详解 ASP.NET并行,异步,多线程
  8. Ajax与jQuery异步加载数据
  9. JAVA运行环境设置
  10. java中的 关键词vali_Java中的关键字volatile详解
  11. 【单片机】RGB和RGBW LED灯珠的区别
  12. c语言编译器 mini,Mini C编译器的设计与实现.ppt
  13. secondary namenode 检查点
  14. MVVM?瞎搞一波?
  15. 艰难抉择,WPS和Office哪个好?
  16. ionic自定义图标
  17. C语言实现万年历系统
  18. cmake详细教程(经验版)
  19. 《人性的弱点》良句收录和读后感想
  20. 一支口红用了5年_一支口红用多久最好 口红一般用多久

热门文章

  1. 一个 Vue 页面的内存泄露分析
  2. 初识Protobuf协议
  3. Qt/C++ + opengl 解析stl文件(二进制和Ascii两种格式)
  4. 图像边缘提取 java_提取图像边缘
  5. 使用python第三方库turtle和datetime来制作动态罗马数字时钟
  6. opencv读取四通道图像
  7. 人工智能建筑设计方案,人工智能与建筑设计
  8. 你这 Saga 事务保“隔离性”吗?
  9. 智维数据加入信创工委会,助力国产化智能运维自主创新
  10. con not set com.xxx field com.xxx to com.sun.proxy.$proxy23问题