lufy's legend

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 732|回复: 6

关于drawTriangles的优化

[复制链接]

30

主题

5

好友

7660

积分

诸侯王

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

发表于 2017-5-16 12:13:51 |显示全部楼层
有不少人通过各种方式问我关于drawTriangles出现白线的问题,这其实是一个老问题了
用过drawTriangles的朋友,大多都看过我的一篇文章
HTML5高级编程之图形扭曲及其应用
http://lufylegend.com/forum/forum.php?mod=viewthread&tid=94
drawTriangles函数的原理就如下图这样,将两次变形通过clip裁剪一下,然后接在一起

但是,canvas的clip有个不足,就是对接起来并不那么完美,两个clip之间出现了一条缝,所以drawTriangles最终的效果会是这样

这就尴尬了....
而其实这一效果在不同浏览器中也是不一样的,有的浏览器会好一些,我一直在等待浏览器自身的完善,能够解决这个问题
但是很长时间过去了,估计这个问题不一定会被修复了,实际上图片扭曲是咱们自己要这么做的,人家clip的用途也并不是为了实现这个效果,所以,还是自己想想办法如何才能解决吧
要说完美的解决方案,我一时也想不到(也不是一时了,好几年了都...),不过投机取巧的方案倒是有的,比如像下面这样

左边的三角形,如图,把其中三角形的两个点分别移动,将三角形扩大,我们多画一部分,这样和第二个三角形对接的时候,那条缝就会被遮住
而右边的三角形,我们采取同样的方法,把其中一个点移动,也将三角形扩大,实际上右边的三角形比较麻烦,因为和这个三角形对接的是下一组三角形(两个三角形是一组,这个应该不用我多做解释了),而且这个点一旦移动,变形效果就会有偏差
另外,我为了说明效果,移动的距离比较远,实际代码中我们必须只能移动一个单位或者两个单位,否则变形就会出现较大的偏差
好了,原理就是这个原理了,接下来修改drawTriangles的代码部分
  1.                 LGraphics.prototype.drawTriangles = function (ve, ind, u, tn, lco) {
  2.                         var s = this;
  3.                         var i, j, l = ind.length, c;
  4.                         s.setList.push(function (c) {
  5.                                 var v = ve, a, k, sw;
  6.                                 for (i = 0, j = 0; i < l; i += 3) {
  7.                                         a = 0;
  8.                                         c.save();
  9.                                         c.beginPath();
  10.                                         c.moveTo(v[ind[i] * 2], v[ind[i] * 2 + 1]);
  11.                                         c.lineTo(v[ind[i + 1] * 2] + (i % 6 == 0 ? 1 : 0), v[ind[i + 1] * 2 + 1]);
  12.                                         c.lineTo(v[ind[i + 2] * 2] + (i % 6 == 0 ? 0 : 2), v[ind[i + 2] * 2 + 1] + 2);
  13.                                         c.lineTo(v[ind[i] * 2], v[ind[i] * 2 + 1]);
  14.                                         c.closePath();
  15.                                         if (tn) {
  16.                                                 c.lineWidth = tn;
  17.                                                 c.strokeStyle = lco;
  18.                                                 c.stroke();
  19.                                         }
  20.                                         c.clip();
  21.                                         if (i % 6 == 0) {
  22.                                                 sw = -1;
  23.                                                 var w = (u[ind[i + 1 + j] * 2] - u[ind[i + j] * 2]) * s.bitmap.width;
  24.                                                 var h = (u[ind[i + 2] * 2 + 1] - u[ind[i] * 2 + 1]) * s.bitmap.height;
  25.                                                 if (j == 0 && w < 0) {
  26.                                                         for (k = i + 9; k < l; k += 3) {
  27.                                                                 if (u[ind[i + 2] * 2 + 1] == u[ind[k + 2] * 2 + 1]) {
  28.                                                                         j = k - i;
  29.                                                                         break;
  30.                                                                 }
  31.                                                         }
  32.                                                         if (j == 0) {
  33.                                                                 j = l - i;
  34.                                                         }
  35.                                                         w = (u[ind[i + 1 + j] * 2] - u[ind[i + j] * 2]) * s.bitmap.width;
  36.                                                 }
  37.                                                 if (i + j >= l) {
  38.                                                         w = (u[ind[i + j - l] * 2] - u[ind[i + 1] * 2]) * s.bitmap.width;
  39.                                                         sw = u[ind[i] * 2] == 1 ? 0 : s.bitmap.width * u[ind[i] * 2] + w;
  40.                                                         if (sw > s.bitmap.width) {
  41.                                                                 sw -= s.bitmap.width;
  42.                                                         }
  43.                                                 } else {
  44.                                                         sw = s.bitmap.width * u[ind[i + j] * 2];
  45.                                                 }
  46.                                                 sh = s.bitmap.height * u[ind[i] * 2 + 1];
  47.                                                 if (h < 0) {
  48.                                                         h = (u[ind[i + 2 - (i > 0 ? 6 : -6)] * 2 + 1] - u[ind[i - (i > 0 ? 6 : -6)] * 2 + 1]) * s.bitmap.height;
  49.                                                         sh = 0;
  50.                                                 }
  51.                                                 if(sw > 0){
  52.                                                         sw -= 1;
  53.                                                 }
  54.                                                 if(sh > 0){
  55.                                                         sh -= 1;
  56.                                                 }
  57.                                                 var t1 = (v[ind[i + 1] * 2] - v[ind[i] * 2]) / w;
  58.                                                 var t2 = (v[ind[i + 1] * 2 + 1] - v[ind[i] * 2 + 1]) / w;
  59.                                                 var t3 = (v[ind[i + 2] * 2] - v[ind[i] * 2]) / h;
  60.                                                 var t4 = (v[ind[i + 2] * 2 + 1] - v[ind[i] * 2 + 1]) / h;
  61.                                                 c.transform(t1, t2, t3, t4, v[ind[i] * 2], v[ind[i] * 2 + 1]);
  62.                                                 w += 1;
  63.                                                 h += 1;
  64.                                                 c.drawImage(s.bitmap.image,
  65.                                                                         s.bitmap.x + sw,
  66.                                                                         s.bitmap.y + sh,
  67.                                                                         w, h,
  68.                                                                         0, 0,
  69.                                                                         w, h);
  70.                                         } else {
  71.                                                 var w = (u[ind[i + 2 + j] * 2] - u[ind[i + 1 + j] * 2]) * s.bitmap.width;
  72.                                                 var h = (u[ind[i + 2] * 2 + 1] - u[ind[i] * 2 + 1]) * s.bitmap.height;
  73.                                                 if (j == 0 && w < 0) {
  74.                                                         for (k = i + 9; k < l; k += 3) {
  75.                                                                 if (u[ind[i + 2] * 2 + 1] == u[ind[k + 2] * 2 + 1]) {
  76.                                                                         j = k - i;
  77.                                                                         break;
  78.                                                                 }
  79.                                                         }
  80.                                                         if (j == 0) {
  81.                                                                 j = l - i;
  82.                                                         }
  83.                                                         w = (u[ind[i + 2 + j] * 2] - u[ind[i + 1 + j] * 2]) * s.bitmap.width;
  84.                                                 }
  85.                                                 if (i + 1 + j >= l) {
  86.                                                         w = (u[ind[i + 1 + j - l] * 2] - u[ind[i + 2] * 2]) * s.bitmap.width;
  87.                                                         sw = u[ind[i + 1] * 2] == 1 ? 0 : s.bitmap.width * u[ind[i + 1] * 2] + w;
  88.                                                         if (sw > s.bitmap.width) {
  89.                                                                 sw -= s.bitmap.width;
  90.                                                         }
  91.                                                 } else {
  92.                                                         sw = s.bitmap.width * u[ind[i + 1 + j] * 2];
  93.                                                 }
  94.                                                 sh = s.bitmap.height * u[ind[i] * 2 + 1];
  95.                                                 if (h < 0) {
  96.                                                         h = (u[ind[i + 2 - (i > 0 ? 6 : -6)] * 2 + 1] - u[ind[i - (i > 0 ? 6 : -6)] * 2 + 1]) * s.bitmap.height;
  97.                                                         sh = 0;
  98.                                                 }
  99.                                                 var t1 = (v[ind[i + 2] * 2] - v[ind[i + 1] * 2]) / w;
  100.                                                 var t2 = (v[ind[i + 2] * 2 + 1] - v[ind[i + 1] * 2 + 1]) / w;
  101.                                                 var t3 = (v[ind[i + 2] * 2] - v[ind[i] * 2]) / h;
  102.                                                 var t4 = (v[ind[i + 2] * 2 + 1] - v[ind[i] * 2 + 1]) / h;
  103.                                                 c.transform(t1, t2, t3, t4, v[ind[i + 1] * 2], v[ind[i + 1] * 2 + 1]);
  104.                                                 c.drawImage(s.bitmap.image,
  105.                                                                 s.bitmap.x + sw,
  106.                                                                 s.bitmap.y + sh,
  107.                                                                 w+2, h+2,
  108.                                                                 0, -h,
  109.                                                                 w+2, h+2);
  110.                                         }
  111.                                         c.restore();
  112.                                 }
  113.                         });
  114.                 };
