1"use strict";(self.webpackChunkcodeandweb=self.webpackChunkcodeandweb||[]).push([[35433],{770:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/19f6ef6eed488f9ad4effa3bb887d39e/6080c/texturepacker-pivotpoints%402x.png","srcSet":"/static/19f6ef6eed488f9ad4effa3bb887d39e/a1acf/texturepacker-pivotpoints%402x.png 346w,\\n/static/19f6ef6eed488f9ad4effa3bb887d39e/95fed/texturepacker-pivotpoints%402x.png 691w,\\n/static/19f6ef6eed488f9ad4effa3bb887d39e/6080c/texturepacker-pivotpoints%402x.png 1382w","sizes":"(min-width: 1382px) 1382px, 100vw"},"sources":[{"srcSet":"/static/19f6ef6eed488f9ad4effa3bb887d39e/e1bd0/texturepacker-pivotpoints%402x.webp 346w,\\n/static/19f6ef6eed488f9ad4effa3bb887d39e/9cafa/texturepacker-pivotpoints%402x.webp 691w,\\n/static/19f6ef6eed488f9ad4effa3bb887d39e/6de6e/texturepacker-pivotpoints%402x.webp 1382w","type":"image/webp","sizes":"(min-width: 1382px) 1382px, 100vw"}]},"width":1382,"height":526}')},1216:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/2c89d875a0453604062e2efa04d4fd06/72170/texturepacker-settingsexportfiles%402x.png","srcSet":"/static/2c89d875a0453604062e2efa04d4fd06/347d6/texturepacker-settingsexportfiles%402x.png 190w,\\n/static/2c89d875a0453604062e2efa04d4fd06/c100e/texturepacker-settingsexportfiles%402x.png 380w,\\n/static/2c89d875a0453604062e2efa04d4fd06/72170/texturepacker-settingsexportfiles%402x.png 759w","sizes":"(min-width: 759px) 759px, 100vw"},"sources":[{"srcSet":"/static/2c89d875a0453604062e2efa04d4fd06/811da/texturepacker-settingsexportfiles%402x.webp 190w,\\n/static/2c89d875a0453604062e2efa04d4fd06/a6f60/texturepacker-settingsexportfiles%402x.webp 380w,\\n/static/2c89d875a0453604062e2efa04d4fd06/39e9c/texturepacker-settingsexportfiles%402x.webp 759w","type":"image/webp","sizes":"(min-width: 759px) 759px, 100vw"}]},"width":759,"height":559}')},15142:function(e,t,a){a.d(t,{h:function(){return n}});const n={title:"CodeAndWeb",siteUrl:"https://www.codeandweb.com",image:"/img/logo.png",author:{name:"Andreas Löw"},organization:{name:"CodeAndWeb GmbH",url:"https://www.codeandweb.com",logo:"https://www.codeandweb.com/img/logo.png"},social:{twitter:"@codeandweb"}}},20912:function(e,t,a){a.d(t,{L:function(){return h}});var n=a(96540),r=a(46942),i=a.n(r),o=a(49778),s=a(98957),c=a.n(s),l=a(81851),d=a(86462),p=a(44753),m=a(15142),u=a(33971);const h=e=>{let{json:t,placeholderImage:a}=e;const r=(0,n.useContext)(o.M),s=(0,n.useContext)(p.d),{0:h,1:f}=(0,n.useState)(!1),{0:g,1:w}=(0,n.useState)(0),{0:b,1:x}=(0,n.useState)(!1),v=t.embedUrl,y=v.includes("vimeo")?"vimeo":"youtube",E=(0,n.useRef)(),{0:k,1:S}=(0,n.useState)(!1),T=(C=t.width,P=t.height,10*C==16*P?"aspect-16/10":"aspect-16/9");var C,P;const M=()=>r.playerEnabled[y],{0:N,1:_}=(0,n.useState)(M()),{pathname:j}=(0,d.useLocation)();(0,n.useEffect)((()=>{const e=new URL(window.location.href),t=new URLSearchParams(e.hash.slice(1)),a=new URLSearchParams(e.search);w(H(t.get("t")||a.get("t")||"00:00")),f(!0)}),[]);const H=e=>{const[t,a]=e.split(":").map(Number);return 60*t+a},z=()=>{M()||r.enablePlayer(y)},G=e=>{r.setNowPlaying(e)},D=Object.assign({"@context":"https://schema.org","@type":"VideoObject"},t,{url:m.h.siteUrl+"/"+s.slug});return n.createElement(n.Fragment,null,n.createElement("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:JSON.stringify(D)}}),n.createElement("div",{className:i()("w-full rounded-lg overflow-hidden bg-gray-200 my-8 relative",T)},!b&&n.createElement(u.R,{embedOrStartVideo:()=>{M()?E.current.seekTo(0):z(),G(v)},isEnabled:M(),isReady:N,placeholderImage:a,playerType:y}),M()&&n.createElement("div",{className:i()("w-full rounded-lg bg-gray-200",T)},n.createElement(c(),{url:v,config:{youtube:{playerVars:{rel:0,modestbranding:1}},vimeo:{playerOptions:{autopause:!0,byline:!1,dnt:!0,responsive:!0}}},controls:!0,width:"100%",height:"100%",playing:r.nowPlaying===v,ref:E,onPlay:()=>{G(v),x(!0),S(!0),l.mm.event("played video",{name:t.name,url:j})},onPause:()=>{G(null),l.mm.event("paused video",{name:t.name,url:j,time:E.current.getCurrentTime()})},onEnded:()=>{E.current.seekTo(0),G(null),S(!1),l.mm.event("finished video",{name:t.name,url:j})},onReady:()=>{S(!0),_(!0),E.current.seekTo(g)}}))),t.chapters&&n.createElement(n.Fragment,null,n.createElement("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:JSON.stringify((()=>{const e=Object.entries(t.chapters||[]).map((e=>
1{let[t,a]=e;return{"@type":"HowToStep",url:m.h.siteUrl+s.slug+"#t="+t,text:a}})),a=s.image?{"@type":"ImageObject",url:m.h.siteUrl+s.image.childImageSharp.resize.src,height:""+s.image.childImageSharp.resize.height,width:""+s.image.childImageSharp.resize.width}:void 0;return{"@context":"https://schema.org","@type":"HowTo",name:t.name,totalTime:t.duration,image:a,step:e}})())}}),n.createElement("h3",null,"Chapters"),n.createElement("ul",null,Object.entries(t.chapters).map((e=>{let[t,a]=e;const r=s.slug+"#t="+t;return n.createElement("li",{key:r}," ",t,":Â ",n.createElement("a",{href:r,onClick:e=>((e,t)=>{h&&(z(),S(!0),G(v),E.current.seekTo(H(t)),e.preventDefault())})(e,t)},a))})))))}},40091:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/7a749792089aeb3c34def0eaa8f970d5/ea3ce/texturepackerloader-projectfiles%402x.png","srcSet":"/static/7a749792089aeb3c34def0eaa8f970d5/0f41f/texturepackerloader-projectfiles%402x.png 122w,\\n/static/7a749792089aeb3c34def0eaa8f970d5/bbcf1/texturepackerloader-projectfiles%402x.png 244w,\\n/static/7a749792089aeb3c34def0eaa8f970d5/ea3ce/texturepackerloader-projectfiles%402x.png 488w","sizes":"(min-width: 488px) 488px, 100vw"},"sources":[{"srcSet":"/static/7a749792089aeb3c34def0eaa8f970d5/04f76/texturepackerloader-projectfiles%402x.webp 122w,\\n/static/7a749792089aeb3c34def0eaa8f970d5/30f85/texturepackerloader-projectfiles%402x.webp 244w,\\n/static/7a749792089aeb3c34def0eaa8f970d5/a3cf5/texturepackerloader-projectfiles%402x.webp 488w","type":"image/webp","sizes":"(min-width: 488px) 488px, 100vw"}]},"width":488,"height":242}')},40297:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/83d0dc4268e6b977805f9b7bef9f97b2/83d58/texturepacker-createproject%402x.png","srcSet":"/static/83d0dc4268e6b977805f9b7bef9f97b2/daced/texturepacker-createproject%402x.png 489w,\\n/static/83d0dc4268e6b977805f9b7bef9f97b2/e691e/texturepacker-createproject%402x.png 979w,\\n/static/83d0dc4268e6b977805f9b7bef9f97b2/83d58/texturepacker-createproject%402x.png 1957w","sizes":"(min-width: 1957px) 1957px, 100vw"},"sources":[{"srcSet":"/static/83d0dc4268e6b977805f9b7bef9f97b2/e3d13/texturepacker-createproject%402x.webp 489w,\\n/static/83d0dc4268e6b977805f9b7bef9f97b2/c5aed/texturepacker-createproject%402x.webp 979w,\\n/static/83d0dc4268e6b977805f9b7bef9f97b2/dced2/texturepacker-createproject%402x.webp 1957w","type":"image/webp","sizes":"(min-width: 1957px) 1957px, 100vw"}]},"width":1957,"height":1388}')},45166:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/d47a75772e4b0adc632bd410327ded81/87706/texturepacker-monogame.png","srcSet":"/static/d47a75772e4b0adc632bd410327ded81/f80f8/texturepacker-monogame.png 320w,\\n/static/d47a75772e4b0adc632bd410327ded81/9a63f/texturepacker-monogame.png 640w,\\n/static/d47a75772e4b0adc632bd410327ded81/87706/texturepacker-monogame.png 1280w","sizes":"(min-width: 1280px) 1280px, 100vw"},"sources":[{"srcSet":"/static/d47a75772e4b0adc632bd410327ded81/e2a10/texturepacker-monogame.avif 320w,\\n/static/d47a75772e4b0adc632bd410327ded81/3d183/texturepacker-monogame.avif 640w,\\n/static/d47a75772e4b0adc632bd410327ded81/af2d5/texturepacker-monogame.avif 1280w","type":"image/avif","sizes":"(min-width: 1280px) 1280px, 100vw"},{"srcSet":"/static/d47a75772e4b0adc632bd410327ded81/c0bcc/texturepacker-monogame.webp 320w,\\n/static/d47a75772e4b0adc632bd410327ded81/17574/texturepacker-monogame.webp 640w,\\n/static/d47a75772e4b0adc632bd410327ded81/71d4d/texturepacker-monogame.webp 1280w","type":"image/webp","sizes":"(min-width: 1280px) 1280px, 100vw"}]}
1,"width":1280,"height":720}')},45245:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/b3f27d874a53e5014cec7c25aa6607aa/ce558/texturepacker-scalingvariants%402x.png","srcSet":"/static/b3f27d874a53e5014cec7c25aa6607aa/1c724/texturepacker-scalingvariants%402x.png 230w,\\n/static/b3f27d874a53e5014cec7c25aa6607aa/ff30f/texturepacker-scalingvariants%402x.png 460w,\\n/static/b3f27d874a53e5014cec7c25aa6607aa/ce558/texturepacker-scalingvariants%402x.png 920w","sizes":"(min-width: 920px) 920px, 100vw"},"sources":[{"srcSet":"/static/b3f27d874a53e5014cec7c25aa6607aa/862d6/texturepacker-scalingvariants%402x.webp 230w,\\n/static/b3f27d874a53e5014cec7c25aa6607aa/4e615/texturepacker-scalingvariants%402x.webp 460w,\\n/static/b3f27d874a53e5014cec7c25aa6607aa/19b5a/texturepacker-scalingvariants%402x.webp 920w","type":"image/webp","sizes":"(min-width: 920px) 920px, 100vw"}]},"width":920,"height":592}')},45605:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/46bec96fa42aa3045440e144e38ff24c/22e0e/windows-monogame-visualstudio%402x.png","srcSet":"/static/46bec96fa42aa3045440e144e38ff24c/c0462/windows-monogame-visualstudio%402x.png 559w,\\n/static/46bec96fa42aa3045440e144e38ff24c/9f9f5/windows-monogame-visualstudio%402x.png 1118w,\\n/static/46bec96fa42aa3045440e144e38ff24c/22e0e/windows-monogame-visualstudio%402x.png 2236w","sizes":"(min-width: 2236px) 2236px, 100vw"},"sources":[{"srcSet":"/static/46bec96fa42aa3045440e144e38ff24c/95794/windows-monogame-visualstudio%402x.webp 559w,\\n/static/46bec96fa42aa3045440e144e38ff24c/7af63/windows-monogame-visualstudio%402x.webp 1118w,\\n/static/46bec96fa42aa3045440e144e38ff24c/3d071/windows-monogame-visualstudio%402x.webp 2236w","type":"image/webp","sizes":"(min-width: 2236px) 2236px, 100vw"}]},"width":2236,"height":1362}')},47681:function(e,t,a){a.d(t,{z:function(){return o}});var n=a(96540),r=a(32532),i=a(20912);const o=()=>n.createElement(i.L,{json:{url:"https://www.codeandweb.com/what-is-a-sprite-sheet",thumbnailUrl:"https://i.vimeocdn.com/video/543955943-0c0a419bb1eb6c1e58e4a83614c9f7295d29a89230a3195b3c49317e8c108acc-d?f=webp",embedUrl:"https://player.vimeo.com/video/44440528?h=a21b4729d0",name:"What is a sprite sheet?",description:"This video explains what a sprite sheet is and how it can help you to reduce memory in your game or application you are developing. It shows how individual sprites…",height:720,width:1280,videoQuality:"HD",uploadDate:"2012-06-21T04:37:42-04:00",dateModified:"2023-10-26T05:38:40-04:00",duration:"PT00H03M01S",keywords:["texture packer","game development","sprites","sprite sheets"],thumbnail:{"@type":"ImageObject",url:"https://i.vimeocdn.com/video/543955943-0c0a419bb1eb6c1e58e4a83614c9f7295d29a89230a3195b3c49317e8c108acc-d?f=webp",width:1280,height:720}},placeholderImage:n.createElement(r.S,{src:"./placeholder-images/what-is-a-sprite-sheet.png",alt:"What is a sprite sheet?",formats:["auto","webp","avif"],__imageData:a(92894)})})},58028:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/eeb4b2a1917e1a856cc041a9e536cf97/812e1/texturepacker-project%402x.png","srcSet":"/static/eeb4b2a1917e1a856cc041a9e536cf97/1ac7b/texturepacker-project%402x.png 528w,\\n/static/eeb4b2a1917e1a856cc041a9e536cf97/15829/texturepacker-project%402x.png 1056w,\\n/static/eeb4b2a1917e1a856cc041a9e536cf97/812e1/texturepacker-project%402x.png 2112w","sizes":"(min-width: 2112px) 2112px, 100vw"},"sources":[{"srcSet":"/static/eeb4b2a1917e1a856cc041a9e536cf97/153a9/texturepacker-project%402x.webp 528w,\\n/static/eeb4b2a1917e1a856cc041a9e536cf97/8b21a/texturepacker-project%402x.webp 1056w,\\n/static/eeb4b2a1917e1a856cc041a9e536cf97/3e181/texturepacker-project%402x.webp 2112w","type":"image/webp","sizes":"(min-width: 2112px) 2112px, 100vw"}]},"width":2112,"height":1388}')},60081:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/efb443c40ca62781da0041853d3b9fd8/5bd08/windows-monogame-loader-nuget-search%402x.png","srcSet":"/static/efb443c40ca62781da0041853d3b9fd8/4bf96/windows-monogame-loader-nuget-search%402x.png 476w,\\n/static/efb443c40ca62781da0041853d3b9fd8/658b8/windows-monogame-loader-nuget-search%402x.png 951w,\\n/static/efb443c40ca62781da0041853d3b9fd8/5bd08/windows-monogame-loader-nuget-search%402x.png 1902w","sizes":"(min-width: 1902px) 1902px, 100vw"},"sources":[{"srcSet":"/static/efb443c40ca62781da0041853d3b9fd8/d38f5/windows-monogame-loader-nuget-search%402x.webp 476w,\\n/static/efb443c40ca62781da0041853d3b9fd8/6682c/windows-monogame-loader-nuget-search%402x.webp 951w,\\n/static/efb443c40ca62781da0041853d3b9fd8/64f68/windows-monogame-loader-nuget-search%402x.webp 1902w","type":"image/webp","sizes":"(min-width: 1902px) 1902px, 100vw"}]},"width":1902,"height":954}')},64024:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/4244666ffbc2b761328a4766052e22b7/5976e/texturepacker-scalingvariantspopulated%402x.png","srcSet":"/static/4244666ffbc2b761328a4766052e22b7/54c4b/texturepacker-scalingvariantspopulated%402x.png 230w,\\n/static/4244666ffbc2b761328a4766052e22b7/5cf2f/texturepacker-scalingvariantspopulated%402x.png 460w,\\n/static/4244666ffbc2b761328a4766052e22b7/5976e/texturepacker-scalingvariantspopulated%402x.png 920w","sizes":"(min-width: 920px) 920px, 100vw"},"sources":[{"srcSet":"/static/4244666ffbc2b761328a4766052e22b7/c290c/texturepacker-scalingvariantspopulated%402x.webp 230w,\\n/static/4244666ffbc2b761328a4766052e22b7/16d3e/texturepacker-scalingvariantspopulated%402x.webp 460w,\\n/static/4244666ffbc2b761328a4766052e22b7/8b377/texturepacker-scalingvariantspopulated%402x.webp 920w","type":"image/webp","sizes":"(min-width: 920px) 920px, 100vw"}]},"width":920,"height":875}')},82327:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/4df51182ecc9aab491add01dd58369c6/dbbc3/texturepacker-settingsexportfilespopulated%402x.png","srcSet":"/static/4df51182ecc9aab491add01dd58369c6/700be/texturepacker-settingsexportfilespopulated%402x.png 191w,\\n/static/4df51182ecc9aab491add01dd58369c6/d548c/texturepacker-settingsexportfilespopulated%402x.png 383w,\\n/static/4df51182ecc9aab491add01dd58369c6/dbbc3/texturepacker-settingsexportfilespopulated%402x.png 765w","sizes":"(min-width: 765px) 765px, 100vw"},"sources":[{"srcSet":"/static/4df51182ecc9aab491add01dd58369c6/c620c/texturepacker-settingsexportfilespopulated%402x.webp 191w,\\n/static/4df51182ecc9aab491add01dd58369c6/5b679/texturepacker-settingsexportfilespopulated%402x.webp 383w,\\n/static/4df51182ecc9aab491add01dd58369c6/a3a95/texturepacker-settingsexportfilespopulated%402x.webp 765w","type":"image/webp","sizes":"(min-width: 765px) 765px, 100vw"}]}
1,"width":765,"height":560}')},90918:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/ac9540c3c912f7fe856ccb0a96bbee45/230c5/texturepacker-settingstrimmode%402x.png","srcSet":"/static/ac9540c3c912f7fe856ccb0a96bbee45/71ccd/texturepacker-settingstrimmode%402x.png 191w,\\n/static/ac9540c3c912f7fe856ccb0a96bbee45/dc49c/texturepacker-settingstrimmode%402x.png 382w,\\n/static/ac9540c3c912f7fe856ccb0a96bbee45/230c5/texturepacker-settingstrimmode%402x.png 764w","sizes":"(min-width: 764px) 764px, 100vw"},"sources":[{"srcSet":"/static/ac9540c3c912f7fe856ccb0a96bbee45/f9cd6/texturepacker-settingstrimmode%402x.webp 191w,\\n/static/ac9540c3c912f7fe856ccb0a96bbee45/5dbd5/texturepacker-settingstrimmode%402x.webp 382w,\\n/static/ac9540c3c912f7fe856ccb0a96bbee45/a7da7/texturepacker-settingstrimmode%402x.webp 764w","type":"image/webp","sizes":"(min-width: 764px) 764px, 100vw"}]},"width":764,"height":274}')},91288:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/0dad22eabed1e56ce92bd0a118cf0fff/e3c0a/windows-monogame-createproject%402x.png","srcSet":"/static/0dad22eabed1e56ce92bd0a118cf0fff/0419b/windows-monogame-createproject%402x.png 445w,\\n/static/0dad22eabed1e56ce92bd0a118cf0fff/06f9e/windows-monogame-createproject%402x.png 890w,\\n/static/0dad22eabed1e56ce92bd0a118cf0fff/e3c0a/windows-monogame-createproject%402x.png 1780w","sizes":"(min-width: 1780px) 1780px, 100vw"},"sources":[{"srcSet":"/static/0dad22eabed1e56ce92bd0a118cf0fff/5c202/windows-monogame-createproject%402x.webp 445w,\\n/static/0dad22eabed1e56ce92bd0a118cf0fff/86b22/windows-monogame-createproject%402x.webp 890w,\\n/static/0dad22eabed1e56ce92bd0a118cf0fff/a66ae/windows-monogame-createproject%402x.webp 1780w","type":"image/webp","sizes":"(min-width: 1780px) 1780px, 100vw"}]},"width":1780,"height":1250}')},92894:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/9423b23dc7fb301f31b42f2e8b7da8b7/c4275/what-is-a-sprite-sheet.png","srcSet":"/static/9423b23dc7fb301f31b42f2e8b7da8b7/66d3e/what-is-a-sprite-sheet.png 283w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/3d04a/what-is-a-sprite-sheet.png 565w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/c4275/what-is-a-sprite-sheet.png 1130w","sizes":"(min-width: 1130px) 1130px, 100vw"},"sources":[{"srcSet":"/static/9423b23dc7fb301f31b42f2e8b7da8b7/f1101/what-is-a-sprite-sheet.avif 283w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/cb7e4/what-is-a-sprite-sheet.avif 565w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/c8029/what-is-a-sprite-sheet.avif 1130w","type":"image/avif","sizes":"(min-width: 1130px) 1130px, 100vw"},{"srcSet":"/static/9423b23dc7fb301f31b42f2e8b7da8b7/2c292/what-is-a-sprite-sheet.webp 283w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/097e4/what-is-a-sprite-sheet.webp 565w,\\n/static/9423b23dc7fb301f31b42f2e8b7da8b7/4beac/what-is-a-sprite-sheet.webp 1130w","type":"image/webp","sizes":"(min-width: 1130px) 1130px, 100vw"}]},"width":1130,"height":634}')},94156:function(e,t,a){a.r(t),a.d(t,{Head:function(){return j},default:function(){return _}});var n=a(28453),r=a(96540),i=a(32532),o=a(20912);const s=()=>r.createElement(o.L,{json:{thumbnailUrl:"https://i.vimeocdn.com/video/1708868871-14986040b24faaf1b67f277961897a22dabbaa549570addd4d8db7ab0b2a1124-d?f=webp",embedUrl:"https://player.vimeo.com/video/853368334?h=a000617b9b",name:"MonoGame Sprite Sheet Demo",description:"Preview of the demo scene created in the tutorial https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-and-animations-with-monogame",height:720,width:1280,videoQuality:"HD",uploadDate:"2023-08-10T09:55:45-04:00",dateModified:"2024-04-15T03:45:53-04:00",duration:"PT00H00M16S",keywords:[],thumbnail:{"@type":"ImageObject",url:"https://i.vimeocdn.com/video/1708868871-14986040b24faaf1b67f277961897a22dabbaa549570addd4d8db7ab0b2a1124-d?f=webp",width:1280,height:720}},placeholderImage:r.createElement(i.S,{src:"./placeholder-images/texturepacker-monogame.png",alt:"MonoGame Sprite Sheet Demo",formats:["auto","webp","avif"],__imageData:a(45166)})});
1var c=a(47681),l=a(94296);const d=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"979px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(40297)})},p=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"1056px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(58028)})},m=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"460px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(45245)})},u=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"460px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(64024)})},h=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"382px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(90918)})},f=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"380px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(1216)})},g=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"383px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(82327)})},w=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"890px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(91288)})},b=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"706px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(94930)})},x=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"951px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(60081)})},v=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"1118px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(45605)})},y=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"244px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(40091)})},E=e=>{let{alt:t,className:n}=e;return r.createElement(i.S,{alt:t,className:n,style:{maxWidth:"691px"},imgStyle:{objectFit:"contain"},src:"./[email protected]",__imageData:a(770)})};function k(e){const t=Object.assign({h2:"h2",a:"a",span:"span",ul:"ul",li:"li",p:"p",strong:"strong",h3:"h3",em:"em",pre:"pre",code:"code"},(0,n.R)(),e.components),{GitHub:a,AlertInfo:i}=t;return i||T("AlertInfo",!0),a||T("GitHub",!0),r.createElement(r.Fragment,null,r.createElement(t.h2,{id:"learn-how-to-use-sprite-sheet-animations-in-monogame",style:{position:"relative"}},"Learn how to use sprite sheet animations in MonoGame:",r.createElement(t.a,{href:"#learn-how-to-use-sprite-sheet-animations-in-monogame","aria-label":"learn how to use sprite sheet animations in monogame permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.ul,null,"\n",r.createElement(t.li,null,"Creating sprite sheets with TexturePacker"),"\n",r.createElement(t.li,null,"Using MonoGame Spritesheet loader"),"\n",r.createElement(t.li,null,"Create a cross-platform desktop application with Visual Studio (Windows & Mac)"),"\n",r.createElement(t.li,null,"Create a complete demo scene with animations"),"\n"),"\n",r.createElement(t.p,null,"The complete tutorial code is available on ",r.createElement(a),"."),"\n",r.createElement(t.p,null,"In this article we will go through, step by step, how to produce the animation shown in the video below:"),"\n",r.createElement(s),"\n",r.createElement(i,null,r.createElement(t.p,null,r.createElement(t.strong,null,"Alternative: MonoGame.Extended")),r.createElement(t.p,null,"If you're using ",r.createElement(t.a,{href:"https://github.com/MonoGame-Extended/Monogame-Extended"},"MonoGame.Extended"),", you might want to check out our\n",r.createElement(t.a,{href:"/texturepacker/tutorials/how-to-use-sprite-sheets-with-monogame-extended"},"How to use sprite sheets with MonoGame.Extended")," tutorial instead.\nMonoGame.Extended has built-in supp
1ort for TexturePacker sprite sheets, eliminating the need for the\nseparate TexturePacker Loader library demonstrated in this tutorial.")),"\n",r.createElement(t.h2,{id:"texturepacker",style:{position:"relative"}},"TexturePacker",r.createElement(t.a,{href:"#texturepacker","aria-label":"texturepacker permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"TexturePacker allows you to easily create sprite sheets and texture atlases, greatly simplifying the process of in-game animation.\nHere's how it works: you take your individual animation frames (of characters, objects, etc.) and drag and drop them into TexturePacker.\nThen TexturePacker combines them into sprite sheets, which you can then load into your game.\nUsing sprite sheets rather than individual images is a much more efficient process, making development quicker and easier for you!\nHere's a video to explain how it all works:"),"\n",r.createElement(c.z),"\n",r.createElement(t.p,null,"TexturePacker has always been quite versatile, and compatible with numerous formats.\nHowever, we've now added the ability to save your sprite sheets and data files in a format compatible with MonoGame,\nas well as the source code to properly manage and use these files in your MonoGame app."),"\n",r.createElement(t.p,null,"Start by downloading TexturePacker from here:"),"\n",r.createElement(l.f,{product:"texturepacker"}),"\n",r.createElement(t.p,null,"After opening it, use the ",r.createElement(t.strong,null,"Choose data format"),"\nbutton to select the ",r.createElement(t.strong,null,"MonoGame")," framework and press the ",r.createElement(t.strong,null,"Convert")," button:"),"\n",r.createElement(d,{alt:"TexturePacker: create project"}),"\n",r.createElement(t.p,null,"Before continuing, make sure that all the images you plan to import are in a logical folder structure (folder names based on animation type is recommended).\nOnce your images are properly organized, drag and drop the parent folder into TexturePacker.\nThe images that we're using for this demonstration can be found ",r.createElement(t.a,{href:"https://github.com/CodeAndWeb/monogame-sprite-sheet-example/tree/main/Assets/sprites"},"here on GitHub"),"."),"\n",r.createElement(t.p,null,"TexturePacker will automatically group images together, as seen below:"),"\n",r.createElement(p,{alt:"TexturePacker: CapGuy Demo project"}),"\n",r.createElement(t.p,null,"Now that your images are in TexturePacker, you may need to alter some settings â this depends on your individual requirements and how you intend to use these images.\nWe'll explain all the settings used for this tutorial, but complete documentation can be found ",r.createElement(t.a,{href:"/texturepacker/documentation"},"here"),"."),"\n",r.createElement(t.h3,{id:"scaling-variants",style:{position:"relative"}},"Scaling Variants",r.createElement(t.a,{href:"#scaling-variants","aria-label":"scaling variants permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"If you've done development for iOS before, then you're familiar with having to create two sets of graphics files â\na normal set for standard resolution, and a high-resolution set for Retina displays.\nThe operating system determines which set to use at run-time by the ",r.createElement(t.strong,null,"@2x")," appended to the high-resolution set."),"\n",r.createElement(t.p,null,"When using MonoGame on an iOS device, it works the same way â Retina devices will load the @2x graphics automatically, while non-Retina devices will use the standard versions."),"\n",r.createElement(t.p,null,"However, TexturePacker has a ",r.createElement(t.strong,null,"Scaling Variants")," feature that eliminates the need to create two separate sets of graphics.\nWith this automated process, you can produce both Retina and non-Retina versions of your graphics without having to do all your work twice!"),"\n",r.createElement(t.p,null,"Let's try it out! Start by clicking on the ",r.createElement(t.strong,null,"Scaling Variants")," gear, and the following screen will appear:"),"\n",r.createElement(m,{alt:"TexturePacker: scaling variants empty"}),"\n",r.createElement(t.p,null,"In the ",r.createElement(t.strong,null,"Presets")," box, select ",r.createElement(t.strong,null,"generic @2x")," and then click ",r.createElement(t.strong,null,"Apply"),". The Scaling variants are automatically filled in as seen below:"),"\n",r.createElement(u,{alt:"TexturePacker: scaling variants populated"}),"\n",r.createElement(t.p,null,"By entering this information into these fields, we are telling TexturePacker that we want two versions of the sprite sheet.\n",r.createElement(t.strong,null,"Scale: 1")," refers to the high-definition Retina version, and the ",r.createElement(t.strong,null,"Scale: 0.5")," is the standard-definition non-Retina version.\n",r.createElement(t.strong,null,"Variant name: @2x")," simply indicates that ",r.createElement(t.strong,null,"@2x")," will be appended onto the variant version's filename."),"\n",r.createElement(t.p,null,"Once you've finished entering the information, click ",r.createElement(t.strong,null,"Close"),"."),"\n",r.createElement(t.p,null,"If your app is intended for a specific device that is only available in either Retina or non-Retina\n(but not both) then there is no need for you to use the Scaling Variants feature."),"\n",r.createElement(t.h3,{id:"trim-mode",style:{position:"relative"}}
1,"Trim Mode",r.createElement(t.a,{href:"#trim-mode","aria-label":"trim mode permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"In TexturePacker's ",r.createElement(t.strong,null,"Sprites")," section, look for ",r.createElement(t.strong,null,"Trim mode"),"."),"\n",r.createElement(h,{alt:"TexturePacker: settings trim mode"}),"\n",r.createElement(t.p,null,"This should be set to ",r.createElement(t.strong,null,"Trim")," by default. This option crops all empty space surrounding your sprites, reducing the sprite sheet's size.\nIf you'd prefer not to use this option, ",r.createElement(t.strong,null,"Trim mode")," can be set to ",r.createElement(t.strong,null,"None"),"."),"\n",r.createElement(t.h3,{id:"pivot-points",style:{position:"relative"}},"Pivot Points",r.createElement(t.a,{href:"#pivot-points","aria-label":"pivot points permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"To edit the pivot points of your sprites click ",r.createElement(t.strong,null,"Sprite Settings")," in the toolbar. Pivot points have two functions:"),"\n",r.createElement(t.ul,null,"\n",r.createElement(t.li,null,"\n",r.createElement(t.p,null,'Pivot points are used to determine which point of the frame will be positioned at a particular location when that frame is rendered.\nFor example, if you choose "100, 100" as your frame location, and set your pivot point to "center" then the center of the sprite\nwill be located at "100, 100". In contrast, if you set your pivot point to "bottom right", then the lower right corner\nof your sprite will be located at "100, 100".'),"\n"),"\n",r.createElement(t.li,null,"\n",r.createElement(t.p,null,"Pivot points also define the sprite's point of rotation."),"\n"),"\n"),"\n",r.createElement(t.p,null,'For our demo app we set the pivot point of the background sprite to "top left" and the pivot point of the ',r.createElement(t.em,null,"capguy"),'\ncharacter to "bottom center"
1:'),"\n",r.createElement(E,{alt:"TexturePacker: set pivot points"}),"\n",r.createElement(t.h3,{id:"export-files",style:{position:"relative"}},"Export Files",r.createElement(t.a,{href:"#export-files","aria-label":"export files permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"Now let's examine the files that are created when TexturePacker converts our images into sprite sheets."),"\n",r.createElement(f,{alt:"TexturePacker: settings export files"}),"\n",r.createElement(t.p,null,"You will initially see a ",r.createElement(t.strong,null,"Settings")," screen with mostly empty fields."),"\n",r.createElement(g,{alt:"TexturePacker: settings export files populated"}),"\n",r.createElement(t.p,null,"The ",r.createElement(t.strong,null,"{v}")," seen in both the ",r.createElement(t.strong,null,"Data file")," and ",r.createElement(t.strong,null,"Texture file")," fields above represents variant file names for the scaled variants.\nWhen the sprite sheet is exported, the ",r.createElement(t.strong,null,"{v}")," will be replaced with the variant name â\nin this case it will be replaced by ",r.createElement(t.strong,null,"@2x")," for the Retina display version, and will simply be removed for the non-Retina display version."),"\n",r.createElement(t.p,null,"The ",r.createElement(t.strong,null,"Data file")," is a text file which contains information about each sprite in the sheet. This includes:"),"\n",r.createElement(t.ul,null,"\n",r.createElement(t.li,null,"Location"),"\n",r.createElement(t.li,null,"Trim"),"\n",r.createElement(t.li,null,"Rotation"),"\n",r.createElement(t.li,null,"Pivot Point"),"\n"),"\n",r.createElement(t.p,null,"The ",r.createElement(t.strong,null,"Class file")," contains a C# class consisting of constants that are used to refer to each frame in the series.\nA little later we'll go into more detail on this, but basically, in MonoGame each frame must be referenced by a string name.\nThese must be exact, as any typo would cause a runtime error. However, with the use of const strings,\nerrors become evident as compile time errors, allowing us to discover and correct these errors much earlier in the process."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},'/*\n * Class auto generated by TexturePacker\n *\n * Contains references to each image within the sprite sheet.\n *\n * https://www.codeandweb.com/texturepacker\n * $TexturePacker:SmartUpdate:2044216056b85e7707659a24b50ece03...\n *\n */\nnamespace TexturePackerMonoGameDefinitions\n{\n public class CapGuyDemo\n {\n public const string Background = "Background";\n public const string Capguy_turn_0001 = "capguy/turn/0001";\n public const string Capguy_turn_0002 = "capguy/turn/0002";\n public const string Capguy_turn_0003 = "capguy/turn/0003";\n public const string Capguy_turn_0004 = "capguy/turn/0004";\n public const string Capguy_turn_0005 = "capguy/turn/0005";\n public const string Capguy_turn_0006 = "capguy/turn/0006";\n')),"\n",r.createElement(t.p,null,"The Texture file is the file that actually contains the sprite sheet. Notice that this field also has a ",r.createElement(t.strong,null,"{v}")," in it.\nTherefore, because the name of the file listed here is ",r.createElement(t.strong,null,"CapGuyDemo{v}.png"),", when exported,\nthis will produce two variants: a non-Retina version called ",r.createElement(t.strong,null,"CapGuyDemo.png")," and a Retina version called ",r.createElement(t.strong,null,r.createElement(t.a,{href:"mailto:[email protected]"},"[email protected]")),"."),"\n",r.createElement(t.p,null,"At this point you may want to consider the location of these files. The Data file and Texture file both need to be in the ",r.createElement(t.strong,null,"Content")," folder\nin order for the app to run properly, so to save yourself the trouble of saving them in some other location and then copying them to ",r.createElement(t.strong,null,"Content"),",\nyou could just save them there now.\nAdditionally, the Class file will need to be saved within the app's source tree.\nYou might save it in the ",r.createElement(t.strong,null,"Content")," folder, too, or in another folder together with your source files."),"\n",r.createElement(t.p,null,"As mentioned, there are other options in addition to the ones explained here, but because these are the only ones you need for this tutorial,\nwe'll move on now. However, feel free to explore other options on your own ",r.createElement(t.a,{href:"/texturepacker/documentation"},"here"),"."),"\n",r.createElement(t.h2,{id:"texturepacker-loader",style:{position:"relative"}}
1,"TexturePacker Loader",r.createElement(t.a,{href:"#texturepacker-loader","aria-label":"texturepacker loader permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"Before starting work on our demo app, let's take a minute to look at the TexturePacker Loader. This can currently be downloaded freely,\nyou can either add it as ",r.createElement(t.a,{href:"https://www.nuget.org/packages/TexturePacker-MonoGameLoader"},"NuGet")," package to your VisualStudio project,\nor you can download its source code from ",r.createElement(t.a,{href:"https://github.com/CodeAndWeb/TexturePacker-MonoGameLoader"},"GitHub"),"."),"\n",r.createElement(t.p,null,"The TexturePacker Loader source code is composed of just four files. Therefore, it's easy for beginners to understand, and it's easy for pros to make modifications."),"\n",r.createElement(y,{alt:"texturepacker loader project files"}),"\n",r.createElement(t.p,null,"Instead of covering every detail of the TexturePacker Loader, we'll focus on what's relevant for this demo."),"\n",r.createElement(t.h3,{id:"sprite-sheet-loader",style:{position:"relative"}},"Sprite Sheet Loader",r.createElement(t.a,{href:"#sprite-sheet-loader","aria-label":"sprite sheet loader permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"Since we'll be creating a new MonoGame app, we want to start by loading our sprite sheets (and any other assets).\nThis is usually done in the LoadContent method of our main Game class."),"\n",r.createElement(t.p,null,"To do this, we'll need to instantiate a new instance of the SpriteSheetLoader class and call the Load method passing in the name of your sprite sheet (as produced by TexturePacker).\nBelow is an example:"),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},'var spriteSheetLoader = new SpriteSheetLoader(Content);\nspriteSheet = spriteSheetLoader.Load("CapGuyDemo");\n')),"\n",r.createElement(t.p,null,"This will create a reference to a sprite sheet. We'd suggest this is a class level variable as it will be required in your draw method as described below."),"\n",r.createElement(t.h3,{id:"spritebatch-extension",style:{position:"relative"}},"SpriteBatch extension",r.createElement(t.a,{href:"#spritebatch-extension","aria-label":"spritebatch extension permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"MonoGame's ",r.createElement(t.code,null,"SpriteBatch")," class provides methods to draw textures and text strings. Our TexturePacker Loader package\ncontains an extension for that class which adds a method to draw sprites loaded from a sprite sheet.\nThe SpriteRender class is obsolete and exists only for backward compatibility."),"\n",r.createElement(t.p,null,"We would recommend instantiating one instance of the ",r.createElement(t.code,null,"SpriteBatch")," class in your LoadContent method, as seen below:"),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"this.spriteBatch = new SpriteBatch(GraphicsDevice);\n")),"\n",r.createElement(t.p,null,"And then in your draw method you simply render frames on screen, something like this:"),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"this.spriteBatch.Begin();\n\nthis.spriteBatch.Draw(\n this.spriteSheet.Sprite(\n TexturePackerMonoGameDefinitions.CapGuyDemo.Capguy_turn_0002\n ),\n new Vector2(350, 530)\n);\n\nthis.spriteBatch.End();\n")),"\n",r.createElement(t.p,null,"As you can see in the example above, we are drawing ",r.createElement(t.strong,null,"Capguy_turn_0002")," at location 350, 530."),"\n",r.createElement(t.p,null,"When we originally exported the TexturePacker files, one of the files we exported was the Class file, which defined each individual sprite's constant values.\
1nHere's where that comes into play. Using this method rather than the string value ensures that, should an image file be missing from the sprite sheet, a compile-time error will occur.\nThis is preferable to a runtime error, which may not occur until deployment, and therefore, may be more complicated to fix."),"\n",r.createElement(t.p,null,"This covers what we need to get started with rendering. TexturePacker Loader's code ensures that sprites appear correctly, even if they've been rotated or\ntrimmed on the sprite sheet itself. All we need to do is let it know which frame to render and where we want it!"),"\n",r.createElement(t.p,null,"Now that we have a better understanding of TexturePacker and TexturePacker Loader, we can start integrating it with MonoGame!"),"\n",r.createElement(t.h2,{id:"monogame",style:{position:"relative"}},"MonoGame",r.createElement(t.a,{href:"#monogame","aria-label":"monogame permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"The main goal of MonoGame is to enable simpler cross-platform game development. Instead of using different standards for each platform, MonoGame allows C# development\nfor one platform, and then requires only minor adjustments to make it compatible with other platforms."),"\n",r.createElement(t.p,null,"MonoGame is incredibly versatile, and can currently be used for such powerhouse platforms as\nWindows, macOS, Linux, iOS/iPadOS, Android, PlayStation 4+5, Xbox and Nintendo Switch."),"\n",r.createElement(t.p,null,'In the demo app we are going to create here, we will animate "CapGuy" walking across the screen.\nIn our example we use Visual Studio 2022 on Windows 11, if you are working with a Mac the steps with Visual Studio for macOS are almost the same.'),"\n",r.createElement(t.h3,{id:"cross-platform-desktop-app-with-visual-studio",style:{position:"relative"}},"Cross Platform Desktop App with Visual Studio",r.createElement(t.a,{href:"#cross-platform-desktop-app-with-visual-studio","aria-label":"cross platform desktop app with visual studio permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"First you have to install Visual Studio 2022 if you're not already using it. You can download it on ",r.createElement(t.a,{href:"https://visualstudio.microsoft.com"},"visualstudio.microsoft.com"),".\nFor our example the Community Edition is sufficient."),"\n",r.createElement(t.p,null,"Additionally, please install the MonoGame project templates."),"\n",r.createElement(t.ul,null,"\n",r.createElement(t.li,null,"You can either use the menu item ",r.createElement(t.strong,null,"Extensions")," â ",r.createElement(t.strong,null,"Manage Extensions"),', search for "monogame" and install the\n"MonoGame Framework C# project templates"'),"\n",r.createElement(t.li,null,"Or you can install the templates from command line with","\n",r.createElement(t.pre,null,r.createElement(t.code,null," dotnet new install MonoGame.Templates.CSharp\n")),"\n"),"\n"),"\n",r.createElement(t.p,null,"This will add an option for MonoGame in Visual Studio's template list for new projects.\nJust select ",r.createElement(t.em,null,'"MonoGame Cross-Platform Desktop Application"')," to quickly and easily get started on your project!"),"\n",r.createElement(w,{alt:"windows monogame create project"}),"\n",r.createElement(t.p,null,"After finishing the ",r.createElement(t.em,null,"New Project wizard"),', we can build and run the solution, resulting in a "cornflower blue" screen.\nIf that\'s what you get, then everything is working correctly!'),"\n",r.createElement(t.p,null,"At this point, please go back to TexturePacker and click ",r.createElement(t.strong,null,"Publish"),". This will export your sprite sheets, class files, and data files.\nIf you have configured data and texture file paths as recommended, these files will appear in the Content folder of your new MonoGame project:"),"\n",r.createElement(b,{alt:"windows monogame set properties of content files"}),"\n",r.createElement(t.p,null,"Select these files and set their ",r.createElement(t.strong,null,"Build Action"),' property to "Content" and their ',r.createElement(t.strong,null,"Copy to Output Directory"),' property\nto "Copy if newer". Doing this guarantees that we\'ll be able to access this data at run-time.'),"\n",r.createElement(t.p,null,"The SpriteNames.cs file is not required to be in any specific location â it can go anywhere you choose."),"\n",r.createElement(t.p,null,"In order to work with the data files from TexturePacker, we now need to use the TexturePacker Loader.\nWe can get this from NuGet, so select ",r.createElement(t.strong,null,"Manage NuGet Packages")," in the ",r.createElement(t.strong,null,"Project"),' menu and enter the search term "texturepacker-monogameloader".'),"\n",r.createElement(t.p,null,"Then simply install the TexturePacker-MonoGameLoader package:"),"\n",r.createElement(x,{alt:"windows monogame loader nuget search"}),"\n",r.createElement(t.p,null,"At this point we've got everything we need from TexturePacker â all of our files (texture, data, and class) as well as the TexturePacker Loader,\nso let's start using it! Now let's download GitHub's demo package."),"\n",r.createElement(t.p,null,"Once you've loaded up the solution, this is what you should see:"),"\n",r.createElement(v,{alt:"windows monogame visual studio"}),"\n",r.createElement(t.p,null,"All you need to do is hit the ",r.createElement(t.strong,null,"F5")," key to make CapGuy walk back and forth across the screen.\nIt may not seem like much, but considering the minimal amount of code used here, it's really pretty impressive!"),"\n",r.createElement(t.h3,{id:"demogame",style:{position:"relative"}}
1,"DemoGame",r.createElement(t.a,{href:"#demogame","aria-label":"demogame permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"Congrats on your demo! We hope you've been enjoying this exercise!"),"\n",r.createElement(t.p,null,"This section of the tutorial doesn't focus on TexturePacker or MonoGame, but on the demo app itself.\nHere we cover some other classes that you may want to use for other projects."),"\n",r.createElement(t.p,null,"Most of the code in the demo should be pretty easy to understand, but what about the ",r.createElement(t.code,null,"InitialiseAnimationManager()")," method?\nThis is what defines CapGuy's animation. It controls where on the screen he starts as well as his speed."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"var characterStartPosition = new Vector2(backgroundSprite.Size.X / 4,\n backgroundSprite.Size.Y * 0.8f);\nvar characterVelocityPixelsPerSecond = backgroundSprite.Size.X / 9;\n")),"\n",r.createElement(t.p,null,"Here two local variables are created that consist of arrays of frame names.\nThese arrays define the frames that compose movement sequences, like walking or turning."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"var turnSprites = new [] {\n TexturePackerMonoGameDefinitions.CapGuyDemo.Capguy_turn_0001,\n TexturePackerMonoGameDefinitions.CapGuyDemo.Capguy_turn_0002,\n TexturePackerMonoGameDefinitions.CapGuyDemo.Capguy_turn_0003,\n TexturePackerMonoGameDefinitions.CapGuyDemo.Capguy_turn_0004,\n ...\n")),"\n",r.createElement(t.p,null,"In addition to the sequence of frames, there are also a number of other variables that we can control here. We can specify the sprite's velocity, amount of time before switching frames,\nand flipping the frames (which direction the sprite is facing). This is everything we need to define our animation. Here's what the code looks like:"),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"var animationWalkRight = new Animation(\n new Vector2(characterVelocityPixelsPerSecond, 0),\n timePerFrame, SpriteEffects.None, walkSprites\n);\nvar animationWalkLeft = new Animation(\n new Vector2(-characterVelocityPixelsPerSecond, 0),\n timePerFrame, SpriteEffects.FlipHorizontally, walkSprites\n);\nvar animationTurnRightToLeft = new Animation(\n Vector2.Zero,\n timePerFrame, SpriteEffects.None, turnSprites\n);\nvar animationTurnLeftToRight = new Animation(\n Vector2.Zero,\n timePerFrame, SpriteEffects.FlipHorizontally, turnSprites\n);\n")),"\n",r.createElement(t.p,null,"So we now defined four types of animation â walking left, walking right, turning left, and turning right.\nBy putting this together in sequence, we can create a continuous loop of CapGuy walking back and forth across the screen."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"var animations = new[]\n{\n animationWalkRight, animationWalkRight, animationWalkRight,\n animationWalkRight, animationWalkRight, animationWalkRight,\n animationTurnRightToLeft,\n animationWalkLeft, animationWalkLeft, animationWalkLeft,\n animationWalkLeft, animationWalkLeft, animationWalkLeft,\n animationTurnLeftToRight\n};\n")),"\n",r.createElement(t.p,null,'In this example, the "walk right" animation will repeat six times before he turns and the "walk left" animation will repeat six times, and so on.'),"\n",r.createElement(t.p,null,"We now need to create an instance of the ",r.createElement(t.code,null,"AnimationManager")," class passing in all of this information."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"this.characterAnimationManager = new AnimationManager (\n this.spriteSheet, characterStartPosition, animations\n);\n")),"\n",r.createElement(t.p,null,"After that's done, we can just call the AnimationManager's ",r.createElement(t.code,null,"update")," method each game loop."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"}
1,"protected override void Update(GameTime gameTime)\n{\n this.characterAnimationManager.Update(gameTime);\n base.Update(gameTime);\n}\n")),"\n",r.createElement(t.p,null,"Then we just need to use AnimationManager to make sure that our images are correct â\nproper sprite and effects in the proper position and Draw method."),"\n",r.createElement(t.pre,null,r.createElement(t.code,{className:"language-csharp"},"protected override void Draw(GameTime gameTime)\n{\n GraphicsDevice.Clear(Color.Black);\n\n spriteBatch.Begin(blendState: BlendState.NonPremultiplied,\n transformMatrix: globalTransformation);\n\n // Draw the background\n spriteBatch.Draw(backgroundSprite, Vector2.Zero);\n\n // Draw character on screen\n spriteBatch.Draw(\n characterAnimationManager.CurrentSprite,\n characterAnimationManager.CurrentPosition,\n Color.White, 0, 1,\n characterAnimationManager.CurrentSpriteEffects);\n\n spriteBatch.End();\n\n base.Draw(gameTime);\n}\n")),"\n",r.createElement(t.p,null,"There are other ways to handle the animation, and there may be other methods that you prefer,\nbut you're welcome to use this code, if you'd like!"),"\n",r.createElement(t.h2,{id:"the-end",style:{position:"relative"}},"The End",r.createElement(t.a,{href:"#the-end","aria-label":"the end permalink",className:"anchor after"},r.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}}))),"\n",r.createElement(t.p,null,"We hope you enjoyed this tutorial and were able to learn something new, or just get a little more practice!\nIf you'd like to see the finished product without having to build it yourself, here's a video of the completed demo:"),"\n",r.createElement(s))}var S=function(e){void 0===e&&(e={});const{wrapper:t}=Object.assign({},(0,n.R)(),e.components);return t?r.createElement(t,e,r.createElement(k,e)):k(e)};function T(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}var C=a(11042),P=a(77891),M=a(74110);function N(e){let{data:t,pageContext:a,children:n}=e;const i=a.pageData,o=t.mdx,s=o.tableOfContents,c=o.frontmatter.noTitleImage?null:o.frontmatter.image;return r.createElement(P.W,null,r.createElement(M.n,{pageData:i,image:c,onPageItems:s.items},n))}function _(e){return r.createElement(N,e,r.createElement(S,e))}const j=e=>{let{pageContext:t}=e;return r.createElement(r.Fragment,null,r.createElement(C.A,{pageData:t.pageData}))}},94930:function(e){e.exports=JSON.parse('{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/cdedc6d116100084e8a25c7317c780ae/e86e8/windows-monogame-set-content-properties%402x.png","srcSet":"/static/cdedc6d116100084e8a25c7317c780ae/9b651/windows-monogame-set-content-properties%402x.png 353w,\\n/static/cdedc6d116100084e8a25c7317c780ae/8e357/windows-monogame-set-content-properties%402x.png 706w,\\n/static/cdedc6d116100084e8a25c7317c780ae/e86e8/windows-monogame-set-content-properties%402x.png 1411w","sizes":"(min-width: 1411px) 1411px, 100vw"},"sources":[{"srcSet":"/static/cdedc6d116100084e8a25c7317c780ae/66726/windows-monogame-set-content-properties%402x.webp 353w,\\n/static/cdedc6d116100084e8a25c7317c780ae/ea5a9/windows-monogame-set-content-properties%402x.webp 706w,\\n/static/cdedc6d116100084e8a25c7317c780ae/0b846/windows-monogame-set-content-properties%402x.webp 1411w","type":"image/webp","sizes":"(min-width: 1411px) 1411px, 100vw"}]},"width":1411,"height":962}')}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.