前言
上文中我们加入了1个敌人,使用A*算法寻路。本文会给我们的炸弹人增加放炸弹的能力。
说明
名词解释
- xx类族
是指以xx为基类的继承树上的所有类。
本文目的
实现“放炸弹”功能
增加1个敌人,即一共有2个敌人追踪炸弹人
本文主要内容
回顾上文更新后的领域模型
对领域模型进行思考
Layer类族的render方法改名为run
Layer的render方法负责统一调用Layer的方法,在概念上属于Actor,因此将其改名为run。
开发策略
首先实现“放炸弹”功能。把这个功能分解成很多个子功能,一个一个地实现子功能。
然后再加入1个敌人。实际上就是在Game中往EnemyLayer集合中再加入一个EnemySprite实例,SpriteData增加第2个敌人的数据,SpriteFactory增加工厂方法createEnemy2。
放炸弹流程
功能分解
显示炸弹和火焰
显示炸弹
首先来实现“地图上显示炸弹”的功能,目前最多显示1个炸弹,玩家、敌人不能穿过炸弹。如果玩家处于炸弹方格中,则敌人会原地等待,玩家离开后,敌人继续追踪。
增加图片
增加图片bomb.png:
增加BomberSprite
增加炸弹精灵类BomberSprite:
var BombSprite = YYC.Class(Sprite, {
Init: function (data, bitmap) {
this.base(null, bitmap);
},
Public: {
draw: function (context) {
context.drawImage(this.bitmap.img, this.x, this.y, this.bitmap.width, this.bitmap.height);
},
clear: function (context) {
context.clearRect(0, 0, bomberConfig.canvas.WIDTH, bomberConfig.canvas.HEIGHT);
}
}
});
window.BombSprite = BombSprite;
}());
增加BombLayer
在画布上增加炸弹层。同时增加对应的BombLayer类,它的集合元素为BombSprite类的实例。
将玩家、敌人画布Canvas的zIndex设为3,炸弹画布的zIndex设为1,使得,炸弹画布位于地图画布(zIndex为0)之上,玩家和敌人画布之下。
BomberLayer
var BombLayer = YYC.Class(Layer, {
Private: {
___hasBomb: function () {
return this.getChilds().length > 0;
},
___render: function () {
if (this.___hasBomb()) {
this.clear();
this.draw();
}
}
},
Public: {
setCanvas: function () {
this.P__canvas = document.getElementById("bombLayerCanvas");
var css = {
"position": "absolute",
"top": bomberConfig.canvas.TOP,
"left": bomberConfig.canvas.LEFT,
"z-index": 1
};
$("#bombLayerCanvas").css(css);
},
draw: function () {
this.P__iterator("draw", this.P__context);
},
clear: function () {
this.P__iterator("clear", this.P__context);
},
run: function () {
this.___render();
}
}
});
window.BombLayer = BombLayer;
}());
增加工厂方法
SpriteFactory增加创建炸弹精灵类实例的工厂方法。
LyaerFactory增加创建炸弹层实例的工厂方法。
SpriteFactory
return new BombSprite(playerSprite, bitmapFactory.createBitmap({ img: window.imgLoader.get("bomb"), width: bomberConfig.WIDTH, height: bomberConfig.HEIGHT }));
},
LayerFactory
return new BombLayer();
},
修改PlayerSprite
PlayerSprite增加createBomb方法:
学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别,比如瞬时状态就是刚new出来一个对象,还没有被保存到数据库中,持久化状态就是已经被保存到数据库中,离线状态就是数据库中有,但是session中不存在该对象。但是大家又是否对hibernate的session的那几个特殊方法一清二楚呢?或者说大家是否能够一眼就快速看出一个测试用例在反复的调用session的诸如save,update方法后会到底发出多少条SQL语句呢?本篇随笔将会给你答案,本篇随笔将会以大量的测试用例来掩饰hibernate的这三种状态的转变,相信看完本篇随笔的你会对hibernate的那三种状态有更深入的理解。
好了,废话不多说了,相信大家都知道hibernate的这三种状态的含义,那我们就通过一张图来开始我们的深入hibernate的三种状态之旅吧。
1.TestTransient
session.beginTransaction();
User user = new User();
user.setUsername("aaa");
user.setPassword("aaa");
user.setBorn(new Date());
/*
* 以上user就是一个Transient(瞬时状态),此时user并没有被session进行托管,即在session的
* 缓存中还不存在user这个对象,当执行完save方法后,此时user被session托管,并且数据库中存在了该对象
* user就变成了一个Persistent(持久化对象)
*/
session.save(user);
session.getTransaction().commit();
此时我们知道hibernate会发出一条insert的语句,执行完save方法后,该user对象就变成了持久化的对象了
2.TestPersistent01
session.beginTransaction();
User user = new User();
user.setUsername("aaa");
user.setPassword("aaa");
user.setBorn(new Date());
//以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有
//执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态
session.save(user);
//此时u是持久化状态,已经被session所管理,当在提交时,会把session中的对象和目前的对象进行比较
//如果两个对象中的值不一致就会继续发出相应的sql语句
user.setPassword("bbb");
//此时会发出2条sql,一条用户做插入,一条用来做更新
session.getTransaction().commit();
在调用了save方法后,此时user已经是持久化对象了,被保存在了session缓存当中,这时user又重新修改了属性值,那么在提交事务时,此时hibernate对象就会拿当前这个user对象和保存在session缓存中的user对象进行比较,如果两个对象相同,则不会发送update语句,否则,如果两个对象不同,则会发出update语句。
Hibernate: update t_user set born=?, password=?, username=? where id=?
3.TestPersistent02
session = HibernateUtil.openSession();
session.beginTransaction();
User u = new User();
u.setBorn(new Date());
u.setUsername("zhangsan");
u.setPassword("zhangsan");
session.save(u);
u.setPassword("222");
//该条语句没有意义
session.save(u);
u.setPassword("zhangsan111");
//没有意义
session.update(u);
u.setBorn(sdf.parse("1988-12-22"));
//没有意义
session.update(u);
session.getTransaction().commit();
这个时候会发出多少sql语句呢?还是同样的道理,在调用save方法后,u此时已经是持久化对象了,记住一点:如果一个对象以及是持久化状态了,那么此时对该对象进行各种修改,或者调用多次update、save方法时,hibernate都不会发送sql语句,只有当事物提交的时候,此时hibernate才会拿当前这个对象与之前保存在session中的持久化对象进行比较,如果不相同就发送一条update的sql语句,否则就不会发送update语句
Hibernate: update t_user set born=?, password=?, username=? where id=?
4.TestPersistent03
session = HibernateUtil.openSession();
session.beginTransaction();
User u = new User();
u.setBorn(sdf.parse("1976-2-3"));
u.setUsername("zhangsan2");
u.setPassword("zhangsan2");
session.save(u);
/*
* 以下三条语句没有任何意义
*/
session.save(u);
session.update(u);
session.update(u);
u.setUsername("zhangsan3");
session.getTransaction().commit();
相信这个测试用例,大家应该都知道结果了,没错,此时hibernate也会发出两条sql语句,原理一样的
Hibernate: update t_user set born=?, password=?, username=? where id=?
5.TestPersistent04
session.beginTransaction();
//此时u是Persistent
User u = (User)session.load(User.class, 4);
//由于u这个对象和session中的对象不一致,所以会发出sql完成更新
u.setUsername("bbb");
session.getTransaction().commit();
我们来看看此时会发出多少sql语句呢?同样记住一点:当session调用load、get方法时,此时如果数据库中有该对象,则该对象也变成了一个持久化对象,被session所托管。因此,这个时候如果对对象进行操作,在提交事务时同样会去与session中的持久化对象进行比较,因此这里会发送两条sql语句
Hibernate: update t_user set born=?, password=?, username=? where id=?
6.TestPersistent05
没有评论:
发表评论