欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS+Canvas實(shí)現(xiàn)接球小游戲的示例代碼

 更新時(shí)間:2022年06月13日 15:47:08   作者:ryyyyy  
本文主要為大家詳細(xì)介紹了如何利用JS+Canvas實(shí)現(xiàn)接球小游戲,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的幫助,感興趣的小伙伴可以了解一下

寫在最前

看了canvas的動(dòng)畫系列,已經(jīng)抑制不住內(nèi)心的沖動(dòng)想寫個(gè)小游戲了,還是那個(gè)套路——多寫寫,你才能了解它。加上這兩天下班后我都沒有機(jī)會(huì)去摸摸籃球,所以就寫了個(gè)接球的小游戲(準(zhǔn)確的說不能叫游戲,太簡單了,叫動(dòng)畫吧...)。 都是一些基礎(chǔ)的實(shí)現(xiàn),有時(shí)間你也可以試試,廢話說到這里,我們開始吧。

git地址

https://github.com/ry928330/ballGame.git

成果展示

實(shí)現(xiàn)思路

這里我們采用疑問的句式給出實(shí)現(xiàn)的思路(步驟),因?yàn)槲覍戇@個(gè)demo的時(shí)候也是這樣去想的:

- canvas上畫一個(gè)小球,如何動(dòng)起來?

- canvas上畫一個(gè)橫條兒,如何像在DOM上那樣去拖動(dòng)它?

- 如何實(shí)現(xiàn)游戲上面的小方塊兒的繪制與刪除?

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

主要就是這4步的實(shí)現(xiàn),然后把他們串接起來,你的簡單接球小動(dòng)畫就實(shí)現(xiàn)了。

詳細(xì)說明

如何讓小球動(dòng)起來

其實(shí)這部分是比較簡單的canvas動(dòng)畫,一個(gè)基本的動(dòng)畫步驟可以歸納為以下幾個(gè)過程:

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

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

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

4.恢復(fù)canvas的狀態(tài),因?yàn)槟阒g對(duì)canvas的信息做了入棧保存,所以此時(shí)你必須restore它。

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

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

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

貼下我的部分代碼:

//ball 對(duì)象用來存儲(chǔ)一個(gè)球
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()函數(shù)里面包含了小球的繪制,小橫條兒的繪制,得分的繪制。 在每次繪制之前都會(huì)清理下整個(gè)canvas,而且講各自的狀態(tài)保存在了各自命名的對(duì)象中,小球會(huì)通過水平和垂直速度不斷改變它x和y的值來改變他的位置。也就形成了運(yùn)動(dòng)的小球。

繪制小橫條兒,怎么像操作DOM一樣去拖動(dòng)它

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

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

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

如何實(shí)現(xiàn)游戲上面的小方塊兒的繪制與刪除?

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

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

上面的函數(shù)返回了一個(gè)二維數(shù)組,數(shù)組里面的元素是對(duì)象,每個(gè)對(duì)象包含了你存儲(chǔ)的小方塊兒的位置以及大小。

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

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

碰撞問題

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

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) 這部分主要判斷兩個(gè)事:&&號(hào)左邊是判斷小球落在橫條兒左邊時(shí),小球的右邊緣必須在橫條所覆蓋的區(qū)域;&&號(hào)右邊是判斷小球落在橫條右邊時(shí),其左側(cè)必須在橫條覆蓋的范圍內(nèi)。接著在滿足上面這個(gè)條件下,(ball.y + ball.vy + ball.radius >= bar.y)判斷小球的高度,球心加上當(dāng)前小球的垂直移動(dòng)速度以及半徑,如果高度值大于等于橫條的垂直高度則碰撞發(fā)生。怎么樣,其實(shí)并沒有想象中的那么難吧,至于小球和canvas邊緣以及小球和上面的小方塊兒碰撞原理和這里一樣,就不再贅述。

關(guān)于計(jì)分以及碰到紅色小塊兒加速問題都是比較簡單的,可以直接看我的代碼,寫到這里整個(gè)demo差不多就實(shí)現(xiàn)了吧。

