• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > HTML5实现圈泡泡游戏的代码分享

HTML5实现圈泡泡游戏的代码分享

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含HTML5,圈泡泡游戏等相关知识,匿名希望在学习及工作中可以帮助到您
功能说明:

  在一分钟内,使用鼠标按着左键,在画布上圈泡泡,其中泡泡的分值分别为10(白)、20(浅蓝)、30(黄)、-10(红)、-20(绿)、-30(深蓝)分,可以一次圈多个泡泡,倒计时结束即计算总分值,该游戏基于cnGameJS。

效果预览:

1269.jpg

实现分析:

 首先每个小球定义一个ball类,由于小球需要使用图片,并且有一定的尺寸和运动,所以使该类继承cnGameJS的sprite类。ball类除了拥有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,然后根据scale调整x,y和width,height,另外我们使小球z大于1000时,小球消失,这样就避免了小球过大而占据整个屏幕。

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;    
        }
    }
}

  关于小球管理就介绍到这里,之后主要介绍怎样实现鼠标的圈选。

  如果我们在每次帧更新时,根据鼠标现时的位置以及上一次的位置绘制一条线段,那么鼠标的移动轨迹就可以被一条曲线表示出来,该曲线由每次绘制的线段组成,因此我们也可以说该曲线是一条由多条线段首尾相连组成的曲线。因此我们可以首先实现一个线段类:

/*    直线    */
        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);
            },

  该类保存线段的起始点坐标和结束点坐标,以及宽度,样式等。

  之后需要考虑的就是怎样实现圈选了。当我们用鼠标画出一个圈时,每条小线段就组成了一个闭合的多边形,这时我们就可以说鼠标圈出了一个闭合区域,之后就可以进一步计算哪些小球在该区域里面。

  但是怎样判断鼠标是否圈出了一个闭合区域呢?这里使用的方法是:遍历每一条线段,从该线段的下一条再下一条线段开始遍历余下的线段,判断它们中是否有线段和开始的那条线段相交,如果相交,则证明曲线闭合了。注意这里从线段的下条再下条线段开始遍历是为了跳过线段首尾相连的情况。(例如,第一条线段肯定和第二条线段相交,因此从第三条线段开始判断,跳过相邻线段收尾相交的情况),代码如下:

/*    返回轨迹是否闭合    */
    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;
    };

  isCross方法返回线段交点的坐标,我们获得该坐标后,还需要把多边形修正成为真正的多边形,因为用鼠标圈出来的多边形并不是一个真正的多边形,它的开始和结束部分很可能会有突出的地方,如下图:

  我们假设鼠标从绿色部分开始圈一个圈,到蓝色部分结束。这样的话轨迹就并不是一个严格的多边形,因为它多出了蓝色和绿色的部分。因此我们需要对圈出来的多边形进行一个修正操作,使其变成一个真正的闭合多边形:

    /*    重置线段    */
    var resetLineSegs=function(lines,i,j,point){
        lines[i].end[0]=point[0];
        lines[i].end[1]=point[1];
        lines[i+1].start[0]=point[0];
        lines[i+1].start[1]=point[1];
        
        lines[j].start[0]=point[0];
        lines[j].start[1]=point[1];
    
        lines[j-1].end[0]=point[0];
        lines[j-1].end[1]=point[1];        for(var m=i+1;m<j;m++){
            closedLineSegsArr.push(lines[m]);
        }    
    }

  当我们判断到两条线段相交后,可以获取到这两条线段的索引,这里分别为i和j(i<j),point为交点。在新增加的resetLineSegs方法中,首先改变i线段的结束坐标,使其刚好为交点,再改变j线段的起始坐标,使其为交点,并且使i线段后面的线段的起始坐标以及j线段前面线段的结束坐标为交点,这样就可以使多边形真正闭合。之后把闭合多边形各个边的对象保存在一个数组中,我们后面就要使用这些边,构造多边形对象了。

       for(var i=0,len=closedLineSegsArr.length;i<len;i++){
                            pointsArr.push([closedLineSegsArr[i].start[0],closedLineSegsArr[i].start[1]]);    
                        }
                        polygon=new Polygon({pointsArr:pointsArr,style:"rgba(241,46,8,0.5)"});

  通过多边形的边对象的数组,可以获取到多边形每个顶点的坐标,并根据这些坐标构造多边形对象,之后的工作就是判断小球是否在多边形里面了。

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




 

您可能想查找下面的文章:

  • HTML5知识点总结
  • HTML5的本地存储
  • HTML5本地存储之IndexedDB
  • Html5实现文件异步上传功能
  • Html5新标签datalist实现输入框与后台数据库数据的动态匹配
  • 详解HTML5 window.postMessage与跨域
  • HTML5拖放API实现拖放排序的实例代码
  • 解决html5中video标签无法播放mp4问题的办法
  • HTML5新特性 多线程(Worker SharedWorker)
  • Html5新增标签有哪些

相关文章

  • 2018-12-03基于HTML5鼠标点击淡入淡出切换代码
  • 2018-12-03HTML5游戏开发 之 循环的控制(3)
  • 2018-12-03移动端利用html5对照片处理的教程实例
  • 2018-12-03小程序学习之如何获取地理定位并显示城市名称
  • 2018-12-03html5新增标签有哪些?html5新增的标签应用
  • 2018-12-03使用<header>,<footer>,<nav>等h5标签,和全部使用<div>有什么区别??
  • 2018-12-03html5动画中关于等待加载动画的实例分享
  • 2018-12-03html5 初试 indexedDB(推荐)
  • 2018-12-03HTML5新增常用的表单元素有哪些?附使用实例
  • 2018-12-03易企秀、兔展类似的在微信上传播的H5微场景制作软件还有哪些?

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • HTML5 Canvas的常用线条属性值总结
    • Tumult hype2下载及教程?
    • 基于html5绘制圆形多角图案_html5教程技巧
    • HTML5 Canvas中绘制矩形实例
    • HTML5是什么,HTML5有哪些特性和优缺点?
    • phonegap实现进行本地存储的方法介绍
    • Web时代变迁及html5与html4的区别
    • HTML5本地存储应用sessionStorage和localStorage
    • html5游戏开发-零基础开发RPG游戏-开源讲座(四)-游戏脚本化&地图跳转
    • html5 mark标签是什么意思?html5 mark标签的作用又是什么?

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有