thml5+js 实现简单的2d引擎

没错,我就是个标题党,被骗进来来了吧。。。大笑大笑

说是个引擎有点夸张,这只是一个小小的小玩意儿。

好了,不 che dan 了。 


开始正文吧:

先上效果,有兴趣才有看下去的动力。

其实效果也一般啦。。碰撞检查还是有点问题,还请大神们指出。


接下来就是代码了,有点长,这代表我没有藏着掖着。。(就你这垃圾玩意还想藏着)


第一个是一个公用的文件,核心功能都在这里面

/* creat by clzmin
   2016.07.30
   canvas frameWork
*/

/*数据层
T:工具类
P:图形类*/
(function(window){
     //工具部分 //
   var T={
      Vector2:function(x,y){
        if(x){
          this.x=x;
        }else{
          this.x=0;
        }
        if(y){
          this.y=y;
        }else{
          this.y=0;
        } 
         this.Distance=function(otherVec2){
          if(otherVec2 instanceof T.Vector2){
               return Math.sqrt((this.x-otherVec2.x)*(this.x-otherVec2.x)+(this.y-otherVec2.y)*(this.y-otherVec2.y));
           }else{
            return -1;
           }
         }
         this.MultiDistance=function(otherVec2){
            if(otherVec2 instanceof T.Vector2){
               return (this.x-otherVec2.x)*(this.x-otherVec2.x)+(this.y-otherVec2.y)*(this.y-otherVec2.y);
           }else{
            return -1;
           }
         }
         this.Rotation=function(sin,cos){
              var temp=new T.Vector2(); 
              temp.x = this.x * cos - this.y * sin;
              temp.y = this.y * cos + this.x * sin;
              return temp;
         }
      }
   }
  /  对象部分 /
       var objcount=0;
       var AllObj=new Array();
       var CanSeeObj=new Array();
    //vanvas类中自己定义的物体类
    var P={
        //参数顺序: type 
       SpuerObj:function(){
         objcount++;
        //初始化值
        if(arguments[0])
         this.ObjType=arguments[0];
        else  
         this.ObjType="SpuerObj";
         this.id=objcount;
         this.IsActive=true;
         //全局操作
         AllObj.push(this);
       
         this.drawSelf=function(){}
         this.IsSelf=function(){}
         //释放该对象
         this.Destroy=function(){
          for(var i=0,k=AllObj.length;i<k;i++){
                if(AllObj[i].id && AllObj[i].id==this.id){
                   AllObj[i]=null;
                   AllObj.splice(i, 1);
                   break;
                }
          }
          objcount--;
         }

       },
       Line:function(start,end){
            P.SpuerObj.call(this,"Line");
             if(start instanceof T.Vector2 && end instanceof T.Vector2){
                 this.start=start;
                 this.end=end;
             }
             this.drawSelf=function(canvas){
              canvas.drawLine(this.start.x,this.start.y, this.end.x, this.end.y);
             }
             this.isSelf=function(mousePosition){
                if(mousePosition instanceof T.Vector2 ){
                     var rate=(this.end.y-this.start.y)/(this.end.x-this.start.x);
                     var mouserate=(mousePosition.y-this.start.y)/(mousePosition.x-this.start.x);
                     return Math.abs(mouserate-rate)<0.00001?true:false;
                }
                return false;
             }

       },
       Circle:function(position,reduice){
          P.SpuerObj.call(this,"Circle");
         if(position && position instanceof T.Vector2 ){
              this.position= position;
         }else{
              this.position= new T.Vector2(0,0);
         }
          if( reduice){
           this.reduice=reduice;
          }else{
             this.reduice=1;
          }
          this.drawSelf=function(canvas){
              canvas.drawCircle(this.position.x,this.position.y,this.reduice,0,2*Math.PI,true);
          }

          this.IsSelf=function(mousePosition){
               if(mousePosition instanceof T.Vector2 ){
                  var distancore= Math.pow(this.position.x-mousePosition.x, 2)+ Math.pow(this.position.y-mousePosition.y, 2);
                  if(distancore>Math.pow(this.reduice,2))return false;
                  else return true;
               }
          }
          this.CheckColider=function(otherCircle){
              if(otherCircle.ObjType=="Circle"){
                  var reduicedistance=(otherCircle.reduice+this.reduice)*(otherCircle.reduice+this.reduice);
                  var multidistance = this.position.MultiDistance(otherCircle.position);
                  if( multidistance!=-1 && multidistance <= reduicedistance) return true;
                  else return false;
              }else{

                return false;
              }

          }
       },
       Rect:function(position,width,height){
           P.SpuerObj.call(this,"Rect");
          if(position instanceof T.Vector2)
             this.position= position;
           this.width=width;
           this.height=height;
           this.startPosition=new T.Vector2(this.position.x-this.width*0.5,this.position.y+this.height*0.5);
           this.drawSelf=function(canvas,self){
              canvas.drawRect(this.startPosition.x,this.startPosition.y,this.width,this.height);
          }
       },
       Triangle:function(a,b,c){
          P.SpuerObj.call(this,"Triangle");
            if(a instanceof T.Vector2 && b instanceof T.Vector2 && c instanceof T.Vector2){
               this.a=a;
               this.b=b;
               this.c=c;
            }
            
            this.drawSelf=function(canvas){
              canvas.drawLine(this.a.x,this.a.y,this.b.x,this.b.y);
              canvas.drawLine(this.b.x,this.b.y,this.c.x,this.c.y);
              canvas.drawLine(this.c.x,this.c.y,this.a.x,this.a.y);
          }   
       }
    }
    window.ObjData={
        allObj:AllObj,
        CanvasObj:P,
        CanvasTool:T
    }
})(window);


