av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

VUE實(shí)現(xiàn)一個(gè)Flappy Bird游戲的示例代碼

瀏覽:3日期:2022-09-30 16:43:36

Flappy Bird是一個(gè)非常簡(jiǎn)單的小游戲,在app上大家都玩過(guò)。這里就用VUE來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的PC版Flappy Bird,娛樂(lè)一下~~~~~

要實(shí)現(xiàn)這個(gè)游戲,首先來(lái)分析一下游戲界面里哪幾塊東西需要?jiǎng)悠饋?lái):

1、第一當(dāng)然就是上下移動(dòng)的小鳥(niǎo);

2、橫向移動(dòng)的背景圖,讓小鳥(niǎo)看起來(lái)在橫向飛行;

3、從畫(huà)面右端進(jìn)入的一排排管道。

這樣很明確了,我們讓上面3塊內(nèi)容按照規(guī)律運(yùn)動(dòng)起來(lái),然后再加上規(guī)則邊界判斷和計(jì)分,就可以得到一個(gè)完整的游戲。所以就一塊塊來(lái)解決。

先來(lái)定義一些常量和變量:

let rafId = null; // requestAnimationFrame的IDlet startSpeed = 1;const SPEED = 0.04; // 加速度const UP = 5.0; // 速度累加上限const UP_SUM = 30; // 按一次跳躍的高度const BIRD_WIDTH = 50; // 小鳥(niǎo)圖片寬50pxconst PIPE_DISTANCE = 350; // 管道之間的橫向距離let id = 0; // 管道唯一id,從0開(kāi)始計(jì)數(shù) ... data() { return { start: false, clientWidth: 0, clientHeight: 0, spaceHeight: [240, 200, 160], // 上管道與下管道之間的距離 pipeArr: [], // 管道數(shù)組 score: 0, // 得分 jumpSum: 0, // 當(dāng)前跳躍相對(duì)高度 jumpFlag: false, // true-按下空格鍵跳躍上升階段;false-自由落體階段 dropBirdImg: require('@/assets/img/bird/bird0_0.png'), flyBirdImg: require('@/assets/img/bird/bird0_2.png'), gameOver: false, // 游戲失敗的flag,用于停止動(dòng)畫(huà)幀 };},1、上下移動(dòng)的小鳥(niǎo)

為了分別控制小鳥(niǎo)和管道的位置,元素定位均采用position: absolute

小鳥(niǎo)本身就是個(gè)div+背景圖,然后定義一下在界面里的初始位置:

<div ref='bird'></div> #bird { height: 50px; width: 50px; border-radius: 50%; background: url('~assets/img/bird/bird0_1.png') no-repeat center/contain; // 小鳥(niǎo)初始位置 position: absolute; left: 300px; top: 300px;}

然后,在什么都不操作的情況下,小鳥(niǎo)從初始位置開(kāi)始'墜落',小鳥(niǎo)的墜落是一個(gè)越落越快的過(guò)程,在這里我沒(méi)有用物理的重力加速度公式,只是簡(jiǎn)單模擬了一個(gè)曲線加速過(guò)程。這是一個(gè)持續(xù)的動(dòng)畫(huà),所以把這個(gè)動(dòng)作放在動(dòng)畫(huà)幀里,即requestAnimationFrame,每一幀的函數(shù)定義為loop()。

所以在loop函數(shù)中,根據(jù)offsetTop和父元素的clientHeight來(lái)判斷小鳥(niǎo)是否觸碰到了畫(huà)面的上下邊界,是則游戲結(jié)束;否,則增加style.top讓小鳥(niǎo)墜落。