复制代码
具体改了什么,大家自己对照下引擎源码吧
把这段代码加到你的js里就能覆盖引擎中的处理了,引擎下次更新我会把它加进去(不要问引擎什么时候更新,我保证引擎不会死了...)
说了半天效果如何呢,看下图吧


对照下上面的图,虽然不算完美,是不是效果也好了很多了
不回答与技术和引擎不相关的问题
回复

使用道具 举报

2

主题

0

好友

134

积分

士兵

Rank: 1

发表于 2017-5-16 12:24:15 |显示全部楼层
厉害了!!!
回复

使用道具 举报

52

主题

2

好友

1018

积分

偏将军

Rank: 4

发表于 2017-6-15 09:44:41 |显示全部楼层
修改后是没有线了,但是有截取的图片会错位,没有之前的好。
回复

使用道具 举报

30

主题

5

好友

7660

积分

诸侯王

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

发表于 2017-6-15 10:17:26 |显示全部楼层
zyflzxy 发表于 2017-6-15 09:44
修改后是没有线了,但是有截取的图片会错位,没有之前的好。

帖子里说了,优化的方法就是错位1px来处理
但是跟其他敌方应该没有影响吧,你指的截取图片是什么?
不回答与技术和引擎不相关的问题
回复

使用道具 举报

