如何实现与粒子的软边缘区域

我的游戏是使用Phaser创建的,但问题本身是引擎不可知的。

在我的游戏中,我有几个环境,基本上是玩家角色可以移动并受其影响的多边形区域。 例如冰,火,毒等。这些区域的graphics元素是填充颜色的多边形区域本身以及合适types的粒子(在本例中为冰块)。 这是我目前正在实现这个 – 用覆盖粒子图案的tilesprite的多边形掩码:

在这里输入图像描述

硬边看起来不好。 我想通过做两件事来改进:1.使多边形填充区域具有柔软的边缘,并融合到背景中。 2.让一些碎片离开多边形区域,这样它们不会在中间被切割,并且该区域没有直线

例如(样机):

在这里输入图像描述

我认为1可以通过模糊多边形来实现,但我不知道如何去处理2。

你将如何去执行这个?

Solutions Collecting From Web of "如何实现与粒子的软边缘区域"

如果你想要一些与你的模型接近的东西,我会使用粒子(它不一定是一个完全成熟的粒子系统)。

在RenderTexture上以多边形的forms渲染粒子。 确保在颗粒上使用添加剂混合。 多边形内部的粒子将平滑地相互混合,而外部的粒子会给出你想要的柔软边缘。 (效果的一个例子可以在这个YouTubevideo中观看: 添加粒子video现在将RenderTexture渲染到主屏幕上,完成后RenderTexture是必要的,以便粒子不会与背景混合。

你可以尝试把三角形直接放在粒子纹理上,看看这是如何工作的。 否则,将它们作为单独的图层渲染在“粒子汤”的顶部。

在更新的jsfiddle中创建一个快速样机,看起来像这样 演示 你可以在这里find更新的演示

每个粒子都有一个速度和一个原点。 当你的玩家触及多边形时,你改变每个粒子的速度与玩家的速度成正比。 粒子离玩家越远,受到玩家速度的影响就越小。

计算粒子速度的公式可能是这样的:

//player.velocity and particle.velocity are vectors //k is a factor to enhance or weaken the influence of players velocity var distanceToPlayer = (player.position - particle.position).length(); particle.velocity = particle.velocity + ((k * player.velocity) + particle.velocity) * (1/distanceToPlayer); 

要计算你的更新方法中的粒子位置:

 var speedY = -(springConstant * (particle.position.y - particle.origin.y)) - (dampingFactor * particle.velocity.y); var speedX = -(springConstant * (particle.position.x - particle.origin.x)) - (dampingFactor * particle.velocity.x); particle.position.y = particle.position.y + speedY; particle.position.x = particle.position.x + speedX; particle.velocity.x = particle.velocity.x + speedX; particle.velocity.y = particle.velocity.y + speedY; 

当玩家搅动液体时,这会给你一个“stream体”,每个粒子在其原点周围摆动。 springConstant改变了一个粒子从原点和阻尼因子离开的速度。 您可能需要调整代码,因为它是我在游戏中使用的1d模拟的修改版本。

现在演示一下: 演示只需调整顶端的3个常量,直到stream体performance得像你想要的那样。

我对这两点的看法:

  1. 你可以使用着色器模糊,但这将是非常昂贵的。 相反,我会画一个额外的三角形的边界,从中心的半透明淡入边缘透明,模拟“模糊”。 我已经在我的一个游戏中完成了它,它工作得很好。 下面是我的游戏中彩虹助推器的两个截图。

    在这里输入图像描述在这里输入图像描述

    外边框有一个渐变。 在我的情况下,边界并不像内部那样以不透明的方式开始,但是如果将这些不透明度设置为相等的话,就会有一个很好的淡入淡出效果。

  2. 我将编程一个粒子系统,使粒子遵循多边形。 通过这样做,您不必担心在边缘会发生什么。 粒子系统的动力学将确保粒子在多边形内并均匀分布。 你可以尝试使最接近的粒子彼此推开,但是使它有很多“质量”,所以你有惯性,看起来很平滑。 为了使这个事情变得快速,有一些可能性,但是最大的问题将是推动彼此机制的时间复杂性。 如果你把每个粒子推到其他粒子上,你将会有O(n ^ 2),如果你的系统中有100个粒子,那么这个效果就不好。 关于如何优化这个的一个很好的阅读是这个PixelJunk的演示文稿: http : //fumufumu.q-games.com/gdc2010/shooterGDC.pdf

    更简单的方法是在构建粒子系统时将每个粒子连接到三个或四个其他粒子。 现在每个粒子只需要推动连接的其他四个粒子。 但是,这种方法使得粒子系统中的动荡不可能。 但这似乎不成问题,因为你目前的情况使用静态纹理。 这种方法将是O(n),这是伟大的。

我读过这篇文章的想法是这样的:
•建立一组您将用于您所在地区的瓷砖。
•在一个小的临时canvas上以瓦片分辨率渲染区域多边形(例如,如果瓦片是16X16,以(16X,16X)较低分辨率渲染)。
•使用该临时canvas决定是否在主canvas上渲染图块:
如果在低分辨率canvas上设置点,请在主canvas上绘制一个“随机”图块。 如果一个点只是一个设置点的邻居,在主canvas上绘制一个较低不透明度(进行过渡)的“随机”图块。

我担心降低分辨率会产生块效应,但即使使用20X20的瓦片,它看起来也不错:

在这里输入图像描述

步骤是:拿你的多边形:
在这里输入图像描述

以您的瓷砖分辨率绘制多边形: 在这里输入图像描述 (!!是的,这是商场红色的东西)。

然后使用低分辨率canvas的imageData来决定是否绘制一个瓦片或音符。
如果在低分辨率canvas上设置像素,则意味着我们应该绘制图块:选取“随机”图块索引以select要绘制的图块。 对于给定的区域/瓦片,随机索引应该总是相同的。
如果一个点是空的,但是在一个填充点旁边,也画一个方块,但是一半是不透明的。

在这里输入图像描述

所以让我们来画砖:

在这里输入图像描述

对于多边形,我只画几次多边形,将其缩小,并增加每个绘图的不透明度(也可以使用globalCompositeOperation'lighter')。

在这里输入图像描述

一旦你把所有东西加起来,就会给出:

在这里输入图像描述

小提琴在这里:

http://jsfiddle.net/gamealchemist/T7b4Y/

让我知道这是否有帮助。

只是一个想法:

在你的瓷砖中,“碎片”最多约80px宽。 我会建议,做2个领域。 你画出你的原始多边形,然后你从每个边上约80个像素做一个模型。 然后,您将您的瓷砖绘制成更大的多边形。

然后,在内部多边形之外有一个像素的所有“块”,与内部多边形不交叉的情况下,您可以用透明度填充它们。

这是非常高的水平,但我想我会分享给你。 这里有很多细节要确定。

一个粗糙的图像来演示:

在这里输入图像描述

如果内部的黑色多边形是原始的,则会用红点擦除所有的多边形。