/*行为层
  C:全局配置
*/
(function(window) {
   // version1.0 /
	var context;
  var canvasElemnet;
  var frmaquery= Math.ceil(1000/30);
  var C={
    width:0,
    height:0,
    top:0,
    left:0
  }
	function canvas(id) {
		return new canvas.prototype.inte(id);
	}
	canvas.prototype = {

    context:context,

    Config:C,

		inte: function(id) {
			if (id && typeof id === "string"&& document.getElementById(id)) {
				 canvasElemnet = document.getElementById(id);
         C.width=canvasElemnet.width;
         C.height=canvasElemnet.height;
         UpdataTopAndLeft(canvasElemnet);
         OnScroll();
				if (canvasElemnet.nodeName.toLowerCase()=="canvas") {
					context=canvasElemnet.getContext("2d");
				}else throw new Error("search canvas is errro");
			}else throw new Error("id error");
		},

		drawLine:function(Sx,Sy,Ex,Ey,width,color,lineCap,lineJoin){
           context.beginPath();
           context.moveTo(Sx,Sy);
           context.lineTo(Ex,Ey);
           context.lineWidth=width?width:1;
           context.strokeStyle=color?color:"#30E99C";
           context.lineCap=lineCap?lineCap:"round";
           context.lineJoin=lineJoin?lineJoin:"round";
           context.closePath();
           context.stroke();
           return this;
		},

		drawCircle:function(x,y,r,sAngle,eAngle,counterclockwise,color,width,fill,count,offsetX,offSetY){
           context.beginPath();
           if(Object.prototype.toString.call(x) === "[object Array]"){
           	    x.forEach( function(element, index) {
           	    	 context.beginPath();
           	    	 var tempx=element[0];
           	    	 var tempy=element[1];
           	    	 var tempr=element[2];
           	    	 var tempsAngle=element[3];
           	    	 var tempeAngle=element[4];
           	    	 var tempcounterclockwise=element[5];
           	    	 context.arc(tempx,tempy,tempr,tempsAngle,tempeAngle,tempcounterclockwise); 
                     var tempcolor=element[6]?element[6]:"#30E99C";
                     context.strokeStyle=tempcolor;
                     if(element[7]) context.fillStyle=element[7];
                     context.lineWidth=element[8]?element[8]:1;
                     context.stroke();
           	    });
           	    return this;
           }
           if(typeof count ==="number"){
           	  for(var i=0,k=Math.abs(count);i<k;i++){
           	  	 context.beginPath();
           	  	context.arc(x+offsetX*i,y+offSetY*i,r,sAngle,eAngle,counterclockwise);
           	  	var tempcolor=color?color:"#30E99C";
                context.strokeStyle=tempcolor;
                context.lineWidth=width?width:1;
                if(fill) context.fillStyle=fill;
                 context.stroke();
           	  }
           }else if(typeof count ==="undefined"){
              context.arc(x,y,r,sAngle,eAngle,counterclockwise); 
              	var tempcolor=color?color:"#30E99C";
                context.strokeStyle=tempcolor;
                context.lineWidth=width?width:1;
                if(fill) context.fillStyle=fill; 
                context.stroke();
           }
           return this;
		},

    drawRect:function(x,y,width,height){
          context.beginPath();
          context.strokeRect(x,y,width,height);
    },

    RenderObj:function(){
      context.clearRect(0,0,C.width,C.height);
      var allObj=new Array();
      do{
        if(typeof arguments[0] =="undefined"){
           allObj=ObjData.allObj;
           break;
       }
       if(typeof arguments[0] =="object"){
          allObj.push(arguments[0]);
          break;
       }
       if(Object.prototype.toString.call(arguments[0]) === "[object Array]"){
          allObj=arguments[0];
           break;
       }
      }while(false);
         allObj.forEach(function(obj){
              if(obj.IsActive && obj.drawSelf instanceof Function){
                  obj.drawSelf(canvas.prototype);
              }
          });
    },

    GetSelecObj:function(mousePosition){
       var allObj=ObjData.allObj;
       var selecObjs=new Array();
         if(mousePosition instanceof ObjData.CanvasTool.Vector2){
            mousePosition.x=mousePosition.x-C.left;
            mousePosition.y=mousePosition.y-C.top;
            allObj.forEach(function(obj){
              if(obj.IsActive && obj.IsSelf instanceof Function){
               if(obj.IsSelf(mousePosition)) selecObjs.push(obj);
              }
          });
         }
         return selecObjs;
    },

    StartEvevnt:function(){
       var envet=["click","mouseup","mousedown","scroll"];
       envet.forEach(function(obj){
          AddEvent(obj, canvasElemnet);
       });
    }
	}
  
	canvas.prototype.inte.prototype = canvas.prototype;
	window.canvas = canvas;

  //补充内容,都以函数形式来写
  function UpdataTopAndLeft(canvasElemnet){
     var rect=Tools.getBoundingClientRect(canvasElemnet);
         C.top=rect.top;
         C.left=rect.left;
  }

  function OnScroll(){
      document.addEventListener("scroll", function(event){
        event.preventDefault();
        UpdataTopAndLeft(canvasElemnet);
      });
  }

  //事件系统
  function AddEvent(type, canvasElemnet) {
    if (typeof type != "string") return;
    type = type.toLowerCase().replace("on", "");
    if (window.addEventListener) {
      canvasElemnet.addEventListener(type, EventLiten);
    }
    else {
      type = "on" + type;
      canvasElemnet.attachEvent(type, EventLiten);
    }

    function EventLiten(event) {
      event.preventDefault();
      var obj = canvas.prototype.GetSelecObj(new ObjData.CanvasTool.Vector2(event.clientX, event.clientY));
      type = type.replace("on", "");
      type = "on" + type;
      obj.forEach( function(element, index) {  
        if (type in element || element.hasOwnProperty(type)) {
        if (typeof element[type] === "function") {
          element[type].call(this,event);
         }
        }
      });
    }
  }
   

})(window);



