一、前言1 w! x }4 o% ]2 Y
很早就知道canvas,当时一直没应用到,最近闲来无事就顺便写写看。吃豆游戏可以说是我们80,90后共同的回忆录,小时候常常在学习机上玩,所以也就有了强烈的欲望去写。为了写这个游戏,看了很多吃豆人游戏的相关信息,包括游戏规则,历史,其它相关游戏设计。又去了各个小游戏平台玩了下,找些灵感!!!就连最简单的配色,也是反复斟酌几个小时确定的方案……哈哈,不容易啊代码分两部分,游戏引擎和游戏主程序,引擎用来类的定义,管理动画场景,事件定义等等……游戏主程序主要组织业务逻辑。算面向对象编程吧,纯手工打造是男人就吃光所有豆子!!! ) b, c8 ~0 T5 V
项目结构4 C6 v3 v; p5 ~
2 {/ p: K7 u; I9 j
因需要四个文件即可实现,index.html 游戏主页,index.js 主页控制,game.js 游戏控制,favicon.png 图标。代码简单,易懂。后续小伙伴们还可以自己加入音乐!可以部署到服务器上,也可用浏览器直接打开index.html玩耍!!!
2 B8 G0 \8 O6 k7 G二、HTML代码+ ^- G* G0 {3 G0 U1 V
- <html>
- <head>
- <meta charset="utf8">
- <title>Pac-Man . 吃豆游戏</title>
- <link rel="shortcut icon" href="favicon.png" rel="external nofollow" >
- <style>
- body{background-color: #292929}
- *{padding:0;margin:0;}
- .wrapper{
- width: 960px;
- margin:0 auto;
- line-height:36px;
- text-align:center;
- color:#999;
- }
- canvas{display:block;background: #000;}
- .mod-botton{
- height: 32px;
- padding: 15px 0;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <div class="wrapper">
- <canvas id="canvas" width="960" height="640">不支持画布</canvas>
- <p>按[空格]暂停或继续</p>
- </div>
- <script src="game.js"></script>
- <script src="index.js"></script>
-
- </body>
- </html>
三、JS代码
. F# b' x9 m E1 u* b: ^2 P3 Q# G- //主程序,业务逻辑
- (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%10);
- 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){ //物体检测
|