成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

VUE實現一個Flappy Bird游戲的示例代碼

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

Flappy Bird是一個非常簡單的小游戲,在app上大家都玩過。這里就用VUE來實現一個簡單的PC版Flappy Bird,娛樂一下~~~~~

要實現這個游戲,首先來分析一下游戲界面里哪幾塊東西需要動起來:

1、第一當然就是上下移動的小鳥;

2、橫向移動的背景圖,讓小鳥看起來在橫向飛行;

3、從畫面右端進入的一排排管道。

這樣很明確了,我們讓上面3塊內容按照規律運動起來,然后再加上規則邊界判斷和計分,就可以得到一個完整的游戲。所以就一塊塊來解決。

先來定義一些常量和變量:

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

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

小鳥本身就是個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; // 小鳥初始位置 position: absolute; left: 300px; top: 300px;}

然后,在什么都不操作的情況下,小鳥從初始位置開始'墜落',小鳥的墜落是一個越落越快的過程,在這里我沒有用物理的重力加速度公式,只是簡單模擬了一個曲線加速過程。這是一個持續的動畫,所以把這個動作放在動畫幀里,即requestAnimationFrame,每一幀的函數定義為loop()。

所以在loop函數中,根據offsetTop和父元素的clientHeight來判斷小鳥是否觸碰到了畫面的上下邊界,是則游戲結束;否,則增加style.top讓小鳥墜落。

