2013年10月16日星期三

炸弹人游戏开发系列(3):显示地图 - 码农终结者

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
炸弹人游戏开发系列(3):显示地图 - 码农终结者  阅读原文»

前言

上文我们进行了初步的高层设计,现在我们将实现图片预加载和显示地图的功能需求。

从本文开始我采用TDD开发,大家可以看到在实现的过程中我们会修改设计,修改设计后又会修改对应的实现代码,这是一个不断迭代的过程。在有测试套件的保护下,我们可以放心地重构。

本文目的

掌握地图绘制的技术。

本文主要内容

回顾上文与显示地图相关的领域模型

开发策略

使用我的控件YPreLoadImg来实现图片预加载,结合progressBar插件,能够显示出加载进度条。

只建一个ShowMap类,用这个类来进行实验,找到显示地图的方法,然后在重构的时候再分离出Main类和MapData数据类。

原因

  • 因为我对canvas很不熟悉,需要先集中精力熟悉canvas的使用,而不是把精力放在架构设计上。
  • 因为我是采用TDD开发,因此可以安全地进行重构。可以在实现“显示地图”功能后,再在重构时提炼出Main和MapData类。

开发策略也是迭代修正的

开发策略只是就当前的知识指定的大概计划,会随着开发的进行而进行细化和修正。如现在的开发策略并没有考虑到在重构时会增加Game类。

预加载图片

预加载的目的

将图片下载到本地内存中。

为什么要预加载

  • 必须等到图片完全加载后才能使用canvas对图片进行操作。如果试图在图片未完全加载之前就将其呈现到canvas上,那么canvas将不会显示任何图片。
  • 如果不使用预加载,则在使用图片之前需要先下载图片到本地。即使有浏览器优化,第一次使用图片时也需要先下载图片,这样在第一次使用图片时,会有卡的感觉。

因此,在游戏开始之前,先要进行游戏初始化,预加载游戏所需的图片。

如何进行预加载

基本示例:

var img = new Image(); //创建一个图片对象
img.src = "test.png"; //下载该路径的图片
img.onload = function () { //图片下载完毕时异步调用callback函数。
callback(img);
};

预加载网上教程

显示进度条

YPreLoadImg控件结合进度条插件progressbar,可以显示出进度条。

新增ShowMap类并实现预加载图片

新增ShowMap类,使用TDD开发并实现预加载图片,需要先写测试用例。

这里先简单介绍下测试驱动开发的步骤:

  1. 写一个测试用例,验证行为
  2. 运行测试,检查测试用例本身是否有错误(测试是否按自己所期望的方式失败)。
  3. 写实现代码,使得测试通过
  4. 重构代码
  5. 运行测试,使得测试通过

测试代码

下面是关于预加载的测试代码(这里只是展示最后结果,实际开发中并不是一口气就先把测试代码写完然后就直接写实现代码了,而是每次先写验证一个行为的测试代码,然后再写相应的实现代码,然后再写验证下一个行为的测试代码,这样迭代开发):

