亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

怎么使用JS+Canvas實現接球小游戲

發布時間:2022-06-14 09:59:07 來源:億速云 閱讀:132 作者:iii 欄目:開發技術

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

成果展示

怎么使用JS+Canvas實現接球小游戲

實現思路

這里我們采用疑問的句式給出實現的思路(步驟),因為我寫這個demo的時候也是這樣去想的:

- canvas上畫一個小球,如何動起來?

- canvas上畫一個橫條兒,如何像在DOM上那樣去拖動它?

- 如何實現游戲上面的小方塊兒的繪制與刪除?

- 碰撞問題:小球與canvas邊界之間怎么去判斷碰撞?小球與小橫條之間怎么去判斷碰撞?小球與上方的小方塊兒之間怎么去判斷碰撞?(其實原理差不多)

主要就是這4步的實現,然后把他們串接起來,你的簡單接球小動畫就實現了。

詳細說明

如何讓小球動起來

其實這部分是比較簡單的canvas動畫,一個基本的動畫步驟可以歸納為以下幾個過程:

1.清除canvas:在每次畫新的圖形的時候,你都必須將之前的圖形給清理掉,這樣才有那種一幀一幀的重繪的感覺。

2.保存當前的state:在你沒走一步時,你都需要將你當前的canvas狀態給保存下來,狀態包括:當前圖形的位置(x,y軸的信息),當前圖形的大小(寬高信息),當前圖形的變化(也就是你對他做了拉伸,角度變化等等)等信息。

3.重新渲染你在當前位置所要繪制的圖形,也就是把你現在想畫的東西給它畫在你的canvas上。

4.恢復canvas的狀態,因為你之間對canvas的信息做了入棧保存,所以此時你必須restore它。

你以為這樣就可以了嗎?哈哈哈,并沒有。加入我們把上面的四個步驟封裝在一個名字叫draw的函數中,這時要讓繪制的圖形動起來,還需要借住下面三個函數之一:

setInterval(function, delay),setTimeout(function, delay),requestAnimationFrame(callback)

相信學習前端的小朋友對前兩個都不陌生,我就不說了,我說說后面這個函數,之前我也沒接觸這個函數,而且該次demo用的就是這個函數:requestAnimationFrame函數會告訴瀏覽器你希望執行動畫,并請求瀏覽器調用指定的函數(也就是你傳入的回調函數)在下一次重繪之前更新動畫。如果你想做逐幀動畫的時候,你應該用這個方法,所以當你把draw函數作為會調傳入requestAnimationFrame,你的draw函數就會不斷的執行。

貼下我的部分代碼:

//ball 對象用來存儲一個球
var ball = {
	x: 150,
	y: 200,
	vx: 5, //水平速度
	vy: 5, //垂直速度
	radius: 20,
	color: 'blue',
	draw: function() {
		ctx.beginPath();
		ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
		ctx.closePath();
		ctx.fillStyle = this.color;
		ctx.fill();
	}
};
function draw() {
	ctx.clearRect(0,0, canvas.width, canvas.height);
	ball.draw();
	bar.draw();
	scores.draw();
	targetRectangle.draw();
	ball.x += ball.vx;
	ball.y += ball.vy;
	animationJudge = window.requestAnimationFrame(draw);
	...
}

draw()函數里面包含了小球的繪制,小橫條兒的繪制,得分的繪制。 在每次繪制之前都會清理下整個canvas,而且講各自的狀態保存在了各自命名的對象中,小球會通過水平和垂直速度不斷改變它x和y的值來改變他的位置。也就形成了運動的小球。

繪制小橫條兒,怎么像操作DOM一樣去拖動它

在canvas上是沒法兒那么自如的操作DOM元素,但是我們卻能對canvas本身進行事件監聽,拿到位置信息。所以跟DOM中拖拽的實現類似,在鼠標移動過程中不斷的統計移動的距離,然后改變橫條兒的位置, 重新繪制它來達到拖動的效果,照例貼代碼:

canvas.addEventListener('mousedown', function(e) {
		if (!beginGame) {
			draw();
			beginGame = true;
		}
		var x = e.clientX;
		var y = e.clientY;
		//判斷拖拽的位置
		if ((x >=bar.x && x <= bar.x + bar.width) && (y >= bar.y && y <= bar.y + bar.height) ) {
			bar.barDragJudge = true;
			bar.xDistance = x;
		}

	})
	canvas.addEventListener('mousemove', function(e) {
		if (bar.barDragJudge) {
			var x = e.clientX;
			var distance = x - bar.xDistance;
			if (bar.x + distance + 60 >= canvas.width) {
				if (distance >= 0) {
					distance = 0;
				}
			} else if (bar.x + distance <= 10) {
				if (distance <= 0) {
					distance = 0;
				}
			}
			bar.x += distance;
			bar.xDistance = x;


		}
	})
	window.addEventListener('mouseup', function(e) {
		bar.barDragJudge = false;
	})

