科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件用 C# 开发智能手机软件:推箱子(十一)

用 C# 开发智能手机软件:推箱子(十一)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在上篇文章“使用 C# 开发智能手机软件:推箱子(十)”中,我对Common/DataFile.cs 源程序文件进行了介绍。

作者:银河 来源:博客园 2007年11月17日

关键字: C# 智能手机 软件 推箱子

  • 评论
  • 分享微博
  • 分享邮件
 在上篇文章使用 C# 开发智能手机软件:推箱子(十)”中,我对Common/DataFile.cs 源程序文件进行了介绍。在这篇文章中,介绍 Common/Env.cs 源程序文件。这个源程序文件中包含表示“工作环境”的密封类 Env 。也就是说,主程序中重要的变量都封装在这个类中,作为整个程序的“工作环境”。她还起着桥梁作用,其中两个字段:

  DataFile db; // 数据文件

  ConfigFile cfg; // 配置文件

  正是我们以前介绍过的管理数据文件的密封类 DataFile 和管理配置文件的密封类 ConfigFile 的实例。密封类 Env 中的不少属性和方法是通过这两个字段调用其各自的属性和方法。

  下面对密封类 Env 中的一些方法作点说明:

  GetClientSize 方法用来计算当使用标准箱子尺寸时主窗体客户区的尺寸。该方法仅当程序运行在计算机上时才会被调用,使主窗体的尺寸根据当前关的尺寸自动调整。程序运行在智能手机时是不会被调用的,因为在智能手机上本程序并不改变主窗体的尺寸。

  SetBoxInfo 方法的作用是根据客户区尺寸计算箱子的尺寸,并相应设定要显示的图形单元。图形单元共有 24x24、20x20、16x16 和 12x12 四种尺寸,如下所示:

  

  

  

  

  如果使用 12x12 的图形单元还不能在客户区完整显示地图的话,可能这一关的游戏就无法玩了。

  Draw 方法用来更新主窗体客户区,也就是在主窗体客户区画出本关的地图,并根据玩家的动作随时更新地图。

  Design 方法实现在设计模式下,当鼠标点击时要采取的动作。

  StepIt 方法实现工人往指定方向前进一步(可能推着箱子)。

  Back 方法实现工人后退一步(可能连带箱子一起后退)。

  GetMoveInfo 方法寻找一条将工人移动到鼠标点击的位置的路线。她调用我们以前介绍过的静态类 FindPath 的 Seek 方法来寻找最短路线。

  GetPushInfo 方法给出将箱子推动到鼠标点击的位置所需的信息

  到此为止,Common 目录下所有源程序文件都介绍完了,这些源程序文件中包含的类是实现整个程序功能的基础。在随后的文章中将介绍 Windows 目录下的源程序文件,她们包含的类实现整个程序的用户界面。

  下面就是密封类 Env 的源程序代码,虽然稍微长了一点,但是里面的注释比较详细,应该不难理解。

