QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

泡泡马甲APP 更多内容请下载泡泡马甲手机客户端APP 立即下载 ×
查看: 5387|回复: 0

[HTML/CSS/JS] JS+HTML实现经典游戏吃豆人

[复制链接]

等级头衔

积分成就    金币 : 2804
   泡泡 : 1516
   精华 : 6
   在线时间 : 1243 小时
   最后登录 : 2024-5-2

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老

联系方式
发表于 2022-4-16 16:45:45 | 显示全部楼层 |阅读模式
一、前言
$ p# S4 ]: e4 c7 H       很早就知道canvas,当时一直没应用到,最近闲来无事就顺便写写看。吃豆游戏可以说是我们80,90后共同的回忆录,小时候常常在学习机上玩,所以也就有了强烈的欲望去写。为了写这个游戏,看了很多吃豆人游戏的相关信息,包括游戏规则,历史,其它相关游戏设计。又去了各个小游戏平台玩了下,找些灵感!!!就连最简单的配色,也是反复斟酌几个小时确定的方案……哈哈,不容易啊代码分两部分,游戏引擎和游戏主程序,引擎用来类的定义,管理动画场景,事件定义等等……游戏主程序主要组织业务逻辑。算面向对象编程吧,纯手工打造是男人就吃光所有豆子!!! 5 n) A, V+ U2 S$ b1 U0 d+ A7 C' w
项目结构; E  r% H3 K9 \  M8 E) x0 J) v
1.jpg
8 c! m4 K- f9 z) z       因需要四个文件即可实现,index.html 游戏主页,index.js 主页控制,game.js 游戏控制,favicon.png 图标。代码简单,易懂。后续小伙伴们还可以自己加入音乐!可以部署到服务器上,也可用浏览器直接打开index.html玩耍!!!3 |( E3 u8 Z4 A4 K( f) }
二、HTML代码
3 J" s/ y8 Y  N) G  N5 n) Z
  1. <html>
  2.         <head>
  3.                 <meta charset="utf8">
  4.                 <title>Pac-Man . 吃豆游戏</title>
  5.                 <link rel="shortcut icon" href="favicon.png" rel="external nofollow" >
  6.                 <style>
  7.                         body{background-color: #292929}
  8.                         *{padding:0;margin:0;}
  9.                         .wrapper{
  10.                                 width: 960px;
  11.                                 margin:0 auto;
  12.                                 line-height:36px;
  13.                                 text-align:center;
  14.                                 color:#999;
  15.                         }
  16.                         canvas{display:block;background: #000;}
  17.                         .mod-botton{
  18.                                 height: 32px;
  19.                                 padding: 15px 0;
  20.                                 text-align: center;
  21.                         }
  22.                 </style>
  23.         </head>
  24.         <body>
  25.                 <div class="wrapper">
  26.                         <canvas id="canvas" width="960" height="640">不支持画布</canvas>
  27.                         <p>按[空格]暂停或继续</p>               
  28.                 </div>
  29.                 <script src="game.js"></script>
  30.                 <script src="index.js"></script>
  31.                
  32.         </body>
  33. </html>
三、JS代码
. W7 ]( G; U9 d- O# W8 U$ r; o- ~
  1. //主程序,业务逻辑
  2. (function(){
  3.         var _DATA = [                //地图数据
  4.                 [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],
  5.                 [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],
  6.                 [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],
  7.                 [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],
  8.                 [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],
  9.                 [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],
  10.                 [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],
  11.                 [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],
  12.                 [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],
  13.                 [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],
  14.                 [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],
  15.                 [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],
  16.                 [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],
  17.                 [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],
  18.                 [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],
  19.                 [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],
  20.                 [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],
  21.                 [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],
  22.                 [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],
  23.                 [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],
  24.                 [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],
  25.                 [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],
  26.                 [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],
  27.                 [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],
  28.                 [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],
  29.                 [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],
  30.                 [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],
  31.                 [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],
  32.                 [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],
  33.                 [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],
  34.                 [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]
  35.         ],
  36.         _GOODS = {                        //能量豆
  37.                 '1,3':1,
  38.                 '26,3':1,
  39.                 '1,23':1,
  40.                 '26,23':1
  41.         },
  42.         _COS = [1,0,-1,0],
  43.         _SIN = [0,1,0,-1],
  44.         _COLOR = ['#F00','#F93','#0CF','#F9C'],//红,橙,
  45.         _LIFE = 3,
  46.         _SCORE = 0;                //得分
  47.         var game = new Game('canvas');
  48.         //启动页
  49.         (function(){
  50.                 var stage = game.createStage();
  51.                 //logo
  52.                 stage.createItem({
  53.                         x:game.width/2,
  54.                         y:game.height*.45,
  55.                         width:100,
  56.                         height:100,
  57.                         frames:3,
  58.                         draw:function(context){
  59.                                 var t = Math.abs(5-this.times%10);
  60.                                 context.fillStyle = '#FFE600';
  61.                                 context.beginPath();
  62.                                 context.arc(this.x,this.y,this.width/2,t*.04*Math.PI,(2-t*.04)*Math.PI,false);
  63.                                 context.lineTo(this.x,this.y);
  64.                                 context.closePath();
  65.                                 context.fill();
  66.                                 context.fillStyle = '#000';
  67.                                 context.beginPath();
  68.                                 context.arc(this.x+5,this.y-27,7,0,2*Math.PI,false);
  69.                                 context.closePath();
  70.                                 context.fill();
  71.                         }
  72.                 });
  73.                 //游戏名
  74.                 stage.createItem({
  75.                         x:game.width/2,
  76.                         y:game.height*.6,
  77.                         draw:function(context){
  78.                                 context.font = 'bold 42px Helvetica';
  79.                                 context.textAlign = 'center';
  80.                                 context.textBaseline = 'middle';
  81.                                 context.fillStyle = '#FFF';
  82.                                 context.fillText('Pac-Man',this.x,this.y);
  83.                         }
  84.                 });
  85.                 //版权信息
  86.                 stage.createItem({
  87.                         x:game.width-12,
  88.                         y:game.height-5,
  89.                         draw:function(context){
  90.                                 context.font = '14px Helvetica';
  91.                                 context.textAlign = 'right';
  92.                                 context.textBaseline = 'bottom';
  93.                                 context.fillStyle = '#AAA';
  94.                                 context.fillText('© passer-by.com',this.x,this.y);
  95.                         }
  96.                 });
  97.                 //事件绑定
  98.                 stage.bind('keydown',function(e){
  99.                         switch(e.keyCode){
  100.                                 case 13:
  101.                                 case 32:
  102.                                 game.nextStage();
  103.                                 break;
  104.                         }
  105.                 });
  106.         })();
  107.         //游戏主程序
  108.         (function(){
  109.                 var stage,map,beans,player,times;
  110.                 stage = game.createStage({
  111.                         update:function(){
  112.                                 var stage = this;
  113.                                 if(stage.status==1){                                                                //场景正常运行
  114.                                         items.forEach(function(item){
  115.                                                 if(map&&!map.get(item.coord.x,item.coord.y)&&!map.get(player.coord.x,player.coord.y)){
  116.                                                         var dx = item.x-player.x;
  117.                                                         var dy = item.y-player.y;
  118.                                                         if(dx*dx+dy*dy<750&&item.status!=4){                //物体检测
  119.                                                                 if(item.status==3){
  120.                                                                         item.status = 4;
  121.                                                                         _SCORE += 10;
  122.                                                                 }else{
  123.                                                                         stage.status = 3;
  124.                                                                         stage.timeout = 30;
  125.                                                                 }
  126.                                                         }
  127.                                                 }
  128.                                         });
  129.                                         if(JSON.stringify(beans.data).indexOf(0)<0){        //当没有物品的时候,进入结束画面
  130.                                                 game.nextStage();
  131.                                         }
  132.                                 }else if(stage.status==3){                //场景临时状态
  133.                                         if(!stage.timeout){
  134.                                                 _LIFE--;
  135.                                                 if(_LIFE){
  136.                                                         stage.resetItems();
  137.                                                 }else{
  138.                                                         game.nextStage();
  139.                                                         return false;
  140.                                                 }
  141.                                         }
  142.                                 }
  143.                         }
  144.                 });
  145.                 //绘制地图
  146.                 map = stage.createMap({
  147.                         x:60,
  148.                         y:10,
  149.                         data:_DATA,
  150.                         cache:true,
  151.                         draw:function(context){
  152.                                 context.lineWidth = 2;
  153.                                 for(var j=0; j<this.y_length; j++){
  154.                                         for(var i=0; i<this.x_length; i++){
  155.                                                 var value = this.get(i,j);
  156.                                                 if(value){
  157.                                                         var code = [0,0,0,0];
  158.                                                         if(this.get(i+1,j)&&!(this.get(i+1,j-1)&&this.get(i+1,j+1)&&this.get(i,j-1)&&this.get(i,j+1))){
  159.                                                                 code[0]=1;
  160.                                                         }
  161.                                                         if(this.get(i,j+1)&&!(this.get(i-1,j+1)&&this.get(i+1,j+1)&&this.get(i-1,j)&&this.get(i+1,j))){
  162.                                                                 code[1]=1;
  163.                                                         }
  164.                                                         if(this.get(i-1,j)&&!(this.get(i-1,j-1)&&this.get(i-1,j+1)&&this.get(i,j-1)&&this.get(i,j+1))){
  165.                                                                 code[2]=1;
  166.                                                         }
  167.                                                         if(this.get(i,j-1)&&!(this.get(i-1,j-1)&&this.get(i+1,j-1)&&this.get(i-1,j)&&this.get(i+1,j))){
  168.                                                                 code[3]=1;
  169.                                                         }
  170.                                                         if(code.indexOf(1)>-1){
  171.                                                                 context.strokeStyle=value==2?"#FFF":"#09C";
  172.                                                                 var pos = this.coord2position(i,j);
  173.                                                                 switch(code.join('')){
  174.                                                                         case '1100':
  175.                                                                                 context.beginPath();
  176.                                                                                 context.arc(pos.x+this.size/2,pos.y+this.size/2,this.size/2,Math.PI,1.5*Math.PI,false);
  177.                                                                                 context.stroke();
  178.                                                                                 context.closePath();
  179.                                                                                 break;
  180.                                                                         case '0110':
  181.                                                                                 context.beginPath();
  182.                                                                                 context.arc(pos.x-this.size/2,pos.y+this.size/2,this.size/2,1.5*Math.PI,2*Math.PI,false);
  183.                                                                                 context.stroke();
  184.                                                                                 context.closePath();
  185.                                                                                 break;
  186.                                                                         case '0011':
  187.                                                                                 context.beginPath();
  188.                                                                                 context.arc(pos.x-this.size/2,pos.y-this.size/2,this.size/2,0,.5*Math.PI,false);
  189.                                                                                 context.stroke();
  190.                                                                                 context.closePath();
  191.                                                                                 break;
  192.                                                                         case '1001':
  193.                                                                                 context.beginPath();
  194.                                                                                 context.arc(pos.x+this.size/2,pos.y-this.size/2,this.size/2,.5*Math.PI,1*Math.PI,false);
  195.                                                                                 context.stroke();
  196.                                                                                 context.closePath();
  197.                                                                                 break;
  198.                                                                         default:
  199.                                                                                 var dist = this.size/2;
  200.                                                                                 code.forEach(function(v,index){
  201.                                                                                         if(v){
  202.                                                                                                 context.beginPath();
  203.                                                                                                 context.moveTo(pos.x,pos.y);
  204.                                                                                                 context.lineTo(pos.x-_COS[index]*dist,pos.y-_SIN[index]*dist);
  205.                                                                                                 context.stroke();
  206.                                                                                                 context.closePath();                                                       
  207.                                                                                         }
  208.                                                                                 });
  209.                                                                 }
  210.                                                         }
  211.                                                 }
  212.                                         }
  213.                                 }
  214.                         }
  215.                 });
  216.                 //物品地图
  217.                 beans = stage.createMap({
  218.                         x:60,
  219.                         y:10,
  220.                         data:_DATA,
  221.                         frames:8,
  222.                         draw:function(context){
  223.                                 for(var j=0; j<this.y_length; j++){
  224.                                         for(var i=0; i<this.x_length; i++){
  225.                                                 if(!this.get(i,j)){
  226.                                                         var pos = this.coord2position(i,j);
  227.                                                         context.fillStyle = "#F5F5DC";
  228.                                                         if(_GOODS[i+','+j]){
  229.                                                                 context.beginPath();
  230.                                                                 context.arc(pos.x,pos.y,3+this.times%2,0,2*Math.PI,true);
  231.                                                                 context.fill();
  232.                                                                 context.closePath();
  233.                                                         }else{
  234.                                                                 context.fillRect(pos.x-2,pos.y-2,4,4);
  235.                                                         }
  236.                                                 }
  237.                                         }
  238.                                 }
  239.                         }
  240.                 });
  241.                 //得分
  242.                 stage.createItem({
  243.                         x:690,
  244.                         y:100,
  245.                         draw:function(context){
  246.                                 context.font = 'bold 28px Helvetica';
  247.                                 context.textAlign = 'left';
  248.                                 context.textBaseline = 'bottom';
  249.                                 context.fillStyle = '#C33';
  250.                                 context.fillText('SCORE',this.x,this.y);
  251.                                 context.font = '28px Helvetica';
  252.                                 context.textAlign = 'left';
  253.                                 context.textBaseline = 'top';
  254.                                 context.fillStyle = '#FFF';
  255.                                 context.fillText(_SCORE,this.x+12,this.y);
  256.                         }
  257.                 });
  258.                 //状态文字
  259.                 stage.createItem({
  260.                         x:690,
  261.                         y:320,
  262.                         frames:25,
  263.                         draw:function(context){
  264.                                 if(stage.status==2&&this.times%2){
  265.                                         context.font = '24px Helvetica';
  266.                                         context.textAlign = 'left';
  267.                                         context.textBaseline = 'center';
  268.                                         context.fillStyle = '#09F';
  269.                                         context.fillText('PAUSE',this.x,this.y);
  270.                                 }
  271.                         }
  272.                 });
  273.                 //生命值
  274.                 stage.createItem({
  275.                         x:705,
  276.                         y:540,
  277.                         width:30,
  278.                         height:30,
  279.                         draw:function(context){
  280.                                 for(var i=0;i<_LIFE-1;i++){
  281.                                         var x=this.x+40*i,y=this.y;
  282.                                         context.fillStyle = '#FFE600';
  283.                                         context.beginPath();
  284.                                         context.arc(x,y,this.width/2,.15*Math.PI,-.15*Math.PI,false);
  285.                                         context.lineTo(x,y);
  286.                                         context.closePath();
  287.                                         context.fill();
  288.                                 }
  289.                         }
  290.                 });
  291.                 //NPC
  292.                 for(var i=0;i<4;i++){
  293.                         stage.createItem({
  294.                                 width:30,
  295.                                 height:30,
  296.                                 orientation:3,
  297.                                 color:_COLOR[i],
  298.                                 location:map,
  299.                                 coord:{x:12+i,y:14},
  300.                                 vector:{x:12+i,y:14},
  301.                                 type:2,
  302.                                 frames:10,
  303.                                 speed:1,
  304.                                 timeout:Math.floor(Math.random()*120),
  305.                                 update:function(){
  306.                                         var new_map;
  307.                                         if(this.status==3&&!this.timeout){
  308.                                                 this.status = 1;
  309.                                         }
  310.                                         if(!this.coord.offset){                        //到达坐标中心时计算
  311.                                                 if(this.status==1){
  312.                                                         if(!this.timeout){                //定时器
  313.                                                                 new_map = JSON.parse(JSON.stringify(map.data).replace(/2/g,0));
  314.                                                                 var id = this._id;
  315.                                                                 items.forEach(function(item){
  316.                                                                         if(item._id!=id&&item.status==1){        //NPC将其它所有还处于正常状态的NPC当成一堵墙
  317.                                                                                 new_map[item.coord.y][item.coord.x]=1;
  318.                                                                         }
  319.                                                                 });
  320.                                                                 this.path = map.finder({
  321.                                                                         map:new_map,
  322.                                                                         start:this.coord,
  323.                                                                         end:player.coord
  324.                                                                 });
  325.                                                                 if(this.path.length){
  326.                                                                         this.vector = this.path[0];
  327.                                                                 }
  328.                                                         }
  329.                                                 }else if(this.status==3){
  330.                                                         new_map = JSON.parse(JSON.stringify(map.data).replace(/2/g,0));
  331.                                                         var id = this._id;
  332.                                                         items.forEach(function(item){
  333.                                                                 if(item._id!=id){
  334.                                                                         new_map[item.coord.y][item.coord.x]=1;
  335.                                                                 }
  336.                                                         });
  337.                                                         this.path = map.finder({
  338.                                                                 map:new_map,
  339.                                                                 start:player.coord,
  340.                                                                 end:this.coord,
  341.                                                                 type:'next'
  342.                                                         });
  343.                                                         if(this.path.length){
  344.                                                                 this.vector = this.path[Math.floor(Math.random()*this.path.length)];
  345.                                                         }
  346.                                                 }else if(this.status==4){
  347.                                                         new_map = JSON.parse(JSON.stringify(map.data).replace(/2/g,0));
  348.                                                         this.path = map.finder({
  349.                                                                 map:new_map,
  350.                                                                 start:this.coord,
  351.                                                                 end:this._params.coord
  352.                                                         });
  353.                                                         if(this.path.length){
  354.                                                                 this.vector = this.path[0];
  355.                                                         }else{
  356.                                                                 this.status = 1;
  357.                                                         }
  358.                                                 }
  359.                                                 //是否转变方向
  360.                                                 if(this.vector.change){
  361.                                                         this.coord.x = this.vector.x;
  362.                                                         this.coord.y = this.vector.y;
  363.                                                         var pos = map.coord2position(this.coord.x,this.coord.y);
  364.                                                         this.x = pos.x;
  365.                                                         this.y = pos.y;
  366.                                                 }
  367.                                                 //方向判定
  368.                                                 if(this.vector.x>this.coord.x){
  369.                                                         this.orientation = 0;
  370.                                                 }else if(this.vector.x<this.coord.x){
  371.                                                         this.orientation = 2;
  372.                                                 }else if(this.vector.y>this.coord.y){
  373.                                                         this.orientation = 1;
  374.                                                 }else if(this.vector.y<this.coord.y){
  375.                                                         this.orientation = 3;
  376.                                                 }
  377.                                         }
  378.                                         this.x += this.speed*_COS[this.orientation];
  379.                                         this.y += this.speed*_SIN[this.orientation];
  380.                                 },
  381.                                 draw:function(context){
  382.                                         var isSick = false;
  383.                                         if(this.status==3){
  384.                                                 isSick = this.timeout>80||this.times%2?true:false;
  385.                                         }
  386.                                         if(this.status!=4){
  387.                                                 context.fillStyle = isSick?'#BABABA':this.color;
  388.                                                 context.beginPath();
  389.                                                 context.arc(this.x,this.y,this.width*.5,0,Math.PI,true);
  390.                                                 switch(this.times%2){
  391.                                                         case 0:
  392.                                                         context.lineTo(this.x-this.width*.5,this.y+this.height*.4);
  393.                                                         context.quadraticCurveTo(this.x-this.width*.4,this.y+this.height*.5,this.x-this.width*.2,this.y+this.height*.3);
  394.                                                         context.quadraticCurveTo(this.x,this.y+this.height*.5,this.x+this.width*.2,this.y+this.height*.3);
  395.                                                         context.quadraticCurveTo(this.x+this.width*.4,this.y+this.height*.5,this.x+this.width*.5,this.y+this.height*.4);
  396.                                                         break;
  397.                                                         case 1:
  398.                                                         context.lineTo(this.x-this.width*.5,this.y+this.height*.3);
  399.                                                         context.quadraticCurveTo(this.x-this.width*.25,this.y+this.height*.5,this.x,this.y+this.height*.3);
  400.                                                         context.quadraticCurveTo(this.x+this.width*.25,this.y+this.height*.5,this.x+this.width*.5,this.y+this.height*.3);
  401.                                                         break;
  402.                                                 }
  403.                                                 context.fill();
  404.                                                 context.closePath();
  405.                                         }
  406.                                         context.fillStyle = '#FFF';
  407.                                         if(isSick){
  408.                                                 context.beginPath();
  409.                                                 context.arc(this.x-this.width*.15,this.y-this.height*.21,this.width*.08,0,2*Math.PI,false);
  410.                                                 context.arc(this.x+this.width*.15,this.y-this.height*.21,this.width*.08,0,2*Math.PI,false);
  411.                                                 context.fill();
  412.                                                 context.closePath();
  413.                                         }else{
  414.                                                 context.beginPath();
  415.                                                 context.arc(this.x-this.width*.15,this.y-this.height*.21,this.width*.12,0,2*Math.PI,false);
  416.                                                 context.arc(this.x+this.width*.15,this.y-this.height*.21,this.width*.12,0,2*Math.PI,false);
  417.                                                 context.fill();
  418.                                                 context.closePath();
  419.                                                 context.fillStyle = '#000';
  420.                                                 context.beginPath();
  421.                                                 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);
  422.                                                 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);
  423.                                                 context.fill();
  424.                                                 context.closePath();
  425.                                         }
  426.                                 }
  427.                         });
  428.                 }
  429.                 items = stage.getItemsByType(2);
  430.                 //主角
  431.                 player = stage.createItem({
  432.                         width:30,
  433.                         height:30,
  434.                         type:1,
  435.                         location:map,
  436.                         coord:{x:13.5,y:23},
  437.                         orientation:2,
  438.                         speed:2,
  439.                         frames:10,
  440.                         update:function(){
  441.                                 var coord = this.coord;
  442.                                 if(!coord.offset){
  443.                                         if(this.control.orientation!='undefined'){
  444.                                                 if(!map.get(coord.x+_COS[this.control.orientation],coord.y+_SIN[this.control.orientation])){
  445.                                                         this.orientation = this.control.orientation;
  446.                                                 }
  447.                                         }
  448.                                         this.control = {};
  449.                                         var value = map.get(coord.x+_COS[this.orientation],coord.y+_SIN[this.orientation]);
  450.                                         if(value==0){
  451.                                                 this.x += this.speed*_COS[this.orientation];
  452.                                                 this.y += this.speed*_SIN[this.orientation];
  453.                                         }else if(value<0){
  454.                                                 this.x -= map.size*(map.x_length-1)*_COS[this.orientation];
  455.                                                 this.y -= map.size*(map.y_length-1)*_SIN[this.orientation];
  456.                                         }
  457.                                 }else{
  458.                                         if(!beans.get(this.coord.x,this.coord.y)){        //吃豆
  459.                                                 _SCORE++;
  460.                                                 beans.set(this.coord.x,this.coord.y,1);
  461.                                                 if(_GOODS[this.coord.x+','+this.coord.y]){        //吃到能量豆
  462.                                                         items.forEach(function(item){
  463.                                                                 if(item.status==1||item.status==3){        //如果NPC为正常状态,则置为临时状态
  464.                                                                         item.timeout = 450;
  465.                                                                         item.status = 3;
  466.                                                                 }
  467.                                                         });
  468.                                                 }
  469.                                         }
  470.                                         this.x += this.speed*_COS[this.orientation];
  471.                                         this.y += this.speed*_SIN[this.orientation];
  472.                                 }
  473.                         },
  474.                         draw:function(context){
  475.                                 context.fillStyle = '#FFE600';
  476.                                 context.beginPath();
  477.                                 if(stage.status!=3){        //玩家正常状态
  478.                                         if(this.times%2){
  479.                                                 context.arc(this.x,this.y,this.width/2,(.5*this.orientation+.20)*Math.PI,(.5*this.orientation-.20)*Math.PI,false);
  480.                                         }else{
  481.                                                 context.arc(this.x,this.y,this.width/2,(.5*this.orientation+.01)*Math.PI,(.5*this.orientation-.01)*Math.PI,false);
  482.                                         }
  483.                                 }else{        //玩家被吃
  484.                                         if(stage.timeout) {
  485.                                                 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);
  486.                                         }
  487.                                 }
  488.                                 context.lineTo(this.x,this.y);
  489.                                 context.closePath();
  490.                                 context.fill();
  491.                         }
  492.                 });
  493.                 //事件绑定
  494.                 stage.bind('keydown',function(e){
  495.                         switch(e.keyCode){
  496.                                 case 13: //回车
  497.                                 case 32: //空格
  498.                                 this.status = this.status==2?1:2;
  499.                                 break;
  500.                                 case 39: //右
  501.                                 player.control = {orientation:0};
  502.                                 break;
  503.                                 case 40: //下
  504.                                 player.control = {orientation:1};
  505.                                 break;
  506.                                 case 37: //左
  507.                                 player.control = {orientation:2};
  508.                                 break;
  509.                                 case 38: //上
  510.                                 player.control = {orientation:3};
  511.                                 break;
  512.                         }
  513.                 });
  514.         })();
  515.         //结束画面
  516.         (function(){
  517.                 var stage = game.createStage();
  518.                 //游戏结束
  519.                 stage.createItem({
  520.                         x:game.width/2,
  521.                         y:game.height*.35,
  522.                         draw:function(context){
  523.                                 context.fillStyle = '#FFF';
  524.                                 context.font = 'bold 48px Helvetica';
  525.                                 context.textAlign = 'center';
  526.                                 context.textBaseline = 'middle';
  527.                                 context.fillText('GAME OVER',this.x,this.y);
  528.                         }
  529.                 });
  530.                 //记分
  531.                 stage.createItem({
  532.                         x:game.width/2,
  533.                         y:game.height*.5,
  534.                         draw:function(context){
  535.                                 context.fillStyle = '#FFF';
  536.                                 context.font = '20px Helvetica';
  537.                                 context.textAlign = 'center';
  538.                                 context.textBaseline = 'middle';
  539.                                 context.fillText('FINAL SCORE: '+(_SCORE+50*Math.max(_LIFE-1,0)),this.x,this.y);
  540.                         }
  541.                 });
  542.                 //事件绑定
  543.                 stage.bind('keydown',function(e){
  544.                         switch(e.keyCode){
  545.                                 case 13: //回车
  546.                                 case 32: //空格
  547.                                 _SCORE = 0;
  548.                                 _LIFE = 3;
  549.                                 var st = game.setStage(1);
  550.                                 st.reset();
  551.                                 break;
  552.                         }
  553.                 });
  554.         })();
  555.         game.init();
  556. })();
四、游戏截图
! n1 s, x& ~: }* D# q0 q# R 2.jpg

  X& A  ]* ?8 M% o 3.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号 )

GMT+8, 2024-5-2 21:55

Powered by paopaomj X3.4 © 2016-2024 sitemap

快速回复 返回顶部 返回列表