>  기사  >  웹 프론트엔드  >  원 버블 게임을 위한 HTML5 코드 공유

원 버블 게임을 위한 HTML5 코드 공유

黄舟
黄舟원래의
2017-03-24 15:29:403249검색

기능 설명:

1분 이내에 마우스 왼쪽 버튼을 사용하여 캔버스의 거품에 원을 그리세요 거품의 포인트는 10(흰색), 20(하늘색), 30(노란색), -10(빨간색), -20(녹색), -30(진한 파란색)이며 한 번 사용할 수 있습니다. 여러 개의 원에 표시 이 게임은 cnGameJS를 기반으로 합니다.

효과 미리보기:

원 버블 게임을 위한 HTML5 코드 공유

구현 분석:

먼저 각 공을 정의합니다. ball 클래스입니다. 공은 그림을 사용해야 하고 특정 크기와 움직임을 가지고 있으므로 이 클래스 cnGameJS의 스프라이트 클래스를 상속합니다. 공 클래스에는 x 및 y 좌표 외에도 공과 플레이어의 시각적 거리 차이를 만드는 데 사용되는 z 좌표도 있습니다.

/*    小球对象    */
var Ball=function(opt){
    this.parent.call(this,opt);
    this.oriPos=[this.x+this.width/2,this.y+this.height/2];
    this.oriSize=opt.size;
    this.z=opt.z||0;
    this.score=opt.score||0;
    this.oriSpeedZ=4+Math.random()*4;
    this.scale=1;
    this.resetXY();
    
}
cg.core.inherit(Ball,Sprite);

그런 다음 공에 ResetXY 메소드를 추가합니다. 이 메소드는 공의 z 좌표에 따라 공의 위치와 크기를 변경하여 공이 원거리와 근거리 사이에 시각적 차이를 갖도록 합니다. 먼저 z를 기준으로 scale ratio scale을 계산한 후 scale을 기준으로 x, y, 너비, 높이를 조정합니다. 또한 z가 1000보다 클 경우 공이 사라지도록 하여 공이 너무 커지는 것을 방지합니다. 전체 화면을 차지합니다.

rree

나중에 여러 개의 공을 관리하기 위해 공 관리자를 추가할 수 있습니다. 관리자는 공과 선수 사이의 거리를 동적으로 변경하고 공이 캔버스의 임의의 위치에 나타나도록 하는 역할을 담당합니다.

rree

이것은 공 관리에 대한 소개이며, 그 다음에는 주로 마우스 원 선택을 수행하는 방법을 소개합니다.

프레임 업데이트될 때마다 마우스의 현재 위치와 마지막 위치를 기준으로 선분을 그리면 마우스의 이동 궤적을 곡선으로 표현할 수 있습니다. 매번 그려지는 선분으로 구성되어 있으므로 곡선은 끝에서 끝까지 연결된 여러 개의 선분으로 구성된 곡선이라고도 할 수 있습니다. 따라서 먼저 선분 클래스를 구현할 수 있습니다:

cg.core.extendProto(Ball,{
    disappear:function(){//小球被选中消失
        list.remove(this);
    },
    resetXY:function(){//根据Z改变x,y的位置和尺寸
        var oriX=this.oriPos[0];
        var oriY=this.oriPos[1];
        var oriSize=this.oriSize;
        this.scale=((center[0]+this.z)/center[0]);//相对于现时的scale        
        this.x=(oriX-center[0])*this.scale+center[0];
        this.y=(oriY-center[1])*this.scale+center[1];
        this.height=this.width=this.oriSize*this.scale;
        this.speedZ=this.oriSpeedZ*this.scale;
        if(this.z>1000){
            this.disappear();
        }
    },
    update:function(){
        this.parent.prototype.update.call(this);
        this.resetXY();
    }
});

이 클래스는 선분의 ​​시작점 좌표와 끝점 좌표는 물론 너비, 스타일 등을 저장합니다.

다음으로 고려해야 할 것은 서클 선택을 구현하는 방법입니다. 마우스로 원을 그리면 각각의 작은 선분은 닫힌 다각형을 형성합니다. 이때 마우스가 닫힌 영역을 돌았다고 말할 수 있으며 그 영역에 어떤 작은 공이 있는지 더 계산할 수 있습니다.

그런데 마우스가 닫힌 영역을 돌았는지 확인하는 방법은 무엇입니까? 여기서 사용되는 방법은 다음과 같습니다. 다음 선분과 다음 선분부터 시작하여 각 선분을 탐색하고 나머지 선분을 탐색하고 그 중 시작 선분과 교차하는 것이 있는지 확인합니다. 곡선이 닫혔습니다. 여기서 다음 선분에서 다음 선분으로 이동하는 것은 선분이 끝에서 끝까지 연결된 상황을 건너뛰는 것입니다. (예를 들어 첫 번째 선분은 두 번째 선분과 교차해야 하므로 마지막에 인접한 선분의 교차점을 건너뛰고 세 번째 선분부터 판단하기 시작하세요.) 코드는 다음과 같습니다.

