<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          這個(gè)厲害了,用前端重返童年??

          共 26237字,需瀏覽 53分鐘

           ·

          2021-09-24 23:46

          點(diǎn)擊上方關(guān)注 前端技術(shù)江湖一起學(xué)習(xí),天天進(jìn)步


          前言 — 背景介紹

          國產(chǎn) 3A 游戲情懷

          了解我的朋友都知道,我是一個(gè)很喜歡玩游戲的人,我甚至還六一兒童節(jié)發(fā)表過兒童節(jié)雜談?dòng)螒蛴洃洝渡C(jī)5》[1],小時(shí)候玩的游戲也不少,從插卡游戲機(jī)到ps3,ps4也都有經(jīng)歷過。

          我們這些玩著國外3A游戲長大的孩子一直有一個(gè)小小的愿望(其實(shí)是大大的夢(mèng)想),就是玩到屬于我們的國產(chǎn)3A游戲,并且不僅僅是由國人開發(fā),國人制作,而是包含著中國的文化底蘊(yùn),我們有著五千年深厚的歷史文化,我們的游戲應(yīng)該做到文化輸出,讓世界的游戲玩家看到中國的游戲,中國的文化,中國的魅力。

          大家會(huì)不會(huì)覺得上面的話很熟悉,沒錯(cuò),國產(chǎn)動(dòng)畫同理,小時(shí)候看著日漫美漫長大的孩子們一直也是在期待著國產(chǎn)動(dòng)畫崛起,突然那一年,大圣歸來,身穿虎虎生風(fēng)黃金甲,身披炙熱烈焰火紅袍,手掄天河定底神珍鐵。為國產(chǎn)動(dòng)漫電影打開了新的道路,但是后面的大圣歸來游戲不盡如人意,然而去年游戲科學(xué)出了黑神話悟空的預(yù)告,今年又出了虛幻5引擎的新版預(yù)告。看得我熱血沸騰,上次是大圣,這是又是大圣,悟空要開辟我熱愛的游戲產(chǎn)業(yè)的國產(chǎn)3A新道路了。「此處因?yàn)楹?? 太過熱血沸騰,于是有了這篇文章,和這幾百行代碼

          image.png

          玩游戲的孩子長大了,成為了工程師

          時(shí)間回到現(xiàn)在,沒錯(cuò),寒草看完演示視頻久久不能平靜的現(xiàn)在,現(xiàn)在的寒草?? 褪去稚氣,成為了一個(gè)在前端行業(yè)摸爬滾打一年的工程師,今天中午和朋友去吃好吃的(沒錯(cuò),周末一定要有好吃的啊~),和他我說了很多黑神話悟空的消息,我越說越激動(dòng),心想,那我用我的技術(shù),來表達(dá)我那一份對(duì)國產(chǎn)游戲的期待與對(duì)游戲?qū)η岸诵袠I(yè)的熱愛吧。

          為大家?guī)碛腥さ那岸藘?nèi)容,用前端去做更好玩的事情,一直是我的初心。一路以來,感謝有你們??

          正篇 — 用前端重返童年

          image.png

          我之前沒有用過canvas,也是一點(diǎn)一點(diǎn)寫的,代碼質(zhì)量不要吐槽哈~因?yàn)槲抑肋@一次代碼質(zhì)量不行??

          Hancao present to Game Science in 2021.

          既然要出的是一個(gè)有情懷的前端作品,我也是花了很長時(shí)間在設(shè)計(jì)上,也試了很多方法去體現(xiàn)我的創(chuàng)意,但是效果并不是很好,邊coding邊摸索,最終就出來了本次作品的設(shè)計(jì),正如我的標(biāo)題所說,夢(mèng)回童年的前端作品,效仿的便是老一代插卡游戲機(jī)中游戲的開機(jī)動(dòng)畫,不知道現(xiàn)在從事前端行業(yè)的伙伴年紀(jì)如何,但是像我這樣剛?cè)胄幸荒甑男氯硕家娺^,大家應(yīng)該,八成,或許,大概,也都見過吧...

          下面讓我們一起見證,寒草用 前端技術(shù) 將 黑神話悟空 與 童年游戲經(jīng)典開始動(dòng)畫結(jié)合的作品吧

          這是前端工程師寒草在2021年獻(xiàn)給游戲科學(xué)創(chuàng)作者們的禮物

          重返80年代馬賽克化的悟空

          image.png

          既然我們要重返童年,那么我們這個(gè)圖片要緊跟時(shí)代啊,哪可以這么清晰。回想一下那個(gè)年代的游戲都是一個(gè)色塊一個(gè)色塊的馬賽克,所以我們需要把悟空'馬賽克化'

          我們先搞一個(gè)canvas

          <canvas id="my-canvas-monkey-king"></canvas>
          復(fù)制代碼

          之后我們?cè)诋嫴紝?dǎo)入圖片,并獲取點(diǎn)陣信息,并間隔12像素去獲取顏色并繪制

          // 顯示孫悟空
          let canvas2 = document.getElementById("my-canvas-monkey-king");
          let ctx2 = canvas2.getContext("2d");

          var image2 = new Image();
          image2.src = "monkey-king.jpeg";
          image2.width = 700;
          image2.height = 700;

          image2.onload = function () {
              canvas2.width = image2.width;
              canvas2.height = image2.height;
              ctx2.drawImage(image2, 00);
              var imageData2 = ctx2.getImageData(00, image2.width, image2.height).data;
              // 將畫布背景圖黑
              ctx2.fillStyle = "#000";
              ctx2.fillRect(00, image2.width, image2.height);
              var gap = 12;
              for (var h = 0; h < image2.height; h += gap) {
                for (var w = 0; w < image2.width; w += gap) {
                  var position = (image2.width * h + w) * 4;
                  var r = imageData2[position], g = imageData2[position + 1], b = imageData2[position + 2];
                  // 因?yàn)槲矣玫脑瓐D背景不是純黑的,所以我直接篩除rgb相加小于165的點(diǎn)(為什么是165呢,因?yàn)?00是整數(shù),255 * 3 - 600 = 165)
                  if (765 - (r + g + b) < 600) {
                    ctx2.fillStyle = `rgb(${r}${g}${b})`;
                    ctx2.fillRect(w, h, gap, gap);
                  }
                }
              }

          }
          復(fù)制代碼

          文字動(dòng)效設(shè)計(jì):悟空!出來吧~

          悟空動(dòng)圖.gif

          這里做了一個(gè)logo馬賽克化并且逐行繪制的效果,馬賽克化的方法和之前一致,這個(gè)逐行繪制其實(shí)加入了一些細(xì)節(jié),越到上面繪制起來越快,有點(diǎn)像一層層摞起來的文字一樣~

          我們?cè)俑阋粋€(gè)canvas

          <canvas id="my-canvas-wukong"></canvas>
          復(fù)制代碼

          之后我們獲取圖片信息,按行存儲(chǔ)在數(shù)組里,之后用定時(shí)器去獲取每一行的信息,逐行繪制,每一次執(zhí)行定時(shí)器的回調(diào)方法的時(shí)候也要記得減少定時(shí)器的時(shí)長。

          let canvas = document.getElementById("my-canvas-wukong");
          let ctx = canvas.getContext("2d");

          var image = new Image();
          image.src = "wukong.png";
          image.width = 240;
          image.height = 240;

          image.onload = function () {
          canvas.width = image.width;
          canvas.height = image.height;
          ctx.drawImage(image, 00);
          var imageData = ctx.getImageData(00, image.width, image.height).data;
          ctx.fillStyle = "#000";
          ctx.fillRect(00, image.width, image.height);
          let pointPixels = [];
          let rowPoints = [];

          for (var h = image.height - 3; h >= 0; h -= 3) {
            if (h !== image.height - 3) {
              pointPixels.push(rowPoints);
              rowPoints = [];
            }
            for (var w = image.width - 3; w >= 0; w -= 3) {
              var position = (image.width * h + w) * 4;
              var r = imageData[position], g = imageData[position + 1], b = imageData[position + 2];
              if (r + g + b !== 0) {
                rowPoints.push([w, h]);
              }

            }
          }
          ctx.fillStyle = "#fff";
          let index = 0;
          const length = pointPixels.length;
          let delay = 30;
          const fn = () => {
            let timer = setTimeout(() => {
              clearTimeout(timer);
              if (index != length) {
                const rowPoints = pointPixels[index];
                for (const rowPoint of rowPoints) {
                  ctx.fillRect(rowPoint[0], rowPoint[1], 33);
                }
                delay = delay - 0.125;
                index++;
                fn();
              } else {
                const dom = document.getElementById('operation');
                dom.style.opacity = 1;
              }
            }, delay)
          }
          fn();
          }
          復(fù)制代碼

          夢(mèng)回童年的游戲菜單

          之后我們來設(shè)計(jì)一下我們的操作界面,我們先去回顧一下那些老游戲的界面:

          image.png

          emm,看上去我們已經(jīng)把上面的title做完了,要設(shè)計(jì)下面操作菜單了,我也是按照經(jīng)典的來:

          image.png

          這里文字用了文字陰影效果。下面的單人游玩和多人游玩使用了金箍棒作為選擇指針~我想金箍棒也是悟空的標(biāo)志了。下面還要留下我的署名:Hancao present to Game Science in 2021.,是不是就有游戲廠商注冊(cè)商標(biāo)那感覺了~

          <style>
          #operation {
                position: absolute;
                left30vw;
                top55vh;
                width40vw;
                height300px;
                text-align: center;
                transition: all 2s;
                opacity0;
              }

              #title {
                color: white;
                font-size40px;
                font-weight800;
                text-shadow8px 8px 8px #888888;
                cursor: pointer;
                text-decoration: none;
              }

              .select {
                margin-top32px;
                text-align: left;
                padding-left160px;
              }

              .option {
                overflow: hidden;
              }

              .op {
                display: inline-block;
                overflow: hidden;
                line-height45px;
                font-size30px;
                font-weight600;
                text-shadow8px 8px 8px #888888;
                color#fff;
              }

              .jingubang {
                display: inline-block;
                height20px;
                width8px;
                background-color#555151;
                border-top10px solid #7c7469;
                border-bottom10px solid #7c7469;
                margin-right16px;
              }

              .placeholder {
                display: inline-block;
                height20px;
                width8px;
                margin-right16px;
              }

              .hancao {
                font-size8px;
                margin-top48px;
                color#fff;
              }
          </style>

          <div id="operation">
              <a id="title" href="https://www.heishenhua.com">
                BLACKMYTH WUKONG
              </a>
              <div class="select">
                <div class="option">
                  <div class="jingubang"></div>
                  <div class="op">
                    1 PLAYER
                  </div>
                </div>
                <div class="option">
                  <div class="placeholder"></div>
                  <div class="op">
                    2 PLAYERS
                  </div>
                </div>
              </div>
              <div class="hancao">
                Hancao present to Game Science in 2021.
              </div>
          </div>
          復(fù)制代碼

          完整代碼在此,復(fù)制粘貼,與我一同重返童年

          完整代碼在此,大家可以復(fù)制粘貼,記得 vscode 下載live server插件來運(yùn)行,否則,canvas存在圖片代理問題

          tip: 完整效果見頭圖。代碼質(zhì)量堪憂,首先是canvas不太會(huì),而且我是邊設(shè)計(jì)邊編碼的,所以代碼結(jié)構(gòu)沒有經(jīng)過設(shè)計(jì)~

          <!DOCTYPE html>
          <html lang="en">

          <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>wukong</title>
            <style>
              body {
                margin0;
                background-color#000;
              }
              #my-canvas-wukong {
                position: absolute;
                margin-left50vw;
                margin-top20vh;
                width16vw;
                height32vh;
              }

              #my-canvas-monkey-king {
                position: absolute;
                margin-left30vw;
                margin-top20vh;
                width16vw;
                height32vh;
              }

              #operation {
                position: absolute;
                left30vw;
                top55vh;
                width40vw;
                height300px;
                text-align: center;
                transition: all 2s;
                opacity0;
              }

              #title {
                color: white;
                font-size40px;
                font-weight800;
                text-shadow8px 8px 8px #888888;
                cursor: pointer;
                text-decoration: none;
              }

              .select {
                margin-top32px;
                text-align: left;
                padding-left160px;
              }
              
              .option {
                overflow: hidden;
              }

              .op {
                display: inline-block;
                overflow: hidden;
                line-height45px;
                font-size30px;
                font-weight600;
                text-shadow8px 8px 8px #888888;
                color#fff;
              }

              .jingubang {
                display: inline-block;
                height20px;
                width8px;
                background-color#555151;
                border-top10px solid #7c7469;
                border-bottom10px solid #7c7469;
                margin-right16px;
              }

              .placeholder {
                display: inline-block;
                height20px;
                width8px;
                margin-right16px;
              }

              .hancao {
                font-size8px;
                margin-top48px;
                color#fff;
              }
            </style>

          </head>

          <body>
            <canvas id="my-canvas-wukong">
            </canvas> 
            <canvas id="my-canvas-monkey-king">
            </canvas>
            <div id="operation">
              <a id="title" href="https://www.heishenhua.com">
                BLACKMYTH WUKONG
              </a>
              <div class="select">
                <div class="option">
                  <div class="jingubang"></div> 
                  <div class="op">
                    1 PLAYER
                  </div>
                </div>  
                <div class="option">
                  <div class="placeholder"></div>
                  <div class="op">
                    2 PLAYERS
                  </div>
                </div>  
              </div>
              <div class="hancao">
                Hancao present to Game Science in 2021.
              </div>
            </div>
            <script>
              setTimeout(() => {
                let canvas = document.getElementById("my-canvas-wukong");
              let ctx = canvas.getContext("2d");

              var image = new Image();
              image.src = "wukong.png";
              image.width = 240;
              image.height = 240;

              image.onload = function () {
                canvas.width = image.width;
                canvas.height = image.height;
                ctx.drawImage(image, 00);
                var imageData = ctx.getImageData(00, image.width, image.height).data;
                ctx.fillStyle = "#000";
                ctx.fillRect(00, image.width, image.height);
                let pointPixels = [];
                let rowPoints = [];

                for (var h = image.height - 3; h >= 0; h -= 3) {
                  if(h !== image.height - 3 ){
                    pointPixels.push(rowPoints);
                    rowPoints = [];
                  }
                  for (var w = image.width - 3; w >= 0; w -= 3) {
                    var position = (image.width * h + w) * 4;
                    var r = imageData[position], g = imageData[position + 1], b = imageData[position + 2];
                    if (r + g + b !== 0) {
                      rowPoints.push([w, h]);
                    }

                  }
                }
                ctx.fillStyle = "#fff";
                let index = 0;
                const length = pointPixels.length;

                let delay = 30;
                const fn = () => {
                  let timer = setTimeout(() => {
                    clearTimeout(timer);
                    if(index != length){
                      const rowPoints = pointPixels[index];
                      for(const rowPoint of rowPoints){
                        ctx.fillRect(rowPoint[0], rowPoint[1], 33);
                      }
                      delay = delay - 0.125;
                      index++;
                      fn();
                    } else {
                      const dom = document.getElementById('operation');
                      dom.style.opacity = 1;
                    }
                }, delay)
                }
                fn();
              }

              // 顯示孫悟空
              let canvas2 = document.getElementById("my-canvas-monkey-king");
                      let ctx2 = canvas2.getContext("2d");

                      var image2 = new Image();
                      image2.src = "monkey-king.jpeg";
                      image2.width = 700;
                      image2.height = 700;

                      image2.onload = function () {
                        console.log(image2, canvas2, ctx2);
                        canvas2.width = image2.width;
                        canvas2.height = image2.height;
                        ctx2.drawImage(image2, 00);
                        var imageData2 = ctx2.getImageData(00, image2.width, image2.height).data;
                        console.log(imageData2)
                        ctx2.fillStyle = "#000";
                        ctx2.fillRect(00, image2.width, image2.height);
                        
                        var gap = 12;

                        for (var h = 0; h < image2.height; h+=gap) {
                            for(var w = 0; w < image2.width; w+=gap){
                                    var position = (image2.width * h + w) * 4;
                                    var r = imageData2[position], g = imageData2[position + 1], b = imageData2[position + 2];
                                    if(765 - (r + g + b) < 600) {
                                      ctx2.fillStyle = `rgb(${r}${g}${b})`;
                                      ctx2.fillRect(w,h,gap,gap);
                                    }
                            }
                        }
                      }
              }, 5000);

            </script>

          </body>

          </html>
          復(fù)制代碼

          結(jié)束語 — 熱愛,所以期待

          image.png

          首先,文章中關(guān)于游戲和前端的看法僅僅代表我的主觀想法,歡迎評(píng)論區(qū)指正,以及感謝大帥老師[2]的文章與代碼對(duì)我有思路上的指引~

          本篇文章到此就結(jié)束了,我們不需要去捧殺黑神話悟空,持續(xù)期待就好了。以及大家或許能從我的文章看出我們可以用技術(shù)去完成很多很多好玩的事情,我也希望我的存在可以為前端開發(fā)者帶來更多的創(chuàng)造力,更多的idea,讓大家對(duì)這個(gè)行業(yè)更熱愛~

          這可能就是我現(xiàn)在作為一個(gè)有趣的,有奇奇怪怪的點(diǎn)子的前端工程師可以為社區(qū)帶來的東西吧。(當(dāng)然我也有硬核內(nèi)容,比如寒草的編譯原理哈哈哈)

          最后,熱愛,所以期待

          踏過三界寶剎,閱過四洲繁華。
          笑過五蘊(yùn)癡纏,舍過六根牽掛。
          為情義披戰(zhàn)甲,為愛人挑擔(dān)、牽馬、送晚霞。
          怕什么欲念不休,怕什么浪跡天涯。
          步履不停,便是得救之法。

          ——敢問路在何方?路在腳下。

          伙伴們,如果喜歡我的文章,可以點(diǎn)贊 ?? 關(guān)注? ,這是對(duì)我最大的支持。

          加我微信:hancao97,邀你進(jìn)群,了解寒草?? 的github小組現(xiàn)狀,一起學(xué)習(xí)前端,成為更優(yōu)秀的工程師~(群二維碼在這里->前端晚晚睡[3], 二維碼過期了的話看鏈接沸點(diǎn)中的評(píng)論,我會(huì)把最新的二維碼放在評(píng)論區(qū),當(dāng)然也可以加我微信我拉你進(jìn)群,畢竟我也是有趣的前端,認(rèn)識(shí)我也不賴??~)

          關(guān)于本文

          作者:寒草

          https://juejin.cn/post/6999413377692860430

          The End

          歡迎自薦投稿到《前端技術(shù)江湖》,如果你覺得這篇內(nèi)容對(duì)你挺有啟發(fā),記得點(diǎn)個(gè) 「在看」


          點(diǎn)個(gè)『在看』支持下 

          瀏覽 74
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  翔田千里无码一区二区 | 韩国黄色一级视频 | 黄色一级操逼 | 操逼站| 婷婷黄色网址导航 |