>  기사  >  웹 프론트엔드  >  캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

黄舟
黄舟원래의
2017-01-16 17:03:031326검색

베지어 곡선과 2차 곡선

다음으로 소개할 경로는 베지어 곡선으로, 2차 및 3차 형태도 가능하며 일반적으로 사용되는 복잡하고 정형적인 도형을 그립니다.

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

위 두 코드 라인의 차이점은 오른쪽 그림과 같습니다. 둘 다 시작점과 끝점(그림의 파란색 점)이 있지만 2차 베지어 곡선에는 하나의(빨간색) 제어점(점)만 있고 3차 베지어 곡선에는 2개가 있습니다. 매개변수 x와 y는 끝점의 좌표이고, cp1x와 cp1y는 첫 번째 제어점의 좌표이고, cp2x와 cp2y는 두 번째 제어점입니다.

캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

벡터 드로잉 소프트웨어인 Adobe Illustrator에서와 같이 즉각적인 시각적 피드백이 없기 때문에 2차 및 3차 베지어 곡선으로 작업하는 것은 상당히 어렵습니다. 복잡한 그래픽을 그리는 데 사용하는 것이 더 번거롭기 때문입니다. 그러나 시간이 있고 가장 중요한 것은 인내심이 있다면 복잡한 그래픽도 그릴 수 있습니다. 아래에 간단하고 규칙적인 그래프를 그려보겠습니다. 이러한 예는 비교적 간단합니다. 우리가 그리는 것은 완전한 그래프입니다.

캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

// 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();

계산을 통해 2차 곡선의 단일 제어점에서 해당 3차 곡선의 두 제어점을 얻을 수 있으므로 2차 곡선을 2차 곡선으로 변환하는 것이 가능합니다. 큐빅 이지만 그 반대는 사실이 아닙니다. 2차 베지어 곡선으로의 변환은 3차 방정식의 3차 항이 0인 경우에만 가능합니다. 일반적으로 세분화 알고리즘을 통해 3차 베지어 곡선을 근사화하기 위해 여러 개의 2차 곡선을 사용할 수 있습니다.

캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

// 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();

직사각형 경로 직사각형

위에서 언급한 직사각형을 직접 그릴 수 있는 세 가지 방법 외에도 직사각형 경로를 그리는 ret 방법도 있습니다.

rect(x, y, width, height)

4개의 매개변수를 허용합니다. x와 y는 왼쪽 위 모서리의 좌표이고, 너비와 높이는 너비와 높이입니다. 호출되면 (0,0) 매개변수로 moveTo 메소드가 자동으로 호출되므로 시작 좌표가 초기 원점으로 복원됩니다.

종합 예시

전체 예시에서 가장 주목할 점은 roundedRect 함수의 사용과 fillStyle 속성의 설정입니다. 사용자 정의 함수는 복잡한 그래픽 그리기를 캡슐화하는 데 매우 유용합니다. 이 예에서 사용자 정의 함수를 사용하면 코드가 절반 정도 절약됩니다. fillStyle 속성의 사용에 대해서는 다음 예에서 자세히 설명합니다. 여기서는 채우기 색상을 기본 검정색에서 흰색으로, 다시 검정색으로 변경하는 데 사용됩니다.

캔버스 게임 개발 학습 3부: 복잡한 모양 그리기

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();
}

위 내용은 캔버스 게임 개발 학습의 세 번째 부분인 복잡한 도형 그리기입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.php)를 참고해주세요. CN)!



성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.