2d游戏开发学习笔记(4)-HTML网页游戏开发

风流意气都作罢 提交于 2020-04-05 19:26:41

拼图游戏

效果如下

游戏介绍:将16张小图片随机打乱,拖动小图片可交换位置,顺序完全正确则为成功。 在“游戏”中,单击滑块选择游戏难易,“容易”为3行3列拼图游戏,中间为一个4行4列拼图游戏,“难”为5行5列拼图游戏。拼块以随机顺序排列,玩家用鼠标单击空白块的四周来交换它们的位置,直到所有拼块都回到原位置

程序实现:

js部分:

//获取画图区域
var context=document.getElementById('pintu').getContext('2d');

//创建图片
var img=new Image();
img.src='pintu.jpg';
img.addEventListener('load',drawTiles,false);

//取得图像大小和分成的块数
var boardSize=document.getElementById('pintu').width;
var tileCount=document.getElementById('scale').value;

var tileSize=boardSize/tileCount;

//追踪空白图片位置,记录点击图片位置
var clickLoc=new Object;
clickLoc.x=0;
clickLoc.y=0;

var emptyLoc=new Object;
emptyLoc.x=0;
emptyLoc.y=0;

var solved=false;
//我们使用一个一维数组存储每个拼块的编号。实现拼块的随机排列。而数组的元素顺序打乱使用带有排序函数的Array.sort()方法来实现。
//获取并初始化画板
var boardParts=new Object;
setBoard();

//更改难度相关方法,更改后重新计算大小
document.getElementById('scale').onchange=function(){
    tileCount=this.value;
    tileSize=boardSize/tileCount;
    setBoard();
    drawTiles();
};
//追踪鼠标划过的区域  
document.getElementById('pintu').onmousemove=function(e){
    clickLoc.x=Math.floor((e.pageX-this.offsetLeft)/tileSize);
    clickLoc.y=Math.floor((e.pageY-this.offsetTop)/tileSize);
};
//追踪鼠标点击的区域
document.getElementById('pintu').onclick=function(){
    if (distance(clickLoc.x,clickLoc.y,emptyLoc.x,emptyLoc.y)==1){
        slideTile(emptyLoc,clickLoc);
        drawTiles();
    }
    if(solved){
        setTimeout(function(){alert("你完成了!");},500);
    }
};
//初始化画板函数,模拟n*n的n宫格,使用二维数组创建图片区域
function setBoard(){
    boardParts=new Array(tileCount);
    for(var i=0;i<tileCount;++i) {
        boardParts[i]=new Array(tileCount);
        for (var j=0;j<tileCount;++j){
            boardParts[i][j]=new Object;
            boardParts[i][j].x=(tileCount-1)-i;
            boardParts[i][j].y=(tileCount-1)-j;
        }
    }
    emptyLoc.x=boardParts[tileCount-1][tileCount-1].x;
    emptyLoc.y=boardParts[tileCount-1][tileCount-1].y;
    solved=false;
}
 //drawTiles()函数用于显示各个拼块,该函数判断是否是空白拼图的位置(emptyLoc.x,emptyLoc.y),不是则调用drawlmage()绘制相应图块。
function drawTiles(){
   
    context.clearRect(0,0,boardSize,boardSize);
    for(var i=0;i<tileCount;++i){
        for(var j=0;j<tileCount;++j){
            var x=boardParts[i][j].x;
            var y=boardParts[i][j].y;
            if(i!=emptyLoc.x || j!=emptyLoc.y || solved==true){
                context.drawImage(img,x*tileSize,y*tileSize,tileSize,tileSize,
                    i*tileSize,j*tileSize,tileSize,tileSize);
            }
        }
    }
}
//判断图片是否可移动的方法
function distance(x1,y1,x2,y2) {
    return Math.abs(x1-x2)+Math.abs(y1-y2);
}
//移动拼图相关方法
function slideTile(toLoc,fromLoc){
    //slideTile(emptyLoc,clickLoc)是移动被单击的拼块clickLoc到空块位置emptyLoc。
    //移动拼图的做法是:交换对应的boardParts元素,然后把单击位置设置成空块位置。
    if(!solved){
        boardParts[toLoc.x][toLoc.y].x=boardParts[fromLoc.x][fromLoc.y].x;
        boardParts[toLoc.x][toLoc.y].y=boardParts[fromLoc.x][fromLoc.y].y;
        boardParts[fromLoc.x][fromLoc.y].x=tileCount-1;
        boardParts[fromLoc.x][fromLoc.y].y=tileCount-1;
        toLoc.x=fromLoc.x;
        toLoc.y=fromLoc.y;
        checkSolved();
    }
}
 //一旦拼图移动了,我们还要检查一下拼图是否全部在正确的位置。
