HTML5 小遊戲開發

HTML的基礎

HTML稱爲超文本標記語言,是一種標識性的語言。它包括一系列標籤.經過這些標籤能夠將網絡上的文檔格式統一,使分散的Internet資源鏈接爲一個邏輯總體。HTML文本是由HTML命令組成的描述性文本,HTML命令能夠說明文字圖形動畫聲音表格連接等。javascript

HTML5是構建Web內容的一種語言描述方式。HTML5是互聯網的下一代標準,是構建以及呈現互聯網內容的一種語言方式.被認爲是互聯網的核心技術之一。HTML產生於1990年,1997年HTML4成爲互聯網標準,並普遍應用於互聯網應用的開發。HTML5是Web中核心語言HTML的規範,用戶使用任何手段進行網頁瀏覽時看到的內容本來都是HTML格式的,在瀏覽器中經過一些技術處理將其轉換成爲了可識別的信息。

 

遊戲案例

【一】人物拼圖

遊戲介紹:將一幅圖片分割成若干拼塊並將它們隨機打亂順序。當將全部拼塊都放回原位置時,就完成了拼圖(遊戲結束)。html

在「遊戲」中,單擊滑塊選擇遊戲難易,「容易」爲3行3列拼圖遊戲,中間爲一個4行4列拼圖遊戲,「難」爲5行5列拼圖遊戲。拼塊以隨機順序排列,玩家用鼠標單擊空白塊的四周來交換它們的位置,直到全部拼塊都回到原位置。java

程序設計的步驟canvas

1. 使用canvas標記建立畫板。數組

var context=document.getElementById('puzzle').getContext('2d');
var img=new Image();
img.src='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;

2. 在JS中編寫主要代碼 瀏覽器

var context=document.getElementById('puzzle').getContext('2d');
//經過調用getContext()方法獲取上下文仕貝面上畫圖
var img=new Image();
img.src='defa.jpg';
img.addEventListener('load',drawTiles,false);
//load’事件是確保圖片完成加載後,再把圖片放入canvas中。drawTiles()函數繪製打亂的圖塊。
var boardSize=document.getElementById('puzzle').width;
var tileCount=document.getElementById('scale').value;

var tileSize=boardSize/tileCount;
//boardSize是canvas的寬度,經過range input設置拼圖的數量tileCount,數據範圍從3到5(幾行幾列)。
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('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(){
    //drawTiles()函數用於顯示各個拼塊,該函數判斷是不是空白拼圖的位置(emptyLoc.x,emptyLoc.y),不是則調用drawlmage()繪製相應圖塊。
    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;
}

3. 新建Html,引入JS和畫布網絡

<!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>

運行截圖:app

         

【二】雷電飛機

遊戲介紹: 上下左右控制飛機移動,空格鍵完成射擊dom

程序設計的步驟  將遊戲種所用到的玩家、敵人、子彈等封裝成類,planobj()來檢測飛機的碰撞ide

1.設置飛機類及其屬性

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;
};
2.不斷刷新對象
 
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;
	}
};

3.檢測飛機的碰撞

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

4.控制飛機的移動

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

參考代碼

<!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 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.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>

運行截圖: 

【三】FlappyBird遊戲

遊戲介紹: 鼠標點擊來控制小鳥,跨越由各類不一樣長度水管所組成的障礙

程序設計步驟:

1. 建立畫布 ,新建bird.js

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

2. 設計類——bird類、 obstacle類

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.height,this.width,this.height,this.x,this.y,this.width,this.height)
        }
    }
};

3. 核心代碼

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,
    upSpeed: 8,
    downSpeed: 3,
    line: 56,
    score: 0,
    touch: false,
    gameOver: false,
    CreateMap: function () {
        //背景
        this.bg = new Image();
        this.bg.src = "img/bg.png";
        var startBg = new Image();
        startBg.src = "img/start.jpg";
        startBg.onload = function () {
            c.drawImage(startBg, 0, 0);
        };
        //小鳥
        var image = new Image();
        image.src = "img/bird.png";
        image.onload = function () {
            this.bird = new Bird(this.startX, this.startY, image);
        }.bind(this);
        //障礙物
        this.obs = new Image();
        this.obs.src = "img/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: 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){
            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.height
            },{
                x:this.bird.x+this.bird.width,
                y:this.bird.x+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=false;
                        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 overImg=new Image();
        overImg.src="img/over.png";
        overImg.onload=function () {
            c.drawImage(overImg,(this.mapWidth-overImg.width)/2,(this.mapHeight-overImg.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);
        }
    }
}

4.新建html,引入畫布和js

<!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>

運行截圖

  

今天的分享就到這啦~    ꒰⑅•ᴗ•⑅꒱

 

相關文章
相關標籤/搜索