JS游戏开发--人物移动

最近花了两周的时间研究了如何用JS开发一个类似梦幻西游,英雄联盟这种操作模式的Web游戏,通过鼠标右键点击行走,并且地图可以跟随人物的移动而不断的移动。

看一下效果:

demo1:

http://www.njhhsj.com/Game/Jianye/

操作:右键点击移动

 

demo2:

http://www.njhhsj.com/Game/mxd/

操作,A键左移,D键右移,空格键攻击。


这个demo的开发花了我挺长时间的,也参考了许多论坛上游戏爱好者的思维方式。
下面我将总结一下我开发过程中是如何实现的,防止以后自己忘了,哈哈~,主要是几个我花了很长时间思考的部分。
主要展示三个部分:
在总结前先给出一张我的思考图,如图把一张地图划分成九个区域,分别标上字母,灰色地区为窗口区域。

JS游戏开发--人物移动_第1张图片

A、B、C、D分别为窗口的左上、左下、右下、右上的四分之一区域,并且在A、B、C、D区域中可以自由移动,人物初始化时在A区中。

以X轴方向移动为例:

1.从A进入D1区域(两条竖着的红线之间的区域)并且继续往右移动时,先到达窗口的二分之一位置也就是红线所在位置,停止人物的移动,切换成地图往左移动,当地图往左一直移动到右边界时,人物进入D区域切换成自由移动,地图到达最右边停止移动。
2.当往左移动时,从D进入D1区域,方法一样,而当人物在D1区域左右移动时中,只需要往反方向移动地图即可,之后再判断是否进入左右边界即可。

人物在Y轴上移动原理是一样的。

变量展示:

 	
        var last_X = 500  // 当前人物图片X轴坐标
           ,last_Y = 300  // 当前人物图片Y轴坐标
           ,Des_x = 547   // 需要人物图片X轴坐标
           ,Des_y = 395   // 需要人物图片Y轴坐标

           ,Cur_x = 547   // 人物脚底需要移动到的X坐标
           ,Cur_y = 395   // 人物脚底需要移动到的坐标
           ,Orz_x = 547   // 当前人物脚底X坐标
           ,Orz_y = 395   // 当前人物脚底Y坐标

           ,n = 0
           ,img_url
           ,m_role_mx = 0  // X轴速度分量
           ,m_role_my = 0  // Y轴速度分量
           ,angle
           ,mapx_shift = 0 // 地图X轴移动量
           ,mapy_shift = 0 // 地图Y轴移动量
           ,PI = 3.141592653
           ,SPEED = 6
           ,dtn = null
           ,inlx = 0       // 人物X轴移动量
           ,inly = 0       // 人物Y轴移动量
           ,angle_D;

人物移动

当点击地图时获取人物的X,Y轴的偏移量inlx,inly,然后分别进行人物X,Y轴的区域判断,分别进行加操作,偏移量为0结束移动,

// 角色移动
	        MoveRole : function(){

        	    var _this = gameMonitor;
                // 人物X轴状态
                if(inlx > 0){
                	
	                // A区域
	                if(Orz_x < w/2 && Orz_x > 0 && gameMonitor.mapX == 0 && gameMonitor.mapY == 0){
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;	 
	            	  	if(Orz_x > w/2){
                            Orz_x = w/2;
	            	    }    
                    // B区域
	                }else if(Orz_x < w/2 && Orz_x > 0 && gameMonitor.mapX == 0 && gameMonitor.mapY == -(_this.bgHeight-h)){
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;	 
                    // C区域
	            	}else if(Orz_x > w/2 && Orz_x < w && gameMonitor.mapY == -(_this.bgHeight-h) && gameMonitor.mapX == -(_this.bgWidth-w)){
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;	             	
	            	 // D区域
	                }else if(Orz_x > w/2 && Orz_x < w && gameMonitor.mapY == 0 && gameMonitor.mapX == -(_this.bgWidth-w)){
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;

                    // A1区域
	                }else if(Orz_x < w/2 && Orz_x > 0 && gameMonitor.mapX == 0 && gameMonitor.mapY < 0 && gameMonitor.mapY > -(_this.bgHeight-h)){
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;	
	            	    if(Orz_x > w/2){
                            Orz_x = w/2;
	            	    }            
                    // C1区域
	            	}else if(Orz_x > w/2 && Orz_x < w && gameMonitor.mapX == -(_this.bgWidth-w) && gameMonitor.mapY < 0 && gameMonitor.mapY > -(_this.bgHeight-h)){	            
	                	inlx -= Math.abs(m_role_mx);	                
	                	last_X += m_role_mx;	        
	            	    Orz_x += m_role_mx;	
	                
	                // E区域地图移动
	            	}else{ // 人物X轴超出窗口一半区域             
                        Orz_x = w/2;
	                    mapx_shift = inlx;
	                    inlx = 0;
	                }

                }else{
                	inlx = 0;
                }

                // 人物Y轴状态
                if(inly > 0){
                 
	                // A区域
	                if(0 < Orz_y && Orz_y < h/2 && gameMonitor.mapX == 0 && gameMonitor.mapY == 0){ 
	          
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my;
	            	    if(Orz_y > h/2){
                            Orz_y = h/2;
	            	    }
                    // B区域
	                }else if(h/2 < Orz_y && Orz_y < h && gameMonitor.mapX == 0 && gameMonitor.mapY == -(_this.bgHeight-h)){	                	
                    
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my;   

                    // C区域
	            	}else if(Orz_y > h/2 && Orz_y < h && gameMonitor.mapY == -(_this.bgHeight-h) && gameMonitor.mapX == -(_this.bgWidth-w)){
	              
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my;  

                    // D区域
	                }else if(Orz_y > 0 && Orz_y < h/2 && gameMonitor.mapY == 0 && gameMonitor.mapX == -(_this.bgWidth-w)){
	             
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my; 
	            	    if(Orz_y > h/2){
                            Orz_y = h/2;
	            	    } 
                    // D1区域
	                }else if(0 < Orz_y && Orz_y < h/2 && gameMonitor.mapY == 0 && gameMonitor.mapX < 0 && gameMonitor.mapX > -(_this.bgWidth-w)){
	               
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my;           
	            	    if(Orz_y > h/2){
                            Orz_y = h/2;
	            	    } 
	            	// B1区域
	                }else if(Orz_y > h/2 && Orz_y < h && gameMonitor.mapY == -(_this.bgHeight-h) && gameMonitor.mapX < 0 && gameMonitor.mapX > -(_this.bgWidth-w)){
	                	// console.log("B1区域"+Orz_y)
	                	inly -= Math.abs(m_role_my);
	            	    last_Y += m_role_my;          	
	            	    Orz_y += m_role_my;  
                    
                    // E区域地图移动
	            	}else{ 	          
	            		Orz_y = h/2;
	                    mapy_shift = inly;
	                    inly = 0;
	                }	                
                }else{
                	inly = 0;
                }

                _this.MoveRoleImage(); // 人物八方位移动图切换
                
                // 绘制角色
                _this.hero.paint(img_url,last_X,last_Y);

	        },

 