function checkSolved(){ //checkSolved()检查是否成功。如果有一个拼块不正确函数就会返回false,否则返回true。
    var flag=true;
    for(var i=0;i<tileCount;++i){
        for(var j=0;j<tileCount;++j){
            if(boardParts[i][j].x!=i || boardParts[i][j].y!=j){
                flag=false;
            }
        }
    }
    solved=flag;
}

html部分:

<!doctype html>
 <html>
     <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
         <title>拼图游戏</title>
         <style>
             .picture{
                 border:1px solid black;
             }
         </style>
     </head>
     <body>
         <div id="title">
             <h2>拼图游戏</h2>
         </div>
         <div id="slider">
             <form>
                 <label>低</label>
                 <input type="range" id="scale" value="4" min="3" max="5" step="1">
                 <label>高</label>
             </form>
             <br>
         </div>
         <div id="main" class="main">
             <canvas id="puzzle" width="480px" height="480px"></canvas>
         </div>
         <script src="sliding.js"></script>
     </body>
 </html>
 

雷电飞机游戏

玩法介绍:飞机射击游戏是一款好玩的基于html5 canvas制作的战斗机射击类网页小游戏。操作简单,适用于PC端,键盘上下左右键移动方向,空格键发射消灭敌机。

js代码

var canvas=document.getElementById('myCanvas');
			var context=canvas.getContext('2d');
			document.addEventListener('keydown',onKeydown);
			//飞机类和其属性
			var Plan=function(image,x,y,n){
				this.image=image;
				this.x=x;
				this.y=y;
				this.orignx=x;
				this.origny=y;
				this.width=image.width/n;
				this.height=image.height;
				this.isCaught=false;
				this.frm=0;
				this.dis=0;
				this.n=n;
			};
			Plan.prototype.getCaught=function(bool){
				this.isCaught=bool;
				if (bool==false){
					this.orignx=0;
					this.origny=this.y;
				}
			};
			Plan.prototype.testPoint=function(x,y){
				var betweenX=(x>=this.x)&&(x<=this.x+this.width);
				var betweenY=(y>=this.y)&&(y<=this.y+this.height);
				return betweenX&&betweenY;
			};
			

			Plan.prototype.move=function(dx,dy){
				this.x+=dx;
				this.y+=dy;
			};
			Plan.prototype.Y=function(){
				return this.y;
			};
			//不断下移飞机
			Plan.prototype.draw=function(ctx){
				ctx.save();
				ctx.translate(this.x,this.y);
				ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height);
				ctx.restore();
				this.y++;
				this.x=this.orignx+20*Math.sin(Math.PI/100*this.y);
				this.dis++;
				if(this.dis>=3){
					this.dis=0;
					this.frm++;
					if(this.frm>=this.n) this.frm=0;
				}
			};
			//原地不动画飞机
			Plan.prototype.draw2=function(ctx){
				ctx.save();
				ctx.translate(this.x,this.y);
				ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height);
				ctx.restore();
				this.dis++;
				//3帧换一次图片
				if(this.dis>=3){
					this.dis=0;
					this.frm++;
					if(this.frm>=this.n) this.frm=0;
				}
			};
			//检测飞机碰撞
			Plan.prototype.hitTestObject=function(planobj){
				if(iscolliding(this.x,this.y,this.width,this.height,planobj.x,planobj.y,planobj.width,planobj.height))
					return true;
				else
					return false;
			}

			function iscolliding(ax,ay,aw,ah,bx,by,bw,bh){
				if(ay>by+bh||by>ay+ah||ax>bx+bw||bx>ax+aw)
					return false;
				else
					return true;
			}
			//子弹类和其属性
			var Bullet=function(image,x,y){
				this.image=image;
				this.x=x;
				this.y=y;
				this.orignx=x;
				this.orignx=y;
				this.width=image.width/4;
				this.height=image.height;
				this.isCaught=false;
				this.frm=0;
				this.dis=0;
			}
			Bullet.prototype.testPoint=function(x,y){
				var betweenX=(x>=this.x)&&(x<this.x+this.width);
				var betweenY=(y>=this.y)&&(y<this.y+this.height);
				return betweenX&&betweenY;
			};
			Bullet.prototype.move=function(dx,dy){
				this.x+=dx;
				this.y+=dy;
			};
			Bullet.prototype.Y=function(){
				return this.y;
			};
			Bullet.prototype.draw=function(ctx){
				ctx.save();
				ctx.translate(this.x,this.y);
				ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height);
				ctx.restore();
				this.y--;
				this.dis++;
				if(this.dis>=10){
					this.dis=0;
					this.frm++;
					if(this.frm>=4) this.frm=0;
				}
			};
			//检测子弹与敌人的碰撞
			Bullet.prototype.hitTestObject=function(planobj){
				if(iscolliding(this.x,this.y,this.width,this.height,planobj.x,planobj.y,planobj.width,planobj.height))
					return true;
				else
					return false;
			}
			//爆炸动画类和属性
			var Bomb=function(image,x,y){
				this.image=image;
				this.x=x;
				this.y=y;
				this.width=image.width/6;
				this.height=image.height;
				this.frm=0;
				this.dis=0;
			};


			Bomb.prototype.draw2=function(ctx){
				ctx.save();
				ctx.translate(this.x,this.y);
				if(this.frm>=6) return ;
				ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height);
				ctx.restore();
				this.dis++;
				if(this.dis>=10){
					this.dis=0;
					this.frm++;
				}
			};
			var plan1,plan2,plan3,plan4,caughtplan=null;
			var isClick=false;
			var mouseX,mouseY,preX,preY;
			var plans=[];
			var bullets=[];
			var bombs=[];
			var score=0;
			var overflag=false;
			var myplane;
			//导入外部材料图
			var image=new Image();
			var image2=new Image();
			var image3=new Image();
			var image4=new Image();
			var image5=new Image();
			var bakground=new Image();
			bakground.src='map_0.png';
			image.src='plan.png';
			image.onload=function(){

			}
			image2.src='bomb.png';
			image2.onload=function(){

			}
			image3.src='enemy.png';
			image3.onload=function(){
				myplane=new Plan(image,300*Math.random(),400,6);

				plan_interval=setInterval(function(){
					plans.push(new Plan(image,300*Math.random(),20*Math.random(),2));
				},3000);//3秒产生一架敌机
				setInterval(function(){
					context.clearRect(0,0,320,480);
					context.drawImage(bakground,0,0);
				//画己方飞机
					if(!overflag)
						myplane.draw2(context);
				//画敌机
					for(var i=plans.length-1;i>=0;i--){
						if (plans[i].Y()>400){
							plans.splice(i,1);//删除敌机
						}
						else{
							plans[i].draw(context);
						}
					}
				//画子弹
					for (var i=bullets.length-1;i>=0;i--){
						if (bullets[i].Y()<100){
							bullets.splice(i,1);//删除子弹
						}
						else{
							bullets[i].draw(context);
						}
					}
				//检测玩家是否撞到敌机
					for (vari=plans.length-1;i>=0;i--){
						e1=plans[i];
						if(e1!=null && myplane!=null && myplane.hitTestObject(e1)){
							clearInterval(plan_interval);
							plans.splice(i,1);//删除敌机
							bombs.push(new Bomb(image2,myplane.x,myplane.y));

							message_txt.innerHTML='敌机碰到玩家自己飞机,游戏结束';
							overflag=true;
						}
					}
			//判断子弹击中没有
					for(var j=bullets.length-1;j>=0;j--){
						var b1=bullets[j];
						for(var i=plans.length-1;i>=0;i--){
							e1=plans[i];
							if (e1!=null && b1!=null && b1.hitTestObject(e1)){
								plans.splice(i,1);
								bullets.splice(i,1);
								bombs.push(new Bomb(image2,b1.x,b1.y-36));

								message_txt.innerHTML='敌机被击中,加20分';
								score+=20;
								score_txt.innerHTML='分数:'+score+'分';
							}
						}
					}
				//画爆炸
					for (var i=bombs.length-1;i>=0;i--){
						if (bombs[i].frm>=6){
							bombs.splice(i,1);
						}
						else{
							bombs[i].draw2(context);
						}
					}

				},1000/60);
			};
			image4.src='bullet.png';
			image4.onload=function(){

			};
			//飞机移动控制
			function onKeydown(e){
				if(e.keyCode==32){
					bullets.push(new Bullet(image4,myplane.x,myplane.y-36));
				}else if(e.keyCode==37){
					myplane.move(-10,0);
				}else if(e.keyCode==39){
					myplane.move(10,0);
				}else if(e.keyCode==38){
					myplane.move(0,-10);
				}else if(e.keyCode==40){
					myplane.move(0,10);
				}
			}
		</script>
	</body>