以下是引用片段:
  1using System;
  2using System.Drawing;
  3using System.Collections.Generic;
  4
  5namespace Skyiv.Ben.PushBox.Common
  6{
  7 /**//// 
  8 /// 工作环境
  9 /// 
  10 sealed class Env : IDisposable
  11 {
  12 DataFile db; // 数据文件
  13 ConfigFile cfg; // 配置文件
  14 string errorMsg; // 错误信息
  15 string debugMsg; // 调试信息
  16 bool isReplay; // 是否正在回放
  17 Action active; // 模式: 正常 新建 编辑 删除
  18 byte pen; // 设计时的笔
  19 Bitmap img; // 图形单元, 横向被均匀分为八份
  20 Stack stack; // 历史路线, 用于后退功能
  21 Size clientSize; // 工作区域尺寸(以像素为单位)
  22 Size boxSize; // 图形元素尺寸(以像素为单位)
  23 Point toPixel; // 将要到达的位置(以像素为单位)
  24 Point worker; // 当前工人位置(以单元格为单位)
  25 int pushSteps; // 推动着箱子走的步数
  26 int levelOem; // 原来的关数,仅用于“菜单 -> 数据 -> 设计 -> 新建”放弃后恢复现场
  27
  28 public string ErrorMsg { get { return errorMsg; } }
  29 public string DebugMsg { get { return debugMsg; } }
  30 public string[] Groups { get { return cfg.Groups; } }
  31 public int Group { get { return cfg.Group; } set { cfg.Group = value; } }
  32 public int Level { get { return cfg.Levels[Group]; } set { cfg.Levels[Group] = value; } }
  33 public int LeveLOem { get { return levelOem; } }
  34 public int MaxLevel { get { return db.MaxLevel; } }
  35 public string Steps { get { return cfg.Steps; } }
  36 public Size LevelSize { get { return db.LevelSize; } }
  37 public Size ClientSize { set { clientSize = value; } }
  38 public Point ToPixel { set { toPixel = value; } }
  39 public int MaxLevelSize { get { return cfg.MaxLevelSize; } set { cfg.MaxLevelSize = value; } }
  40 public int StepDelay { get { return cfg.StepDelay; } set { cfg.StepDelay = value; } }
  41 public int ReplayDelay { get { return cfg.ReplayDelay; } set { cfg.ReplayDelay = value; } }
  42 public Action Active { get { return active; } set { active = value; } }
  43 public byte Pen { get { return pen; } set { pen = value; } }
  44 public bool HasError { get { return !string.IsNullOrEmpty(errorMsg); } }
  45 public bool HasWorker { get { return db.HasWorker; } }
  46 public bool CanUndo { get { return stack.Count != 0; } }
  47 public bool CanReplay { get { return db.IsFinished && !CanUndo; } }
  48 public bool IsSave { get { return cfg.IsSave; } set { cfg.IsSave = value; } }
  49 public bool IsFinish { get { return db.Tasks == db.Boths; } }
  50 public bool IsReplay { get { return isReplay; } set { isReplay = value; } }
  51 public bool IsDesign { get { return active != Action.None; } }
  52
  53 public Env()
  54 {
  55 stack = new Stack();
  56 cfg = new ConfigFile();
  57 db = new DataFile();
  58 Init();
  59 }
  60
  61 /**//// 
  62 /// 状态栏信息
  63 /// 
  64 public string StatusMessage
  65 {
  66 get
  67 {
  68 return HasError ? "请点击“菜单 -> 帮助 -> 错误信息”" : string.Format(
  69 "{0} {1}/{2} {3} {4} {5} [{6}] {7}",
  70 (active == Action.Create) ? '+' : (active == Action.Edit) ? '=' : isReplay ? "|/-\\"[stack.Count % 4] : '>',
  71 Level + 1, MaxLevel, Pub.ToString(LevelSize),
  72 IsDesign ? string.Format("{0}={1}", db.Boxs, db.Slots) : string.Format("{0}/{1}", db.Boths, db.Tasks),
  73 IsDesign ? Block.GetPenName(pen) : string.Format("{0}({1})", stack.Count, pushSteps),
  74 IsDesign ? (active == Action.Create ? "新建" : "编辑") : db.IsFinished ?
  75 string.Format("{0}({1})", db.MovedSteps, db.PushedSteps) : string.Empty,
  76 db.GroupName);
  77 }
  78 }
  79
  80 public void Dispose()
  81 {
  82 db.Dispose();
  83 }
  84
  85 public void Init()
  86 {
  87 active = Action.None;
  88 pen = Block.Land;
  89 stack.Clear();
  90 SetExceptionMessage(null);
  91 }
  92
  93 void SetExceptionMessage(Exception ex)
  94 {
  95 errorMsg = Pub.GetMessage(ex, false);
  96 debugMsg = Pub.GetMessage(ex, true);
  97 }
  98
  99 /**//// 
  100 /// 计算当使用标准箱子尺寸时主窗体客户区的尺寸
  101 /// 
  102 /// 状态条的高度
  103 /// 客户区的尺寸
  104 public Size GetClientSize(int statusBarHeight)
  105 {
  106 int width = (Properties.Resources.PushBox24.Width / 8) * LevelSize.Width;
  107 int height = Properties.Resources.PushBox24.Height * LevelSize.Height + statusBarHeight;
  108 if (width < 240) width = 240;
  109 if (height < 48) height = 48;
  110 if (width > 1008) width = 1008;
  111 if (height > 672) height = 672;
  112 return new Size(width, height);
  113 }
  114
  115 /**//// 
  116 /// 根据客户区尺寸,计算箱子的尺寸,并相应设定要显示的图形单元
  117 /// 
  118 public void SetBoxInfo()
  119 {
  120 if (HasError) return;
  121 if (LevelSize.IsEmpty) return;
  122 int rX = clientSize.Width / LevelSize.Width;
  123 int rY = clientSize.Height / LevelSize.Height;
  124 int r = Math.Min(rX, rY);
  125 if (r >= 24) img = Properties.Resources.PushBox24;
  126 else if (r >= 20) img = Properties.Resources.PushBox20;
  127 else if (r >= 16) img = Properties.Resources.PushBox16;
  128 else img = Properties.Resources.PushBox12;
  129 boxSize = new Size(img.Height, img.Width / 8);
  130 }
  131
  132 /**//// 
  133 /// 装入配置文件
  134 /// 
  135 public void LoadConfig()
  136 {
  137 if (HasError) return;
  138 try
  139 {
  140 cfg.LoadConfig();
  141 }
  142 catch (Exception ex)
  143 {
  144 SetExceptionMessage(ex);
  145 }
  146 }
  147
  148 /**//// 
  149 /// 保存组信息到配置文件
  150 /// 
  151 /// 组信息
  152 public void SaveConfig(string[] groups)
  153 {
  154 if (HasError) return;
  155 try
  156 {
  157 cfg.SaveConfig(groups);
  158 }
  159 catch (Exception ex)
  160 {
  161 SetExceptionMessage(ex);
  162 }
  163 }
  164
  165 /**//// 
  166 /// 保存当前选项及当前走法到配置文件
  167 /// 
  168 public void SaveConfig()
  169 {
  170 if (HasError) return;
  171 try
  172 {
  173 cfg.SaveConfig(stack.ToArray());
  174 }
  175 catch (Exception ex)
  176 {
  177 SetExceptionMessage(ex);
  178 }
  179 }
  180
  181 /**//// 
  182 /// 装入当前组信息
  183 /// 
  184 public void LoadGroup()
  185 {
  186 if (HasError) return;
  187 try
  188 {
  189 db.LoadGroup(Groups[Group]);
  190 }
  191 catch (Exception ex)
  192 {
  193 SetExceptionMessage(ex);
  194 }
  195 }
  196
  197 /**//// 
  198 /// 装入当前关信息
  199 /// 
  200 public void LoadLevel()
  201 {
  202 active = Action.None;
  203 if (HasError) return;
  204 try
  205 {
  206 db.LoadLevel(Level);
  207 worker = db.Worker;
  208 stack.Clear();
  209 pushSteps = 0;
  210 isReplay = false;
  211 }
  212 catch (Exception ex)
  213 {
  214 SetExceptionMessage(ex);
  215 }
  216 }
  217
  218 /**//// 
  219 /// 新建一关
  220 /// 
  221 /// 是否复制当前关
  222 /// 新建关的尺寸
  223 public void NewLevel(bool isCopy, Size size)
  224 {
  225 if (HasError) return;
  226 try
  227 {
  228 levelOem = Level;
  229 Level = MaxLevel;
  230 db.NewLevel(isCopy, size);
  231 }
  232 catch (Exception ex)
  233 {
  234 SetExceptionMessage(ex);
  235 }
  236 }
  237
  238 /**//// 
  239 /// 给出通关步骤
  240 /// 
  241 /// 通关步骤
  242 public string GetSteps()
  243 {
  244 string steps = "";
  245 if (!HasError)
  246 {
  247 try
  248 {
  249 steps = db.GetSteps(Level);
  250 }
  251 catch (Exception ex)
  252 {
  253 SetExceptionMessage(ex);
  254 }

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章