先上一個辛苦弄出來的gif效果。寫公衆號時間不長,不少技巧還在慢慢跟小夥伴學習。可關注公衆號,回覆「繪圖」或者「填色」均可得到demo的git地址。請使用Creator2.4.0運行
node
填色遊戲種類也挺多的,我今天要說的是一種相對簡單的填色。
對於填色遊戲的作法,我在論壇裏搜到很多帖子,尤爲是這個帖子的留言比較多:油漆桶填色效果怎麼實現啊,找了兩天都找不到資源
其中有一條留言跟個人想法不謀而合,
尤爲是作了以前的取色,繪圖等功能後,對webgl的readPixels()函數返回的數據處理起來愈來愈順手。因此就用了替換數據的方式。
還有一種填色遊戲採用的純Graphics的方式,各類貝塞爾曲線,矩形,直線和moveTo,實現幾個區塊填指定顏色的填色遊戲,我感受那種應該是藉助工具的,由於生成的文件至關大。若是有知道的同窗能夠在下方留言,一塊兒交流。git
import TextureRenderUtils from "../TextureRenderUtils"; const { ccclass, property } = cc._decorator; @ccclass export default class FillColorV1 extends cc.Component { @property([cc.Component.EventHandler]) callback: cc.Component.EventHandler[] = []; @property(cc.Camera) camera: cc.Camera = null; @property(cc.Sprite) target: cc.Sprite = null; @property(cc.Node) renderNode: cc.Node = null; private pointList: number[] = [] private r: number; private g: number; private b: number; protected textureHelper: TextureRenderUtils = new TextureRenderUtils() private grid: number[] = [] private imgData: ArrayBufferView = null; start() { this.node.on(cc.Node.EventType.TOUCH_START, this.touchStart, this) this.init(); } getTextureInfo() { return this.textureHelper.getTextureInfo(); } getDataUrl() { return this.textureHelper.getDataUrl() } changeColor(color: cc.Color) { this.r = color.r; this.g = color.g; this.b = color.b; } init() { this.textureHelper.init(this.camera, this.renderNode) this.textureHelper.render() let data = this.textureHelper.getData() if (data.length > 0) { this.imgData = data; cc.log('FillColorV1 width ', this.renderNode.width, ' height ', this.renderNode.height) cc.log(' 實際上有多少個點 == ', data.length / 4) let count = this.renderNode.width * this.renderNode.height; cc.log(" 應該有多少個點的顏色 ", count) if (this.target) { let tTexture = this.target.spriteFrame.getTexture() tTexture.setFlipY(false) this.target.node.scaleY = -1 tTexture.initWithData(data, tTexture.getPixelFormat(), this.renderNode.width, this.renderNode.height) } } } update(dt: number) { let flag = false; let count = 0; let width = this.textureHelper.width; let r = this.r; let g = this.g; let b = this.b; //當發現有點擊座標的時候開始執行。這個5000 while (this.pointList.length >= 2 && count++ <= 5000) { flag = true; let x = this.pointList.shift(); let y = this.pointList.shift(); this.paintPoint(x, y, width, r, g, b) } if (flag) { let texture = this.target.spriteFrame.getTexture(); texture.initWithData(this.imgData, texture.getPixelFormat(), texture.width, texture.height) } } paintPoint(x: number, y: number, width: number, r: number, g: number, b: number) { let data = this.imgData; let rowW = Math.floor(width) * 4//一行的長度 x = Math.floor(x) let srow = Math.floor(y);//行開始位置 let startX = srow * rowW + x * 4;//列開始位置 if (!this.grid[startX]) { this.grid[startX] = 1 // cc.log('r g b%{} ', data[startX + 0], data[startX + 1], data[startX + 2]) if (data[startX + 0] > 100 || data[startX + 1] > 100 || data[startX + 2] > 50) { data[startX + 0] = r; data[startX + 1] = g; data[startX + 2] = b; this.pointList.push(x - 1) this.pointList.push(y); this.pointList.push(x + 1) this.pointList.push(y); this.pointList.push(x) this.pointList.push(y - 1) this.pointList.push(x) this.pointList.push(y + 1) } } } //用於打印點擊的位置,可有可無 showPointColor(x: number, y: number, width: number) { let data = this.imgData; let rowW = Math.floor(width) * 4//一行的長度 x = Math.floor(x) let srow = Math.floor(y);//行開始位置 let startX = srow * rowW + x * 4;//列開始位置 cc.log('r g b', data[startX + 0], data[startX + 1], data[startX + 2]) } touchStart(e: cc.Touch) { let pos = e.getLocation(); pos = this.node.convertToNodeSpaceAR(pos) cc.log('touchStart x ', pos.x, ' y = ', pos.y) this.pointList.length = 0; this.grid.length = 0; this.pointList.push(pos.x) this.pointList.push(pos.y) this.showPointColor(pos.x, pos.y, this.textureHelper.width) } }
以上是我作的一種填色方案,並無涉及到很大的圖案,也沒有涉及到放大縮小。我沒有說個人方案是最好的,我相信方案有不少種,不少方案都有它的侷限性,有它的適用範圍;只要沒有bug,就有參考價值;可是不要拿來主義,要根據你本身的狀況,酌情考慮。web
前幾天公衆號好不容易湊夠了500人,開了廣告。可是感受僅憑廣告的收入,不說了,都是眼淚。數組
之後更新的速度可能會慢不少,一週兩篇,或者一篇或者沒有,還請你們見諒。畢竟不能靠這個養活本身,並且還至關耗費時間。微信
歡迎掃碼關注公衆號《微笑遊戲》,瀏覽更多內容。函數