搜尋
首頁web前端H5教程HTML5實現圈泡泡遊戲的程式碼分享

功能說明:

  在一分鐘內,使用滑鼠按左鍵,在畫布上圈泡泡,其中泡泡的分數分別為10(白)、20(淺藍)、30(黃)、-10(紅)、-20(綠)、-30(深藍)分,可以一次圈多個泡泡,倒數結束即計算總分值,遊戲基於cnGameJS

效果預覽:

 HTML5實現圈泡泡遊戲的程式碼分享

#實現分析: 

## 先每個小球定義一個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陣列中,我們後面就要使用這些邊,建構多邊形物件了。

       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方法如下:

/**
            *判断某点是否在多边形内(射线法)
            **/
            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
H5代碼:Web開發人員的最佳實踐H5代碼:Web開發人員的最佳實踐Apr 16, 2025 am 12:14 AM

H5代碼的最佳實踐包括:1.使用正確的DOCTYPE聲明和字符編碼;2.採用語義化標籤;3.減少HTTP請求;4.使用異步加載;5.優化圖像。這些實踐能提升網頁的效率、可維護性和用戶體驗。

H5:網絡標準和技術的發展H5:網絡標準和技術的發展Apr 15, 2025 am 12:12 AM

Web标准和技术从HTML4、CSS2和简单的JavaScript演变至今,经历了显著的发展。1)HTML5引入了Canvas、WebStorage等API,增强了Web应用的复杂性和互动性。2)CSS3增加了动画和过渡功能,使页面效果更加丰富。3)JavaScript通过Node.js和ES6的现代化语法,如箭头函数和类,提升了开发效率和代码可读性,这些变化推动了Web应用的性能优化和最佳实践的发展。

H5是HTML5的速記嗎?探索細節H5是HTML5的速記嗎?探索細節Apr 14, 2025 am 12:05 AM

H5不僅僅是HTML5的簡稱,它代表了一個更廣泛的現代網頁開發技術生態:1.H5包括HTML5、CSS3、JavaScript及相關API和技術;2.它提供更豐富、互動、流暢的用戶體驗,能在多設備上無縫運行;3.使用H5技術棧可以創建響應式網頁和復雜交互功能。

H5和HTML5:網絡開發中常用的術語H5和HTML5:網絡開發中常用的術語Apr 13, 2025 am 12:01 AM

H5與HTML5指的是同一個東西,即HTML5。 HTML5是HTML的第五個版本,帶來了語義化標籤、多媒體支持、畫布與圖形、離線存儲與本地存儲等新功能,提升了網頁的表現力和交互性。

H5指的是什麼?探索上下文H5指的是什麼?探索上下文Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

H5:工具,框架和最佳實踐H5:工具,框架和最佳實踐Apr 11, 2025 am 12:11 AM

H5開發需要掌握的工具和框架包括Vue.js、React和Webpack。 1.Vue.js適用於構建用戶界面,支持組件化開發。 2.React通過虛擬DOM優化頁面渲染,適合複雜應用。 3.Webpack用於模塊打包,優化資源加載。

HTML5的遺產:當前了解H5HTML5的遺產:當前了解H5Apr 10, 2025 am 09:28 AM

HTML5hassignificantlytransformedwebdevelopmentbyintroducingsemanticelements,enhancingmultimediasupport,andimprovingperformance.1)ItmadewebsitesmoreaccessibleandSEO-friendlywithsemanticelementslike,,and.2)HTML5introducednativeandtags,eliminatingthenee

H5代碼:可訪問性和語義HTMLH5代碼:可訪問性和語義HTMLApr 09, 2025 am 12:05 AM

H5通過語義化元素和ARIA屬性提升網頁的可訪問性和SEO效果。 1.使用、、等元素組織內容結構,提高SEO。 2.ARIA屬性如aria-label增強可訪問性,輔助技術用戶可順利使用網頁。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器