iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 5
2
Modern Web

三十天路邊賭場上線了!系列 第 5

DAY05 賭桌感應區域、繪製互動區域

前言

今天非常的趕,因為其實這幾天都在想後端架構,本業是前端,後端架構沒有非常熟悉,於是今天來畫個感應區域吧!
為什麼要特別畫感應區域呢?其實是因為我們都是載入圖檔,並非像flash可以直接繪製物件,圖片的感應區域都是正方形,在特殊形狀時我們必須使用Pixijs Graph畫出特定奇怪的圖案,那我們會用到甚麼呢?

beziertool
這是可以載入圖片並用拉的方式生成貝茲曲線,就可以產生我們想要的圖形範圍,也可以用來描述我們Pixijs Graph。

載入互動圖片

我們期待我們Hover到賭桌時會出現相對應的反應,並且我們下注時是要點賭桌的,但首先我們先來載入圖片吧!這是一個稱為DeskHover的Objects,以下為資料夾結構。

   │  └─objects
    │          Bg.ts
    │          Chip.ts
    │          Desk.ts
    │          DeskHover.ts

DeskHover有甚麼呢?我們期待他可以載入我們要的對應圖片,這是賭桌,那我們希望上面的各區域有Hover效果。
https://ithelp.ithome.com.tw/upload/images/20190906/20109783qzkXJXMGNL.png

這是我們的Hover圖片,總共有八個位置,分別就是莊閒和等等各八種區域。
https://ithelp.ithome.com.tw/upload/images/20190906/20109783WLWqG9AQYW.png

DeskHover.ts內容如下,由於相當繁瑣,直接從code解釋吧!

DeskHover.ts

import Sprite from '@/components/elements/Sprite'
import imagePath from '@/config/imagePath'

export default class DeskHover extends Sprite {
  private _hoveArea: PIXI.Graphics // 我們的Graphics就是用來繪製感應區域
  private _type: string // 這一個DeskHover是八種的哪一種呢?

  constructor(type: string) {
    // 因為有壓成Sprite檔案,所以當然是繼承Sprite,透過super新增我們要的圖片。
    super(imagePath.tablePath, type)
    this._hoveArea = new PIXI.Graphics() // 新增我們的感應區域物件
    this._container.addChild(this._hoveArea)
    this._type = type // 決定我們的Type,來決定我們繪製的區域
    this.drawHover() // 繪製感應區域
    this.setInteractive(true) // 設定成可以感應,才可以hover
    this.setAlpha(false, 0) // 先透明隱藏
  }

  /**
   * Override
   */
  public setInteractive(interactive: boolean): void{
    this._hoveArea.interactive = interactive
    this._hoveArea.buttonMode = interactive
  }

  private drawHover() {
    // 這邊會判斷我們的type,並決定要繪製哪區域
    switch (this._type) {
      case 'playerpair':
        this.drawPlayerpair(this._hoveArea, 0, 0)
        break
      case 'player':
        this.drawPlayer(this._hoveArea, 0, 0)
        break
      case 'playerking':
        this.drawPlayerking(this._hoveArea, 0, 0)
        break
      case 'tiepair':
        this.drawTiepair(this._hoveArea, 0, 0)
        break
      case 'tie':
        this.drawTie(this._hoveArea, 0, 0)
        break
      case 'bankerking':
        this.drawBankerking(this._hoveArea, 0, 0)
        break
      case 'banker':
        this.drawBanker(this._hoveArea, 0, 0)
        break
      case 'bankerpair':
        this.drawBankerpair(this._hoveArea, 0, 0)
        break
      default:
        break
    }
  }

  // 繪製hover區域 這邊我們還沒有補上繪製方法,之後會有步驟如何產生。

  private drawPlayerpair(graph: PIXI.Graphics, xoff: number, yoff: number) { // 閒對子

  }

  private drawPlayer(graph: PIXI.Graphics, xoff: number, yoff: number) { // 閒

  }

  private drawPlayerking(graph: PIXI.Graphics, xoff: number, yoff: number) { // 閒王

  }

  private drawTiepair(graph: PIXI.Graphics, xoff: number, yoff: number) { // 平對

  }

  private drawTie(graph: PIXI.Graphics, xoff: number, yoff: number) { // 平對

  }

  private drawBankerking(graph: PIXI.Graphics, xoff: number, yoff: number) { // 莊王

  }

  private drawBanker(graph: PIXI.Graphics, xoff: number, yoff: number) { // 莊

  }

  private drawBankerpair(graph: PIXI.Graphics, xoff: number, yoff: number) { // 莊對
 
  }

  public on(event: string, listener: any): void {
    this._hoveArea.on(event, listener)
  }

}

bezier貝茲曲線繪製

使用beziertool,並載入圖片。
https://ithelp.ithome.com.tw/upload/images/20190906/20109783iIktNkuie5.png
右邊就可以輕易繪製出我們要的貝茲曲線定義的點了!是不是相當方便。

並且把曲線寫到我們繪製的地方,把graph傳進來並繪製。有刪除一些不重要的內容,並且把這區域設成透明。