監聽mousedown事件,當鼠標按下并且鼠標位置是和橫條所覆蓋的位置重合(當然在我們開始游戲后,會繪制一次橫條兒,即頁面相應位置會出現橫條兒)時,我將拖拽標志barDragJudge設置為true,表示可以進行拖拽了。然后在鼠標移動過程中通過計算鼠標移動的距離更新橫條兒的位置,完成橫條的拖動,并且判斷當橫條移動到canvas邊界之后不能左拖和右拖。最后,結束點擊,將barDragJudge設置為false。

如何實現游戲上面的小方塊兒的繪制與刪除?

其實,光是繪制小方塊兒并不能難,你就寫一個二維數組,存儲你要繪制的矩形方塊兒的信息,貼下我的代碼:

function initialTargetRectangleArr() {
		var targetRectangleArr = [];
		for (var i = 0; i < 4; i++) {
			targetRectangleArr[i] = [];
			for (var j = 0; j < 4; j++) {
				targetRectangleArr[i][j] = {};
				targetRectangleArr[i][j].x = 35 + j*(50 + 10);
				targetRectangleArr[i][j].y = 35 + i*(20 + 10);
				targetRectangleArr[i][j].width = 50;
				targetRectangleArr[i][j].height = 20;
			}
		}
		return targetRectangleArr;
	}

上面的函數返回了一個二維數組,數組里面的元素是對象,每個對象包含了你存儲的小方塊兒的位置以及大小。

接下來說下小方塊兒的刪除,這里我們先假設小球碰到了我們的小方塊兒,碰到之后我們需要講該方塊兒擦除掉,

即借用clearRect函數,然后問題來了,你只是降頁面的方塊兒擦除掉了,但是方塊兒還是在的,這時我采取的辦法是降方塊兒"移出"我的canvas,然后將他的寬高都設置為0。

碰撞問題

這個是本次DEMO的關鍵問題了,該如何去判斷小球和各種東西之間的碰撞呢?我們這里拿小球和底部小橫條兒的碰撞來說明下。 其實碰撞的核心在于位置,你要準確的拿到橫條兒在canvas中的覆蓋區域,然后小球在進入這個區域后就當作是發生了碰撞。照理,貼下代碼(關鍵部分就一句話):

if ((ball.x + ball.vx >= bar.x - ball.radius && ball.x + ball.vx - ball.radius <= bar.x + bar.width) && (ball.y + ball.vy + ball.radius >= bar.y)) {
		ball.vy = -ball.vy;
	}

我們稍微來解析下,(ball.x + ball.vx >= bar.x - ball.radius && ball.x + ball.vx - ball.radius <= bar.x + bar.width) 這部分主要判斷兩個事:&&號左邊是判斷小球落在橫條兒左邊時,小球的右邊緣必須在橫條所覆蓋的區域;&&號右邊是判斷小球落在橫條右邊時,其左側必須在橫條覆蓋的范圍內。接著在滿足上面這個條件下,(ball.y + ball.vy + ball.radius >= bar.y)判斷小球的高度,球心加上當前小球的垂直移動速度以及半徑,如果高度值大于等于橫條的垂直高度則碰撞發生。怎么樣,其實并沒有想象中的那么難吧,至于小球和canvas邊緣以及小球和上面的小方塊兒碰撞原理和這里一樣,就不再贅述。

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

向AI問一下細節

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

AI

炉霍县| 集安市| 平远县| 辰溪县| 句容市| 惠州市| 进贤县| 高密市| 桂平市| 大新县| 娄烦县| 雅江县| 花垣县| 吴桥县| 波密县| 蓬安县| 梁山县| 通渭县| 额济纳旗| 阿拉善右旗| 巧家县| 东丰县| 阳新县| 临洮县| 石景山区| 庆元县| 应城市| 安龙县| 剑阁县| 白银市| 新乐市| 疏附县| 石阡县| 开远市| 武城县| 通河县| 青海省| 项城市| 家居| 广水市| 油尖旺区|