<dfn id="hx5t3"><strike id="hx5t3"><em id="hx5t3"></em></strike></dfn>

    <thead id="hx5t3"></thead><nobr id="hx5t3"><font id="hx5t3"><rp id="hx5t3"></rp></font></nobr>

    <listing id="hx5t3"></listing>

    <var id="hx5t3"></var>
    <big id="hx5t3"></big>

      
      

      <output id="hx5t3"><ruby id="hx5t3"></ruby></output>
      <menuitem id="hx5t3"><dfn id="hx5t3"></dfn></menuitem>

      <big id="hx5t3"></big>

        ForkKillet

        ForkKillet 查看完整檔案

        上海編輯  |  填寫畢業院校額我能說 IceLava 開發組嗎  |  組長 編輯 icelava.top/ 編輯
        編輯

        我是一只快樂的小蒟蒻~

        個人動態

        ForkKillet 贊了回答 · 3月9日

        文字固定顯示兩行,并且結尾不能出現... 或者半個字體,有什么方法么?

        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;(行數)
        -webkit-box-orient: vertical;

        關注 4 回答 3

        ForkKillet 贊了文章 · 3月9日

        使用 Phaser3+Matter.js 實現“合成大西瓜”游戲

        前言

        最近有一款“合成大西瓜”的小游戲有點火,試玩了一下,玩法比較簡單,實現難度也不大,所以參照游戲原型自己實現了一下,游戲開發主要使用了 Phaser 游戲框架,本文主要分享游戲功能的具體實現,對框架使用的 API 不會做過多介紹。

        玩法分析

        首先簡單介紹下游戲的玩法:控制水果從上方掉落,兩個相同水果會合成一個更大的水果,最終合成一個大西瓜,效果展示:

        游戲的玩法在于合理控制下落的點避免空間的浪費,在頂部有一條“死亡線”,當水果超過這個高度就結束,有點像俄羅斯方塊,每合成一次水果都會得分,看誰能在游戲結束前或得更高的分數。

        有多少種水果

        游戲總共會出現 11 種水果,經過觀察,前 5 種水果會隨機掉落,后面的水果都是合成才會出現的

        如何計算得分

        每次合成新水果都會得分,按順序的話第一種是 1 分,第二種 2 分,第 10 種就是 10 分,最后合成大西瓜后是額外得 100 分:

        快速開始

        游戲的基本玩法都已經清楚了,接下來就是開發了,首先我們通過Githubclone一個 phaser3 的腳手架來進行開發,我們首選 Typescript 版本的,對于這種復雜的框架,類型提示真的非常方便。

        #! /bin/bash
        
        $git clone git@github.com:photonstorm/phaser3-typescript-project-template.git hexigua
        $cd hexigua
        $npm install
        
        #啟動
        $npm run watch
        

        安裝依賴并啟動后,進入src/game.ts,把原來的一些示例代碼刪掉,結果如下:

        import 'phaser'
        export default class Demo extends Phaser.Scene {
          constructor () {
            super('demo')
          }
        
          preload () {
          }
        
          create () {
          }
        }
        
        const config = {
          type: Phaser.AUTO,
          backgroundColor: '#125555',
          width: 800,
          height: 600,
          scene: Demo
        }
        
        const game = new Phaser.Game(config)

        preloadcreate都屬于框架的生命周期,preload主要用于預先下載資源,create用于創建對象或事件。

        修改 config 參數

        修改游戲初始化參數,指定使用 Matter.js 物理引擎,縮放模式通常設置為等比例縮放模式Phaser.Scale.FIT,

        const config = {
          type: Phaser.AUTO,
          backgroundColor: '#ffe8a3', // 改為游戲的背景顏色
          mode: Phaser.Scale.FIT, // 縮放模式
          physics: {
            default: 'matter', // 使用matterjs物理引擎
            matter: {
              gravity: {
                y: 2
              },
              debug: true // 開啟調試
            }
          },
          width: window.innerWidth,
          height: window.innerHeight,
          scene: Demo
        }

        加載資源

        接下在preload函數中加載準備好的圖片, 前面我已經準備好了 11 中類型水果的圖片,為了方便開發,分別命名為 1-11.png

        preload () {
          // 11種類型水果
          for (let i = 1; i <= 11; i++) {
            this.load.image(`${i}`, `assets/${i}.png`)
          }
          // 地板圖片
          this.load.image('ground', 'assets/ground.png')
        }

        新建水果

        加載資源后,我們先來創建游戲中最主要的對象水果,游戲中水果出現的情況有兩種,一種是在頂部落下,一種是碰撞后生成,除了位置不同,還有狀態和類型也不同,用一個表示如下:

        出現位置狀態類型
        頂部先靜止點擊后落下前 5 種隨機
        合成后的位置非靜止上一種+1

        把不同的部分作為參數,創建一個createFruite函數:

         /**
             * 添加一個水果
             * @param x 坐標x
             * @param y 坐標y
             * @param key 瓜的類型
             * @param isStatic 是否靜止
             */
          createFruite (x: number, y: number, isStatic = true, key?: string,) {
            if (!key) {
              // 頂部落下的瓜前5個隨機
              key = `${Phaser.Math.Between(1, 5)}`
            }
            // 創建
            const fruit = this.matter.add.image(x, y, key)
            // 設置物理剛體
            fruit.setBody({
              type: 'circle',
              radius: fruit.width / 2
            }, {
              isStatic,
              label: key // 設置label 用于后續碰撞判斷是否同一類型
            })
            // 添加一個動畫效果
            this.tweens.add({
              targets: fruit,
              scale: {
                from: 0,
                to: 1
              },
              ease: 'Back',
              easeParams: [3.5],
              duration: 200
            })
            return fruit
          }

        create函數中創建地板和生成水果

        create(){
        
            //設置邊界
            this.matter.world.setBounds()
            //添加地面
            const groundSprite = this.add.tileSprite(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 127 / 2, WINDOW_WIDTH, 127, 'ground')
            this.matter.add.gameObject(groundSprite, { isStatic: true })
        
            //初始化第一個一個水果
            const x = WINDOW_WIDTH / 2
            const y = WINDOW_HEIGHT / 10
            let fruit = this.createFruite(x, y)
        
        }

        綁定點擊屏幕事件

        接下來就是添加事件點擊屏幕的時候水果往下掉,并生成一個新的水果,新水果生成的時間點就設在落下后一秒鐘

        create(){
             ...
            //綁定pointerdown事件
            this.input.on('pointerdown', (point) => {
                if (this.enableAdd) {
                    this.enableAdd = false
                    //先x軸上移動到手指按下的點
                    this.tweens.add({
                        targets: fruit,
                        x: point.x,
                        duration: 100,
                        ease: 'Power1',
                        onComplete: () => {
                            //取消靜止狀態,讓物體掉落
                            fruit.setStatic(false)
                            //1s后生成新的水果
                            setTimeout(() => {
                                fruit = this.createFruite(x, y)
                                this.enableAdd = true
                            }, 1000);
                        }
                    })
                }
            }
        }

        物體碰撞事件

        完成水果生成后,下一步就是添加碰撞事件,在phaser中我們可以使用this.matter.world.on('collisionstart',fn)來監聽物體的碰撞事件,fn中會返回兩個相互碰撞的物體對象,我們根據前面設置的label值就能判斷是否同一組,并進行后續操作

        create(){
          ...
          this.matter.world.on('collisionstart', (event, bodyA, bodyB) => {
              const notXigua = bodyA.label !== '11'   //非大西瓜
              const same = bodyA.label === bodyB.label //相同水果
              const live = !bodyA.isStatic && !bodyB.isStatic //非靜態
              if (notXigua && same && live) {
                  //設置為Static,這樣可以調整物體位置,使物體重合
                  bodyA.isStatic = true
                  bodyB.isStatic = true
                  const { x, y } = bodyA.position
                  const lable = parseInt(bodyA.label) + 1
                  //添加兩個動畫合并的動畫
                  this.tweens.add({
                      targets: bodyB.position,
                      props: {
                          x: { value: x, ease: 'Power3' },
                          y: { value: y, ease: 'Power3' }
                      },
                      duration: 150,
                      onComplete: () => {
                          // 物體銷毀
                          bodyA.gameObject.alpha = 0
                          bodyB.gameObject.alpha = 0
                          bodyB.destroy()
                          bodyA.destroy()
                          //合成新水果
                          this.createFruite(x, y, false, `${lable}`)
        
                      }
                  })
              }
          })
        }

        到這一步我們就基本完成了游戲的核心部分,先看下效果:

        合成后只是簡單的銷毀物體,有時間的話可以加入一些幀動畫之類的效果會更好,這里就不加了,接下來繼續加上結束判定和得分。

        結束判斷

        前面提到,當落下的球超過指定的高度游戲即結束,我們還是使用一個碰撞檢測來實現,創建一個矩形物體作為我們的“結束線”,當矩形碰到物體的時候即表示空間已經不夠游戲結束,還有一點需要特殊處理的是當我們點擊水果落下時是會碰到線的,這次碰撞需要過濾掉

        create(){
        ...
        //線創建在水果200px下的位置
        const endLineSprite = this.add.tileSprite(WINDOW_WIDTH / 2, y + 200, WINDOW_WIDTH, 8, 'endLine'  )
        //設為隱藏
        endLineSprite.setVisible(false)
        //設置物理效果
        this.matter.add.gameObject(endLineSprite, {
          //靜止
          isStatic: true,
          //傳感器模式,可以檢測到碰撞,但是不會對物體產品效果
          isSensor: true,
          //物體碰撞回調,
          onCollideCallback: () => {
             //落下時碰到線不觸發
             if(this.enableAdd){
                // 游戲結束
                console.log('end')
             }
          })
         })
        }

        得分

        得分的邏輯其實比較簡單了,在合成成功后加入代碼

        let score = parseInt(bodyA.label)
        this.score += score
        //合成西瓜額外加100分
        if (score === 10) {
            this.score += 100
        }
        this.scoreText.setText(this.score)
        //
        create(){
            //創建一個Text
            this.scoreText = this.add.text(30, 20, `${this.score}`, { font: '90px Arial Black', color: '#ffe325' }).setStroke('#974c1e', 16)
        }

        最后

        到這里游戲的基礎玩法就開發結束了,借助 Phaser 框架基本算能快速的開發游戲的原型,如果你是新手對 H5 游戲開發感興趣的話,那么 Phaser 是一個非常容易上手的框架,api 的設計也比較友好,還有大量的 demo 可以學習,或許下一個爆款游戲就出自于你呢。

        本項目源碼已經發布到 github 倉庫,感興趣的可以自行查看

        參考文章

        如何隨手合成大西瓜,把把 1000 分?手殘必看的高分攻略來了!

        Phaser


        歡迎關注凹凸實驗室博客:aotu.io

        或者關注凹凸實驗室公眾號(AOTULabs),不定時推送文章。

        查看原文

        贊 3 收藏 1 評論 0

        ForkKillet 贊了回答 · 3月9日

        解決CSS如何實現局部光照效果?

        之前寫過一個類似的效果。通過 box-shadow 來實現的。但是那個效果和你這個不太像,我那個把文字也蓋住了。
        考慮可以通過給文字加層級來實現。

        JS效果之《獲取鼠標所在區域的容器,區域外都遮罩半透明》

        關注 4 回答 4

        ForkKillet 贊了回答 · 3月9日

        解決CSS如何實現局部光照效果?

        參考我這篇博文,完美實現透視鏡,比采納的答案效果更完美.

        codepen在線地址
        https://codepen.io/xty1992a/p...

        關注 4 回答 4

        ForkKillet 贊了回答 · 3月9日

        解決CSS如何實現局部光照效果?

        用 CSS 實現過這個效果,可以用 mask 遮罩實現,但是 border 必須放到單獨的層。過程中發現 mask-border 這種東西,不過兼容性不好,等 mask-border 可以用的時候就簡單了。

        demo: https://codepen.io/liuxiaole-...

        文章:https://juejin.cn/post/684490...

        關注 4 回答 4

        ForkKillet 贊了回答 · 3月9日

        解決CSS如何實現局部光照效果?

        image

        <!DOCTYPE html>
        <html>
        <head>
         <meta charset="UTF-8">
         <title>light effect</title>
         <style type="text/css">
         .flex-row {display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row;}
            .flex-row > .flex-main {-webkit-flex:1 1 auto;flex:1 1 auto;}
            .flex-row > .flex-side {-webkit-flex:0 0 auto;flex:0 0 auto;}
            .flex-row.flex-spacing > .flex-main:not(:first-child), .flex-row.flex-spacing > .flex-side:not(:first-child) {margin-left:0.5em;}
            .flex-row.flex-margin {margin-left:0.5em;margin-right:0.5em;}
            .flex-row.flex-padding {padding-left:0.5em;padding-right:0.5em;}
            .flex-row .flex-warp {flex-wrap:wrap;}
            .flex-column {display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;}
            .flex-column > .flex-main {-webkit-flex:1 1 auto;flex:1 1 auto;}
            .flex-column > .flex-side {-webkit-flex:0 0 auto;flex:0 0 auto;}
            .box {position:relative;display:inline-block;color:#FFF;font-size:20px;background-color:#000;
         --pt-x : 0;
         --pt-y : 0;
         }
            .box .effect {position:absolute;top:0;bottom:0;left:0;right:0;
         background:radial-gradient(circle at calc(var(--pt-x) * 1px) calc(var(--pt-y) * 1px), #FFF, rgba(255,255,255,0) 4em);z-index:0;}
            .box .item-list {z-index:2;}
            .box .item-list .item {position:relative;margin:1em;padding:1em;line-height:1.5em;border:2px solid rgba(255,255,255,0.5);background-color:rgba(0,0,0,0.7);background-clip:padding-box;box-shadow:0 0 0 1em #000;}
            .box .item-list .item .icon {margin-right:1em;width:1.5em;height:1.5em;background-color:rgba(255,255,255,0.5);}
            .box .item-list .item .name {}
            .box .item-list .item .desc {color:#999;font-size:16px;}
            </style>
         <script> document.addEventListener('DOMContentLoaded', function(){
                let domBox = document.querySelector('.box');
         domBox.addEventListener('mousemove', function($evt){
                    let rect = domBox.getBoundingClientRect();
         domBox.style.setProperty('--pt-x', $evt.pageX - rect.left);
         domBox.style.setProperty('--pt-y', $evt.pageY - rect.top);
         });
         });
         </script>
        </head>
        <body>
        <div class="box">
         <div class="effect"></div>
         <div class="item-list">
         <div class="flex-row item-list-row">
         <div class="flex-side flex-row item">
         <div class="flex-side icon"></div>
         <div class="flex-main">
         <div class="name">系統</div>
         <div class="desc">顯示、聲音、通知、電源</div>
         </div> </div> <div class="flex-side flex-row item">
         <div class="flex-side icon"></div>
         <div class="flex-main">
         <div class="name">系統</div>
         <div class="desc">顯示、聲音、通知、電源</div>
         </div> </div> </div> <div class="flex-row item-list-row">
         <div class="flex-side flex-row item">
         <div class="flex-side icon"></div>
         <div class="flex-main">
         <div class="name">系統</div>
         <div class="desc">顯示、聲音、通知、電源</div>
         </div> </div> <div class="flex-side flex-row item">
         <div class="flex-side icon"></div>
         <div class="flex-main">
         <div class="name">系統</div>
         <div class="desc">顯示、聲音、通知、電源</div>
         </div> </div> </div> </div></div>
        </body>
        </html>

        關注 4 回答 4

        ForkKillet 贊了問題 · 3月9日

        解決CSS如何實現局部光照效果?

        在Win10中,可以看到這樣的效果
        image.png
        image.png

        當鼠標處于圖中紅色標記位置時,周圍會帶有一個局部光,可以照亮原本是黑色的線框,背景也由原來的純黑變成了一部分受光照影響,請問這種效果用CSS怎么實現?

        關注 4 回答 4

        ForkKillet 贊了回答 · 3月9日

        解決Nodejs 如何獲取用戶使用的瀏覽器呢?

        關注 2 回答 1

        ForkKillet 提出了問題 · 3月8日

        解決Nodejs 如何獲取用戶使用的瀏覽器呢?

        我發現 github-cli 這個工具在 windows 和 linux 下都能打開你用的瀏覽器,想知道什么原理,以及 nodejs 能不能實現,以及如果有相關的包能不能推薦一下?

        關注 2 回答 1

        認證與成就

        • 獲得 76 次點贊
        • 獲得 18 枚徽章 獲得 1 枚金徽章, 獲得 4 枚銀徽章, 獲得 13 枚銅徽章

        擅長技能
        編輯

        開源項目 & 著作
        編輯

        (??? )
        暫時沒有

        注冊于 2017-08-29
        個人主頁被 2.1k 人瀏覽

        一本到在线是免费观看_亚洲2020天天堂在线观看_国产欧美亚洲精品第一页_最好看的2018中文字幕