...省略
private drawPlayerpair(graph: PIXI.Graphics, xoff: number, yoff: number) { // 閒對子
    // graph.clear()
    graph.beginFill(0)
    graph.alpha = 0
    graph.moveTo(291 + xoff, 12 + yoff)
    graph.bezierCurveTo(279 + xoff, 4 + yoff, 429 + xoff, 107 + yoff, 417 + xoff, 99 + yoff)
    graph.bezierCurveTo(404 + xoff, 91 + yoff, 345 + xoff, 117 + yoff, 327 + xoff, 158 + yoff)
    graph.bezierCurveTo(313 + xoff, 162 + yoff, 66 + xoff, 132 + yoff, 3 + xoff, 133 + yoff)
    graph.bezierCurveTo(-11 + xoff, 139 + yoff, 137 + xoff, 11 + yoff, 289 + xoff, 13 + yoff)
    graph.endFill()
  }
...省略

增加感觸方法

...省略
constructor(type: string) {
    super(imagePath.tablePath, type)
    this._hoveArea = new PIXI.Graphics()
    this._container.addChild(this._hoveArea)
    this._type = type
    this.drawHover()
    this.setInteractive(true)
    this.setAlpha(false, 0)

    this.on('mouseover', () => {
    // 如果感受到mouseover就把這透明度設成1
      this.setAlpha(true, 1)
    })
    this.on('mouseout', () => {
    // 如果感受到mouseout就把這透明度設成0
      this.setAlpha(true, 0)
    })
  }
...省略

把感應區域增加到賭桌

這部分比較搞剛,因為每一感應區域都必須分配到圖片的特定區域,這部分我已經抓好,所以就是在initPosition這function中執行,並這位置並不會常常變動,所以沒有另外寫設定檔,直接定位在class內部即可。

import Wrapper from '@/components/elements/Wrapper'
import WrapperContainerCenter from '@/components/elements/WrapperContainerCenter'
import DeskHover from '@/components/objects/DeskHover'
import Desk from '@/components/objects/Desk'

export default class Table extends WrapperContainerCenter {
    private _desk: Wrapper
    private _deskHover_playerpair: DeskHover
    private _deskHover_playerking: DeskHover
    private _deskHover_tiepair: DeskHover
    private _deskHover_tie: DeskHover
    private _deskHover_bankerking: DeskHover
    private _deskHover_banker: DeskHover
    private _deskHover_bankerpair: DeskHover
    private _deskHover_player: DeskHover
    constructor() {
        super()
        this._desk = new Desk()
        // 新增一堆DeskHover物件。
        this._deskHover_playerpair = new DeskHover('playerpair')
        this._deskHover_playerking = new DeskHover('playerking')
        this._deskHover_tiepair = new DeskHover('tiepair')
        this._deskHover_tie = new DeskHover('tie')
        this._deskHover_bankerking = new DeskHover('bankerking')
        this._deskHover_banker = new DeskHover('banker')
        this._deskHover_bankerpair = new DeskHover('bankerpair')
        this._deskHover_player = new DeskHover('player')
        this.addChild(this._desk)
        // 全部add進去這一容器
        this.addChild(this._deskHover_playerpair)
        this.addChild(this._deskHover_playerking)
        this.addChild(this._deskHover_tiepair)
        this.addChild(this._deskHover_tie)
        this.addChild(this._deskHover_bankerking)
        this.addChild(this._deskHover_banker)
        this.addChild(this._deskHover_bankerpair)
        this.addChild(this._deskHover_player)

        // 初始化位置
        this.initPosition()
    }

    private initPosition() {
        // 各種感應區域的對應位置
        let config = {
            'playerpair': {
                x: 198,
                y: 52
            },
            'playerking': {
                x: 345,
                y: 337
            },
            'tiepair': {
                x: 639,
                y: 336
            },
            'tie': {
                x: 515,
                y: 149
            },
            'bankerking': {
                x: 782,
                y: 337
            },
            'banker': {
                x: 900,
                y: 188
            },
            'bankerpair': {
                x: 854,
                y: 61
            },
            'player': {
                x: 122,
                y: 182
            }
        }
        this._desk.setPosition({ animation: true }, 0, 0)
        // 設定位置
        this._deskHover_playerpair.setPosition({ animation: false }, config['playerpair'].x, config['playerpair'].y)
        this._deskHover_playerking.setPosition({ animation: false }, config['playerking'].x, config['playerking'].y)
        this._deskHover_tiepair.setPosition({ animation: false }, config['tiepair'].x, config['tiepair'].y)
        this._deskHover_tie.setPosition({ animation: false }, config['tie'].x, config['tie'].y)
        this._deskHover_bankerking.setPosition({ animation: false }, config['bankerking'].x, config['bankerking'].y)
        this._deskHover_banker.setPosition({ animation: false }, config['banker'].x, config['banker'].y)
        this._deskHover_bankerpair.setPosition({ animation: false }, config['bankerpair'].x, config['bankerpair'].y)
        this._deskHover_player.setPosition({ animation: false }, config['player'].x, config['player'].y)
    }
}

以下就是完成的樣子,可以hover,而且範圍不會受圖片方形影響!
https://ithelp.ithome.com.tw/upload/images/20190906/20109783kXztygfmZw.png

結尾

今天真的太趕了,沒有特別規劃,可能相當混亂,如果想了解更多就去看Github吧!

連結

Github
Pixijs


上一篇
DAY04 載入畫面、基本場景
下一篇
DAY06 製作倒數鐘、倒數數字
系列文
三十天路邊賭場上線了!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
阿展展展
iT邦好手 1 級 ‧ 2019-11-15 06:45:37

數學/images/emoticon/emoticon06.gif

哪裡!?

我要留言

立即登入留言