寫在最后

剛想到寫這個(gè)demo的時(shí)候還感覺有點(diǎn)困難,主要就是想到碰撞可能不好實(shí)現(xiàn)。直到完成后,誒,其實(shí)也挺簡單的哈。各位大佬如果有時(shí)間玩兒玩兒這個(gè)小demo的話(現(xiàn)在只能從git上靠代碼,自己在頁面玩兒),如果存在什么bug之類的歡迎指出哈。(其實(shí)我有點(diǎn)擔(dān)心碰撞邊界的問題,設(shè)置不好會(huì)不會(huì)有什么bug出現(xiàn))接下來,我想試試難度升級(jí),如果有多個(gè)小球呢,不停的重繪 會(huì)不會(huì)導(dǎo)致頁面卡頓,恩,當(dāng)然,這是后話了。

到此這篇關(guān)于JS+Canvas實(shí)現(xiàn)接球小游戲的示例代碼的文章就介紹到這了,更多相關(guān)JS Canvas接球游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS實(shí)現(xiàn)html頁面點(diǎn)擊下載文件的兩種方式

    JS實(shí)現(xiàn)html頁面點(diǎn)擊下載文件的兩種方式

    這篇文章主要介紹了JS實(shí)現(xiàn)html頁面點(diǎn)擊下載文件的兩種方式,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 一文總結(jié)JavaScript中常見的設(shè)計(jì)模式

    一文總結(jié)JavaScript中常見的設(shè)計(jì)模式

    在程序設(shè)計(jì)中有很多實(shí)用的設(shè)計(jì)模式,而其中大部分語言的實(shí)現(xiàn)都是基于“類”。在程序設(shè)計(jì)中有很多實(shí)用的設(shè)計(jì)模式,而其中大部分語言的實(shí)現(xiàn)都是基于“類”。,本文將總結(jié)了JavaScript中常見的十五種設(shè)計(jì)模式,感興趣的朋友可以參考下
    2023-05-05
  • js操作table示例(個(gè)人心得)

    js操作table示例(個(gè)人心得)

    有一個(gè)表格,然后有4個(gè)輸入框,一個(gè)合并按鈕,輸入框是這樣的,從第幾行到第幾行,從第幾列到第幾列,然后點(diǎn)擊按鈕,合并
    2013-11-11
  • 微信小程序?qū)崿F(xiàn)表單驗(yàn)證源碼

    微信小程序?qū)崿F(xiàn)表單驗(yàn)證源碼

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)表單驗(yàn)證源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JavaScript實(shí)現(xiàn)隨機(jī)五位數(shù)驗(yàn)證碼

    JavaScript實(shí)現(xiàn)隨機(jī)五位數(shù)驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)隨機(jī)五位數(shù)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • JS原生雙欄穿梭選擇框的實(shí)現(xiàn)示例

    JS原生雙欄穿梭選擇框的實(shí)現(xiàn)示例

    本文主要介紹了JS原生雙欄穿梭選擇框的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 微信小程序自定義模態(tài)框

    微信小程序自定義模態(tài)框

    這篇文章主要為大家詳細(xì)介紹了微信小程序自定義模態(tài)框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Bootstrap實(shí)現(xiàn)下拉菜單效果

    Bootstrap實(shí)現(xiàn)下拉菜單效果

    這篇文章主要為大家詳細(xì)介紹了Bootstrap實(shí)現(xiàn)下拉菜單效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 5款JavaScript代碼壓縮工具推薦

    5款JavaScript代碼壓縮工具推薦

    這篇文章主要介紹了5款JavaScript代碼壓縮工具推薦,代碼壓縮(也稱代碼最小化)是一個(gè)從源代碼中消除所有不必要的字符的過程,需要的朋友可以參考下
    2014-07-07
  • 小程序獲取周圍IBeacon設(shè)備的方法

    小程序獲取周圍IBeacon設(shè)備的方法

    這篇文章主要為大家詳細(xì)介紹了小程序獲取周圍IBeacon設(shè)備的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10

最新評(píng)論