</html>

html代码:

<!DOCTYPE html>
<html>
	<head>
		<title>飞机大战</title>
		<meta charset="utf-8">
	</head>
	<body>
		<canvas id='myCanvas' width="320" height="480" style="border: solid">
			你的浏览器不支持canves画布元素,请更新浏览器获得演示效果。
		</canvas>
		<div id="message_txt" style="display: block;">飞机大战</div>
		<div id="score_txt" style="display: block;">分数:0分</div>
   <script src="sliding.js"></script>
     </body>
 </html>

FlappyBird游戏

效果如下:

玩法介绍: 适用于PC端,鼠标左键点击小鸟使得小鸟可上升移动,小鸟每通过一根油管分数加一分, 若触碰油管游戏结束。

js代码:

var canvas = document.getElementById(“ canvas”);
var c = canvas.getContext(“ 2d”);

函数Bird(x,y,image){
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = image.height,
    this.image = image;
    this.draw = function(context,state){
        if(state ===“ up”)
            context.drawImage(image,0,0,this.width,this.height,this.x,this.y,this.width,this.height);
        其他{
            context.drawImage(image,this.width,0,this,width,this.height,this.x,this.y,this.width,this.height);
        }
    }
};
函数Obstacle(x,y,h,image){
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = h,
    this.flypast = false;
    this.draw = function(context,state){
        if(state ===“ up”)
            context.drawImage(image,0,0,this.width,this.height,this.x,this.y,this.width,this.height);
        其他{
            context.drawImage(图像,此宽度,图像高度,此高度,此高度,此宽度,此高度,此x,此y,此宽度,此高度)
        }
    }
};