describe("showMap.js", function () {

describe(
"init", function () {

beforeEach(function () {
//不执行onload
spyOn(showMap, "onload").andCallFake(function () {
});
});
afterEach(function () {
});
it(
"传入的参数为数组,数组元素包含id和url属性", function () {
var urls = [];
var temp = [];
var i = 0, len = 0;
spyOn(window.YYC.Control,
"PreLoadImg");

temp
= [
{ id:
"ground", url: "ground.png" },
{ id:
"wall", url: "wall.png" }
];

for (i = 0, len = temp.length; i < len; i++) {
urls.push({ id: temp.id, url:
"../../../../Content/Bomber/Image/Map/" + temp.url });
}
showMap.init();
expect(YYC.Control.PreLoadImg).toHaveBeenCalled();
expect(YYC.Control.PreLoadImg.calls[
0].args[0]).toBeArray();
expect(YYC.Control.PreLoadImg.calls[
0].args[0][0].id).toBeDefined();
expect(YYC.Control.PreLoadImg.calls[
0].args[0][0].url).toBeDefined();
});
});
describe(
"onload", function () {
var dom = null;

function insertDom() {
dom
= $("<div id='progressBar'></div>");
$(
"body").append(dom);
};
function removeDom() {
dom.remove();
};
beforeEach(function () {
ins
EasyUI在MVC4中需要部分刷新页面时load()后页面变形问题! - 政政糖  阅读原文»

  最近在使用MVC4与EasUI过程中遇到些容易导致界面变形的问题,纠结了很久,但其实当发现问题在哪里时,倒觉得最终还是自己对MVC4的概念没把握好,OK,show time. 本示例Contact 页面的部分标签loadAbout页面。

  1. 首先复原一下问题,相信应该会有后来的朋友也遇见。加载JS 与CSS 。

    App_Start文件下的BundleConfig.cs

1 bundles.Add(new ScriptBundle("~/bundles/jquery-easyui").Include(
2 "~/Content/jquery-easyui-1.3.4/jquery-easyui-min.js"));
3
4 bundles.Add(new StyleBundle("~/Content/jquery-easyui-1.3.4/themes/default/css").Include("~/Content/jquery-easyui-1.3.4/themes/default/easyui.css"));

  以上内容在配置时需要注意:默认download下来的jquery.easyui.min.js 名称要改为jquery-easyui-min.js,否则加载不成功;其次尤其要注意stylebundle的virtualpath问题,必须是XXX/Default/XXX 才可以,要到达CSS的目录,但名称可以自定义;如果为XXX/Default的话,不好意思,认不到相应的CSS。

  2. 在_Layout.cshtml 页加载相应的引用;  

1 @Scripts.Render("~/bundles/jquery-easyui")
2  @Styles.Render("~/Content/css")

  使用link标签将样式表放在文档head中,且在script标签前。

  原因是:另外样式放在底部的加载情况是:当页面逐步加载时,文字首先显示,接着是图片。最后,当样式表正确下载了之后,已经呈现的文字  和图片就要用新的样式重绘。就好像格子铺里,东西都按顺序摆好了,但是老板说,这个东西得这样、那样摆,又得挨个重新摆了。

  将script脚本放在底部

  原因是:脚本放在页面顶部同样会引起页面阻塞,阻止页面逐渐呈现。

  http协议1.1规范,建议浏览器从每个主机并行下载两个组件,并行下载的数量的优劣取决于带宽和CPU,过多的并行下载也会降低性能。并行  下载的优点很明显,组件可以并行下载,但是下载脚本时并行下载是禁用的,是为了保证脚本能够按照正确的顺序执行。因为脚本不能并行下  载,为避免组件的下载延迟,最好将脚本放在页面底部。

  3. Controller代码调用页面,使用PartialView,如此框架便会自动过滤掉母版页的样式与脚本,成为一个干净的partial.

1 public PartialViewResult About()
2 {
3 ViewBag.Message = "Your app description page.";
5 return PartialView();
6 }

  4. Contact页面

1 <section class="contact">
2 <h2>日历 - Calendar</h2>
3 <div id="contantDiv" class="demo-info" style="margin-bottom: 10px">
4 <div class="demo-tip icon-tip"></div>
5 <div>单击选择日期</div>
6 </div>
7 </section>
8
9 <script type="text/javascript">
10 function loadit() {
11 $("#contantDiv").load("About");}
12 </script>

  5. About页面

1 <div id="nihao" class="easyui-calendar" style="width: 180px; height: 180px;"></div>
2 @* @Scripts.Render("~/bundles/jquery")*@ //此处是主要问题点,一不小心,就会让人很捉鸡。
3 @Scripts.Render("~/bundles/jquery-easyui")

如果不增加标红的jquery引用,则一切正常;

如果加上后,某处似乎会出现重复的问题,如下:

此问题,原因其实很简单,easyui 的控件是需要动态画上去的,而之前母版页加载的easyui.js 在Load()方法调用后,是不会再执行了,因为那货已经在母版页加载过一次了,此次本来就是使用了Ajax的部分页面重画,当然不能再麻烦人家了。有时心不平气不和就会费神费力浪费青春,回过头来,原来解决问题的方案早都在哪里等Cao了。


本文链接:http://www.cnblogs.com/mqgh/p/RogerZ.html,转载请注明。

阅读更多内容

没有评论:

发表评论