diff --git a/build/td-pkg-min.js b/build/td-pkg-min.js index 0c51ad4..41aa01f 100644 --- a/build/td-pkg-min.js +++ b/build/td-pkg-min.js @@ -1 +1,3 @@ -var _TD={a:[],init:function(c,d){delete this.init;var b,a={version:"0.1.16",is_debug:!!d,is_paused:true,width:16,height:16,show_monster_life:true,fps:0,exp_fps:24,exp_fps_half:12,exp_fps_quarter:6,exp_fps_eighth:4,stage_data:{},defaultSettings:function(){return{step_time:36,grid_size:32,padding:10,global_speed:0.1}},init:function(e){this.obj_board=a.lang.$e(e);this.canvas=this.obj_board.getElementsByTagName("canvas")[0];if(!this.canvas.getContext){return}this.ctx=this.canvas.getContext("2d");this.monster_type_count=a.getDefaultMonsterAttributes();this.iframe=0;this.last_iframe_time=(new Date()).getTime();this.fps=0;this.start()},start:function(){clearTimeout(this._st);a.log("Start!");var e=this;this._exp_fps_0=this.exp_fps-0.4;this._exp_fps_1=this.exp_fps+0.4;this.mode="normal";this.eventManager.clear();this.lang.mix(this,this.defaultSettings());this.stage=new a.Stage("stage-main",a.getDefaultStageData("stage_main"));this.canvas.setAttribute("width",this.stage.width);this.canvas.setAttribute("height",this.stage.height);this.canvas.onmousemove=function(g){var f=e.getEventXY.call(e,g);e.hover(f[0],f[1])};this.canvas.onclick=function(g){var f=e.getEventXY.call(e,g);e.click(f[0],f[1])};this.is_paused=false;this.stage.start();this.step();return this},checkCheat:function(e){switch(e){case"money+":this.money+=1000000;this.log("cheat success!");break;case"life+":this.life=100;this.log("cheat success!");break;case"life-":this.life=1;this.log("cheat success!");break;case"difficulty+":this.difficulty*=2;this.log("cheat success! difficulty = "+this.difficulty);break;case"difficulty-":this.difficulty/=2;this.log("cheat success! difficulty = "+this.difficulty);break}},step:function(){if(this.is_debug&&_TD&&_TD.cheat){this.checkCheat(_TD.cheat);_TD.cheat=""}if(this.is_paused){return}this.iframe++;if(this.iframe%50==0){var f=(new Date()).getTime(),e=this.step_time;this.fps=Math.round(500000/(f-this.last_iframe_time))/10;this.last_iframe_time=f;if(this.fps1){e--}else{if(this.fps>this._exp_fps_1){e++}}this.step_time=e}if(this.iframe%2400==0){a.gc()}this.stage.step();this.stage.render();var g=this;this._st=setTimeout(function(){g.step()},this.step_time)},getEventXY:function(h){var g=a.lang.$e("wrapper"),f=h.clientX-g.offsetLeft-this.canvas.offsetLeft+Math.max(document.documentElement.scrollLeft,document.body.scrollLeft),i=h.clientY-g.offsetTop-this.canvas.offsetTop+Math.max(document.documentElement.scrollTop,document.body.scrollTop);return[f,i]},hover:function(e,f){this.eventManager.hover(e,f)},click:function(e,f){this.eventManager.click(e,f)},mouseHand:function(e){this.canvas.style.cursor=e?"pointer":"default"},log:function(e){this.is_debug&&window.console&&console.log&&console.log(e)},gc:function(){if(window.CollectGarbage){CollectGarbage();setTimeout(CollectGarbage,1)}}};for(b=0;this.a[b];b++){this.a[b](a)}delete this.a;a.init(c)}};_TD.a.push(function(a){a.lang={$e:function(b){return document.getElementById(b)},$c:function(f,c,e){var d=document.createElement(f);c=c||{};for(var b in c){d.setAttribute(b,c[b])}if(e){e.appendChild(d)}return d},strLeft:function(g,h){var e=g.slice(0,h),f=e.replace(/[^\x00-\xff]/g,"**").length;if(f<=h){return e}f-=e.length;switch(f){case 0:return e;case h:return g.slice(0,h>>1);default:var c=h-f,b=g.slice(c,h),d=b.replace(/[\x00-\xff]/g,"").length;return d?g.slice(0,c)+this.arguments.callee(b,d):g.slice(0,c)}},strLen2:function(b){return b.replace(/[^\x00-\xff]/g,"**").length},each:function(e,d){if(Array.prototype.forEach){e.forEach(d)}else{for(var c=0,b=e.length;cb.x&&this.exb.y&&this.ey0){this._wait_clearInvalidElements--;return}this._wait_clearInvalidElements=f;var g=[];a.lang.shift(this.buildings,function(h){if(h.is_valid){g.push(h)}});this.buildings=g;g=[];a.lang.shift(this.monsters,function(h){if(h.is_valid){g.push(h)}});this.monsters=g;g=[];a.lang.shift(this.bullets,function(h){if(h.is_valid){g.push(h)}});this.bullets=g},addMonster:function(g){if(!this.entrance){return}if(typeof g=="number"){g=new a.Monster(null,{idx:g,difficulty:a.difficulty,step_level:this.step_level,render_level:this.render_level+2})}this.entrance.addMonster(g)},addMonsters:function(h,g){this._wait_add_monsters=h;this._wait_add_monsters_objidx=g},addMonsters2:function(g){this._wait_add_monsters_arr=g},checkPassable:function(i,h){var g=this.getGrid(i,h);return(g!=null&&g.passable_flag==1&&g.build_flag!=2)},step:function(){this.clearInvalidElements();if(this._wait_add_monsters>0){this.addMonster(this._wait_add_monsters_objidx);this._wait_add_monsters--}else{if(this._wait_add_monsters_arr.length>0){var g=this._wait_add_monsters_arr.shift();this.addMonsters(g[0],g[1])}}},render:function(){var g=a.ctx;g.strokeStyle="#99a";g.lineWidth=1;g.beginPath();g.strokeRect(this.x+0.5,this.y+0.5,this.width,this.height);g.closePath();g.stroke()},onOut:function(){if(this.is_main_map&&this.pre_building){this.pre_building.hide()}}};a.Map=function(i,g){g.on_events=["enter","out"];var h=new a.Element(i,g);a.lang.mix(h,d);h._init(g);return h};var c={_init:function(g){this.map=g.map;this.width=a.grid_size+2;this.height=a.grid_size+2;this.is_visiable=false},show:function(g){this.x=g.x;this.y=g.y;this.is_visiable=true},render:function(){var g=a.ctx;g.lineWidth=2;g.strokeStyle="#f93";g.beginPath();g.strokeRect(this.x,this.y,this.width-1,this.height-1);g.closePath();g.stroke()}};a.MapSelectHighLight=function(i,g){var h=new a.Element(i,g);a.lang.mix(h,c);h._init(g);return h};var e={_init:function(g){this.map=g.map;this.x1=this.map.x;this.y1=this.map.y;this.x2=this.map.x2+1;this.y2=this.map.y2+1;this.w=this.map.scene.stage.width;this.h=this.map.scene.stage.height;this.w2=this.w-this.x2;this.h2=this.h-this.y2},render:function(){var g=a.ctx;g.fillStyle="#fff";g.beginPath();g.fillRect(0,0,this.x1,this.h);g.fillRect(0,0,this.w,this.y1);g.fillRect(0,this.y2,this.w,this.h2);g.fillRect(this.x2,0,this.w2,this.h);g.closePath();g.fill()}};function b(i,g){var h=new a.Element(i,g);a.lang.mix(h,e);h._init(g);return h}});_TD.a.push(function(a){var b={_init:function(c){c=c||{};this.map=c.map;this.scene=this.map.scene;this.mx=c.mx;this.my=c.my;this.width=a.grid_size;this.height=a.grid_size;this.is_entrance=this.is_exit=false;this.passable_flag=1;this.build_flag=1,this.building=null;this.caculatePos()},caculatePos:function(){this.x=this.map.x+this.mx*a.grid_size;this.y=this.map.y+this.my*a.grid_size;this.x2=this.x+a.grid_size;this.y2=this.y+a.grid_size;this.cx=Math.floor(this.x+a.grid_size/2);this.cy=Math.floor(this.y+a.grid_size/2)},checkBlock:function(){if(this.is_entrance||this.is_exit){this._block_msg=a._t("entrance_or_exit_be_blocked");return true}var d,e=this,c=new a.FindWay(this.map.grid_x,this.map.grid_y,this.map.entrance.mx,this.map.entrance.my,this.map.exit.mx,this.map.exit.my,function(f,g){return !(f==e.mx&&g==e.my)&&e.map.checkPassable(f,g)});d=c.is_blocked;if(!d){d=!!this.map.anyMonster(function(f){return f.chkIfBlocked(e.mx,e.my)});if(d){this._block_msg=a._t("monster_be_blocked")}}else{this._block_msg=a._t("blocked")}return d},buyBuilding:function(c){var d=a.getDefaultBuildingAttributes(c).cost||0;if(a.money>=d){a.money-=d;this.addBuilding(c)}else{a.log(a._t("not_enough_money",[d]));this.scene.panel.balloontip.msg(a._t("not_enough_money",[d]),this)}},addBuilding:function(c){if(this.building){this.removeBuilding()}var d=new a.Building("building-"+c+"-"+a.lang.rndStr(),{type:c,step_level:this.step_level,render_level:this.render_level});d.locate(this);this.scene.addElement(d,this.step_level,this.render_level+1);this.map.buildings.push(d);this.building=d;this.build_flag=2;this.map.checkHasWeapon();if(this.map.pre_building){this.map.pre_building.hide()}},removeBuilding:function(){if(this.build_flag==2){this.build_flag=1}if(this.building){this.building.remove()}this.building=null},addMonster:function(c){c.beAddToGrid(this);this.map.monsters.push(c);c.start()},hightLight:function(c){this.map.select_hl[c?"show":"hide"](this)},render:function(){var c=a.ctx,e=this.x+0.5,d=this.y+0.5;if(this.is_hover){c.fillStyle="rgba(255, 255, 200, 0.2)";c.beginPath();c.fillRect(e,d,this.width,this.height);c.closePath();c.fill()}if(this.passable_flag==0){c.fillStyle="#fcc";c.beginPath();c.fillRect(e,d,this.width,this.height);c.closePath();c.fill()}if(this.is_entrance||this.is_exit){c.lineWidth=1;c.fillStyle="#ccc";c.beginPath();c.fillRect(e,d,this.width,this.height);c.closePath();c.fill();c.strokeStyle="#666";c.fillStyle=this.is_entrance?"#fff":"#666";c.beginPath();c.arc(this.cx,this.cy,a.grid_size*0.325,0,Math.PI*2,true);c.closePath();c.fill();c.stroke()}c.strokeStyle="#eee";c.lineWidth=1;c.beginPath();c.strokeRect(e,d,this.width,this.height);c.closePath();c.stroke()},onEnter:function(){if(this.map.is_main_map&&a.mode=="build"){if(this.build_flag==1){this.map.pre_building.show();this.map.pre_building.locate(this)}else{this.map.pre_building.hide()}}else{if(this.map.is_main_map){var c="";if(this.is_entrance){c=a._t("entrance")}else{if(this.is_exit){c=a._t("exit")}else{if(this.passable_flag==0){c=a._t("_cant_pass")}else{if(this.build_flag==0){c=a._t("_cant_build")}}}}if(c){this.scene.panel.balloontip.msg(c,this)}}}},onOut:function(){if(this.scene.panel.balloontip.el==this){this.scene.panel.balloontip.hide()}},onClick:function(){if(this.scene.state!=1){return}if(a.mode=="build"&&this.map.is_main_map&&!this.building){if(this.checkBlock()){this.scene.panel.balloontip.msg(this._block_msg,this)}else{this.buyBuilding(this.map.pre_building.type)}}else{if(!this.building&&this.map.selected_building){this.map.selected_building.toggleSelected();this.map.selected_building=null}}}};a.Grid=function(e,c){c.on_events=["enter","out","click"];var d=new a.Element(e,c);a.lang.mix(d,b);d._init(c);return d}});_TD.a.push(function(a){var c={_init:function(d){this.is_selected=false;this.level=0;this.killed=0;this.target=null;d=d||{};this.map=d.map||null;this.grid=d.grid||null;this.bullet_type=d.bullet_type||1;this.type=d.type;this.speed=d.speed;this.bullet_speed=d.bullet_speed;this.is_pre_building=!!d.is_pre_building;this.blink=this.is_pre_building;this.wait_blink=this._default_wait_blink=20;this.is_weapon=(this.type!="wall");var e=a.getDefaultBuildingAttributes(this.type);a.lang.mix(this,e);this.range_px=this.range*a.grid_size;this.money=this.cost;this.caculatePos()},getUpgradeCost:function(){return Math.floor(this.money*0.75)},getSellMoney:function(){return Math.floor(this.money*0.5)||1},toggleSelected:function(){this.is_selected=!this.is_selected;this.grid.hightLight(this.is_selected);var d=this;if(this.is_selected){this.map.eachBuilding(function(e){e.is_selected=e==d});(this.map.is_main_map?this.scene.panel_map:this.scene.map).eachBuilding(function(e){e.is_selected=false;e.grid.hightLight(false)});this.map.selected_building=this;if(!this.map.is_main_map){this.scene.map.preBuild(this.type)}else{this.scene.map.cancelPreBuild()}}else{if(this.map.selected_building==this){this.map.selected_building=null}if(!this.map.is_main_map){this.scene.map.cancelPreBuild()}}if(this.map.is_main_map){if(this.map.selected_building){this.scene.panel.btn_upgrade.show();this.scene.panel.btn_sell.show();this.updateBtnDesc()}else{this.scene.panel.btn_upgrade.hide();this.scene.panel.btn_sell.hide()}}},updateBtnDesc:function(){this.scene.panel.btn_upgrade.desc=a._t("upgrade",[a._t("building_name_"+this.type),this.level+1,this.getUpgradeCost()]);this.scene.panel.btn_sell.desc=a._t("sell",[a._t("building_name_"+this.type),this.getSellMoney()])},locate:function(d){this.grid=d;this.map=d.map;this.cx=this.grid.cx;this.cy=this.grid.cy;this.x=this.grid.x;this.y=this.grid.y;this.x2=this.grid.x2;this.y2=this.grid.y2;this.width=this.grid.width;this.height=this.grid.height;this.px=this.x+0.5;this.py=this.y+0.5;this.wait_blink=this._default_wait_blink;this._fire_wait=Math.floor(Math.max(2/(this.speed*a.global_speed),1));this._fire_wait2=this._fire_wait},remove:function(){if(this.grid&&this.grid.building&&this.grid.building==this){this.grid.building=null}this.hide();this.del()},findTaget:function(){if(!this.is_weapon||this.is_pre_building||!this.grid){return}var e=this.cx,f=this.cy,d=Math.pow(this.range_px,2);if(this.target&&this.target.is_valid&&Math.pow(this.target.cx-e,2)+Math.pow(this.target.cy-f,2)<=d){return}this.target=a.lang.any(a.lang.rndSort(this.map.monsters),function(g){return Math.pow(g.cx-e,2)+Math.pow(g.cy-f,2)<=d})},getTargetPosition:function(){if(!this.target){var d=this.map.is_main_map?this.map.entrance:this.grid;return[d.cx,d.cy]}return[this.target.cx,this.target.cy]},fire:function(){if(!this.target||!this.target.is_valid){return}if(this.type=="laser_gun"){this.target.beHit(this,this.damage);return}var e=this.muzzle||[this.cx,this.cy],d=e[0],f=e[1];new a.Bullet(null,{building:this,damage:this.damage,target:this.target,speed:this.bullet_speed,x:d,y:f})},tryToFire:function(){if(!this.is_weapon||!this.target){return}this._fire_wait--;if(this._fire_wait>0){}else{if(this._fire_wait<0){this._fire_wait=this._fire_wait2}else{this.fire()}}},_upgrade2:function(f){if(!this._upgrade_records[f]){this._upgrade_records[f]=this[f]}var e=this._upgrade_records[f],d="max_"+f,g="_upgrade_rule_"+f,h=this[g]||a.default_upgrade_rule;if(!e||isNaN(e)){return}e=h(this.level,e);if(this[d]&&!isNaN(this[d])&&this[d]a.money){e=a._t("not_enough_money",[f])}else{a.money-=f;this.money+=f;this.upgrade();e=a._t("upgrade_success",[a._t("building_name_"+this.type),this.level,this.getUpgradeCost()])}this.updateBtnDesc();this.scene.panel.balloontip.msg(e,d)},tryToSell:function(){if(!this.is_valid){return}a.money+=this.getSellMoney();this.grid.removeBuilding();this.is_valid=false;this.map.selected_building=null;this.map.select_hl.hide();this.map.checkHasWeapon();this.scene.panel.btn_upgrade.hide();this.scene.panel.btn_sell.hide();this.scene.panel.balloontip.hide()},step:function(){if(this.blink){this.wait_blink--;if(this.wait_blink<-this._default_wait_blink){this.wait_blink=this._default_wait_blink}}this.findTaget();this.tryToFire()},render:function(){if(!this.is_visiable||this.wait_blink<0){return}var d=a.ctx;a.renderBuilding(this);if(this.map.is_main_map&&(this.is_selected||(this.is_pre_building)||this.map.show_all_ranges)&&this.is_weapon&&this.range>0&&this.grid){d.lineWidth=1;d.fillStyle="rgba(187, 141, 32, 0.15)";d.strokeStyle="#bb8d20";d.beginPath();d.arc(this.cx,this.cy,this.range_px,0,Math.PI*2,true);d.closePath();d.fill();d.stroke()}if(this.type=="laser_gun"&&this.target&&this.target.is_valid){d.lineWidth=3;d.strokeStyle="rgba(50, 50, 200, 0.5)";d.beginPath();d.moveTo(this.cx,this.cy);d.lineTo(this.target.cx,this.target.cy);d.closePath();d.stroke();d.lineWidth=1;d.strokeStyle="rgba(150, 150, 255, 0.5)";d.beginPath();d.lineTo(this.cx,this.cy);d.closePath();d.stroke()}},onEnter:function(){if(this.is_pre_building){return}var d="\u5efa\u7b51\u5de5\u4e8b";if(this.map.is_main_map){d=a._t("building_info"+(this.type=="wall"?"_wall":""),[a._t("building_name_"+this.type),this.level,this.damage,this.speed,this.range,this.killed])}else{d=a._t("building_intro_"+this.type,[a.getDefaultBuildingAttributes(this.type).cost])}this.scene.panel.balloontip.msg(d,this.grid)},onOut:function(){if(this.scene.panel.balloontip.el==this.grid){this.scene.panel.balloontip.hide()}},onClick:function(){if(this.is_pre_building||this.scene.state!=1){return}this.toggleSelected()}};a.Building=function(f,d){d.on_events=["enter","out","click"];var e=new a.Element(f,d);a.lang.mix(e,c);e._init(d);return e};var b={_init:function(d){d=d||{};this.speed=d.speed;this.damage=d.damage;this.target=d.target;this.cx=d.x;this.cy=d.y;this.r=d.r||Math.max(Math.log(this.damage),2);if(this.r<1){this.r=1}if(this.r>6){this.r=6}this.building=d.building||null;this.map=d.map||this.building.map;this.type=d.type||1;this.color=d.color||"#000";this.map.bullets.push(this);this.addToScene(this.map.scene,1,6);if(this.type==1){this.caculate()}},caculate:function(){var i,g,h,e=this.target.cx,d=this.target.cy,f;i=e-this.cx;g=d-this.cy;h=Math.sqrt(Math.pow(i,2)+Math.pow(g,2)),f=20*this.speed*a.global_speed,this.vx=i*f/h,this.vy=g*f/h},checkOutOfMap:function(){this.is_valid=!(this.cxthis.map.x2||this.cythis.map.y2);return !this.is_valid},checkHit:function(){var d=this.cx,g=this.cy,f=this.r,e=this.map.anyMonster(function(h){return Math.pow(h.cx-d,2)+Math.pow(h.cy-g,2)<=Math.pow(h.r+f,2)*2});if(e){e.beHit(this.building,this.damage);this.is_valid=false;a.Explode(this.id+"-explode",{cx:this.cx,cy:this.cy,r:this.r,step_level:this.step_level,render_level:this.render_level,color:this.color,scene:this.map.scene,time:0.2});return true}return false},step:function(){if(this.checkOutOfMap()||this.checkHit()){return}this.cx+=this.vx;this.cy+=this.vy},render:function(){var d=a.ctx;d.fillStyle=this.color;d.beginPath();d.arc(this.cx,this.cy,this.r,0,Math.PI*2,true);d.closePath();d.fill()}};a.Bullet=function(f,e){var d=new a.Element(f,e);a.lang.mix(d,b);d._init(e);return d}});_TD.a.push(function(a){var b={_init:function(e){e=e||{};this.is_monster=true;this.idx=e.idx||1;this.difficulty=e.difficulty||1;var d=a.getDefaultMonsterAttributes(this.idx);this.speed=Math.floor((d.speed+this.difficulty/2)*(Math.random()*0.5+0.75));if(this.speed<1){this.speed=1}if(this.speed>e.max_speed){this.speed=e.max_speed}this.life=this.life0=Math.floor(d.life*(this.difficulty+1)*(Math.random()+0.5)*0.5);if(this.life<1){this.life=this.life0=1}this.shield=Math.floor(d.shield+this.difficulty/2);if(this.shield<0){this.shield=0}this.damage=Math.floor((d.damage||1)*(Math.random()*0.5+0.75));if(this.damage<1){this.damage=1}this.money=d.money||Math.floor(Math.sqrt((this.speed+this.life)*(this.shield+1)*this.damage));if(this.money<1){this.money=1}this.color=d.color||a.lang.rndRGB();this.r=Math.floor(this.damage*1.2);if(this.r<4){this.r=4}if(this.r>a.grid_size/2-4){this.r=a.grid_size/2-4}this.render=d.render;this.grid=null;this.map=null;this.next_grid=null;this.way=[];this.toward=2;this._dx=0;this._dy=0;this.is_blocked=false},caculatePos:function(){var d=this.r;this.x=this.cx-d;this.y=this.cy-d;this.x2=this.cx+d;this.y2=this.cy+d},beHit:function(d,e){if(!this.is_valid){return}var g=Math.ceil(e*0.1);e-=this.shield;if(e<=g){e=g}this.life-=e;a.score+=Math.floor(Math.sqrt(e));if(this.life<=0){this.beKilled(d)}var f=this.scene.panel.balloontip;if(f.el==this){f.text=a._t("monster_info",[this.life,this.shield,this.speed,this.damage])}},beKilled:function(d){if(!this.is_valid){return}this.life=0;this.is_valid=false;a.money+=this.money;d.killed++;a.Explode(this.id+"-explode",{cx:this.cx,cy:this.cy,color:this.color,r:this.r,step_level:this.step_level,render_level:this.render_level,scene:this.grid.scene})},arrive:function(){this.grid=this.next_grid;this.next_grid=null;this.checkFinish()},findWay:function(){var e=this;var d=new a.FindWay(this.map.grid_x,this.map.grid_y,this.grid.mx,this.grid.my,this.map.exit.mx,this.map.exit.my,function(f,g){return e.map.checkPassable(f,g)});this.way=d.way;delete d},checkFinish:function(){if(this.grid&&this.map&&this.grid==this.map.exit){a.life-=this.damage;a.wave_damage+=this.damage;if(a.life<=0){a.life=0;a.stage.gameover()}else{this.pause();this.del()}}},beAddToGrid:function(d){this.grid=d;this.map=d.map;this.cx=d.cx;this.cy=d.cy;this.grid.scene.addElement(this)},getToward:function(){if(!this.grid||!this.next_grid){return}if(this.grid.mythis.next_grid.my){this.toward=2}else{if(this.grid.mx>this.next_grid.mx){this.toward=3}}}}},getNextGrid:function(){if(this.way.length==0||Math.random()<0.1){this.findWay()}var d=this.way.shift();if(d&&!this.map.checkPassable(d[0],d[1])){this.findWay();d=this.way.shift()}if(!d){return}this.next_grid=this.map.getGrid(d[0],d[1])},chkIfBlocked:function(f,e){var g=this,d=new a.FindWay(this.map.grid_x,this.map.grid_y,this.grid.mx,this.grid.my,this.map.exit.mx,this.map.exit.my,function(h,i){return !(h==f&&i==e)&&g.map.checkPassable(h,i)});return d.is_blocked},beBlocked:function(){if(this.is_blocked){return}this.is_blocked=true;a.log("monster be blocked!")},step:function(){if(!this.is_valid||this.is_paused||!this.grid){return}if(!this.next_grid){this.getNextGrid();if(!this.next_grid){this.beBlocked();return}}if(this.cx==this.next_grid.cx&&this.cy==this.next_grid.cy){this.arrive()}else{var d=this.next_grid.cx-this.cx,h=this.next_grid.cy-this.cy,g=d<0?-1:1,f=h<0?-1:1,e=this.speed*a.global_speed;if(Math.abs(d)0;this.rgb_a=this.wait/this.wait0},render:function(){var d=a.ctx;d.fillStyle="rgba("+this.rgb_r+","+this.rgb_g+","+this.rgb_b+","+this.rgb_a+")";d.beginPath();d.arc(this.cx,this.cy,this.r,0,Math.PI*2,true);d.closePath();d.fill()}};a.Explode=function(f,d){var e=new a.Element(f,d);a.lang.mix(e,c);e._init(d);return e}});_TD.a.push(function(a){var d={_init:function(f){f=f||{};this.x=f.x;this.y=f.y;this.scene=f.scene;this.map=f.main_map;var g=new a.Map("panel-map",a.lang.mix({x:this.x+f.map.x,y:this.y+f.map.y,scene:this.scene,step_level:this.step_level,render_level:this.render_level},f.map,false));this.addToScene(this.scene,1,7);g.addToScene(this.scene,1,7,g.grids);this.scene.panel_map=g;this.gameover_obj=new a.GameOver("panel-gameover",{panel:this,scene:this.scene,step_level:this.step_level,is_visiable:false,x:0,y:0,width:this.scene.stage.width,height:this.scene.stage.height,render_level:9});this.balloontip=new a.BalloonTip("panel-balloon-tip",{scene:this.scene,step_level:this.step_level,render_level:9});this.balloontip.addToScene(this.scene,1,9);this.btn_pause=new a.Button("panel-btn-pause",{scene:this.scene,x:this.x,y:this.y+260,text:a._t("button_pause_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){if(this.scene.state==1){this.scene.pause();this.text=a._t("button_continue_text");this.scene.panel.btn_upgrade.hide();this.scene.panel.btn_sell.hide();this.scene.panel.btn_restart.show()}else{if(this.scene.state==2){this.scene.start();this.text=a._t("button_pause_text");this.scene.panel.btn_restart.hide();if(this.scene.map.selected_building){this.scene.panel.btn_upgrade.show();this.scene.panel.btn_sell.show()}}}}});this.btn_restart=new a.Button("panel-btn-restart",{scene:this.scene,x:this.x,y:this.y+300,is_visiable:false,text:a._t("button_restart_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){setTimeout(function(){a.stage.clear();a.is_paused=true;a.start();a.mouseHand(false)},0)}});this.btn_upgrade=new a.Button("panel-btn-upgrade",{scene:this.scene,x:this.x,y:this.y+300,is_visiable:false,text:a._t("button_upgrade_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){this.scene.map.selected_building.tryToUpgrade(this)}});this.btn_sell=new a.Button("panel-btn-sell",{scene:this.scene,x:this.x,y:this.y+340,is_visiable:false,text:a._t("button_sell_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){this.scene.map.selected_building.tryToSell(this)}})},step:function(){if(a.life_recover){this._life_recover=this._life_recover2=a.life_recover;this._life_recover_wait=this._life_recover_wait2=a.exp_fps*3;a.life_recover=0}if(this._life_recover&&(a.iframe%a.exp_fps_eighth==0)){a.life++;this._life_recover--}},render:function(){var g=a.ctx;g.textAlign="left";g.textBaseline="top";g.fillStyle="#000";g.font="normal 12px 'Courier New'";g.beginPath();g.fillText(a._t("panel_money_title")+a.money,this.x,this.y);g.fillText(a._t("panel_score_title")+a.score,this.x,this.y+20);g.fillText(a._t("panel_life_title")+a.life,this.x,this.y+40);g.fillText(a._t("panel_building_title")+this.map.buildings.length,this.x,this.y+60);g.fillText(a._t("panel_monster_title")+this.map.monsters.length,this.x,this.y+80);g.fillText(a._t("wave_info",[this.scene.wave]),this.x,this.y+210);g.closePath();if(this._life_recover_wait){var f=this._life_recover_wait/this._life_recover_wait2;g.fillStyle="rgba(255, 0, 0, "+f+")";g.font="bold 12px 'Verdana'";g.beginPath();g.fillText("+"+this._life_recover2,this.x+60,this.y+40);g.closePath();this._life_recover_wait--}g.textAlign="right";g.fillStyle="#666";g.font="normal 12px 'Courier New'";g.beginPath();g.fillText("version: "+a.version+" | oldj.net",a.stage.width-a.padding,a.stage.height-a.padding*2);g.closePath();g.textAlign="left";g.fillStyle="#666";g.font="normal 12px 'Courier New'";g.beginPath();g.fillText("FPS: "+a.fps,a.padding,a.stage.height-a.padding*2);g.closePath()}};a.Panel=function(h,g){var f=new a.Element(h,g);a.lang.mix(f,d);f._init(g);return f};var b={_init:function(f){f=f||{};this.scene=f.scene},caculatePos:function(){var f=this.el;this.x=f.cx+0.5;this.y=f.cy+0.5;if(this.x+this.width>this.scene.stage.width-a.padding){this.x=this.x-this.width}this.px=this.x+5;this.py=this.y+4},msg:function(f,h){this.text=f;var g=a.ctx;g.font="normal 12px 'Courier New'";this.width=Math.max(g.measureText(f).width+10,a.lang.strLen2(f)*6+10);this.height=24;if(h&&h.cx&&h.cy){this.el=h;this.caculatePos();this.show()}},step:function(){if(!this.el||!this.el.is_valid){this.hide();return}if(this.el.is_monster){this.caculatePos()}},render:function(){if(!this.el){return}var f=a.ctx;f.lineWidth=1;f.fillStyle="rgba(255, 255, 0, 0.5)";f.strokeStyle="rgba(222, 222, 0, 0.9)";f.beginPath();f.rect(this.x,this.y,this.width,this.height);f.closePath();f.fill();f.stroke();f.textAlign="left";f.textBaseline="top";f.fillStyle="#000";f.font="normal 12px 'Courier New'";f.beginPath();f.fillText(this.text,this.px,this.py);f.closePath()}};a.BalloonTip=function(h,f){var g=new a.Element(h,f);a.lang.mix(g,b);g._init(f);return g};var e={_init:function(f){f=f||{};this.text=f.text;this.onClick=f.onClick||a.lang.nullFunc;this.x=f.x;this.y=f.y;this.width=f.width||80;this.height=f.height||30;this.font_x=this.x+8;this.font_y=this.y+7;this.scene=f.scene;this.desc=f.desc||"";this.addToScene(this.scene,this.step_level,this.render_level);this.caculatePos()},onEnter:function(){a.mouseHand(true);if(this.desc){this.scene.panel.balloontip.msg(this.desc,this)}},onOut:function(){a.mouseHand(false);if(this.scene.panel.balloontip.el==this){this.scene.panel.balloontip.hide()}},render:function(){var f=a.ctx;f.lineWidth=2;f.fillStyle=this.is_hover?"#eee":"#ccc";f.strokeStyle="#999";f.beginPath();f.rect(this.x,this.y,this.width,this.height);f.closePath();f.fill();f.stroke();f.textAlign="left";f.textBaseline="top";f.fillStyle="#000";f.font="normal 12px 'Courier New'";f.beginPath();f.fillText(this.text,this.font_x,this.font_y);f.closePath();f.fill()}};a.Button=function(h,f){f.on_events=["enter","out","click"];var g=new a.Element(h,f);a.lang.mix(g,e);g._init(f);return g};var c={_init:function(f){this.panel=f.panel;this.scene=f.scene;this.addToScene(this.scene,1,9)},render:function(){this.panel.btn_pause.hide();this.panel.btn_upgrade.hide();this.panel.btn_sell.hide();this.panel.btn_restart.show();var f=a.ctx;f.textAlign="center";f.textBaseline="middle";f.fillStyle="#ccc";f.font="bold 62px 'Verdana'";f.beginPath();f.fillText("GAME OVER",this.width/2,this.height/2);f.closePath();f.fillStyle="#f00";f.font="bold 60px 'Verdana'";f.beginPath();f.fillText("GAME OVER",this.width/2,this.height/2);f.closePath()}};a.GameOver=function(h,f){var g=new a.Element(h,f);a.lang.mix(g,c);g._init(f);return g};a.recover=function(f){a.life_recover=f;a.log("life recover: "+f)}});_TD.a.push(function(a){var c=function(){var e=new a.Act(this,"act-1"),g=new a.Scene(e,"scene-1"),d=a.getDefaultStageData("scene_endless");this.config=d.config;a.life=this.config.life;a.money=this.config.money;a.score=this.config.score;a.difficulty=this.config.difficulty;a.wave_damage=this.config.wave_damage;var f=new a.Map("main-map",a.lang.mix({scene:g,is_main_map:true,step_level:1,render_level:2},d.map));f.addToScene(g,1,2,f.grids);g.map=f;g.panel=new a.Panel("panel",a.lang.mix({scene:g,main_map:f,step_level:1,render_level:7},d.panel));this.newWave=d.newWave;this.map=f;this.wait_new_wave=this.config.wait_new_wave},b=function(){var f=this.current_act.current_scene,d=f.wave;if((d==0&&!this.map.has_weapon)||f.state!=1){return}if(this.map.monsters.length==0){if(d>0&&this.wait_new_wave==this.config.wait_new_wave-1){var e=0;if(d%10==0){e=10}else{if(d%5==0){e=5}}if(a.life+e>100){e=100-a.life}if(e>0){a.recover(e)}}if(this.wait_new_wave>0){this.wait_new_wave--;return}this.wait_new_wave=this.config.wait_new_wave;d++;f.wave=d;this.newWave({map:this.map,wave:d})}};a.getDefaultStageData=function(d){var e={stage_main:{width:640,height:560,init:c,step2:b},scene_endless:{map:{grid_x:16,grid_y:16,x:a.padding,y:a.padding,entrance:[0,0],exit:[15,15],grids_cfg:[{pos:[3,3],passable_flag:0},{pos:[7,15],build_flag:0},{pos:[4,12],building:"wall"},{pos:[4,13],building:"wall"}]},panel:{x:a.padding*2+a.grid_size*16,y:a.padding,map:{grid_x:3,grid_y:3,x:0,y:110,grids_cfg:[{pos:[0,0],building:"cannon"},{pos:[1,0],building:"LMG"},{pos:[2,0],building:"HMG"},{pos:[0,1],building:"laser_gun"},{pos:[2,2],building:"wall"}]}},config:{endless:true,wait_new_wave:a.exp_fps*3,difficulty:1,wave:0,max_wave:-1,wave_damage:0,max_monsters_per_wave:100,money:500,score:0,life:100,waves:[[],[[1,0]],[[1,0],[1,1]],[[2,0],[1,1]],[[2,0],[1,1]],[[3,0],[2,1]],[[4,0],[2,1]],[[5,0],[3,1],[1,2]],[[6,0],[4,1],[1,2]],[[7,0],[3,1],[2,2]],[[8,0],[4,1],[3,2]]]},newWave:function(g){g=g||{};var j=g.map,i=g.wave||1,h=a.wave_damage||0;if(i==1){}else{if(h==0){if(i<5){a.difficulty*=1.05}else{if(a.difficulty>30){a.difficulty*=1.1}else{a.difficulty*=1.2}}}else{if(a.wave_damage>=50){a.difficulty*=0.6}else{if(a.wave_damage>=30){a.difficulty*=0.7}else{if(a.wave_damage>=20){a.difficulty*=0.8}else{if(a.wave_damage>=10){a.difficulty*=0.9}else{if(i>=10){a.difficulty*=1.05}}}}}}}if(a.difficulty<1){a.difficulty=1}a.log("wave "+i+", last wave damage = "+h+", difficulty = "+a.difficulty);var f=this.config.waves[i]||a.makeMonsters(Math.min(Math.floor(Math.pow(i,1.1)),this.config.max_monsters_per_wave));j.addMonsters2(f);a.wave_damage=0}}};return e[d]||{}}});_TD.a.push(function(a){a.default_upgrade_rule=function(c,b){return b*1.2};a.getDefaultBuildingAttributes=function(b){var c={wall:{damage:0,range:0,speed:0,bullet_speed:0,life:100,shield:500,cost:5},cannon:{damage:12,range:4,max_range:8,speed:2,bullet_speed:6,life:100,shield:100,cost:300,_upgrade_rule_damage:function(e,d){return d*(e<=10?1.2:1.3)}},LMG:{damage:5,range:5,max_range:10,speed:3,bullet_speed:6,life:100,shield:50,cost:100},HMG:{damage:30,range:3,max_range:5,speed:3,bullet_speed:5,life:100,shield:200,cost:800,_upgrade_rule_damage:function(e,d){return d*1.3}},laser_gun:{damage:25,range:6,max_range:10,speed:20,life:100,shield:100,cost:2000}};return c[b]||{}}});_TD.a.push(function(a){function b(){if(!this.is_valid||!this.grid){return}var d=a.ctx;d.strokeStyle="#000";d.lineWidth=1;d.fillStyle=this.color;d.beginPath();d.arc(this.cx,this.cy,this.r,0,Math.PI*2,true);d.closePath();d.fill();d.stroke();if(a.show_monster_life){var e=Math.floor(a.grid_size/4),c=e*2-2;d.fillStyle="#000";d.beginPath();d.fillRect(this.cx-e,this.cy-this.r-6,e*2,4);d.closePath();d.fillStyle="#f00";d.beginPath();d.fillRect(this.cx-e+1,this.cy-this.r-5,this.life*c/this.life0,2);d.closePath()}}a.getDefaultMonsterAttributes=function(f){var d=[{name:"monster 1",desc:"\u6700\u5f31\u5c0f\u7684\u602a\u7269",speed:3,max_speed:10,life:50,damage:1,shield:0,money:5},{name:"monster 2",desc:"\u7a0d\u5f3a\u4e00\u4e9b\u7684\u5c0f\u602a",speed:6,max_speed:20,life:50,damage:2,shield:1},{name:"monster speed",desc:"\u901f\u5ea6\u8f83\u5feb\u7684\u5c0f\u602a",speed:12,max_speed:30,life:50,damage:3,shield:1},{name:"monster life",desc:"\u751f\u547d\u503c\u5f88\u5f3a\u7684\u5c0f\u602a",speed:5,max_speed:10,life:500,damage:3,shield:1},{name:"monster shield",desc:"\u9632\u5fa1\u5f88\u5f3a\u7684\u5c0f\u602a",speed:5,max_speed:10,life:50,damage:3,shield:20},{name:"monster damage",desc:"\u4f24\u5bb3\u503c\u5f88\u5927\u7684\u5c0f\u602a",speed:7,max_speed:14,life:50,damage:10,shield:2},{name:"monster speed-life",desc:"\u901f\u5ea6\u3001\u751f\u547d\u90fd\u8f83\u9ad8\u7684\u602a\u7269",speed:15,max_speed:30,life:100,damage:3,shield:3},{name:"monster speed-2",desc:"\u901f\u5ea6\u5f88\u5feb\u7684\u602a\u7269",speed:30,max_speed:40,life:30,damage:4,shield:1},{name:"monster shield-life",desc:"\u9632\u5fa1\u5f88\u5f3a\u3001\u751f\u547d\u503c\u5f88\u9ad8\u7684\u602a\u7269",speed:3,max_speed:10,life:300,damage:5,shield:15}];if(typeof f=="undefined"){return d.length}var c=d[f]||d[0],e={};a.lang.mix(e,c);if(!e.render){e.render=b}return e};a.makeMonsters=function(f,j){var p=[],k=0,h,o,m,e,g=a.monster_type_count;if(!j){j=[];for(h=0;hr?r+k:r-k}else{if(r==q){n=r;e=g>h?h+k:h-k}else{o=(r-q)/(h-g);m=r-h*o;d=o*o+1;l=2*(o*(m-r)-h);j=Math.pow(m-r,2)+h*h-Math.pow(k,2);f=Math.pow(l,2)-4*d*j;if(f<0){return[0,0]}f=Math.sqrt(f);i=(-l+f)/(2*d);if((g-h>0&&i-h>0)||(g-h<0&&i-h<0)){e=i;n=o*e+m}else{e=(-l-f)/(2*d);n=o*e+m}}}s.lineCap="round";s.moveTo(h,r);s.lineTo(e,n);return[e,n]}var a={cannon:function(d,e,h,f,i){var g=d.getTargetPosition();e.fillStyle="#393";e.strokeStyle="#000";e.beginPath();e.lineWidth=1;e.arc(d.cx,d.cy,i-5,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.lineWidth=3;e.beginPath();e.moveTo(d.cx,d.cy);d.muzzle=c(e,d.cx,d.cy,g[0],g[1],i);e.closePath();e.stroke();e.lineWidth=1;e.fillStyle="#060";e.beginPath();e.arc(d.cx,d.cy,7,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.fillStyle="#cec";e.beginPath();e.arc(d.cx+2,d.cy-2,3,0,Math.PI*2,true);e.closePath();e.fill()},LMG:function(d,e,h,f,i){var g=d.getTargetPosition();e.fillStyle="#36f";e.strokeStyle="#000";e.beginPath();e.lineWidth=1;e.arc(d.cx,d.cy,7,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.lineWidth=2;e.beginPath();e.moveTo(d.cx,d.cy);d.muzzle=c(e,d.cx,d.cy,g[0],g[1],i);e.closePath();e.fill();e.stroke();e.lineWidth=1;e.fillStyle="#66c";e.beginPath();e.arc(d.cx,d.cy,5,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.fillStyle="#ccf";e.beginPath();e.arc(d.cx+1,d.cy-1,2,0,Math.PI*2,true);e.closePath();e.fill()},HMG:function(d,e,h,f,i){var g=d.getTargetPosition();e.fillStyle="#933";e.strokeStyle="#000";e.beginPath();e.lineWidth=1;e.arc(d.cx,d.cy,i-2,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.lineWidth=5;e.beginPath();e.moveTo(d.cx,d.cy);d.muzzle=c(e,d.cx,d.cy,g[0],g[1],i);e.closePath();e.fill();e.stroke();e.lineWidth=1;e.fillStyle="#630";e.beginPath();e.arc(d.cx,d.cy,i-5,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.fillStyle="#960";e.beginPath();e.arc(d.cx+1,d.cy-1,8,0,Math.PI*2,true);e.closePath();e.fill();e.fillStyle="#fcc";e.beginPath();e.arc(d.cx+3,d.cy-3,4,0,Math.PI*2,true);e.closePath();e.fill()},wall:function(d,e,g,f,h){e.lineWidth=1;e.fillStyle="#666";e.strokeStyle="#000";e.fillRect(d.cx-h+1,d.cy-h+1,f-1,f-1);e.beginPath();e.moveTo(d.cx-h+0.5,d.cy-h+0.5);e.lineTo(d.cx-h+0.5,d.cy+h+0.5);e.lineTo(d.cx+h+0.5,d.cy+h+0.5);e.lineTo(d.cx+h+0.5,d.cy-h+0.5);e.lineTo(d.cx-h+0.5,d.cy-h+0.5);e.moveTo(d.cx-h+0.5,d.cy+h+0.5);e.lineTo(d.cx+h+0.5,d.cy-h+0.5);e.moveTo(d.cx-h+0.5,d.cy-h+0.5);e.lineTo(d.cx+h+0.5,d.cy+h+0.5);e.closePath();e.stroke()},laser_gun:function(d,e){e.fillStyle="#f00";e.strokeStyle="#000";e.beginPath();e.lineWidth=1;e.moveTo(d.cx,d.cy-10);e.lineTo(d.cx-8.66,d.cy+5);e.lineTo(d.cx+8.66,d.cy+5);e.lineTo(d.cx,d.cy-10);e.closePath();e.fill();e.stroke();e.fillStyle="#60f";e.beginPath();e.arc(d.cx,d.cy,7,0,Math.PI*2,true);e.closePath();e.fill();e.stroke();e.fillStyle="#000";e.beginPath();e.arc(d.cx,d.cy,3,0,Math.PI*2,true);e.closePath();e.fill();e.fillStyle="#666";e.beginPath();e.arc(d.cx+1,d.cy-1,1,0,Math.PI*2,true);e.closePath();e.fill();e.lineWidth=3;e.beginPath();e.moveTo(d.cx,d.cy);e.closePath();e.fill();e.stroke()}};b.renderBuilding=function(f){var d=b.ctx,g=f.map,e=b.grid_size,h=b.grid_size/2;(a[f.type]||a.wall)(f,d,g,e,h)}});_TD.a.push(function(a){a._msg_texts={_cant_build:"\u4e0d\u80fd\u5728\u8fd9\u513f\u4fee\u5efa",_cant_pass:"\u602a\u7269\u4e0d\u80fd\u901a\u8fc7\u8fd9\u513f",entrance:"\u8d77\u70b9",exit:"\u7ec8\u70b9",not_enough_money:"\u91d1\u94b1\u4e0d\u8db3\uff0c\u9700\u8981 $${0}\uff01",wave_info:"\u7b2c ${0} \u6ce2",panel_money_title:"\u91d1\u94b1: ",panel_score_title:"\u79ef\u5206: ",panel_life_title:"\u751f\u547d: ",panel_building_title:"\u5efa\u7b51: ",panel_monster_title:"\u602a\u7269: ",building_name_wall:"\u8def\u969c",building_name_cannon:"\u70ae\u53f0",building_name_LMG:"\u8f7b\u673a\u67aa",building_name_HMG:"\u91cd\u673a\u67aa",building_name_laser_gun:"\u6fc0\u5149\u70ae",building_info:"${0}: \u7b49\u7ea7 ${1}\uff0c\u653b\u51fb ${2}\uff0c\u901f\u5ea6 ${3}\uff0c\u5c04\u7a0b ${4}\uff0c\u6218\u7ee9 ${5}",building_info_wall:"${0}",building_intro_wall:"\u8def\u969c \u53ef\u4ee5\u963b\u6b62\u602a\u7269\u901a\u8fc7 ($${0})",building_intro_cannon:"\u70ae\u53f0 \u5c04\u7a0b\u3001\u6740\u4f24\u529b\u8f83\u4e3a\u5e73\u8861 ($${0})",building_intro_LMG:"\u8f7b\u673a\u67aa \u5c04\u7a0b\u8f83\u8fdc\uff0c\u6740\u4f24\u529b\u4e00\u822c ($${0})",building_intro_HMG:"\u91cd\u673a\u67aa \u5feb\u901f\u5c04\u51fb\uff0c\u5a01\u529b\u8f83\u5927\uff0c\u5c04\u7a0b\u4e00\u822c ($${0})",building_intro_laser_gun:"\u6fc0\u5149\u67aa \u4f24\u5bb3\u8f83\u5927\uff0c\u547d\u4e2d\u7387 100% ($${0})",click_to_build:"\u5de6\u952e\u70b9\u51fb\u5efa\u9020 ${0} ($${1})",upgrade:"\u5347\u7ea7 ${0} \u5230 ${1} \u7ea7\uff0c\u9700\u82b1\u8d39 $${2}\u3002",sell:"\u51fa\u552e ${0}\uff0c\u53ef\u83b7\u5f97 $${1}",upgrade_success:"\u5347\u7ea7\u6210\u529f\uff0c${0} \u5df2\u5347\u7ea7\u5230 ${1} \u7ea7\uff01\u4e0b\u6b21\u5347\u7ea7\u9700\u8981 $${2}\u3002",monster_info:"\u602a\u7269: \u751f\u547d ${0}\uff0c\u9632\u5fa1 ${1}\uff0c\u901f\u5ea6 ${2}\uff0c\u4f24\u5bb3 ${3}",button_upgrade_text:"\u5347\u7ea7",button_sell_text:"\u51fa\u552e",button_start_text:"\u5f00\u59cb",button_restart_text:"\u91cd\u65b0\u5f00\u59cb",button_pause_text:"\u6682\u505c",button_continue_text:"\u7ee7\u7eed",button_pause_desc_0:"\u6e38\u620f\u6682\u505c",button_pause_desc_1:"\u6e38\u620f\u7ee7\u7eed",blocked:"\u4e0d\u80fd\u5728\u8fd9\u513f\u4fee\u5efa\u5efa\u7b51\uff0c\u8d77\u70b9\u4e0e\u7ec8\u70b9\u4e4b\u95f4\u81f3\u5c11\u8981\u6709\u4e00\u6761\u8def\u53ef\u5230\u8fbe\uff01",monster_be_blocked:"\u4e0d\u80fd\u5728\u8fd9\u513f\u4fee\u5efa\u5efa\u7b51\uff0c\u6709\u602a\u7269\u88ab\u56f4\u8d77\u6765\u4e86\uff01",entrance_or_exit_be_blocked:"\u4e0d\u80fd\u5728\u8d77\u70b9\u6216\u7ec8\u70b9\u5904\u4fee\u5efa\u5efa\u7b51\uff01",_:"ERROR"};a._t=a.translate=function(c,d){d=(typeof d=="object"&&d.constructor==Array)?d:[];var f=this._msg_texts[c]||this._msg_texts._,e,b=d.length;for(e=0;ethis.len){return false}this.m[d]=c},getNeighborsOf:function(b,d){var c=[];if(d>0){c.push([b,d-1])}if(b0){c.push([b-1,d])}return c},getAllNeighbors:function(){var e=[],d,f,g,b=this.current.length;for(f=0;fn){m=n}}for(d=0;d1?Math.floor(Math.random()*c):0;f=k[d];h=f[0];g=f[1]}},arrive:function(){this.current=[];this.is_arrived=true;this.findWay()},blocked:function(){this.current=[];this.is_blocked=true},next:function(){var h=this.getAllNeighbors(),c,d=h.length,f=[],b,j,g,e;this.distance++;for(g=0;g1?i--:this.fps>this._exp_fps_1&&i++,this.step_time=i}this.iframe%2400==0&&s.gc(),this.stage.step(),this.stage.render();var e=this;this._st=setTimeout(function(){e.step()},this.step_time)}},getEventXY:function(t){var i=s.lang.$e("wrapper"),e=t.clientX-i.offsetLeft-this.canvas.offsetLeft+Math.max(document.documentElement.scrollLeft,document.body.scrollLeft),n=t.clientY-i.offsetTop-this.canvas.offsetTop+Math.max(document.documentElement.scrollTop,document.body.scrollTop);return[e*_TD.retina,n*_TD.retina]},hover:function(t,i){this.eventManager.hover(t,i)},click:function(t,i){this.eventManager.click(t,i)},mouseHand:function(t){this.canvas.style.cursor=t?"pointer":"default"},log:function(t){this.is_debug&&window.console&&console.log&&void 0},gc:function(){window.CollectGarbage&&(CollectGarbage(),setTimeout(CollectGarbage,1))}};for(e=0;this.a[e];e++)this.a[e](s);delete this.a,s.init(t)}};_TD.a.push(function(t){t.lang={$e:function(t){return document.getElementById(t)},$c:function(t,i,e){var s=document.createElement(t);i=i||{};for(var n in i)i.hasOwnProperty(n)&&s.setAttribute(n,i[n]);return e&&e.appendChild(s),s},strLeft:function(t,i){var e=t.slice(0,i),s=e.replace(/[^\x00-\xff]/g,"**").length;if(i>=s)return e;switch(s-=e.length){case 0:return e;case i:return t.slice(0,i>>1);default:var n=i-s,h=t.slice(n,i),a=h.replace(/[\x00-\xff]/g,"").length;return a?t.slice(0,n)+this.arguments.callee(h,a):t.slice(0,n)}},strLen2:function(t){return t.replace(/[^\x00-\xff]/g,"**").length},each:function(t,i){if(Array.prototype.forEach)t.forEach(i);else for(var e=0,s=t.length;s>e;e++)i(t[e])},any:function(t,i){for(var e=0,s=t.length;s>e;e++)if(i(t[e]))return t[e];return null},shift:function(t,i){for(;t[0];)i(t.shift())},rndSort:function(t){var i=t.concat();return i.sort(function(){return Math.random()-.5})},_rndRGB2:function(t){var i=t.toString(16);return 2==i.length?i:"0"+i},rndRGB:function(){var t=Math.floor(256*Math.random()),i=Math.floor(256*Math.random()),e=Math.floor(256*Math.random());return"#"+this._rndRGB2(t)+this._rndRGB2(i)+this._rndRGB2(e)},rgb2Arr:function(t){if(7!=t.length)return[0,0,0];var i=t.substr(1,2),e=t.substr(3,2),s=t.substr(3,2);return[parseInt(i,16),parseInt(e,16),parseInt(s,16)]},rndStr:function(t){t=t||16;var i,e,s="1234567890abcdefghijklmnopqrstuvwxyz",n=[],h=s.length;for(i=0;t>i;i++)e=Math.floor(Math.random()*h),n.push(s.substr(e,1));return n.join("")},nullFunc:function(){},arrayEqual:function(t,i){var e,s=t.length;if(s!=i.length)return!1;for(e=0;s>e;e++)if(t[e]!=i[e])return!1;return!0},mix:function(t,i,e){if(!i||!t)return t;for(var s in i)!i.hasOwnProperty(s)||e===!1&&s in t||(t[s]=i[s]);return t}}}),_TD.a.push(function(t){t.eventManager={ex:-1,ey:-1,_registers:{},ontypes:["enter","hover","out","click"],current_type:"hover",isOn:function(t){return-1!=this.ex&&-1!=this.ey&&this.ex>t.x&&this.ext.y&&this.eya;a++)r.removeEventListener(t,r.ontypes[a])}),this.current_type=""}},hover:function(t,i){"click"!=this.current_type&&(this.current_type="hover",this.ex=t,this.ey=i)},click:function(t,i){this.current_type="click",this.ex=t,this.ey=i}}}),_TD.a.push(function(t){t.Stage=function(i,e){this.id=i||"stage-"+t.lang.rndStr(),this.cfg=e||{},this.width=this.cfg.width||640,this.height=this.cfg.height||540,this.mode="normal",this.state=0,this.acts=[],this.current_act=null,this._step2=t.lang.nullFunc,this._init()},t.Stage.prototype={_init:function(){"function"==typeof this.cfg.init&&this.cfg.init.call(this),"function"==typeof this.cfg.step2&&(this._step2=this.cfg.step2)},start:function(){this.state=1,t.lang.each(this.acts,function(t){t.start()})},pause:function(){this.state=2},gameover:function(){this.current_act.gameover()},clear:function(){this.state=3,t.lang.each(this.acts,function(t){t.clear()})},step:function(){1==this.state&&this.current_act&&(t.eventManager.step(),this.current_act.step(),this._step2())},render:function(){0!=this.state&&3!=this.state&&this.current_act&&this.current_act.render()},addAct:function(t){this.acts.push(t)},addElement:function(t,i,e){this.current_act&&this.current_act.addElement(t,i,e)}}}),_TD.a.push(function(t){t.Act=function(i,e){this.stage=i,this.id=e||"act-"+t.lang.rndStr(),this.state=0,this.scenes=[],this.end_queue=[],this.current_scene=null,this._init()},t.Act.prototype={_init:function(){this.stage.addAct(this)},start:function(){return this.stage.current_act&&3!=this.stage.current_act.state?(this.state=0,void this.stage.current_act.queue(this.start)):(this.state=1,this.stage.current_act=this,void t.lang.each(this.scenes,function(t){t.start()}))},pause:function(){this.state=2},end:function(){this.state=3;for(var t;t=this.end_queue.shift();)t();this.stage.current_act=null},queue:function(t){this.end_queue.push(t)},clear:function(){this.state=3,t.lang.each(this.scenes,function(t){t.clear()})},step:function(){1==this.state&&this.current_scene&&this.current_scene.step()},render:function(){0!=this.state&&3!=this.state&&this.current_scene&&this.current_scene.render()},addScene:function(t){this.scenes.push(t)},addElement:function(t,i,e){this.current_scene&&this.current_scene.addElement(t,i,e)},gameover:function(){this.current_scene.gameover()}}}),_TD.a.push(function(t){t.Scene=function(i,e){this.act=i,this.stage=i.stage,this.is_gameover=!1,this.id=e||"scene-"+t.lang.rndStr(),this.state=0,this.end_queue=[],this._step_elements=[[],[],[]],this._render_elements=[[],[],[],[],[],[],[],[],[],[]],this._init()},t.Scene.prototype={_init:function(){this.act.addScene(this),this.wave=0},start:function(){return this.act.current_scene&&this.act.current_scene!=this&&3!=this.act.current_scene.state?(this.state=0,void this.act.current_scene.queue(this.start)):(this.state=1,void(this.act.current_scene=this))},pause:function(){this.state=2},end:function(){this.state=3;for(var t;t=this.end_queue.shift();)t();this.clear(),this.act.current_scene=null},clear:function(){t.lang.shift(this._step_elements,function(i){t.lang.shift(i,function(t){t.del()})}),t.lang.shift(this._render_elements,function(i){t.lang.shift(i,function(t){t.del()})})},queue:function(t){this.end_queue.push(t)},gameover:function(){this.is_gameover||(this.pause(),this.is_gameover=!0)},step:function(){if(1==this.state){t.life<=0&&(t.life=0,this.gameover());var i,e;for(i=0;3>i;i++){e=[];var s=this._step_elements[i];t.lang.shift(s,function(t){t.is_valid?(t.is_paused||t.step(),e.push(t)):setTimeout(function(){t=null},500)}),this._step_elements[i]=e}}},render:function(){if(0!=this.state&&3!=this.state){var i,e,s=t.ctx;for(s.clearRect(0,0,this.stage.width,this.stage.height),i=0;10>i;i++){e=[];var n=this._render_elements[i];t.lang.shift(n,function(t){t.is_valid&&(t.is_visiable&&t.render(),e.push(t))}),this._render_elements[i]=e}this.is_gameover&&this.panel.gameover_obj.show()}},addElement:function(t,i,e){i=i||t.step_level||1,e=e||t.render_level,this._step_elements[i].push(t),this._render_elements[e].push(t),t.scene=this,t.step_level=i,t.render_level=e}}}),_TD.a.push(function(t){t.Element=function(i,e){this.id=i||"el-"+t.lang.rndStr(),this.cfg=e||{},this.is_valid=!0,this.is_visiable="undefined"!=typeof e.is_visiable?e.is_visiable:!0,this.is_paused=!1,this.is_hover=!1,this.x=this.cfg.x||-1,this.y=this.cfg.y||-1,this.width=this.cfg.width||0,this.height=this.cfg.height||0,this.step_level=e.step_level||1,this.render_level=e.render_level,this.on_events=e.on_events||[],this._init()},t.Element.prototype={_init:function(){var t,i,e,s=this;for(t=0,e=this.on_events.length;e>t;t++)switch(i=this.on_events[t]){case"enter":this.on("enter",function(){s.onEnter()});break;case"out":this.on("out",function(){s.onOut()});break;case"hover":this.on("hover",function(){s.onHover()});break;case"click":this.on("click",function(){s.onClick()})}this.caculatePos()},caculatePos:function(){this.cx=this.x+this.width/2,this.cy=this.y+this.height/2,this.x2=this.x+this.width,this.y2=this.y+this.height},start:function(){this.is_paused=!1},pause:function(){this.is_paused=!0},hide:function(){this.is_visiable=!1,this.onOut()},show:function(){this.is_visiable=!0},del:function(){this.is_valid=!1},on:function(i,e){t.eventManager.on(this,i,e)},onEnter:t.lang.nullFunc,onOut:t.lang.nullFunc,onHover:t.lang.nullFunc,onClick:t.lang.nullFunc,step:t.lang.nullFunc,render:t.lang.nullFunc,addToScene:function(i,e,s,n){this.scene=i,isNaN(e)||(this.step_level=e||this.step_level,this.render_level=s||this.render_level,n&&t.lang.each(n,function(t){i.addElement(t,e,s)}),i.addElement(this,e,s))}}}),_TD.a.push(function(t){function i(i,e){var s=new t.Element(i,e);return t.lang.mix(s,h),s._init(e),s}var e=20,s={_init:function(s){s=s||{},this.grid_x=s.grid_x||10,this.grid_y=s.grid_y||10,this.x=s.x||0,this.y=s.y||0,this.width=this.grid_x*t.grid_size,this.height=this.grid_y*t.grid_size,this.x2=this.x+this.width,this.y2=this.y+this.width,this.grids=[],this.entrance=this.exit=null,this.buildings=[],this.monsters=[],this.bullets=[],this.scene=s.scene,this.is_main_map=!!s.is_main_map,this.select_hl=t.MapSelectHighLight(this.id+"-hl",{map:this}),this.select_hl.addToScene(this.scene,1,9),this.selected_building=null,this._wait_clearInvalidElements=e,this._wait_add_monsters=0,this._wait_add_monsters_arr=[],this.is_main_map&&(this.mmm=new i(this.id+"-mmm",{map:this}),this.mmm.addToScene(this.scene,1,7));var n,h,a,l=this.grid_x*this.grid_y,r=s.grid_data||[];for(n=0;l>n;n++)h=r[n]||{},h.mx=n%this.grid_x,h.my=Math.floor(n/this.grid_x),h.map=this,h.step_level=this.step_level,h.render_level=this.render_level,a=new t.Grid(this.id+"-grid-"+h.mx+"-"+h.my,h),this.grids.push(a);s.entrance&&s.exit&&!t.lang.arrayEqual(s.entrance,s.exit)&&(this.entrance=this.getGrid(s.entrance[0],s.entrance[1]),this.entrance.is_entrance=!0,this.exit=this.getGrid(s.exit[0],s.exit[1]),this.exit.is_exit=!0);var c=this;s.grids_cfg&&t.lang.each(s.grids_cfg,function(t){var i=c.getGrid(t.pos[0],t.pos[1]);i&&(isNaN(t.passable_flag)||(i.passable_flag=t.passable_flag),isNaN(t.build_flag)||(i.build_flag=t.build_flag),t.building&&i.addBuilding(t.building))})},checkHasWeapon:function(){this.has_weapon=null!=this.anyBuilding(function(t){return t.is_weapon})},getGrid:function(t,i){var e=i*this.grid_x+t;return this.grids[e]},anyMonster:function(i){return t.lang.any(this.monsters,i)},anyBuilding:function(i){return t.lang.any(this.buildings,i)},anyBullet:function(i){return t.lang.any(this.bullets,i)},eachBuilding:function(i){t.lang.each(this.buildings,i)},eachMonster:function(i){t.lang.each(this.monsters,i)},eachBullet:function(i){t.lang.each(this.bullets,i)},preBuild:function(i){t.mode="build",this.pre_building&&this.pre_building.remove(),this.pre_building=new t.Building(this.id+"-pre-building-"+t.lang.rndStr(),{type:i,map:this,is_pre_building:!0}),this.scene.addElement(this.pre_building,1,this.render_level+1)},cancelPreBuild:function(){t.mode="normal",this.pre_building&&this.pre_building.remove()},clearInvalidElements:function(){if(this._wait_clearInvalidElements>0)return void this._wait_clearInvalidElements--;this._wait_clearInvalidElements=e;var i=[];t.lang.shift(this.buildings,function(t){t.is_valid&&i.push(t)}),this.buildings=i,i=[],t.lang.shift(this.monsters,function(t){t.is_valid&&i.push(t)}),this.monsters=i,i=[],t.lang.shift(this.bullets,function(t){t.is_valid&&i.push(t)}),this.bullets=i},addMonster:function(i){this.entrance&&("number"==typeof i&&(i=new t.Monster(null,{idx:i,difficulty:t.difficulty,step_level:this.step_level,render_level:this.render_level+2})),this.entrance.addMonster(i))},addMonsters:function(t,i){this._wait_add_monsters=t,this._wait_add_monsters_objidx=i},addMonsters2:function(t){this._wait_add_monsters_arr=t},checkPassable:function(t,i){var e=this.getGrid(t,i);return null!=e&&1==e.passable_flag&&2!=e.build_flag},step:function(){if(this.clearInvalidElements(),this._wait_add_monsters>0)this.addMonster(this._wait_add_monsters_objidx),this._wait_add_monsters--;else if(this._wait_add_monsters_arr.length>0){var t=this._wait_add_monsters_arr.shift();this.addMonsters(t[0],t[1])}},render:function(){var i=t.ctx;i.strokeStyle="#99a",i.lineWidth=_TD.retina,i.beginPath(),i.strokeRect(this.x+.5,this.y+.5,this.width,this.height),i.closePath(),i.stroke()},onOut:function(){this.is_main_map&&this.pre_building&&this.pre_building.hide()}};t.Map=function(i,e){e.on_events=["enter","out"];var n=new t.Element(i,e);return t.lang.mix(n,s),n._init(e),n};var n={_init:function(i){this.map=i.map,this.width=t.grid_size+2,this.height=t.grid_size+2,this.is_visiable=!1},show:function(t){this.x=t.x,this.y=t.y,this.is_visiable=!0},render:function(){var i=t.ctx;i.lineWidth=2,i.strokeStyle="#f93",i.beginPath(),i.strokeRect(this.x,this.y,this.width-1,this.height-1),i.closePath(),i.stroke()}};t.MapSelectHighLight=function(i,e){var s=new t.Element(i,e);return t.lang.mix(s,n),s._init(e),s};var h={_init:function(t){this.map=t.map,this.x1=this.map.x,this.y1=this.map.y,this.x2=this.map.x2+1,this.y2=this.map.y2+1,this.w=this.map.scene.stage.width,this.h=this.map.scene.stage.height,this.w2=this.w-this.x2,this.h2=this.h-this.y2},render:function(){var i=t.ctx;i.fillStyle="#fff",i.beginPath(),i.fillRect(0,0,this.x1,this.h),i.fillRect(0,0,this.w,this.y1),i.fillRect(0,this.y2,this.w,this.h2),i.fillRect(this.x2,0,this.w2,this.h),i.closePath(),i.fill()}}}),_TD.a.push(function(t){var i={_init:function(i){i=i||{},this.map=i.map,this.scene=this.map.scene,this.mx=i.mx,this.my=i.my,this.width=t.grid_size,this.height=t.grid_size,this.is_entrance=this.is_exit=!1,this.passable_flag=1,this.build_flag=1,this.building=null,this.caculatePos()},caculatePos:function(){this.x=this.map.x+this.mx*t.grid_size,this.y=this.map.y+this.my*t.grid_size,this.x2=this.x+t.grid_size,this.y2=this.y+t.grid_size,this.cx=Math.floor(this.x+t.grid_size/2),this.cy=Math.floor(this.y+t.grid_size/2)},checkBlock:function(){if(this.is_entrance||this.is_exit)return this._block_msg=t._t("entrance_or_exit_be_blocked"),!0;var i,e=this,s=new t.FindWay(this.map.grid_x,this.map.grid_y,this.map.entrance.mx,this.map.entrance.my,this.map.exit.mx,this.map.exit.my,function(t,i){return!(t==e.mx&&i==e.my)&&e.map.checkPassable(t,i)});return i=s.is_blocked,i?this._block_msg=t._t("blocked"):(i=!!this.map.anyMonster(function(t){return t.chkIfBlocked(e.mx,e.my)}),i&&(this._block_msg=t._t("monster_be_blocked"))),i},buyBuilding:function(i){var e=t.getDefaultBuildingAttributes(i).cost||0;t.money>=e?(t.money-=e,this.addBuilding(i)):(t.log(t._t("not_enough_money",[e])),this.scene.panel.balloontip.msg(t._t("not_enough_money",[e]),this))},addBuilding:function(i){this.building&&this.removeBuilding();var e=new t.Building("building-"+i+"-"+t.lang.rndStr(),{type:i,step_level:this.step_level,render_level:this.render_level});e.locate(this),this.scene.addElement(e,this.step_level,this.render_level+1),this.map.buildings.push(e),this.building=e,this.build_flag=2,this.map.checkHasWeapon(),this.map.pre_building&&this.map.pre_building.hide()},removeBuilding:function(){2==this.build_flag&&(this.build_flag=1),this.building&&this.building.remove(),this.building=null},addMonster:function(t){t.beAddToGrid(this),this.map.monsters.push(t),t.start()},hightLight:function(t){this.map.select_hl[t?"show":"hide"](this)},render:function(){var i=t.ctx,e=this.x+.5,s=this.y+.5;this.is_hover&&(i.fillStyle="rgba(255, 255, 200, 0.2)",i.beginPath(),i.fillRect(e,s,this.width,this.height),i.closePath(),i.fill()),0==this.passable_flag&&(i.fillStyle="#fcc",i.beginPath(),i.fillRect(e,s,this.width,this.height),i.closePath(),i.fill()),(this.is_entrance||this.is_exit)&&(i.lineWidth=1,i.fillStyle="#ccc",i.beginPath(),i.fillRect(e,s,this.width,this.height),i.closePath(),i.fill(),i.strokeStyle="#666",i.fillStyle=this.is_entrance?"#fff":"#666",i.beginPath(),i.arc(this.cx,this.cy,.325*t.grid_size,0,2*Math.PI,!0),i.closePath(),i.fill(),i.stroke()),i.strokeStyle="#eee",i.lineWidth=1,i.beginPath(),i.strokeRect(e,s,this.width,this.height),i.closePath(),i.stroke()},onEnter:function(){if(this.map.is_main_map&&"build"==t.mode)1==this.build_flag?(this.map.pre_building.show(),this.map.pre_building.locate(this)):this.map.pre_building.hide();else if(this.map.is_main_map){var i="";this.is_entrance?i=t._t("entrance"):this.is_exit?i=t._t("exit"):0==this.passable_flag?i=t._t("_cant_pass"):0==this.build_flag&&(i=t._t("_cant_build")),i&&this.scene.panel.balloontip.msg(i,this)}},onOut:function(){this.scene.panel.balloontip.el==this&&this.scene.panel.balloontip.hide()},onClick:function(){1==this.scene.state&&("build"==t.mode&&this.map.is_main_map&&!this.building?this.checkBlock()?this.scene.panel.balloontip.msg(this._block_msg,this):this.buyBuilding(this.map.pre_building.type):!this.building&&this.map.selected_building&&(this.map.selected_building.toggleSelected(),this.map.selected_building=null))}};t.Grid=function(e,s){s.on_events=["enter","out","click"];var n=new t.Element(e,s);return t.lang.mix(n,i),n._init(s),n}}),_TD.a.push(function(t){var i={_init:function(i){this.is_selected=!1,this.level=0,this.killed=0,this.target=null,i=i||{},this.map=i.map||null,this.grid=i.grid||null,this.bullet_type=i.bullet_type||1,this.type=i.type,this.speed=i.speed,this.bullet_speed=i.bullet_speed,this.is_pre_building=!!i.is_pre_building,this.blink=this.is_pre_building,this.wait_blink=this._default_wait_blink=20,this.is_weapon="wall"!=this.type;var e=t.getDefaultBuildingAttributes(this.type);t.lang.mix(this,e),this.range_px=this.range*t.grid_size,this.money=this.cost,this.caculatePos()},getUpgradeCost:function(){return Math.floor(.75*this.money)},getSellMoney:function(){return Math.floor(.5*this.money)||1},toggleSelected:function(){this.is_selected=!this.is_selected,this.grid.hightLight(this.is_selected);var t=this;this.is_selected?(this.map.eachBuilding(function(i){i.is_selected=i==t}),(this.map.is_main_map?this.scene.panel_map:this.scene.map).eachBuilding(function(t){t.is_selected=!1,t.grid.hightLight(!1)}),this.map.selected_building=this,this.map.is_main_map?this.scene.map.cancelPreBuild():this.scene.map.preBuild(this.type)):(this.map.selected_building==this&&(this.map.selected_building=null),this.map.is_main_map||this.scene.map.cancelPreBuild()),this.map.is_main_map&&(this.map.selected_building?(this.scene.panel.btn_upgrade.show(),this.scene.panel.btn_sell.show(),this.updateBtnDesc()):(this.scene.panel.btn_upgrade.hide(),this.scene.panel.btn_sell.hide()))},updateBtnDesc:function(){this.scene.panel.btn_upgrade.desc=t._t("upgrade",[t._t("building_name_"+this.type),this.level+1,this.getUpgradeCost()]),this.scene.panel.btn_sell.desc=t._t("sell",[t._t("building_name_"+this.type),this.getSellMoney()])},locate:function(i){this.grid=i,this.map=i.map,this.cx=this.grid.cx,this.cy=this.grid.cy,this.x=this.grid.x,this.y=this.grid.y,this.x2=this.grid.x2,this.y2=this.grid.y2,this.width=this.grid.width,this.height=this.grid.height,this.px=this.x+.5,this.py=this.y+.5,this.wait_blink=this._default_wait_blink,this._fire_wait=Math.floor(Math.max(2/(this.speed*t.global_speed),1)),this._fire_wait2=this._fire_wait},remove:function(){this.grid&&this.grid.building&&this.grid.building==this&&(this.grid.building=null),this.hide(),this.del()},findTaget:function(){if(this.is_weapon&&!this.is_pre_building&&this.grid){var i=this.cx,e=this.cy,s=Math.pow(this.range_px,2);this.target&&this.target.is_valid&&Math.pow(this.target.cx-i,2)+Math.pow(this.target.cy-e,2)<=s||(this.target=t.lang.any(t.lang.rndSort(this.map.monsters),function(t){return Math.pow(t.cx-i,2)+Math.pow(t.cy-e,2)<=s}))}},getTargetPosition:function(){if(!this.target){var t=this.map.is_main_map?this.map.entrance:this.grid;return[t.cx,t.cy]}return[this.target.cx,this.target.cy]},fire:function(){if(this.target&&this.target.is_valid){if("laser_gun"==this.type)return void this.target.beHit(this,this.damage);var i=this.muzzle||[this.cx,this.cy],e=i[0],s=i[1];new t.Bullet(null,{building:this,damage:this.damage,target:this.target,speed:this.bullet_speed,x:e,y:s})}},tryToFire:function(){this.is_weapon&&this.target&&(this._fire_wait--,this._fire_wait>0||(this._fire_wait<0?this._fire_wait=this._fire_wait2:this.fire()))},_upgrade2:function(i){this._upgrade_records[i]||(this._upgrade_records[i]=this[i]);var e=this._upgrade_records[i],s="max_"+i,n="_upgrade_rule_"+i,h=this[n]||t.default_upgrade_rule;e&&!isNaN(e)&&(e=h(this.level,e),this[s]&&!isNaN(this[s])&&this[s]i;i++)this._upgrade2(e[i]);this.level++,this.range_px=this.range*t.grid_size},tryToUpgrade:function(i){var e=this.getUpgradeCost(),s="";e>t.money?s=t._t("not_enough_money",[e]):(t.money-=e,this.money+=e,this.upgrade(),s=t._t("upgrade_success",[t._t("building_name_"+this.type),this.level,this.getUpgradeCost()])),this.updateBtnDesc(),this.scene.panel.balloontip.msg(s,i)},tryToSell:function(){this.is_valid&&(t.money+=this.getSellMoney(),this.grid.removeBuilding(),this.is_valid=!1,this.map.selected_building=null,this.map.select_hl.hide(),this.map.checkHasWeapon(),this.scene.panel.btn_upgrade.hide(),this.scene.panel.btn_sell.hide(),this.scene.panel.balloontip.hide())},step:function(){this.blink&&(this.wait_blink--,this.wait_blink<-this._default_wait_blink&&(this.wait_blink=this._default_wait_blink)),this.findTaget(),this.tryToFire()},render:function(){if(this.is_visiable&&!(this.wait_blink<0)){var i=t.ctx;t.renderBuilding(this),this.map.is_main_map&&(this.is_selected||this.is_pre_building||this.map.show_all_ranges)&&this.is_weapon&&this.range>0&&this.grid&&(i.lineWidth=_TD.retina,i.fillStyle="rgba(187, 141, 32, 0.15)",i.strokeStyle="#bb8d20",i.beginPath(),i.arc(this.cx,this.cy,this.range_px,0,2*Math.PI,!0),i.closePath(),i.fill(),i.stroke()),"laser_gun"==this.type&&this.target&&this.target.is_valid&&(i.lineWidth=3*_TD.retina,i.strokeStyle="rgba(50, 50, 200, 0.5)",i.beginPath(),i.moveTo(this.cx,this.cy),i.lineTo(this.target.cx,this.target.cy),i.closePath(),i.stroke(),i.lineWidth=_TD.retina,i.strokeStyle="rgba(150, 150, 255, 0.5)",i.beginPath(),i.lineTo(this.cx,this.cy),i.closePath(),i.stroke())}},onEnter:function(){if(!this.is_pre_building){var i="建筑工事";i=this.map.is_main_map?t._t("building_info"+("wall"==this.type?"_wall":""),[t._t("building_name_"+this.type),this.level,this.damage,this.speed,this.range,this.killed]):t._t("building_intro_"+this.type,[t.getDefaultBuildingAttributes(this.type).cost]),this.scene.panel.balloontip.msg(i,this.grid)}},onOut:function(){this.scene.panel.balloontip.el==this.grid&&this.scene.panel.balloontip.hide()},onClick:function(){this.is_pre_building||1!=this.scene.state||this.toggleSelected()}};t.Building=function(e,s){s.on_events=["enter","out","click"];var n=new t.Element(e,s);return t.lang.mix(n,i),n._init(s),n};var e={_init:function(t){t=t||{},this.speed=t.speed,this.damage=t.damage,this.target=t.target,this.cx=t.x,this.cy=t.y,this.r=t.r||Math.max(Math.log(this.damage),2),this.r<1&&(this.r=1),this.r>6&&(this.r=6),this.building=t.building||null,this.map=t.map||this.building.map,this.type=t.type||1,this.color=t.color||"#000",this.map.bullets.push(this),this.addToScene(this.map.scene,1,6),1==this.type&&this.caculate()},caculate:function(){var i,e,s,n,h=this.target.cx,a=this.target.cy;i=h-this.cx,e=a-this.cy,s=Math.sqrt(Math.pow(i,2)+Math.pow(e,2)),n=20*this.speed*t.global_speed,this.vx=i*n/s,this.vy=e*n/s},checkOutOfMap:function(){return this.is_valid=!(this.cxthis.map.x2||this.cythis.map.y2),!this.is_valid},checkHit:function(){var i=this.cx,e=this.cy,s=this.r*_TD.retina,n=this.map.anyMonster(function(t){return Math.pow(t.cx-i,2)+Math.pow(t.cy-e,2)<=2*Math.pow(t.r+s,2)});return n?(n.beHit(this.building,this.damage),this.is_valid=!1,t.Explode(this.id+"-explode",{cx:this.cx,cy:this.cy,r:this.r,step_level:this.step_level,render_level:this.render_level,color:this.color,scene:this.map.scene,time:.2}),!0):!1},step:function(){this.checkOutOfMap()||this.checkHit()||(this.cx+=this.vx,this.cy+=this.vy)},render:function(){var i=t.ctx;i.fillStyle=this.color,i.beginPath(),i.arc(this.cx,this.cy,this.r,0,2*Math.PI,!0),i.closePath(),i.fill()}};t.Bullet=function(i,s){var n=new t.Element(i,s);return t.lang.mix(n,e),n._init(s),n}}),_TD.a.push(function(t){var i={_init:function(i){i=i||{},this.is_monster=!0,this.idx=i.idx||1,this.difficulty=i.difficulty||1;var e=t.getDefaultMonsterAttributes(this.idx);this.speed=Math.floor((e.speed+this.difficulty/2)*(.5*Math.random()+.75)),this.speed<1&&(this.speed=1),this.speed>i.max_speed&&(this.speed=i.max_speed),this.life=this.life0=Math.floor(e.life*(this.difficulty+1)*(Math.random()+.5)*.5),this.life<1&&(this.life=this.life0=1),this.shield=Math.floor(e.shield+this.difficulty/2),this.shield<0&&(this.shield=0),this.damage=Math.floor((e.damage||1)*(.5*Math.random()+.75)),this.damage<1&&(this.damage=1),this.money=e.money||Math.floor(Math.sqrt((this.speed+this.life)*(this.shield+1)*this.damage)),this.money<1&&(this.money=1),this.color=e.color||t.lang.rndRGB(),this.r=Math.floor(1.2*this.damage)*_TD.retina,this.r<4*_TD.retina&&(this.r=4*_TD.retina),this.r>t.grid_size/2-4*_TD.retina&&(this.r=t.grid_size/2-4*_TD.retina),this.render=e.render,this.grid=null,this.map=null,this.next_grid=null,this.way=[],this.toward=2,this._dx=0,this._dy=0,this.is_blocked=!1},caculatePos:function(){var t=this.r;this.x=this.cx-t,this.y=this.cy-t,this.x2=this.cx+t,this.y2=this.cy+t},beHit:function(i,e){if(this.is_valid){var s=Math.ceil(.1*e);e-=this.shield,s>=e&&(e=s),this.life-=e,t.score+=Math.floor(Math.sqrt(e)),this.life<=0&&this.beKilled(i);var n=this.scene.panel.balloontip;n.el==this&&(n.text=t._t("monster_info",[this.life,this.shield,this.speed,this.damage]))}},beKilled:function(i){this.is_valid&&(this.life=0,this.is_valid=!1,t.money+=this.money,i.killed++,t.Explode(this.id+"-explode",{cx:this.cx,cy:this.cy,color:this.color,r:this.r,step_level:this.step_level,render_level:this.render_level,scene:this.grid.scene}))},arrive:function(){this.grid=this.next_grid,this.next_grid=null,this.checkFinish()},findWay:function(){var i=this,e=new t.FindWay(this.map.grid_x,this.map.grid_y,this.grid.mx,this.grid.my,this.map.exit.mx,this.map.exit.my,function(t,e){return i.map.checkPassable(t,e)});this.way=e.way},checkFinish:function(){this.grid&&this.map&&this.grid==this.map.exit&&(t.life-=this.damage,t.wave_damage+=this.damage,t.life<=0?(t.life=0,t.stage.gameover()):(this.pause(),this.del()))},beAddToGrid:function(t){this.grid=t,this.map=t.map,this.cx=t.cx,this.cy=t.cy,this.grid.scene.addElement(this)},getToward:function(){this.grid&&this.next_grid&&(this.grid.mythis.next_grid.my?this.toward=2:this.grid.mx>this.next_grid.mx&&(this.toward=3))},getNextGrid:function(){(0==this.way.length||Math.random()<.1)&&this.findWay();var t=this.way.shift();t&&!this.map.checkPassable(t[0],t[1])&&(this.findWay(),t=this.way.shift()),t&&(this.next_grid=this.map.getGrid(t[0],t[1]))},chkIfBlocked:function(i,e){var s=this,n=new t.FindWay(this.map.grid_x,this.map.grid_y,this.grid.mx,this.grid.my,this.map.exit.mx,this.map.exit.my,function(t,n){return!(t==i&&n==e)&&s.map.checkPassable(t,n)});return n.is_blocked},beBlocked:function(){this.is_blocked||(this.is_blocked=!0,t.log("monster be blocked!"))},step:function(){if(this.is_valid&&!this.is_paused&&this.grid){if(!this.next_grid&&(this.getNextGrid(),!this.next_grid))return void this.beBlocked();if(this.cx==this.next_grid.cx&&this.cy==this.next_grid.cy)this.arrive();else{var i=this.next_grid.cx-this.cx,e=this.next_grid.cy-this.cy,s=0>i?-1:1,n=0>e?-1:1,h=this.speed*t.global_speed;Math.abs(i)0,this.rgb_a=this.wait/this.wait0)},render:function(){var i=t.ctx;i.fillStyle="rgba("+this.rgb_r+","+this.rgb_g+","+this.rgb_b+","+this.rgb_a+")",i.beginPath(),i.arc(this.cx,this.cy,this.r,0,2*Math.PI,!0),i.closePath(),i.fill()}};t.Explode=function(i,s){var n=new t.Element(i,s);return t.lang.mix(n,e),n._init(s),n}}),_TD.a.push(function(t){var i={_init:function(i){i=i||{},this.x=i.x,this.y=i.y,this.scene=i.scene,this.map=i.main_map;var e=new t.Map("panel-map",t.lang.mix({x:this.x+i.map.x,y:this.y+i.map.y,scene:this.scene,step_level:this.step_level, +render_level:this.render_level},i.map,!1));this.addToScene(this.scene,1,7),e.addToScene(this.scene,1,7,e.grids),this.scene.panel_map=e,this.gameover_obj=new t.GameOver("panel-gameover",{panel:this,scene:this.scene,step_level:this.step_level,is_visiable:!1,x:0,y:0,width:this.scene.stage.width,height:this.scene.stage.height,render_level:9}),this.balloontip=new t.BalloonTip("panel-balloon-tip",{scene:this.scene,step_level:this.step_level,render_level:9}),this.balloontip.addToScene(this.scene,1,9),this.btn_pause=new t.Button("panel-btn-pause",{scene:this.scene,x:this.x,y:this.y+260*_TD.retina,text:t._t("button_pause_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){1==this.scene.state?(this.scene.pause(),this.text=t._t("button_continue_text"),this.scene.panel.btn_upgrade.hide(),this.scene.panel.btn_sell.hide(),this.scene.panel.btn_restart.show()):2==this.scene.state&&(this.scene.start(),this.text=t._t("button_pause_text"),this.scene.panel.btn_restart.hide(),this.scene.map.selected_building&&(this.scene.panel.btn_upgrade.show(),this.scene.panel.btn_sell.show()))}}),this.btn_restart=new t.Button("panel-btn-restart",{scene:this.scene,x:this.x,y:this.y+300*_TD.retina,is_visiable:!1,text:t._t("button_restart_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){setTimeout(function(){t.stage.clear(),t.is_paused=!0,t.start(),t.mouseHand(!1)},0)}}),this.btn_upgrade=new t.Button("panel-btn-upgrade",{scene:this.scene,x:this.x,y:this.y+300*_TD.retina,is_visiable:!1,text:t._t("button_upgrade_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){this.scene.map.selected_building.tryToUpgrade(this)}}),this.btn_sell=new t.Button("panel-btn-sell",{scene:this.scene,x:this.x,y:this.y+340*_TD.retina,is_visiable:!1,text:t._t("button_sell_text"),step_level:this.step_level,render_level:this.render_level+1,onClick:function(){this.scene.map.selected_building.tryToSell(this)}})},step:function(){t.life_recover&&(this._life_recover=this._life_recover2=t.life_recover,this._life_recover_wait=this._life_recover_wait2=3*t.exp_fps,t.life_recover=0),this._life_recover&&t.iframe%t.exp_fps_eighth==0&&(t.life++,this._life_recover--)},render:function(){var i=t.ctx;if(i.textAlign="left",i.textBaseline="top",i.fillStyle="#000",i.font="normal "+12*_TD.retina+"px 'Courier New'",i.beginPath(),i.fillText(t._t("panel_money_title")+t.money,this.x,this.y),i.fillText(t._t("panel_score_title")+t.score,this.x,this.y+20*_TD.retina),i.fillText(t._t("panel_life_title")+t.life,this.x,this.y+40*_TD.retina),i.fillText(t._t("panel_building_title")+this.map.buildings.length,this.x,this.y+60*_TD.retina),i.fillText(t._t("panel_monster_title")+this.map.monsters.length,this.x,this.y+80*_TD.retina),i.fillText(t._t("wave_info",[this.scene.wave]),this.x,this.y+210*_TD.retina),i.closePath(),this._life_recover_wait){var e=this._life_recover_wait/this._life_recover_wait2;i.fillStyle="rgba(255, 0, 0, "+e+")",i.font="bold "+12*_TD.retina+"px 'Verdana'",i.beginPath(),i.fillText("+"+this._life_recover2,this.x+60*_TD.retina,this.y+40*_TD.retina),i.closePath(),this._life_recover_wait--}i.textAlign="right",i.fillStyle="#666",i.font="normal "+12*_TD.retina+"px 'Courier New'",i.beginPath(),i.fillText("version: "+t.version+" | oldj.net",t.stage.width-t.padding,t.stage.height-2*t.padding),i.closePath(),i.textAlign="left",i.fillStyle="#666",i.font="normal "+12*_TD.retina+"px 'Courier New'",i.beginPath(),i.fillText("FPS: "+t.fps,t.padding,t.stage.height-2*t.padding),i.closePath()}};t.Panel=function(e,s){var n=new t.Element(e,s);return t.lang.mix(n,i),n._init(s),n};var e={_init:function(t){t=t||{},this.scene=t.scene},caculatePos:function(){var i=this.el;this.x=i.cx+.5,this.y=i.cy+.5,this.x+this.width>this.scene.stage.width-t.padding&&(this.x=this.x-this.width),this.px=this.x+5*_TD.retina,this.py=this.y+4*_TD.retina},msg:function(i,e){this.text=i;var s=t.ctx;s.font="normal "+12*_TD.retina+"px 'Courier New'",this.width=Math.max(s.measureText(i).width+10*_TD.retina,6*t.lang.strLen2(i)+10*_TD.retina),this.height=20*_TD.retina,e&&e.cx&&e.cy&&(this.el=e,this.caculatePos(),this.show())},step:function(){return this.el&&this.el.is_valid?void(this.el.is_monster&&this.caculatePos()):void this.hide()},render:function(){if(this.el){var i=t.ctx;i.lineWidth=_TD.retina,i.fillStyle="rgba(255, 255, 0, 0.5)",i.strokeStyle="rgba(222, 222, 0, 0.9)",i.beginPath(),i.rect(this.x,this.y,this.width,this.height),i.closePath(),i.fill(),i.stroke(),i.textAlign="left",i.textBaseline="top",i.fillStyle="#000",i.font="normal "+12*_TD.retina+"px 'Courier New'",i.beginPath(),i.fillText(this.text,this.px,this.py),i.closePath()}}};t.BalloonTip=function(i,s){var n=new t.Element(i,s);return t.lang.mix(n,e),n._init(s),n};var s={_init:function(i){i=i||{},this.text=i.text,this.onClick=i.onClick||t.lang.nullFunc,this.x=i.x,this.y=i.y,this.width=i.width||80*_TD.retina,this.height=i.height||30*_TD.retina,this.font_x=this.x+8*_TD.retina,this.font_y=this.y+9*_TD.retina,this.scene=i.scene,this.desc=i.desc||"",this.addToScene(this.scene,this.step_level,this.render_level),this.caculatePos()},onEnter:function(){t.mouseHand(!0),this.desc&&this.scene.panel.balloontip.msg(this.desc,this)},onOut:function(){t.mouseHand(!1),this.scene.panel.balloontip.el==this&&this.scene.panel.balloontip.hide()},render:function(){var i=t.ctx;i.lineWidth=2*_TD.retina,i.fillStyle=this.is_hover?"#eee":"#ccc",i.strokeStyle="#999",i.beginPath(),i.rect(this.x,this.y,this.width,this.height),i.closePath(),i.fill(),i.stroke(),i.textAlign="left",i.textBaseline="top",i.fillStyle="#000",i.font="normal "+12*_TD.retina+"px 'Courier New'",i.beginPath(),i.fillText(this.text,this.font_x,this.font_y),i.closePath(),i.fill()}};t.Button=function(i,e){e.on_events=["enter","out","click"];var n=new t.Element(i,e);return t.lang.mix(n,s),n._init(e),n};var n={_init:function(t){this.panel=t.panel,this.scene=t.scene,this.addToScene(this.scene,1,9)},render:function(){this.panel.btn_pause.hide(),this.panel.btn_upgrade.hide(),this.panel.btn_sell.hide(),this.panel.btn_restart.show();var i=t.ctx;i.textAlign="center",i.textBaseline="middle",i.fillStyle="#ccc",i.font="bold 62px 'Verdana'",i.beginPath(),i.fillText("GAME OVER",this.width/2,this.height/2),i.closePath(),i.fillStyle="#f00",i.font="bold 60px 'Verdana'",i.beginPath(),i.fillText("GAME OVER",this.width/2,this.height/2),i.closePath()}};t.GameOver=function(i,e){var s=new t.Element(i,e);return t.lang.mix(s,n),s._init(e),s},t.recover=function(i){t.life_recover=i,t.log("life recover: "+i)}}),_TD.a.push(function(t){var i=function(){var i=new t.Act(this,"act-1"),e=new t.Scene(i,"scene-1"),s=t.getDefaultStageData("scene_endless");this.config=s.config,t.life=this.config.life,t.money=this.config.money,t.score=this.config.score,t.difficulty=this.config.difficulty,t.wave_damage=this.config.wave_damage;var n=new t.Map("main-map",t.lang.mix({scene:e,is_main_map:!0,step_level:1,render_level:2},s.map));n.addToScene(e,1,2,n.grids),e.map=n,e.panel=new t.Panel("panel",t.lang.mix({scene:e,main_map:n,step_level:1,render_level:7},s.panel)),this.newWave=s.newWave,this.map=n,this.wait_new_wave=this.config.wait_new_wave},e=function(){var i=this.current_act.current_scene,e=i.wave;if((0!=e||this.map.has_weapon)&&1==i.state&&0==this.map.monsters.length){if(e>0&&this.wait_new_wave==this.config.wait_new_wave-1){var s=0;e%10==0?s=10:e%5==0&&(s=5),t.life+s>100&&(s=100-t.life),s>0&&t.recover(s)}if(this.wait_new_wave>0)return void this.wait_new_wave--;this.wait_new_wave=this.config.wait_new_wave,e++,i.wave=e,this.newWave({map:this.map,wave:e})}};t.getDefaultStageData=function(s){var n={stage_main:{width:640*_TD.retina,height:560*_TD.retina,init:i,step2:e},scene_endless:{map:{grid_x:16,grid_y:16,x:t.padding,y:t.padding,entrance:[0,0],exit:[15,15],grids_cfg:[{pos:[3,3],passable_flag:0},{pos:[7,15],build_flag:0},{pos:[4,12],building:"wall"},{pos:[4,13],building:"wall"}]},panel:{x:2*t.padding+16*t.grid_size,y:t.padding,map:{grid_x:3,grid_y:3,x:0,y:110*_TD.retina,grids_cfg:[{pos:[0,0],building:"cannon"},{pos:[1,0],building:"LMG"},{pos:[2,0],building:"HMG"},{pos:[0,1],building:"laser_gun"},{pos:[2,2],building:"wall"}]}},config:{endless:!0,wait_new_wave:3*t.exp_fps,difficulty:1,wave:0,max_wave:-1,wave_damage:0,max_monsters_per_wave:100,money:500,score:0,life:100,waves:[[],[[1,0]],[[1,0],[1,1]],[[2,0],[1,1]],[[2,0],[1,1]],[[3,0],[2,1]],[[4,0],[2,1]],[[5,0],[3,1],[1,2]],[[6,0],[4,1],[1,2]],[[7,0],[3,1],[2,2]],[[8,0],[4,1],[3,2]]]},newWave:function(i){i=i||{};var e=i.map,s=i.wave||1,n=t.wave_damage||0;1==s||(0==n?5>s?t.difficulty*=1.05:t.difficulty>30?t.difficulty*=1.1:t.difficulty*=1.2:t.wave_damage>=50?t.difficulty*=.6:t.wave_damage>=30?t.difficulty*=.7:t.wave_damage>=20?t.difficulty*=.8:t.wave_damage>=10?t.difficulty*=.9:s>=10&&(t.difficulty*=1.05)),t.difficulty<1&&(t.difficulty=1),t.log("wave "+s+", last wave damage = "+n+", difficulty = "+t.difficulty);var h=this.config.waves[s]||t.makeMonsters(Math.min(Math.floor(Math.pow(s,1.1)),this.config.max_monsters_per_wave));e.addMonsters2(h),t.wave_damage=0}}};return n[s]||{}}}),_TD.a.push(function(t){t.default_upgrade_rule=function(t,i){return 1.2*i},t.getDefaultBuildingAttributes=function(t){var i={wall:{damage:0,range:0,speed:0,bullet_speed:0,life:100,shield:500,cost:5},cannon:{damage:12,range:4,max_range:8,speed:2,bullet_speed:6,life:100,shield:100,cost:300,_upgrade_rule_damage:function(t,i){return i*(10>=t?1.2:1.3)}},LMG:{damage:5,range:5,max_range:10,speed:3,bullet_speed:6,life:100,shield:50,cost:100},HMG:{damage:30,range:3,max_range:5,speed:3,bullet_speed:5,life:100,shield:200,cost:800,_upgrade_rule_damage:function(t,i){return 1.3*i}},laser_gun:{damage:25,range:6,max_range:10,speed:20,life:100,shield:100,cost:2e3}};return i[t]||{}}}),_TD.a.push(function(t){function i(){if(this.is_valid&&this.grid){var i=t.ctx;if(i.strokeStyle="#000",i.lineWidth=1,i.fillStyle=this.color,i.beginPath(),i.arc(this.cx,this.cy,this.r,0,2*Math.PI,!0),i.closePath(),i.fill(),i.stroke(),t.show_monster_life){var e=Math.floor(t.grid_size/4),s=2*e-2*_TD.retina;i.fillStyle="#000",i.beginPath(),i.fillRect(this.cx-e,this.cy-this.r-6,2*e,4*_TD.retina),i.closePath(),i.fillStyle="#f00",i.beginPath(),i.fillRect(this.cx-e+_TD.retina,this.cy-this.r-(6-_TD.retina),this.life*s/this.life0,2*_TD.retina),i.closePath()}}}t.getDefaultMonsterAttributes=function(e){var s=[{name:"monster 1",desc:"最弱小的怪物",speed:3,max_speed:10,life:50,damage:1,shield:0,money:5},{name:"monster 2",desc:"稍强一些的小怪",speed:6,max_speed:20,life:50,damage:2,shield:1},{name:"monster speed",desc:"速度较快的小怪",speed:12,max_speed:30,life:50,damage:3,shield:1},{name:"monster life",desc:"生命值很强的小怪",speed:5,max_speed:10,life:500,damage:3,shield:1},{name:"monster shield",desc:"防御很强的小怪",speed:5,max_speed:10,life:50,damage:3,shield:20},{name:"monster damage",desc:"伤害值很大的小怪",speed:7,max_speed:14,life:50,damage:10,shield:2},{name:"monster speed-life",desc:"速度、生命都较高的怪物",speed:15,max_speed:30,life:100,damage:3,shield:3},{name:"monster speed-2",desc:"速度很快的怪物",speed:30,max_speed:40,life:30,damage:4,shield:1},{name:"monster shield-life",desc:"防御很强、生命值很高的怪物",speed:3,max_speed:10,life:300,damage:5,shield:15}];if("undefined"==typeof e)return s.length;var n=s[e]||s[0],h={};return t.lang.mix(h,n),h.render||(h.render=i),h},t.makeMonsters=function(i,e){var s,n,h,a,l=[],r=0,c=t.monster_type_count;if(!e)for(e=[],s=0;c>s;s++)e.push(s);for(;i>r;)h=i-r,n=Math.min(Math.floor(Math.random()*h)+1,3),a=Math.floor(Math.random()*c),l.push([n,e[a]]),r+=n;return l}}),_TD.a.push(function(t){function i(t,i,e,s,n,h){var a,l,r,c,o,_,d,u,g;if(i==s)a=i,l=n>e?e+h:e-h;else if(e==n)l=e,a=s>i?i+h:i-h;else{if(r=(e-n)/(i-s),c=e-i*r,d=r*r+1,u=2*(r*(c-e)-i),g=Math.pow(c-e,2)+i*i-Math.pow(h,2),o=Math.pow(u,2)-4*d*g,0>o)return[0,0];o=Math.sqrt(o),_=(-u+o)/(2*d),s-i>0&&_-i>0||0>s-i&&0>_-i?(a=_,l=r*a+c):(a=(-u-o)/(2*d),l=r*a+c)}return t.lineCap="round",t.moveTo(i,e),t.lineTo(a,l),[a,l]}var e={cannon:function(t,e,s,n,h){var a=t.getTargetPosition();e.fillStyle="#393",e.strokeStyle="#000",e.beginPath(),e.lineWidth=_TD.retina,e.arc(t.cx,t.cy,h-5,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.lineWidth=3*_TD.retina,e.beginPath(),e.moveTo(t.cx,t.cy),t.muzzle=i(e,t.cx,t.cy,a[0],a[1],h),e.closePath(),e.stroke(),e.lineWidth=_TD.retina,e.fillStyle="#060",e.beginPath(),e.arc(t.cx,t.cy,7*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#cec",e.beginPath(),e.arc(t.cx+2,t.cy-2,3*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill()},LMG:function(t,e,s,n,h){var a=t.getTargetPosition();e.fillStyle="#36f",e.strokeStyle="#000",e.beginPath(),e.lineWidth=_TD.retina,e.arc(t.cx,t.cy,7*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.lineWidth=2*_TD.retina,e.beginPath(),e.moveTo(t.cx,t.cy),t.muzzle=i(e,t.cx,t.cy,a[0],a[1],h),e.closePath(),e.fill(),e.stroke(),e.lineWidth=_TD.retina,e.fillStyle="#66c",e.beginPath(),e.arc(t.cx,t.cy,5*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#ccf",e.beginPath(),e.arc(t.cx+1,t.cy-1,2*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill()},HMG:function(t,e,s,n,h){var a=t.getTargetPosition();e.fillStyle="#933",e.strokeStyle="#000",e.beginPath(),e.lineWidth=_TD.retina,e.arc(t.cx,t.cy,h-2,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.lineWidth=5*_TD.retina,e.beginPath(),e.moveTo(t.cx,t.cy),t.muzzle=i(e,t.cx,t.cy,a[0],a[1],h),e.closePath(),e.fill(),e.stroke(),e.lineWidth=_TD.retina,e.fillStyle="#630",e.beginPath(),e.arc(t.cx,t.cy,h-5*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#960",e.beginPath(),e.arc(t.cx+1,t.cy-1,8*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="#fcc",e.beginPath(),e.arc(t.cx+3,t.cy-3,4*_TD.retina,0,2*Math.PI,!0),e.closePath(),e.fill()},wall:function(t,i,e,s,n){i.lineWidth=_TD.retina,i.fillStyle="#666",i.strokeStyle="#000",i.fillRect(t.cx-n+1,t.cy-n+1,s-1,s-1),i.beginPath(),i.moveTo(t.cx-n+.5,t.cy-n+.5),i.lineTo(t.cx-n+.5,t.cy+n+.5),i.lineTo(t.cx+n+.5,t.cy+n+.5),i.lineTo(t.cx+n+.5,t.cy-n+.5),i.lineTo(t.cx-n+.5,t.cy-n+.5),i.moveTo(t.cx-n+.5,t.cy+n+.5),i.lineTo(t.cx+n+.5,t.cy-n+.5),i.moveTo(t.cx-n+.5,t.cy-n+.5),i.lineTo(t.cx+n+.5,t.cy+n+.5),i.closePath(),i.stroke()},laser_gun:function(t,i){i.fillStyle="#f00",i.strokeStyle="#000",i.beginPath(),i.lineWidth=_TD.retina,i.moveTo(t.cx,t.cy-10*_TD.retina),i.lineTo(t.cx-8.66*_TD.retina,t.cy+5*_TD.retina),i.lineTo(t.cx+8.66*_TD.retina,t.cy+5*_TD.retina),i.lineTo(t.cx,t.cy-10*_TD.retina),i.closePath(),i.fill(),i.stroke(),i.fillStyle="#60f",i.beginPath(),i.arc(t.cx,t.cy,7*_TD.retina,0,2*Math.PI,!0),i.closePath(),i.fill(),i.stroke(),i.fillStyle="#000",i.beginPath(),i.arc(t.cx,t.cy,3*_TD.retina,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="#666",i.beginPath(),i.arc(t.cx+1,t.cy-1,_TD.retina,0,2*Math.PI,!0),i.closePath(),i.fill(),i.lineWidth=3*_TD.retina,i.beginPath(),i.moveTo(t.cx,t.cy),i.closePath(),i.fill(),i.stroke()}};t.renderBuilding=function(i){var s=t.ctx,n=i.map,h=t.grid_size,a=t.grid_size/2;(e[i.type]||e.wall)(i,s,n,h,a)}}),_TD.a.push(function(t){t._msg_texts={_cant_build:"不能在这儿修建",_cant_pass:"怪物不能通过这儿",entrance:"起点",exit:"终点",not_enough_money:"金钱不足,需要 $${0}!",wave_info:"第 ${0} 波",panel_money_title:"金钱: ",panel_score_title:"积分: ",panel_life_title:"生命: ",panel_building_title:"建筑: ",panel_monster_title:"怪物: ",building_name_wall:"路障",building_name_cannon:"炮台",building_name_LMG:"轻机枪",building_name_HMG:"重机枪",building_name_laser_gun:"激光炮",building_info:"${0}: 等级 ${1},攻击 ${2},速度 ${3},射程 ${4},战绩 ${5}",building_info_wall:"${0}",building_intro_wall:"路障 可以阻止怪物通过 ($${0})",building_intro_cannon:"炮台 射程、杀伤力较为平衡 ($${0})",building_intro_LMG:"轻机枪 射程较远,杀伤力一般 ($${0})",building_intro_HMG:"重机枪 快速射击,威力较大,射程一般 ($${0})",building_intro_laser_gun:"激光枪 伤害较大,命中率 100% ($${0})",click_to_build:"左键点击建造 ${0} ($${1})",upgrade:"升级 ${0} 到 ${1} 级,需花费 $${2}。",sell:"出售 ${0},可获得 $${1}",upgrade_success:"升级成功,${0} 已升级到 ${1} 级!下次升级需要 $${2}。",monster_info:"怪物: 生命 ${0},防御 ${1},速度 ${2},伤害 ${3}",button_upgrade_text:"升级",button_sell_text:"出售",button_start_text:"开始",button_restart_text:"重新开始",button_pause_text:"暂停",button_continue_text:"继续",button_pause_desc_0:"游戏暂停",button_pause_desc_1:"游戏继续",blocked:"不能在这儿修建建筑,起点与终点之间至少要有一条路可到达!",monster_be_blocked:"不能在这儿修建建筑,有怪物被围起来了!",entrance_or_exit_be_blocked:"不能在起点或终点处修建建筑!",_:"ERROR"},t._t=t.translate=function(t,i){i="object"==typeof i&&i.constructor==Array?i:[];var e,s=this._msg_texts[t]||this._msg_texts._,n=i.length;for(e=0;n>e;e++)s=s.replace("${"+e+"}",i[e]);return s}}),_TD.a.push(function(t){t.FindWay=function(t,i,e,s,n,h,a){this.m=[],this.w=t,this.h=i,this.x1=e,this.y1=s,this.x2=n,this.y2=h,this.way=[],this.len=this.w*this.h,this.is_blocked=this.is_arrived=!1,this.fPassable="function"==typeof a?a:function(){return!0},this._init()},t.FindWay.prototype={_init:function(){if(this.x1==this.x2&&this.y1==this.y2)return this.is_arrived=!0,void(this.way=[[this.x1,this.y1]]);for(var t=0;tthis.len?!1:void(this.m[s]=e)},getNeighborsOf:function(t,i){var e=[];return i>0&&e.push([t,i-1]),t0&&e.push([t-1,i]),e},getAllNeighbors:function(){var t,i,e,s=[],n=this.current.length;for(i=0;n>i;i++)e=this.current[i],t=this.getNeighborsOf(e[0],e[1]),s=s.concat(t);return s},findWay:function(){for(var t,i,e,s,n,h,a,l=this.x2,r=this.y2,c=this.len,o=-1;(l!=this.x1||r!=this.y1)&&0!=o&&this.way.lengths;s++)h=this.getVal(e[s][0],e[s][1]),0>h||(0>o||o>h)&&(o=h);for(s=0;i>s;s++)t=e[s],o==this.getVal(t[0],t[1])&&a.push(t);n=a.length,s=n>1?Math.floor(Math.random()*n):0,t=a[s],l=t[0],r=t[1]}},arrive:function(){this.current=[],this.is_arrived=!0,this.findWay()},blocked:function(){this.current=[],this.is_blocked=!0},next:function(){var t,i,e,s,n,h=this.getAllNeighbors(),a=h.length,l=[];for(this.distance++,s=0;a>s;s++)if(t=h[s],i=t[0],e=t[1],-2==this.getVal(i,e)&&(this.fPassable(i,e)?(n=this.distance,l.push(t)):n=-1,this.setVal(i,e,n),i==this.x2&&e==this.y2))return this.arrive(),!1;return 0==l.length?(this.blocked(),!1):(this.current=l,!0)}}}); +//# sourceMappingURL=td-pkg-min.js.map \ No newline at end of file diff --git a/build/td-pkg-min.js.map b/build/td-pkg-min.js.map new file mode 100644 index 0000000..05efc3c --- /dev/null +++ b/build/td-pkg-min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["td.js","td-lang.js","td-event.js","td-stage.js","td-element.js","td-obj-map.js","td-obj-grid.js","td-obj-building.js","td-obj-monster.js","td-obj-panel.js","td-data-stage-1.js","td-cfg-buildings.js","td-cfg-monsters.js","td-render-buildings.js","td-msg.js","td-walk.js"],"names":["_TD","a","retina","init","td_board","is_debug","this","i","TD","version","is_paused","width","height","show_monster_life","fps","exp_fps","exp_fps_half","exp_fps_quarter","exp_fps_eighth","stage_data","defaultSettings","step_time","grid_size","padding","global_speed","ob_board","obj_board","lang","$e","canvas","getElementsByTagName","getContext","ctx","monster_type_count","getDefaultMonsterAttributes","iframe","last_iframe_time","Date","getTime","start","clearTimeout","_st","log","_this","_exp_fps_0","_exp_fps_1","mode","eventManager","clear","mix","stage","Stage","getDefaultStageData","setAttribute","style","onmousemove","e","xy","getEventXY","call","hover","onclick","click","step","checkCheat","cheat_code","money","life","difficulty","cheat","t","Math","round","gc","render","setTimeout","wra","x","clientX","offsetLeft","max","document","documentElement","scrollLeft","body","y","clientY","offsetTop","scrollTop","mouseHand","v","cursor","txt","window","console","CollectGarbage","push","el_id","getElementById","$c","tag_name","attributes","parent_node","el","createElement","k","hasOwnProperty","appendChild","strLeft","s","n","s2","slice","replace","length","s3","j","arguments","callee","strLen2","each","list","f","Array","prototype","forEach","l","any","shift","rndSort","concat","sort","random","_rndRGB2","toString","rndRGB","r","floor","g","b","rgb2Arr","rgb_str","substr","parseInt","rndStr","chars","chars_len","join","nullFunc","arrayEqual","arr1","arr2","is_overwrite","p","ex","ey","_registers","ontypes","current_type","isOn","x2","y2","_mkElEvtName","evt_type","id","on","removeEventListener","en","et","is_evt_on","ontypes_len","to_del_el","is_valid","is_visiable","is_hover","obj","cfg","state","acts","current_act","_step2","_init","step2","pause","gameover","addAct","act","addElement","step_level","render_level","Act","scenes","end_queue","current_scene","queue","end","addScene","scene","Scene","is_gameover","_step_elements","_render_elements","wave","obj2","del","level_elements","clearRect","panel","gameover_obj","show","Element","on_events","len","onEnter","onOut","onHover","onClick","caculatePos","cx","cy","hide","addToScene","pre_add_list","isNaN","MainMapMask","mmm","mmm_obj","_default_wait_clearInvalidElements","map_obj","grid_x","grid_y","grids","entrance","exit","buildings","monsters","bullets","is_main_map","select_hl","MapSelectHighLight","map","selected_building","_wait_clearInvalidElements","_wait_add_monsters","_wait_add_monsters_arr","d","grid","grid_data","mx","my","Grid","getGrid","is_entrance","is_exit","grids_cfg","pos","passable_flag","build_flag","building","addBuilding","checkHasWeapon","has_weapon","anyBuilding","is_weapon","anyMonster","anyBullet","eachBuilding","eachMonster","eachBullet","preBuild","building_type","pre_building","remove","Building","type","is_pre_building","cancelPreBuild","clearInvalidElements","addMonster","monster","Monster","idx","addMonsters","_wait_add_monsters_objidx","addMonsters2","arr","checkPassable","strokeStyle","lineWidth","beginPath","strokeRect","closePath","stroke","Map","map_selecthl_obj","map_selecthl","x1","y1","w","h","w2","h2","fillStyle","fillRect","fill","grid_obj","checkBlock","_block_msg","_t","is_blocked","fw","FindWay","chkIfBlocked","buyBuilding","cost","getDefaultBuildingAttributes","balloontip","msg","removeBuilding","locate","beAddToGrid","hightLight","px","py","arc","PI","toggleSelected","building_obj","is_selected","level","killed","target","bullet_type","speed","bullet_speed","blink","wait_blink","_default_wait_blink","o","range_px","range","getUpgradeCost","getSellMoney","panel_map","btn_upgrade","btn_sell","updateBtnDesc","desc","_fire_wait","_fire_wait2","findTaget","range2","pow","getTargetPosition","fire","beHit","damage","muzzle","Bullet","tryToFire","_upgrade2","_upgrade_records","mk","uk","uf","default_upgrade_rule","upgrade","attrs","tryToUpgrade","btn","tryToSell","renderBuilding","show_all_ranges","moveTo","lineTo","bullet_obj","color","caculate","sx","sy","c","tx","ty","sqrt","vx","vy","checkOutOfMap","checkHit","Explode","time","bullet","monster_obj","is_monster","attr","max_speed","life0","shield","next_grid","way","toward","_dx","_dy","min_damage","ceil","score","beKilled","text","arrive","checkFinish","findWay","wave_damage","getToward","getNextGrid","beBlocked","dpx","dpy","abs","explode_obj","rgb","rgb_r","rgb_g","rgb_b","rgb_a","wait","wait0","explode","panel_obj","main_map","GameOver","BalloonTip","btn_pause","Button","btn_restart","life_recover","_life_recover","_life_recover2","_life_recover_wait","_life_recover_wait2","textAlign","textBaseline","font","fillText","Panel","balloontip_obj","measureText","rect","button_obj","font_x","font_y","button","recover","_stage_main_init","config","newWave","wait_new_wave","_stage_main_step2","wave_reward","data","stage_main","scene_endless","endless","max_wave","max_monsters_per_wave","waves","wave_data","makeMonsters","min","old_level","old_value","building_attributes","wall","cannon","max_range","_upgrade_rule_damage","LMG","HMG","laser_gun","defaultMonsterRender","monster_idx","monster_attributes","name","attr2","count","lineTo2","x0","y0","xt","a2","b2","c2","lineCap","renderFunctions","gs","gs2","target_position","_msg_texts","_cant_build","_cant_pass","not_enough_money","wave_info","panel_money_title","panel_score_title","panel_life_title","panel_building_title","panel_monster_title","building_name_wall","building_name_cannon","building_name_LMG","building_name_HMG","building_name_laser_gun","building_info","building_info_wall","building_intro_wall","building_intro_cannon","building_intro_LMG","building_intro_HMG","building_intro_laser_gun","click_to_build","sell","upgrade_success","monster_info","button_upgrade_text","button_sell_text","button_start_text","button_restart_text","button_pause_text","button_continue_text","button_pause_desc_0","button_pause_desc_1","blocked","monster_be_blocked","entrance_or_exit_be_blocked","_","translate","args","constructor","f_passable","m","is_arrived","fPassable","distance","current","setVal","next","getVal","getNeighborsOf","nbs","getAllNeighbors","nb1","nb","nbs_len","closest_nbs","max_len","min_v","unshift","neighbors","valid_neighbors"],"mappings":"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","file":"td-pkg-min.js","sourcesContent":["/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n */\n\nvar _TD = {\n\ta: [],\n\tretina: 2,\n\tinit: function (td_board, is_debug) {\n\t\tdelete this.init; // 一旦初始化运行,即删除这个入口引用,防止初始化方法被再次调用\n\n\t\tvar i, TD = {\n\t\t\tversion: \"0.1.16\", // 版本命名规范参考:http://semver.org/\n\t\t\tis_debug: !!is_debug,\n\t\t\tis_paused: true,\n\t\t\twidth: 16, // 横向多少个格子\n\t\t\theight: 16, // 纵向多少个格子\n\t\t\tshow_monster_life: true, // 是否显示怪物的生命值\n\t\t\tfps: 0,\n\t\t\texp_fps: 24, // 期望的 fps\n\t\t\texp_fps_half: 12,\n\t\t\texp_fps_quarter: 6,\n\t\t\texp_fps_eighth: 4,\n\t\t\tstage_data: {},\n\t\t\tdefaultSettings: function () {\n\t\t\t\treturn {\n\t\t\t\t\tstep_time: 36, // 每一次 step 循环之间相隔多少毫秒\n\t\t\t\t\tgrid_size: 32 * _TD.retina, // px\n\t\t\t\t\tpadding: 10 * _TD.retina, // px\n\t\t\t\t\tglobal_speed: 0.1 // 全局速度系数\n\t\t\t\t};\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 初始化\n\t\t\t * @param ob_board\n\t\t\t */\n\t\t\tinit: function (ob_board/*, ob_info*/) {\n\t\t\t\tthis.obj_board = TD.lang.$e(ob_board);\n\t\t\t\tthis.canvas = this.obj_board.getElementsByTagName(\"canvas\")[0];\n\t\t\t\t//this.obj_info = TD.lang.$e(ob_info);\n\t\t\t\tif (!this.canvas.getContext) return; // 不支持 canvas\n\t\t\t\tthis.ctx = this.canvas.getContext(\"2d\");\n\t\t\t\tthis.monster_type_count = TD.getDefaultMonsterAttributes(); // 一共有多少种怪物\n\t\t\t\tthis.iframe = 0; // 当前播放到第几帧了\n\t\t\t\tthis.last_iframe_time = (new Date()).getTime();\n\t\t\t\tthis.fps = 0;\n\n\t\t\t\tthis.start();\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 开始游戏,或重新开始游戏\n\t\t\t */\n\t\t\tstart: function () {\n\t\t\t\tclearTimeout(this._st);\n\t\t\t\tTD.log(\"Start!\");\n\t\t\t\tvar _this = this;\n\t\t\t\tthis._exp_fps_0 = this.exp_fps - 0.4; // 下限\n\t\t\t\tthis._exp_fps_1 = this.exp_fps + 0.4; // 上限\n\n\t\t\t\tthis.mode = \"normal\"; // mode 分为 normail(普通模式)及 build(建造模式)两种\n\t\t\t\tthis.eventManager.clear(); // 清除事件管理器中监听的事件\n\t\t\t\tthis.lang.mix(this, this.defaultSettings());\n\t\t\t\tthis.stage = new TD.Stage(\"stage-main\", TD.getDefaultStageData(\"stage_main\"));\n\n\t\t\t\tthis.canvas.setAttribute(\"width\", this.stage.width);\n\t\t\t\tthis.canvas.setAttribute(\"height\", this.stage.height);\n\t\t\t\tthis.canvas.style.width = (this.stage.width / _TD.retina) + \"px\";\n\t\t\t\tthis.canvas.style.height = (this.stage.height / _TD.retina) + \"px\";\n\n\t\t\t\tthis.canvas.onmousemove = function (e) {\n\t\t\t\t\tvar xy = _this.getEventXY.call(_this, e);\n\t\t\t\t\t_this.hover(xy[0], xy[1]);\n\t\t\t\t};\n\t\t\t\tthis.canvas.onclick = function (e) {\n\t\t\t\t\tvar xy = _this.getEventXY.call(_this, e);\n\t\t\t\t\t_this.click(xy[0], xy[1]);\n\t\t\t\t};\n\n\t\t\t\tthis.is_paused = false;\n\t\t\t\tthis.stage.start();\n\t\t\t\tthis.step();\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 作弊方法\n\t\t\t * @param cheat_code\n\t\t\t *\n\t\t\t * 用例:\n\t\t\t * 1、增加 100 万金钱:javascript:_TD.cheat=\"money+\";void(0);\n\t\t\t * 2、难度增倍:javascript:_TD.cheat=\"difficulty+\";void(0);\n\t\t\t * 3、难度减半:javascript:_TD.cheat=\"difficulty-\";void(0);\n\t\t\t * 4、生命值恢复:javascript:_TD.cheat=\"life+\";void(0);\n\t\t\t * 5、生命值降为最低:javascript:_TD.cheat=\"life-\";void(0);\n\t\t\t */\n\t\t\tcheckCheat: function (cheat_code) {\n\t\t\t\tswitch (cheat_code) {\n\t\t\t\t\tcase \"money+\":\n\t\t\t\t\t\tthis.money += 1000000;\n\t\t\t\t\t\tthis.log(\"cheat success!\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"life+\":\n\t\t\t\t\t\tthis.life = 100;\n\t\t\t\t\t\tthis.log(\"cheat success!\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"life-\":\n\t\t\t\t\t\tthis.life = 1;\n\t\t\t\t\t\tthis.log(\"cheat success!\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"difficulty+\":\n\t\t\t\t\t\tthis.difficulty *= 2;\n\t\t\t\t\t\tthis.log(\"cheat success! difficulty = \" + this.difficulty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"difficulty-\":\n\t\t\t\t\t\tthis.difficulty /= 2;\n\t\t\t\t\t\tthis.log(\"cheat success! difficulty = \" + this.difficulty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 主循环方法\n\t\t\t */\n\t\t\tstep: function () {\n\n\t\t\t\tif (this.is_debug && _TD && _TD.cheat) {\n\t\t\t\t\t// 检查作弊代码\n\t\t\t\t\tthis.checkCheat(_TD.cheat);\n\t\t\t\t\t_TD.cheat = \"\";\n\t\t\t\t}\n\n\t\t\t\tif (this.is_paused) return;\n\n\t\t\t\tthis.iframe++; // 当前总第多少帧\n\t\t\t\tif (this.iframe % 50 == 0) {\n\t\t\t\t\t// 计算 fps\n\t\t\t\t\tvar t = (new Date()).getTime(),\n\t\t\t\t\t\tstep_time = this.step_time;\n\t\t\t\t\tthis.fps = Math.round(500000 / (t - this.last_iframe_time)) / 10;\n\t\t\t\t\tthis.last_iframe_time = t;\n\n\t\t\t\t\t// 动态调整 step_time ,保证 fps 恒定为 24 左右\n\t\t\t\t\tif (this.fps < this._exp_fps_0 && step_time > 1) {\n\t\t\t\t\t\tstep_time--;\n\t\t\t\t\t} else if (this.fps > this._exp_fps_1) {\n\t\t\t\t\t\tstep_time++;\n\t\t\t\t\t}\n//\t\t\t\t\tif (step_time != this.step_time)\n//\t\t\t\t\t\tTD.log(\"FPS: \" + this.fps + \", Step Time: \" + step_time);\n\t\t\t\t\tthis.step_time = step_time;\n\t\t\t\t}\n\t\t\t\tif (this.iframe % 2400 == 0) TD.gc(); // 每隔一段时间自动回收垃圾\n\n\t\t\t\tthis.stage.step();\n\t\t\t\tthis.stage.render();\n\n\t\t\t\tvar _this = this;\n\t\t\t\tthis._st = setTimeout(function () {\n\t\t\t\t\t_this.step();\n\t\t\t\t}, this.step_time);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 取得事件相对于 canvas 左上角的坐标\n\t\t\t * @param e\n\t\t\t */\n\t\t\tgetEventXY: function (e) {\n\t\t\t\tvar wra = TD.lang.$e(\"wrapper\"),\n\t\t\t\t\tx = e.clientX - wra.offsetLeft - this.canvas.offsetLeft + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft),\n\t\t\t\t\ty = e.clientY - wra.offsetTop - this.canvas.offsetTop + Math.max(document.documentElement.scrollTop, document.body.scrollTop);\n\n\t\t\t\treturn [x * _TD.retina, y * _TD.retina];\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 鼠标移到指定位置事件\n\t\t\t * @param x\n\t\t\t * @param y\n\t\t\t */\n\t\t\thover: function (x, y) {\n\t\t\t\tthis.eventManager.hover(x, y);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 点击事件\n\t\t\t * @param x\n\t\t\t * @param y\n\t\t\t */\n\t\t\tclick: function (x, y) {\n\t\t\t\tthis.eventManager.click(x, y);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 是否将 canvas 中的鼠标指针变为手的形状\n\t\t\t * @param v {Boolean}\n\t\t\t */\n\t\t\tmouseHand: function (v) {\n\t\t\t\tthis.canvas.style.cursor = v ? \"pointer\" : \"default\";\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 显示调试信息,只在 is_debug 为 true 的情况下有效\n\t\t\t * @param txt\n\t\t\t */\n\t\t\tlog: function (txt) {\n\t\t\t\tthis.is_debug && window.console && console.log && console.log(txt);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * 回收内存\n\t\t\t * 注意:CollectGarbage 只在 IE 下有效\n\t\t\t */\n\t\t\tgc: function () {\n\t\t\t\tif (window.CollectGarbage) {\n\t\t\t\t\tCollectGarbage();\n\t\t\t\t\tsetTimeout(CollectGarbage, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfor (i = 0; this.a[i]; i++) {\n\t\t\t// 依次执行添加到列表中的函数\n\t\t\tthis.a[i](TD);\n\t\t}\n\t\tdelete this.a;\n\n\t\tTD.init(td_board);\n\t}\n};\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tTD.lang = {\n\t\t/**\n\t\t * document.getElementById 方法的简写\n\t\t * @param el_id {String}\n\t\t */\n\t\t$e: function (el_id) {\n\t\t\treturn document.getElementById(el_id);\n\t\t},\n\n\t\t/**\n\t\t * 创建一个 DOM 元素\n\t\t * @param tag_name {String}\n\t\t * @param attributes {Object}\n\t\t * @param parent_node {HTMLElement}\n\t\t * @return {HTMLElement}\n\t\t */\n\t\t$c: function (tag_name, attributes, parent_node) {\n\t\t\tvar el = document.createElement(tag_name);\n\t\t\tattributes = attributes || {};\n\n\t\t\tfor (var k in attributes) {\n\t\t\t\tif (attributes.hasOwnProperty(k)) {\n\t\t\t\t\tel.setAttribute(k, attributes[k]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (parent_node)\n\t\t\t\tparent_node.appendChild(el);\n\n\t\t\treturn el;\n\t\t},\n\n\t\t/**\n\t\t * 从字符串 s 左边截取n个字符\n\t\t * 如果包含汉字,则汉字按两个字符计算\n\t\t * @param s {String} 输入的字符串\n\t\t * @param n {Number}\n\t\t */\n\t\tstrLeft: function (s, n) {\n\t\t\tvar s2 = s.slice(0, n),\n\t\t\t\ti = s2.replace(/[^\\x00-\\xff]/g, \"**\").length;\n\t\t\tif (i <= n) return s2;\n\t\t\ti -= s2.length;\n\t\t\tswitch (i) {\n\t\t\t\tcase 0:\n\t\t\t\t\treturn s2;\n\t\t\t\tcase n:\n\t\t\t\t\treturn s.slice(0, n >> 1);\n\t\t\t\tdefault:\n\t\t\t\t\tvar k = n - i,\n\t\t\t\t\t\ts3 = s.slice(k, n),\n\t\t\t\t\t\tj = s3.replace(/[\\x00-\\xff]/g, \"\").length;\n\t\t\t\t\treturn j ?\n\t\t\t\t\ts.slice(0, k) + this.arguments.callee(s3, j) :\n\t\t\t\t\t\ts.slice(0, k);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 取得一个字符串的字节长度\n\t\t * 汉字等字符长度算2,英文、数字等算1\n\t\t * @param s {String}\n\t\t */\n\t\tstrLen2: function (s) {\n\t\t\treturn s.replace(/[^\\x00-\\xff]/g, \"**\").length;\n\t\t},\n\n\t\t/**\n\t\t * 对一个数组的每一个元素执行指定方法\n\t\t * @param list {Array}\n\t\t * @param f {Function}\n\t\t */\n\t\teach: function (list, f) {\n\t\t\tif (Array.prototype.forEach) {\n\t\t\t\tlist.forEach(f);\n\t\t\t} else {\n\t\t\t\tfor (var i = 0, l = list.length; i < l; i++) {\n\t\t\t\t\tf(list[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 对一个数组的每一项依次执行指定方法,直到某一项的返回值为 true\n\t\t * 返回第一个令 f 值为 true 的元素,如没有元素令 f 值为 true,则\n\t\t * 返回 null\n\t\t * @param list {Array}\n\t\t * @param f {Function}\n\t\t * @return {Object}\n\t\t */\n\t\tany: function (list, f) {\n\t\t\tfor (var i = 0, l = list.length; i < l; i++) {\n\t\t\t\tif (f(list[i]))\n\t\t\t\t\treturn list[i];\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\n\t\t/**\n\t\t * 依次弹出列表中的元素,并对其进行操作\n\t\t * 注意,执行完毕之后原数组将被清空\n\t\t * 类似于 each,不同的是这个函数执行完后原数组将被清空\n\t\t * @param list {Array}\n\t\t * @param f {Function}\n\t\t */\n\t\tshift: function (list, f) {\n\t\t\twhile (list[0]) {\n\t\t\t\tf(list.shift());\n//\t\t\tf.apply(list.shift(), args);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 传入一个数组,将其随机排序并返回\n\t\t * 返回的是一个新的数组,原数组不变\n\t\t * @param list {Array}\n\t\t * @return {Array}\n\t\t */\n\t\trndSort: function (list) {\n\t\t\tvar a = list.concat();\n\t\t\treturn a.sort(function () {\n\t\t\t\treturn Math.random() - 0.5;\n\t\t\t});\n\t\t},\n\n\t\t_rndRGB2: function (v) {\n\t\t\tvar s = v.toString(16);\n\t\t\treturn s.length == 2 ? s : (\"0\" + s);\n\t\t},\n\t\t/**\n\t\t * 随机生成一个 RGB 颜色\n\t\t */\n\t\trndRGB: function () {\n\t\t\tvar r = Math.floor(Math.random() * 256),\n\t\t\t\tg = Math.floor(Math.random() * 256),\n\t\t\t\tb = Math.floor(Math.random() * 256);\n\n\t\t\treturn \"#\" + this._rndRGB2(r) + this._rndRGB2(g) + this._rndRGB2(b);\n\t\t},\n\t\t/**\n\t\t * 将一个 rgb 色彩字符串转化为一个数组\n\t\t * eg: '#ffffff' => [255, 255, 255]\n\t\t * @param rgb_str {String} rgb色彩字符串,类似于“#f8c693”\n\t\t */\n\t\trgb2Arr: function (rgb_str) {\n\t\t\tif (rgb_str.length != 7) return [0, 0, 0];\n\n\t\t\tvar r = rgb_str.substr(1, 2),\n\t\t\t\tg = rgb_str.substr(3, 2),\n\t\t\t\tb = rgb_str.substr(3, 2);\n\n\t\t\treturn [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)];\n\t\t},\n\n\t\t/**\n\t\t * 生成一个长度为 n 的随机字符串\n\t\t *\n\t\t * @param [n] {Number}\n\t\t */\n\t\trndStr: function (n) {\n\t\t\tn = n || 16;\n\t\t\tvar chars = \"1234567890abcdefghijklmnopqrstuvwxyz\",\n\t\t\t\ta = [],\n\t\t\t\ti, chars_len = chars.length, r;\n\n\t\t\tfor (i = 0; i < n; i++) {\n\t\t\t\tr = Math.floor(Math.random() * chars_len);\n\t\t\t\ta.push(chars.substr(r, 1));\n\t\t\t}\n\t\t\treturn a.join(\"\");\n\t\t},\n\n\t\t/**\n\t\t * 空函数,一般用于占位\n\t\t */\n\t\tnullFunc: function () {\n\t\t},\n\n\t\t/**\n\t\t * 判断两个数组是否相等\n\t\t *\n\t\t * @param arr1 {Array}\n\t\t * @param arr2 {Array}\n\t\t */\n\t\tarrayEqual: function (arr1, arr2) {\n\t\t\tvar i, l = arr1.length;\n\n\t\t\tif (l != arr2.length) return false;\n\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\tif (arr1[i] != arr2[i]) return false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * 将所有 s 的属性复制给 r\n\t\t * @param r {Object}\n\t\t * @param s {Object}\n\t\t * @param [is_overwrite] {Boolean} 如指定为 false ,则不覆盖已有的值,其它值\n\t\t * 包括 undefined ,都表示 s 中的同名属性将覆盖 r 中的值\n\t\t */\n\t\tmix: function (r, s, is_overwrite) {\n\t\t\tif (!s || !r) return r;\n\n\t\t\tfor (var p in s) {\n\t\t\t\tif (s.hasOwnProperty(p) && (is_overwrite !== false || !(p in r))) {\n\t\t\t\t\tr[p] = s[p];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t};\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * 事件管理器\n\t */\n\tTD.eventManager = {\n\t\tex: -1, // 事件坐标 x\n\t\tey: -1, // 事件坐标 y\n\t\t_registers: {}, // 注册监听事件的元素\n\n\t\t// 目前支持的事件类型\n\t\tontypes: [\n\t\t\t\"enter\", // 鼠标移入\n\t\t\t\"hover\", // 鼠标在元素上,相当于 onmouseover\n\t\t\t\"out\", // 鼠标移出\n\t\t\t\"click\" // 鼠标点击\n\t\t],\n\n\t\t// 当前事件类型\n\t\tcurrent_type: \"hover\",\n\n\t\t/**\n\t\t * 根据事件坐标,判断事件是否在元素上\n\t\t * @param el {Element} Element 元素\n\t\t * @return {Boolean}\n\t\t */\n\t\tisOn: function (el) {\n\t\t\treturn (this.ex != -1 &&\n\t\t\tthis.ey != -1 &&\n\t\t\tthis.ex > el.x &&\n\t\t\tthis.ex < el.x2 &&\n\t\t\tthis.ey > el.y &&\n\t\t\tthis.ey < el.y2);\n\t\t},\n\n\t\t/**\n\t\t * 根据元素名、事件名,生成一个字符串标识,用于注册事件监听\n\t\t * @param el {Element}\n\t\t * @param evt_type {String}\n\t\t * @return evt_name {String} 字符串标识\n\t\t */\n\t\t_mkElEvtName: function (el, evt_type) {\n\t\t\treturn el.id + \"::_evt_::\" + evt_type;\n\t\t},\n\n\t\t/**\n\t\t * 为元素注册事件监听\n\t\t * 现在的实现比较简单,如果一个元素对某个事件多次注册监听,后面的监听将会覆盖前面的\n\t\t *\n\t\t * @param el {Element}\n\t\t * @param evt_type {String}\n\t\t * @param f {Function}\n\t\t */\n\t\ton: function (el, evt_type, f) {\n\t\t\tthis._registers[this._mkElEvtName(el, evt_type)] = [el, evt_type, f];\n\t\t},\n\n\t\t/**\n\t\t * 移除元素对指定事件的监听\n\t\t * @param el {Element}\n\t\t * @param evt_type {String}\n\t\t */\n\t\tremoveEventListener: function (el, evt_type) {\n\t\t\tvar en = this._mkElEvtName(el, evt_type);\n\t\t\tdelete this._registers[en];\n\t\t},\n\n\t\t/**\n\t\t * 清除所有监听事件\n\t\t */\n\t\tclear: function () {\n\t\t\tdelete this._registers;\n\t\t\tthis._registers = {};\n\t\t\t//this.elements = [];\n\t\t},\n\n\t\t/**\n\t\t * 主循环方法\n\t\t */\n\t\tstep: function () {\n\t\t\tif (!this.current_type) return; // 没有事件被触发\n\n\t\t\tvar k, a, el, et, f,\n\t\t\t//en,\n\t\t\t\tj,\n\t\t\t\t_this = this,\n\t\t\t\tontypes_len = this.ontypes.length,\n\t\t\t\tis_evt_on,\n//\t\t\t\treg_length = 0,\n\t\t\t\tto_del_el = [];\n\n\t\t\t//var m = TD.stage.current_act.current_scene.map;\n\t\t\t//TD.log([m.is_hover, this.isOn(m)]);\n\n\t\t\t// 遍历当前注册的事件\n\t\t\tfor (k in this._registers) {\n//\t\t\t\treg_length ++;\n\t\t\t\tif (!this._registers.hasOwnProperty(k)) continue;\n\t\t\t\ta = this._registers[k];\n\t\t\t\tel = a[0]; // 事件对应的元素\n\t\t\t\tet = a[1]; // 事件类型\n\t\t\t\tf = a[2]; // 事件处理函数\n\t\t\t\tif (!el.is_valid) {\n\t\t\t\t\tto_del_el.push(el);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!el.is_visiable) continue; // 不可见元素不响应事件\n\n\t\t\t\tis_evt_on = this.isOn(el); // 事件是否发生在元素上\n\n\t\t\t\tif (this.current_type != \"click\") {\n\t\t\t\t\t// enter / out / hover 事件\n\n\t\t\t\t\tif (et == \"hover\" && el.is_hover && is_evt_on) {\n\t\t\t\t\t\t// 普通的 hover\n\t\t\t\t\t\tf();\n\t\t\t\t\t\tthis.current_type = \"hover\";\n\t\t\t\t\t} else if (et == \"enter\" && !el.is_hover && is_evt_on) {\n\t\t\t\t\t\t// enter 事件\n\t\t\t\t\t\tel.is_hover = true;\n\t\t\t\t\t\tf();\n\t\t\t\t\t\tthis.current_type = \"enter\";\n\t\t\t\t\t} else if (et == \"out\" && el.is_hover && !is_evt_on) {\n\t\t\t\t\t\t// out 事件\n\t\t\t\t\t\tel.is_hover = false;\n\t\t\t\t\t\tf();\n\t\t\t\t\t\tthis.current_type = \"out\";\n//\t\t\t\t\t} else {\n\t\t\t\t\t\t// 事件与当前元素无关\n//\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\t// click 事件\n\t\t\t\t\tif (is_evt_on && et == \"click\") f();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 删除指定元素列表的事件\n\t\t\tTD.lang.each(to_del_el, function (obj) {\n\t\t\t\tfor (j = 0; j < ontypes_len; j++)\n\t\t\t\t\t_this.removeEventListener(obj, _this.ontypes[j]);\n\t\t\t});\n//\t\t\tTD.log(reg_length);\n\t\t\tthis.current_type = \"\";\n\t\t},\n\n\t\t/**\n\t\t * 鼠标在元素上\n\t\t * @param ex {Number}\n\t\t * @param ey {Number}\n\t\t */\n\t\thover: function (ex, ey) {\n\t\t\t// 如果还有 click 事件未处理则退出,点击事件具有更高的优先级\n\t\t\tif (this.current_type == \"click\") return;\n\n\t\t\tthis.current_type = \"hover\";\n\t\t\tthis.ex = ex;\n\t\t\tthis.ey = ey;\n\t\t},\n\n\t\t/**\n\t\t * 点击事件\n\t\t * @param ex {Number}\n\t\t * @param ey {Number}\n\t\t */\n\t\tclick: function (ex, ey) {\n\t\t\tthis.current_type = \"click\";\n\t\t\tthis.ex = ex;\n\t\t\tthis.ey = ey;\n\t\t}\n\t};\n\n}); // _TD.a.push end\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * 舞台类\n\t * @param id {String} 舞台ID\n\t * @param cfg {Object} 配置\n\t */\n\tTD.Stage = function (id, cfg) {\n\t\tthis.id = id || (\"stage-\" + TD.lang.rndStr());\n\t\tthis.cfg = cfg || {};\n\t\tthis.width = this.cfg.width || 640;\n\t\tthis.height = this.cfg.height || 540;\n\n\t\t/**\n\t\t * mode 有以下状态:\n\t\t * \"normal\": 普通状态\n\t\t * \"build\": 建造模式\n\t\t */\n\t\tthis.mode = \"normal\";\n\n\t\t/*\n\t\t * state 有以下几种状态:\n\t\t * 0: 等待中\n\t\t * 1: 运行中\n\t\t * 2: 暂停\n\t\t * 3: 已结束\n\t\t */\n\t\tthis.state = 0;\n\t\tthis.acts = [];\n\t\tthis.current_act = null;\n\t\tthis._step2 = TD.lang.nullFunc;\n\n\t\tthis._init();\n\t};\n\n\tTD.Stage.prototype = {\n\t\t_init: function () {\n\t\t\tif (typeof this.cfg.init == \"function\") {\n\t\t\t\tthis.cfg.init.call(this);\n\t\t\t}\n\t\t\tif (typeof this.cfg.step2 == \"function\") {\n\t\t\t\tthis._step2 = this.cfg.step2;\n\t\t\t}\n\t\t},\n\t\tstart: function () {\n\t\t\tthis.state = 1;\n\t\t\tTD.lang.each(this.acts, function (obj) {\n\t\t\t\tobj.start();\n\t\t\t});\n\t\t},\n\t\tpause: function () {\n\t\t\tthis.state = 2;\n\t\t},\n\t\tgameover: function () {\n\t\t\t//this.pause();\n\t\t\tthis.current_act.gameover();\n\t\t},\n\t\t/**\n\t\t * 清除本 stage 所有物品\n\t\t */\n\t\tclear: function () {\n\t\t\tthis.state = 3;\n\t\t\tTD.lang.each(this.acts, function (obj) {\n\t\t\t\tobj.clear();\n\t\t\t});\n//\t\tdelete this;\n\t\t},\n\t\t/**\n\t\t * 主循环函数\n\t\t */\n\t\tstep: function () {\n\t\t\tif (this.state != 1 || !this.current_act) return;\n\t\t\tTD.eventManager.step();\n\t\t\tthis.current_act.step();\n\n\t\t\tthis._step2();\n\t\t},\n\t\t/**\n\t\t * 绘制函数\n\t\t */\n\t\trender: function () {\n\t\t\tif (this.state == 0 || this.state == 3 || !this.current_act) return;\n\t\t\tthis.current_act.render();\n\t\t},\n\t\taddAct: function (act) {\n\t\t\tthis.acts.push(act);\n\t\t},\n\t\taddElement: function (el, step_level, render_level) {\n\t\t\tif (this.current_act)\n\t\t\t\tthis.current_act.addElement(el, step_level, render_level);\n\t\t}\n\t};\n\n}); // _TD.a.push end\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tTD.Act = function (stage, id) {\n\t\tthis.stage = stage;\n\t\tthis.id = id || (\"act-\" + TD.lang.rndStr());\n\n\t\t/*\n\t\t * state 有以下几种状态:\n\t\t * 0: 等待中\n\t\t * 1: 运行中\n\t\t * 2: 暂停\n\t\t * 3: 已结束\n\t\t */\n\t\tthis.state = 0;\n\t\tthis.scenes = [];\n\t\tthis.end_queue = []; // 本 act 结束后要执行的队列,添加时请保证里面全是函数\n\t\tthis.current_scene = null;\n\n\t\tthis._init();\n\t};\n\n\tTD.Act.prototype = {\n\t\t_init: function () {\n\t\t\tthis.stage.addAct(this);\n\t\t},\n\t\t/*\n\t\t * 开始当前 act\n\t\t */\n\t\tstart: function () {\n\t\t\tif (this.stage.current_act && this.stage.current_act.state != 3) {\n\t\t\t\t// queue...\n\t\t\t\tthis.state = 0;\n\t\t\t\tthis.stage.current_act.queue(this.start);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// start\n\t\t\tthis.state = 1;\n\t\t\tthis.stage.current_act = this;\n\t\t\tTD.lang.each(this.scenes, function (obj) {\n\t\t\t\tobj.start();\n\t\t\t});\n\t\t},\n\t\tpause: function () {\n\t\t\tthis.state = 2;\n\t\t},\n\t\tend: function () {\n\t\t\tthis.state = 3;\n\t\t\tvar f;\n\t\t\twhile (f = this.end_queue.shift()) {\n\t\t\t\tf();\n\t\t\t}\n\t\t\tthis.stage.current_act = null;\n\t\t},\n\t\tqueue: function (f) {\n\t\t\tthis.end_queue.push(f);\n\t\t},\n\t\tclear: function () {\n\t\t\tthis.state = 3;\n\t\t\tTD.lang.each(this.scenes, function (obj) {\n\t\t\t\tobj.clear();\n\t\t\t});\n//\t\tdelete this;\n\t\t},\n\t\tstep: function () {\n\t\t\tif (this.state != 1 || !this.current_scene) return;\n\t\t\tthis.current_scene.step();\n\t\t},\n\t\trender: function () {\n\t\t\tif (this.state == 0 || this.state == 3 || !this.current_scene) return;\n\t\t\tthis.current_scene.render();\n\t\t},\n\t\taddScene: function (scene) {\n\t\t\tthis.scenes.push(scene);\n\t\t},\n\t\taddElement: function (el, step_level, render_level) {\n\t\t\tif (this.current_scene)\n\t\t\t\tthis.current_scene.addElement(el, step_level, render_level);\n\t\t},\n\t\tgameover: function () {\n\t\t\t//this.is_paused = true;\n\t\t\t//this.is_gameover = true;\n\t\t\tthis.current_scene.gameover();\n\t\t}\n\t};\n\n}); // _TD.a.push end\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tTD.Scene = function (act, id) {\n\t\tthis.act = act;\n\t\tthis.stage = act.stage;\n\t\tthis.is_gameover = false;\n\t\tthis.id = id || (\"scene-\" + TD.lang.rndStr());\n\t\t/*\n\t\t * state 有以下几种状态:\n\t\t * 0: 等待中\n\t\t * 1: 运行中\n\t\t * 2: 暂停\n\t\t * 3: 已结束\n\t\t */\n\t\tthis.state = 0;\n\t\tthis.end_queue = []; // 本 scene 结束后要执行的队列,添加时请保证里面全是函数\n\t\tthis._step_elements = [\n\t\t\t// step 共分为 3 层\n\t\t\t[],\n\t\t\t// 0\n\t\t\t[],\n\t\t\t// 1 默认\n\t\t\t[] // 2\n\t\t];\n\t\tthis._render_elements = [ // 渲染共分为 10 层\n\t\t\t[], // 0 背景 1 背景图片\n\t\t\t[], // 1 背景 2\n\t\t\t[], // 2 背景 3 地图、格子\n\t\t\t[], // 3 地面 1 一般建筑\n\t\t\t[], // 4 地面 2 人物、NPC等\n\t\t\t[], // 5 地面 3\n\t\t\t[], // 6 天空 1 子弹等\n\t\t\t[], // 7 天空 2 主地图外边的遮罩,panel\n\t\t\t[], // 8 天空 3\n\t\t\t[] // 9 系统特殊操作,如选中高亮,提示、文字遮盖等\n\t\t];\n\n\t\tthis._init();\n\t};\n\n\tTD.Scene.prototype = {\n\t\t_init: function () {\n\t\t\tthis.act.addScene(this);\n\t\t\tthis.wave = 0; // 第几波\n\t\t},\n\t\tstart: function () {\n\t\t\tif (this.act.current_scene &&\n\t\t\t\tthis.act.current_scene != this &&\n\t\t\t\tthis.act.current_scene.state != 3) {\n\t\t\t\t// queue...\n\t\t\t\tthis.state = 0;\n\t\t\t\tthis.act.current_scene.queue(this.start);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// start\n\t\t\tthis.state = 1;\n\t\t\tthis.act.current_scene = this;\n\t\t},\n\t\tpause: function () {\n\t\t\tthis.state = 2;\n\t\t},\n\t\tend: function () {\n\t\t\tthis.state = 3;\n\t\t\tvar f;\n\t\t\twhile (f = this.end_queue.shift()) {\n\t\t\t\tf();\n\t\t\t}\n\t\t\tthis.clear();\n\t\t\tthis.act.current_scene = null;\n\t\t},\n\t\t/**\n\t\t * 清空场景\n\t\t */\n\t\tclear: function () {\n\t\t\t// 清空本 scene 中引用的所有对象以回收内存\n\t\t\tTD.lang.shift(this._step_elements, function (obj) {\n\t\t\t\tTD.lang.shift(obj, function (obj2) {\n\t\t\t\t\t// element\n\t\t\t\t\t//delete this.scene;\n\t\t\t\t\tobj2.del();\n//\t\t\t\tdelete this;\n\t\t\t\t});\n//\t\t\tdelete this;\n\t\t\t});\n\t\t\tTD.lang.shift(this._render_elements, function (obj) {\n\t\t\t\tTD.lang.shift(obj, function (obj2) {\n\t\t\t\t\t// element\n\t\t\t\t\t//delete this.scene;\n\t\t\t\t\tobj2.del();\n//\t\t\t\tdelete this;\n\t\t\t\t});\n//\t\t\tdelete this;\n\t\t\t});\n//\t\tdelete this;\n\t\t},\n\t\tqueue: function (f) {\n\t\t\tthis.end_queue.push(f);\n\t\t},\n\t\tgameover: function () {\n\t\t\tif (this.is_gameover) return;\n\t\t\tthis.pause();\n\t\t\tthis.is_gameover = true;\n\t\t},\n\t\tstep: function () {\n\t\t\tif (this.state != 1) return;\n\t\t\tif (TD.life <= 0) {\n\t\t\t\tTD.life = 0;\n\t\t\t\tthis.gameover();\n\t\t\t}\n\n\t\t\tvar i, a;\n\t\t\tfor (i = 0; i < 3; i++) {\n\t\t\t\ta = [];\n\t\t\t\tvar level_elements = this._step_elements[i];\n\t\t\t\tTD.lang.shift(level_elements, function (obj) {\n\t\t\t\t\tif (obj.is_valid) {\n\t\t\t\t\t\tif (!obj.is_paused)\n\t\t\t\t\t\t\tobj.step();\n\t\t\t\t\t\ta.push(obj);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tobj = null;\n\t\t\t\t\t\t}, 500); // 一会儿之后将这个对象彻底删除以收回内存\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._step_elements[i] = a;\n\t\t\t}\n\t\t},\n\t\trender: function () {\n\t\t\tif (this.state == 0 || this.state == 3) return;\n\t\t\tvar i, a,\n\t\t\t\tctx = TD.ctx;\n\n\t\t\tctx.clearRect(0, 0, this.stage.width, this.stage.height);\n\n\t\t\tfor (i = 0; i < 10; i++) {\n\t\t\t\ta = [];\n\t\t\t\tvar level_elements = this._render_elements[i];\n\t\t\t\tTD.lang.shift(level_elements, function (obj) {\n\t\t\t\t\tif (obj.is_valid) {\n\t\t\t\t\t\tif (obj.is_visiable)\n\t\t\t\t\t\t\tobj.render();\n\t\t\t\t\t\ta.push(obj);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._render_elements[i] = a;\n\t\t\t}\n\n\t\t\tif (this.is_gameover) {\n\t\t\t\tthis.panel.gameover_obj.show();\n\t\t\t}\n\t\t},\n\t\taddElement: function (el, step_level, render_level) {\n\t\t\t//TD.log([step_level, render_level]);\n\t\t\tstep_level = step_level || el.step_level || 1;\n\t\t\trender_level = render_level || el.render_level;\n\t\t\tthis._step_elements[step_level].push(el);\n\t\t\tthis._render_elements[render_level].push(el);\n\t\t\tel.scene = this;\n\t\t\tel.step_level = step_level;\n\t\t\tel.render_level = render_level;\n\t\t}\n\t};\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n *\n * 本文件定义了 Element 类,这个类是游戏中所有元素的基类,\n * 包括地图、格子、怪物、建筑、子弹、气球提示等都基于这个类\n *\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * Element 是游戏中所有可控制元素的基类\n\t * @param id {String} 给这个元素一个唯一的不重复的 ID,如果不指定则随机生成\n\t * @param cfg {Object} 元素的配置信息\n\t */\n\tTD.Element = function (id, cfg) {\n\t\tthis.id = id || (\"el-\" + TD.lang.rndStr());\n\t\tthis.cfg = cfg || {};\n\n\t\tthis.is_valid = true;\n\t\tthis.is_visiable = typeof cfg.is_visiable != \"undefined\" ? cfg.is_visiable : true;\n\t\tthis.is_paused = false;\n\t\tthis.is_hover = false;\n\t\tthis.x = this.cfg.x || -1;\n\t\tthis.y = this.cfg.y || -1;\n\t\tthis.width = this.cfg.width || 0;\n\t\tthis.height = this.cfg.height || 0;\n\t\tthis.step_level = cfg.step_level || 1;\n\t\tthis.render_level = cfg.render_level;\n\t\tthis.on_events = cfg.on_events || [];\n\n\t\tthis._init();\n\t};\n\n\tTD.Element.prototype = {\n\t\t_init: function () {\n\t\t\tvar _this = this,\n\t\t\t\ti, en, len;\n\n\t\t\t// 监听指定事件\n\t\t\tfor (i = 0, len = this.on_events.length; i < len; i++) {\n\t\t\t\ten = this.on_events[i];\n\t\t\t\tswitch (en) {\n\n\t\t\t\t\t// 鼠标进入元素\n\t\t\t\t\tcase \"enter\":\n\t\t\t\t\t\tthis.on(\"enter\", function () {\n\t\t\t\t\t\t\t_this.onEnter();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// 鼠标移出元素\n\t\t\t\t\tcase \"out\":\n\t\t\t\t\t\tthis.on(\"out\", function () {\n\t\t\t\t\t\t\t_this.onOut();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// 鼠标在元素上,相当于 DOM 中的 onmouseover\n\t\t\t\t\tcase \"hover\":\n\t\t\t\t\t\tthis.on(\"hover\", function () {\n\t\t\t\t\t\t\t_this.onHover();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// 鼠标点击了元素\n\t\t\t\t\tcase \"click\":\n\t\t\t\t\t\tthis.on(\"click\", function () {\n\t\t\t\t\t\t\t_this.onClick();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.caculatePos();\n\t\t},\n\t\t/**\n\t\t * 重新计算元素的位置信息\n\t\t */\n\t\tcaculatePos: function () {\n\t\t\tthis.cx = this.x + this.width / 2; // 中心的位置\n\t\t\tthis.cy = this.y + this.height / 2;\n\t\t\tthis.x2 = this.x + this.width; // 右边界\n\t\t\tthis.y2 = this.y + this.height; // 下边界\n\t\t},\n\t\tstart: function () {\n\t\t\tthis.is_paused = false;\n\t\t},\n\t\tpause: function () {\n\t\t\tthis.is_paused = true;\n\t\t},\n\t\thide: function () {\n\t\t\tthis.is_visiable = false;\n\t\t\tthis.onOut();\n\t\t},\n\t\tshow: function () {\n\t\t\tthis.is_visiable = true;\n\t\t},\n\t\t/**\n\t\t * 删除本元素\n\t\t */\n\t\tdel: function () {\n\t\t\tthis.is_valid = false;\n\t\t},\n\t\t/**\n\t\t * 绑定指定类型的事件\n\t\t * @param evt_type {String} 事件类型\n\t\t * @param f {Function} 处理方法\n\t\t */\n\t\ton: function (evt_type, f) {\n\t\t\tTD.eventManager.on(this, evt_type, f);\n\t\t},\n\n\t\t// 下面几个方法默认为空,实例中按需要重载\n\t\tonEnter: TD.lang.nullFunc,\n\t\tonOut: TD.lang.nullFunc,\n\t\tonHover: TD.lang.nullFunc,\n\t\tonClick: TD.lang.nullFunc,\n\t\tstep: TD.lang.nullFunc,\n\t\trender: TD.lang.nullFunc,\n\n\t\t/**\n\t\t * 将当前 element 加入到场景 scene 中\n\t\t * 在加入本 element 之前,先加入 pre_add_list 中的element\n\t\t * @param scene\n\t\t * @param step_level {Number}\n\t\t * @param render_level {Number}\n\t\t * @param pre_add_list {Array} Optional [element1, element2, ...]\n\t\t */\n\t\taddToScene: function (scene, step_level, render_level, pre_add_list) {\n\t\t\tthis.scene = scene;\n\t\t\tif (isNaN(step_level)) return;\n\t\t\tthis.step_level = step_level || this.step_level;\n\t\t\tthis.render_level = render_level || this.render_level;\n\n\t\t\tif (pre_add_list) {\n\t\t\t\tTD.lang.each(pre_add_list, function (obj) {\n\t\t\t\t\tscene.addElement(obj, step_level, render_level);\n\t\t\t\t});\n\t\t\t}\n\t\t\tscene.addElement(this, step_level, render_level);\n\t\t}\n\t};\n\n}); // _TD.a.push end\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tvar _default_wait_clearInvalidElements = 20;\n\n\t// map 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar map_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.grid_x = cfg.grid_x || 10;\n\t\t\tthis.grid_y = cfg.grid_y || 10;\n\t\t\tthis.x = cfg.x || 0;\n\t\t\tthis.y = cfg.y || 0;\n\t\t\tthis.width = this.grid_x * TD.grid_size;\n\t\t\tthis.height = this.grid_y * TD.grid_size;\n\t\t\tthis.x2 = this.x + this.width;\n\t\t\tthis.y2 = this.y + this.width;\n\t\t\tthis.grids = [];\n\t\t\tthis.entrance = this.exit = null;\n\t\t\tthis.buildings = [];\n\t\t\tthis.monsters = [];\n\t\t\tthis.bullets = [];\n\t\t\tthis.scene = cfg.scene;\n\t\t\tthis.is_main_map = !!cfg.is_main_map;\n\t\t\tthis.select_hl = TD.MapSelectHighLight(this.id + \"-hl\", {\n\t\t\t\tmap: this\n\t\t\t});\n\t\t\tthis.select_hl.addToScene(this.scene, 1, 9);\n\t\t\tthis.selected_building = null;\n\t\t\tthis._wait_clearInvalidElements = _default_wait_clearInvalidElements;\n\t\t\tthis._wait_add_monsters = 0;\n\t\t\tthis._wait_add_monsters_arr = [];\n\t\t\tif (this.is_main_map) {\n\t\t\t\tthis.mmm = new MainMapMask(this.id + \"-mmm\", {\n\t\t\t\t\tmap: this\n\t\t\t\t});\n\t\t\t\tthis.mmm.addToScene(this.scene, 1, 7);\n\n\t\t\t}\n\n\t\t\t// 下面添加相应的格子\n\t\t\tvar i, l = this.grid_x * this.grid_y,\n\t\t\t\tgrid_data = cfg[\"grid_data\"] || [],\n\t\t\t\td, grid;\n\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\td = grid_data[i] || {};\n\t\t\t\td.mx = i % this.grid_x;\n\t\t\t\td.my = Math.floor(i / this.grid_x);\n\t\t\t\td.map = this;\n\t\t\t\td.step_level = this.step_level;\n\t\t\t\td.render_level = this.render_level;\n\t\t\t\tgrid = new TD.Grid(this.id + \"-grid-\" + d.mx + \"-\" + d.my, d);\n\t\t\t\tthis.grids.push(grid);\n\t\t\t}\n\n\t\t\tif (cfg.entrance && cfg.exit && !TD.lang.arrayEqual(cfg.entrance, cfg.exit)) {\n\t\t\t\tthis.entrance = this.getGrid(cfg.entrance[0], cfg.entrance[1]);\n\t\t\t\tthis.entrance.is_entrance = true;\n\t\t\t\tthis.exit = this.getGrid(cfg.exit[0], cfg.exit[1]);\n\t\t\t\tthis.exit.is_exit = true;\n\t\t\t}\n\n\t\t\tvar _this = this;\n\t\t\tif (cfg.grids_cfg) {\n\t\t\t\tTD.lang.each(cfg.grids_cfg, function (obj) {\n\t\t\t\t\tvar grid = _this.getGrid(obj.pos[0], obj.pos[1]);\n\t\t\t\t\tif (!grid) return;\n\t\t\t\t\tif (!isNaN(obj.passable_flag))\n\t\t\t\t\t\tgrid.passable_flag = obj.passable_flag;\n\t\t\t\t\tif (!isNaN(obj.build_flag))\n\t\t\t\t\t\tgrid.build_flag = obj.build_flag;\n\t\t\t\t\tif (obj.building) {\n\t\t\t\t\t\tgrid.addBuilding(obj.building);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 检查地图中是否有武器(具备攻击性的建筑)\n\t\t * 因为第一波怪物只有在地图上有了第一件武器后才会出现\n\t\t */\n\t\tcheckHasWeapon: function () {\n\t\t\tthis.has_weapon = (this.anyBuilding(function (obj) {\n\t\t\t\treturn obj.is_weapon;\n\t\t\t}) != null);\n\t\t},\n\n\t\t/**\n\t\t * 取得指定位置的格子对象\n\t\t * @param mx {Number} 地图上的坐标 x\n\t\t * @param my {Number} 地图上的坐标 y\n\t\t */\n\t\tgetGrid: function (mx, my) {\n\t\t\tvar p = my * this.grid_x + mx;\n\t\t\treturn this.grids[p];\n\t\t},\n\n\t\tanyMonster: function (f) {\n\t\t\treturn TD.lang.any(this.monsters, f);\n\t\t},\n\t\tanyBuilding: function (f) {\n\t\t\treturn TD.lang.any(this.buildings, f);\n\t\t},\n\t\tanyBullet: function (f) {\n\t\t\treturn TD.lang.any(this.bullets, f);\n\t\t},\n\t\teachBuilding: function (f) {\n\t\t\tTD.lang.each(this.buildings, f);\n\t\t},\n\t\teachMonster: function (f) {\n\t\t\tTD.lang.each(this.monsters, f);\n\t\t},\n\t\teachBullet: function (f) {\n\t\t\tTD.lang.each(this.bullets, f);\n\t\t},\n\n\t\t/**\n\t\t * 预建设\n\t\t * @param building_type {String}\n\t\t */\n\t\tpreBuild: function (building_type) {\n\t\t\tTD.mode = \"build\";\n\t\t\tif (this.pre_building) {\n\t\t\t\tthis.pre_building.remove();\n\t\t\t}\n\n\t\t\tthis.pre_building = new TD.Building(this.id + \"-\" + \"pre-building-\" + TD.lang.rndStr(), {\n\t\t\t\ttype: building_type,\n\t\t\t\tmap: this,\n\t\t\t\tis_pre_building: true\n\t\t\t});\n\t\t\tthis.scene.addElement(this.pre_building, 1, this.render_level + 1);\n\t\t\t//this.show_all_ranges = true;\n\t\t},\n\n\t\t/**\n\t\t * 退出预建设状态\n\t\t */\n\t\tcancelPreBuild: function () {\n\t\t\tTD.mode = \"normal\";\n\t\t\tif (this.pre_building) {\n\t\t\t\tthis.pre_building.remove();\n\t\t\t}\n\t\t\t//this.show_all_ranges = false;\n\t\t},\n\n\t\t/**\n\t\t * 清除地图上无效的元素\n\t\t */\n\t\tclearInvalidElements: function () {\n\t\t\tif (this._wait_clearInvalidElements > 0) {\n\t\t\t\tthis._wait_clearInvalidElements--;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._wait_clearInvalidElements = _default_wait_clearInvalidElements;\n\n\t\t\tvar a = [];\n\t\t\tTD.lang.shift(this.buildings, function (obj) {\n\t\t\t\tif (obj.is_valid)\n\t\t\t\t\ta.push(obj);\n\t\t\t});\n\t\t\tthis.buildings = a;\n\n\t\t\ta = [];\n\t\t\tTD.lang.shift(this.monsters, function (obj) {\n\t\t\t\tif (obj.is_valid)\n\t\t\t\t\ta.push(obj);\n\t\t\t});\n\t\t\tthis.monsters = a;\n\n\t\t\ta = [];\n\t\t\tTD.lang.shift(this.bullets, function (obj) {\n\t\t\t\tif (obj.is_valid)\n\t\t\t\t\ta.push(obj);\n\t\t\t});\n\t\t\tthis.bullets = a;\n\t\t},\n\n\t\t/**\n\t\t * 在地图的入口处添加一个怪物\n\t\t * @param monster 可以是数字,也可以是 monster 对象\n\t\t */\n\t\taddMonster: function (monster) {\n\t\t\tif (!this.entrance) return;\n\t\t\tif (typeof monster == \"number\") {\n\t\t\t\tmonster = new TD.Monster(null, {\n\t\t\t\t\tidx: monster,\n\t\t\t\t\tdifficulty: TD.difficulty,\n\t\t\t\t\tstep_level: this.step_level,\n\t\t\t\t\trender_level: this.render_level + 2\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.entrance.addMonster(monster);\n\t\t},\n\n\t\t/**\n\t\t * 在地图的入口处添加 n 个怪物\n\t\t * @param n\n\t\t * @param monster\n\t\t */\n\t\taddMonsters: function (n, monster) {\n\t\t\tthis._wait_add_monsters = n;\n\t\t\tthis._wait_add_monsters_objidx = monster;\n\t\t},\n\n\t\t/**\n\t\t * arr 的格式形如:\n\t\t * [[1, 0], [2, 5], [3, 6], [10, 4]...]\n\t\t */\n\t\taddMonsters2: function (arr) {\n\t\t\tthis._wait_add_monsters_arr = arr;\n\t\t},\n\n\t\t/**\n\t\t * 检查地图的指定格子是否可通过\n\t\t * @param mx {Number}\n\t\t * @param my {Number}\n\t\t */\n\t\tcheckPassable: function (mx, my) {\n\t\t\tvar grid = this.getGrid(mx, my);\n\t\t\treturn (grid != null && grid.passable_flag == 1 && grid.build_flag != 2);\n\t\t},\n\n\t\tstep: function () {\n\t\t\tthis.clearInvalidElements();\n\n\t\t\tif (this._wait_add_monsters > 0) {\n\t\t\t\tthis.addMonster(this._wait_add_monsters_objidx);\n\t\t\t\tthis._wait_add_monsters--;\n\t\t\t} else if (this._wait_add_monsters_arr.length > 0) {\n\t\t\t\tvar a = this._wait_add_monsters_arr.shift();\n\t\t\t\tthis.addMonsters(a[0], a[1]);\n\t\t\t}\n\t\t},\n\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\t\t\tctx.strokeStyle = \"#99a\";\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.beginPath();\n\t\t\tctx.strokeRect(this.x + 0.5, this.y + 0.5, this.width, this.height);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t},\n\n\t\t/**\n\t\t * 鼠标移出地图事件\n\t\t */\n\t\tonOut: function () {\n\t\t\tif (this.is_main_map && this.pre_building)\n\t\t\t\tthis.pre_building.hide();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String} 配置对象\n\t * @param cfg {Object} 配置对象\n\t * 至少需要包含以下项:\n\t * {\n\t *\t\t\t grid_x: 宽度(格子),\n\t *\t\t\t grid_y: 高度(格子),\n\t *\t\t\t scene: 属于哪个场景,\n\t *\t\t }\n\t */\n\tTD.Map = function (id, cfg) {\n\t\t// map 目前只需要监听 out 事件\n\t\t// 虽然只需要监听 out 事件,但同时也需要监听 enter ,因为如果\n\t\t// 没有 enter ,out 将永远不会被触发\n\t\tcfg.on_events = [\"enter\", \"out\"];\n\t\tvar map = new TD.Element(id, cfg);\n\t\tTD.lang.mix(map, map_obj);\n\t\tmap._init(cfg);\n\n\t\treturn map;\n\t};\n\n\n\t/**\n\t * 地图选中元素高亮边框对象\n\t */\n\tvar map_selecthl_obj = {\n\t\t_init: function (cfg) {\n\t\t\tthis.map = cfg.map;\n\t\t\tthis.width = TD.grid_size + 2;\n\t\t\tthis.height = TD.grid_size + 2;\n\t\t\tthis.is_visiable = false;\n\t\t},\n\t\tshow: function (grid) {\n\t\t\tthis.x = grid.x;\n\t\t\tthis.y = grid.y;\n\t\t\tthis.is_visiable = true;\n\t\t},\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\t\t\tctx.lineWidth = 2;\n\t\t\tctx.strokeStyle = \"#f93\";\n\t\t\tctx.beginPath();\n\t\t\tctx.strokeRect(this.x, this.y, this.width - 1, this.height - 1);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t}\n\t};\n\n\t/**\n\t * 地图选中的高亮框\n\t * @param id {String} 至少需要包含\n\t * @param cfg {Object} 至少需要包含\n\t * {\n\t * map: map 对象\n\t * }\n\t */\n\tTD.MapSelectHighLight = function (id, cfg) {\n\t\tvar map_selecthl = new TD.Element(id, cfg);\n\t\tTD.lang.mix(map_selecthl, map_selecthl_obj);\n\t\tmap_selecthl._init(cfg);\n\n\t\treturn map_selecthl;\n\t};\n\n\n\tvar mmm_obj = {\n\t\t_init: function (cfg) {\n\t\t\tthis.map = cfg.map;\n\n\t\t\tthis.x1 = this.map.x;\n\t\t\tthis.y1 = this.map.y;\n\t\t\tthis.x2 = this.map.x2 + 1;\n\t\t\tthis.y2 = this.map.y2 + 1;\n\t\t\tthis.w = this.map.scene.stage.width;\n\t\t\tthis.h = this.map.scene.stage.height;\n\t\t\tthis.w2 = this.w - this.x2;\n\t\t\tthis.h2 = this.h - this.y2;\n\t\t},\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\t\t\t/*ctx.clearRect(0, 0, this.x1, this.h);\n\t\t\t ctx.clearRect(0, 0, this.w, this.y1);\n\t\t\t ctx.clearRect(0, this.y2, this.w, this.h2);\n\t\t\t ctx.clearRect(this.x2, 0, this.w2, this.h2);*/\n\n\t\t\tctx.fillStyle = \"#fff\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(0, 0, this.x1, this.h);\n\t\t\tctx.fillRect(0, 0, this.w, this.y1);\n\t\t\tctx.fillRect(0, this.y2, this.w, this.h2);\n\t\t\tctx.fillRect(this.x2, 0, this.w2, this.h);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t}\n\t};\n\n\t/**\n\t * 主地图外边的遮罩,用于遮住超出地图的射程等\n\t */\n\tfunction MainMapMask(id, cfg) {\n\t\tvar mmm = new TD.Element(id, cfg);\n\t\tTD.lang.mix(mmm, mmm_obj);\n\t\tmmm._init(cfg);\n\n\t\treturn mmm;\n\t}\n\n}); // _TD.a.push end\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t// grid 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar grid_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.map = cfg.map;\n\t\t\tthis.scene = this.map.scene;\n\t\t\tthis.mx = cfg.mx; // 在 map 中的格子坐标\n\t\t\tthis.my = cfg.my;\n\t\t\tthis.width = TD.grid_size;\n\t\t\tthis.height = TD.grid_size;\n\t\t\tthis.is_entrance = this.is_exit = false;\n\t\t\tthis.passable_flag = 1; // 0: 不可通过; 1: 可通过\n\t\t\tthis.build_flag = 1;// 0: 不可修建; 1: 可修建; 2: 已修建\n\t\t\tthis.building = null;\n\t\t\tthis.caculatePos();\n\t\t},\n\n\t\t/**\n\t\t * 根据 map 位置及本 grid 的 (mx, my) ,计算格子的位置\n\t\t */\n\t\tcaculatePos: function () {\n\t\t\tthis.x = this.map.x + this.mx * TD.grid_size;\n\t\t\tthis.y = this.map.y + this.my * TD.grid_size;\n\t\t\tthis.x2 = this.x + TD.grid_size;\n\t\t\tthis.y2 = this.y + TD.grid_size;\n\t\t\tthis.cx = Math.floor(this.x + TD.grid_size / 2);\n\t\t\tthis.cy = Math.floor(this.y + TD.grid_size / 2);\n\t\t},\n\n\t\t/**\n\t\t * 检查如果在当前格子建东西,是否会导致起点与终点被阻塞\n\t\t */\n\t\tcheckBlock: function () {\n\t\t\tif (this.is_entrance || this.is_exit) {\n\t\t\t\tthis._block_msg = TD._t(\"entrance_or_exit_be_blocked\");\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar is_blocked,\n\t\t\t\t_this = this,\n\t\t\t\tfw = new TD.FindWay(\n\t\t\t\t\tthis.map.grid_x, this.map.grid_y,\n\t\t\t\t\tthis.map.entrance.mx, this.map.entrance.my,\n\t\t\t\t\tthis.map.exit.mx, this.map.exit.my,\n\t\t\t\t\tfunction (x, y) {\n\t\t\t\t\t\treturn !(x == _this.mx && y == _this.my) && _this.map.checkPassable(x, y);\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\tis_blocked = fw.is_blocked;\n\n\t\t\tif (!is_blocked) {\n\t\t\t\tis_blocked = !!this.map.anyMonster(function (obj) {\n\t\t\t\t\treturn obj.chkIfBlocked(_this.mx, _this.my);\n\t\t\t\t});\n\t\t\t\tif (is_blocked)\n\t\t\t\t\tthis._block_msg = TD._t(\"monster_be_blocked\");\n\t\t\t} else {\n\t\t\t\tthis._block_msg = TD._t(\"blocked\");\n\t\t\t}\n\n\t\t\treturn is_blocked;\n\t\t},\n\n\t\t/**\n\t\t * 购买建筑\n\t\t * @param building_type {String}\n\t\t */\n\t\tbuyBuilding: function (building_type) {\n\t\t\tvar cost = TD.getDefaultBuildingAttributes(building_type).cost || 0;\n\t\t\tif (TD.money >= cost) {\n\t\t\t\tTD.money -= cost;\n\t\t\t\tthis.addBuilding(building_type);\n\t\t\t} else {\n\t\t\t\tTD.log(TD._t(\"not_enough_money\", [cost]));\n\t\t\t\tthis.scene.panel.balloontip.msg(TD._t(\"not_enough_money\", [cost]), this);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 在当前格子添加指定类型的建筑\n\t\t * @param building_type {String}\n\t\t */\n\t\taddBuilding: function (building_type) {\n\t\t\tif (this.building) {\n\t\t\t\t// 如果当前格子已经有建筑,先将其移除\n\t\t\t\tthis.removeBuilding();\n\t\t\t}\n\n\t\t\tvar building = new TD.Building(\"building-\" + building_type + \"-\" + TD.lang.rndStr(), {\n\t\t\t\ttype: building_type,\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level\n\t\t\t});\n\t\t\tbuilding.locate(this);\n\n\t\t\tthis.scene.addElement(building, this.step_level, this.render_level + 1);\n\t\t\tthis.map.buildings.push(building);\n\t\t\tthis.building = building;\n\t\t\tthis.build_flag = 2;\n\t\t\tthis.map.checkHasWeapon();\n\t\t\tif (this.map.pre_building)\n\t\t\t\tthis.map.pre_building.hide();\n\t\t},\n\n\t\t/**\n\t\t * 移除当前格子的建筑\n\t\t */\n\t\tremoveBuilding: function () {\n\t\t\tif (this.build_flag == 2)\n\t\t\t\tthis.build_flag = 1;\n\t\t\tif (this.building)\n\t\t\t\tthis.building.remove();\n\t\t\tthis.building = null;\n\t\t},\n\n\t\t/**\n\t\t * 在当前建筑添加一个怪物\n\t\t * @param monster\n\t\t */\n\t\taddMonster: function (monster) {\n\t\t\tmonster.beAddToGrid(this);\n\t\t\tthis.map.monsters.push(monster);\n\t\t\tmonster.start();\n\t\t},\n\n\t\t/**\n\t\t * 高亮当前格子\n\t\t * @param show {Boolean}\n\t\t */\n\t\thightLight: function (show) {\n\t\t\tthis.map.select_hl[show ? \"show\" : \"hide\"](this);\n\t\t},\n\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx,\n\t\t\t\tpx = this.x + 0.5,\n\t\t\t\tpy = this.y + 0.5;\n\n\t\t\t//if (this.map.is_main_map) {\n\t\t\t//ctx.drawImage(this.map.res,\n\t\t\t//0, 0, 32, 32, this.x, this.y, 32, 32\n\t\t\t//);\n\t\t\t//}\n\n\t\t\tif (this.is_hover) {\n\t\t\t\tctx.fillStyle = \"rgba(255, 255, 200, 0.2)\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.fillRect(px, py, this.width, this.height);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.fill();\n\t\t\t}\n\n\t\t\tif (this.passable_flag == 0) {\n\t\t\t\t// 不可通过\n\t\t\t\tctx.fillStyle = \"#fcc\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.fillRect(px, py, this.width, this.height);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.fill();\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * 画入口及出口\n\t\t\t */\n\t\t\tif (this.is_entrance || this.is_exit) {\n\t\t\t\tctx.lineWidth = 1;\n\t\t\t\tctx.fillStyle = \"#ccc\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.fillRect(px, py, this.width, this.height);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.fill();\n\n\t\t\t\tctx.strokeStyle = \"#666\";\n\t\t\t\tctx.fillStyle = this.is_entrance ? \"#fff\" : \"#666\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.arc(this.cx, this.cy, TD.grid_size * 0.325, 0, Math.PI * 2, true);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\t\t\tctx.strokeStyle = \"#eee\";\n\t\t\tctx.lineWidth = 1;\n\t\t\tctx.beginPath();\n\t\t\tctx.strokeRect(px, py, this.width, this.height);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t},\n\n\t\t/**\n\t\t * 鼠标进入当前格子事件\n\t\t */\n\t\tonEnter: function () {\n\t\t\tif (this.map.is_main_map && TD.mode == \"build\") {\n\t\t\t\tif (this.build_flag == 1) {\n\t\t\t\t\tthis.map.pre_building.show();\n\t\t\t\t\tthis.map.pre_building.locate(this);\n\t\t\t\t} else {\n\t\t\t\t\tthis.map.pre_building.hide();\n\t\t\t\t}\n\t\t\t} else if (this.map.is_main_map) {\n\t\t\t\tvar msg = \"\";\n\t\t\t\tif (this.is_entrance) {\n\t\t\t\t\tmsg = TD._t(\"entrance\");\n\t\t\t\t} else if (this.is_exit) {\n\t\t\t\t\tmsg = TD._t(\"exit\");\n\t\t\t\t} else if (this.passable_flag == 0) {\n\t\t\t\t\tmsg = TD._t(\"_cant_pass\");\n\t\t\t\t} else if (this.build_flag == 0) {\n\t\t\t\t\tmsg = TD._t(\"_cant_build\");\n\t\t\t\t}\n\n\t\t\t\tif (msg) {\n\t\t\t\t\tthis.scene.panel.balloontip.msg(msg, this);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 鼠标移出当前格子事件\n\t\t */\n\t\tonOut: function () {\n\t\t\t// 如果当前气球提示指向本格子,将其隐藏\n\t\t\tif (this.scene.panel.balloontip.el == this) {\n\t\t\t\tthis.scene.panel.balloontip.hide();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 鼠标点击了当前格子事件\n\t\t */\n\t\tonClick: function () {\n\t\t\tif (this.scene.state != 1) return;\n\n\t\t\tif (TD.mode == \"build\" && this.map.is_main_map && !this.building) {\n\t\t\t\t// 如果处于建设模式下,并且点击在主地图的空格子上,则尝试建设指定建筑\n\t\t\t\tif (this.checkBlock()) {\n\t\t\t\t\t// 起点与终点之间被阻塞,不能修建\n\t\t\t\t\tthis.scene.panel.balloontip.msg(this._block_msg, this);\n\t\t\t\t} else {\n\t\t\t\t\t// 购买建筑\n\t\t\t\t\tthis.buyBuilding(this.map.pre_building.type);\n\t\t\t\t}\n\t\t\t} else if (!this.building && this.map.selected_building) {\n\t\t\t\t// 取消选中建筑\n\t\t\t\tthis.map.selected_building.toggleSelected();\n\t\t\t\tthis.map.selected_building = null;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {object} 配置对象\n\t * 至少需要包含以下项:\n\t * {\n\t *\t\t\t mx: 在 map 格子中的横向坐标,\n\t *\t\t\t my: 在 map 格子中的纵向坐标,\n\t *\t\t\t map: 属于哪个 map,\n\t *\t\t }\n\t */\n\tTD.Grid = function (id, cfg) {\n\t\tcfg.on_events = [\"enter\", \"out\", \"click\"];\n\n\t\tvar grid = new TD.Element(id, cfg);\n\t\tTD.lang.mix(grid, grid_obj);\n\t\tgrid._init(cfg);\n\n\t\treturn grid;\n\t};\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t// building 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar building_obj = {\n\t\t_init: function (cfg) {\n\t\t\tthis.is_selected = false;\n\t\t\tthis.level = 0;\n\t\t\tthis.killed = 0; // 当前建筑杀死了多少怪物\n\t\t\tthis.target = null;\n\n\t\t\tcfg = cfg || {};\n\t\t\tthis.map = cfg.map || null;\n\t\t\tthis.grid = cfg.grid || null;\n\n\t\t\t/**\n\t\t\t * 子弹类型,可以有以下类型:\n\t\t\t * 1:普通子弹\n\t\t\t * 2:激光类,发射后马上命中,暂未实现\n\t\t\t * 3:导弹类,击中后会爆炸,带来面攻击,暂未实现\n\t\t\t */\n\t\t\tthis.bullet_type = cfg.bullet_type || 1;\n\n\t\t\t/**\n\t\t\t * type 可能的值有:\n\t\t\t * \"wall\": 墙壁,没有攻击性\n\t\t\t * \"cannon\": 炮台\n\t\t\t * \"LMG\": 轻机枪\n\t\t\t * \"HMG\": 重机枪\n\t\t\t * \"laser_gun\": 激光枪\n\t\t\t *\n\t\t\t */\n\t\t\tthis.type = cfg.type;\n\n\t\t\tthis.speed = cfg.speed;\n\t\t\tthis.bullet_speed = cfg.bullet_speed;\n\t\t\tthis.is_pre_building = !!cfg.is_pre_building;\n\t\t\tthis.blink = this.is_pre_building;\n\t\t\tthis.wait_blink = this._default_wait_blink = 20;\n\t\t\tthis.is_weapon = (this.type != \"wall\"); // 墙等不可攻击的建筑此项为 false ,其余武器此项为 true\n\n\t\t\tvar o = TD.getDefaultBuildingAttributes(this.type);\n\t\t\tTD.lang.mix(this, o);\n\t\t\tthis.range_px = this.range * TD.grid_size;\n\t\t\tthis.money = this.cost; // 购买、升级本建筑已花费的钱\n\n\t\t\tthis.caculatePos();\n\t\t},\n\n\t\t/**\n\t\t * 升级本建筑需要的花费\n\t\t */\n\t\tgetUpgradeCost: function () {\n\t\t\treturn Math.floor(this.money * 0.75);\n\t\t},\n\n\t\t/**\n\t\t * 出售本建筑能得到多少钱\n\t\t */\n\t\tgetSellMoney: function () {\n\t\t\treturn Math.floor(this.money * 0.5) || 1;\n\t\t},\n\n\t\t/**\n\t\t * 切换选中 / 未选中状态\n\t\t */\n\t\ttoggleSelected: function () {\n\t\t\tthis.is_selected = !this.is_selected;\n\t\t\tthis.grid.hightLight(this.is_selected); // 高亮\n\t\t\tvar _this = this;\n\n\t\t\tif (this.is_selected) {\n\t\t\t\t// 如果当前建筑被选中\n\n\t\t\t\tthis.map.eachBuilding(function (obj) {\n\t\t\t\t\tobj.is_selected = obj == _this;\n\t\t\t\t});\n\t\t\t\t// 取消另一个地图中选中建筑的选中状态\n\t\t\t\t(\n\t\t\t\t\tthis.map.is_main_map ? this.scene.panel_map : this.scene.map\n\t\t\t\t).eachBuilding(function (obj) {\n\t\t\t\t\t\tobj.is_selected = false;\n\t\t\t\t\t\tobj.grid.hightLight(false);\n\t\t\t\t\t});\n\t\t\t\tthis.map.selected_building = this;\n\n\t\t\t\tif (!this.map.is_main_map) {\n\t\t\t\t\t// 在面版地图中选中了建筑,进入建筑模式\n\t\t\t\t\tthis.scene.map.preBuild(this.type);\n\t\t\t\t} else {\n\t\t\t\t\t// 取消建筑模式\n\t\t\t\t\tthis.scene.map.cancelPreBuild();\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// 如果当前建筑切换为未选中状态\n\n\t\t\t\tif (this.map.selected_building == this)\n\t\t\t\t\tthis.map.selected_building = null;\n\n\t\t\t\tif (!this.map.is_main_map) {\n\t\t\t\t\t// 取消建筑模式\n\t\t\t\t\tthis.scene.map.cancelPreBuild();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 如果是选中 / 取消选中主地图上的建筑,显示 / 隐藏对应的操作按钮\n\t\t\tif (this.map.is_main_map) {\n\t\t\t\tif (this.map.selected_building) {\n\t\t\t\t\tthis.scene.panel.btn_upgrade.show();\n\t\t\t\t\tthis.scene.panel.btn_sell.show();\n\t\t\t\t\tthis.updateBtnDesc();\n\t\t\t\t} else {\n\t\t\t\t\tthis.scene.panel.btn_upgrade.hide();\n\t\t\t\t\tthis.scene.panel.btn_sell.hide();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 生成、更新升级按钮的说明文字\n\t\t */\n\t\tupdateBtnDesc: function () {\n\t\t\tthis.scene.panel.btn_upgrade.desc = TD._t(\n\t\t\t\t\"upgrade\", [\n\t\t\t\t\tTD._t(\"building_name_\" + this.type),\n\t\t\t\t\tthis.level + 1,\n\t\t\t\t\tthis.getUpgradeCost()\n\t\t\t\t]);\n\t\t\tthis.scene.panel.btn_sell.desc = TD._t(\n\t\t\t\t\"sell\", [\n\t\t\t\t\tTD._t(\"building_name_\" + this.type),\n\t\t\t\t\tthis.getSellMoney()\n\t\t\t\t]);\n\t\t},\n\n\t\t/**\n\t\t * 将本建筑放置到一个格子中\n\t\t * @param grid {Element} 指定格子\n\t\t */\n\t\tlocate: function (grid) {\n\t\t\tthis.grid = grid;\n\t\t\tthis.map = grid.map;\n\t\t\tthis.cx = this.grid.cx;\n\t\t\tthis.cy = this.grid.cy;\n\t\t\tthis.x = this.grid.x;\n\t\t\tthis.y = this.grid.y;\n\t\t\tthis.x2 = this.grid.x2;\n\t\t\tthis.y2 = this.grid.y2;\n\t\t\tthis.width = this.grid.width;\n\t\t\tthis.height = this.grid.height;\n\n\t\t\tthis.px = this.x + 0.5;\n\t\t\tthis.py = this.y + 0.5;\n\n\t\t\tthis.wait_blink = this._default_wait_blink;\n\t\t\tthis._fire_wait = Math.floor(Math.max(2 / (this.speed * TD.global_speed), 1));\n\t\t\tthis._fire_wait2 = this._fire_wait;\n\n\t\t},\n\n\t\t/**\n\t\t * 将本建筑彻底删除\n\t\t */\n\t\tremove: function () {\n//\t\t\tTD.log(\"remove building #\" + this.id + \".\");\n\t\t\tif (this.grid && this.grid.building && this.grid.building == this)\n\t\t\t\tthis.grid.building = null;\n\t\t\tthis.hide();\n\t\t\tthis.del();\n\t\t},\n\n\t\t/**\n\t\t * 寻找一个目标(怪物)\n\t\t */\n\t\tfindTaget: function () {\n\t\t\tif (!this.is_weapon || this.is_pre_building || !this.grid) return;\n\n\t\t\tvar cx = this.cx, cy = this.cy,\n\t\t\t\trange2 = Math.pow(this.range_px, 2);\n\n\t\t\t// 如果当前建筑有目标,并且目标还是有效的,并且目标仍在射程内\n\t\t\tif (this.target && this.target.is_valid &&\n\t\t\t\tMath.pow(this.target.cx - cx, 2) + Math.pow(this.target.cy - cy, 2) <= range2)\n\t\t\t\treturn;\n\n\t\t\t// 在进入射程的怪物中寻找新的目标\n\t\t\tthis.target = TD.lang.any(\n\t\t\t\tTD.lang.rndSort(this.map.monsters), // 将怪物随机排序\n\t\t\t\tfunction (obj) {\n\t\t\t\t\treturn Math.pow(obj.cx - cx, 2) + Math.pow(obj.cy - cy, 2) <= range2;\n\t\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * 取得目标的坐标(相对于地图左上角)\n\t\t */\n\t\tgetTargetPosition: function () {\n\t\t\tif (!this.target) {\n\t\t\t\t// 以 entrance 为目标\n\t\t\t\tvar grid = this.map.is_main_map ? this.map.entrance : this.grid;\n\t\t\t\treturn [grid.cx, grid.cy];\n\t\t\t}\n\t\t\treturn [this.target.cx, this.target.cy];\n\t\t},\n\n\t\t/**\n\t\t * 向自己的目标开火\n\t\t */\n\t\tfire: function () {\n\t\t\tif (!this.target || !this.target.is_valid) return;\n\n\t\t\tif (this.type == \"laser_gun\") {\n\t\t\t\t// 如果是激光枪,目标立刻被击中\n\t\t\t\tthis.target.beHit(this, this.damage);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar muzzle = this.muzzle || [this.cx, this.cy], // 炮口的位置\n\t\t\t\tcx = muzzle[0],\n\t\t\t\tcy = muzzle[1];\n\n\t\t\tnew TD.Bullet(null, {\n\t\t\t\tbuilding: this,\n\t\t\t\tdamage: this.damage,\n\t\t\t\ttarget: this.target,\n\t\t\t\tspeed: this.bullet_speed,\n\t\t\t\tx: cx,\n\t\t\t\ty: cy\n\t\t\t});\n\t\t},\n\n\t\ttryToFire: function () {\n\t\t\tif (!this.is_weapon || !this.target)\n\t\t\t\treturn;\n\n\t\t\tthis._fire_wait--;\n\t\t\tif (this._fire_wait > 0) {\n//\t\t\treturn;\n\t\t\t} else if (this._fire_wait < 0) {\n\t\t\t\tthis._fire_wait = this._fire_wait2;\n\t\t\t} else {\n\t\t\t\tthis.fire();\n\t\t\t}\n\t\t},\n\n\t\t_upgrade2: function (k) {\n\t\t\tif (!this._upgrade_records[k])\n\t\t\t\tthis._upgrade_records[k] = this[k];\n\t\t\tvar v = this._upgrade_records[k],\n\t\t\t\tmk = \"max_\" + k,\n\t\t\t\tuk = \"_upgrade_rule_\" + k,\n\t\t\t\tuf = this[uk] || TD.default_upgrade_rule;\n\t\t\tif (!v || isNaN(v)) return;\n\n\t\t\tv = uf(this.level, v);\n\t\t\tif (this[mk] && !isNaN(this[mk]) && this[mk] < v)\n\t\t\t\tv = this[mk];\n\t\t\tthis._upgrade_records[k] = v;\n\t\t\tthis[k] = Math.floor(v);\n\t\t},\n\n\t\t/**\n\t\t * 升级建筑\n\t\t */\n\t\tupgrade: function () {\n\t\t\tif (!this._upgrade_records)\n\t\t\t\tthis._upgrade_records = {};\n\n\t\t\tvar attrs = [\n\t\t\t\t// 可升级的变量\n\t\t\t\t\"damage\", \"range\", \"speed\", \"life\", \"shield\"\n\t\t\t], i, l = attrs.length;\n\t\t\tfor (i = 0; i < l; i++)\n\t\t\t\tthis._upgrade2(attrs[i]);\n\t\t\tthis.level++;\n\t\t\tthis.range_px = this.range * TD.grid_size;\n\t\t},\n\n\t\ttryToUpgrade: function (btn) {\n\t\t\tvar cost = this.getUpgradeCost(),\n\t\t\t\tmsg = \"\";\n\t\t\tif (cost > TD.money) {\n\t\t\t\tmsg = TD._t(\"not_enough_money\", [cost]);\n\t\t\t} else {\n\t\t\t\tTD.money -= cost;\n\t\t\t\tthis.money += cost;\n\t\t\t\tthis.upgrade();\n\t\t\t\tmsg = TD._t(\"upgrade_success\", [\n\t\t\t\t\tTD._t(\"building_name_\" + this.type), this.level,\n\t\t\t\t\tthis.getUpgradeCost()\n\t\t\t\t]);\n\t\t\t}\n\n\t\t\tthis.updateBtnDesc();\n\t\t\tthis.scene.panel.balloontip.msg(msg, btn);\n\t\t},\n\n\t\ttryToSell: function () {\n\t\t\tif (!this.is_valid) return;\n\n\t\t\tTD.money += this.getSellMoney();\n\t\t\tthis.grid.removeBuilding();\n\t\t\tthis.is_valid = false;\n\t\t\tthis.map.selected_building = null;\n\t\t\tthis.map.select_hl.hide();\n\t\t\tthis.map.checkHasWeapon();\n\t\t\tthis.scene.panel.btn_upgrade.hide();\n\t\t\tthis.scene.panel.btn_sell.hide();\n\t\t\tthis.scene.panel.balloontip.hide();\n\t\t},\n\n\t\tstep: function () {\n\t\t\tif (this.blink) {\n\t\t\t\tthis.wait_blink--;\n\t\t\t\tif (this.wait_blink < -this._default_wait_blink)\n\t\t\t\t\tthis.wait_blink = this._default_wait_blink;\n\t\t\t}\n\n\t\t\tthis.findTaget();\n\t\t\tthis.tryToFire();\n\t\t},\n\n\t\trender: function () {\n\t\t\tif (!this.is_visiable || this.wait_blink < 0) return;\n\n\t\t\tvar ctx = TD.ctx;\n\n\t\t\tTD.renderBuilding(this);\n\n\t\t\tif (\n\t\t\t\tthis.map.is_main_map &&\n\t\t\t\t(\n\t\t\t\t\tthis.is_selected || (this.is_pre_building) ||\n\t\t\t\t\tthis.map.show_all_ranges\n\t\t\t\t) &&\n\t\t\t\tthis.is_weapon && this.range > 0 && this.grid\n\t\t\t) {\n\t\t\t\t// 画射程\n\t\t\t\tctx.lineWidth = _TD.retina;\n\t\t\t\tctx.fillStyle = \"rgba(187, 141, 32, 0.15)\";\n\t\t\t\tctx.strokeStyle = \"#bb8d20\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.arc(this.cx, this.cy, this.range_px, 0, Math.PI * 2, true);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\t\t\tif (this.type == \"laser_gun\" && this.target && this.target.is_valid) {\n\t\t\t\t// 画激光\n\t\t\t\tctx.lineWidth = 3 * _TD.retina;\n\t\t\t\tctx.strokeStyle = \"rgba(50, 50, 200, 0.5)\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(this.cx, this.cy);\n\t\t\t\tctx.lineTo(this.target.cx, this.target.cy);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\t\t\t\tctx.lineWidth = _TD.retina;\n\t\t\t\tctx.strokeStyle = \"rgba(150, 150, 255, 0.5)\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.lineTo(this.cx, this.cy);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\n\t\tonEnter: function () {\n\t\t\tif (this.is_pre_building) return;\n\n\t\t\tvar msg = \"建筑工事\";\n\t\t\tif (this.map.is_main_map) {\n\t\t\t\tmsg = TD._t(\"building_info\" + (this.type == \"wall\" ? \"_wall\" : \"\"), [TD._t(\"building_name_\" + this.type), this.level, this.damage, this.speed, this.range, this.killed]);\n\t\t\t} else {\n\t\t\t\tmsg = TD._t(\"building_intro_\" + this.type, [TD.getDefaultBuildingAttributes(this.type).cost]);\n\t\t\t}\n\n\t\t\tthis.scene.panel.balloontip.msg(msg, this.grid);\n\t\t},\n\n\t\tonOut: function () {\n\t\t\tif (this.scene.panel.balloontip.el == this.grid) {\n\t\t\t\tthis.scene.panel.balloontip.hide();\n\t\t\t}\n\t\t},\n\n\t\tonClick: function () {\n\t\t\tif (this.is_pre_building || this.scene.state != 1) return;\n\t\t\tthis.toggleSelected();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {object} 配置对象\n\t * 至少需要包含以下项:\n\t * {\n\t *\t\t\t type: 建筑类型,可选的值有\n\t *\t\t\t\t \"wall\"\n\t *\t\t\t\t \"cannon\"\n\t *\t\t\t\t \"LMG\"\n\t *\t\t\t\t \"HMG\"\n\t *\t\t\t\t \"laser_gun\"\n\t *\t\t }\n\t */\n\tTD.Building = function (id, cfg) {\n\t\tcfg.on_events = [\"enter\", \"out\", \"click\"];\n\t\tvar building = new TD.Element(id, cfg);\n\t\tTD.lang.mix(building, building_obj);\n\t\tbuilding._init(cfg);\n\n\t\treturn building;\n\t};\n\n\n\t// bullet 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar bullet_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\n\t\t\tthis.speed = cfg.speed;\n\t\t\tthis.damage = cfg.damage;\n\t\t\tthis.target = cfg.target;\n\t\t\tthis.cx = cfg.x;\n\t\t\tthis.cy = cfg.y;\n\t\t\tthis.r = cfg.r || Math.max(Math.log(this.damage), 2);\n\t\t\tif (this.r < 1) this.r = 1;\n\t\t\tif (this.r > 6) this.r = 6;\n\n\t\t\tthis.building = cfg.building || null;\n\t\t\tthis.map = cfg.map || this.building.map;\n\t\t\tthis.type = cfg.type || 1;\n\t\t\tthis.color = cfg.color || \"#000\";\n\n\t\t\tthis.map.bullets.push(this);\n\t\t\tthis.addToScene(this.map.scene, 1, 6);\n\n\t\t\tif (this.type == 1) {\n\t\t\t\tthis.caculate();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 计算子弹的一些数值\n\t\t */\n\t\tcaculate: function () {\n\t\t\tvar sx, sy, c,\n\t\t\t\ttx = this.target.cx,\n\t\t\t\tty = this.target.cy,\n\t\t\t\tspeed;\n\t\t\tsx = tx - this.cx;\n\t\t\tsy = ty - this.cy;\n\t\t\tc = Math.sqrt(Math.pow(sx, 2) + Math.pow(sy, 2));\n\t\t\tspeed = 20 * this.speed * TD.global_speed;\n\t\t\tthis.vx = sx * speed / c;\n\t\t\tthis.vy = sy * speed / c;\n\t\t},\n\n\t\t/**\n\t\t * 检查当前子弹是否已超出地图范围\n\t\t */\n\t\tcheckOutOfMap: function () {\n\t\t\tthis.is_valid = !(\n\t\t\t\tthis.cx < this.map.x ||\n\t\t\t\tthis.cx > this.map.x2 ||\n\t\t\t\tthis.cy < this.map.y ||\n\t\t\t\tthis.cy > this.map.y2\n\t\t\t);\n\n\t\t\treturn !this.is_valid;\n\t\t},\n\n\t\t/**\n\t\t * 检查当前子弹是否击中了怪物\n\t\t */\n\t\tcheckHit: function () {\n\t\t\tvar cx = this.cx,\n\t\t\t\tcy = this.cy,\n\t\t\t\tr = this.r * _TD.retina,\n\t\t\t\tmonster = this.map.anyMonster(function (obj) {\n\t\t\t\t\treturn Math.pow(obj.cx - cx, 2) + Math.pow(obj.cy - cy, 2) <= Math.pow(obj.r + r, 2) * 2;\n\t\t\t\t});\n\n\t\t\tif (monster) {\n\t\t\t\t// 击中的怪物\n\t\t\t\tmonster.beHit(this.building, this.damage);\n\t\t\t\tthis.is_valid = false;\n\n\t\t\t\t// 子弹小爆炸效果\n\t\t\t\tTD.Explode(this.id + \"-explode\", {\n\t\t\t\t\tcx: this.cx,\n\t\t\t\t\tcy: this.cy,\n\t\t\t\t\tr: this.r,\n\t\t\t\t\tstep_level: this.step_level,\n\t\t\t\t\trender_level: this.render_level,\n\t\t\t\t\tcolor: this.color,\n\t\t\t\t\tscene: this.map.scene,\n\t\t\t\t\ttime: 0.2\n\t\t\t\t});\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\tstep: function () {\n\t\t\tif (this.checkOutOfMap() || this.checkHit()) return;\n\n\t\t\tthis.cx += this.vx;\n\t\t\tthis.cy += this.vy;\n\t\t},\n\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\t\t\tctx.fillStyle = this.color;\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(this.cx, this.cy, this.r, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String} 配置对象\n\t * @param cfg {Object} 配置对象\n\t * 至少需要包含以下项:\n\t * {\n\t *\t\t\t x: 子弹发出的位置\n\t *\t\t\t y: 子弹发出的位置\n\t *\t\t\t speed:\n\t *\t\t\t damage:\n\t *\t\t\t target: 目标,一个 monster 对象\n\t *\t\t\t building: 所属的建筑\n\t *\t\t }\n\t * 子弹类型,可以有以下类型:\n\t * 1:普通子弹\n\t * 2:激光类,发射后马上命中\n\t * 3:导弹类,击中后会爆炸,带来面攻击\n\t */\n\tTD.Bullet = function (id, cfg) {\n\t\tvar bullet = new TD.Element(id, cfg);\n\t\tTD.lang.mix(bullet, bullet_obj);\n\t\tbullet._init(cfg);\n\n\t\treturn bullet;\n\t};\n\n}); // _TD.a.push end\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t// monster 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar monster_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.is_monster = true;\n\t\t\tthis.idx = cfg.idx || 1;\n\t\t\tthis.difficulty = cfg.difficulty || 1.0;\n\t\t\tvar attr = TD.getDefaultMonsterAttributes(this.idx);\n\n\t\t\tthis.speed = Math.floor(\n\t\t\t\t(attr.speed + this.difficulty / 2) * (Math.random() * 0.5 + 0.75)\n\t\t\t);\n\t\t\tif (this.speed < 1) this.speed = 1;\n\t\t\tif (this.speed > cfg.max_speed) this.speed = cfg.max_speed;\n\n\t\t\tthis.life = this.life0 = Math.floor(\n\t\t\t\tattr.life * (this.difficulty + 1) * (Math.random() + 0.5) * 0.5\n\t\t\t);\n\t\t\tif (this.life < 1) this.life = this.life0 = 1;\n\n\t\t\tthis.shield = Math.floor(attr.shield + this.difficulty / 2);\n\t\t\tif (this.shield < 0) this.shield = 0;\n\n\t\t\tthis.damage = Math.floor(\n\t\t\t\t(attr.damage || 1) * (Math.random() * 0.5 + 0.75)\n\t\t\t);\n\t\t\tif (this.damage < 1) this.damage = 1;\n\n\t\t\tthis.money = attr.money || Math.floor(\n\t\t\t\t\tMath.sqrt((this.speed + this.life) * (this.shield + 1) * this.damage)\n\t\t\t\t);\n\t\t\tif (this.money < 1) this.money = 1;\n\n\t\t\tthis.color = attr.color || TD.lang.rndRGB();\n\t\t\tthis.r = Math.floor(this.damage * 1.2) * _TD.retina;\n\t\t\tif (this.r < (4 * _TD.retina)) this.r = 4 * _TD.retina;\n\t\t\tif (this.r > TD.grid_size / 2 - (4 * _TD.retina)) this.r = TD.grid_size / 2 - (4 * _TD.retina);\n\t\t\tthis.render = attr.render;\n\n\t\t\tthis.grid = null; // 当前格子\n\t\t\tthis.map = null;\n\t\t\tthis.next_grid = null;\n\t\t\tthis.way = [];\n\t\t\tthis.toward = 2; // 默认面朝下方\n\t\t\tthis._dx = 0;\n\t\t\tthis._dy = 0;\n\n\t\t\tthis.is_blocked = false; // 前进的道路是否被阻塞了\n\t\t},\n\t\tcaculatePos: function () {\n//\t\tif (!this.map) return;\n\t\t\tvar r = this.r;\n\t\t\tthis.x = this.cx - r;\n\t\t\tthis.y = this.cy - r;\n\t\t\tthis.x2 = this.cx + r;\n\t\t\tthis.y2 = this.cy + r;\n\t\t},\n\n\t\t/**\n\t\t * 怪物被击中\n\t\t * @param building {Element} 对应的建筑(武器)\n\t\t * @param damage {Number} 本次攻击的原始伤害值\n\t\t */\n\t\tbeHit: function (building, damage) {\n\t\t\tif (!this.is_valid) return;\n\t\t\tvar min_damage = Math.ceil(damage * 0.1);\n\t\t\tdamage -= this.shield;\n\t\t\tif (damage <= min_damage) damage = min_damage;\n\n\t\t\tthis.life -= damage;\n\t\t\tTD.score += Math.floor(Math.sqrt(damage));\n\t\t\tif (this.life <= 0) {\n\t\t\t\tthis.beKilled(building);\n\t\t\t}\n\n\t\t\tvar balloontip = this.scene.panel.balloontip;\n\t\t\tif (balloontip.el == this) {\n\t\t\t\tballoontip.text = TD._t(\"monster_info\", [this.life, this.shield, this.speed, this.damage]);\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * 怪物被杀死\n\t\t * @param building {Element} 对应的建筑(武器)\n\t\t */\n\t\tbeKilled: function (building) {\n\t\t\tif (!this.is_valid) return;\n\t\t\tthis.life = 0;\n\t\t\tthis.is_valid = false;\n\n\t\t\tTD.money += this.money;\n\t\t\tbuilding.killed++;\n\n\t\t\tTD.Explode(this.id + \"-explode\", {\n\t\t\t\tcx: this.cx,\n\t\t\t\tcy: this.cy,\n\t\t\t\tcolor: this.color,\n\t\t\t\tr: this.r,\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level,\n\t\t\t\tscene: this.grid.scene\n\t\t\t});\n\t\t},\n\t\tarrive: function () {\n\t\t\tthis.grid = this.next_grid;\n\t\t\tthis.next_grid = null;\n\t\t\tthis.checkFinish();\n\t\t},\n\t\tfindWay: function () {\n\t\t\tvar _this = this;\n\t\t\tvar fw = new TD.FindWay(\n\t\t\t\tthis.map.grid_x, this.map.grid_y,\n\t\t\t\tthis.grid.mx, this.grid.my,\n\t\t\t\tthis.map.exit.mx, this.map.exit.my,\n\t\t\t\tfunction (x, y) {\n\t\t\t\t\treturn _this.map.checkPassable(x, y);\n\t\t\t\t}\n\t\t\t);\n\t\t\tthis.way = fw.way;\n\t\t\t//delete fw;\n\t\t},\n\n\t\t/**\n\t\t * 检查是否已到达终点\n\t\t */\n\t\tcheckFinish: function () {\n\t\t\tif (this.grid && this.map && this.grid == this.map.exit) {\n\t\t\t\tTD.life -= this.damage;\n\t\t\t\tTD.wave_damage += this.damage;\n\t\t\t\tif (TD.life <= 0) {\n\t\t\t\t\tTD.life = 0;\n\t\t\t\t\tTD.stage.gameover();\n\t\t\t\t} else {\n\t\t\t\t\tthis.pause();\n\t\t\t\t\tthis.del();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tbeAddToGrid: function (grid) {\n\t\t\tthis.grid = grid;\n\t\t\tthis.map = grid.map;\n\t\t\tthis.cx = grid.cx;\n\t\t\tthis.cy = grid.cy;\n\n\t\t\tthis.grid.scene.addElement(this);\n\t\t},\n\n\t\t/**\n\t\t * 取得朝向\n\t\t * 即下一个格子在当前格子的哪边\n\t\t * 0:上;1:右;2:下;3:左\n\t\t */\n\t\tgetToward: function () {\n\t\t\tif (!this.grid || !this.next_grid) return;\n\t\t\tif (this.grid.my < this.next_grid.my) {\n\t\t\t\tthis.toward = 0;\n\t\t\t} else if (this.grid.mx < this.next_grid.mx) {\n\t\t\t\tthis.toward = 1;\n\t\t\t} else if (this.grid.my > this.next_grid.my) {\n\t\t\t\tthis.toward = 2;\n\t\t\t} else if (this.grid.mx > this.next_grid.mx) {\n\t\t\t\tthis.toward = 3;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 取得要去的下一个格子\n\t\t */\n\t\tgetNextGrid: function () {\n\t\t\tif (this.way.length == 0 ||\n\t\t\t\tMath.random() < 0.1 // 有 1/10 的概率自动重新寻路\n\t\t\t) {\n\t\t\t\tthis.findWay();\n\t\t\t}\n\n\t\t\tvar next_grid = this.way.shift();\n\t\t\tif (next_grid && !this.map.checkPassable(next_grid[0], next_grid[1])) {\n\t\t\t\tthis.findWay();\n\t\t\t\tnext_grid = this.way.shift();\n\t\t\t}\n\n\t\t\tif (!next_grid) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.next_grid = this.map.getGrid(next_grid[0], next_grid[1]);\n//\t\t\tthis.getToward(); // 在这个版本中暂时没有用\n\t\t},\n\n\t\t/**\n\t\t * 检查假如在地图 (x, y) 的位置修建建筑,是否会阻塞当前怪物\n\t\t * @param mx {Number} 地图的 x 坐标\n\t\t * @param my {Number} 地图的 y 坐标\n\t\t * @return {Boolean}\n\t\t */\n\t\tchkIfBlocked: function (mx, my) {\n\n\t\t\tvar _this = this,\n\t\t\t\tfw = new TD.FindWay(\n\t\t\t\t\tthis.map.grid_x, this.map.grid_y,\n\t\t\t\t\tthis.grid.mx, this.grid.my,\n\t\t\t\t\tthis.map.exit.mx, this.map.exit.my,\n\t\t\t\t\tfunction (x, y) {\n\t\t\t\t\t\treturn !(x == mx && y == my) &&\n\t\t\t\t\t\t\t_this.map.checkPassable(x, y);\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\treturn fw.is_blocked;\n\n\t\t},\n\n\t\t/**\n\t\t * 怪物前进的道路被阻塞(被建筑包围了)\n\t\t */\n\t\tbeBlocked: function () {\n\t\t\tif (this.is_blocked) return;\n\n\t\t\tthis.is_blocked = true;\n\t\t\tTD.log(\"monster be blocked!\");\n\t\t},\n\n\t\tstep: function () {\n\t\t\tif (!this.is_valid || this.is_paused || !this.grid) return;\n\n\t\t\tif (!this.next_grid) {\n\t\t\t\tthis.getNextGrid();\n\n\t\t\t\t/**\n\t\t\t\t * 如果依旧找不着下一步可去的格子,说明当前怪物被阻塞了\n\t\t\t\t */\n\t\t\t\tif (!this.next_grid) {\n\t\t\t\t\tthis.beBlocked();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.cx == this.next_grid.cx && this.cy == this.next_grid.cy) {\n\t\t\t\tthis.arrive();\n\t\t\t} else {\n\t\t\t\t// 移动到 next grid\n\n\t\t\t\tvar dpx = this.next_grid.cx - this.cx,\n\t\t\t\t\tdpy = this.next_grid.cy - this.cy,\n\t\t\t\t\tsx = dpx < 0 ? -1 : 1,\n\t\t\t\t\tsy = dpy < 0 ? -1 : 1,\n\t\t\t\t\tspeed = this.speed * TD.global_speed;\n\n\t\t\t\tif (Math.abs(dpx) < speed && Math.abs(dpy) < speed) {\n\t\t\t\t\tthis.cx = this.next_grid.cx;\n\t\t\t\t\tthis.cy = this.next_grid.cy;\n\t\t\t\t\tthis._dx = speed - Math.abs(dpx);\n\t\t\t\t\tthis._dy = speed - Math.abs(dpy);\n\t\t\t\t} else {\n\t\t\t\t\tthis.cx += dpx == 0 ? 0 : sx * (speed + this._dx);\n\t\t\t\t\tthis.cy += dpy == 0 ? 0 : sy * (speed + this._dy);\n\t\t\t\t\tthis._dx = 0;\n\t\t\t\t\tthis._dy = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.caculatePos();\n\t\t},\n\n\t\tonEnter: function () {\n\t\t\tvar msg,\n\t\t\t\tballoontip = this.scene.panel.balloontip;\n\n\t\t\tif (balloontip.el == this) {\n\t\t\t\tballoontip.hide();\n\t\t\t\tballoontip.el = null;\n\t\t\t} else {\n\t\t\t\tmsg = TD._t(\"monster_info\",\n\t\t\t\t\t[this.life, this.shield, this.speed, this.damage]);\n\t\t\t\tballoontip.msg(msg, this);\n\t\t\t}\n\t\t},\n\n\t\tonOut: function () {\n//\t\t\tif (this.scene.panel.balloontip.el == this) {\n//\t\t\t\tthis.scene.panel.balloontip.hide();\n//\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t * 至少需要包含以下项:\n\t * {\n\t *\t\t\t life: 怪物的生命值\n\t *\t\t\t shield: 怪物的防御值\n\t *\t\t\t speed: 怪物的速度\n\t *\t\t }\n\t */\n\tTD.Monster = function (id, cfg) {\n\t\tcfg.on_events = [\"enter\", \"out\"];\n\t\tvar monster = new TD.Element(id, cfg);\n\t\tTD.lang.mix(monster, monster_obj);\n\t\tmonster._init(cfg);\n\n\t\treturn monster;\n\t};\n\n\n\t/**\n\t * 怪物死亡时的爆炸效果对象\n\t */\n\tvar explode_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\n\t\t\tvar rgb = TD.lang.rgb2Arr(cfg.color);\n\t\t\tthis.cx = cfg.cx;\n\t\t\tthis.cy = cfg.cy;\n\t\t\tthis.r = cfg.r * _TD.retina;\n\t\t\tthis.step_level = cfg.step_level;\n\t\t\tthis.render_level = cfg.render_level;\n\n\t\t\tthis.rgb_r = rgb[0];\n\t\t\tthis.rgb_g = rgb[1];\n\t\t\tthis.rgb_b = rgb[2];\n\t\t\tthis.rgb_a = 1;\n\n\t\t\tthis.wait = this.wait0 = TD.exp_fps * (cfg.time || 1);\n\n\t\t\tcfg.scene.addElement(this);\n\t\t},\n\t\tstep: function () {\n\t\t\tif (!this.is_valid) return;\n\n\t\t\tthis.wait--;\n\t\t\tthis.r++;\n\n\t\t\tthis.is_valid = this.wait > 0;\n\t\t\tthis.rgb_a = this.wait / this.wait0;\n\t\t},\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\n\t\t\tctx.fillStyle = \"rgba(\" + this.rgb_r + \",\" + this.rgb_g + \",\"\n\t\t\t\t+ this.rgb_b + \",\" + this.rgb_a + \")\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(this.cx, this.cy, this.r, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t * {\n\t *\t\t\t// 至少需要包含以下项:\n\t * \t\t\t cx: 中心 x 坐标\n\t * \t\t\t cy: 中心 y 坐标\n\t * \t\t\t r: 半径\n\t * \t\t\t color: RGB色彩,形如“#f98723”\n\t * \t\t\t scene: Scene 对象\n\t * \t\t\t step_level:\n\t * \t\t\t render_level:\n\t *\n\t * \t\t\t// 以下项可选:\n\t * \t\t\ttime: 持续时间,默认为 1,单位大致为秒(根据渲染情况而定,不是很精确)\n\t *\t\t }\n\t */\n\tTD.Explode = function (id, cfg) {\n//\t\tcfg.on_events = [\"enter\", \"out\"];\n\t\tvar explode = new TD.Element(id, cfg);\n\t\tTD.lang.mix(explode, explode_obj);\n\t\texplode._init(cfg);\n\n\t\treturn explode;\n\t};\n\n}); // _TD.a.push end\n\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t// panel 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar panel_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.x = cfg.x;\n\t\t\tthis.y = cfg.y;\n\t\t\tthis.scene = cfg.scene;\n\t\t\tthis.map = cfg.main_map;\n\n\t\t\t// make panel map\n\t\t\tvar panel_map = new TD.Map(\"panel-map\", TD.lang.mix({\n\t\t\t\t\tx: this.x + cfg.map.x,\n\t\t\t\t\ty: this.y + cfg.map.y,\n\t\t\t\t\tscene: this.scene,\n\t\t\t\t\tstep_level: this.step_level,\n\t\t\t\t\trender_level: this.render_level\n\t\t\t\t}, cfg.map, false));\n\n\t\t\tthis.addToScene(this.scene, 1, 7);\n\t\t\tpanel_map.addToScene(this.scene, 1, 7, panel_map.grids);\n\t\t\tthis.scene.panel_map = panel_map;\n\t\t\tthis.gameover_obj = new TD.GameOver(\"panel-gameover\", {\n\t\t\t\tpanel: this,\n\t\t\t\tscene: this.scene,\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\tis_visiable: false,\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\twidth: this.scene.stage.width,\n\t\t\t\theight: this.scene.stage.height,\n\t\t\t\trender_level: 9\n\t\t\t});\n\n\t\t\tthis.balloontip = new TD.BalloonTip(\"panel-balloon-tip\", {\n\t\t\t\tscene: this.scene,\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: 9\n\t\t\t});\n\t\t\tthis.balloontip.addToScene(this.scene, 1, 9);\n\n\t\t\t// make buttons\n\t\t\t// 暂停按钮\n\t\t\tthis.btn_pause = new TD.Button(\"panel-btn-pause\", {\n\t\t\t\tscene: this.scene,\n\t\t\t\tx: this.x,\n\t\t\t\ty: this.y + 260 * _TD.retina,\n\t\t\t\ttext: TD._t(\"button_pause_text\"),\n\t\t\t\t//desc: TD._t(\"button_pause_desc_0\"),\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level + 1,\n\t\t\t\tonClick: function () {\n\t\t\t\t\tif (this.scene.state == 1) {\n\t\t\t\t\t\tthis.scene.pause();\n\t\t\t\t\t\tthis.text = TD._t(\"button_continue_text\");\n\t\t\t\t\t\tthis.scene.panel.btn_upgrade.hide();\n\t\t\t\t\t\tthis.scene.panel.btn_sell.hide();\n\t\t\t\t\t\tthis.scene.panel.btn_restart.show();\n\t\t\t\t\t\t//this.desc = TD._t(\"button_pause_desc_1\");\n\t\t\t\t\t} else if (this.scene.state == 2) {\n\t\t\t\t\t\tthis.scene.start();\n\t\t\t\t\t\tthis.text = TD._t(\"button_pause_text\");\n\t\t\t\t\t\tthis.scene.panel.btn_restart.hide();\n\t\t\t\t\t\tif (this.scene.map.selected_building) {\n\t\t\t\t\t\t\tthis.scene.panel.btn_upgrade.show();\n\t\t\t\t\t\t\tthis.scene.panel.btn_sell.show();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//this.desc = TD._t(\"button_pause_desc_0\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t// 重新开始按钮\n\t\t\tthis.btn_restart = new TD.Button(\"panel-btn-restart\", {\n\t\t\t\tscene: this.scene,\n\t\t\t\tx: this.x,\n\t\t\t\ty: this.y + 300 * _TD.retina,\n\t\t\t\tis_visiable: false,\n\t\t\t\ttext: TD._t(\"button_restart_text\"),\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level + 1,\n\t\t\t\tonClick: function () {\n\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\tTD.stage.clear();\n\t\t\t\t\t\tTD.is_paused = true;\n\t\t\t\t\t\tTD.start();\n\t\t\t\t\t\tTD.mouseHand(false);\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t});\n\t\t\t// 建筑升级按钮\n\t\t\tthis.btn_upgrade = new TD.Button(\"panel-btn-upgrade\", {\n\t\t\t\tscene: this.scene,\n\t\t\t\tx: this.x,\n\t\t\t\ty: this.y + 300 * _TD.retina,\n\t\t\t\tis_visiable: false,\n\t\t\t\ttext: TD._t(\"button_upgrade_text\"),\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level + 1,\n\t\t\t\tonClick: function () {\n\t\t\t\t\tthis.scene.map.selected_building.tryToUpgrade(this);\n\t\t\t\t}\n\t\t\t});\n\t\t\t// 建筑出售按钮\n\t\t\tthis.btn_sell = new TD.Button(\"panel-btn-sell\", {\n\t\t\t\tscene: this.scene,\n\t\t\t\tx: this.x,\n\t\t\t\ty: this.y + 340 * _TD.retina,\n\t\t\t\tis_visiable: false,\n\t\t\t\ttext: TD._t(\"button_sell_text\"),\n\t\t\t\tstep_level: this.step_level,\n\t\t\t\trender_level: this.render_level + 1,\n\t\t\t\tonClick: function () {\n\t\t\t\t\tthis.scene.map.selected_building.tryToSell(this);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tstep: function () {\n\t\t\tif (TD.life_recover) {\n\t\t\t\tthis._life_recover = this._life_recover2 = TD.life_recover;\n\t\t\t\tthis._life_recover_wait = this._life_recover_wait2 = TD.exp_fps * 3;\n\t\t\t\tTD.life_recover = 0;\n\t\t\t}\n\n\t\t\tif (this._life_recover && (TD.iframe % TD.exp_fps_eighth == 0)) {\n\t\t\t\tTD.life ++;\n\t\t\t\tthis._life_recover --;\n\t\t\t}\n\n\t\t},\n\t\trender: function () {\n\t\t\t// 画状态文字\n\t\t\tvar ctx = TD.ctx;\n\n\t\t\tctx.textAlign = \"left\";\n\t\t\tctx.textBaseline = \"top\";\n\t\t\tctx.fillStyle = \"#000\";\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(TD._t(\"panel_money_title\") + TD.money, this.x, this.y);\n\t\t\tctx.fillText(TD._t(\"panel_score_title\") + TD.score, this.x, this.y + 20 * _TD.retina);\n\t\t\tctx.fillText(TD._t(\"panel_life_title\") + TD.life, this.x, this.y + 40 * _TD.retina);\n\t\t\tctx.fillText(TD._t(\"panel_building_title\") + this.map.buildings.length,\n\t\t\t\tthis.x, this.y + 60 * _TD.retina);\n\t\t\tctx.fillText(TD._t(\"panel_monster_title\") + this.map.monsters.length,\n\t\t\t\tthis.x, this.y + 80 * _TD.retina);\n\t\t\tctx.fillText(TD._t(\"wave_info\", [this.scene.wave]), this.x, this.y + 210 * _TD.retina);\n\t\t\tctx.closePath();\n\n\t\t\tif (this._life_recover_wait) {\n\t\t\t\t// 画生命恢复提示\n\t\t\t\tvar a = this._life_recover_wait / this._life_recover_wait2;\n\t\t\t\tctx.fillStyle = \"rgba(255, 0, 0, \" + a + \")\";\n\t\t\t\tctx.font = \"bold \" + (12 * _TD.retina) + \"px 'Verdana'\";\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.fillText(\"+\" + this._life_recover2, this.x + 60 * _TD.retina, this.y + 40 * _TD.retina);\n\t\t\t\tctx.closePath();\n\t\t\t\tthis._life_recover_wait --;\n\t\t\t}\n\n\t\t\t// 在右下角画版本信息\n\t\t\tctx.textAlign = \"right\";\n\t\t\tctx.fillStyle = \"#666\";\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(\"version: \" + TD.version + \" | oldj.net\", TD.stage.width - TD.padding,\n\t\t\t\tTD.stage.height - TD.padding * 2);\n\t\t\tctx.closePath();\n\n\t\t\t// 在左下角画FPS信息\n\t\t\tctx.textAlign = \"left\";\n\t\t\tctx.fillStyle = \"#666\";\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(\"FPS: \" + TD.fps, TD.padding, TD.stage.height - TD.padding * 2);\n\t\t\tctx.closePath();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t *\t\t 至少需要包含以下项:\n\t *\t\t {\n\t *\t\t\t life: 怪物的生命值\n\t *\t\t\t shield: 怪物的防御值\n\t *\t\t\t speed: 怪物的速度\n\t *\t\t }\n\t */\n\tTD.Panel = function (id, cfg) {\n\t\tvar panel = new TD.Element(id, cfg);\n\t\tTD.lang.mix(panel, panel_obj);\n\t\tpanel._init(cfg);\n\n\t\treturn panel;\n\t};\n\n\t// balloon tip对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar balloontip_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.scene = cfg.scene;\n\t\t},\n\t\tcaculatePos: function () {\n\t\t\tvar el = this.el;\n\n\t\t\tthis.x = el.cx + 0.5;\n\t\t\tthis.y = el.cy + 0.5;\n\n\t\t\tif (this.x + this.width > this.scene.stage.width - TD.padding) {\n\t\t\t\tthis.x = this.x - this.width;\n\t\t\t}\n\n\t\t\tthis.px = this.x + 5 * _TD.retina;\n\t\t\tthis.py = this.y + 4 * _TD.retina;\n\t\t},\n\t\tmsg: function (txt, el) {\n\t\t\tthis.text = txt;\n\t\t\tvar ctx = TD.ctx;\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tthis.width = Math.max(\n\t\t\t\tctx.measureText(txt).width + 10 * _TD.retina,\n\t\t\t\tTD.lang.strLen2(txt) * 6 + 10 * _TD.retina\n\t\t\t\t);\n\t\t\tthis.height = 20 * _TD.retina;\n\n\t\t\tif (el && el.cx && el.cy) {\n\t\t\t\tthis.el = el;\n\t\t\t\tthis.caculatePos();\n\n\t\t\t\tthis.show();\n\t\t\t}\n\t\t},\n\t\tstep: function () {\n\t\t\tif (!this.el || !this.el.is_valid) {\n\t\t\t\tthis.hide();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.el.is_monster) {\n\t\t\t\t// monster 会移动,所以需要重新计算 tip 的位置\n\t\t\t\tthis.caculatePos();\n\t\t\t}\n\t\t},\n\t\trender: function () {\n\t\t\tif (!this.el) return;\n\t\t\tvar ctx = TD.ctx;\n\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.fillStyle = \"rgba(255, 255, 0, 0.5)\";\n\t\t\tctx.strokeStyle = \"rgba(222, 222, 0, 0.9)\";\n\t\t\tctx.beginPath();\n\t\t\tctx.rect(this.x, this.y, this.width, this.height);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.textAlign = \"left\";\n\t\t\tctx.textBaseline = \"top\";\n\t\t\tctx.fillStyle = \"#000\";\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(this.text, this.px, this.py);\n\t\t\tctx.closePath();\n\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t *\t\t 至少需要包含以下项:\n\t *\t\t {\n\t *\t\t\t scene: scene\n\t *\t\t }\n\t */\n\tTD.BalloonTip = function (id, cfg) {\n\t\tvar balloontip = new TD.Element(id, cfg);\n\t\tTD.lang.mix(balloontip, balloontip_obj);\n\t\tballoontip._init(cfg);\n\n\t\treturn balloontip;\n\t};\n\n\t// button 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar button_obj = {\n\t\t_init: function (cfg) {\n\t\t\tcfg = cfg || {};\n\t\t\tthis.text = cfg.text;\n\t\t\tthis.onClick = cfg.onClick || TD.lang.nullFunc;\n\t\t\tthis.x = cfg.x;\n\t\t\tthis.y = cfg.y;\n\t\t\tthis.width = cfg.width || 80 * _TD.retina;\n\t\t\tthis.height = cfg.height || 30 * _TD.retina;\n\t\t\tthis.font_x = this.x + 8 * _TD.retina;\n\t\t\tthis.font_y = this.y + 9 * _TD.retina;\n\t\t\tthis.scene = cfg.scene;\n\t\t\tthis.desc = cfg.desc || \"\";\n\n\t\t\tthis.addToScene(this.scene, this.step_level, this.render_level);\n\t\t\tthis.caculatePos();\n\t\t},\n\t\tonEnter: function () {\n\t\t\tTD.mouseHand(true);\n\t\t\tif (this.desc) {\n\t\t\t\tthis.scene.panel.balloontip.msg(this.desc, this);\n\t\t\t}\n\t\t},\n\t\tonOut: function () {\n\t\t\tTD.mouseHand(false);\n\t\t\tif (this.scene.panel.balloontip.el == this) {\n\t\t\t\tthis.scene.panel.balloontip.hide();\n\t\t\t}\n\t\t},\n\t\trender: function () {\n\t\t\tvar ctx = TD.ctx;\n\n\t\t\tctx.lineWidth = 2 * _TD.retina;\n\t\t\tctx.fillStyle = this.is_hover ? \"#eee\" : \"#ccc\";\n\t\t\tctx.strokeStyle = \"#999\";\n\t\t\tctx.beginPath();\n\t\t\tctx.rect(this.x, this.y, this.width, this.height);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.textAlign = \"left\";\n\t\t\tctx.textBaseline = \"top\";\n\t\t\tctx.fillStyle = \"#000\";\n\t\t\tctx.font = \"normal \" + (12 * _TD.retina) + \"px 'Courier New'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(this.text, this.font_x, this.font_y);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t *\t\t 至少需要包含以下项:\n\t *\t\t {\n\t *\t\t\t x:\n\t *\t\t\t y:\n\t *\t\t\t text:\n\t *\t\t\t onClick: function\n\t *\t\t\t sence:\n\t *\t\t }\n\t */\n\tTD.Button = function (id, cfg) {\n\t\tcfg.on_events = [\"enter\", \"out\", \"click\"];\n\t\tvar button = new TD.Element(id, cfg);\n\t\tTD.lang.mix(button, button_obj);\n\t\tbutton._init(cfg);\n\n\t\treturn button;\n\t};\n\n\n\t// gameover 对象的属性、方法。注意属性中不要有数组、对象等\n\t// 引用属性,否则多个实例的相关属性会发生冲突\n\tvar gameover_obj = {\n\t\t_init: function (cfg) {\n\t\t\tthis.panel = cfg.panel;\n\t\t\tthis.scene = cfg.scene;\n\n\t\t\tthis.addToScene(this.scene, 1, 9);\n\t\t},\n\t\trender: function () {\n\n\t\t\tthis.panel.btn_pause.hide();\n\t\t\tthis.panel.btn_upgrade.hide();\n\t\t\tthis.panel.btn_sell.hide();\n\t\t\tthis.panel.btn_restart.show();\n\n\t\t\tvar ctx = TD.ctx;\n\t\t\tctx.textAlign = \"center\";\n\t\t\tctx.textBaseline = \"middle\";\n\t\t\tctx.fillStyle = \"#ccc\";\n\t\t\tctx.font = \"bold 62px 'Verdana'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(\"GAME OVER\", this.width / 2, this.height / 2);\n\t\t\tctx.closePath();\n\t\t\tctx.fillStyle = \"#f00\";\n\t\t\tctx.font = \"bold 60px 'Verdana'\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillText(\"GAME OVER\", this.width / 2, this.height / 2);\n\t\t\tctx.closePath();\n\n\t\t}\n\t};\n\n\t/**\n\t * @param id {String}\n\t * @param cfg {Object} 配置对象\n\t *\t\t 至少需要包含以下项:\n\t *\t\t {\n\t *\t\t\t panel:\n\t *\t\t\t scene:\n\t *\t\t }\n\t */\n\tTD.GameOver = function (id, cfg) {\n\t\tvar obj = new TD.Element(id, cfg);\n\t\tTD.lang.mix(obj, gameover_obj);\n\t\tobj._init(cfg);\n\n\t\treturn obj;\n\t};\n\n\n\t/**\n\t * 恢复 n 点生命值\n\t * @param n\n\t */\n\tTD.recover = function (n) {\n//\t\tTD.life += n;\n\t\tTD.life_recover = n;\n\t\tTD.log(\"life recover: \" + n);\n\t};\n\n}); // _TD.a.push end\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * 默认关卡\n */\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n// main stage 初始化方法\n\tvar _stage_main_init = function () {\n\t\t\tvar act = new TD.Act(this, \"act-1\"),\n\t\t\t\tscene = new TD.Scene(act, \"scene-1\"),\n\t\t\t\tcfg = TD.getDefaultStageData(\"scene_endless\");\n\n\t\t\tthis.config = cfg.config;\n\t\t\tTD.life = this.config.life;\n\t\t\tTD.money = this.config.money;\n\t\t\tTD.score = this.config.score;\n\t\t\tTD.difficulty = this.config.difficulty;\n\t\t\tTD.wave_damage = this.config.wave_damage;\n\n\t\t\t// make map\n\t\t\tvar map = new TD.Map(\"main-map\", TD.lang.mix({\n\t\t\t\tscene: scene,\n\t\t\t\tis_main_map: true,\n\t\t\t\tstep_level: 1,\n\t\t\t\trender_level: 2\n\t\t\t}, cfg.map));\n\t\t\tmap.addToScene(scene, 1, 2, map.grids);\n\t\t\tscene.map = map;\n\n\t\t\t// make panel\n\t\t\tscene.panel = new TD.Panel(\"panel\", TD.lang.mix({\n\t\t\t\tscene: scene,\n\t\t\t\tmain_map: map,\n\t\t\t\tstep_level: 1,\n\t\t\t\trender_level: 7\n\t\t\t}, cfg.panel));\n\n\t\t\tthis.newWave = cfg.newWave;\n\t\t\tthis.map = map;\n\t\t\tthis.wait_new_wave = this.config.wait_new_wave;\n\t\t},\n\t\t_stage_main_step2 = function () {\n\t\t\t//TD.log(this.current_act.current_scene.wave);\n\n\t\t\tvar scene = this.current_act.current_scene,\n\t\t\t\twave = scene.wave;\n\t\t\tif ((wave == 0 && !this.map.has_weapon) || scene.state != 1) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.map.monsters.length == 0) {\n\t\t\t\tif (wave > 0 && this.wait_new_wave == this.config.wait_new_wave - 1) {\n\t\t\t\t\t// 一波怪物刚刚走完\n\t\t\t\t\t// 奖励生命值\n\n\t\t\t\t\tvar wave_reward = 0;\n\t\t\t\t\tif (wave % 10 == 0) {\n\t\t\t\t\t\twave_reward = 10;\n\t\t\t\t\t} else if (wave % 5 == 0) {\n\t\t\t\t\t\twave_reward = 5;\n\t\t\t\t\t}\n\t\t\t\t\tif (TD.life + wave_reward > 100) {\n\t\t\t\t\t\twave_reward = 100 - TD.life;\n\t\t\t\t\t}\n\t\t\t\t\tif (wave_reward > 0) {\n\t\t\t\t\t\tTD.recover(wave_reward);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.wait_new_wave > 0) {\n\t\t\t\t\tthis.wait_new_wave--;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.wait_new_wave = this.config.wait_new_wave;\n\t\t\t\twave++;\n\t\t\t\tscene.wave = wave;\n\t\t\t\tthis.newWave({\n\t\t\t\t\tmap: this.map,\n\t\t\t\t\twave: wave\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\tTD.getDefaultStageData = function (k) {\n\t\tvar data = {\n\t\t\tstage_main: {\n\t\t\t\twidth: 640 * _TD.retina, // px\n\t\t\t\theight: 560 * _TD.retina,\n\t\t\t\tinit: _stage_main_init,\n\t\t\t\tstep2: _stage_main_step2\n\t\t\t},\n\n\t\t\tscene_endless: {\n\t\t\t\t// scene 1\n\t\t\t\tmap: {\n\t\t\t\t\tgrid_x: 16,\n\t\t\t\t\tgrid_y: 16,\n\t\t\t\t\tx: TD.padding,\n\t\t\t\t\ty: TD.padding,\n\t\t\t\t\tentrance: [0, 0],\n\t\t\t\t\texit: [15, 15],\n\t\t\t\t\tgrids_cfg: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpos: [3, 3],\n\t\t\t\t\t\t\t//building: \"cannon\",\n\t\t\t\t\t\t\tpassable_flag: 0\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpos: [7, 15],\n\t\t\t\t\t\t\tbuild_flag: 0\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpos: [4, 12],\n\t\t\t\t\t\t\tbuilding: \"wall\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpos: [4, 13],\n\t\t\t\t\t\t\tbuilding: \"wall\"\n\t\t\t\t\t\t\t//}, {\n\t\t\t\t\t\t\t//pos: [11, 9],\n\t\t\t\t\t\t\t//building: \"cannon\"\n\t\t\t\t\t\t\t//}, {\n\t\t\t\t\t\t\t//pos: [5, 2],\n\t\t\t\t\t\t\t//building: \"HMG\"\n\t\t\t\t\t\t\t//}, {\n\t\t\t\t\t\t\t//pos: [14, 9],\n\t\t\t\t\t\t\t//building: \"LMG\"\n\t\t\t\t\t\t\t//}, {\n\t\t\t\t\t\t\t//pos: [3, 14],\n\t\t\t\t\t\t\t//building: \"LMG\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\tpanel: {\n\t\t\t\t\tx: TD.padding * 2 + TD.grid_size * 16,\n\t\t\t\t\ty: TD.padding,\n\t\t\t\t\tmap: {\n\t\t\t\t\t\tgrid_x: 3,\n\t\t\t\t\t\tgrid_y: 3,\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 110 * _TD.retina,\n\t\t\t\t\t\tgrids_cfg: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpos: [0, 0],\n\t\t\t\t\t\t\t\tbuilding: \"cannon\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpos: [1, 0],\n\t\t\t\t\t\t\t\tbuilding: \"LMG\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpos: [2, 0],\n\t\t\t\t\t\t\t\tbuilding: \"HMG\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpos: [0, 1],\n\t\t\t\t\t\t\t\tbuilding: \"laser_gun\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpos: [2, 2],\n\t\t\t\t\t\t\t\tbuilding: \"wall\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tconfig: {\n\t\t\t\t\tendless: true,\n\t\t\t\t\twait_new_wave: TD.exp_fps * 3, // 经过多少 step 后再开始新的一波\n\t\t\t\t\tdifficulty: 1.0, // 难度系数\n\t\t\t\t\twave: 0,\n\t\t\t\t\tmax_wave: -1,\n\t\t\t\t\twave_damage: 0, // 当前一波怪物造成了多少点生命值的伤害\n\t\t\t\t\tmax_monsters_per_wave: 100, // 每一波最多多少怪物\n\t\t\t\t\tmoney: 500,\n\t\t\t\t\tscore: 0, // 开局时的积分\n\t\t\t\t\tlife: 100,\n\t\t\t\t\twaves: [ // 这儿只定义了前 10 波怪物,从第 11 波开始自动生成\n\t\t\t\t\t\t[],\n\t\t\t\t\t\t// 第一个参数是没有用的(第 0 波)\n\n\t\t\t\t\t\t// 第一波\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[1, 0] // 1 个 0 类怪物\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// 第二波\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[1, 0], // 1 个 0 类怪物\n\t\t\t\t\t\t\t[1, 1] // 1 个 1 类怪物\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 3\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[2, 0], // 2 个 0 类怪物\n\t\t\t\t\t\t\t[1, 1] // 1 个 1 类怪物\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 4\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[2, 0],\n\t\t\t\t\t\t\t[1, 1]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 5\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[3, 0],\n\t\t\t\t\t\t\t[2, 1]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 6\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[4, 0],\n\t\t\t\t\t\t\t[2, 1]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 7\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[5, 0],\n\t\t\t\t\t\t\t[3, 1],\n\t\t\t\t\t\t\t[1, 2]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 8\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[6, 0],\n\t\t\t\t\t\t\t[4, 1],\n\t\t\t\t\t\t\t[1, 2]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 9\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[7, 0],\n\t\t\t\t\t\t\t[3, 1],\n\t\t\t\t\t\t\t[2, 2]\n\t\t\t\t\t\t],\n\n\t\t\t\t\t\t// wave 10\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[8, 0],\n\t\t\t\t\t\t\t[4, 1],\n\t\t\t\t\t\t\t[3, 2]\n\t\t\t\t\t\t]\n\t\t\t\t\t]\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * 生成第 n 波怪物的方法\n\t\t\t\t */\n\t\t\t\tnewWave: function (cfg) {\n\t\t\t\t\tcfg = cfg || {};\n\t\t\t\t\tvar map = cfg.map,\n\t\t\t\t\t\twave = cfg.wave || 1,\n\t\t\t\t\t//difficulty = TD.difficulty || 1.0,\n\t\t\t\t\t\twave_damage = TD.wave_damage || 0;\n\n\t\t\t\t\t// 自动调整难度系数\n\t\t\t\t\tif (wave == 1) {\n\t\t\t\t\t\t//pass\n\t\t\t\t\t} else if (wave_damage == 0) {\n\t\t\t\t\t\t// 没有造成伤害\n\t\t\t\t\t\tif (wave < 5) {\n\t\t\t\t\t\t\tTD.difficulty *= 1.05;\n\t\t\t\t\t\t} else if (TD.difficulty > 30) {\n\t\t\t\t\t\t\tTD.difficulty *= 1.1;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tTD.difficulty *= 1.2;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (TD.wave_damage >= 50) {\n\t\t\t\t\t\tTD.difficulty *= 0.6;\n\t\t\t\t\t} else if (TD.wave_damage >= 30) {\n\t\t\t\t\t\tTD.difficulty *= 0.7;\n\t\t\t\t\t} else if (TD.wave_damage >= 20) {\n\t\t\t\t\t\tTD.difficulty *= 0.8;\n\t\t\t\t\t} else if (TD.wave_damage >= 10) {\n\t\t\t\t\t\tTD.difficulty *= 0.9;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// 造成了 10 点以内的伤害\n\t\t\t\t\t\tif (wave >= 10)\n\t\t\t\t\t\t\tTD.difficulty *= 1.05;\n\t\t\t\t\t}\n\t\t\t\t\tif (TD.difficulty < 1) TD.difficulty = 1;\n\n\t\t\t\t\tTD.log(\"wave \" + wave + \", last wave damage = \" + wave_damage + \", difficulty = \" + TD.difficulty);\n\n\t\t\t\t\t//map.addMonsters(100, 7);\n\t\t\t\t\t//map.addMonsters2([[10, 7], [5, 0], [5, 5]]);\n\t\t\t\t\t//\n\t\t\t\t\tvar wave_data = this.config.waves[wave] ||\n\t\t\t\t\t\t\t// 自动生成怪物\n\t\t\t\t\t\tTD.makeMonsters(Math.min(\n\t\t\t\t\t\t\tMath.floor(Math.pow(wave, 1.1)),\n\t\t\t\t\t\t\tthis.config.max_monsters_per_wave\n\t\t\t\t\t\t));\n\t\t\t\t\tmap.addMonsters2(wave_data);\n\n\t\t\t\t\tTD.wave_damage = 0;\n\t\t\t\t}\n\t\t\t} // end of scene_endless\n\t\t};\n\n\t\treturn data[k] || {};\n\t};\n\n}); // _TD.a.push end\n\n\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * 本文件定义了建筑的参数、属性\n */\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * 默认的升级规则\n\t * @param old_level {Number}\n\t * @param old_value {Number}\n\t * @return new_value {Number}\n\t */\n\tTD.default_upgrade_rule = function (old_level, old_value) {\n\t\treturn old_value * 1.2;\n\t};\n\n\t/**\n\t * 取得建筑的默认属性\n\t * @param building_type {String} 建筑类型\n\t */\n\tTD.getDefaultBuildingAttributes = function (building_type) {\n\n\t\tvar building_attributes = {\n\t\t\t// 路障\n\t\t\t\"wall\": {\n\t\t\t\tdamage: 0,\n\t\t\t\trange: 0,\n\t\t\t\tspeed: 0,\n\t\t\t\tbullet_speed: 0,\n\t\t\t\tlife: 100,\n\t\t\t\tshield: 500,\n\t\t\t\tcost: 5\n\t\t\t},\n\n\t\t\t// 炮台\n\t\t\t\"cannon\": {\n\t\t\t\tdamage: 12,\n\t\t\t\trange: 4,\n\t\t\t\tmax_range: 8,\n\t\t\t\tspeed: 2,\n\t\t\t\tbullet_speed: 6,\n\t\t\t\tlife: 100,\n\t\t\t\tshield: 100,\n\t\t\t\tcost: 300,\n\t\t\t\t_upgrade_rule_damage: function (old_level, old_value) {\n\t\t\t\t\treturn old_value * (old_level <= 10 ? 1.2 : 1.3);\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// 轻机枪\n\t\t\t\"LMG\": {\n\t\t\t\tdamage: 5,\n\t\t\t\trange: 5,\n\t\t\t\tmax_range: 10,\n\t\t\t\tspeed: 3,\n\t\t\t\tbullet_speed: 6,\n\t\t\t\tlife: 100,\n\t\t\t\tshield: 50,\n\t\t\t\tcost: 100\n\t\t\t},\n\n\t\t\t// 重机枪\n\t\t\t\"HMG\": {\n\t\t\t\tdamage: 30,\n\t\t\t\trange: 3,\n\t\t\t\tmax_range: 5,\n\t\t\t\tspeed: 3,\n\t\t\t\tbullet_speed: 5,\n\t\t\t\tlife: 100,\n\t\t\t\tshield: 200,\n\t\t\t\tcost: 800,\n\t\t\t\t_upgrade_rule_damage: function (old_level, old_value) {\n\t\t\t\t\treturn old_value * 1.3;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// 激光枪\n\t\t\t\"laser_gun\": {\n\t\t\t\tdamage: 25,\n\t\t\t\trange: 6,\n\t\t\t\tmax_range: 10,\n\t\t\t\tspeed: 20,\n//\t\t\t\tbullet_speed: 10, // laser_gun 的 bullet_speed 属性没有用\n\t\t\t\tlife: 100,\n\t\t\t\tshield: 100,\n\t\t\t\tcost: 2000\n\t\t\t}\n\t\t};\n\n\t\treturn building_attributes[building_type] || {};\n\t};\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * 本文件定义了怪物默认属性及渲染方法\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * 默认的怪物渲染方法\n\t */\n\tfunction defaultMonsterRender() {\n\t\tif (!this.is_valid || !this.grid) return;\n\t\tvar ctx = TD.ctx;\n\n\t\t// 画一个圆代表怪物\n\t\tctx.strokeStyle = \"#000\";\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = this.color;\n\t\tctx.beginPath();\n\t\tctx.arc(this.cx, this.cy, this.r, 0, Math.PI * 2, true);\n\t\tctx.closePath();\n\t\tctx.fill();\n\t\tctx.stroke();\n\n\t\t// 画怪物的生命值\n\t\tif (TD.show_monster_life) {\n\t\t\tvar s = Math.floor(TD.grid_size / 4),\n\t\t\t\tl = s * 2 - 2 * _TD.retina;\n\t\t\tctx.fillStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(this.cx - s, this.cy - this.r - 6, s * 2, 4 * _TD.retina);\n\t\t\tctx.closePath();\n\t\t\tctx.fillStyle = \"#f00\";\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(this.cx - s + _TD.retina, this.cy - this.r - (6 - _TD.retina), this.life * l / this.life0, 2 * _TD.retina);\n\t\t\tctx.closePath();\n\t\t}\n\t}\n\n\t/**\n\t * 取得怪物的默认属性\n\t * @param [monster_idx] {Number} 怪物的类型\n\t * @return attributes {Object}\n\t */\n\tTD.getDefaultMonsterAttributes = function (monster_idx) {\n\n\t\tvar monster_attributes = [\n\t\t\t{\n\t\t\t\t// idx: 0\n\t\t\t\tname: \"monster 1\",\n\t\t\t\tdesc: \"最弱小的怪物\",\n\t\t\t\tspeed: 3,\n\t\t\t\tmax_speed: 10,\n\t\t\t\tlife: 50,\n\t\t\t\tdamage: 1, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 0,\n\t\t\t\tmoney: 5 // 消灭本怪物后可得多少金钱(可选)\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 1\n\t\t\t\tname: \"monster 2\",\n\t\t\t\tdesc: \"稍强一些的小怪\",\n\t\t\t\tspeed: 6,\n\t\t\t\tmax_speed: 20,\n\t\t\t\tlife: 50,\n\t\t\t\tdamage: 2, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 2\n\t\t\t\tname: \"monster speed\",\n\t\t\t\tdesc: \"速度较快的小怪\",\n\t\t\t\tspeed: 12,\n\t\t\t\tmax_speed: 30,\n\t\t\t\tlife: 50,\n\t\t\t\tdamage: 3, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 3\n\t\t\t\tname: \"monster life\",\n\t\t\t\tdesc: \"生命值很强的小怪\",\n\t\t\t\tspeed: 5,\n\t\t\t\tmax_speed: 10,\n\t\t\t\tlife: 500,\n\t\t\t\tdamage: 3, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 4\n\t\t\t\tname: \"monster shield\",\n\t\t\t\tdesc: \"防御很强的小怪\",\n\t\t\t\tspeed: 5,\n\t\t\t\tmax_speed: 10,\n\t\t\t\tlife: 50,\n\t\t\t\tdamage: 3, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 20\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 5\n\t\t\t\tname: \"monster damage\",\n\t\t\t\tdesc: \"伤害值很大的小怪\",\n\t\t\t\tspeed: 7,\n\t\t\t\tmax_speed: 14,\n\t\t\t\tlife: 50,\n\t\t\t\tdamage: 10, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 2\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 6\n\t\t\t\tname: \"monster speed-life\",\n\t\t\t\tdesc: \"速度、生命都较高的怪物\",\n\t\t\t\tspeed: 15,\n\t\t\t\tmax_speed: 30,\n\t\t\t\tlife: 100,\n\t\t\t\tdamage: 3, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 3\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 7\n\t\t\t\tname: \"monster speed-2\",\n\t\t\t\tdesc: \"速度很快的怪物\",\n\t\t\t\tspeed: 30,\n\t\t\t\tmax_speed: 40,\n\t\t\t\tlife: 30,\n\t\t\t\tdamage: 4, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t// idx: 8\n\t\t\t\tname: \"monster shield-life\",\n\t\t\t\tdesc: \"防御很强、生命值很高的怪物\",\n\t\t\t\tspeed: 3,\n\t\t\t\tmax_speed: 10,\n\t\t\t\tlife: 300,\n\t\t\t\tdamage: 5, // 到达终点后会带来多少点伤害(1 ~ 10)\n\t\t\t\tshield: 15\n\t\t\t}\n\t\t];\n\n\t\tif (typeof monster_idx == \"undefined\") {\n\t\t\t// 如果只传了一个参数,则只返回共定义了多少种怪物(供 td.js 中使用)\n\t\t\treturn monster_attributes.length;\n\t\t}\n\n\t\tvar attr = monster_attributes[monster_idx] || monster_attributes[0],\n\t\t\tattr2 = {};\n\n\t\tTD.lang.mix(attr2, attr);\n\t\tif (!attr2.render) {\n\t\t\t// 如果没有指定当前怪物的渲染方法\n\t\t\tattr2.render = defaultMonsterRender\n\t\t}\n\n\t\treturn attr2;\n\t};\n\n\n\t/**\n\t * 生成一个怪物列表,\n\t * 包含 n 个怪物\n\t * 怪物类型在 range 中指定,如未指定,则为随机\n\t */\n\tTD.makeMonsters = function (n, range) {\n\t\tvar a = [], count = 0, i, c, d, r, l = TD.monster_type_count;\n\t\tif (!range) {\n\t\t\trange = [];\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\trange.push(i);\n\t\t\t}\n\t\t}\n\n\t\twhile (count < n) {\n\t\t\td = n - count;\n\t\t\tc = Math.min(\n\t\t\t\tMath.floor(Math.random() * d) + 1,\n\t\t\t\t3 // 同一类型的怪物一次最多出现 3 个,防止某一波中怪出大量高防御或高速度的怪\n\t\t\t);\n\t\t\tr = Math.floor(Math.random() * l);\n\t\t\ta.push([c, range[r]]);\n\t\t\tcount += c;\n\t\t}\n\n\t\treturn a;\n\t};\n\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tfunction lineTo2(ctx, x0, y0, x1, y1, len) {\n\t\tvar x2, y2, a, b, p, xt,\n\t\t\ta2, b2, c2;\n\n\t\tif (x0 == x1) {\n\t\t\tx2 = x0;\n\t\t\ty2 = y1 > y0 ? y0 + len : y0 - len;\n\t\t} else if (y0 == y1) {\n\t\t\ty2 = y0;\n\t\t\tx2 = x1 > x0 ? x0 + len : x0 - len;\n\t\t} else {\n\t\t\t// 解一元二次方程\n\t\t\ta = (y0 - y1) / (x0 - x1);\n\t\t\tb = y0 - x0 * a;\n\t\t\ta2 = a * a + 1;\n\t\t\tb2 = 2 * (a * (b - y0) - x0);\n\t\t\tc2 = Math.pow(b - y0, 2) + x0 * x0 - Math.pow(len, 2);\n\t\t\tp = Math.pow(b2, 2) - 4 * a2 * c2;\n\t\t\tif (p < 0) {\n//\t\t\t\tTD.log(\"ERROR: [a, b, len] = [\" + ([a, b, len]).join(\", \") + \"]\");\n\t\t\t\treturn [0, 0];\n\t\t\t}\n\t\t\tp = Math.sqrt(p);\n\t\t\txt = (-b2 + p) / (2 * a2);\n\t\t\tif ((x1 - x0 > 0 && xt - x0 > 0) ||\n\t\t\t\t(x1 - x0 < 0 && xt - x0 < 0)) {\n\t\t\t\tx2 = xt;\n\t\t\t\ty2 = a * x2 + b;\n\t\t\t} else {\n\t\t\t\tx2 = (-b2 - p) / (2 * a2);\n\t\t\t\ty2 = a * x2 + b;\n\t\t\t}\n\t\t}\n\n\t\tctx.lineCap = \"round\";\n\t\tctx.moveTo(x0, y0);\n\t\tctx.lineTo(x2, y2);\n\n\t\treturn [x2, y2];\n\t}\n\n\tvar renderFunctions = {\n\t\t\"cannon\": function (b, ctx, map, gs, gs2) {\n\t\t\tvar target_position = b.getTargetPosition();\n\n\t\t\tctx.fillStyle = \"#393\";\n\t\t\tctx.strokeStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.arc(b.cx, b.cy, gs2 - 5, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = 3 * _TD.retina;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(b.cx, b.cy);\n\t\t\tb.muzzle = lineTo2(ctx, b.cx, b.cy, target_position[0], target_position[1], gs2);\n\t\t\tctx.closePath();\n//\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.fillStyle = \"#060\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx, b.cy, 7 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.fillStyle = \"#cec\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx + 2, b.cy - 2, 3 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t},\n\t\t\"LMG\": function (b, ctx, map, gs, gs2) {\n\t\t\tvar target_position = b.getTargetPosition();\n\n\t\t\tctx.fillStyle = \"#36f\";\n\t\t\tctx.strokeStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.arc(b.cx, b.cy, 7 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = 2 * _TD.retina;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(b.cx, b.cy);\n\t\t\tb.muzzle = lineTo2(ctx, b.cx, b.cy, target_position[0], target_position[1], gs2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.fillStyle = \"#66c\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx, b.cy, 5 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.fillStyle = \"#ccf\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx + 1, b.cy - 1, 2 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t},\n\t\t\"HMG\": function (b, ctx, map, gs, gs2) {\n\t\t\tvar target_position = b.getTargetPosition();\n\n\t\t\tctx.fillStyle = \"#933\";\n\t\t\tctx.strokeStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.arc(b.cx, b.cy, gs2 - 2, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = 5 * _TD.retina;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(b.cx, b.cy);\n\t\t\tb.muzzle = lineTo2(ctx, b.cx, b.cy, target_position[0], target_position[1], gs2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.fillStyle = \"#630\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx, b.cy, gs2 - 5 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.fillStyle = \"#960\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx + 1, b.cy - 1, 8 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t\tctx.fillStyle = \"#fcc\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx + 3, b.cy - 3, 4 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t},\n\t\t\"wall\": function (b, ctx, map, gs, gs2) {\n\t\t\tctx.lineWidth = _TD.retina;\n\t\t\tctx.fillStyle = \"#666\";\n\t\t\tctx.strokeStyle = \"#000\";\n\t\t\tctx.fillRect(b.cx - gs2 + 1, b.cy - gs2 + 1, gs - 1, gs - 1);\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(b.cx - gs2 + 0.5, b.cy - gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx - gs2 + 0.5, b.cy + gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx + gs2 + 0.5, b.cy + gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx + gs2 + 0.5, b.cy - gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx - gs2 + 0.5, b.cy - gs2 + 0.5);\n\t\t\tctx.moveTo(b.cx - gs2 + 0.5, b.cy + gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx + gs2 + 0.5, b.cy - gs2 + 0.5);\n\t\t\tctx.moveTo(b.cx - gs2 + 0.5, b.cy - gs2 + 0.5);\n\t\t\tctx.lineTo(b.cx + gs2 + 0.5, b.cy + gs2 + 0.5);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t},\n\t\t\"laser_gun\": function (b, ctx/*, map, gs, gs2*/) {\n//\t\t\tvar target_position = b.getTargetPosition();\n\n\t\t\tctx.fillStyle = \"#f00\";\n\t\t\tctx.strokeStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.lineWidth = _TD.retina;\n//\t\t\tctx.arc(b.cx, b.cy, gs2 - 5, 0, Math.PI * 2, true);\n\t\t\tctx.moveTo(b.cx, b.cy - 10 * _TD.retina);\n\t\t\tctx.lineTo(b.cx - 8.66 * _TD.retina, b.cy + 5 * _TD.retina);\n\t\t\tctx.lineTo(b.cx + 8.66 * _TD.retina, b.cy + 5 * _TD.retina);\n\t\t\tctx.lineTo(b.cx, b.cy - 10 * _TD.retina);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.fillStyle = \"#60f\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx, b.cy, 7 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\n\t\t\tctx.fillStyle = \"#000\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx, b.cy, 3 * _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t\tctx.fillStyle = \"#666\";\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(b.cx + 1, b.cy - 1, _TD.retina, 0, Math.PI * 2, true);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\n\t\t\tctx.lineWidth = 3 * _TD.retina;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(b.cx, b.cy);\n//\t\t\tb.muzzle = lineTo2(ctx, b.cx, b.cy, target_position[0], target_position[1], gs2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.stroke();\n\t\t}\n\t};\n\n\tTD.renderBuilding = function (building) {\n\t\tvar ctx = TD.ctx,\n\t\t\tmap = building.map,\n\t\t\tgs = TD.grid_size,\n\t\t\tgs2 = TD.grid_size / 2;\n\n\t\t(renderFunctions[building.type] || renderFunctions[\"wall\"])(\n\t\t\tbuilding, ctx, map, gs, gs2\n\t\t);\n\t}\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\tTD._msg_texts = {\n\t\t\"_cant_build\": \"不能在这儿修建\",\n\t\t\"_cant_pass\": \"怪物不能通过这儿\",\n\t\t\"entrance\": \"起点\",\n\t\t\"exit\": \"终点\",\n\t\t\"not_enough_money\": \"金钱不足,需要 $${0}!\",\n\t\t\"wave_info\": \"第 ${0} 波\",\n\t\t\"panel_money_title\": \"金钱: \",\n\t\t\"panel_score_title\": \"积分: \",\n\t\t\"panel_life_title\": \"生命: \",\n\t\t\"panel_building_title\": \"建筑: \",\n\t\t\"panel_monster_title\": \"怪物: \",\n\t\t\"building_name_wall\": \"路障\",\n\t\t\"building_name_cannon\": \"炮台\",\n\t\t\"building_name_LMG\": \"轻机枪\",\n\t\t\"building_name_HMG\": \"重机枪\",\n\t\t\"building_name_laser_gun\": \"激光炮\",\n\t\t\"building_info\": \"${0}: 等级 ${1},攻击 ${2},速度 ${3},射程 ${4},战绩 ${5}\",\n\t\t\"building_info_wall\": \"${0}\",\n\t\t\"building_intro_wall\": \"路障 可以阻止怪物通过 ($${0})\",\n\t\t\"building_intro_cannon\": \"炮台 射程、杀伤力较为平衡 ($${0})\",\n\t\t\"building_intro_LMG\": \"轻机枪 射程较远,杀伤力一般 ($${0})\",\n\t\t\"building_intro_HMG\": \"重机枪 快速射击,威力较大,射程一般 ($${0})\",\n\t\t\"building_intro_laser_gun\": \"激光枪 伤害较大,命中率 100% ($${0})\",\n\t\t\"click_to_build\": \"左键点击建造 ${0} ($${1})\",\n\t\t\"upgrade\": \"升级 ${0} 到 ${1} 级,需花费 $${2}。\",\n\t\t\"sell\": \"出售 ${0},可获得 $${1}\",\n\t\t\"upgrade_success\": \"升级成功,${0} 已升级到 ${1} 级!下次升级需要 $${2}。\",\n\t\t\"monster_info\": \"怪物: 生命 ${0},防御 ${1},速度 ${2},伤害 ${3}\",\n\t\t\"button_upgrade_text\": \"升级\",\n\t\t\"button_sell_text\": \"出售\",\n\t\t\"button_start_text\": \"开始\",\n\t\t\"button_restart_text\": \"重新开始\",\n\t\t\"button_pause_text\": \"暂停\",\n\t\t\"button_continue_text\": \"继续\",\n\t\t\"button_pause_desc_0\": \"游戏暂停\",\n\t\t\"button_pause_desc_1\": \"游戏继续\",\n\t\t\"blocked\": \"不能在这儿修建建筑,起点与终点之间至少要有一条路可到达!\",\n\t\t\"monster_be_blocked\": \"不能在这儿修建建筑,有怪物被围起来了!\",\n\t\t\"entrance_or_exit_be_blocked\": \"不能在起点或终点处修建建筑!\",\n\t\t\"_\": \"ERROR\"\n\t};\n\n\tTD._t = TD.translate = function (k, args) {\n\t\targs = (typeof args == \"object\" && args.constructor == Array) ? args : [];\n\t\tvar msg = this._msg_texts[k] || this._msg_texts[\"_\"],\n\t\t\ti,\n\t\t\tl = args.length;\n\t\tfor (i = 0; i < l; i++) {\n\t\t\tmsg = msg.replace(\"${\" + i + \"}\", args[i]);\n\t\t}\n\n\t\treturn msg;\n\t};\n\n\n}); // _TD.a.push end\n","/*\n * Copyright (c) 2011.\n *\n * Author: oldj \n * Blog: http://oldj.net/\n *\n * Last Update: 2011/1/10 5:22:52\n */\n\n\n// _TD.a.push begin\n_TD.a.push(function (TD) {\n\n\t/**\n\t * 使用 A* 算法(Dijkstra算法?)寻找从 (x1, y1) 到 (x2, y2) 最短的路线\n\t *\n\t */\n\tTD.FindWay = function (w, h, x1, y1, x2, y2, f_passable) {\n\t\tthis.m = [];\n\t\tthis.w = w;\n\t\tthis.h = h;\n\t\tthis.x1 = x1;\n\t\tthis.y1 = y1;\n\t\tthis.x2 = x2;\n\t\tthis.y2 = y2;\n\t\tthis.way = [];\n\t\tthis.len = this.w * this.h;\n\t\tthis.is_blocked = this.is_arrived = false;\n\t\tthis.fPassable = typeof f_passable == \"function\" ? f_passable : function () {\n\t\t\treturn true;\n\t\t};\n\n\t\tthis._init();\n\t};\n\n\tTD.FindWay.prototype = {\n\t\t_init: function () {\n\t\t\tif (this.x1 == this.x2 && this.y1 == this.y2) {\n\t\t\t\t// 如果输入的坐标已经是终点了\n\t\t\t\tthis.is_arrived = true;\n\t\t\t\tthis.way = [\n\t\t\t\t\t[this.x1, this.y1]\n\t\t\t\t];\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < this.len; i++)\n\t\t\t\tthis.m[i] = -2; // -2 表示未探索过,-1 表示不可到达\n\n\t\t\tthis.x = this.x1;\n\t\t\tthis.y = this.y1;\n\t\t\tthis.distance = 0;\n\t\t\tthis.current = [\n\t\t\t\t[this.x, this.y]\n\t\t\t]; // 当前一步探索的格子\n\n\t\t\tthis.setVal(this.x, this.y, 0);\n\n\t\t\twhile (this.next()) {\n\t\t\t}\n\t\t},\n\t\tgetVal: function (x, y) {\n\t\t\tvar p = y * this.w + x;\n\t\t\treturn p < this.len ? this.m[p] : -1;\n\t\t},\n\t\tsetVal: function (x, y, v) {\n\t\t\tvar p = y * this.w + x;\n\t\t\tif (p > this.len) return false;\n\t\t\tthis.m[p] = v;\n\t\t},\n\t\t/**\n\t\t * 得到指定坐标的邻居,即从指定坐标出发,1 步之内可以到达的格子\n\t\t * 目前返回的是指定格子的上、下、左、右四个邻格\n\t\t * @param x {Number}\n\t\t * @param y {Number}\n\t\t */\n\t\tgetNeighborsOf: function (x, y) {\n\t\t\tvar nbs = [];\n\t\t\tif (y > 0) nbs.push([x, y - 1]);\n\t\t\tif (x < this.w - 1) nbs.push([x + 1, y]);\n\t\t\tif (y < this.h - 1) nbs.push([x, y + 1]);\n\t\t\tif (x > 0) nbs.push([x - 1, y]);\n\n\t\t\treturn nbs;\n\t\t},\n\t\t/**\n\t\t * 取得当前一步可到达的 n 个格子的所有邻格\n\t\t */\n\t\tgetAllNeighbors: function () {\n\t\t\tvar nbs = [], nb1, i, c, l = this.current.length;\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\tc = this.current[i];\n\t\t\t\tnb1 = this.getNeighborsOf(c[0], c[1]);\n\t\t\t\tnbs = nbs.concat(nb1);\n\t\t\t}\n\t\t\treturn nbs;\n\t\t},\n\t\t/**\n\t\t * 从终点倒推,寻找从起点到终点最近的路径\n\t\t * 此处的实现是,从终点开始,从当前格子的邻格中寻找值最低(且大于 0)的格子,\n\t\t * 直到到达起点。\n\t\t * 这个实现需要反复地寻找邻格,有时邻格中有多个格子的值都为最低,这时就从中\n\t\t * 随机选取一个。还有一种实现方式是在一开始的遍历中,给每一个到达过的格子添加\n\t\t * 一个值,指向它的来时的格子(父格子)。\n\t\t */\n\t\tfindWay: function () {\n\t\t\tvar x = this.x2,\n\t\t\t\ty = this.y2,\n\t\t\t\tnb, max_len = this.len,\n\t\t\t\tnbs_len,\n\t\t\t\tnbs, i, l, v, min_v = -1,\n\t\t\t\tclosest_nbs;\n\n\t\t\twhile ((x != this.x1 || y != this.y1) && min_v != 0 &&\n\t\t\tthis.way.length < max_len) {\n\n\t\t\t\tthis.way.unshift([x, y]);\n\n\t\t\t\tnbs = this.getNeighborsOf(x, y);\n\t\t\t\tnbs_len = nbs.length;\n\t\t\t\tclosest_nbs = [];\n\n\t\t\t\t// 在邻格中寻找最小的 v\n\t\t\t\tmin_v = -1;\n\t\t\t\tfor (i = 0; i < nbs_len; i++) {\n\t\t\t\t\tv = this.getVal(nbs[i][0], nbs[i][1]);\n\t\t\t\t\tif (v < 0) continue;\n\t\t\t\t\tif (min_v < 0 || min_v > v)\n\t\t\t\t\t\tmin_v = v;\n\t\t\t\t}\n\t\t\t\t// 找出所有 v 最小的邻格\n\t\t\t\tfor (i = 0; i < nbs_len; i++) {\n\t\t\t\t\tnb = nbs[i];\n\t\t\t\t\tif (min_v == this.getVal(nb[0], nb[1])) {\n\t\t\t\t\t\tclosest_nbs.push(nb);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// 从 v 最小的邻格中随机选取一个作为当前格子\n\t\t\t\tl = closest_nbs.length;\n\t\t\t\ti = l > 1 ? Math.floor(Math.random() * l) : 0;\n\t\t\t\tnb = closest_nbs[i];\n\n\t\t\t\tx = nb[0];\n\t\t\t\ty = nb[1];\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * 到达终点\n\t\t */\n\t\tarrive: function () {\n\t\t\tthis.current = [];\n\t\t\tthis.is_arrived = true;\n\n\t\t\tthis.findWay();\n\t\t},\n\t\t/**\n\t\t * 道路被阻塞\n\t\t */\n\t\tblocked: function () {\n\t\t\tthis.current = [];\n\t\t\tthis.is_blocked = true;\n\t\t},\n\t\t/**\n\t\t * 下一次迭代\n\t\t * @return {Boolean} 如果返回值为 true ,表示未到达终点,并且道路\n\t\t * 未被阻塞,可以继续迭代;否则表示不必继续迭代\n\t\t */\n\t\tnext: function () {\n\t\t\tvar neighbors = this.getAllNeighbors(), nb,\n\t\t\t\tl = neighbors.length,\n\t\t\t\tvalid_neighbors = [],\n\t\t\t\tx, y,\n\t\t\t\ti, v;\n\n\t\t\tthis.distance++;\n\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\tnb = neighbors[i];\n\t\t\t\tx = nb[0];\n\t\t\t\ty = nb[1];\n\t\t\t\tif (this.getVal(x, y) != -2) continue; // 当前格子已探索过\n\t\t\t\t//grid = this.map.getGrid(x, y);\n\t\t\t\t//if (!grid) continue;\n\n\t\t\t\tif (this.fPassable(x, y)) {\n\t\t\t\t\t// 可通过\n\n\t\t\t\t\t/**\n\t\t\t\t\t * 从起点到当前格子的耗费\n\t\t\t\t\t * 这儿只是简单地把从起点到当前格子需要走几步作为耗费\n\t\t\t\t\t * 比较复杂的情况下,可能还需要考虑不同的路面耗费也会不同,\n\t\t\t\t\t * 比如沼泽地的耗费比平地要多。不过现在的版本中路况没有这么复杂,\n\t\t\t\t\t * 先不考虑。\n\t\t\t\t\t */\n\t\t\t\t\tv = this.distance;\n\n\t\t\t\t\tvalid_neighbors.push(nb);\n\t\t\t\t} else {\n\t\t\t\t\t// 不可通过或有建筑挡着\n\t\t\t\t\tv = -1;\n\t\t\t\t}\n\n\t\t\t\tthis.setVal(x, y, v);\n\n\t\t\t\tif (x == this.x2 && y == this.y2) {\n\t\t\t\t\tthis.arrive();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (valid_neighbors.length == 0) {\n\t\t\t\tthis.blocked();\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tthis.current = valid_neighbors;\n\n\t\t\treturn true;\n\t\t}\n\t};\n\n}); // _TD.a.push end\n\n\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 1af8f38..c39766c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,6 +7,11 @@ var uglify = require("gulp-uglify"); var browserify = require("gulp-browserify"); var concat = require("gulp-concat"); var sourcemaps = require("gulp-sourcemaps"); +var args = require("yargs").argv; + +var IS_DEBUG = !!args.debug; +console.log("IS_DEBUG: ", IS_DEBUG); +console.log("--------------------"); gulp.task("scripts", function () { gulp.src([ @@ -41,7 +46,7 @@ gulp.task("scripts", function () { }); gulp.task("default", function () { - gulp.start("srcipt"); + gulp.start("scripts"); gulp.watch([ "src/**/*.js" ], [ diff --git a/package.json b/package.json index 522554e..8f6db7f 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,11 @@ }, "homepage": "https://github.com/oldj/html5-tower-defense#readme", "devDependencies": { - "gulp": "^3.9.0", - "gulp-browserify": "^0.5.1", - "gulp-concat": "^2.6.0", + "gulp": "~3.9.0", + "gulp-browserify": "~0.5.1", + "gulp-concat": "~2.6.0", "gulp-sourcemaps": "^1.5.2", - "gulp-uglify": "^1.4.0" + "gulp-uglify": "~1.4.0", + "yargs": "^3.24.0" } }