函数FlappyBird(){}
FlappyBird.prototype = {
    鸟:null,
    bg:null,
    obs:null,
    obsList:[],

    mapWidth:340,
    mapHeight:453,
    startX:90,
    开始:225,
    距离:150,
    obsSpeed:2
    obsInterval:2000,
    最高速度:8
    降速:3,
    线:56
    得分:0,
    接触:错误,
    gameOver:否,

    CreateMap:function(){
        //背景
        this.bg = new Image();
        this.bg.src =“ bg.png”;
        var startBg = new Image();
        startBg.src =“ start.jpg”;
        startBg.onload = function(){
            c.drawImage(startBg,0,0);
        };
        //小鸟
        var image = new Image();
        image.src =“ bird.png”;
        image.onload = function(){
            this.bird = new Bird(this.startX,this.startY,image);
        } .bind(this);

        //障碍物
        this.obs = new Image();
        this.obs.src =“ obs.png”;
        this.obs.onload = function(){
            var h = 100;
            var h2 = this.mapHeight-h-this.obsDistance;
            var obs1 = new Obstacle(this.mapWidth,0,h,this.obs);
            var obs2 = new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
            this.obsList.push(obs1);
            this.obsList.push(obs2);
        } .bind(this);
    },

    CreatObs:函数(){
        var h = Math.floor(Math.random()*(this.mapHeight-this.obsDistance-this.line));
        var h2 = this.mapHeight-h-this.obsDistance;
        var obs1 = new Obstacle(this.mapWidth,0,h,this.obs);
        var obs2 = new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
        this.obsList.push(obs1);
        this.obsList.push(obs2);

        如果(this.obsList [0] .x <-this.obsList [0] .width)
            this.obsList.splice(0,2);
    },
    DrawObs:function(){
        c.fillStyle =“#00ff00”;
        for(var i = 0; i <this.obsList.length; i ++){
            this.obsList [i] .x- = this.obsSpeed;
            如果(i%2)
                this.obsList [i] .draw(c,“ up”);
            其他
                this.obsList [i] .draw(c,“ down”);
        }
    },
    
    CountScore:function(){
        if(this.obsList [0] .x + this.obsList [0] .width <this.startX && this.obsList [0] .flypast == false){
            this.score + = 1;
            this.obsList [0] .flypast = true;
        }
    },
    ShowScore:function(){
        c.strokeStyle =“#000”;
        c.lineWidth = 1;
        c.fillStyle =“#fff”;
        c.fillText(this.score,10,50);
        c.strokeText(this.score,10,50);
    },
    CanMove:function(){
        if(this.bird.y <0 || this.bird.y> this.mapHeight-this.bird.height-this.line){
            this.gameOver = true;
        }其他{
            var boundary = [{
                x:this.bird.x,
                y:this.bird.y
            },{
                x:this.bird.x + this.bird.width,
                y:this.bird.y
            },{
                x:this.bird.x,
                y:this.bird.y + this.bird.height
            },{
                x:this.bird.x + this.bird.width,
                y:this.bird.x + this.bird.height
            }];
            对于(var i = 0; i <this.obsList.length; i ++){
                for(var j = 0; j <4; j ++)
                    if(boundary [j] .x> = this.obsList [i] .x && boundary [j] .x <= this.obsList [i] .x + this.obsList [i] .width &&
                    boundary [j] .y> = this.obsList [i] .y && boundary [j] .y <= this.obsList [i] .y + this.obsList [i] .height){
                        this.gameOver = false;
                        打破;
                    }
                如果(this.gameOver)
                    打破;
            }
        }
    },
    CheckTouch:function(){
        如果(this.touch){
            this.bird.y- = this.upSpeed;
            this.bird.draw(c,“ up”);
        }其他{
            this.bird.y + = this.downSpeed;
            this.bird.draw(c,“ down”);
        }
    },
    ClearScreen:function(){
        c.drawImage(this.bg,0,0);
    },
    ShowOver:function(){
        var overImg = new Image();
        overImg.src =“ over.png”;
        overImg.onload = function(){
            c.drawImage(overImg,(this.mapWidth-overImg.width)/ 2,(this.mapHeight-overImg.height)/ 2-50);
        } .bind(this);
        返回;
    }
};