地图移动:


地图的移动X,Y轴是从(0,0)到(-(地图宽度-窗口宽度),-(地图高度-地图高度))这个范围。
当地图接收到偏移量mapx_shift,mapy_shift之后,开始移动,知道偏移量为0结束移动。

  // 地图移动
	        MoveImage : function(ctx){
                var _this = gameMonitor;

                //地图X轴需要移动
                if(mapx_shift > 0){
                    mapx_shift -= Math.abs(m_role_mx);
                    gameMonitor.mapX -= m_role_mx;

            
                    if(gameMonitor.mapX > 0){
                    	gameMonitor.mapX = 0;
                    }
                    if(gameMonitor.mapX < (-(_this.bgWidth-w))){
                    	gameMonitor.mapX = (-(_this.bgWidth-w));
                    }

                    if(gameMonitor.mapX == 0){  // 到达左边界
                        _this.IsLeftBorder();
                    } 

                    if(gameMonitor.mapX == (-(_this.bgWidth-w))){ // 到达右边界
                        _this.IsRightBorder();
                    } 

                }else{
                	mapx_shift = 0;
                }

                //地图Y轴需要移动
                if(mapy_shift > 0){
                
                	mapy_shift -= Math.abs(m_role_my);                   
                    gameMonitor.mapY -= m_role_my;

                    if(gameMonitor.mapY > 0){
                    	gameMonitor.mapY = 0;
                    }
                    if(gameMonitor.mapY < (-(_this.bgHeight-h))){
                    	gameMonitor.mapY = (-(_this.bgHeight-h));
                    }                    
             
                    if(gameMonitor.mapY == 0){  // 到达上边界
                        _this.IsTopBorder();
                    } 

                    if(gameMonitor.mapY == (-(_this.bgHeight-h))){ // 到达下边界
                        _this.IsBottomBorder();
                    }                      

                }else{
                	 mapy_shift = 0;
                }
                
                // 绘制背景
				ctx.drawImage(img, gameMonitor.mapX, gameMonitor.mapY);

                
	        },

 

边界处理


当进行跨区域操作时将人物偏移量inlx,inly赋值给地图的偏移量mapx_shift,mapy_shift让地图继续接替运动。
当人物进入到自由移动区域时,同样将地图偏移量mapx_shift,mapy_shift返给人物偏移量inlx,inly,接替运动。

	        // 是否在左边界
	        IsLeftBorder : function(){
	        	var _this = gameMonitor;
	        	console.log("=====进入左边界====")      
            	Orz_x = w/2 - 1;
            	inlx = mapx_shift;
            	if(mapy_shift > 0){
            		inly = mapy_shift;          		
            	} 
            	mapx_shift = 0;
            	mapy_shift = 0;
	        },
	        // 是否在右边界
	        IsRightBorder : function(){
	        	var _this = gameMonitor;
	        	console.log("====进入右边界====")
            	Orz_x = w/2 + 1;   
            	inlx = mapx_shift;
            	if(mapy_shift > 0){
            		inly = mapy_shift;          		
            	} 
            	mapx_shift = 0;
            	mapy_shift = 0;
	        },
	        // 是否在上边界
	        IsTopBorder : function(){
	        	var _this = gameMonitor;
	        	console.log("====进入上边界====")
            	Orz_y = h/2 - 1;      
            	if(mapx_shift > 0){
            		inlx = mapx_shift;          		
            	}           	
            	inly = mapy_shift;
            	mapx_shift = 0;
            	mapy_shift = 0;
	        },
	        // 是否在下边界
	        IsBottomBorder : function(){
	        	var _this = gameMonitor;
	        	console.log("====进入下边界====")
            	Orz_y = h/2 + 1;    
            	if(mapx_shift > 0){
            		inlx = mapx_shift;          		
            	}
            	inly = mapy_shift;
            	mapx_shift = 0;
            	mapy_shift = 0;
	        },

最后再分享一个参考链接,这篇文章我也看了三四遍,由于语言不同,理解起来也不同。

https://blog.csdn.net/crocodile__/article/details/18039107

你可能感兴趣的:(学习笔记)