loop() { let _this = this; if (_this.jumpFlag) {// 小鳥跳躍_this.jump(); } let top = _this.$refs.bird.offsetTop; if (top > _this.clientHeight - BIRD_WIDTH || top <= 0) {// 碰到邊界,游戲結束_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(); // 管道移動}

游戲中,玩家按下空格鍵,小鳥會向上跳躍一段距離,用this.jumpFlag[true/false]來記錄這一狀態,當按下時,置為true,loop函數中小鳥jump(),在jump到一定距離后,jumpFlag置為false,小鳥開始墜落。

所以,jump函數很容易實現:

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、橫向移動的背景圖

這個比較簡單,就是background-position無限循環切換就行了,位置根據自己下載的背景圖素材寬度決定。

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

經過這兩步,我們就可以得到一個正在飛行的小鳥了,用document.onkeydown監聽空格鍵來切換jumpFlag,如下圖:

VUE實現一個Flappy Bird游戲的示例代碼

3、從右往左一移動進入管道

管道是由上下兩個div組成,每個div通過不同的top: -xx和bottom: -yy實現中間有間隙。

首先實現生成一個隨機間隙管道的函數,管道存放在pipeArr對象數組中:

addPipe(id) { let obj = {}; let top_num = this.sum(10, 170); let height = this.spaceHeight[Math.floor(Math.random() * this.spaceHeight.length) ]; // 隨機選取間隙值 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) { // 隨機n-m之間的數字 return Math.floor(Math.random() * (m - n) + n);}

然后需要將管道移動起來,即loop()中管道移動函數pipesMove(),整個函數實現如下:

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++) {// 判斷一下小鳥是否接觸到了管道,小鳥50*50,left:300px;管道寬100px;管道進入范圍right是width-450到width-300if ( _this.pipeArr[i].right >= _this.clientWidth - 450 && _this.pipeArr[i].right <= _this.clientWidth - 300) { // 該管道進入了小鳥觸碰范圍 let bird_top = _this.$refs.bird.offsetTop; // 12是小鳥圖片素材上下有空白間隙 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) { // 當某個管道剛好在小鳥左邊,證明小鳥通過該管道,根據管道id算出小鳥得分 _this.score = _this.pipeArr[i].id + 1;}_this.pipeArr[i].right = _this.pipeArr[i].right + 2; // 管道每幀移動2px }}

這里做了五件事:

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

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

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

(4)當某一個管道剛好位于小鳥左側時,證明小鳥成功通過,分數+1;

(5)每個管道移動2px像素,數值記錄在right屬性里。

通過DOM里:style設置right就可以使得管道橫向移動了

<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實現一個Flappy Bird游戲的示例代碼

以上就是vue實現flappy bird的思路和核心代碼了,總共也就兩百多行代碼。在我看來,難點主要集中在管道的移動、觸碰判定以及分數計算上。當然代碼里還有很多可以優化的不足點,共勉~~

標簽: Vue
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产欧美日韩视频一区二区| 一区二区欧美国产| 欧美日韩精品三区| 亚洲成人动漫一区| 亚洲高清视频一区| 国产亚洲精品aa午夜观看| 毛片av一区二区| 国产精品美女黄网| 亚洲美女一区二区三区| 影音欧美亚洲| 国产片一区二区| 成人免费精品视频| 国产精品一卡二卡在线观看| 91电影在线观看| 亚洲一区在线观看免费观看电影高清| 国产精品v欧美精品v日本精品动漫| 老色鬼精品视频在线观看播放| 欧美吞精做爰啪啪高潮| 日韩成人一区二区| 久久综合九色综合欧美狠狠| 亚洲成人一区二区在线观看| 一区二区三区免费看| 亚洲欧美日韩在线| 亚洲无玛一区| 国产精品久久久久久久久免费丝袜 | 99国产精品久久久久久久成人热| 国产精品剧情在线亚洲| 国内一区二区三区| 国产精品久久三| 亚洲区国产区| 亚洲精品videosex极品| 亚洲激情自拍| 亚洲另类在线视频| 日韩久久一区二区| 国产日韩欧美一区在线| 亚洲一二三四区| 蜜桃久久精品乱码一区二区| 亚洲午夜影视影院在线观看| 亚洲综合在线视频| 亚洲视频播放| 同产精品九九九| 蜜臀久久99精品久久久久久9 | 免费欧美在线视频| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 亚洲精品日日夜夜| 性xx色xx综合久久久xx| 秋霞av亚洲一区二区三| 91精品国产综合久久久久久久久久| 福利一区福利二区| 亚洲二区精品| 日韩在线播放一区二区| 欧美日韩免费高清一区色橹橹| 国产一区免费电影| www欧美成人18+| 激情久久久久久久| 日韩av一区二区三区| 在线播放一区二区三区| 91小视频在线观看| 亚洲三级视频在线观看| 久久精品五月| 国内一区二区在线| 精品国产一区二区三区不卡| 欧美国产91| 亚洲精选一二三| 欧美色涩在线第一页| 成人黄色777网| 中文字幕一区二区三区色视频| 午夜在线精品| 国产成人精品免费在线| 1区2区3区欧美| 久久精品日产第一区二区三区| 国产精品一二三四区| 国产精品乱码一区二区三区软件 | 欧美xxxxxxxx| 韩国在线一区| 日韩国产精品久久久久久亚洲| 欧美一卡在线观看| 欧美日韩一区二| 亚洲一二三区不卡| 在线成人午夜影院| 欧美一区二区三区在线播放| 亚洲成人动漫在线免费观看| 5858s免费视频成人| 精品av久久久久电影| 琪琪一区二区三区| 中文字幕精品—区二区四季| 丁香桃色午夜亚洲一区二区三区| 国产精品久久久久婷婷| 久久视频一区| www.色综合.com| 亚洲亚洲人成综合网络| 欧美大片免费久久精品三p| 1024亚洲| 国产大片一区二区| 亚洲乱码中文字幕综合| 欧美精品久久一区二区三区| 激情亚洲网站| 精油按摩中文字幕久久| 中文在线一区二区| 欧美亚洲国产一区二区三区 | 美女视频免费一区| 国产精品全国免费观看高清 | 日韩一区二区三区视频在线| 激情综合久久| 国产一区二区三区电影在线观看| 国产精品第五页| 8v天堂国产在线一区二区| 99re66热这里只有精品4| 国产成人午夜99999| 亚洲国产精品久久一线不卡| wwwwxxxxx欧美| 欧美在线一区二区| 最新亚洲一区| av激情成人网| 老色鬼精品视频在线观看播放| 亚洲人一二三区| 欧美电影免费观看完整版| 老牛影视一区二区三区| 色综合天天性综合| 久久国产精品免费| 亚洲精品久久久久久国产精华液| 日韩欧美一区二区视频| 国产精品日韩精品欧美精品| 99久久精品国产精品久久| 日本美女视频一区二区| 一区在线中文字幕| 日韩欧美在线一区二区三区| 色成人在线视频| 99精品免费| 色综合网色综合| 国产综合成人久久大片91| 亚洲一区av在线| 中文字幕电影一区| 日韩欧美国产一区在线观看| 国产精品久久久久9999高清| 99久久er热在这里只有精品15| 久久 天天综合| 亚洲一二三四区| 国产精品不卡在线观看| 欧美精品一区二区在线播放| 欧美日韩精品免费| 香蕉久久久久久久av网站| 黄色亚洲精品| 99久久国产综合精品女不卡| 国产一区二区影院| 日日摸夜夜添夜夜添国产精品| 亚洲蜜臀av乱码久久精品| 久久精品欧美日韩精品| 日韩视频免费直播| 欧洲一区二区av| 色婷婷激情一区二区三区| 国产欧美一级| 一区二区三区av| 亚洲欧洲精品一区二区| 欧美日韩理论| 成人蜜臀av电影| 麻豆久久久久久久| 婷婷一区二区三区| 亚洲一区二区在线视频| 国产精品国产三级国产三级人妇 | av一区二区三区| 国产在线国偷精品免费看| 日韩黄色小视频| 亚洲图片一区二区| 亚洲精品写真福利| 亚洲靠逼com| 综合久久久久久| 国产精品欧美久久久久一区二区| 日韩一区二区三区视频在线观看| 制服丝袜亚洲精品中文字幕| 欧美视频一区在线| 欧美亚洲一区二区三区四区| 色婷婷av一区二区三区gif| 美女网站久久| 国产伦精品一区二区三| 黄色一区二区三区四区| 国内精品视频在线播放| 欧美精品成人| 在线欧美日韩| 亚洲视频二区| 亚洲欧美日韩国产综合精品二区| 丁香啪啪综合成人亚洲小说| 成人午夜视频在线观看| 国产成人鲁色资源国产91色综| 国产一区欧美二区| 国产成人综合在线播放| 大尺度一区二区| 粉嫩蜜臀av国产精品网站| 国产成人av一区二区三区在线| 激情久久五月天| 国产99精品视频| 成年人午夜久久久| 欧美1区2区3区| 亚洲午夜伦理| 亚洲欧美日本日韩| 在线视频一区二区三区| 欧美精品日韩一本| 欧美精品一区二区三区久久久| 日本一区二区久久| 亚洲丝袜精品丝袜在线|