繁体   English   中英

HTML5 Canvas:使用构造函数创建复杂的 Canvas 形状

[英]HTML5 Canvas: Using constructor functions to create complex Canvas shapes

我目前正在研究 HTML5 Canvas 项目(我在这里写了一个单独的问题)。 我认为我面临的问题的解决方案之一是为路径创建一个引用(保存为对象),并使用方法ispointinpath检查我的鼠标 position 是否在路径内 - 如果不是,它重置游戏。

我尝试为复杂的路径形状创建构造函数 function。 以下是复杂形状作为原始代码的样子:

 var canvas = document.querySelector('canvas'); // returning a drawing context to a variable 'c' // allows you to draw 2d elements var c = canvas.getContext('2d'); canvas.width = 1000; canvas.height = 700; canvas.style.width = 1000; canvas.style.height = 700; c.beginPath(); c.moveTo(350, 650); //start c.lineTo(350, 200); c.lineTo(900, 200); c.lineTo(900, 250); c.lineTo(700, 250); c.lineTo(600, 250); c.lineTo(600, 650); c.fillStyle = "#C1EEFF"; c.fill();
 <canvas></canvas>

这是我尝试制作的构造函数 function 的样子:

 var canvas = document.querySelector('canvas'); // returning a drawing context to a variable 'c' // allows you to draw 2d elements var c = canvas.getContext('2d'); canvas.width = 1000; canvas.height = 700; canvas.style.width = 1000; canvas.style.height = 700; var points = [(350, 200), (900, 200), (900, 250), (700, 250), (600, 250), (600, 650)]; function Path(startX, startY, array, color){ c.beginPath(); c.moveTo(startX, startY); // For however many element pairs in the array, create a lineTo statement for(i = 1; i < array.length; i++){ c.lineTo(array[i][0], array[i][1]); } c.fillStyle = color; c.fill(); } var blue = new Path(350, 200, points, '#C1EEFF');
 <canvas></canvas>

它似乎不起作用。 有谁知道这是为什么? 另外,对于我正在尝试做的事情,最好的语法是什么?

如果您将 object 与 position x, y 一起使用会更好

 var canvas = document.querySelector("canvas"); // returning a drawing context to a variable 'c' // allows you to draw 2d elements var c = canvas.getContext("2d"); canvas.width = 1000; canvas.height = 700; canvas.style.width = 1000; canvas.style.height = 700; var points = [ { x: 350, y: 200 }, { x: 900, y: 200 }, { x: 900, y: 250 }, { x: 700, y: 250 }, { x: 600, y: 250 }, { x: 600, y: 650 } ]; function Path(startX, startY, array, color) { c.beginPath(); c.moveTo(startX, startY); // For however many element pairs in the array, create a lineTo statement for (var i = 1; i < array.length; i++) { c.lineTo(array[i].x, array[i].y); } c.fillStyle = color; c.fill(); } var blue = new Path(350, 200, points, "#C1EEFF");
 <canvas></canvas>

第一个问题是您的积分数组:
var points = [(350, 200), (900, 200),...
这不是一个正确的二维数组,也许你的意思是:
var points = [[350, 200], [900, 200],...

同样在您的代码Path中是 function 而不是 class,不确定您为什么要使用new Path(...)也许您将它与new Path2D()混合在一起,但这完全不同...
查看isPointInPath的参数:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath#syntax

这是一个工作示例

 var canvas = document.querySelector('canvas'); var c = canvas.getContext('2d'); canvas.width = 1000; canvas.height = 700; // Function to generate a Path2D object function Path(array) { let path = new Path2D(); path.moveTo(array[0][0], array[0][1]); for (i = 1; i < array.length; i++) { path.lineTo(array[i][0], array[i][1]); } path.lineTo(array[0][0], array[0][1]); return path } //Create the paths var big = [[350,200], [900,200], [900,250], [700,250], [600,250], [600,650], [350,650]]; var blue = Path(big); var triangle = [[25,10], [70,10], [90,85]]; var red = Path(triangle); // Draw all the paths c.beginPath() c.fillStyle = "blue"; c.fill(blue); c.beginPath() c.fillStyle = "red"; c.fill(red); // use isPointInPath console.log(c.isPointInPath(blue, 10, 10)) console.log(c.isPointInPath(blue, 351,201))
 <canvas></canvas>


现在,关于现在已结束的问题,我对使用isPointInPath的建议是提高可伸缩性,你有一堆硬编码的 if 语句,这种方法用于更复杂的多边形是行不通的......但你的游戏中仍然存在问题如何处理级别之间的转换,这是该问题的根本问题。

您似乎正在尝试使用此语法 array[i][0], array[i][1] 访问您的数组坐标,但是您的数组不是 arrays 的数组,它是括号数组。 我没有时间玩它,但试着让它成为一个 arrays 的数组,这样你就可以访问元素 [0] 和 [1]。

[[350, 200], [400, 250]] 等

编辑:我提供 ES6 class 来创建您的地图。 这只是此处提供的其他选项之上的另一个选项。

const canvas = document.querySelector('canvas');
const c = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 700;
 
let points = [[300, 400], [400, 400], [400, 350], [400, 250], [700, 250], [700, 150], [750, 150], [750, 50], [775, 50], [775, 175], [725, 175], [725, 400], [500, 400], [500, 500], [500, 650], [300, 650] ];
let points2 = [[750, 50], [775, 50], [775, 100], [750, 100]];

class Map {
  constructor(start_x, start_y, arr, c) {
    this.start_x = start_x;
    this.start_y = start_y;
    this.arr = arr;
    this.color = c;
  }
  draw() {
    c.beginPath();
    c.moveTo(this.start_x, this.start_y); //start
    this.arr.forEach(point => c.lineTo(point[0], point[1]));
    c.fillStyle = this.color;
    c.fill();
    c.closePath(); 
  }
}
let map1 = new Map(300, 650, points, 'blue');
let map1Finish = new Map(750, 100, points2, 'red');
map1.draw();
map1Finish.draw();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM