《Cocos Creator遊戲實戰》你畫我猜中的畫板功能

你畫我猜中的畫板功能

創建節點

完成腳本


本節我們來做一個畫板,該畫板一共有三個小功能:

  1. 調節筆刷大小
  2. 改變筆刷顏色
  3. 橡皮擦

 

運行效果如下:

 

Cocos Creator版本:2.2.0

後臺回覆"畫板",獲取該項目完整文件:

 

創建節點

筆者在層級管理器中創建了以下節點:

1. bg爲畫板背景,顏色爲白色。

 

2. brush爲筆刷節點,我們在該節點上添加了Graphics組件和自定義腳本Brush.js:

注:讀者可以去官方文檔上了解下Graphics組件的各個屬性。

 

3. v_layout爲一個垂直佈局節點,它有三個子節點:width_slider,color_layout和tool_layout。

width_slider是引擎中默認的Slider控件,這裏用來更改筆刷的粗細或者橡皮擦的大小。我們這裏要爲該節點上的Slider組件添加一個事件監聽函數,之後會詳細講解函數內容。

color_layout是一個垂直佈局節點,它一共有六個按鈕子節點,每個按鈕分別表示一種顏色。當玩家按下某個按鈕後,筆刷顏色也作相應改變。

在初始狀態,黑色按鈕透明度不變,爲255,其他按鈕透明度爲100。當玩家按下某個按鈕後,該按鈕透明度變爲255,其餘顏色按鈕透明度變爲100。這樣做可以起到更好的提示作用。

我們也給各個按鈕加上了事件監聽函數:

tool_layout也是一個垂直節點,它一共有兩個按鈕子節點,一個爲筆刷按鈕,一個爲橡皮擦按鈕。當玩家按下筆刷按鈕後,可以在畫板上畫畫,而按下橡皮擦按鈕後則可以進行擦除操作。按鈕的透明度設置同上。

 

接着對節點進行適當佈局後,效果如下:

 

完成腳本

在該項目中,筆者一共創建了兩個腳本:Game.js和Brush.js。前者掛在Canvas上,後者掛在brush節點上。

我們首先來看下Brush.js:

// Brush.js
cc.Class({
    extends: cc.Component,

    properties: {
        
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.ctx = this.node.getComponent(cc.Graphics);
    },

    setBrushPos (x, y) {
        // 設置筆刷起始位置
        this.ctx.moveTo(x, y);
    },

    setBrushLineWidth(lineWidth) {
        // 設置筆刷粗細
        this.ctx.lineWidth = lineWidth;
    },

    setBrushColor(color) {
        // 設置筆刷顏色(包括邊框顏色和填充顏色)
        this.ctx.strokeColor = color;
        this.ctx.fillColor = color;
    },

    drawTo (x, y) {
        // 從起始位置一直畫到目標位置
        this.ctx.lineTo(x, y);
        this.ctx.stroke();
        this.ctx.moveTo(x, y);
    }
});

1. 首先在onLoad方法中獲取Graphics組件,保存到變量ctx中,方便我們之後修改筆刷屬性。

2. 在setBrushPos方法中我們調用Graphics組件的moveTo()接口,用來設置筆刷的起始位置(畫東西肯定要個起始點)。

3. 在setBrushLineWidth中我們直接通過修改Graphics的lineWidth屬性來改變筆刷粗細。

4. setBrushColor方法用來修改筆刷顏色,strokeColor屬性表示線的輪廓顏色,而fillColor屬性表示線的填充顏色。

5. 在drawTo方法中,我們調用Graphics組件的lineTo接口來指定線的終點位置,再調用stroke方法來繪製出路徑。其實最後的        this.ctx.moveTo(x, y);代碼沒有必要寫,但是如果不加的話在Cocos Creator模擬器上畫畫會有問題,不方便開發階段調試(官方回覆說模擬器可能存在問題),希望在之後的版本中能修復。當然不用Cocos Creator模擬器調試的話不會有問題,筆者在手機上已測試。具體可以看下這個鏈接

 

接下來是Game.js。

我們在properties中添加了如下屬性:

// Brush.js
properties: {
    brush: cc.Node,
    widthSlider: cc.Node,
    colorLayout: cc.Node,
    toolLayout: cc.Node
},

 

onLoad方法編寫如下:

// Game.js
onLoad () {
    // 去掉模擬器上的FPS信息
    cc.debug.setDisplayStats(false);

    this.lineWidth = 1;                     // 筆刷粗細(默認1)
    this.eraserWidth = 10;                  // 橡皮擦大小(特殊筆刷,默認10)
    this.color = cc.Color.BLACK;            // 筆刷顏色(默認黑色)
    this.tool = 'BRUSH';                    // 當前工具(默認筆刷)

    this.node.on('touchstart', this.onTouchStart, this);
    this.node.on('touchmove', this.onTouchMove, this);
},

