中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用h5實現打火箭小游戲

發布時間:2021-07-28 17:21:08 來源:億速云 閱讀:132 作者:chen 欄目:云計算

本篇內容介紹了“怎么用h5實現打火箭小游戲”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一.游戲介紹

游戲介紹:
不斷有攜帶字母炸彈的火箭撞向地面,請根據火箭身上的字母敲擊鍵盤,每一次對應的敲擊會擊落攜帶該字母的火箭并使得分加一,每一架火箭撞到地面會使生命值減一,每擊落十架火箭,火箭數會加一,并獎勵一點額外生命值,生命值上限為八。

二.HTML內容

index.html里包含canvas畫布和一個 介紹游戲規則的div,

當鼠標點擊頁面任何一個地方的時候,進入游戲界面:


index

瀏覽器不支持canvas

1.Click space to pause or begin game.
2.Enter the letter on the rockets to hit them.
3.Number of the hearts will add one together with the rockets after ten rockets hit.
4.Failed when the number of hearts equals zero.
5.Click anywhere to start game!

二.JS內容

1.動畫實現

common.js中并未使用setTimeOut()或者setInterval()作為動畫定時器,而是使用window.requestAnimationFrame,一種更為優化的方式實現動畫效果。

requestAnimFrame的用法,先設置瀏覽器的兼容,并設置動畫的幀率,這里設置為每1000/60ms執行一次回調函數

window.requestAnimFrame = (function() {
        return  window.requestAnimationFrame        ||
        window.webkitRequestAnimationFrame          ||
        window.mozRequestAnimationFrame             ||
        window.oRequestAnimationFrame               ||
        window.msRequestAnimationFrame              ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    })();

 requestAnimFrame中的兩個參數,callback為下次重畫執行的函數,element為要重畫的節點,即

requestAnimFrame(callback, element);

2.代碼塊及對象分析

(1) 在Game代碼塊控制游戲的開始、結束和重新開始以及動畫的運行和鼠標、鍵盤點擊事件的判定

Game.begin(),游戲開始界面,點擊任意位置,調用Game.run()函數進入游戲運行界面

Game.run(),游戲運行界面,這里使用自定義兼容函數requestAnimFrame不斷回調Game.transform()函數對畫布重繪,并調用鍵盤點擊監聽函數Game.hit(event),判斷按鍵是否擊中火箭

Game.over(),游戲結束界面,顯示游戲得分、游戲中獎勵的生命值和最終火箭數,點擊任意位置會調用Game.restart()函數初始化游戲參數并調用Game.begin()進入游戲開始界面

(2) Background代碼塊用于繪制背景,默認樣式為垂直方向灰度加深的漸變色

(3) Hearts代碼塊,根據全局變量heartsNum設置生命值的數量,初始為5,通過迭代和設置水平偏移量offSetX創建hearts數組中對象的位置屬性,而Heart對象則要保存位置和半徑屬性。另外,Heart對象中設置draw()函數進行自繪,而Hearts代碼塊中設置draw()函數控制hearts數組中所有對象的自繪 ,以此實現動畫運行時生命值的狀態管理 。

(4) Rockets代碼塊負責繪制小火箭們,火箭數量由全局變量rocketsNum控制,初始為5,火箭的具體繪制由Rocket對象完成,在這里Rocket對象的狀態是隨機產生的,Rockets代碼塊中的rockets數組負責保存所有Rocket對象的狀態。Rockets代碼塊控制所有Rocket對象的自繪,并在鍵盤敲擊時,循環遍歷數組中的對象以判斷火箭是否被擊中。

(5) TextNodes代碼塊負責繪制文本,TextNodes.setup()函數負責設置文本的內容、位置、字體、樣式和字符的偏移量,當然也可以不進行設置,這時會采用默認值。TextNode對象保存單個字符的內容和位置信息并負責文本的自繪,TextNodes代碼塊會負責所有nodes數組中的對象的自繪。

(6) start函數負責從介紹游戲規則的界面轉到游戲開始界面。

下面就不多說了,貼代碼common.js:

window.onload=function(){
	var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");
	canvas_width=canvas.width;
	canvas_height=canvas.height;

	var heartsNum=5;//生命值數
	var extraHearts=0;//額外增加的生命值數
	var rocketsNum=5;//火箭數
	var score=0;//得分數

	window.requestAnimFrame = (function() {
        return  window.requestAnimationFrame        ||
        window.webkitRequestAnimationFrame          ||
        window.mozRequestAnimationFrame             ||
        window.oRequestAnimationFrame               ||
        window.msRequestAnimationFrame              ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
	})();

	var Game={
		animationID:0,//animationID,flag控制暫停和開始
		flag:true,

		begin:function(){
			ctx.clearRect(0,0,canvas_width,canvas_height);

			Background.draw("yellow");

			TextNodes.setup("HitRocket",100,240,"96px 楷體,arial","#000");
			TextNodes.draw();
			TextNodes.setup("Click anywhere to start",150,360,"42px 楷體,arial","#000");
			TextNodes.draw();

			Rockets.init();
			Hearts.init();

			window.addEventListener("click",Game.run);
		},

		//緩沖,移除監聽器
		run:function(){
			window.removeEventListener("click",Game.run);
			Game.transform();

			window.addEventListener("keyup",Game.hit);
		},

		transform:function(){
			if(heartsNum>0){
				Game.animationID=requestAnimationFrame(Game.transform);

				//清空畫布
				ctx.clearRect(0,0,canvas_width,canvas_height);

				//背景
				Background.draw();

				//計分
				TextNodes.setup("Score:"+score,640,50,"42px 楷體,arial","#f00",20);
				TextNodes.draw();

				//火箭
				Rockets.transform();
				Rockets.modify();
				Rockets.draw();

				//生命值
				Hearts.modify();
				Hearts.draw();

			}else Game.over();
		},

		hit:function(event){
			event = (event)?event:window.event;

			if(event.keyCode==32)
				//暫停開始
				if(Game.flag){
					Game.flag=false;
					window.cancelAnimationFrame(Game.animationID);
				}else{
					Game.flag=true;
					requestAnimationFrame(Game.transform);
				}
			else if(event.keyCode>=65&&event.keyCode<=90)
				//打擊火箭
				Rockets.loopHit(String.fromCharCode(event.keyCode));
		},

		over:function(){
			window.removeEventListener("keyup",Game.hit);

			Background.draw("#000");

			TextNodes.setup("Game Over!",100,120,"96px 楷體,arial","#f00");
			TextNodes.draw();
			TextNodes.setup("Click anywhere to retry!",120,200,"48px 楷體,arial","#f00");
			TextNodes.draw();
			TextNodes.setup("Score:"+score,240,320,"90px 楷體,arial","#f00");
			TextNodes.draw();
			TextNodes.setup("Extra hearts:"+extraHearts,120,420,"42px 楷體,arial","#f00",25);
			TextNodes.draw();
			TextNodes.setup("Total rockets:"+rocketsNum,120,500,"42px 楷體,arial","#f00",25);
			TextNodes.draw();

			window.addEventListener("click",Game.restart);
		},

		restart:function(){
			window.removeEventListener("click",Game.restart);

			//init
			heartsNum=5;
			extraHearts=0;
			rocketsNum=5;
			score=0;

			Game.begin();
		}
	}

	//繪制背景
	//有傳入繪制樣式,則使用該樣式,否則使用默認樣式,垂直加深灰色漸變
	var Background={
		draw:function(fillStyle){
			if(fillStyle)
				ctx.fillStyle=fillStyle;
			else{
				var grd=ctx.createLinearGradient(0,0,0,canvas_height);
				grd.addColorStop(0,"#ccc");
				grd.addColorStop(1,"#777");
				ctx.fillStyle=grd;
			}
			ctx.fillRect(0,0,canvas_width,canvas_height);
		}
	}

	//繪制生命值
	var Heart=function(x,y){
		//不能初始化
		var x,y,radius;

		this.x=x;
		this.y=y;
		this.radius=20;

		this.draw=function(){
			ctx.beginPath();
			ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
			ctx.closePath();

			var grd=ctx.createRadialGradient(this.x,this.y,0,this.x,this.y,this.radius);
			grd.addColorStop(1,"#f00");
			grd.addColorStop(0,"#fff");
			ctx.fillStyle=grd;

			ctx.fill();
		}
	}

	//管理生命值的初始化和數量變化
	var Hearts={
		hearts:null,
		x:50,
		y:40,
		offSetX:50,
		init:function(){
			this.hearts=new Array();
			for(var i=0;i<heartsNum;i++)//按水平偏移排列生命值
				this.hearts[i]=new Heart(this.x+i*this.offSetX,this.y);
		},
		modify:function(){
			//修改生命值數量
			if(heartsNum<this.hearts.length)
				for(var i=heartsNum;i<this.hearts.length;i++)
					this.hearts[i]=null;
			else 
				for(var i=this.hearts.length;i<heartsNum;i++)
					this.hearts[i]=new Heart(this.x+i*this.offSetX,this.y);
		},
		draw:function(){
			for(var i=0;i<this.hearts.length;i++)
				this.hearts[i].draw();
		}
	}

	var Rocket=function(scale){
		var str="ABCDEFGHIJKLMNOPQRSTUVWSYZ";
		var x,y,scale,letter,speed,fontColor;

		this.init=function(scale){
			this.x=Math.random()*(canvas_width-20)+10;
			this.y=Math.random()*canvas_height/5*2;
			this.scale=scale;
			//隨機生成火箭體上的字母
			this.letter=str[Math.floor(Math.random()*26)];
			this.speed=Math.random()*2+1;
			this.fontColor="#000";
		}

		this.init(scale);

		this.draw=function(){

			ctx.save();
			ctx.translate(this.x,this.y);
			ctx.scale(this.scale,this.scale);

			//火箭火焰
			ctx.beginPath();
			ctx.moveTo(0,-80);
			ctx.lineTo(-25,0);
			ctx.lineTo(-10,30);
			ctx.lineTo(10,30);
			ctx.lineTo(25,0);
			ctx.closePath();
			var fire=ctx.createLinearGradient(-25,0,25,0);
			fire.addColorStop(0.2,"#f00");
			fire.addColorStop(0.5,"#f80");
			fire.addColorStop(0.8,"#f00");
			ctx.fillStyle=fire;
			ctx.fill();

			//火箭身體
			ctx.beginPath();
			ctx.moveTo(-10,30);
			ctx.lineTo(-30,160);
			ctx.lineTo(0,200);
			ctx.lineTo(30,160);
			ctx.lineTo(10,30);
			ctx.closePath();
			var body=ctx.createLinearGradient(-30,0,30,0);
			body.addColorStop(0.01,"#fff");
			body.addColorStop(0.5,"#00f");
			body.addColorStop(0.99,"#fff");
			ctx.fillStyle=body;
			ctx.fill();

			//火箭窗戶
			ctx.fillStyle="#ade";
			ctx.fillRect(-10,150,12,20);

			//火箭文字
			ctx.fillStyle=this.fontColor;
			ctx.font="42px bold 楷體,arial";

			ctx.fillText(this.letter,-12,120);

			ctx.restore();

		}

		this.hit=function(key){
			//判斷是否擊中火箭
			//若擊中,分數+1,重置火箭
			if(this.letter==key){
				score++;
				
				//每擊中10個火箭,生命值+1,上限為8,火箭數+1,無上限
				if(score%10==0&&heartsNum<8){
					heartsNum++;
					extraHearts++;
					rocketsNum++;
				}

				//擊中時重置火箭屬性
				this.init(this.scale);
				return true;
			}
			return false;
		}

		this.move=function(){
			//火箭沒有被擊落,重置火箭屬性,生命值-1
			if(this.y>=canvas_height){
				this.init(this.scale);
				heartsNum--;
			}//即將超出屏幕范圍的時候,進行預警,火箭體上的字母變為紅色
			else if(this.y>canvas_height/7*5)
				this.fontColor="#f00";
			this.y+=this.speed;
		}
	}

	//管理火箭的初始化,數量變化,運動
	var Rockets={
		rockets:null,
		scale:0.4,//控制火箭的大小
		init:function(){
			this.rockets=new Array();
			for(var i=0;i<rocketsNum;i++)
				this.rockets[i]=new Rocket(this.scale);
		},
		draw:function(){
			for(var i=0;i<this.rockets.length;i++)
				this.rockets[i].draw();
		},
		transform:function(){
			for(var i=0;i<this.rockets.length;i++)
				this.rockets[i].move();
		},
		modify:function(){
			//修改火箭數量
			for(var i=this.rockets.length;i<rocketsNum;i++)
				this.rockets[i]=new Rocket(this.scale);
		},
		loopHit:function(key){
			for(var i=0;i<this.rockets.length;i++)
				if(this.rockets[i].hit(key))
					//如果擊中火箭,退出循環
					break;
		}
	}

	//繪制文本的單個字符
	var TextNode=function(txt,x,y){
		var txt,x,y;

		this.txt=txt;
		this.x=x;
		this.y=y;

		this.setup=function(txt,x,y){
			this.txt=txt;
			this.x=x;
			this.y=y;
		}

		this.draw=function(){
			ctx.fillText(this.txt,this.x,this.y);
		}
	}

	//管理字符串屬性的變化和繪制
	var TextNodes={
		nodes:null,
		x:100,
		y:200,
		offSetX:60,
		font:"96px 楷體,arial",
		fillStyle:"#000",
		setup:function(txt,x,y,font,fillStyle,offSetX){
			this.x=x;
			this.y=y;
			this.font=font;
			this.fillStyle=fillStyle;
			//可選參數,字符的偏移
			this.offSetX=offSetX?offSetX:(canvas_width-2*x)/txt.length;

			this.nodes=new Array();
			for(var i=0;i<txt.length;i++)
				this.nodes[i]=new TextNode(txt[i],this.x+i*this.offSetX,this.y);
		},
		draw:function(){
			ctx.font=this.font;
			ctx.fillStyle=this.fillStyle;

			for(var i=0;i<this.nodes.length;i++)
				this.nodes[i].draw();
		}
	}

	var start=function(){
		document.getElementById("ins").style.display="none";
		Game.begin();
		window.removeEventListener("click",start);
	}

	//點擊介紹,開始游戲
	window.addEventListener("click",start);
};

“怎么用h5實現打火箭小游戲”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

h5
AI

桃园县| 桐梓县| 淮安市| 阜南县| 阿瓦提县| 北辰区| 明星| 温宿县| 从化市| 桃江县| 莆田市| 乐东| 天峨县| 古田县| 清原| 西乌珠穆沁旗| 疏附县| 徐汇区| 同仁县| 苍溪县| 庐江县| 南川市| 长武县| 沙河市| 永康市| 凤台县| 宿迁市| 胶南市| 汤阴县| 龙门县| 井冈山市| 兴安县| 舞阳县| 霍林郭勒市| 九江县| 武穴市| 桐城市| 台中县| 桃源县| 延吉市| 黑山县|