模仿cnGameJs写的简单的坦克大战

此次只简单地实现了地图的绘制和基本的碰撞检测,感觉如果再深一步写下去估计要花一年时间才能搞定,目前暂时只支持IE

很多地方的实现没有找到原作者的代码,只靠自己的一点想法简单的完成了类似的功能



















(function(){
	var _kdGame = {
			init:function(id,options){
				options = options || {};
				this.width = options.width||800;
				this.height = options.height||600;
				
			},
			addModule:function(moduleName,func){
				var moduleArray = moduleName.split('.');
				var parent = window;
				for(var i = 0;i< moduleArray.length;i++){
					if(typeof(parent[moduleArray[i]]) == 'undefined')
						parent[moduleArray[i]] = {};
					parent = parent[moduleArray[i]];
				}
				if(func)
					func.call(parent,this);
				return parent;
			}
	};
	
	
	
	
	kdGame = _kdGame;
	
	//添加一个功能模块 
	kdGame.addModule('kdGame.core',function(cg){
		this.name = "kdGameCore";
		this.$=function(id){
			return document.getElementById(id);		
		};
		this.$$=function(tagName,parent){
			parent=parent||document;
			return parent.getElementsByTagName(tagName);	
		};
		this.extend = function(des,sou){
			for(name in sou)
				des[name] = sou[name];
			return des;
		};
		this.bindHandler=(function(){
			if(window.addEventListener){
				return function(elem,type,handler){
					elem.addEventListener(type,handler,false);
				};
			}
			else if(window.attachEvent){
				return function(elem,type,handler){
					elem.attachEvent("on"+type,handler);
				};
			}
	})();

	this.removeHandler=(function(){
				if(window.removeEventListerner){
					return function(elem,type,handler){
						elem.removeEventListerner(type,handler,false);
						
					};
				}
				else if(window.detachEvent){
					return function(elem,type,handler){
						elem.detachEvent("on"+type,handler);
					};
				}
	})();
	/**获取指定元素在数组中的下标*/
	Array.prototype.indexOf = function(value){
		for ( var i = 0; i < this.length; i++) {
			if(this[i] == value)
				return i;
		}
		return -1;
	};
	});
	
	
	
	kdGame.addModule('kdGame',function(cg){
		var map = function(gameData){
				//判断用什么方式调用,this instanceof arguments.callee这种方式是用来判断是否是用new运算符调用的
				if(!(this instanceof arguments.callee)){
		            return new arguments.callee(gameData);
		        }
		   this.init(gameData);
		};
		map.prototype = {
				init:function(gameData){
					var defaults = {
							cellSize:[40,40],
							width:200,
							height:200,
							beginX:0,
							beginY:0
					};
					
					options = gameData.startOptions || {};
					options = cg.core.extend(defaults,options);
					this.mapMatrix = gameData.mapMatrix;
					this.cellSize = options.cellSize;
					this.beginX = options.beginX;
					this.beginY = options.beginY;
					this.width = options.width;
					this.height = options.height;
					this.srcObj = options.srcObj;
					this.srcArray = [];
					var i = 0;
					for(name in this.srcObj){
						this.srcArray[i] = this.srcObj[name]; 
						i++;
					}
				},
				getImg:function(type){
					if(!this.srcArray[type])
						this.srcArray[type] = "images/grass.png";
					return this.srcArray[type];
				},
				draw:function(){
					var cellHeight = this.cellSize[1];
					var cellWidth = this.cellSize[0];
					var beginY = this.beginY;
					var beginX = this.beginX;
					var selfPosition = this.selfPosition;
					var srcObj = this.srcObj;
					var curRow = 0;
					var curCol = 0;
					var curObj;
					var mapMatrix = this.mapMatrix;
					for(var i = beginY,len = beginY+mapMatrix.length*cellHeight;i < len ;i += cellHeight){
						curRow = (i-beginY)/cellHeight;
						for ( var j = 0,xlen = beginX+mapMatrix[j].length*cellWidth; j < xlen; j += cellWidth) {
							curCol = (j-beginX)/cellWidth;
							var curImg = document.createElement("img");
							curObj = this.getImg(mapMatrix[curRow][curCol]);
							curImg.src = curObj;
							curImg.style.position = 'absolute';
							curImg.style.left = j;
							curImg.style.top = i;
							curImg.id = "map"+j+i;
							curImg.cellType = mapMatrix[curRow][curCol];
							cg.core.$$('body')[0].appendChild(curImg);
						}
					}
				}
		};
		this.Map = map;
	});
	kdGame.addModule('kdGame.input',function(cg){
		var keydown_callbacks={};
		var keyup_callbacks={};
		
		var k=[];
		k[8] = "backspace",
		k[9] = "tab",
		k[13] = "enter",
		k[16] = "shift",
		k[17] = "ctrl",
		k[18] = "alt",
		k[19] = "pause",
		k[20] = "capslock",
		k[27] = "esc",
		k[32] = "space",
		k[33] = "pageup",
		k[34] = "pagedown",
		k[35] = "end",
		k[36] = "home",
		k[37] = "left",
		k[38] = "up",
		k[39] = "right",
		k[40] = "down" ,
		k[45] = "insert",
		k[46] = "delete",
		
		k[91] = "leftwindowkey",
		k[92] = "rightwindowkey",
		k[93] = "selectkey",
		k[106] = "multiply",
		k[107] = "add",
		k[109] = "subtract",
		k[110] = "decimalpoint",
		k[111] = "divide",
		
		k[144] = "numlock",
		k[145] = "scrollock",
		k[186] = "semicolon",
		k[187] = "equalsign",
		k[188] = "comma",
		k[189] = "dash",
		k[190] = "period",
		k[191] = "forwardslash",
		k[192] = "graveaccent",
		k[219] = "openbracket",
		k[220] = "backslash",
		k[221] = "closebracket",
		k[222] = "singlequote";
		
		var numpadkeys = ["numpad1","numpad2","numpad3","numpad4","numpad5","numpad6","numpad7","numpad8","numpad9"];
		var fkeys = ["f1","f2","f3","f4","f5","f6","f7","f8","f9"];
		var numbers = ["0","1","2","3","4","5","6","7","8","9"];
		var letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
		for(var i = 0; numbers[i]; i++)     { k[48+i] = numbers[i]; }
		for(var i = 0; letters[i]; i++)     { k[65+i] = letters[i]; }
		for(var i = 0; numpadkeys[i]; i++)  { k[96+i] = numpadkeys[i]; }
		for(var i = 0; fkeys[i]; i++)       { k[112+i] = fkeys[i]; }
		var timer; 
		var targetMove = function(eve){
			eve = eve||win.event;
			var keyname = k[eve.keyCode];
			//addKeyPressListener(keyname,listener);
			//keydown_callbacks[keyname]();
				var target = cg.core.$('targetPlayer');
				if(cg.player.dirs[cg.player.dir] != keyname){
					var n = cg.player.rotateAngle(keyname);
					target.style.filter =  'progid:DXImageTransform.Microsoft.BasicImage(rotation='+n+')';//旋转方向
					return;
				}
				var speed = cg.player.movespeed;
				switch(keyname){
					case "up": 
						if(cg.collision.isBottomTo(target))
							target.style.top = parseInt(target.style.top) - speed;
						break;	
					case "left": 
						if(cg.collision.isRightTo(target))
							target.style.left = parseInt(target.style.left) - speed;			
						break;	
					case "down":
						if(cg.collision.isTopTo(target))
							target.style.top = parseInt(target.style.top) + speed;
						break;	
					case "right": 
						if(cg.collision.isLeftTo(target))
							target.style.left = parseInt(target.style.left) + speed;						
						break;	
				}
		};
		var targetStopMove = function(eve){
			clearInterval(timer);
		};
		var addKeyPressListener = function(eventType,handler){
			keydown_callbacks[eventType] = handler;
		};
		
		
		cg.core.bindHandler(document,'keydown',targetMove);
		//cg.core.bindHandler(document,'keyup',targetStopMove);
	});
	
	kdGame.addModule('kdGame.collision',function(cg){
		//四个判断碰撞检测的方法有点冗余后面再优化
			this.isBottomTo = function(curObj){
				var curX = parseInt(curObj.style.left);
				var curY = parseInt(curObj.style.top);
				if(curX <= 0 || curY <= 0)
					return false;
				curObj.position = [curX,curY];
				if(curY%40!=0)
					return true;
				var nextObjX = curX;
				var nextObjY = curY-40;
				var result = false;
				if(nextObjX%40==0){
					result = this.isInner(nextObjX,nextObjY);
					if(!result)
						return result;
				}else{
					result = this.isInner(Math.floor(nextObjX/40)*40,nextObjY);
					if(!result)
						return result;
					result = this.isInner(Math.ceil(nextObjX/40)*40,nextObjY);
					if(!result)
						return result;
				}
				return true;
			};
			this.isRightTo = function(curObj){
				var curX = parseInt(curObj.style.left);
				var curY = parseInt(curObj.style.top);
				if(curX <= 0 || curY <= 0)
					return false;
				curObj.position = [curX,curY];
				if(curX%40!=0)//如果已经进入了一个单位,则不需要继续碰撞检测
					return true;
				var nextObjX = curX-40;
				var nextObjY = curY;
				var result = false;
				if(nextObjY%40==0){
					result = this.isInner(nextObjX,nextObjY);
					if(!result)
						return result;
				}else{
					result = this.isInner(nextObjX,Math.floor(nextObjY/40)*40);
					if(!result)
						return result;
					result = this.isInner(nextObjX,Math.ceil(nextObjY/40)*40);
					if(!result)
						return result;
				}
				return true;
			};
			this.isTopTo = function(curObj){
				var curX = parseInt(curObj.style.left);
				var curY = parseInt(curObj.style.top);
				if(curX <= 0 || curY <= 0)
					return false;
				curObj.position = [curX,curY];
				if(curY%40!=0)
					return true;
				var nextObjX = curX;
				var nextObjY = curY+40;
				var result = false;
				if(nextObjX%40==0){
					result = this.isInner(nextObjX,nextObjY);
					if(!result)
						return result;
				}else{
					result = this.isInner(Math.floor(nextObjX/40)*40,nextObjY);
					if(!result)
						return result;
					result = this.isInner(Math.ceil(nextObjX/40)*40,nextObjY);
					if(!result)
						return result;
				}
				return true;
			};
			this.isLeftTo = function(curObj){
				var curX = parseInt(curObj.style.left);
				var curY = parseInt(curObj.style.top);
				if(curX <= 0 || curY <= 0)
					return false;
				curObj.position = [curX,curY];
				if(curX%40!=0)//如果已经进入了一个单位,则不需要继续碰撞检测
					return true;
				var nextObjX = curX+40;
				var nextObjY = curY;
				var result = false;
				if(nextObjY%40==0){
					result = this.isInner(nextObjX,nextObjY);
					if(!result)
						return result;
				}else{
					result = this.isInner(nextObjX,Math.floor(nextObjY/40)*40);
					if(!result)
						return result;
					result = this.isInner(nextObjX,Math.ceil(nextObjY/40)*40);
					if(!result)
						return result;
				}
				return true;
			};
			this.isInner = function(nextObjX,nextObjY){
				var nextObj = cg.core.$('map'+nextObjX+nextObjY);
				if(nextObj && nextObj.cellType == 3){
					alert("you are the winner");
					return true;
				}
				if(nextObj && nextObj.cellType!=0){
					return false;					
				}
				return true;
			};
	});
	
	//add player
	kdGame.addModule('kdGame.player',function(cg){
		this.init = function(playerObj){
					var defaults = {
						icon:'images/player1.png',
						name:'palyer1',
						position:[0,0],
						dir:0,
						movespeed:10
					};
					var options = defaults || {};
					options = cg.core.extend(options,playerObj);
					this.icon = options.icon;
					this.name = options.name;
					this.dir = options.dir;
					this.movespeed = options.movespeed;
					this.position = options.selfPosition;
					this.dirs = ['left','up','right','down'];
					this.draw();
				};
			this.draw = function(){
					var selfPosition = this.position;
					var curImg = document.createElement("img");
					curImg.id = "targetPlayer";
					curImg.src = this.icon;
					curImg.style.position = 'absolute';
					curImg.style.left = selfPosition[0];
					curImg.style.top = selfPosition[1];
					kdGame.core.$$('body')[0].appendChild(curImg);
				};
				this.rotateAngle = function(dir){
					var nextDir = this.dirs.indexOf(dir);
					this.dir = nextDir;
					return nextDir;
				};
	});
	
})();