loop() { let _this = this; if (_this.jumpFlag) {// 小鳥(niǎo)跳躍_this.jump(); } let top = _this.$refs.bird.offsetTop; if (top > _this.clientHeight - BIRD_WIDTH || top <= 0) {// 碰到邊界,游戲結(jié)束_this.resetGame(); } else if (!_this.jumpFlag) {_this.$refs.bird.style.background = `url(’${_this.dropBirdImg}’) no-repeat center/contain`;_this.$refs.bird.style.top = top + startSpeed * startSpeed + 'px'; // 模擬加速墜落if (startSpeed < UP) { startSpeed += SPEED;} } _this.pipesMove(); // 管道移動(dòng)}

游戲中,玩家按下空格鍵,小鳥(niǎo)會(huì)向上跳躍一段距離,用this.jumpFlag[true/false]來(lái)記錄這一狀態(tài),當(dāng)按下時(shí),置為true,loop函數(shù)中小鳥(niǎo)jump(),在jump到一定距離后,jumpFlag置為false,小鳥(niǎo)開(kāi)始?jí)嬄洹?/p>

所以,jump函數(shù)很容易實(shí)現(xiàn):

jump() { let _this = this; _this.$refs.bird.style.background = `url(’${_this.flyBirdImg}’) no-repeat center/contain`; if (_this.jumpSum > UP_SUM) {// 到頂部就落下_this.jumpFlag = false;_this.jumpSum = 0;startSpeed = 1; } else {_this.$refs.bird.style.top = _this.$refs.bird.offsetTop - 8 + 'px';_this.jumpSum += 8; }}2、橫向移動(dòng)的背景圖

這個(gè)比較簡(jiǎn)單,就是background-position無(wú)限循環(huán)切換就行了,位置根據(jù)自己下載的背景圖素材寬度決定。

animation: bgMove 8s linear infinite; @keyframes bgMove {0% { background-position: 805px 0;}100% { background-position: 0 0;}}

經(jīng)過(guò)這兩步,我們就可以得到一個(gè)正在飛行的小鳥(niǎo)了,用document.onkeydown監(jiān)聽(tīng)空格鍵來(lái)切換jumpFlag,如下圖:

VUE實(shí)現(xiàn)一個(gè)Flappy Bird游戲的示例代碼

3、從右往左一移動(dòng)進(jìn)入管道

管道是由上下兩個(gè)div組成,每個(gè)div通過(guò)不同的top: -xx和bottom: -yy實(shí)現(xiàn)中間有間隙。

首先實(shí)現(xiàn)生成一個(gè)隨機(jī)間隙管道的函數(shù),管道存放在pipeArr對(duì)象數(shù)組中:

addPipe(id) { let obj = {}; let top_num = this.sum(10, 170); let height = this.spaceHeight[Math.floor(Math.random() * this.spaceHeight.length) ]; // 隨機(jī)選取間隙值 let bottom_num = height - top_num; obj.top = top_num; obj.id = id; obj.right = -(PIPE_DISTANCE / 2); obj.bottom = bottom_num; this.pipeArr.push(obj);},sum(m, n) { // 隨機(jī)n-m之間的數(shù)字 return Math.floor(Math.random() * (m - n) + n);}

然后需要將管道移動(dòng)起來(lái),即loop()中管道移動(dòng)函數(shù)pipesMove(),整個(gè)函數(shù)實(shí)現(xiàn)如下:

pipesMove() { let _this = this; if (_this.pipeArr.length === 0) {return; } let right0 = _this.pipeArr[0].right; if (right0 > this.clientWidth + 300) {this.pipeArr.shift(); } let right_last = _this.pipeArr[_this.pipeArr.length - 1].right; if (right_last >= PIPE_DISTANCE / 2) {id++;this.addPipe(id); } for (let i = 0; i < _this.pipeArr.length; i++) {// 判斷一下小鳥(niǎo)是否接觸到了管道,小鳥(niǎo)50*50,left:300px;管道寬100px;管道進(jìn)入范圍right是width-450到width-300if ( _this.pipeArr[i].right >= _this.clientWidth - 450 && _this.pipeArr[i].right <= _this.clientWidth - 300) { // 該管道進(jìn)入了小鳥(niǎo)觸碰范圍 let bird_top = _this.$refs.bird.offsetTop; // 12是小鳥(niǎo)圖片素材上下有空白間隙 if ( bird_top <= _this.clientHeight / 2 - _this.pipeArr[i].top - 12 || bird_top >= _this.clientHeight / 2 + _this.pipeArr[i].bottom - BIRD_WIDTH + 12 ) { // 碰到了管道 _this.resetGame(); return; }}if (_this.pipeArr[i].right === _this.clientWidth - 300 && _this.pipeArr[i].right === _this.clientWidth - 301) { // 當(dāng)某個(gè)管道剛好在小鳥(niǎo)左邊,證明小鳥(niǎo)通過(guò)該管道,根據(jù)管道id算出小鳥(niǎo)得分 _this.score = _this.pipeArr[i].id + 1;}_this.pipeArr[i].right = _this.pipeArr[i].right + 2; // 管道每幀移動(dòng)2px }}

這里做了五件事:

(1)管道出了左邊畫(huà)面后shift()最左的管道;

(2)最右的管道離畫(huà)面右側(cè)一定距離后,加入新的一根管道;

(3)循環(huán)遍歷中,判斷小鳥(niǎo)是否進(jìn)入了某一根管道的范圍,判斷小鳥(niǎo)top是否有觸碰到上下管道,觸碰則輸;

(4)當(dāng)某一個(gè)管道剛好位于小鳥(niǎo)左側(cè)時(shí),證明小鳥(niǎo)成功通過(guò),分?jǐn)?shù)+1;

(5)每個(gè)管道移動(dòng)2px像素,數(shù)值記錄在right屬性里。

通過(guò)DOM里:style設(shè)置right就可以使得管道橫向移動(dòng)了

<section ref='pipes'> <div v-for='(item, index) in pipeArr' :key='item.id' : : > <div : ></div> <div : ></div> </div></section> .pipes-wrap {position: relative;height: 100%;overflow: hidden;.pipe-item { position: absolute; height: 100%; width: 100px; .pipe { width: 100%; height: 50%; position: relative; } .pipe-top { background: url(’'~assets/img/bird/pipe_down.png’) no-repeat; background-size: 100px; background-position: bottom; } .pipe-bottom { background: url(’'~assets/img/bird/pipe_up.png’) no-repeat; background-size: 100px; background-position: top; }}}

VUE實(shí)現(xiàn)一個(gè)Flappy Bird游戲的示例代碼

以上就是vue實(shí)現(xiàn)flappy bird的思路和核心代碼了,總共也就兩百多行代碼。在我看來(lái),難點(diǎn)主要集中在管道的移動(dòng)、觸碰判定以及分?jǐn)?shù)計(jì)算上。當(dāng)然代碼里還有很多可以優(yōu)化的不足點(diǎn),共勉~~

標(biāo)簽: Vue
相關(guān)文章:
主站蜘蛛池模板: 日韩网站在线观看 | a在线视频| 中文字幕亚洲区 | 成人一级黄色毛片 | 欧美久久久久久久久 | 成人毛片一区二区三区 | 日日操av| 欧美性另类 | 亚洲国产成人精品在线 | 中文字幕亚洲精品 | 欧美国产一区二区 | www亚洲精品 | av网站免费观看 | 国产精品一区在线观看你懂的 | 91精品国产综合久久久亚洲 | 黄色精品 | 中文字幕日韩在线 | 国产精品观看 | 日韩欧美视频免费在线观看 | 亚洲h色| 久久国产精品视频 | 国产精品成人一区二区三区 | av在线播放免费 | av在线免费观看网站 | 亚洲精品一区二区二区 | 日韩精品在线网站 | 欧美一级久久精品 | 日韩三级| 欧美在线观看一区 | 操操日 | 最新国产视频 | 久久99这里只有精品 | 一区二区三区高清 | 欧美精品一区二区三区一线天视频 | 国产在线播放av | 久久国 | 日本一区二区三区免费观看 | 夜夜爽99久久国产综合精品女不卡 | 嫩草视频在线免费观看 | 国产福利91精品一区二区三区 | 91福利网 |