新書推薦:
《
Python贝叶斯深度学习
》
售價:HK$
91.8
《
文本的密码:社会语境中的宋代文学
》
售價:HK$
69.0
《
启微·狂骉年代:西洋赛马在中国
》
售價:HK$
80.5
《
有趣的中国古建筑
》
售價:HK$
68.8
《
十一年夏至
》
售價:HK$
78.2
《
如何打造成功的商业赛事
》
售價:HK$
91.9
《
万千教育学前·透视学前儿童的发展:解析幼儿教师常问的那些问题
》
售價:HK$
59.8
《
慈悲与玫瑰
》
售價:HK$
89.7
|
內容簡介: |
C#是当今使用最为频繁的编程语言之一,一直在开发领域中占据重要的地位。本书通过12个综合案例的实现过程,详细讲解C#在实践项目中的综合运用过程,这些项目从作者的学生时代写起,到项目经理结束,一直贯穿于作者最重要的开发时期。
第1章讲解一个俄罗斯方块游戏的具体实现流程;第2章讲解多媒体学习社区系统的具体实现流程;第3章讲解大东科技人事管理系统的具体实现流程;第4章讲解在线留言簿系统的具体实现流程;第5章讲解浪漫满屋通信录系统的具体实现流程;第6章讲解在线点歌系统的具体实现流程;第7章讲解在线商城系统的具体实现流程;第8章讲解一个企业交互系统的具体实现流程;第9章讲解一个餐饮管理系统的具体实现流程;第10章讲解一个短信群发系统的具体实现流程。第11章讲解超市进销存系统的具体实现流程;第12章讲解家庭视频监控系统的具体实现流程。
在具体讲解每个实例时,都遵循项目的进度来展开,从接到项目到具体开发,直到最后的调试和发布。内容循序渐进,并穿插学习技巧和职场生存法则,引领读者全面掌握C#。
本书不但适合C#初学者阅读,也可供有一定C#基础的读者学习,亦可作为有一定造诣的程序员的参考书。
|
目錄:
|
目 录
第1章 俄罗斯方块游戏1
1.1 赢在规划2
1.1.1 赢在起点——程序员的职业
规划2
1.1.2 赢在项目开发伊始——做好
项目分析2
1.2 第一个项目4
1.3 功能描述4
1.3.1 功能模块分析6
1.3.2 游戏的模块结构6
1.3.3 游戏的运行流程6
1.4 搭建开发平台7
1.4.1 安装Visual Studio 20137
1.4.2 规划项目文件9
1.5 界面设计10
1.5.1 制作游戏窗体11
1.5.2 窗体元素设置文件14
1.6 具体编码18
1.6.1 事件处理程序18
1.6.2 游戏控制、处理方法21
1.7 测试运行36
第2章 多媒体学习社区37
2.1 修炼自身38
2.1.1 “码农”和“高大上”38
2.1.2 赢在自身——快速提升自身
修养38
2.2 开发背景简介40
2.3 系统设计分析40
2.3.1 互动媒体学习社区的优势40
2.3.2 系统的特点41
2.3.3 系统目标41
2.3.4 确定设计方案——BS体系
结构42
2.4 需求分析42
2.4.1 可行性分析43
2.4.2 功能分析43
2.4.3 业务流程44
2.5 总体设计44
2.6 系统预览46
2.7 构建开发环境47
2.8 数据库设计48
2.8.1 概念设计48
2.8.2 实体E-R图49
2.8.3 逻辑设计50
2.9 设计文件夹组织结构和功能模块53
2.9.1 文件组织结构的设计53
2.9.2 用户功能模块设计54
2.10 公共类的设计57
2.10.1 数据库操作类的设计57
2.10.2 业务功能类设计60
2.11 网站首页设计62
2.12 实现用户注册模块63
2.12.1 login.aspx页面部分代码
分析64
2.12.2 用户登录设计64
2.13 发布并管理教程66
2.13.1 发布教程68
2.13.2 查看教程页设计70
2.14 后台管理页面的设计71
2.14.1 实现用户管理的页面72
2.14.2 视频管理模块设计73
2.15 系统测试74
第3章 大东科技人事管理系统77
3.1 程序员职场生存必杀技78
3.1.1 程序员的生存现状78
3.1.2 中外IT领域的企业文化78
3.1.3 赢在职场——修炼程序员
职场秘籍79
3.2 系统介绍81
3.2.1 系统背景介绍82
3.2.2 应用的目的与意义82
3.2.3 人事管理系统的发展趋势83
3.3 系统需求分析83
3.4 系统设计85
3.4.1 系统设计目标85
3.4.2 系统功能设计86
3.5 数据库设计89
3.5.1 数据库描述89
3.5.2 数据库分析89
3.5.3 数据库概念设计89
3.6 实现公共类94
3.6.1 实现MyMeans公共类94
3.6.2 实现MyModule公共类96
3.7 实现用户登录模块104
3.7.1 登录模块技术分析104
3.7.2 具体实现105
3.8 主窗体详细设计106
3.8.1 主窗体技术分析107
3.8.2 具体实现108
3.9 实现人事档案浏览模块112
3.10 实现人事资料查询模块133
3.10.1 人事资料查询窗体的技术
分析133
3.10.2 具体实现133
第4章 在线留言簿系统139
4.1 企业沟通之道140
4.1.1 开发公司的部门现状140
4.1.2 赢在职场——探讨部门之间的
沟通之道141
4.2 第一个盈利项目142
4.2.1 组建团队142
4.2.2 系统规划142
4.3 系统概述和总体设计143
4.3.1 在线留言簿模块的功能
原理143
4.3.2 在线留言簿系统的构成
模块144
4.4 规划系统文件144
4.4.1 规划文件144
4.4.2 选择开发工具145
4.5 设计数据库145
4.5.1 后台数据库及数据库访问
接口的选择145
4.5.2 数据库结构的设计145
4.6 系统配置和数据库访问层146
4.6.1 系统配置146
4.6.2 数据库访问层设计149
4.7 具体编码155
4.7.1 留言数据显示155
4.7.2 留言分页列表显示模块159
4.7.3 留言回复模块162
4.7.4 添加留言信息模块164
4.7.5 留言管理模块165
4.8 测试运行168
第5章 浪漫满屋通信录系统171
5.1 体验语言之美172
5.1.1 程序员经常忽视的问题172
5.1.2 赢在程序自身——体现
代码之美172
5.2 新的项目173
5.2.1 系统分析174
5.2.2 系统目标174
5.3 功能模块划分175
5.4 设计窗体176
5.4.1 设置和启动应用程序176
5.4.2 设计用户界面178
5.4.3 实现三维动画效果182
5.4.4 遍历窗体可视化树183
5.4.5 添加联系人184
5.4.6 实现多媒体188
5.4.7 添加图片189
5.4.8 保存联系人资料190
5.5 系统测试193
第6章 在线点歌系统197
6.1 架构中的可扩展性198
6.1.1 软件的发展是一个不断完善的
过程198
6.1.2 赢在项目本身——让程序具有
更好的可扩展性198
6.2 系统分析199
6.2.1 背景介绍199
6.2.2 需求分析200
6.2.3 可行性分析200
6.2.4 编写项目计划书201
6.3 系统模块划分203
6.4 设计数据库203
6.4.1 数据库概念结构设计204
6.4.2 数据库逻辑结构的设计206
6.5 设计公共类207
6.5.1 数据库连接207
6.5.2 歌曲信息参数208
6.5.3 歌曲信息操作处理209
6.6 设计窗体213
6.7 具体编码工作217
6.7.1 登录验证模块217
6.7.2 后台维护模块218
6.7.3 明星管理模块221
6.7.4 系统点歌模块226
6.7.5 歌曲信息模块228
6.7.6 播放歌曲模块232
6.8 项目调试234
6.9 系统升级236
6.9.1 功能升级——升级前的
思考236
6.9.2 增加维护歌曲信息模块237
6.9.3 增加维护明星信息模块239
6.9.4 以“人性化”为目标的功能
升级240
6.10 数据库工具升级245
6.10.1 导入数据245
6.10.2 修改连接程序246
6.10.3 用OleDbConnection对象
连接OLE DB数据源248
第7章 在线商城系统249
7.1 模块化编程250
7.1.1 谈模块化设计思想250
7.1.2 赢在模块化思想——实现
高内聚和低耦合的代码251
7.2 新的项目253
7.3 项目规划分析254
7.4 规划项目文件254
7.5 系统配置文件255
7.6 搭建数据库256
7.6.1 数据库的设计257
7.6.2 设置系统参数259
7.7 数据访问层260
7.7.1 商品显示260
7.7.2 订单处理265
7.7.3 商品评论272
7.7.4 商品分类275
7.7.5 商品管理285
7.8 显示商品287
7.8.1 主框架页288
7.8.2 顶部导航页面288
7.8.3 左侧导航——分类列表
页面289
7.8.4 右侧导航——商品列表
页面289
7.8.5 按被点击次数显示290
7.8.6 按商品名称显示模块292
7.8.7 商品详情页面293
7.9 商品分类处理295
7.9.1 设置分类的层次结构296
7.9.2 添加分类模块298
7.9.3 分类修改模块299
7.9.4 分类管理模块300
7.10 商品管理302
7.10.1 商品添加模块302
7.10.2 商品修改模块303
7.10.3 商品管理列表模块305
7.10.4 商品图片修改模块306
7.11 购物车310
7.11.1 购物车组件的设计310
7.11.2 购物车商品添加模块315
7.11.3 购物车管理316
7.12 订单处理319
7.12.1 生成订单编号319
7.12.2 提交并创建新订单320
7.12.3 查看订单详情322
7.12.4 订单列表模块323
7.12.5 订单状态处理模块324
7.13 商品评论模块326
7.13.1 评论显示模块327
7.13.2 评论管理模块327
7.14 商品搜索模块329
7.15 项目调试330
第8章 企业交互系统333
8.1 程序的可移植性334
8.1.1 什么是程序的可移植性334
8.1.2 赢在项目——实现跨开发
平台的转换334
8.2 新的挑战335
8.3 项目规划和分析336
8.3.1 在线交互系统的背景336
8.3.2 企业在线交互系统的构成
模块336
8.4 规划项目文件338
8.5 系统配置文件338
8.6 搭建数据库339
8.6.1 数据库设计340
8.6.2 系统参数设置文件343
8.7 数据访问层344
8.7.1 数据访问层——用户登录
验证344
8.7.2 数据访问层——客户分组348
8.7.3 数据访问层——团队模块353
8.8 实现身份验证模块357
8.8.1 用户登录验证模块357
8.8.2 登录用户注销模块359
8.9 客户分组处理模块359
8.9.1 用户分组添加模块360
8.9.2 用户分组修改模块360
8.9.3 用户组管理列表模块362
8.9.4 客户检索模块363
8.9.5 客户管理列表模块366
8.9.6 客户移动转换模块367
8.9.7 客户信息显示模块369
8.10 系统团队处理模块370
8.10.1 添加团队模块370
8.10.2 修改团队处理模块371
8.10.3 团队管理列表模块372
8.10.4 加入团队处理模块374
8.11 在线交互模块375
8.11.1 系统主页显示模块376
8.11.2 一对一交互处理模块377
8.11.3 团队交互处理模块379
8.11.4 文件发送模块383
8.12 项目调试388
第9章 餐饮管理系统391
9.1 考虑所有可能会发生的情形392
9.1.1 一段代码所引发的思考392
9.1.2 赢在项目——提高程序的
健壮性392
9.2 新的项目394
9.3 项目规划分析395
9.3.1 开发背景395
9.3.2 项目模块分析395
9.3.3 构成模块395
9.4 搭建数据库396
9.4.1 数据库概念设计396
9.4.2 数据库逻辑结构设计398
9.5 设计窗体400
9.6 具体编码402
9.6.1 数据库连接402
9.6.2 登录模块403
9.6.3 主窗体模块404
9.6.4 开台模块410
9.6.5 点菜模块412
9.6.6 结账模块418
9.6.7 员工管理模块420
9.6.8 修改密码模块423
9.6.9 桌台信息模块426
9.7 项目调试431
第10章 短信群发系统435
10.1 做好项目管理者436
10.1.1 软件工程师到项目管理者
之路436
10.1.2 赢在管理——运转一个高效
的开发团队436
10.2 做好需求分析439
10.2.1 开发背景439
10.2.2 需求分析440
10.3 项目规划440
10.3.1 系统目标441
10.3.2 划分功能模块441
10.3.3 规划运作流程441
10.4 搭建数据库443
10.4.1 数据库E-R图分析443
10.4.2 数据表的结构444
10.5 设计公共类446
10.5.1 ConnClass类447
10.5.2 GSM类447
10.6 具体编码454
10.6.1 登录验证模块454
10.6.2 主窗体模块456
10.6.3 短信群发模块459
10.6.4 短信接收模块463
10.6.5 电话簿管理模块468
10.6.6 常用短语管理模块471
10.6.7 修改密码模块474
10.7 项目调试476
第11章 超市进销存系统479
11.1 算法是程序的灵魂480
11.1.1 什么是算法480
11.1.2 赢在技术沉淀——计算机
中的算法481
11.2 新的项目484
11.3 系统需求分析484
11.3.1 系统背景介绍485
11.3.2 功能模块划分485
11.4 规划和运作486
11.4.1 规划系统文件486
11.4.2 运作流程487
11.5 设计数据库487
11.5.1 数据库的概念设计487
11.5.2 逻辑结构设计489
11.6 设计公共类492
11.7 具体编码502
11.7.1 用户登录模块502
11.7.2 主窗体模块503
11.7.3 进货管理模块506
11.7.4 进货查询模块510
11.7.5 商品销售管理模块512
11.7.6 退货管理模块515
11.7.7 库存管理模块517
11.7.8 库存查询模块519
11.7.9 数据备份模块520
11.8 项目调试522
第12章 家庭视频监控系统525
12.1 走向架构师之路526
12.1.1 什么是架构师526
12.1.2 赢在架构——如何成为一名
架构师526
12.1.3 赢在架构——如何成就一个
美丽的架构527
12.2 新的项目528
12.3 需求分析529
12.3.1 系统背景介绍529
12.3.2 系统需求529
12.3.3 可行性分析529
12.3.4 编写项目计划书530
12.4 系统设计532
12.5 数据库设计533
12.5.1 数据库分析533
12.5.2 数据库的概念设计533
12.5.3 数据库的逻辑结构设计533
12.6 设计公共类534
12.6.1 DataCon类534
12.6.2 DataOperate类535
12.6.3 SoftReg类535
12.6.4 类VideoOperate538
12.6.5 类PelcoD540
12.7 具体编码542
12.7.1 登录模块542
12.7.2 视频监控模块543
12.7.3 监控管理模块551
12.7.4 录像回放模块553
12.8 项目调试554
|
內容試閱:
|
第1章 俄罗斯方块游戏
俄罗斯方块游戏是一款曾经风靡全球的电视游戏机和掌上游戏机游戏产品,它造就过令人惊奇的商业价值,影响过一代游戏产业链。
这款游戏最初是由苏联的游戏制作人Alex Pajitnov制作的,它看似简单,却变化无穷,令人玩起来上瘾。
本章将介绍如何在Visual Studio 2013环境下开发一款俄罗斯方块游戏,从而使读者能够迅速了解使用Visual Studio 2013集成开发环境创建小型、简单游戏的方法。
在开发过程中,读者将可以体验到C#所具有的强大功能,并熟悉其可视化的编程方式。
001走进C#的世界
002.NET Framework简介
003几个重要的概念
004C#的地位
005C#与Java、C++的关系
006C#的基本语法
007C#的数据类型
008基本类型
009给变量命名
010变量的声明和赋值
1.1 赢 在 规 划
光盘:视频\第1章\赢在规划.avi
当一名程序员从实习生开始做起,依次经历码农、软件工程师、架构师、CTO等职位的磨砺后,蓦然回首,会发现自己的成功并非偶然!如果需要总结出自己的成功秘诀,那么秘诀就是“比别人更加细致地做工作”。
在众多应届毕业生中,我们要想胜出,就要坦然面对职场竞争,作为刚刚步入职场的程序员,应该从细节上为自己的成功做好准备,这里的细节就是指职业规划。良好的职业规划决定了程序员以后的发展方向和具体轨迹,沿着规划的足迹行走的人,其成功率要远远高于那些好似“无头苍蝇”的迷茫者。
1.1.1 赢在起点——程序员的职业规划
通常来说,程序开发人员的职业发展有如下所示的几个选择:
* 专注于技术,成为技术专家。
* 转型到技术型销售、技术支持等。
* 随着技术的成长,从技术性管理走向高级管理。
上述三个方向是都能看得很清楚的,并且这三个方向都是以技术为基础的。在扎实的技术基础上,如果有比较强的抽象设计能力,而且又打算专注于技术开发,则做架构师是一个不错的选择;如果待人接物能力突出,善于跟客户打交道,则可以转型到销售部门,做技术支持;如果性格更适合于管理,情商表现很突出,则技术管理岗位乃至高级管理岗位应该是下一步的方向。
所以,对于已经工作两年以上的程序员来说,一般可以有几种基本的职业选择:技术专家、软件架构师、实施顾问或销售。并且,无论是C、C++、C#、Java、.NET还是数据库领域,都要首先成为专家,然后才可能继续发展为架构师。尽管架构师的职位待遇优厚,可以工作一辈子,但这种工作职位是很有限的,目前在我国的IT行业中,对架构师的条件要求比较苛刻,且并不是很合理的,与国际上同行业的现状相比,是有一定差距的。
1.1.2 赢在项目开发伊始——做好项目分析
很多开发者,特别是一些初级开发者,写程序时,总是在看到功能需求后,就立即投入到代码编写工作中,需要什么功能,就编写函数去一一实现。
按照这种习惯做事情,在后期调试时,却总会出现这样或那样的错误,可能需要返工,重新做大量的修改。
幸运的是,初学者所接触到的,一般都是小项目,修改的工作量也不是很大。
但是,如果在大型项目中,要对几千行代码返回修改,则是一件很恐怖的事情!
可见,提前做好项目分析和规划是非常重要的。
一个软件项目的开发主要分为5个阶段,分别是需求分析阶段、设计阶段、编码阶段、测试阶段和维护阶段。这里,需求分析阶段所得到的结果,是软件项目开发中其他4个阶段的必备条件。从以往的经验来看,需求分析中的一个小小的偏差,就可能导致整个项目无法达到预期的效果,或者说,可能导致最终开发出的产品不是用户所需要的。
软件需求分析的任务,不是确定系统是怎样完成工作的,而是确定系统必须完成哪些工作,也就是对目标系统提出完整、准确、清晰、具体的要求。它所做的工作是深入描述软件的功能和性能,确定软件设计的限制,以及软件同其他系统的接口细节,定义软件的其他有效性要求。
我们可以把软件需求分析的过程具体分为4个阶段,分别是对问题的识别、分析与综合、制定规格说明和评审。
1. 对问题的识别
对问题的识别是指系统分析人员研究可行性分析报告和软件项目实施计划,确定目标系统的综合要求,并提出这些需求实现的条件,以及需要达到的标准。这些需求主要分为功能性需求和非功能性需求两种,具体如下。
1功能需求:列举出所开发的软件在功能上应具备什么。
2性能需求:给出所开发软件的技术性能指标,如存储容量限制、运行时间限制、安全保密性要求等。
3环境需求:软件系统运行时所处环境的要求。如硬件方面的机型、外部设备、数据通信接口;软件方面的系统软件包括操作系统、网络软件、数据库管理系统;使用方面的部门制度、操作人员的技术水平等。
4可靠性需求:对所开发的软件在投入运行后不发生故障的概率按实际的运行环境提出要求。所以对于重要的软件,或是运行失效会造成严重后果的软件,应提出较高的可靠性要求。
5安全保密要求:应当在这方面恰当地做出规定,对所开发的软件给予特殊的设计,使其在运行中的安全保密性能得到必要的保证。
6用户界面需求:为用户界面细致地规定应该达到的要求。
7资源使用需求:开发的软件在运行时和开发时所需要的各种资源。
8 软件成本消耗和开发进度需求:在软件项目立项后,要根据合同规定,对软件开发的进度和各步骤的费用提出要求,作为开发管理的依据。
9 预先估计以后系统可能达到的目标,这样,可以比较容易对系统进行必要的补充和修改。除了这些必需的需求,问题识别的另一个工作是建立分析所需要的通信途径,以保证能顺利地对问题进行分析。
2. 分析与综合
分析与综合的目标,是给出目标系统的详细逻辑模型。在此步骤中,分析和综合工作需反复地进行。
3. 制定规格说明
需要编制需求分析文档,这种文档又称为软件需求规格说明书。除了编写软件需求规格说明书之外,还要制定数据要求说明书,以及编写初步的用户手册。
4. 评审
需求分析评审,是指在需求分析的最后一步,对系统功能的正确性、完整性和清晰性以及其他需求给予评价。
1.2 第一个项目
光盘:视频\第1章\第一个项目.avi
在做一个项目之前,一定要做好构思和规划工作,并根据需要制定开发流程。本项目的开发流程如图1-1所示。
图1-1 本项目的开发流程
对于初次开发完整软件项目的程序员来说,开发的第一个项目十分重要。在开发伊始,可能会信心不足。此时,就需要建立充分的自信心。
作为一名程序员,面对项目时,我们要仔细分析,想法尝试,想法去实现,这样才能进步,才能找到自己的不足。
1.3 功 能 描 述
光盘:视频\第1章\功能描述.avi
在程序员开发一个应用系统之前,需要彻底弄清这个应用系统的使用过程和必备的具体功能。几乎所有的程序员都会知道这一点,但是绝大多数开发者都对此不重视,认为太基本、太简单和太理所当然。
在此我们提醒开发人员,一定要重视市场调研工作。因为市场的发展是瞬息万变的,一夜之间可能会诞生很多的新奇好用的应用。
所以,要想更好地做好俄罗斯方块游戏项目的功能分析工作,需要将这款游戏彻底试玩几次,全面了解俄罗斯方块游戏的具体玩法。
为此,作者专门从网上下载了一款俄罗斯方块游戏,并详细地进行了试玩。
其游戏界面效果如图1-2所示。很华丽,是不是?我们将取其精华,做个简单的。
根据俄罗斯方块游戏的游戏规则和要求,可以总结出俄罗斯方块游戏的基本功能模块。当然,因为俄罗斯方块游戏是一款在市面中流行多年的游戏,所以游戏的基本玩法和功能大家都耳熟能详。这就有利于在项目规划伊始进行玩法规划设计。显然,这是一个比较“庞大”的工程,相关的要点将在接下来的内容中进行讲解。
图1-2 某款俄罗斯方块游戏的界面
1由软件项目的开发流程,可以做出一个简单的项目规划书,整个规划书分为如下两个部分:
* 系统需求分析。
* 结构规划。
2俄罗斯方块游戏项目的具体开发流程如图1-3所示。
图1-3 俄罗斯方块游戏项目的具体开发流程
* 功能分析:分析整个系统所需要的功能。
* 结构规划:规划系统中所需要的功能模块。
* 总体设计:分析系统处理流程,探索系统核心模块的运作。
* 数据结构:设计系统中需要的数据结构。
* 规划函数:预先规划系统中需要的功能函数。
* 具体编码:编写系统的具体实现代码。
1.3.1 功能模块分析
本项目实例的主要功能就是控制游戏的运行,实现游戏的完整过程。具体来说,主要包括如下功能模块。
1 游戏运行界面:供用户在可视平台下控制游戏。
2 游戏控制菜单:可以控制游戏的开始、退出和级别选择。
3 设置菜单:可以设置游戏的显示样式,并提供游戏帮助等信息。
1.3.2 游戏的模块结构
游戏的模块结构如图1-4所示。
图1-4 游戏的模块结构
1.3.3 游戏的运行流程
具体的运行流程如图1-5所示。
图1-5 具体的运行流程
1.4 搭建开发平台
光盘:视频\第1章\搭建开发平台.avi
一款好的开发工具能够决定整个项目进展的顺利性。但是长久以来,我们一直很困惑,因为Visual Studio .NET已经推出好几个版本,市面中最流行的是Visual Studio 2010,而当前最新的版本是Visual Studio 2013。
工具的不断更新虽然提升了开发效能,但也提高了学习成本。本项目将使用Visual Studio 2013工具开发,这样可以体验Visual Studio 2013的最新功能。
1.4.1 安装Visual Studio 2013
在安装Visual Studio 2013之前,需要先明确如下硬件要求:
* 最好有酷睿II 2.0GHz以上的CPU。
* 至少应有2GB的RAM内存,其中1GB用于维持操作系统运行。
* 至少10GB的硬盘空间。
Visual Studio 2013的具体安装步骤如下所示。
1将安装盘放入光驱,或双击存储在硬盘内的安装文件autorun.exe,弹出“开始安装”界面,如图1-6所示。
2在出现的“安装路径”界面中选择安装路径,并勾选“同意安装条款”选项,单击“下一步”按钮,进入安装起始页界面,在这里选择将要安装的功能,如图1-7所示。在此建议全部选中,避免以后安装时遇到不可预知的麻烦。
图1-6 “开始安装”界面 图1-7 选择安装的功能
3单击“安装”按钮,出现安装进度界面,开始安装,如图1-8所示。
4安装完成后,出现“重启”界面,在该界面中单击“立即重新启动”按钮。
5重启后,将会继续安装,进度完成后,将完成所有的安装工作,如图1-9所示。
图1-8 安装进度界面图1-9 安装成功
6完成安装后,可以从“开始”菜单中启动Visual Studio 2013,如图1-10所示。
图1-10 启动Visual Studio 2013
首次打开安装后的Visual Studio 2013时,将会弹出“选择默认环境设置”对话框,如图1-11所示。本书中用C#开发ASP.NET程序,所以选择“Visual C#开发设置”选项。
然后单击“启动Visual Studio”按钮,开始加载用户环境设置,如图1-12所示。
图1-11 “选择默认环境设置”对话框图1-12 加载用户环境设置
配置完成后,将来到Visual Studio 2013的集成开发界面,如图1-13所示。
图1-13 Visual Studio 2013默认的集成开发界面
1.4.2 规划项目文件
安装Visual Studio 2013之后,发现比以往版本的界面好看了,具体增强的功能还得在后面的使用中才能体会到。接下来,需要新建一个名为“youxi”的窗体项目文件。并新建项目中需要的程序文件,在VS资源管理器中的效果如图1-14所示。
图1-14 实例中资源管理器的效果
各个构成文件的具体说明如下。
* 文件Form1.cs:是项目的窗体文件,项目运行后,将调用各窗体元素的对应属性来显示窗体,并且设置各控件的对应事件处理程序。
* 方法定义文件you.cs:功能是使用C#设计项目所需要的各种功能方法,当其他文件需要时,只需调用方法的文件名即可。
* 文件Program.cs:是整个项目的入口文件。
* 文件Form1.Designer.cs:设置窗体各控件和组件的属性。
历时两天,确定好了整个项目的功能模块,做好了整体规划,并选好开发工具开始开发了。这几天体会到总体设计是一个项目的开始,也是后续工作得以顺利进行的前提。所以在此阶段应当是一丝不苟的,考虑到一切影响因素,尽量为后续工作打好坚实的基础。这样看似前面的工作使用了较多的时间,但实际上是节约了后面的时间。总结完毕之后,决定早点休息,为接下来的界面设计养精蓄锐。
1.5 界 面 设 计
光盘:视频\第1章\界面设计.avi
界面设计是实现窗体项目的第一个步骤,需要在Visual Studio 2013窗体中插入布局控件。系统窗体界面是项目运行后显示的界面,也是游戏的运行界面,用户可以在此窗体上实现对游戏的控制。
使用Visual Studio 2013可以轻松地实现对游戏窗体界面的设计。在界面设计的过程中,需要遵循软件用户界面的设计原则。
软件用户界面Software User Interface是指软件用于同用户交流的外观、部件和程序等。软件界面的设计,既要从外观上进行创意以达到吸引眼球的目的,又要符合图形和版面设计的相关原理。
通常来讲,软件用户界面的设计应遵循以下几个基本原则。
1面向用户User-oriented
设计软件首先要明确到底谁是使用者,要站在用户的观点和立场上来设计软件。要做到这一点,必须要与用户进行沟通,了解他们的需求、目标、期望和偏好等。界面的设计者要清楚,用户之间差别很大,他们的能力各有不同。另外,用户使用的计算机机器配置也是千差万别的,包括显卡、声卡、内存、操作系统等都可能不同。设计者如果忽视了这些差别,设计出的程序在不同机器上的表现就会比较混乱。
2KISSKeep It Simple and Stupid
KISS原则就是Keep It Sample and Stupid简单明快,简洁和易于操作是设计的最重要的原则。毕竟,软件建设出来是为普通人群服务的,没有必要在界面上设置过多的操作。该原则一般的要求是减少大幅图片和动画的使用,确保操作尽量简单,并且有明确的操作提示,软件所有的内容和服务都在显眼处向用户做出说明等。
3布局控制
在界面布局方面,很多设计者重视不够,界面设计得过于死板。如果界面布局凌乱,堆砌了大量的信息,就会干扰正常使用。
4色彩的搭配和文字的可阅读性
颜色是影响界面的重要因素,不同的颜色对人的感觉有不同的影响,例如,红色和橙色使人兴奋和心跳加快,黄色使人联想到阳光,是一种快活的颜色,黑色显得比较庄重。
为方便阅读软件上的信息,可以参考报纸的编排方式,将软件内容分栏设计。
另一种能够提高文字可读性的因素是所选择的字体,通用的字体Arial、Courier New、Garamond、Times New Roman、中文宋体等最易阅读,适合用于正文。特殊字体用于标题效果较好,但是不适合正文。如果在整个界面中使用很多特殊字体如 Cloister、Gothic、Script、Westminster、华文彩云、华文行楷,则人们阅读起来感觉一定会很糟糕,会使阅读颇为费力,眼睛很快就会疲劳,不得不转移到其他界面。
5和谐一致性
通过对软件的各种元素颜色、字体、图形、空白等使用一定的规格,使得设计良好的界面看起来显得和谐。
或者说,软件的众多单独界面应该看起来像一个整体。
软件设计上要保持一致性,这是很重要的一点。
一致性的结构设计可以让浏览者对软件的形象有深刻的记忆,一致的导航设计可以让浏览者迅速而又有效地进入软件中自己所需要的部分,一致的操作设计可以让浏览者快速学会在整个软件中的各种功能操作。如果破坏这一原则,就会误导浏览者,并且让整个软件显得杂乱无章,给人留下不良的印象。
6个性化
①符合网络文化
企业软件不同于传统的企业商务活动,要符合Internet网络文化的要求。整个互联网的文化是一种休闲的、非正式性的、轻松活泼的文化。
在软件上使用幽默的网络语言,可以创造出一种休闲的、轻松愉快的、非正式的氛围,会使软件的访问量大增。
②塑造软件个性
软件的整体风格和整体气氛表达要与企业形象相符合,并应该很好地体现企业CI。
在这方面,比较经典的案例有:可口可乐个性鲜明的前卫软件Life Tastes Good;工整、全面、细致的通用电气公司软件We bring good things to lifeGE带来美好的生活;崇尚科技创新文化的3M公司软件Creating solutions for business, industry and home等。
在接下来的内容中,将遵循上述界面设计原则,创建俄罗斯方块游戏软件的界面。
1.5.1 制作游戏窗体
本游戏项目窗体界面的设计过程如下。
1打开Visual Studio 2013,新建一个名为“youxi”的Windows窗体应用程序,“新建项目”界面如图1-15所示。
2根据面向用户的设计原则,从工具箱中依次将4个Button控件和1个TrackBar控件拖入窗体中,各控件从上到下的具体设置如下。
* 第一个Button控件:设置name属性为“buttonReplay”,Text属性为“重新开始”,设置其Click事件为“buttonReplay_Click”。
* 第二个Button控件:设置name属性为“buttonSave”,Text属性为“保存”,设置其Click事件为“buttonSave_Click”。
* 第三个Button控件:设置name属性为“buttonLoad”,Text属性为“载入”,设置其Click事件为“buttonLoad_Click”。
* 设置TrackBar控件控件:设置name属性为“trackBarReviewSpeed”,Maximum属性为“15”,Minimum属性为“1”,设置其Scroll事件为“trackBar1_Scroll”。
* 第四个Button控件:设置name属性为“buttonReview”,Text属性为“Review”,设置其Click事件为“buttonReview_Click”。
图1-15 新建Windows窗体应用程序
设置完毕后的窗体界面效果如图1-16所示。
图1-16 窗体界面的效果
3为了方便用户灵活地使用软件,从工具箱中拖入MenuStrip控件到窗体顶部,并分别设置“文件”、“设置选项”和“游戏帮助”这3个菜单,如图1-17所示。
图1-17 设置主菜单
4设置主菜单中的各个菜单命令,首先设置“文件”菜单,在其下面设置6个菜单项。从上到下各个菜单项的具体信息如下。
* 第一个菜单项:设置name属性为“replayToolStripMenuItem”,Text属性为“重新开始”,设置其Click事件为“replayToolStripMenuItem_Click”。
* 第二个菜单项:设置name属性为“replayExtendedToolStripMenuItem”,Text属性为“ReplayExtended”,设置其Click事件为“replayExtendedToolStripMenuItem_ Click”。
* 第三个菜单项:设置name属性为“saveToolStripMenuItem”,Text属性为“Save”,设置其Click事件为“saveToolStripMenuItem_Click”。
* 第四个菜单项:设置name属性为“loadToolStripMenuItem”,Text属性为“Load”,设置其Click事件为“loadToolStripMenuItem_Click”。
* 第五个菜单项:设置name属性为“reviewToolStripMenuItem”,Text属性为“Review”,设置其Click事件为“reviewToolStripMenuItem_Click”。
* 第六个菜单项:设置name属性为“exiToolStripMenuItem”,Text属性为“Exit”,设置其Click事件为“exiToolStripMenuItem_Click”。
5设置“设置选项”菜单,在其下面设置1个名为“styleToolStripMenuItem”的菜单项,然后在此菜单项下再设置3个子菜单,从上到下各子菜单项的具体信息如下。
* 第一个子菜单项:设置name属性为“style1ToolStripMenuItem”,Text属性为“style1”,设置其Click事件为“style1ToolStripMenuItem_Click”。
* 第二个子菜单项:设置name属性为“style2ToolStripMenuItem”,Text属性为“style2”,设置其Click事件为“style2ToolStripMenuItem_Click”。
* 第三个子菜单项:设置name属性为“style3ToolStripMenuItem”,Text属性为“style3”,设置其Click事件为“style3ToolStripMenuItem_Click”。
6从工具箱插入组件OpenFileDialog和SaveFileDialog,分别设置name属性为“openFileDialog1”和“saveFileDialog1”。
7从工具箱中拖入ProgressBar控件到窗体底部,并且设置该控件的name属性为“progressBarReview”。
8从工具箱中分别拖入3个ImageList控件,用于设置游戏窗体界面的外观显示样式。各控件的具体设置信息如下:
* 第一个ImageList控件,设置name属性为“imageList1”。
* 第二个ImageList控件,设置name属性为“imageList2”。
* 第三个ImageList控件,设置name属性为“imageList3”。
1.5.2 窗体元素设置文件
经过1.5.1小节中的设置操作后,项目的窗体界面基本设计完毕。在窗体元素设置文件Form1.Designer.cs内,定义了各窗体控件的具体属性设置。在下面的内容中将分别介绍。
1.控制按钮
在窗体右侧的各控制按钮控件的功能是控制游戏的进程,例如游戏开始、载入和保存。对应属性的设置代码如下:
buttonReplay
this.buttonReplay.Location = new System.Drawing.Point180, 197;
this.buttonReplay.Name = "buttonReplay";
this.buttonReplay.Size = new System.Drawing.Size75, 23;
this.buttonReplay.TabIndex = 0;
this.buttonReplay.Text = "重新开始";
this.buttonReplay.UseVisualStyleBackColor = true;
this.buttonReplay.Click += new System.EventHandlerthis.buttonReplay_Click;
buttonReview
this.buttonReview.Location = new System.Drawing.Point180, 338;
this.buttonReview.Name = "buttonReview";
this.buttonReview.Size = new System.Drawing.Size75, 23;
this.buttonReview.TabIndex = 1;
this.buttonReview.Text = "Review";
this.buttonReview.UseVisualStyleBackColor = true;
this.buttonReview.Click += new System.EventHandlerthis.buttonReview_Click;
trackBarReviewSpeed
this.trackBarReviewSpeed.Location = new System.Drawing.Point180, 292;
this.trackBarReviewSpeed.Maximum = 15;
this.trackBarReviewSpeed.Minimum = 1;
this.trackBarReviewSpeed.Name = "trackBarReviewSpeed";
this.trackBarReviewSpeed.Size = new System.Drawing.Size75, 42;
this.trackBarReviewSpeed.TabIndex = 2;
this.trackBarReviewSpeed.Value = 1;
this.trackBarReviewSpeed.Scroll += new System.EventHandlerthis.trackBar1_Scroll;
buttonSave
this.buttonSave.Location = new System.Drawing.Point180, 238;
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size75, 23;
this.buttonSave.TabIndex = 3;
this.buttonSave.Text = "保存";
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandlerthis.buttonSave_Click;
buttonLoad
this.buttonLoad.Location = new System.Drawing.Point180, 267;
this.buttonLoad.Name = "buttonLoad";
this.buttonLoad.Size = new System.Drawing.Size75, 23;
this.buttonLoad.TabIndex = 4;
this.buttonLoad.Text = "载入";
this.buttonLoad.UseVisualStyleBackColor = true;
this.buttonLoad.Click += new System.EventHandlerthis.buttonLoad_Click;
progressBarReview
this.progressBarReview.Location = new System.Drawing.Point3, 381;
this.progressBarReview.Name = "progressBarReview";
this.progressBarReview.Size = new System.Drawing.Size252, 17;
this.progressBarReview.TabIndex = 5;
2.窗体菜单
在窗体顶部的各菜单选项都包括对应的子选项,甚至还包含孙选项,其功能是对游戏进行控制和设置,并显示游戏的使用帮助信息。对应于窗体菜单各选项的属性设置代码如下所示:
fileToolStripMenuItem
this.fileToolStripMenuItem.DropDownItems.AddRange
new System.Windows.Forms.ToolStripItem[] {
this.replayToolStripMenuItem,
this.replayExtendedToolStripMenuItem,
this.saveToolStripMenuItem,
this.loadToolStripMenuItem,
this.reviewToolStripMenuItem,
this.toolStripMenuItemLine,
this.exiToolStripMenuItem};
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size41, 32;
this.fileToolStripMenuItem.Text = "文件";
replayToolStripMenuItem
this.replayToolStripMenuItem.Name = "replayToolStripMenuItem";
this.replayToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.replayToolStripMenuItem.Text = "重新开始";
this.replayToolStripMenuItem.Click +=
new System.EventHandlerthis.replayToolStripMenuItem_Click;
replayExtendedToolStripMenuItem
this.replayExtendedToolStripMenuItem.Name = "replayExtendedToolStripMenuItem";
this.replayExtendedToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.replayExtendedToolStripMenuItem.Text = "ReplayExtended";
this.replayExtendedToolStripMenuItem.Click +=
new System.EventHandlerthis.replayExtendedToolStripMenuItem_Click;
saveToolStripMenuItem
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click +=
new System.EventHandlerthis.saveToolStripMenuItem_Click;
loadToolStripMenuItem
this.loadToolStripMenuItem.Name = "loadToolStripMenuItem";
this.loadToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.loadToolStripMenuItem.Text = "Load";
this.loadToolStripMenuItem.Click +=
new System.EventHandlerthis.loadToolStripMenuItem_Click;
reviewToolStripMenuItem
this.reviewToolStripMenuItem.Name = "reviewToolStripMenuItem";
this.reviewToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.reviewToolStripMenuItem.Text = "Review";
this.reviewToolStripMenuItem.Click +=
new System.EventHandlerthis.reviewToolStripMenuItem_Click;
toolStripMenuItemLine
this.toolStripMenuItemLine.Name = "toolStripMenuItemLine";
this.toolStripMenuItemLine.Size = new System.Drawing.Size163, 6;
exiToolStripMenuItem
this.exiToolStripMenuItem.Name = "exiToolStripMenuItem";
this.exiToolStripMenuItem.Size = new System.Drawing.Size166, 22;
this.exiToolStripMenuItem.Text = "Exit";
this.exiToolStripMenuItem.Click +=
new System.EventHandlerthis.exiToolStripMenuItem_Click;
optionToolStripMenuItem
this.optionToolStripMenuItem.DropDownItems.AddRange
new System.Windows.Forms.ToolStripItem[] {
this.styleToolStripMenuItem};
this.optionToolStripMenuItem.Name = "optionToolStripMenuItem";
this.optionToolStripMenuItem.Size = new System.Drawing.Size65, 32;
this.optionToolStripMenuItem.Text = "设置选项";
styleToolStripMenuItem
this.styleToolStripMenuItem.DropDownItems.AddRange
new System.Windows.Forms.ToolStripItem[] {
this.style1ToolStripMenuItem,
this.style2ToolStripMenuItem,
this.style3ToolStripMenuItem};
this.styleToolStripMenuItem.Name = "styleToolStripMenuItem";
this.styleToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.styleToolStripMenuItem.Text = "Style";
style1ToolStripMenuItem
this.style1ToolStripMenuItem.Name = "style1ToolStripMenuItem";
this.style1ToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.style1ToolStripMenuItem.Tag = "";
this.style1ToolStripMenuItem.Text = "style1";
this.style1ToolStripMenuItem.Click +=
new System.EventHandlerthis.style1ToolStripMenuItem_Click;
style2ToolStripMenuItem
this.style2ToolStripMenuItem.Name = "style2ToolStripMenuItem";
this.style2ToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.style2ToolStripMenuItem.Text = "style2";
this.style2ToolStripMenuItem.Click +=
new System.EventHandlerthis.style1ToolStripMenuItem_Click;
style3ToolStripMenuItem
this.style3ToolStripMenuItem.Name = "style3ToolStripMenuItem";
this.style3ToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.style3ToolStripMenuItem.Text = "style3";
this.style3ToolStripMenuItem.Click +=
new System.EventHandlerthis.style1ToolStripMenuItem_Click;
helpToolStripMenuItem
this.helpToolStripMenuItem.DropDownItems.AddRange
new System.Windows.Forms.ToolStripItem[] {
this.keyboardToolStripMenuItem,
this.aboutToolStripMenuItem};
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size65, 32;
this.helpToolStripMenuItem.Text = "游戏帮助";
keyboardToolStripMenuItem
this.keyboardToolStripMenuItem.Name = "keyboardToolStripMenuItem";
this.keyboardToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.keyboardToolStripMenuItem.Text = "操作键";
this.keyboardToolStripMenuItem.Click +=
new System.EventHandlerthis.keyBoardToolStripMenuItem_Click;
aboutToolStripMenuItem
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size152, 22;
this.aboutToolStripMenuItem.Text = "关于";
this.aboutToolStripMenuItem.Click +=
new System.EventHandlerthis.aboutToolStripMenuItem_Click;
menuStripMain
this.menuStripMain.Items.AddRange
new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.optionToolStripMenuItem,
this.helpToolStripMenuItem};
this.menuStripMain.Location = new System.Drawing.Point0, 0;
this.menuStripMain.Name = "menuStripMain";
this.menuStripMain.Size = new System.Drawing.Size260, 24;
this.menuStripMain.TabIndex = 6;
this.menuStripMain.Text = "menuStrip1";
3.图片列表控件和窗体的总体设置
在窗体内插入了图片列表控件,其功能是设置游戏的外观显示样式,供用户根据个人喜好进行选择。而窗体总体设置属性的功能是设置窗体Form1的对应属性。
上述各窗体选项属性的设置代码如下所示:
imageList1
this.imageList1.ImageStream = System.Windows.Forms.ImageListStreamer
resources.GetObject"imageList1.ImageStream";
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
this.imageList1.Images.SetKeyName0, "1";
this.imageList1.Images.SetKeyName1, "2";
this.imageList1.Images.SetKeyName2, "3";
this.imageList1.Images.SetKeyName3, "4";
this.imageList1.Images.SetKeyName4, "5";
this.imageList1.Images.SetKeyName5, "6";
this.imageList1.Images.SetKeyName6, "7";
imageList2
this.imageList2.ImageStream = System.Windows.Forms.ImageListStreamer
resources.GetObject"imageList2.ImageStream";
this.imageList2.TransparentColor = System.Drawing.Color.Transparent;
this.imageList2.Images.SetKeyName0, "1";
this.imageList2.Images.SetKeyName1, "2";
this.imageList2.Images.SetKeyName2, "3";
this.imageList2.Images.SetKeyName3, "4";
this.imageList2.Images.SetKeyName4, "5";
this.imageList2.Images.SetKeyName5, "6";
this.imageList2.Images.SetKeyName6, "7";
saveFileDialog1
this.saveFileDialog1.Filter = "youxi records files*.trf|*.trf";
imageList3
this.imageList3.ImageStream = System.Windows.Forms.ImageListStreamer
resources.GetObject"imageList3.ImageStream";
this.imageList3.TransparentColor = System.Drawing.Color.Transparent;
this.imageList3.Images.SetKeyName0, "1";
this.imageList3.Images.SetKeyName1, "2";
this.imageList3.Images.SetKeyName2, "3";
this.imageList3.Images.SetKeyName3, "4";
this.imageList3.Images.SetKeyName4, "5";
this.imageList3.Images.SetKeyName5, "6";
this.imageList3.Images.SetKeyName6, "7";
Form1
this.AutoScaleDimensions = new System.Drawing.SizeF6F, 12F;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ActiveBorder;
this.ClientSize = new System.Drawing.Size260, 410;
this.Controls.Addthis.progressBarReview;
this.Controls.Addthis.buttonLoad;
this.Controls.Addthis.buttonSave;
this.Controls.Addthis.trackBarReviewSpeed;
this.Controls.Addthis.buttonReview;
this.Controls.Addthis.buttonReplay;
this.Controls.Addthis.menuStripMain;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = System.Drawing.Iconresources.GetObject"$this.Icon";
this.MainMenuStrip = this.menuStripMain;
this.MaximizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "youxi";
this.Load += new System.EventHandlerthis.Formyouxi_Load;
System.ComponentModel.ISupportInitializethis.trackBarReviewSpeed.EndInit;
this.menuStripMain.ResumeLayoutfalse;
this.menuStripMain.PerformLayout;
this.ResumeLayoutfalse;
this.PerformLayout;
作为桌面系统,窗体界面的美感十分重要。好的窗体效果能给用户带来视觉冲击,也会留下好的印象。当然,最直接的好处是增加用户的满意度,让项目能够通过。在具体美化时,我们通常会用一些漂亮的素材图片作为背景,并用CSS来配合控件和信息的显示。至于具体怎样搭配,就要根据客户和设计师的喜好而确定了。
1.6 具 体 编 码
光盘:视频\第1章\具体编码.avi
系统窗体界面的设计工作完毕后,接下来,开始步入正式的编码阶段的工作。在本节的内容中,将详细讲解本章俄罗斯方块游戏项目的具体编码过程。
1.6.1 事件处理程序
本章的项目实例通过编写的事件处理程序实现对游戏的控制,例如单击“重新开始”按钮后,将激活buttonReplay_Click事件,用户可以重新开始玩新的游戏。在1.5节的窗体设计过程中,已经涉及了项目内的各个事件,各事件的定义代码在文件Form1.cs内定义。
1. 初始设置
这里的初始设置,是指通过using引用指令定义命名空间,分别定义窗体类Form1和对应的构造函数,具体代码如下所示:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using youxi;
using System.IO;
namespace youxiApp
{
public partial class Form1 : Form
{
private youxiControl youxiControl = new youxiControl;
private youxiNext youxiNext = new youxiNext;
private youxiScore youxiScore = new youxiScore;
public Form1
{
InitializeComponent;
youxiControl.Top = menuStripMain.Height + 2;
youxiControl.Left = 2;
youxiControl.Parent = this;
youxiControl.ImageList = imageList1;
youxiNext.Parent = this;
youxiNext.Top = youxiControl.Top;
youxiNext.Left = youxiControl.Left + youxiControl.Width + 4;
youxiControl.TetrisNext = youxiNext;
youxiScore.Parent = this;
youxiScore.Top = youxiNext.Top + youxiNext.Height + 4;
youxiScore.Left = youxiNext.Left;
youxiControl.TetrisScore = youxiScore;
style1ToolStripMenuItem.Image = imageList1.Images[0];
style2ToolStripMenuItem.Image = imageList2.Images[0];
style3ToolStripMenuItem.Image = imageList3.Images[0];
youxiControl.ProgressBar = progressBarReview;
openFileDialog1.FileName =
Path.GetDirectoryNameApplication.ExecutablePath + @"\sample.trf";
saveFileDialog1.FileName =
Path.GetDirectoryNameApplication.ExecutablePath + @"\sample.trf";
}
2. 编写事件处理代码
通过单击窗体Form1内的各个控件和组件,可以执行对应的事件处理程序,实现游戏的运行和对游戏的控制。在本章1.5节的窗体设计过程中,已经了解了各控件的执行事件名称,在此只对事件的具体处理代码进行介绍。各事件的具体代码如下。
1右侧按钮控件的处理事件
右侧按钮控件是指“重新开始”、“保存”、“载入”、“滑动条”和“Review”控件,各控件对应事件的处理代码如下所示:
private void buttonReplay_Clickobject sender, EventArgs e
{
youxiControl.Replaytrue, false;
}
private void buttonReview_Clickobject sender, EventArgs e
{
youxiControl.Review;
}
private void trackBar1_Scrollobject sender, EventArgs e
{
youxiControl.ReviewSpeed = trackBarReviewSpeed.Value;
}
private void buttonSave_Clickobject sender, EventArgs e
{
if saveFileDialog1.ShowDialog != DialogResult.OK return;
if Path.GetExtensionsaveFileDialog1.FileName == string.Empty
saveFileDialog1.FileName =
Path.ChangeExtensionsaveFileDialog1.FileName, ".trf";
youxiControl.SaveToFilesaveFileDialog1.FileName;
}
private void buttonLoad_Clickobject sender, EventArgs e
{
if openFileDialog1.ShowDialog != DialogResult.OK return;
if !File.ExistsopenFileDialog1.FileName return;
youxiControl.LoadFromFileopenFileDialog1.FileName;
}
2窗体菜单的处理事件
窗体菜单是指窗体顶部的“文件”、“设置选项”、“游戏帮助”三个主菜单,并包含它们的各子菜单和孙菜单。上述各菜单对应事件的处理代码如下所示:
private void replayToolStripMenuItem_Clickobject sender, EventArgs e
{
buttonReplay_ClickbuttonReplay, new EventArgs;
}
private void saveToolStripMenuItem_Clickobject sender, EventArgs e
{
buttonSave_ClickbuttonSave, new EventArgs;
}
private void loadToolStripMenuItem_Clickobject sender, EventArgs e
{
buttonLoad_ClickbuttonLoad, new EventArgs;
}
private void reviewToolStripMenuItem_Clickobject sender, EventArgs e
{
buttonReview_ClickbuttonReview, new EventArgs;
}
private void exiToolStripMenuItem_Clickobject sender, EventArgs e
{
Close;
}
private void keyBoardToolStripMenuItem_Clickobject sender, EventArgs e
{
MessageBox.Show"左移: Left、A\r\n右移: Right、D\r\n"
+ "下移: Down、S\r\n变换: Up、W\r\n变化: Back、F\r\n直下: Space、J、Enter",
"按键说明";
}
private void blogToolStripMenuItem_Clickobject sender, EventArgs e
{
Process.Start"http:blog.sina.com.cnu589d32f5010008ls";
}
private void aboutToolStripMenuItem_Clickobject sender, EventArgs e
{
MessageBox.Show"俄罗斯方块\r\n设计: 天涯沦落人\r\n"
+ "日期: 2013-11-24\r\n联系: xxx@126.com", "关于本程序";
}
private void style1ToolStripMenuItem_Clickobject sender, EventArgs e
{
if sender == style1ToolStripMenuItem
youxiControl.ImageList = imageList1;
else if sender == style2ToolStripMenuItem
youxiControl.ImageList = imageList2;
if sender == style3ToolStripMenuItem
youxiControl.ImageList = imageList3;
}
private void replayExtendedToolStripMenuItem_Clickobject sender, EventArgs e
{
youxiControl.Replaytrue, true;
}
1.6.2 游戏控制、处理方法
普通的社会规则是倡导助人为乐的,而我们玩的游戏却设置了很多等级和关口,这不是因为开发者偏要跟社会规则闹别扭,而是因为游戏就是游戏,是要吊玩家胃口的。在游戏中设置分数功能后,就可以激发用户永远去追逐高分。高分伴随高等级,等级能够提高玩家的争强好胜之心,吸引玩家继续玩下去,从而产生更多的乐趣。
从前面的实现过程可以看出,整个游戏项目的控制和处理是通过事件处理程序控制的。每个事件处理程序只是调用处理方法的名称,而实现具体功能的各种处理方法在文件you.cs中定义。
1. 初始设置
这里的初始设置是指定义游戏的控制类youxiControl,并设置玩游戏过程中的返回行数、参数、等级、积分和方块的操作等参数。具体代码如下所示:
public class youxiControl : Control
{
private const int rowCount = 21; 行数
private const int colCount = 11; 列数
private int brickWidth = 16; 小块宽度
private int brickHeight = 16; 小块高度
private ImageList imageList; 方块素材
private Bitmap backBitmap; 背景图片
private ListListListPoint brickTemplets =
new ListListListPoint; 方块模板[模板序号,朝向]
private byte[,] points = new byte[colCount, rowCount]; 点阵
private byte brickIndex = 0; 模板序号
private byte facingIndex = 0; 当前变化号
private Point brickPoint = new Point; 方块的位子
private byte afterBrickIndex = 0; 下一个模板序号
private byte afterFacingIndex = 0; 下一个变化号
private System.Windows.Forms.Timer timer; 控制下落的定时器
private int lines; 消行数
private Random random = new Random; 随机数
private int level = 0; 当前速度
private int score = 0; 成绩
下落速度,数值表示每次下落的时间差,以毫秒为单位
private int[] speeds = new int[] { 700, 500, 400, 300, 320, 320, 100, 80, 70, 60, 50 };
每次消除行所增加的积分
private int[] scoress = new int[] { 0001, 0100, 0300, 0500, 1000, 3200 };
private bool playing = false; 玩家是否正在游戏
private youxiNext youxiNext; 下一个方块的显示控件
private youxiScore youxiScore; 积分显示控件
private int stepIndex = -1; 当前回放的步数
private bool reviewing = false; 是否正在回放中
private Thread threadReview = null; 回放使用的线程
private int reviewSpeed = 1; 回放的速度,数值表示倍数
private ListStepInfo StepInfos = new ListStepInfo; 记录玩家每一步的操作
private int lastRecordTime = 0; 最后记录的时间
private bool recordMode = false; 是否采用记录模式
private ProgressBar progressBar; 回放进度条
private bool extended = false; 扩展方块
消除的行数
public int Lines { get { return lines; } }
当前的积分
public int Score { get { return score; } }
当前的关数
public int Level { get { return level; } }
方块的操作
public enum BrickOperates
{
boMoveLeft = 0, 左移
boMoveRight = 1, 右移
boMoveDown = 2, 下移
boMoveBottom = 3, 直下
boTurnLeft = 4, 左旋
boTurnRight = 5, 右旋
}
2. Replay处理
单击窗体内的“重新开始”按钮时,会执行buttonReplay_Click事件,该事件将会调用Replay方法,设置重新开始游戏。Replay方法的具体代码如下所示:
public void Replaybool ARecordMode, bool AExtended
{
if threadReview != null
{
threadReview.Abort;
threadReview = null;
}
if AExtended != extended
NewTempletsAExtended;
reviewing = false;
playing = true;
recordMode = ARecordMode;
Clear;
StepInfos.Clear;
afterBrickIndex = byterandom.NextbrickTemplets.Count;
afterFacingIndex = byterandom.NextbrickTemplets[afterBrickIndex].Count;
if youxiNext != null youxiNext.Updatethis;
if recordMode !reviewing
{
StepInfos.Addnew StepInfo0, 0, afterBrickIndex, afterFacingIndex;
lastRecordTime = Environment.TickCount;
}
level = 0;
score = 0;
lines = 0;
stepIndex = -1;
if progressBar != null progressBar.Value = 0;
NextBrick;
timer.Interval = speeds[level];
timer.Enabled = true;
if youxiScore != null youxiScore.Updatethis;
if CanFocus Focus;
}
3. Review处理
单击窗体内的Review按钮时,将会执行buttonReview_Click事件,该事件将会调用Review方法,设置查看游戏的历史回放进程。具体代码如下所示:
public void Review
{
if threadReview != null
{
threadReview.Abort;
threadReview = null;
}
timer.Enabled = false;
reviewing = true;
playing = true;
Clear;
level = 0;
score = 0;
lines = 0;
stepIndex = 0;
NextStep;
NextStep;
if progressBar != null
progressBar.Maximum = StepInfos.Count;
threadReview = new Threadnew ThreadStartDoReview;
threadReview.Start;
}
在执行上述方法时,先通过DoReview方法设置回放速度。DoReview方法的具体实现代码如下:
private void DoReview
{
while reviewing
{
if stepIndex 0 || stepIndex = StepInfos.Count
{
reviewing = false;
break;
}
Thread.SleepintdoubleStepInfos[stepIndex].timeTick reviewSpeed;
if !reviewing break;
Invokenew EventHandlerDoInvoke;
}
Invokenew EventHandlerDoInvoke;
threadReview = null;
}
4. 载入处理
载入处理的范围比较广,包括游戏载入和统计数据载入,在此,将着重介绍统计数据的载入。具体过程如下。
1通过LoadFromFile方法,从指定文件中将玩家的操作记录载入,变量AFileName是载入的源文件。LoadFromFile方法的具体代码如下所示:
public void LoadFromFilestring AFileName
{
if !File.ExistsAFileName return;
FileStream vFileStream = new FileStreamAFileName, FileMode.Open, FileAccess.Read;
LoadFromStreamvFileStream;
vFileStream.Close;
}
2通过LoadFromStream方法从指定流中将玩家的操作记录载入,变量AStream是指载入的流。LoadFromStream方法的具体代码如下所示:
从流中载入玩家操作记录
summary
public void LoadFromStreamStream AStream
{
if AStream == null return;
byte[] vBuffer = new byte[3];
if AStream.ReadvBuffer, 0, vBuffer.Length != 3 return;
if vBuffer[0] != 116 || vBuffer[1] != 114 || vBuffer[2] != 102 return;
if colCount != byteAStream.ReadByte return;
if rowCount != byteAStream.ReadByte return;
if threadReview != null
{
threadReview.Abort; 如果正在回放
threadReview = null;
}
timer.Enabled = false;
playing = false;
reviewing = false;
brickTemplets.Clear;
if progressBar != null progressBar.Value = 0;
int vTempletsCount = AStream.ReadByte;
for int i=0; ivTempletsCount; i++
{
ListListPoint templets = new ListListPoint;
int vPointsLength = AStream.ReadByte;
for int j=0; jvPointsLength; j++
{
ListPoint bricks = new ListPoint;
int vPointCount = AStream.ReadByte;
for int k=0; kvPointCount; k++
{
int vData = AStream.ReadByte;
if vData 0 break;
bricks.Addnew PointvData 3, vData 4 3;
}
templets.Addbricks;
}
brickTemplets.Addtemplets;
}
StepInfos.Clear;
vBuffer = new byte[sizeofint];
if AStream.ReadvBuffer, 0, vBuffer.Length != vBuffer.Length return;
int vStepCount = BitConverter.ToInt32vBuffer, 0;
for int i=0; ivStepCount; i++
{
StepInfo vStepInfo = new StepInfo;
vStepInfo.param1 = byteAStream.ReadByte;
vBuffer = new byte[sizeofushort];
if AStream.ReadvBuffer, 0, vBuffer.Length != vBuffer.Length return;
vStepInfo.timeTick = ushortBitConverter.ToInt16vBuffer, 0;
int vData = AStream.ReadByte;
vStepInfo.command = bytevData 3;
vStepInfo.param2 = bytevData 4 3;
StepInfos.AddvStepInfo;
}
Clear;
Invalidate;
}
3通过SaveToFile方法将玩家的操作记录保存到指定文件中,变量AFileName是保存的文件。SaveToFile方法的具体代码如下所示:
将玩家操作记录保存到文件中
public void SaveToFilestring AFileName
{
FileStream vFileStream =
new FileStreamAFileName, FileMode.Create, FileAccess.Write;
SaveToStreamvFileStream;
vFileStream.Close;
}
4通过SaveToStream方法将玩家的操作记录保存到指定流中,变量AStream是保存的流。SaveToStream方法的具体代码如下所示:
将玩家操作记录保存到流中
public void SaveToStreamStream AStream
{
if AStream == null return;
byte[] vBuffer = Encoding.ASCII.GetBytes"trf";
AStream.WritevBuffer, 0, vBuffer.Length; 写头信息
AStream.WriteBytebytecolCount;
AStream.WriteBytebyterowCount;
byte vByte = bytebrickTemplets.Count;
AStream.WriteBytevByte;
foreach ListListPoint vList in brickTemplets
{
vByte = bytevList.Count;
AStream.WriteBytevByte;
foreach ListPoint vPoints in vList
{
vByte = bytevPoints.Count;
AStream.WriteBytevByte;
foreach Point vPoint in vPoints
{
vByte = bytevPoint.Y 4 | vPoint.X;
AStream.WriteBytevByte;
}
}
}
AStream.WriteBitConverter.GetBytesStepInfos.Count, 0, sizeofint;
foreach StepInfo vStepInfo in StepInfos
{
AStream.WriteBytevStepInfo.param1;
AStream.WriteBitConverter.GetBytesvStepInfo.timeTick, 0, sizeofushort;
vByte = bytevStepInfo.param2 4 | vStepInfo.command;
AStream.WriteBytevByte;
}
}
5. 绘制方块处理
绘制方块处理是指在窗体内绘制指定的俄罗斯方块,并且在绘制过程中能够控制它的位置和显示样式。在C#程序中,使用GDI+实现窗体绘图功能。GDI+是Graphics Device Interface Plus的缩写,是公共语言运行时用来创建图形、绘制文本以及进行图形对象操作的技术。GDI+提供了在Windows窗体和控件上绘制图形、图像和文本的方法,是C#的核心应用技术之一。
Graphics是GDI+的核心,在里面提供了将对象绘制到显示设备的方法。Graphics可以与特定设备的上下文相关联,来创建图形的对象。Graphics类封装了绘制直线、曲线、图形、图像和文本的方法,是GDI+实现绘制直线、曲线、图形、图像和文本的类,是GDI+操作的基础类。GDI+绘制的实现流程是:首先创建Graphics对象;然后通过Graphics对象绘制线条、形状或文本。
有如下3种方法创建GDI+对象。
在窗体或控件的Paint事件处理方法中创建,PaintEventArgs类参数中包含了对图形对象的引用。例如下面的代码:
private void Form1_Paintobject sender, System.Windows.Forms.PaintEventArgs pe
{
Graphics g = pe.Graphics;
}
调用窗体或控件的CreateGraphics方法创建Graphics对象,例如下面的代码:
Graphics g = pe.Graphics;
g = this.CreateGraphics;
通过从Image继承的对象创建Graphics对象,例如下面的代码:
Bitmap mm = new Bitmap@"D:\123.bmp";
Graphics g = Graphics.FormImagemm;
创建上述Graphics对象后,可以用该对象来绘制线条、形状或文本。
本项目中,窗体图像绘制的具体实现流程如下。
1通过DrawPoint方法在窗体内绘制一个点的方块,其中变量AGraphics是绘制的图像,APoint变量是绘制的坐标,ABrick变量是绘制的方块图案。
DrawPoint方法的具体代码如下所示:
public void DrawPointGraphics AGraphics, Point APoint, byte ABrick
{
if ImageList == null return;
if ImageList.Images.Count = 0 return;
if APoint.X 0 || APoint.X = colCount return;
if APoint.Y 0 || APoint.Y =
|
|