[Scratch3 拡張機能] svg画像からRPG風のマップを生成する拡張機能を作る〜準備編①


2021/02/01

RPG風のマップをペン機能で作るという試みは、ウェブ検索するといくつか引っかかります。Scratch2時代のものですが、
この解説記事がとても詳しく解説してあります。

基本的にはタイル(マップを構成する画像の単位要素)となるコスチュームを用意しておいて、一定の座標をずらして並べているようなプログラムになるのですが、今回はもっと上級者向けの試みとして、svg画像から生成したマップの画像を直接内部でレンダリングさせる拡張機能を作ってみたいと思います。

SVGマップを拡張機能化する意義

先にRPG風のSVGマップを作るモチベーションに関して挙げると、半分は思いつきですが、以下のマップをScratchのレンダラー(scratch-render)から直接操作することで、色んな利点が考えられます。

            1. 背景とは別にマップを呼び出すだけで使いたい
2. タイルの座標値からイベントを発生させたい
3. マップを効率的に切り替えたい
4. テキストだけで複数のマップを管理したい
        
などなどです。

現時点では抽象的なアイデアのお話をしているだけですが、以降の記事では順を追いながらこのポイントを念頭に具体的な実装を説明していきます。

SVGからタイルマップを作る方法

まず今回は、SVGタイルマップを作るための基本的なアイデアから説明していきます。

defsとuseを使ってsvg画像を作成する

簡単のために全体40x40のサイズ、タイルのサイズ10x10の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>
        
これをSVG画像のテストサイトなどで試すと、

といった感じに4x4のタイルが作成されます。

ただこの画像は同じ
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要素内で定義したタイル要素画像はid属性を通じて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>
        

あとはRPG風の画像を持ったタイルを用意できれば
defsにガンガン登録するのですが、肝心の画像は、自分でベクター画像を書いたり、何かしらのペインターソフトでフリーの素材のpng画像を変換したりすることになります。

一から全てのタイルの絵を描くとなるとそれはそれで大変ですので、個人的にやっているタイルの用意のやり方を次の節で紹介しておきます。

タイルの作成方法

本番用のスクラッチのステージ画面は480x360のフレームサイズがデフォルトになっています。ということでタイルサイズ選びにはステージの縦横の値が割り切れるような正方形を選ぶほうが都合が良いですので、ここでは24x24で行います。

以下の例はまだ画像は定義してませんが、
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>
        
そしてタイルにしたい24px四方のpng画像をbase64で持ってくるわけですが、ちょうど利用させていただけるような例えばこちらのサイトで公開されている画像を利用させていただきます。

例えば草原のタイルを
grassland.pngでローカルに保存しておきます。

次にこちらの
png > base64に画像変換して貰えるサイトでこのpng画像をbase64変換します。

ということで、得られたbase64画像の文字列を先程の
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>