var game = new FlappyBird();
var Speed = 20;
var IsPlay = false;
var GameTime = null;
var btn_start;
window.onload = InitGame;

函数InitGame(){
    c.font =“ 3em微软雅黑”;
    game.CreateMap();
    canvas.onmousedown =功能(){
        game.touch = true;
    }
    canvas.onmouseup =功能(){
        game.touch = false;
    };
    canvas.onclick = function(){
        如果(!IsPlay){
            IsPlay = true;
            GameTime = RunGame(Speed);
        }
    }
}


函数RunGame(speed){
    var updateTimer = setInterval(function(){
        game.CanMove();
        if(game.gameOver){
            game.ShowOver();
            clearInterval(updateTimer);
            返回;
        }
        game.ClearScreen();
        game.DrawObs();
        game.CheckTouch();
        game.CountScore();
        game.ShowScore();
    },速度);
    var obsTimer = setInterval(function(){
        如果(game.gameOver){
            clearInterval(obsTimer);
            返回;
        }
        game.CreatObs();
    },game.obsInterval);
}

html代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Flappy Bird</title>
 </head>
 <body>
 <canvas id="canvas" width="340" height="453" style="border: 2px solid #000;background: #fff;"></canvas>
 <script src="bird.js" type="text/javascript"></script>
 </body>
 
 </html>

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!