//工具函数 Tools.方法名
   + function() {
     var Tools={
         getBoundingClientRect:function(element) {
         var scrollTop = document.documentElement.scrollTop;
         var scrollLeft = document.documentElement.scrollLeft;
         if (element.getBoundingClientRect) {
           if (typeof arguments.callee.offset != "number") {
             var temp = document.createElement("div");
             temp.style.cssText = "position:absolute;top:0px;left:0px;";
             document.body.appendChild(temp);
             arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop;
             document.body.removeChild(temp);
             temp = null;
           }
           var rect = element.getBoundingClientRect();
           var offset = arguments.callee.offset;
           return {
             left: rect.left + offset,
             right: rect.right + offset,
             top: rect.top + offset,
             bottom: rect.bottom + offset
           }
         } else {
           var acutaLeft = Tools.getElemntLeft(element);
           var acutaTop = Tools.getElementTop(element);
           return {
             left: acutaLeft - scrollLeft,
             right: acutaLeft + element.offsetWidth - scrollLeft,
             top: acutaTop - scrollTop,
             bottom: acutaTop + element.offsetHeight - scrollTop
           }
         }
       },
          getElementTop:function(element){
              var actuaTop=element.offsetTop;
              var current=element.offsetParent;
              while(current!==null){
                  actuaTop+=current.offsetTop;
                   current=current.offsetParent;
              }
              return actuaTop;
          },
          getElemntLeft:function(element){
              var actuaLeft=element.offsetLeft;
              var current=element.offsetParent;
              while(current!==null){
                  actuaLeft+=current.offsetLeft;
                  current=current.offsetParent;
              }
              return actuaLeft;
          }
     }
     window.Tools=Tools;
   }();


下面一个是界面的逻辑文件,画圈圈与碰撞检测都是在这里面完成的。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>cnvers</title>
	<script src="common/canvas.js"></script>
	<style>
	    .contaner{
           width:30px;
		   
		}
	</style>
</head>
<body height="100%">
	  <div>
             <canvas height="768" width="1024" id="canvas" style=" border: 1px solid red;"> youre browers don't surrpost canvas, please use chorme</canvas>
	  </div>