/*    小球对象管理器    */
var ballsManager={
    createDuration:200,
    ballSize:30,
    lastCreateTime:Date.now(),
    /*    随机生成小球    */
    createRandomBalls:function(num){
        var now=Date.now();
        if(now-this.lastCreateTime>this.createDuration){
            for(var i=0;i<num;i++){
                var x=Math.random()* cg.width;
                var y=Math.random()* cg.height;
                var randomKind=ballKinds[Math.floor(Math.random()*6)];//随机获得的小球种类和分值    
                var newBall=new Ball({x:x,y:y,size:this.ballSize,z:-280,score:randomKind[1]});
                newBall.setCurrentImage(srcObj[randomKind[0]]);//设置图片
                list.add(newBall);
            }
            this.lastCreateTime=now;
        }
    },
    /*    改变小球位置    */
    changeBallsPos:function(){
        var ballsArr=list.get(function(elem){
            return elem instanceof Ball;                               
        });
        for(var i=0,len=ballsArr.length;i<len;i++){
            var ball=ballsArr[i];
            ball.z+=ball.speedZ;    
        }
    }
}

isCross 메소드는 선분의 ​​교차점을 반환합니다. 좌표를 얻은 후 다각형을 실제 다각형으로 수정해야 합니다. 마우스로 원을 그린 다각형은 실제 다각형이 아니고 시작 부분과 끝 부분이 그럴 가능성이 높기 때문입니다.

마우스가 녹색 부분에서 원을 시작하여 파란색 부분에서 끝난다고 가정합니다. 이 경우 궤적에는 파란색과 녹색 부분이 추가로 포함되어 있으므로 엄격한 다각형이 아닙니다. 따라서 원으로 둘러싸인 다각형을 수정 작업을 수행하여 실제 닫힌 다각형으로 바꿔야 합니다.

/*    直线    */
        var line=function(options){
            if (!(this instanceof arguments.callee)) {
                return new arguments.callee(options);
            }
            this.init(options);
        }
    
        
        line.prototype = {
            /**
            *初始化
            **/
            init: function(options) {    
                this.start=[0,0];
                this.end=[0,0];    
                this.style="red";
                this.lineWidth=1;
                this.context=cg.context;
                options = options || {};
                cg.core.extend(this,options);
            },

두 선분이 교차한다고 판단하면 다음 두 선분을 얻을 수 있습니다. index , 여기에는 각각 i와 j(i배열에 저장합니다. 나중에 이 측면을 사용하여 다각형 개체를 구성합니다.

/*    返回轨迹是否闭合    */
    var isClose=function(lines){    
        var hasClose=false;
        for(var i=0;i<lines.length;i++){
            var l1=lines[i];
            for(var j=i+2;j<lines.length;j++){
                var l2=lines[j];
                if(l2){
                    var point=l1.isCross(l2);//交点坐标
                    if(point){//非连接的相交
                        resetLineSegs(lines,i,j,point);
                        hasClosed=true;
                        return true;
                    }
                }
            }
        }
        
        return false;
    };

다각형 가장자리 객체의 배열을 통해 다각형의 각 꼭지점의 좌표를 얻을 수 있으며, 이 좌표를 기반으로 다각형 객체를 구성할 수 있습니다. 다음 단계는 공이 맞는지 확인하는 것입니다. 폴리곤 내부.

  判断小球是否在多边形里,可以转化为判断小球的中点是否在多边形里,这里使用的方法叫射线法,意思是从一点向左发射出一条射线,如果射线和多边形有奇数个交点,则证明点在多边形内部。根据该定理实现的isInside方法如下:

/**
            *判断某点是否在多边形内(射线法)
            **/
            isInside:function(point){
                var lines=this.getLineSegs();

                var count=0;//相交的边的数量
                var lLine=new Line({start:[point[0],point[1]],end:[-9999,point[1]]});//左射线
                var crossPointArr=[];//相交的点的数组
                for(var i=0,len=lines.length;i<len;i++){
                    var crossPoint=lLine.isCross(lines[i]);
                    if(crossPoint){
                        for(var j=0,len2=crossPointArr.length;j<len2;j++){
                            //如果交点和之前的交点相同,即表明交点为多边形的顶点
                            if(crossPointArr[j][0]==crossPoint[0]&&crossPointArr[j][1]==crossPoint[1]){
                                break;    
                            }
                            
                        }
                        if(j==len2){
                            crossPointArr.push(crossPoint);    
                            count++;
                        }
                        
                    }
                }
        
                if(count%2==0){//不包含
                    return false;
                }
                return true;//包含
            },

  另外需要注意的是,由于射线与多边形相交交点个数是通过射线和多边形的每条边是否相交来判断,所以如果射线通过多边形的顶点,我们得出的结果就是相交了两次(通过顶点使射线与两条边都有相交)。因此我们需要记录判断过的交点,每次判断时检查该交点是否已经出现过,若出现过则不纳入计数,这样就基本实现了判断小球是否在鼠标圈选的多边形区域内。

   

위 내용은 원 버블 게임을 위한 HTML5 코드 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.