2D游戏开发——HTML5和JavaScript

为君一笑 提交于 2020-08-04 18:37:29

基于HTML5的游戏制作
本次实验为验证性作业,代码为老师所给。
拼图游戏 游戏介绍:拼图游戏将一幅图片分割咸若干拼块并将它们随机打乱顺序,当将所有拼块都放回原位置时,就完成了拼图(游戏结束)。此拼图可调节难度,增加或减少块数。
HTML代码如下:

<!doctype html>
<html>
<head>
<meta 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>
</body>
<script src="js/sliding.js"></script>
</html>

JavaScript代码如下:

var context = document.getElementById('puzzle').getContext('2d');

var img = new Image();
img.src = 'images/defa.jpg'
img.addEventListener('load',drawTiles,false);

var boardSize = document.getElementById('puzzle').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;

var boardParts = new Object;
setBoard();

document.getElementById('scale').onchange = function(){
	tileCount = this.value;
	tileSize = boardSize / tileCount;
	setBoard();
	drawTiles();
};

document.getElementById('puzzle').onmousemove = function(e){
	clickLoc.x = Math.floor((e.pageX - this.offsetLeft) / tileSize);
	clickLoc.y = Math.floor((e.pageY - this.offsetTop) / tileSize);
};

document.getElementById('puzzle').onclick = function(){
	if(distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1){
		slideTile(emptyLoc, clickLoc);
		drawTiles();
	}
	if(solved){
		setTimeout(function(){alert("You solved it!");}, 500);
	}
};

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;
}

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){
	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(){
	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;
}

雷电飞机设计游戏
游戏介绍:经典小游戏,飞机从上向下出现,玩家操控自己的飞机发射激光,破坏敌机,自己的飞机被破坏游戏结束。
代码如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>飞机大战</title>
</head>
<body>
<canvas id="myCanvas" width="320" height="480" style="border: solid">
	你的浏览器不支持canvas画布元素,请更新浏览器获得演示效果。
</canvas>
<div id="message_txt" style="display: block;">飞机大战</div>
<div id="score_txt" style="display: block;">分数:0分</div>
<script type="text/javascript">
	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.originX=x;
		this.originY=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.originX=0;
			this.originY=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.originX+20*Math.sin(Math.PI/100*this.y);
		this.dis++;
		if(this.dis>=3){//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++;
		if(this.dis>=3){//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.originX=x;
		this.originY=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){//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){//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;//游戏是否结束,true为结束
	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='images/map_0.png';
	image.src='images/plan.png';//自己飞机图片
	image.onload=function(){

	}
	image2.src='images/bomb.png';//爆炸图片
	image2.onload=function(){

	}
	image3.src='images/enemy.png';//敌机图片
	image3.onload=function(){
		myplane=new Plan(image,300*Math.random(),400,6);
		plan_interval=setInterval(function(){
			plans.push(new Plan(image3,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='images/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>


FlappyBird游戏
游戏介绍:鼠标点击开始游戏,并控制小鸟的飞翔,躲避障碍物,飞向终点。
HTML代码如下:

<!doctype html>
<html>
<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="js/bird.js" type="text/javascript"></script>
</body>
</html>

JavaScript代码如下:

var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
//三个类,Bird类,Obstacle类,FlappyBird类(游戏主要函数)
function 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);
		else
			context.drawImage(image, this.width, 0, this.width, this.height, this.x, this.y, this.width, this.height);
	}
};
function 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);
		else
			context.drawImage(image, this.width, image.height - this.height, this.width, this.height, this.x, this.y, this.width, this.height);
	}
};
//FlappyBird类包括了游戏主要参数及运行时需要的函数
function FlappyBird(){}
FlappyBird.prototype = {
	bird: null, //小鸟
	bg: null, //背景图
	obs: null, //障碍物
	obsList: [],
	
	mapWidth: 340, //画布宽度
	mapHeight: 453, //画布高度
	startX: 90, //起始位置
	startY: 225, 
	obsDistance: 150, //上下障碍物距离
	obsSpeed: 2, //障碍物移动速度
	obsInterval: 2000, //制造障碍物间隔ms
	upSpeed: 8, //上升速度
	downSpeed: 3, //下降速度
	line: 56, //地面高度
	score: 0, //得分
	touch: false, //是否触摸
	gameOver: false,
	
	/*变化参数可以改变游戏难度。
	函数列表:
	CreateMap: function(){}
	CreateObs: function(){}
	DrawObs: function(){}
	CountScore: function(){}
	ShowScore: function(){}
	CanMove: function(){}
	CheckTouch: function(){}
	ClearScreen: function(){}
	ShowOver: function(){}
	*/
	
	CreateMap: function(){
		//背景
		this.bg = new Image();
		this.bg.src = "images/flappybird/bg.png";
		var startBg = new Image();
		startBg.src = "images/flappybird/start.jpg";
		// 由于Image异步加载,在加载完成时绘制图像
		startBg.onload = function(){
			c.drawImage(startBg, 0, 0);
		};
		
		//小鸟
		var image = new Image();
		image.src = "images/flappybird/bird.png";
		image.onload = function(){
			this.bird = new Bird(this.startX, this.startY, image);
			//this.bird.draw(c, "down");
		}.bind(this);
		
		//障碍物
		this.obs = new Image();
		this.obs.src = "images/flappybird/obs.png";
		this.obs.onload = function(){
			var h =100; //默认第一障碍物上管道高度为100
			var h2 = this.mapHeight - h - this.obsDistance;
			var obs1 = new Obstacle(this.mapWidth, this.mapHeight - h2, h2 - this.line, 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)
	},
	CreateObs: function(){
		//随机产生障碍物上管道高度
		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);
		
		//移除越界障碍物
		if(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;
			if(i % 2)
				this.obsList[i].draw(c, "up");
			else
				this.obsList[i].draw(c, "down");
		}
	},
	CountScore: function(){//计分
		if(this.obsList[0].x + this.obsList[0].width < this.startX && this.obsList[0].flypast==false){
			//小鸟坐标超过obsList[0]障碍物
			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;
		}else{
			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.width,
			},{
				x: this.bird.x + this.bird.width,
				y: this.bird.y + this.bird.height
			}];
			for(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 = true;
							break;
						}
				if(this.gameOver)
					break;
			}
		}
	},
	CheckTouch: function(){
		if(this.touch){
			this.bird.y -= this.upSpeed;
			this.bird.draw(c, "up")
		}else{
			this.bird.y += this.downSpeed;
			this.bird.draw(c, "down")
		}
	},
	ClearScreen: function(){
		c.drawImage(this.bg, 0, 0);
	},
	ShowOver: function(){
		var overImag = new Image();
		overImag.src = "images/flappybird/over.png";
		overImag.onload = function(){
			c.drawImage(overImag, (this.mapWidth - overImag.width) / 2, (this.mapHeight - overImag.height) / 2 - 50);
		}.bind(this);
		return;
	}
};

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

function InitGame(){
	c.font = "3em 微软雅黑";
	game.CreateMap();
	canvas.onmousedown = function(){
		game.touch = true;
	}
	canvas.onmouseup = function(){
		game.touch = false;
	};
	canvas.onclick = function(){
		if(!IsPlay){
			IsPlay = true;
			GameTime = RunGame(Speed);
		}
	}
}
//游戏运行函数
function RunGame(speed){
	var updateTimer = setInterval(function(){
		//若小鸟通过第一个障碍物启动记分器
		game.CanMove();
		if(game.gameOver){
			game.ShowOver();
			clearInterval(updateTimer);
			return;
		}
		game.ClearScreen();
		game.DrawObs();
		game.CheckTouch();
		game.CountScore();
		game.ShowScore();
	}, speed);
	var obsTimer = setInterval(function(){
		if(game.gameOver){
			clearInterval(obsTimer);
			return;
		}
		game.CreateObs();
	}, game.obsInterval);
}

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