【Scratch拡張機能をJavascriptで自作】svg画像からRPG風のマップを生成する拡張機能を作る〜準備編①
※ 当ページには【広告/PR】を含む場合があります。
2021/02/01
SVGマップを拡張機能化する意義
1. 背景とは別にマップを呼び出すだけで使いたい
2. タイルの座標値からイベントを発生させたい
3. マップを効率的に切り替えたい
4. テキストだけで複数のマップを管理したい
SVGからタイルマップを作る方法
defsとuseを使ってsvg画像を作成する
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" version="1.1">
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(0,0)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(10,0)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(20,0)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(30,0)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(0,10)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(10,10)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(20,10)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(30,10)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(0,20)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(10,20)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(20,20)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(30,20)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(0,30)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(10,30)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(20,30)"/>
<rect width="9" height="9" stroke="black" stroke-width="1" fill="yellow" transform="translate(30,30)"/>
</svg>
rect
defs
use
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" version="1.1" viewBox="0 0 40 40">
<defs>
<rect id="tile1" width="10" height="10" stroke="black" fill="green" viewBox="0 0 10 10"/>
</defs>
<use xlink:href="#tile1" x="0" y="0"/>
<use xlink:href="#tile1" x="10" y="0"/>
<use xlink:href="#tile1" x="20" y="0"/>
<use xlink:href="#tile1" x="30" y="0"/>
<use xlink:href="#tile1" x="0" y="10"/>
<use xlink:href="#tile1" x="10" y="10"/>
<use xlink:href="#tile1" x="20" y="10"/>
<use xlink:href="#tile1" x="30" y="10"/>
<use xlink:href="#tile1" x="0" y="20"/>
<use xlink:href="#tile1" x="10" y="20"/>
<use xlink:href="#tile1" x="20" y="20"/>
<use xlink:href="#tile1" x="30" y="20"/>
<use xlink:href="#tile1" x="0" y="30"/>
<use xlink:href="#tile1" x="10" y="30"/>
<use xlink:href="#tile1" x="20" y="30"/>
<use xlink:href="#tile1" x="30" y="30"/>
</svg>
defs
use
defs
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" version="1.1" viewBox="0 0 40 40">
<defs>
<rect id="tile1" width="10" height="10" stroke="black" fill="green" viewBox="0 0 10 10"/>
<rect id="tile2" width="10" height="10" stroke="black" fill="blue" viewBox="0 0 10 10"/>
<rect id="tile3" width="10" height="10" stroke="black" fill="red" viewBox="0 0 10 10"/>
<rect id="tile4" width="10" height="10" stroke="black" fill="yellow" viewBox="0 0 10 10"/>
</defs>
<use xlink:href="#tile1" x="0" y="0"/>
<use xlink:href="#tile2" x="10" y="0"/>
<use xlink:href="#tile3" x="20" y="0"/>
<use xlink:href="#tile4" x="30" y="0"/>
<use xlink:href="#tile3" x="0" y="10"/>
<use xlink:href="#tile2" x="10" y="10"/>
<use xlink:href="#tile4" x="20" y="10"/>
<use xlink:href="#tile1" x="30" y="10"/>
<use xlink:href="#tile4" x="0" y="20"/>
<use xlink:href="#tile2" x="10" y="20"/>
<use xlink:href="#tile3" x="20" y="20"/>
<use xlink:href="#tile1" x="30" y="20"/>
<use xlink:href="#tile3" x="0" y="30"/>
<use xlink:href="#tile4" x="10" y="30"/>
<use xlink:href="#tile2" x="20" y="30"/>
<use xlink:href="#tile1" x="30" y="30"/>
</svg>
defs
タイルの作成方法
image
xlink:href="data:image/png;base64,"
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" version="1.1" viewBox="0 0 96 96">
<defs>
<image id="tile1" x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,"/>
</defs>
<use xlink:href="#tile1" x="0" y="0"/>
<use xlink:href="#tile1" x="24" y="0"/>
<use xlink:href="#tile1" x="48" y="0"/>
<use xlink:href="#tile1" x="72" y="0"/>
<use xlink:href="#tile1" x="0" y="24"/>
<use xlink:href="#tile1" x="24" y="24"/>
<use xlink:href="#tile1" x="48" y="24"/>
<use xlink:href="#tile1" x="72" y="24"/>
<use xlink:href="#tile1" x="0" y="48"/>
<use xlink:href="#tile1" x="24" y="48"/>
<use xlink:href="#tile1" x="48" y="48"/>
<use xlink:href="#tile1" x="72" y="48"/>
<use xlink:href="#tile1" x="0" y="72"/>
<use xlink:href="#tile1" x="24" y="72"/>
<use xlink:href="#tile1" x="48" y="72"/>
<use xlink:href="#tile1" x="72" y="72"/>
</svg>
grassland.png
xlink:href
...
<image x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/>
...
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" version="1.1" viewBox="0 0 96 96">
<defs>
<image id="tile1" x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/>
<image id="tile2" x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABPSURBVEhLYzx8+PB/BhoCxvr6eqItcHFxYdizZw+URxiA1DNB2TQDoxYQBAOTishJLbjUj0YyQTBMUxEuMFoW0QQM01Q0WhYhg6FuAQMDAMbWKtE8sR+/AAAAAElFTkSuQmCC"/>
<image id="tile3" x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAIySURBVEhLlZXfahNBGMXn3uuiqUmQJiURawrGKEqRCpYKioogXvc1fILeqAhFLIIsNLbamLbZZI1BENFH8EZFq0l2s5ONsb7Bcecrs06atfAtnD3fzP7OMH9IRtRlGjtuCrY/DdvNoNVO48iFY3B6KSwPl7C2dx6b3lHU+wnq4/KiHr6cfhbbbhZVN0fwVO06SQGrg0tYH85iy0+H7QS4vLA7k2jIDH00YTO0sncbL4MZNPwkuLxo9sJQMDoTa7g4FirLIrbcNLi8eO0nsOHlY2ez08+TPxssUKganAKXFxU/R424gNKL7klyq38FlpwDlxdP5GIEHww15GRUq0GVuLxYCe7EzsYJkuTNbhKbboHq+7+XwOWFgs2Arm15Iurb9vcDems4vHjs70NmyJTt/gs+6N8Al6cVmIBSvRMfVuLyQi9bNcxwrTMR1et+kVwfHIePzsCEnd7xqNZ69OsmOZcfO+Q4Vdxpcj17Dh9tkQ79L/zUO0fO5WMPuRH+E5rtqjdF/lDeih3wMD52i3TbkamRfv2Nw4s1WRoJKZ8XYgTaCH841uAq1VxehE8Eay2LCVLNvTzSr8TmrT+l6OBMWMscrBzMgsuLVXmWZmV1i+QHYefrGfJKJ0sDc3nxfFBE2S3hVXce9e/XaD/N0MdvF/HmSx5v5WnUellw+fDSDy+QnwV8+LwwBkehT3No7RbQ8HLhpc/jRbOdwvsfMwSrJWlXYOve3ah+t1uC3c6Ax2fwF9qj7qM6gFKRAAAAAElFTkSuQmCC"/>
<image id="tile4" x="0" y="0" width="24" height="24" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAJTSURBVEhLjZXBbtNAEIbH66ROI0oOiEBBAXEqL8BTcOiJY0+9IyROSHAqghMSQjwBHDlWiFdA4gVyBCTSEtqiChSaxuuFf+LfnWxslU+ydj37zz87aztJdvdvBJ8HcWlHxBeSulOxHK1ek2zyWVZbTpxvSeESsfrMzyRvh1I9Z7w3lf56pnMnRZB2O5PD0bHMpKVByyTPJO9clVnR1vuDbyfy8/tUvA+qhzkMLTCfx3JxIfcSQtBgx02WxCtfh9KbHkn2TwOgu3x9TVbcVPVNdAd9CUkqybu9jdANzUKy9ehCOZvz9vnvhaOwMP7D3ZTk/WigW2OQHdhEmL+4f1jezXn46pIWsdiCnCevx/fCrfyjBmO469icsIg1jnGxOTs4z5xA12QOXDlWQFxnbk045xFRD3yR6siNagHegNg83h3urZ465qXO68g8LVCXZI05t6Ndjzs5Tvo6guqIkGBbBdbEYnXU2E56YaxzsPQM7O7vTB7raEGn0LAINLiQYztZeAYAweGTBwvmn7pPqyKjsK7j3d5OZYYcaAB1LEIfLcDd0JDm2MXtnZe6tvlnuzIBds4iFnbhaI7dEyQgzg+JBXnRnF0QxHHZLrQDmjPRGnAOIxoQu2ax8aWHDHgs1qwJbo45hPGlAhTaI4tpMovjQAtwockc8brY/6A/1/EZEpjWmYPzijI32R1tBHeaydrJFfl1cVgunz24OnMQd0BDy5tnhSQfvgzC/kH973lTZ4CvIoh1WOOXXP2jESzUFQN2jQZNWrLwFjWZ15lhHmupO0PkL0Q+bDUvpbHbAAAAAElFTkSuQmCC"/>
</defs>
<use xlink:href="#tile1" x="0" y="0"/>
<use xlink:href="#tile2" x="24" y="0"/>
<use xlink:href="#tile3" x="48" y="0"/>
<use xlink:href="#tile4" x="72" y="0"/>
<use xlink:href="#tile3" x="0" y="24"/>
<use xlink:href="#tile2" x="24" y="24"/>
<use xlink:href="#tile4" x="48" y="24"/>
<use xlink:href="#tile1" x="72" y="24"/>
<use xlink:href="#tile4" x="0" y="48"/>
<use xlink:href="#tile2" x="24" y="48"/>
<use xlink:href="#tile3" x="48" y="48"/>
<use xlink:href="#tile1" x="72" y="48"/>
<use xlink:href="#tile3" x="0" y="72"/>
<use xlink:href="#tile4" x="24" y="72"/>
<use xlink:href="#tile2" x="48" y="72"/>
<use xlink:href="#tile1" x="72" y="72"/>
</svg>
まとめ
記事を書いた人
ナンデモ系エンジニア
これからの"地方格差"なきプログラミング教育とは何かを考えながら、 地方密着型プログラミング学習関連テーマの記事を不定期で独自にブログ発信しています。
カテゴリー