var gameData = {
		/* 地图矩阵:0.空地 1.墙壁 2.石头 3.目的地 4.敌人基地*/
		mapMatrix:[
														[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
														[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1],
														[1,0,1,0,0,2,2,0,0,0,2,2,0,0,0,1],
														[1,0,1,0,0,0,2,0,0,0,4,0,0,0,2,1],
														[1,0,1,0,0,0,0,0,2,0,0,0,0,0,0,1],
														[1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,1],
														[1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1],
														[1,1,1,1,1,1,1,0,0,0,1,1,1,2,0,1],
														[1,0,0,0,0,2,0,0,0,1,1,3,0,0,0,1],
														[1,0,0,0,0,2,0,2,0,0,1,0,0,0,0,1],
														[1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1],
														[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
			   					],
	 startOptions:{
	   			//游戏资源字典
	   		srcObj:{
	   			ground:"images/desert2.png",
	   			wall:"images/wall.png",
	   			stone:"images/stone1.png",
	   			destination:"images/destination.png",
	   			source:"images/source.png",
	   			bullet:"images/bullet1.png",
	   			goods:"images/goods.png",
	   			boom:"images/boom.png",
	   			enemy:"images/enemy2.png",
   				player:"images/player1.png"
	   		},
  		movespeed:10
	   }
};			   
var playerObj = {//玩家对象
		name:'liubei',
		selfPosition:[360,360],
		movespeed:10
};
var mapObj = new kdGame.Map(gameData); //地图对象
function startGame(){
	mapObj.draw();	
	var player = kdGame.player.init(playerObj);
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值