1. lineWidth和eraserWidth變量分別用來保存筆刷和橡皮擦的大小,color變量用來保存筆刷顏色。

2. 我們會用tool變量來判斷當前玩家所使用的工具,如果是筆刷則爲'BRUSH',橡皮擦則爲'ERASER'。

3. 給整個Canvas畫布添加觸摸監聽。

 

監聽函數編寫如下:

// Game.js
onTouchStart(event) {
    // 設置筆刷起始位置
    let pos = this.node.convertToNodeSpaceAR(event.getLocation());
    this.brush.getComponent('Brush').setBrushPos(pos.x, pos.y);
},

onTouchMove(event) {
    let pos = this.node.convertToNodeSpaceAR(event.getLocation());
    this.brush.getComponent('Brush').drawTo(pos.x, pos.y);
},

在onTouchStart中,我們通過event.getLocation獲取到世界座標並轉換成Canvas上的座標,接着調用setBrushPos方法設置筆刷起始位置。onTouchMove編寫邏輯同理。

 

接下來我們就是編寫滑動條Slider和各個按鈕的事件監聽函數了。

首先是滑動條:

// Game.js
sliderEvent(slider) {
    // 調整筆刷粗細
    if (this.tool == 'BRUSH') {
        this.lineWidth = 1 + slider.progress * 5;
        this.brush.getComponent('Brush').setBrushLineWidth(this.lineWidth);
    }
    else if (this.tool == 'ERASER') {
        this.eraserWidth = 10 + slider.progress * 50;
        this.brush.getComponent('Brush').setBrushLineWidth(this.eraserWidth);
    }
},

很簡單,我們其實就是通過滑動條的progress值來設置筆刷和橡皮擦的大小。

 

接下來是六個顏色按鈕: 

// Game.js
blackBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = cc.Color.BLACK;
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==0)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

redBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = cc.Color.RED;
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==1)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

greenBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = cc.Color.GREEN;
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==2)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

blueBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = cc.Color.BLUE;
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==3)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

yellowBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = cc.Color.YELLOW;
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==4)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

purpleBtnEvent() {  
    if (this.tool == 'BRUSH') {
        this.color = new cc.Color(255, 0, 255);
        this.brush.getComponent('Brush').setBrushColor(this.color);

        for (let i=0; i<this.colorLayout.children.length; i++) {
            if (i==5)
                {this.colorLayout.children[i].opacity = 255;}
            else 
                {this.colorLayout.children[i].opacity = 100;}
        }
    }
},

玩家點擊哪個按鈕,我們就把筆刷顏色設置成對應的,當然別忘了要修改下各自的透明度。

 

最後是兩個工具按鈕:

// Game.js
brushBtnEvent() {
    // 設置筆刷爲普通畫筆
    this.tool = 'BRUSH';
    this.toolLayout.children[0].opacity = 255;
    this.toolLayout.children[1].opacity = 100;
    this.brush.getComponent('Brush').setBrushColor(this.color);
    this.brush.getComponent('Brush').setBrushLineWidth(this.lineWidth);

    // 設置slider上的handle位置
    this.widthSlider.getComponent(cc.Slider).progress = (this.lineWidth-1) / 5;
},

eraserBtnEvent() {
    // 設置筆刷爲橡皮擦(特殊筆刷)
    this.tool = 'ERASER';
    this.toolLayout.children[0].opacity = 100;
    this.toolLayout.children[1].opacity = 255;
    this.brush.getComponent('Brush').setBrushColor(cc.Color.WHITE);
    this.brush.getComponent('Brush').setBrushLineWidth(this.eraserWidth);

    // 設置slider上的handle位置
    this.widthSlider.getComponent(cc.Slider).progress = (this.eraserWidth-10) / 50;
}

1. 當玩家點擊筆刷按鈕後,我們設置tool變量值爲'BRUSH',更改透明度,並設置筆刷顏色和粗細,最後復原滑動條上的按鈕位置(讓玩家知道之前在設置筆刷粗細時,滑動條上按鈕的位置)。

2. 當玩家點擊橡皮擦按鈕後,我們設置tool變量值爲'ERASER',更改透明度,並設置橡皮擦顏色和粗細(顏色同背景顏色相同,都爲白色),最後復原滑動條上的按鈕位置(讓玩家知道之前在設置橡皮擦大小時,滑動條上按鈕的位置)。

 

好,講到這就結束啦,希望大家有所收穫!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章