Home  >  Article  >  Web Front-end  >  Canvas Game Development Learning Part 3: Drawing Complex Shapes

Canvas Game Development Learning Part 3: Drawing Complex Shapes

黄舟
黄舟Original
2017-01-16 17:03:031326browse

Bezier and quadratic curves

The path to be introduced next is the Bezier curve, which can be in the form of quadratic and cubic, and is generally used Draw complex and regular shapes.

quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

The difference between the above two lines of code is shown in the picture on the right. They both have a starting point and an ending point (the blue point in the picture), but a quadratic Bezier curve has only one (red) control point (point) while a cubic Bezier curve has two. Parameters x and y are the coordinates of the end point, cp1x and cp1y are the coordinates of the first control point, and cp2x and cp2y are the second.

Canvas Game Development Learning Part 3: Drawing Complex Shapes

Working with quadratic and cubic Bezier curves is quite challenging because there is no immediate visual feedback like in the vector drawing software Adobe Illustrator. Because it is more troublesome to use it to draw complex graphics. But if you have time, and most importantly, patience, you can draw even complex graphics. Let's draw a simple and regular graph below. These examples are relatively simple. What we draw are complete graphs.

Canvas Game Development Learning Part 3: Drawing Complex Shapes

// Quadratric curves example
ctx.beginPath();
ctx.moveTo(75,25);
ctx.quadraticCurveTo(25,25,25,62.5);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,65,100);
ctx.quadraticCurveTo(125,100,125,62.5);
ctx.quadraticCurveTo(125,25,75,25);
ctx.stroke();

Through calculation, two control points of the corresponding cubic curve can be obtained from a single control point of the quadratic curve, so it is possible to convert the quadratic to the cubic , but the opposite is not true. Conversion to a quadratic Bezier curve is only possible if the cubic term in the cubic equation is zero. Usually, multiple quadratic curves can be used to approximate the cubic Bezier curve through a subdivision algorithm.

Canvas Game Development Learning Part 3: Drawing Complex Shapes

// Bezier curves example
ctx.beginPath();
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62.5);
ctx.bezierCurveTo(130,62.5,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.fill();

Rectangle PathRectangles

In addition to the three methods mentioned above that can directly draw rectangles, we also have a rect method for drawing Rectangular path.

rect(x, y, width, height)

It accepts four parameters, x and y are the coordinates of its upper left corner, width and height are its width and height. When it is called, the moveTo method will be called automatically with the parameter (0,0), so the starting coordinates are restored to the initial origin.

Comprehensive Example

In the entire example, the most noteworthy is the use of the roundedRect function and the setting of the fillStyle attribute. Custom functions are very useful for encapsulating the drawing of complex graphics. Using a custom function in this example saves about half the code. The use of the fillStyle attribute will be discussed in depth in the following examples. Here it is used to change the fill color from the default black, to white, and back to black.

Canvas Game Development Learning Part 3: Drawing Complex Shapes

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  roundedRect(ctx,12,12,150,150,15);
  roundedRect(ctx,19,19,150,150,9);
  roundedRect(ctx,53,53,49,33,10);
  roundedRect(ctx,53,119,49,16,6);
  roundedRect(ctx,135,53,49,33,10);
  roundedRect(ctx,135,119,25,49,10);

  ctx.beginPath();
  ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false); //chiensexu  本来是true呵呵,反了
  ctx.lineTo(31,37);
  ctx.fill();
  for(i=0;i<8;i++){
    ctx.fillRect(51+i*16,35,4,4);
  }
  for(i=0;i<6;i++){
    ctx.fillRect(115,51+i*16,4,4);
  }
  for(i=0;i<8;i++){
    ctx.fillRect(51+i*16,99,4,4);
  }
  ctx.beginPath();
  ctx.moveTo(83,116);
  ctx.lineTo(83,102);
  ctx.bezierCurveTo(83,94,89,88,97,88);
  ctx.bezierCurveTo(105,88,111,94,111,102);
  ctx.lineTo(111,116);
  ctx.lineTo(106.333,111.333);
  ctx.lineTo(101.666,116);
  ctx.lineTo(97,111.333);
  ctx.lineTo(92.333,116);
  ctx.lineTo(87.666,111.333);
  ctx.lineTo(83,116);
  ctx.fill();
  ctx.fillStyle = "white";
  ctx.beginPath();
  ctx.moveTo(91,96);
  ctx.bezierCurveTo(88,96,87,99,87,101);
  ctx.bezierCurveTo(87,103,88,106,91,106);
  ctx.bezierCurveTo(94,106,95,103,95,101);
  ctx.bezierCurveTo(95,99,94,96,91,96);
  ctx.moveTo(103,96);
  ctx.bezierCurveTo(100,96,99,99,99,101);
  ctx.bezierCurveTo(99,103,100,106,103,106);
  ctx.bezierCurveTo(106,106,107,103,107,101);
  ctx.bezierCurveTo(107,99,106,96,103,96);
  ctx.fill();
  ctx.fillStyle = "black";
  ctx.beginPath();
  ctx.arc(101,102,2,0,Math.PI*2,true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(89,102,2,0,Math.PI*2,true);
  ctx.fill();
}
function roundedRect(ctx,x,y,width,height,radius){
  ctx.beginPath();
  ctx.moveTo(x,y+radius);
  ctx.lineTo(x,y+height-radius);
  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
  ctx.lineTo(x+width-radius,y+height);
  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
  ctx.lineTo(x+width,y+radius);
  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
  ctx.lineTo(x+radius,y);
  ctx.quadraticCurveTo(x,y,x,y+radius);
  ctx.stroke();
}

The above is the third part of canvas game development learning: drawing complex shapes. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!



Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn