1 Jx().$package("tank.event", function(J) {
  2   /**
  3 	* @namespace	
  4 	* @name tank
  5 	* @type Object
  6 	*/
  7 	var cg=J.cnGame,
  8 	em=cg.eventManager;
  9 
 10 	/**
 11 	 * 子弹击中其他robot的事件对象
 12 	 * @memberOf tank.event
 13 	 * @class
 14 	 * @name BulletHitEvent
 15 	 * @return BulletHitEvent实例
 16 	 */
 17 	this.BulletHitEvent=function(options){
 18 
 19 		this.name=options.name;		//被打中robot的名字
 20 		this.energy=options.energy;//被打中robot的剩余energy
 21 		this.bullet=options.bullet;//打中其他robot的子弹
 22 	}
 23 	this.BulletHitEvent.prototype={
 24 		/**
 25 		 * 获取击中敌人的子弹对象
 26 		 * 
 27 		 * @name getBullet
 28 		 * @function
 29 		 * @memberOf tank.event.BulletHitEvent.prototype
 30 		 * @return {Object} 击中敌人的子弹对象
 31 		 */
 32 		getBullet:function(){
 33 			return this.bullet;
 34 		},
 35 		/**
 36 		 * 获取击中的敌人的名字
 37 		 * 
 38 		 * @name getName
 39 		 * @function
 40 		 * @memberOf tank.event.BulletHitEvent.prototype
 41 		 * @return {Number} 击中的敌人的名字
 42 		 */		
 43 		getName:function(){
 44 			return this.name;
 45 		},
 46 		/**
 47 		 * 获取击中的敌人的能量
 48 		 * 
 49 		 * @name getEnergy
 50 		 * @function
 51 		 * @memberOf tank.event.BulletHitEvent.prototype
 52 		 * @return {Number} 击中的敌人的能量
 53 		 */				
 54 		getEnergy:function(){
 55 			return this.energy;
 56 		}
 57 	}
 58 	/**
 59 	 * 子弹击中其他robot的子弹的事件对象
 60 	 * @memberOf tank.event
 61 	 * @class
 62 	 * @name BulletHitBulletEvent
 63 	 * @param {Object} options 初始化参数
 64 	 * @return {Object} BulletHitBulletEvent实例
 65 	 */	
 66 
 67 	this.BulletHitBulletEvent=function(options){
 68 
 69 		this.bullet=options.bullet;//击中其他子弹的子弹
 70 		this.hitBullet=options.hitBullet;//被robot的子弹击中的子弹
 71 	}
 72 	this.BulletHitBulletEvent.prototype={
 73 		/**
 74 		 * 获取击中的敌人子弹的子弹
 75 		 * 
 76 		 * @name getBullet
 77 		 * @function
 78 		 * @memberOf tank.event.BulletHitBulletEvent.prototype
 79 		 * @return {Object} 击中的敌人子弹的子弹
 80 		 */			
 81 		getBullet:function(){
 82 			return this.bullet;
 83 		},
 84 		/**获取被击中的子弹
 85 		 * 
 86 		 * @name getHitBullet
 87 		 * @function
 88 		 * @memberOf tank.event.BulletHitBulletEvent.prototype
 89 		 * @return {Object} 击被击中的子弹
 90 		 */			
 91 		getHitBullet:function(){
 92 			return this.hitBullet;
 93 		}
 94 	}
 95 	/**
 96 	 * 子弹击中墙壁的事件对象
 97 	 * @memberOf tank.event
 98 	 * @class
 99 	 * @name BulletMissedEvent
100 	 * @param {Object} options 初始化参数
101 	 * @return BulletMissedEvent实例
102 	 */		
103 	this.BulletMissedEvent=function(options){
104 		this.bullet=options.bullet;///missed的子弹
105 	}
106 	this.BulletMissedEvent.prototype={
107 		/**获取射失的子弹
108 		 * 
109 		 * @name getBullet
110 		 * @function
111 		 * @memberOf tank.event.BulletMissedEvent.prototype
112 		 * @return {Object} 射失的子弹
113 		 */		
114 		getBullet:function(){
115 			return this.bullet;
116 		}
117 	}
118 	/**
119 	 * robot死亡的事件对象
120 	 * @memberOf tank.event
121 	 * @class
122 	 * @name DeathEvent
123 	 * @param {Object} options 初始化参数
124 	 * @return DeathEvent实例
125 	 */			
126 	this.DeathEvent=function(options){
127 
128 	}
129 	/**
130 	 * 被其他子弹击中的事件对象
131 	 * @memberOf tank.event
132 	 * @class
133 	 * @name HitByBulletEvent
134 	 * @param {Object} options 初始化参数
135 	 * @return HitByBulletEvent实例
136 	 */		
137 	this.HitByBulletEvent=function(options){
138 
139 		this.bearing=options.bearing;//子弹相对于robot的方向
140 		this.bullet=options.bullet;//击中robot的子弹对象
141 	}
142 	this.HitByBulletEvent.prototype={
143 		/**获取子弹相对于robot的角度
144 		 * 
145 		 * @name getBearing
146 		 * @function
147 		 * @memberOf tank.event.HitByBulletEvent.prototype
148 		 * @return {Object} 射失的子弹
149 		 */			
150 		getBearing:function(){
151 			return this.bearing;
152 		},
153 		/**获取子弹
154 		 * 
155 		 * @name getBullet
156 		 * @function
157 		 * @memberOf tank.event.HitByBulletEvent.prototype
158 		 * @return {Object} 击中的子弹
159 		 */			
160 		getBullet:function(){
161 			return this.bullet;	
162 		},
163 		/**获取子弹朝向
164 		 * 
165 		 * @name getHeading
166 		 * @function
167 		 * @memberOf tank.event.HitByBulletEvent.prototype
168 		 * @return {Number} 击中的子弹
169 		 */			
170 		getHeading:function(){//子弹的朝向
171 			return this.bullet.getHeading();
172 		},
173 		/**获取发出子弹的robot的名字
174 		 * 
175 		 * @name getName
176 		 * @function
177 		 * @memberOf tank.event.HitByBulletEvent.prototype
178 		 * @return {String} 发出子弹的robot的名字
179 		 */			
180 		getName:function(){//返回发出子弹的robot的名字
181 			return this.bullet.robot.getName();
182 		},
183 		/**获取子弹的power
184 		 * 
185 		 * @name getPower
186 		 * @function
187 		 * @memberOf tank.event.HitByBulletEvent.prototype
188 		 * @return {Number} 子弹的power
189 		 */			
190 		getPower:function(){//返回子弹的power
191 			return this.bullet.power;
192 		},
193 		/**获取子弹的速度
194 		 * 
195 		 * @name getSpeed
196 		 * @function
197 		 * @memberOf tank.event.HitByBulletEvent.prototype
198 		 * @return {Number} 子弹的速度
199 		 */			
200 		getSpeed:function(){
201 			return this.bullet.getSpeed();	
202 		}
203 	}
204 	/**
205 	 * 撞到其他robot的事件
206 	 * @memberOf tank.event
207 	 * @class
208 	 * @name HitRobotEvent
209 	 * @param {Object} options 初始化参数
210 	 * @return HitRobotEvent实例
211 	 */		
212 	this.HitRobotEvent=function(options){
213 
214 		this.name=options.name;//撞到的robot的名字
215 		this.bearing=options.bearing;//撞到的robot相对于该robot的角度
216 		this.energy=options.energy;//撞到的robot的剩余energy
217 	}
218 	this.HitRobotEvent.prototype={
219 		/**获取撞击的robot相对位置
220 		 * 
221 		 * @name getBearing
222 		 * @function
223 		 * @memberOf tank.event.HitRobotEvent.prototype
224 		 * @return {Number} 位置相对角度
225 		 */				
226 		getBearing:function(){
227 			return this.bearing;
228 		},
229 		/**获取撞击的robot的能量
230 		 * 
231 		 * @name getEnergy
232 		 * @function
233 		 * @memberOf tank.event.HitRobotEvent.prototype
234 		 * @return {Number} 撞击的robot的能量
235 		 */			
236 		getEnergy:function(){
237 			return this.energy;
238 		},
239 		/**获取撞击的robot的名字
240 		 * 
241 		 * @name getName
242 		 * @function
243 		 * @memberOf tank.event.HitRobotEvent.prototype
244 		 * @return {Number} 撞击的robot的名字
245 		 */			
246 		getName:function(){
247 			return this.name;
248 		}
249 	};
250 	/**
251 	 * 撞到墙壁的事件
252 	 * @memberOf tank.event
253 	 * @class
254 	 * @name HitWallEvent
255 	 * @param {Object} options 初始化参数
256 	 * @return HitWallEvent实例
257 	 */		
258 	this.HitWallEvent=function(options){
259 		this.bearing=options.bearing;//墙相对于robot的弧度
260 		
261 	}
262 	this.HitWallEvent.prototype={
263 		/**获取撞击的墙壁的朝向角度
264 		 * 
265 		 * @name getBearing
266 		 * @function
267 		 * @memberOf tank.event.HitWallEvent.prototype
268 		 * @return {Number} 撞击的墙壁的朝向角度
269 		 */			
270 		getBearing:function(){
271 			return this.bearing;
272 		}
273 	}
274 	/**
275 	 * 其他robot死亡的事件
276 	 * @memberOf tank.event
277 	 * @class
278 	 * @name RobotDeathEvent
279 	 * @param {Object} options 初始化参数
280 	 * @return RobotDeathEvent实例
281 	 */			
282 
283 	this.RobotDeathEvent=function(options){
284 		this.name=options.name;//死亡的robot的名字
285 	}
286 	this.RobotDeathEvent.prototype={
287 		/**获取死亡的robot的名字
288 		 * 
289 		 * @name getName
290 		 * @function
291 		 * @memberOf tank.event.RobotDeathEvent.prototype
292 		 * @return {String} 死亡的robot的名字
293 		 */			
294 		getName:function(){
295 			return this.name;
296 		}
297 	}
298 	/**
299 	 * 扫描到其他robot的事件
300 	 * @memberOf tank.event
301 	 * @class
302 	 * @name ScannedRobotEvent
303 	 * @param {Object} options 初始化参数
304 	 * @return ScannedRobotEvent实例
305 	 */			
306 	this.ScannedRobotEvent=function(options){
307 
308 		this.name=options.name;		//扫描到的robot的名字
309 		this.energy=options.energy;//扫描到的robot的剩余energy	
310 		this.bearing=options.bearing;//扫描到的robot相对于该robot的角度
311 		this.heading=options.heading;//扫描到的robot的角度
312 		this.distance=options.distance;//扫描到的robot相对于该robot的距离
313 		this.speed=options.speed;//扫描到的robot的速度
314 		
315 	}
316 	this.ScannedRobotEvent.prototype={
317 		/**获取扫描到robot的能量
318 		 * 
319 		 * @name getEnergy
320 		 * @function
321 		 * @memberOf tank.event.ScannedRobotEvent.prototype
322 		 * @return {Number} 扫描到robot的能量
323 		 */			
324 		getEnergy:function(){
325 			return this.energy;
326 		},
327 		/**获取扫描到robot的名字
328 		 * 
329 		 * @name getName
330 		 * @function
331 		 * @memberOf tank.event.ScannedRobotEvent.prototype
332 		 * @return {String} 扫描到robot的名字
333 		 */				
334 		getName:function(){
335 			return this.name;
336 		},
337 		/**获取扫描到robot的相对朝向
338 		 * 
339 		 * @name getBearing
340 		 * @function
341 		 * @memberOf tank.event.ScannedRobotEvent.prototype
342 		 * @return {String} 扫描到robot的名字
343 		 */			
344 		getBearing:function(){
345 			return this.bearing;
346 		},
347 		/**获取扫描到robot的朝向
348 		 * 
349 		 * @name getHeading
350 		 * @function
351 		 * @memberOf tank.event.ScannedRobotEvent.prototype
352 		 * @return {String} 扫描到robot的朝向
353 		 */			
354 		getHeading:function(){
355 			return this.getHeading();
356 		},
357 		/**获取扫描到robot的距离
358 		 * 
359 		 * @name getDistance
360 		 * @function
361 		 * @memberOf tank.event.ScannedRobotEvent.prototype
362 		 * @return {String} 扫描到robot的距离
363 		 */			
364 		getDistance:function(){
365 			return this.distance;
366 		},
367 		/**获取扫描到robot的速度
368 		 * 
369 		 * @name getSpeed
370 		 * @function
371 		 * @memberOf tank.event.ScannedRobotEvent.prototype
372 		 * @return {Number} 扫描到robot的速度
373 		 */			
374 		getSpeed:function(){
375 			return this.speed;
376 		}
377 	}
378 	/**
379 	 * 胜利的事件
380 	 * @memberOf tank.event
381 	 * @class
382 	 * @name WinEvent
383 	 * @param {Object} options 初始化参数
384 	 * @return WinEvent实例
385 	 */			
386 	this.WinEvent=function(){}
387 	/**
388 	 * 获取到消息的事件
389 	 * @memberOf tank.event
390 	 * @class
391 	 * @name MessageEvent
392 	 * @param {Object} options 初始化参数
393 	 * @return MessageEvent实例
394 	 */			
395 	this.MessageEvent=function(options){
396 		this.sender=options.sender;
397 		this.message=options.message;
398 	};
399 	this.MessageEvent.prototype={
400 		/**获取消息发送者
401 		 * 
402 		 * @name getSender
403 		 * @function
404 		 * @memberOf tank.event.MessageEvent.prototype
405 		 * @return {Object} 获取消息发送者
406 		 */	
407 		getSender:function(){
408 			return this.sender;
409 		},
410 		/**获取消息
411 		 * 
412 		 * @name getMessage
413 		 * @function
414 		 * @memberOf tank.event.MessageEvent.prototype
415 		 * @return {Object} 获取消息
416 		 */			
417 		getMessage:function(){
418 			return this.message;
419 		}
420 	};
421 	/**
422 	 * 绘制事件对象
423 	 * @memberOf tank.event
424 	 * @class
425 	 * @name PaintEvent
426 	 * @param {Object} options 初始化参数
427 	 * @return PaintEvent实例
428 	 */		
429 	 this.PaintEvent=function(options){
430 	 	this.context=options.context;
431 	 };
432 	 this.PaintEvent.prototype={
433 		/**获取绘制的context元素
434 		 * 
435 		 * @name getContext
436 		 * @function
437 		 * @memberOf tank.event.PaintEvent.prototype
438 		 * @return {Object} 用于绘制的context
439 		 */	 	
440 	 	getContext:function(){
441 	 		return this.context;
442 	 	}
443 	 }
444 	/**
445 	 * 鼠标事件对象
446 	 * @memberOf tank.event
447 	 * @class
448 	 * @name MouseEvent
449 	 * @param {Object} options 初始化参数
450 	 * @return MouseEvent实例
451 	 */		
452 	 this.MouseEvent=function(options){
453 	 	this.pos=options.pos;
454 	 	this.button=options.button;
455 	 }
456 	 this.MouseEvent.prototype={
457 		/**获取鼠标相对canvas位置
458 		 * 
459 		 * @name getPos
460 		 * @function
461 		 * @memberOf tank.event.MouseEvent.prototype
462 		 * @return {Array} 鼠标相对canvas位置
463 		 */		 	
464 	 	getPos:function(){
465 	 		return this.pos;
466 	 	},
467 		/**获取鼠标点击button
468 		 * 
469 		 * @name getButton
470 		 * @function
471 		 * @memberOf tank.event.MouseEvent.prototype
472 		 * @return {String} 点击button
473 		 */			 	
474 	 	getButton:function(){
475 	 		return this.button;
476 	 	}
477 	 };
478 	/**
479 	 * 键盘事件对象
480 	 * @memberOf tank.event
481 	 * @class
482 	 * @name KeyEvent
483 	 * @param {Object} options 初始化参数
484 	 * @return KeyEvent实例
485 	 */		
486 	 this.KeyEvent=function(){
487 	 }
488 	 this.KeyEvent.prototype={
489 		/**获取某个键是否点击
490 		 * 
491 		 * @name getButton
492 		 * @function
493 		 * @memberOf tank.event.KeyEvent.prototype
494 		 * @return {Boolean} 某个键是否点击
495 		 */		 	
496 	 	isPressed:function(keyName){
497 	 		return J.cnGame.input.isPressed(keyName);
498 	 	}
499 	 };
500 	 this.notify=function(target,evtName,evtObj){
501 		var handlerName="on"+evtName.substring(0,1).toUpperCase( ) + evtName.substring(1);
502 		if(target.constructor.prototype.hasOwnProperty(handlerName)){
503 			
504 			if(evtName=="paint"){//paint事件特殊处理,不中断其他事件
505 				em.notify(target,evtName,evtObj);
506 				return;
507 			}
508 			if(target.currentEvtName&&config.eventPriority[evtName]<=config.eventPriority[target.currentEvtName])//事件优先级比较,高优先级中断低优先级
509 				return;
510 			target.isInterEvent=true;		
511 			target.stateManager.cleanEventStateList();//中断正在执行的其他事件处理
512 			target.currentEvtName=evtName;
513 			em.notify(target,evtName,evtObj);
514 			if(!target.stateManager.getEventListLength()){
515 				target.currentEvtName=null;
516 			}
517 			target.isInterEvent=false;
518 		}
519 	};
520 	/*	处理程序代理	*/
521 	this.subscribe=function(target,evtName,func){
522 		var handlerName="on"+evtName.substring(0,1).toUpperCase( ) + evtName.substring(1);
523 		if(target.constructor.prototype.hasOwnProperty(handlerName)){
524 			em.subscribe(target,evtName,function(){
525 				func.apply(this,arguments);
526 			},target);
527 		}
528 	};
529 	 
530 	this.bindOriHandler=function(target,evtName){
531 		var handlerName="on"+evtName.substring(0,1).toUpperCase( ) + evtName.substring(1);
532 		var evtObj;
533 		var btn;
534 		var input=J.cnGame.input;
535 
536 		if(target.constructor.prototype.hasOwnProperty(handlerName)){
537 
538 			cg.core.bindHandler(window,evtName.toLowerCase(),function(e){
539 				if(!gameObj.isStartBattle) return;
540 
541 				if(evtName=="mouseMove"&&target.currentEvtName&&target.currentEvtName!=evtName)//mouseMove不中断正在执行的事件
542 					return;
543 
544 				if(evtName=="mouseMove"||evtName=="click"||evtName=="mouseDown"||evtName=="mouseUp"){
545 					if(input.mouse.left_pressed) btn="left";
546 					if(input.mouse.right_pressed) btn="right";
547 
548 					evtObj=new tank.event.MouseEvent({
549 						pos:[input.mouse.x,input.mouse.y].slice(),
550 						button:btn
551 					});
552 				}
553 				else if(evtName=="keyDown"||evtName=="keyUp"){
554 					evtObj=new tank.event.KeyEvent();		
555 				}
556 				this.isInterEvent=true;
557 				this.currentEvtName=evtName;
558 				this.stateManager.cleanEventStateList();//中断正在执行的其他事件处理
559 				this[handlerName].call(this,evtObj);
560 				this.isInterEvent=false;
561 			},target);
562 			
563 		}
564 	};
565 	this.notifyBulletMissedEvent=function(bullet){
566 		this.notify(bullet.robot,"bulletMissed",new this.BulletMissedEvent({
567 			bullet:bullet
568 		}));
569 	};
570 	this.notifyBulletHitBulletEvent=function(bullet1,bullet2){
571 		//子弹和子弹相碰撞
572 		this.notify(bullet1.robot,"bulletHitBullet",new this.BulletHitBulletEvent({
573 			bullet:bullet1,
574 			hitBullet:bullet2
575 		}));
576 		
577 		this.notify(bullet2.robot,"bulletHitBullet",new this.BulletHitBulletEvent({
578 			bullet:bullet2,
579 			hitBullet:bullet1
580 		}));	
581 	};
582 	this.notifyBulletHitEvent=function(r,b){
583 		this.notify(b.robot,"bulletHit",new this.BulletHitEvent({
584 			name:r.getName(),
585 			energy:r.getEnergy(),
586 			bullet:b	
587 		}));
588 	};
589 	this.notifyHitByBulletEvent=function(r,b){
590 		this.notify(r,"hitByBullet",new this.HitByBulletEvent({
591 					bearing:r.getBearing(b),
592 					bullet:b
593 					
594 		}));
595 	};
596 	this.notifyDeathEvent=function(r){
597 		this.notify(r,"death",new this.DeathEvent({}));
598 	};
599 	this.notifyRobotDeathEvent=function(robotList,deadRobot){
600 		for(var m=0,len=robotList.length;m<len;m++){
601 			if(!robotList[m].isExplode)
602 				this.notify(robotList[m],"robotDeath",new this.RobotDeathEvent({name:deadRobot.name}));//robot死亡事件广而告之
603 		}
604 
605 	};
606 	this.notifyWinEvent=function(robotList){
607 		for(var k=0;k<robotList.length;k++){
608 			if(!robotList[k].isExplode)
609 				this.notify(robotList[k],"win",new this.WinEvent({}));//触发胜利事件 	
610 		}
611 	};
612 	this.notifyHitRobotEvent=function(r1,r2){
613 		this.notify(r1,"hitRobot",new this.HitRobotEvent({
614 			name:r2.getName(),
615 			bearing:r1.getBearing(r2),
616 			energy:r2.getEnergy()
617 		}));
618 		this.notify(r2,"hitRobot",new this.HitRobotEvent({
619 			name:r1.getName(),
620 			bearing:r2.getBearing(r1),
621 			energy:r1.getEnergy()
622 		}));				
623 	};
624 	this.notifyHitWallEvent=function(r,wallAngle){	
625 		var angle=wallAngle-r.getHeading();
626 		if(angle>180){
627 			angle=angle-360;
628 		}
629 		else if(angle<-180){
630 			angle=angle+360;
631 		}
632 		this.notify(r,"hitWall",new this.HitWallEvent({bearing:angle}));
633 	};
634 	this.notifyScannedRobotEvent=function(r,r1){
635 		this.notify(r,"scannedRobot",new this.ScannedRobotEvent({//扫描到其他robot的事件
636 			name:r1.getName(),
637 			energy:r1.getEnergy(),
638 			bearing:r.getBearing(r1),
639 			heading:r1.getHeading(),
640 			distance:r.getDistance(r1),
641 			speed:r1.getSpeed()
642 		}));
643 	};
644 	this.notifyMessageReceivedEvent=function(sender,robot,message){
645 		this.notify(robot,"messageReceived",new tank.event.MessageEvent({
646 			sender:sender,
647 			message:message
648 		}));		
649 	};
650 	this.notifyPaintEvent=function(robot,context){
651 		this.notify(robot,"paint",new tank.event.PaintEvent({
652 			context:context
653 		}));		
654 	};
655 
656 });
657 
658 
659