UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

162 lines (131 loc) 5.98 kB
/** * @author Benjamin D. Richards <benjamindrichards@gmail.com> * @copyright 2013-2026 Phaser Studio Inc. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var Earcut = require('../../../geom/polygon/Earcut'); var Class = require('../../../utils/Class'); var RenderNode = require('./RenderNode'); /** * @classdesc * A RenderNode which fills a closed path with solid color. * * It works by taking the array of path data and passing it through * Earcut, which triangulates the polygon into a list of triangles. * Each triangle is then submitted to the batch for rendering. * The first and last points in the path are always preserved; interior * points may be skipped based on the `detail` threshold. * * @class FillPath * @memberof Phaser.Renderer.WebGL.RenderNodes * @constructor * @since 4.0.0 * @extends Phaser.Renderer.WebGL.RenderNodes.RenderNode * @param {Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager} manager - The manager that owns this RenderNode. */ var FillPath = new Class({ Extends: RenderNode, initialize: function FillPath (manager) { RenderNode.call(this, 'FillPath', manager); }, /** * Render the path using Earcut. * * @method Phaser.Renderer.WebGL.RenderNodes.FillPath#run * @since 4.0.0 * @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The context currently in use. * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform matrix. * @param {Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat} submitterNode - The Submitter node to use. * @param {Phaser.Types.GameObjects.Graphics.WidePoint[]} path - The points that define the line segments. * @param {number} tintTL - The top-left tint color. * @param {number} tintTR - The top-right tint color. * @param {number} tintBL - The bottom-left tint color. * @param {number} detail - The level of detail to use when filling the path, in pixels. Any interior point whose x and y distances from the previous accepted point are both within this threshold is skipped. The first and last points are always kept. A value of 0 disables simplification and keeps all points. * @param {boolean} lighting - Whether to apply lighting effects to the path. */ run: function (drawingContext, currentMatrix, submitterNode, path, tintTL, tintTR, tintBL, detail, lighting) { this.onRunBegin(drawingContext); if (detail === undefined) { detail = 0; } var length = path.length; var index, pathIndex, point, polygonIndexArray, x, y; var polygonCacheIndex = 0; var indexedTrianglesIndex = 0; var polygonCache = []; var colors = []; var colorsIndex = 0; for (pathIndex = 0; pathIndex < length; pathIndex++) { point = path[pathIndex]; // Transform the point. x = currentMatrix.getX(point.x, point.y); y = currentMatrix.getY(point.x, point.y); if ( pathIndex > 0 && pathIndex < length - 1 && Math.abs(x - polygonCache[polygonCacheIndex - 2]) <= detail && Math.abs(y - polygonCache[polygonCacheIndex - 1]) <= detail ) { // Skip this point if it's too close to the previous point // and is not the first or last point in the path. continue; } polygonCache[polygonCacheIndex++] = x; polygonCache[polygonCacheIndex++] = y; } polygonIndexArray = Earcut(polygonCache); if (tintTL === tintTR && tintTL === tintBL) { // If the tint colors are all the same, // then we can share vertices between the triangles. var polygonCacheLength = polygonCache.length; for (index = 0; index < polygonCacheLength; index += 2) { colors[colorsIndex++] = tintTL; } submitterNode.batch(drawingContext, polygonIndexArray, polygonCache, colors, lighting); } else { // If the tint colors are different, // then we need to create a new vertex for each triangle. var indexLength = polygonIndexArray.length; var indexedTriangles = Array(indexLength); var vertices = Array(indexLength * 2); var verticesIndex = 0; for (index = 0; index < indexLength; index += 3) { // Vertex A var p = polygonIndexArray[index] * 2; x = polygonCache[p + 0]; y = polygonCache[p + 1]; vertices[verticesIndex++] = x; vertices[verticesIndex++] = y; // Vertex B p = polygonIndexArray[index + 1] * 2; x = polygonCache[p + 0]; y = polygonCache[p + 1]; vertices[verticesIndex++] = x; vertices[verticesIndex++] = y; // Vertex C p = polygonIndexArray[index + 2] * 2; x = polygonCache[p + 0]; y = polygonCache[p + 1]; vertices[verticesIndex++] = x; vertices[verticesIndex++] = y; colors[colorsIndex++] = tintTL; colors[colorsIndex++] = tintTR; colors[colorsIndex++] = tintBL; // Add new indices for the triangle. indexedTriangles[indexedTrianglesIndex++] = index + 0; indexedTriangles[indexedTrianglesIndex++] = index + 1; indexedTriangles[indexedTrianglesIndex++] = index + 2; } submitterNode.batch(drawingContext, indexedTriangles, vertices, colors, lighting); } this.onRunEnd(drawingContext); } }); module.exports = FillPath;