SVG를 사용하여 13KB의 JS 게임 만들기

12943 단어 svgjs13kjavascript
이것은 나의 JS13K 검시 보고서의 두 번째 부분으로 기술성이 더욱 강하다.니가 아직 없으면
JS13K는 당신이 원하는 모든 것을 사용하여 13KB를 개발하는 자바스크립트 게임입니다. 코드, 이미지, 소리, 게임 데이터와 당신이 필요로 할 수 있는 모든 라이브러리를 포함하여 당신의 모든 동의가 13KB에 적합하기만 하면 됩니다.

총유기탄소

  • Choice of graphics
  • Creating and manipulating SVGs
  • Saving and optimizing SVGs
  • Animating dots on an SVG
  • Moving SVG elements around
  • Final notes
  • 그래픽 선택


    Last year 나는 2D 캔버스로 게임을 개발했다.캔버스는 매우 유연하여 사용하기 쉽다.자바스크립트에서 동적으로 자신의 도형을 생성함으로써 대량의 바이트를 절약할 수 있다.

    올해 어려운 시작을 한 후에 나는 이 생각을 포기하고 게임 메커니즘에 전념했다.하지만 나는 여전히 게임을 더욱 좋아보이고 매력적으로 보이게 하는 UI를 원한다.그래서 SVG를 사용할 생각이 생겼어요.SVG의 장점은 다음과 같습니다.
  • 래스터 형식에 비해 크고 복잡하며 매끄럽고 축소 가능한 이미지 크기가 작습니다.
  • XML이며 HTML을 포함할 수 있습니다. 각 요소에 대한 클래스와 ID를 설정할 수 있습니다.
  • javascript에서 조작할 수 있습니다.OpenGL이 아닌 웹 dev 배경이 있다면, UI를 DOM으로 조작하는 것은 매우 매력적인 주장입니다.
  • CSS3
  • 를 사용하여 스타일 및 애니메이션을 설정할 수 있습니다.
  • SVG 애니메이션(SMIL)은 HTML5와 browser compatibility is great for non-Edge browser 중 하나입니다.
  • 나는 SVG를 사용하기로 결정할 때 천진난만한 가설을 했다는 것을 알게 될 것이다.
  • SVG는 크기가 작지만 쉽게 압축되지 않습니다.경로 정의는 사실상 상당히 지루하고 XML 자체도 마찬가지다.
  • SVG 요소에서 CSS를 사용하는 기능은 제한적입니다.전환에 대한 지원이 신뢰할 수 없음;
  • SVG 브라우저 지원은 실제로 매우 엉망입니다.2005년으로 돌아가 모든 브라우저가 자신의 일을 하고 있는 것과 같다.이것은 사실 나로 하여금 초기에 Safari와 Edge에 대한 지지를 포기하게 했다.
  • SMIL은 CSS 애니메이션에 비해 문서가 엉망인 골치 아픈 문제이다.
  • 그러나 내가 이 모든 것을 깨달았을 때 침몰의 비용은 너무 높았다.
    나는 또한 모든 아이콘에 이모티콘을 광범위하게 사용하기로 결정했다.이모티콘은 주요 운영체제(적어도 Ubuntu, MacOS, Windows)에서 이미 매우 보편적이다.이렇게 하면 아이콘마다 몇 바이트만 필요합니다.물론 취사는 시스템마다 이모티콘의 외관을 제어할 수 없다는 것이다.

    SVG 생성 및 작업


    나의 goto 벡터 이미지 편집기는 Inkscape 이다.이것은 libre 소프트웨어로 Linux에서도 다른 운영체제를 실행할 수 있다.나는 이미 여러 해 동안 썼기 때문에 사용하기에 매우 편안하다.

    대부분의 형태는 노드와 곡선으로 이루어져 있다.간단히 말하면, 복잡도나 곡선이 아니라 모양의 크기가 노드의 수량에 따라 SVG 파일의 크기가 정의됩니다.SVG는 다음과 같은 다양한 유형의 시각 요소를 지원합니다.
  • 경로는 매우 유연하고 사람이 원하는 대로 복잡하지만 더욱 상세하다.
  • 물체, 예를 들어 직사각형과 원형은 그다지 유연하지 않지만 사이즈는 비교적 작다.
  • 기호, 원소를 중용하여 대량의 지식 라이브러리를 절약하는 데 도움이 된다.
  • 그룹은 사용자가 정의한 경로, 대상, 기호와 다른 그룹의 집단이다.
  • SVG에는 스타일, 그래디언트, 애니메이션 등의 정의가 있는 제목도 포함될 수 있습니다.Inkscape의 UI는 내가 언급한 모든 내용을 거의 지원하지만 애니메이션은 제외됩니다.사실, 나는 내가 SVG 태그에서 애니메이션을 수동으로 작성할 때, Inkscape는 그것들을 무시할 뿐만 아니라, 다음에 저장할 때 그것들을 삭제한다는 것을 알아차렸다.
    다행히도 HTML에 여러 SVG를 포함할 수 있습니다. 모든 스타일과 다른 정의가 공유됩니다.

    SVG 저장 및 최적화


    Inkscape는 PDF, PNG 또는 Postscript와 같은 여러 가지 다른 형식으로 SVG를 저장할 수 있습니다.가장 많이 사용되는 형식은 최적화된 SVG입니다.이 형식은 파일에서 쓸모없는 주석, 제목, 속성을 제거합니다.파일을 저장할 때마다 사용할 최적화를 선택할 수 있습니다.그럼에도 불구하고, 나는 가끔 수동으로 표시를 편집해서 쓸모없는 정보를 삭제해야 한다는 것을 발견했다.

    예를 들어, paint-order 는 요소를 채우기 전이나 이후에 그리는 획을 정의하는 속성입니다.그러나 나의 대다수 형상은 심지어 필획이 없기 때문에 전체 풍격은 필요없다.Inkscape에서 이 스타일을 다시 추가하기 때문에 가끔 이 스타일을 삭제합니다.
    앞에서 설명한 대로 SVG는 기호를 지원합니다.이것은 어떤 장면에서 효과가 매우 좋다. 즉, 정적 대상, 예를 들어 나의 게임 속의 작은 집에 대한 것이다.그러나 주위 사람들에게 자바스크립트에서 SVG 대상을 복제하는 것이 효과적이라는 것을 알게 되었다.

    위의gif에서 저는 당신에게 제 게임 속의'달리는 개미'애니메이션을 보여 드리겠습니다.그리고 나서 나는 경로의 마스크를 사용하지 않았다. 그러면 너는 이 점들이 실제로는 경로를 따라 애니메이션을 설정하는 단일 대시를 볼 수 있다.이 경로는 템플릿 경로의 클론으로 X축에 임의 축척 변환이 적용됩니다.
    $newTrail.style.transform = `scaleX(${1 + Math.random()*0.7 - 0.2})`;
    
    그래서 모든'사람'은 경로의 복제이다.

    SVG에 점을 설정한 애니메이션


    SVG 스타일 속성 stroke-dasharray 을 사용하여 SVG 경로를 따라 점의 애니메이션을 설정할 수 있습니다.이 속성은 경로의 점선 패턴을 정의하는 값 그룹을 받아들입니다.
    따라서 예를 들어 획획선 배열 값 "2-1-4-1"은 2px 획선, 1px 간격, 4px 획선, 다른 1px 간격으로 획 도안을 그리고 경로가 끝날 때까지 반복합니다.해당 CSS 속성은 애니메이션을 설정할 수 있습니다.따라서 경로 애니메이션을 생성하기 위해 크기가 1인 대시 기호를 만들고 주변 간격의 크기를 조정합니다.더 정확히 말하자면, 나는 간극을 위해 애니메이션을 설정하여 0에서 경로의 길이로 바꾸었다.

    위의 애니메이션 코드는 this codepen 에서 찾을 수 있습니다.
    나는 어떻게 경로의 시작에 점이 하나도 없는지 모르겠다.만약 네가 어떻게 하는지 안다면, 나는 듣고 싶다.
    그리고 모든 사람들은 한 길의 단거리 달리기였는데, 사냥꾼만 예외였고, 그들은 항상 쌍쌍이 되어 여행을 했다.사냥꾼의 단거리 달리기 모드는 기본적으로 1, 2, 1이다. 그리고 가변 간극에 둘러싸인다.

    Fun fact: the stars in the sky are also a dashed path with a very large gap between dots!



    그래디언트 배경 애니메이션 설정하기


    아무도 눈치채지 못할 또 다른 애니메이션은 게임이 시작될 때의 스모그 애니메이션이다.유저가 처음으로 나무를 얻었을 때, 게임 속의 사람들은 그것을 태우기 시작했다.

    SVG 요소는 CSS 속성을 허용하지 않습니다background.반면 이들이 사용하는 속성fill은 순색을 받아들여 그라데이션을 허용하지 않는다.따라서 애니메이션 그래디언트도 얻을 수 없습니다.SVG의 사다리 자체가 요소입니다.SVG 소스 코드에서 애니메이션을 정의할 수 있습니다.
    <linearGradient id="grad"
        x1="157" x2="157" y1="28" y2="28"
        gradientUnits="userSpaceOnUse">
      <stop stop-color="#fff" stop-opacity=".9" offset="0" />
      <stop stop-color="#e0e0e0" stop-opacity="0" offset="1" />
      <animate fill="freeze"
        attributeName="y2" begin="indefinite"
        dur="5" from="28" to="1" repeatCount="1" />
    </linearGradient>
    
    상기 <animate> 요소는 그래디언트 애니메이션을 정의합니다.일반적으로 애니메이션은 바로 시작됩니다.그러나 begin="indefinite" 속성으로 인해 애니메이션은 대기 상태입니다.자바스크립트를 사용하여 애니메이션을 터치할 수 있습니다.
    querySelect('animate').beginElement()
    

    SVG 요소 이동


    나는 동작을 완성하기 위해 몇 가지 다른 방법을 찾았다.이 경우 CSS는 실행 가능한 선택입니다.단일 요소 및 요소 그룹에 대해 CSS 변환을 사용할 수 있습니다.불행하게도 원소의 이동 방식은 의외일 수도 있다.
    우선, SVG는 서로 다른 차원에서 생활한다.내 말은, 만약 SVG가 이미 축소되었다면, 웹 페이지의 픽셀이 반드시 SVG의 픽셀이 아니라는 것이다.또한 이동을 시도한 요소가 번역된 경우 (예: Inkscape에서) 변환 원점은 요소의 중간에 없을 수 있습니다.회전 중심을 잘 모르기 때문에 회전을 사용하기가 매우 어렵다.
    더 나빠!Firefox에서 정상적으로 작동하는 변환 + 회전은 Chrome에서 전혀 정상적으로 작동하지 않습니다.나의 예에서, 나는 게임이 시작될 때 침몰선을 위해 애니메이션을 만들려고 시도했다.내 해결 방안은 Inkscape의 비행선을 위치(0,0)로 이동하는 것이다. 이것은 도움이 될 것 같다.하지만 나는 틀림없이 뭔가를 바꿨을 거야. 회전이 또 끊겼어.나는 결국 배를 회전하지 않고 가라앉히고 아래로 이동시켰다.
    해난 애니메이션을 조정한 후, 플레이어가'리셋'을 눌렀을 때, 크롬은 중복 애니메이션을 처리할 수 없다는 것을 발견했다.SVG는 처음과 완전히 같고 애니메이션도 마찬가지지만 어떤 이유로든 배 애니메이션은 완전히 버려졌다.그것제조의아니오, 느낌.
    나는 마지막으로 일부 추악한 CSS를 추가했다. 단지 크롬이 전환을 재설정하려고 시도했을 뿐이다.
    /* Stupid hack for stupid Chrome */
    @supports (not (-moz-appearance:none))
    { 
      #ship.new {
        transform: translate(0%, 0%);
      }
      #ship.go {
        transition: transform 7s cubic-bezier(.5,0,1,1);
        transform: translate(-20%, 60%)
      }
    }
    
    게임이 리셋되면 크롬이 배에 추가되는 것도 봤어요 translate(0,0).이것은 아무런 의미가 없다.SVG는 원시적이어야 하는데 아무도 크롬에게 이렇게 하라고 말하지 않았다.이 문제를 해결하기 위해 게임을 다시 시작할 때 번역을 수동으로 삭제해야 합니다.
    $shipTop.removeAttribute('transform') // Because Chrome is shit
    

    최종 주석


    나는 단지 배 한 척을 옮기기 위해 많은 번거로움을 겪었기 때문에, 너는 내가 SVG와 SMIL을 사용하여 더 많은 게임을 만들었다는 것을 발견하지 못할 것이다.나는 그것을 간단하게 추천할 수 없다. 적어도 어떤 라이브러리도 없는 상황에서 원시적인 형식이다.따라서 우리가 처한 상황은 SVG의 CSS3 애니메이션이 신뢰할 수 없지만 이미 SMIL의 대체품으로 밀려났다는 것이다almost to the point of deprecating SMIL, but not quite.

    In the 15 months since we announced our intention to deprecate and eventually remove SMIL, we’ve heard a variety of opinions from members of the community. We value all of your feedback, and it's clear that there are use cases serviced by SMIL that just don’t have high-fidelity replacements yet. As a result, we’ve decided to suspend our intent to deprecate and take smaller steps toward other options.

    • Chrome team, 2016/08/17

    나의 올해 주요 수확은 다음 시합 전에 준비를 잘 하고 캔버스 엔진과 웹 GL 같은 새로운 도구를 배워야 한다는 것이다.그 밖에 나는 왜 생각하지 못했는지 모르겠지만, 이 전체 혼란 국면에 대해 가장 뚜렷한 해결 방안은 배를 단독 SVG로 만들어 지도와 겹치게 하는 것이다.사후 제갈량 그렇죠?

    좋은 웹페이지 즐겨찾기