52

主题

2

好友

1018

积分

偏将军

Rank: 4

发表于 2017-6-15 14:42:00 |显示全部楼层
lufy 发表于 2017-6-15 10:17
帖子里说了,优化的方法就是错位1px来处理
但是跟其他敌方应该没有影响吧,你指的截取图片是什么? ...

错位1PX明白了,错位会影响图片的变化效果,感觉没有之前的好。因为在微信端是没有线的。
回复

使用道具 举报

46

主题

3

好友

1796

积分

偏将军

Rank: 4

发表于 2017-6-15 19:34:37 |显示全部楼层
马上要读大学了,想抽点时间帮lufy前辈做点什么?前辈有什么需求吗?我尽力去做吧。
我对引擎的设想是将来提供一个完善的系统,也就是说有一个很大的社区可以给开发者提供讨论,源码分享,教程,甚至组件(比如手柄,按钮等),还有各式各样的开发工具。
回复

使用道具 举报

30

主题

5

好友

7660

积分

诸侯王

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

发表于 2017-6-16 14:21:53 |显示全部楼层
yorhomwang 发表于 2017-6-15 19:34
马上要读大学了,想抽点时间帮lufy前辈做点什么?前辈有什么需求吗?我尽力去做吧。
我对引擎的设想是将来 ...

兄弟可以抽时间多写几个游戏分享一下,
一来锻炼自己,二来对引擎的推广也会起到一定作用
不回答与技术和引擎不相关的问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

Archiver|lufy's legend

GMT+8, 2017-11-23 05:50 , Processed in 0.074103 second(s), 30 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部