你畫我猜中的畫板功能
本節我們來做一個畫板,該畫板一共有三個小功能:
- 調節筆刷大小
- 改變筆刷顏色
- 橡皮擦
運行效果如下:
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',更改透明度,並設置橡皮擦顏色和粗細(顏色同背景顏色相同,都爲白色),最後復原滑動條上的按鈕位置(讓玩家知道之前在設置橡皮擦大小時,滑動條上按鈕的位置)。
好,講到這就結束啦,希望大家有所收穫!