Cocos2d-js 3.x: 像素触摸

前端之家收集整理的这篇文章主要介绍了Cocos2d-js 3.x: 像素触摸前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

像素触摸的大致思路都是一样的,无论是-x中的版本还是html5中。

第一步:获得纹理的像素信息。

第二步:根据图片的像素信息获得触摸(点击)点上的像素信息。

第三步:触摸判断,是否透明。透明则不处理,不透明则触摸到了。


具体的实现思路:

目前我们基本上都是使用UIButton这个类,所以我只实现了这个的简单封装,其他的都类似。

第一步:修改Button的onTouchBegan函数截取开始的触摸事件,在这个地方实现是否为透明区域的判断处理。

第二步:为Sprite添加一个读取纹理像素信息的方法

第三步:给UIButton添加方法,设置是否实用像素触摸。


使用方法

在创建按钮的地方,设置按钮是否使用像素触摸即可。

具体实现:

  1. cc.Sprite.prototype._pixels = [];
  2. cc.Sprite.prototype.readPixels = function(x,y){
  3. var w = this.width;
  4. var h = this.height;
  5. if(!this._pixels || this._pixels.length == 0){
  6. var canvas = cc.newElement("canvas"); // 创建一个新的元素节点
  7. canvas.width = w;
  8. canvas.height = h;
  9. var ctx = canvas.getContext("2d"); // 获得一个2d的画布(通过它就可以这个画布上的像素信息,我们只在上面绘制一张图片)
  10. ctx.drawImage(this.getTexture().getHtmlElementObj(),0); // 因此获得的像素信息也就等于是这个图片的像素信息</span>
  11.  
  12. this._pixels = ctx.getImageData(0,w,h).data; // 获得像素信息
  13. }
  14. var idx = (h-y) * w * 4 + x * 4; // 根据触摸坐标得到像素上的索引
  15. return [this._pixels[idx],this._pixels[idx + 1],this._pixels[idx + 2],this._pixels[idx + 3]]; // 返回这个点上的的像素信息
  16. };
  17.  
  18.  
  19. ccui.Button.prototype.setPixelTouchEnabled = function (b) {
  20. this._pixelEnabled = b;
  21. };
  22.  
  23. ccui.Button.prototype.getPixelTouchEnabled = function (b) {
  24. return this._pixelEnabled;
  25. };
  26.  
  27. ccui.Widget.prototype.onTouchBegan = function (touch,event) {
  28. this._hit = false;
  29. if (this.isVisible() && this.isEnabled() && this._isAncestorsEnabled() && this._isAncestorsVisible(this) ){
  30. var touchPoint = touch.getLocation();
  31. this._touchBeganPosition.x = touchPoint.x;
  32. this._touchBeganPosition.y = touchPoint.y;
  33. if(this.hitTest(this._touchBeganPosition) && this.isClippingParentContainsPoint(this._touchBeganPosition))
  34. this._hit = true;
  35. var target = event.getCurrentTarget();
  36. if(target instanceof ccui.Button && target.getPixelTouchEnabled()){
  37. var locationInNode = target.convertToNodeSpace(touchPoint);
  38. //var locationInNode = touchPoint;
  39.  
  40.  
  41. var s = target.getContentSize();
  42. var rect = cc.rect(0,s.width,s.height);
  43. if (cc.rectContainsPoint(rect,locationInNode)) {
  44. var sp = target.getVirtualRenderer();
  45. var x = locationInNode.x;
  46. var y = locationInNode.y;
  1. if(sp instanceof cc.Sprite){
  2. var pexels = sp.readPixels(Math.round(x),Math.round(y));
  3. cc.log("alhpa : %d",(pexels[3]));
  4. if(pexels[3] > 0){
  5. // 非透明
  6. this._hit = true;
  7. }else{
  8. // 透明
  9. this._hit = false;
  10. }
  11. }
  12. }
  13. }
  14. }
  15. if (!this._hit) {
  16. return false;
  17. }
  18. this.setHighlighted(true);
  19. /*
  20. * Propagate touch events to its parents
  21. */
  22. if (this._propagateTouchEvents)
  23. {
  24. this.propagateTouchEvent(ccui.Widget.TOUCH_BEGAN,this,touch);
  25. }
  26.  
  27.  
  28. this._pushDownEvent();
  29. return true;
  30. };


最后补充:

当我写完canvas版本的时候,想到要做到位,肯定也要支持webGL。webGL的绘制方法和canvas不一样。但是找了半天,没有找到方法。于是我想,webGL严格来说是属于canvas上的内容。然后直接实验这段代码能不能在webGL模式下跑,测试后通过,没问题。

最近还在学习webGL,有结果了再补充原因。

猜你在找的Cocos2d-x相关文章