</body>
<script>
     var frmacout=30;
     var frmaquery= Math.ceil(1000/30);
     var canva=canvas("canvas");
     +function(){
     	var T=ObjData.CanvasTool;
     	var P=ObjData.CanvasObj;
     	var moveCircles=new Array();

         function MoveCirCles(speed,position,reduice){
          P.Circle.call(this);
          moveCircles.push(this);
          if(position instanceof  T.Vector2){
              this.position=position;
           }
          this.speed=new T.Vector2(0,0);
          if(speed instanceof  T.Vector2){
              this.speed=speed;
           }
           this.reduice=reduice;
           this.Move=function(speed){
            if( speed && speed instanceof T.Vector2){
              this.position.x+=(speed.x)/frmacout;
              this.position.y+=(speed.y)/frmacout;
             }else{
              this.position.x+=(this.speed.x)/frmacout;
              this.position.y+=(this.speed.y)/frmacout;
             }
           }
         }

         var creat=setInterval(function(){
              var circleone=new MoveCirCles(new T.Vector2(Math.random()*300,Math.random()*300),new T.Vector2(Math.random()*500,Math.random()*500),30);
              if(moveCircles.length>30){
              	clearInterval(creat);
              }
         },1000);

          
          // 	var BeziCircles=new Array();

          // 	function BeziCircle( start, beizipos, endpos){
          //      P.Circle.call(this);
          //      BeziCircles.push(this);
          //      this.position=start;
          //      this.cazhi=0.0;
          //      this.endpos=endpos;
          //      this.beizipos=beizipos;
               
          //      this.Move=function(){
          //         this.position.x=(1.0- this.cazhi)*(1.0- this.cazhi)*start.x+2.0*this.cazhi*(1.0- this.cazhi)*beizipos.x+this.cazhi*this.cazhi*endpos.x;
          //         this.position.y=(1.0- this.cazhi)*(1.0- this.cazhi)*start.y+2.0*this.cazhi*(1.0- this.cazhi)*beizipos.y+this.cazhi*this.cazhi*endpos.y;
          //         var cicl=new P.Circle(new T.Vector2(this.position.x,this.position.y));
          //      }
          // 	}
          // var bezicir=new BeziCircle(new T.Vector2(100.0,100.0), new T.Vector2(250.0,100.0),new T.Vector2(300.0,300.0));
          //  var cicl=new P.Circle(new T.Vector2(100,100));
          //  cicl.reduice=5;
          //  var cicl=new P.Circle(new T.Vector2(250,100));
          //  cicl.reduice=5;
          //  var cicl=new P.Circle(new T.Vector2(300,300));
          //  cicl.reduice=5;
     window.οnlοad=function(){
        +function(){
        	Updata();
	 		    Render();
        timer=setTimeout(arguments.callee, frmaquery);
	 	}();
	 
     function Render(){
       canva.RenderObj();
     }
     function Updata(){
     	// if(bezicir.cazhi>1){
      //      bezicir.cazhi=1;		
     	// }else {
     	// 	bezicir.Move();
     	// }
     	// bezicir.cazhi+=(1.0/300.0);

     	    for (var i = moveCircles.length - 1; i >= 0; i--) {
            	 IsRechFrige(moveCircles[i],canva);
                 moveCircles[i].Move();
            } 
           for (var i = moveCircles.length - 1; i >= 1; i--) {
             	for (var j = i - 1; j >= 0; j--) {
             		if(moveCircles[i].CheckColider(moveCircles[j])){
             			 var reduice=moveCircles[j].position.Distance(moveCircles[i]);
                         var sin=(moveCircles[j].y-moveCircles[i].y)/reduice;
                         var cos=(moveCircles[j].x-moveCircles[i].x)/reduice;
                         var speedi=new T.Vector2(moveCircles[i].speed.x,moveCircles[i].speed.y);
                         var speedj=new T.Vector2(moveCircles[j].speed.x,moveCircles[j].speed.y);
                         moveCircles[i].speed.Rotation(sin,cos);
                         moveCircles[j].speed.Rotation(sin,cos);
                         moveCircles[i].speed.x=-moveCircles[i].speed.x;
                         moveCircles[j].speed.x=-moveCircles[j].speed.x;
                         while(moveCircles[i].CheckColider(moveCircles[j])){
                         	moveCircles[i].Move(-speedi.x,-speedi.y);
                         	moveCircles[j].Move(-speedj.x,-speedj.y);
                         }
             		}
             	}
             }
         }
       }
     }();

     function IsRechFrige(circle,canvas){
       if(circle.position.x-circle.reduice<=0){
       	  circle.speed.x = Math.abs(circle.speed.x);
       }
       if(circle.position.x+circle.reduice>=canvas.Config.width){
       	  circle.speed.x = -Math.abs(circle.speed.x);
       }
       if(circle.position.y-circle.reduice<=0){
       	  circle.speed.y = Math.abs(circle.speed.y);
       }
       if(circle.position.y+circle.reduice>canvas.Config.height){
           circle.speed.y = -Math.abs(circle.speed.y);
       }
     }
</script>
</html>
如果不出意外,ctrl + c ,ctrl + v 应该是能运行起来的。 不过实际效果还是要看人品的。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值