千家信息网

JS+HTML怎么实现经典吃豆人游戏

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要介绍"JS+HTML怎么实现经典吃豆人游戏"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"JS+HTML怎么实现经典吃豆人游戏"文章能帮助大家解决问
千家信息网最后更新 2025年01月19日JS+HTML怎么实现经典吃豆人游戏

这篇文章主要介绍"JS+HTML怎么实现经典吃豆人游戏"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"JS+HTML怎么实现经典吃豆人游戏"文章能帮助大家解决问题。

项目结构

因需要四个文件即可实现,index.html 游戏主页,index.js 主页控制,game.js 游戏控制,favicon.png 图标。代码简单,易懂。后续小伙伴们还可以自己加入音乐!可以部署到服务器上,也可用浏览器直接打开index.html玩耍!!!

HTML代码

                                        Pac-Man . 吃豆游戏                                                                
不支持画布

按[空格]暂停或继续

JS代码

//主程序,业务逻辑(function(){        var _DATA = [            //地图数据                [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],                [1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],                [1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1],                [1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1],                [1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1],                [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],                [1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1],                [1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1],                [1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1],                [1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,1,1,1,2,2,1,1,1,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,1,2,2,2,2,2,2,1,0,1,1,0,1,1,1,1,1,1],                [0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0],                [1,1,1,1,1,1,0,1,1,0,1,2,2,2,2,2,2,1,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1],                [1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1],                [1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],                [1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1],                [1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1],                [1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1],                [1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1],                [1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1],                [1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1],                [1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1],                [1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1],                [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],                [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]        ],        _GOODS = {                    //能量豆                '1,3':1,                '26,3':1,                '1,23':1,                '26,23':1        },        _COS = [1,0,-1,0],        _SIN = [0,1,0,-1],        _COLOR = ['#F00','#F93','#0CF','#F9C'],//红,橙,        _LIFE = 3,        _SCORE = 0;           //得分         var game = new Game('canvas');        //启动页        (function(){                var stage = game.createStage();                //logo                stage.createItem({                        x:game.width/2,                        y:game.height*.45,                        width:100,                        height:100,                        frames:3,                        draw:function(context){                                var t = Math.abs(5-this.times);                                context.fillStyle = '#FFE600';                                context.beginPath();                                context.arc(this.x,this.y,this.width/2,t*.04*Math.PI,(2-t*.04)*Math.PI,false);                                context.lineTo(this.x,this.y);                                context.closePath();                                context.fill();                                context.fillStyle = '#000';                                context.beginPath();                                context.arc(this.x+5,this.y-27,7,0,2*Math.PI,false);                                context.closePath();                                context.fill();                        }                });                //游戏名                stage.createItem({                        x:game.width/2,                        y:game.height*.6,                        draw:function(context){                                context.font = 'bold 42px Helvetica';                                context.textAlign = 'center';                                context.textBaseline = 'middle';                                context.fillStyle = '#FFF';                                context.fillText('Pac-Man',this.x,this.y);                        }                });                //版权信息                stage.createItem({                        x:game.width-12,                        y:game.height-5,                        draw:function(context){                                context.font = '14px Helvetica';                                context.textAlign = 'right';                                context.textBaseline = 'bottom';                                context.fillStyle = '#AAA';                                context.fillText('© passer-by.com',this.x,this.y);                        }                });                //事件绑定                stage.bind('keydown',function(e){                        switch(e.keyCode){                                case 13:                                case 32:                                game.nextStage();                                break;                        }                });        })();        //游戏主程序        (function(){                var stage,map,beans,player,times;                stage = game.createStage({                        update:function(){                                var stage = this;                                if(stage.status==1){                                                            //场景正常运行                                        items.forEach(function(item){                                                if(map&&!map.get(item.coord.x,item.coord.y)&&!map.get(player.coord.x,player.coord.y)){                                                        var dx = item.x-player.x;                                                        var dy = item.y-player.y;                                                        if(dx*dx+dy*dy<750&&item.status!=4){         //物体检测                                                                if(item.status==3){                                                                        item.status = 4;                                                                        _SCORE += 10;                                                                }else{                                                                        stage.status = 3;                                                                        stage.timeout = 30;                                                                }                                                        }                                                }                                        });                                        if(JSON.stringify(beans.data).indexOf(0)<0){ //当没有物品的时候,进入结束画面                                                game.nextStage();                                        }                                }else if(stage.status==3){         //场景临时状态                                        if(!stage.timeout){                                                _LIFE--;                                                if(_LIFE){                                                        stage.resetItems();                                                }else{                                                        game.nextStage();                                                        return false;                                                }                                        }                                }                        }                });                //绘制地图                map = stage.createMap({                        x:60,                        y:10,                        data:_DATA,                        cache:true,                        draw:function(context){                                context.lineWidth = 2;                                for(var j=0; j-1){                                                                context.strokeStyle=value==2?"#FFF":"#09C";                                                                var pos = this.coord2position(i,j);                                                                switch(code.join('')){                                                                        case '1100':                                                                                context.beginPath();                                                                                context.arc(pos.x+this.size/2,pos.y+this.size/2,this.size/2,Math.PI,1.5*Math.PI,false);                                                                                context.stroke();                                                                                context.closePath();                                                                                break;                                                                        case '0110':                                                                                context.beginPath();                                                                                context.arc(pos.x-this.size/2,pos.y+this.size/2,this.size/2,1.5*Math.PI,2*Math.PI,false);                                                                                context.stroke();                                                                                context.closePath();                                                                                break;                                                                        case '0011':                                                                                context.beginPath();                                                                                context.arc(pos.x-this.size/2,pos.y-this.size/2,this.size/2,0,.5*Math.PI,false);                                                                                context.stroke();                                                                                context.closePath();                                                                                break;                                                                        case '1001':                                                                                context.beginPath();                                                                                context.arc(pos.x+this.size/2,pos.y-this.size/2,this.size/2,.5*Math.PI,1*Math.PI,false);                                                                                context.stroke();                                                                                context.closePath();                                                                                break;                                                                        default:                                                                                var dist = this.size/2;                                                                                code.forEach(function(v,index){                                                                                        if(v){                                                                                                context.beginPath();                                                                                                context.moveTo(pos.x,pos.y);                                                                                                context.lineTo(pos.x-_COS[index]*dist,pos.y-_SIN[index]*dist);                                                                                                context.stroke();                                                                                                context.closePath();                                                                                                                                            }                                                                                });                                                                }                                                        }                                                }                                        }                                }                        }                });                //物品地图                beans = stage.createMap({                        x:60,                        y:10,                        data:_DATA,                        frames:8,                        draw:function(context){                                for(var j=0; jthis.coord.x){                                                        this.orientation = 0;                                                }else if(this.vector.xthis.coord.y){                                                        this.orientation = 1;                                                }else if(this.vector.y80||this.times%2?true:false;                                        }                                        if(this.status!=4){                                                context.fillStyle = isSick?'#BABABA':this.color;                                                context.beginPath();                                                context.arc(this.x,this.y,this.width*.5,0,Math.PI,true);                                                switch(this.times%2){                                                        case 0:                                                        context.lineTo(this.x-this.width*.5,this.y+this.height*.4);                                                        context.quadraticCurveTo(this.x-this.width*.4,this.y+this.height*.5,this.x-this.width*.2,this.y+this.height*.3);                                                        context.quadraticCurveTo(this.x,this.y+this.height*.5,this.x+this.width*.2,this.y+this.height*.3);                                                        context.quadraticCurveTo(this.x+this.width*.4,this.y+this.height*.5,this.x+this.width*.5,this.y+this.height*.4);                                                        break;                                                        case 1:                                                        context.lineTo(this.x-this.width*.5,this.y+this.height*.3);                                                        context.quadraticCurveTo(this.x-this.width*.25,this.y+this.height*.5,this.x,this.y+this.height*.3);                                                        context.quadraticCurveTo(this.x+this.width*.25,this.y+this.height*.5,this.x+this.width*.5,this.y+this.height*.3);                                                        break;                                                }                                                context.fill();                                                context.closePath();                                        }                                        context.fillStyle = '#FFF';                                        if(isSick){                                                context.beginPath();                                                context.arc(this.x-this.width*.15,this.y-this.height*.21,this.width*.08,0,2*Math.PI,false);                                                context.arc(this.x+this.width*.15,this.y-this.height*.21,this.width*.08,0,2*Math.PI,false);                                                context.fill();                                                context.closePath();                                        }else{                                                context.beginPath();                                                context.arc(this.x-this.width*.15,this.y-this.height*.21,this.width*.12,0,2*Math.PI,false);                                                context.arc(this.x+this.width*.15,this.y-this.height*.21,this.width*.12,0,2*Math.PI,false);                                                context.fill();                                                context.closePath();                                                context.fillStyle = '#000';                                                context.beginPath();                                                context.arc(this.x-this.width*(.15-.04*_COS[this.orientation]),this.y-this.height*(.21-.04*_SIN[this.orientation]),this.width*.07,0,2*Math.PI,false);                                                context.arc(this.x+this.width*(.15+.04*_COS[this.orientation]),this.y-this.height*(.21-.04*_SIN[this.orientation]),this.width*.07,0,2*Math.PI,false);                                                context.fill();                                                context.closePath();                                        }                                }                        });                }                items = stage.getItemsByType(2);                //主角                player = stage.createItem({                        width:30,                        height:30,                        type:1,                        location:map,                        coord:{x:13.5,y:23},                        orientation:2,                        speed:2,                        frames:10,                        update:function(){                                var coord = this.coord;                                if(!coord.offset){                                        if(this.control.orientation!='undefined'){                                                if(!map.get(coord.x+_COS[this.control.orientation],coord.y+_SIN[this.control.orientation])){                                                        this.orientation = this.control.orientation;                                                }                                        }                                        this.control = {};                                        var value = map.get(coord.x+_COS[this.orientation],coord.y+_SIN[this.orientation]);                                        if(value==0){                                                this.x += this.speed*_COS[this.orientation];                                                this.y += this.speed*_SIN[this.orientation];                                        }else if(value<0){                                                this.x -= map.size*(map.x_length-1)*_COS[this.orientation];                                                this.y -= map.size*(map.y_length-1)*_SIN[this.orientation];                                        }                                }else{                                        if(!beans.get(this.coord.x,this.coord.y)){      //吃豆                                                _SCORE++;                                                beans.set(this.coord.x,this.coord.y,1);                                                if(_GOODS[this.coord.x+','+this.coord.y]){      //吃到能量豆                                                        items.forEach(function(item){                                                                if(item.status==1||item.status==3){     //如果NPC为正常状态,则置为临时状态                                                                        item.timeout = 450;                                                                        item.status = 3;                                                                }                                                        });                                                }                                        }                                        this.x += this.speed*_COS[this.orientation];                                        this.y += this.speed*_SIN[this.orientation];                                }                        },                        draw:function(context){                                context.fillStyle = '#FFE600';                                context.beginPath();                                if(stage.status!=3){    //玩家正常状态                                        if(this.times%2){                                                context.arc(this.x,this.y,this.width/2,(.5*this.orientation+.20)*Math.PI,(.5*this.orientation-.20)*Math.PI,false);                                        }else{                                                context.arc(this.x,this.y,this.width/2,(.5*this.orientation+.01)*Math.PI,(.5*this.orientation-.01)*Math.PI,false);                                        }                                }else{  //玩家被吃                                        if(stage.timeout) {                                                context.arc(this.x,this.y,this.width/2,(.5*this.orientation+1-.02*stage.timeout)*Math.PI,(.5*this.orientation-1+.02*stage.timeout)*Math.PI,false);                                        }                                }                                context.lineTo(this.x,this.y);                                context.closePath();                                context.fill();                        }                });                //事件绑定                stage.bind('keydown',function(e){                        switch(e.keyCode){                                case 13: //回车                                case 32: //空格                                this.status = this.status==2?1:2;                                break;                                case 39: //右                                player.control = {orientation:0};                                break;                                case 40: //下                                player.control = {orientation:1};                                break;                                case 37: //左                                player.control = {orientation:2};                                break;                                case 38: //上                                player.control = {orientation:3};                                break;                        }                });        })();        //结束画面        (function(){                var stage = game.createStage();                //游戏结束                stage.createItem({                        x:game.width/2,                        y:game.height*.35,                        draw:function(context){                                context.fillStyle = '#FFF';                                context.font = 'bold 48px Helvetica';                                context.textAlign = 'center';                                context.textBaseline = 'middle';                                context.fillText('GAME OVER',this.x,this.y);                        }                });                //记分                stage.createItem({                        x:game.width/2,                        y:game.height*.5,                        draw:function(context){                                context.fillStyle = '#FFF';                                context.font = '20px Helvetica';                                context.textAlign = 'center';                                context.textBaseline = 'middle';                                context.fillText('FINAL SCORE: '+(_SCORE+50*Math.max(_LIFE-1,0)),this.x,this.y);                        }                });                //事件绑定                stage.bind('keydown',function(e){                        switch(e.keyCode){                                case 13: //回车                                case 32: //空格                                _SCORE = 0;                                _LIFE = 3;                                var st = game.setStage(1);                                st.reset();                                break;                        }                });        })();        game.init();})();

游戏截图

操作说明 ,按键盘上下左右键移动 ,按键盘空格键暂停!

关于"JS+HTML怎么实现经典吃豆人游戏"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

0