CINXE.COM
Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer - Google Developers Blog
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title> Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer - Google Developers Blog </title> <meta property="og:title" content="Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer- Google Developers Blog" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="description" content="Purrfect Code is a sokoban style box pushing puzzler Purrfect based on Google tech (Flutter, IDX, FLAME, Firebase) and designed to be playable on web browsers. Open the game in Project IDX, earn badges for each level, and showcase your badges on your Developer Profile." /> <meta content="summary_large_image" name="twitter:card"/> <meta content="Google for Developers Blog - News about Web, Mobile, AI and Cloud" property="twitter:title"/> <meta property="og:title" content="Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer" /> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Google for Developers Blog", "item": "https://developers.googleblog.com/" },{ "@type": "ListItem", "position": 2, "name": "Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer", "item": "http://developers.googleblog.com/id/how-we-built-purrfect-code/" }] } </script> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "headline": "Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer", "description": "Purrfect Code adalah teka-teki mendorong kotak bergaya sokoban, Purrfect berbasis teknologi Google (Flutter, IDX, FLAME, Firebase) dan didesain untuk dapat dimainkan di browser web. Buka game di Project IDX, dapatkan badge untuk setiap level, dan tunjukkan badge Anda di Profil Developer.", "image": "https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/image2_R0cO2EO.2e16d0ba.fill-800x400.png", "datePublished": "2024-08-01", "author": [ { "@type": "Person", "name": "Google for Developers", "url": "/id/search/?author=Google+for+Developers" } ] } </script> <meta content="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/image2_R0cO2EO.2e16d0ba.fill-1200x600.png" property="og:image"/> <!-- Google Tag Manager --> <script type="text/javascript" src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/js/analytics.js"></script> <!-- End Google Tag Manager --> <link href="//www.gstatic.com/glue/v27_1/glue.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/css/dgc_blog.css"> <link rel="icon" href="https://storage.googleapis.com/gweb-developer-goog-blog-assets/meta/favicon.ico" type="image/x-icon"> <link rel="apple-touch-icon" href="https://storage.googleapis.com/gweb-developer-goog-blog-assets/meta/apple-touch-icon.png"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preload" href="https://fonts.googleapis.com/css2?family=Product+Sans&family=Google+Sans+Display:ital@0;1&family=Google+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Google+Sans+Text:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap" as="style"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Product+Sans&family=Google+Sans+Display:ital@0;1&family=Google+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Google+Sans+Text:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap"> <link href="https://www.gstatic.com/glue/cookienotificationbar/cookienotificationbar.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/css/blog_detail.css" /> <link rel="stylesheet" href="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/pygmentify/css/default.min.css"> </head> <body id="main-content" class="glue-body "> <!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WVTLDSL " height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) --> <!-- HTML --> <header class="dgc-header"> <div class="dgc-header-inner"> <button class="hamburger" aria-haspopup="true" aria-expanded="false" aria-label="Buka Menu"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#menu"></use> </svg> </button> <div class="product-name-wrapper"> <a href="https://developers.google.com/" class="site-logo-link" data-label="Site logo"> <img src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/images/g-dev.svg" class="site-logo" alt="Google for Developers"> </a> </div> <div class="desktop-nav-wrapper"> <div class="upper-tabs-wrapper"> <div class="upper-tabs"> <nav class="tabs" aria-label="Tab Atas"> <div class="tab" dropdown> <a href="//developers.google.com/products" class="top-nav-title"> Produk </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="true" aria-label="Menu dropdown untuk Produk" class="dropdown-toggle"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#arrow-drop-down"></use> </svg> </a> <div class="tabs-dropdown" aria-label="Submenu"> <div class="tabs-dropdown-content"> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Develop">Develop</li> <li class="nav-item"> <a href="//developer.android.com"> <div class="nav-item-title"> Android </div> </a> </li> <li class="nav-item"> <a href="//developer.chrome.com"> <div class="nav-item-title"> Chrome </div> </a> </li> <li class="nav-item"> <a href="//chromeos.dev/"> <div class="nav-item-title"> ChromeOS </div> </a> </li> <li class="nav-item"> <a href="//cloud.google.com"> <div class="nav-item-title"> Cloud </div> </a> </li> <li class="nav-item"> <a href="//firebase.google.com"> <div class="nav-item-title"> Firebase </div> </a> </li> <li class="nav-item"> <a href="//flutter.dev"> <div class="nav-item-title"> Flutter </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/assistant"> <div class="nav-item-title"> Google Assistant </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/maps"> <div class="nav-item-title"> Google Maps Platform </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/workspace"> <div class="nav-item-title"> Google Workspace </div> </a> </li> <li class="nav-item"> <a href="//www.tensorflow.org"> <div class="nav-item-title"> TensorFlow </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/youtube"> <div class="nav-item-title"> YouTube </div> </a> </li> </ul> </div> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Tumbuh">Tumbuh</li> <li class="nav-item"> <a href="//firebase.google.com"> <div class="nav-item-title"> Firebase </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/google-ads"> <div class="nav-item-title"> Google Ads </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/analytics"> <div class="nav-item-title"> Google Analytics </div> </a> </li> <li class="nav-item"> <a href="//developer.android.com/distribute"> <div class="nav-item-title"> Google Play </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/search"> <div class="nav-item-title"> Search </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/web/fundamentals/engage-and-retain/push-notifications"> <div class="nav-item-title"> Web Push and Notification APIs </div> </a> </li> </ul> </div> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Hasilkan Uang">Hasilkan uang</li> <li class="nav-item"> <a href="//developers.google.com/admob"> <div class="nav-item-title"> AdMob </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/google-ads/api"> <div class="nav-item-title"> Google Ads API </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/pay"> <div class="nav-item-title"> Google Pay </div> </a> </li> <li class="nav-item"> <a href="//developer.android.com/google/play/billing/"> <div class="nav-item-title"> Google Play Billing </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/interactive-media-ads"> <div class="nav-item-title"> Interactive Media Ads </div> </a> </li> </ul> </div> </div> </div> </div> <div class="tab"> <a href="//developers.google.com/solutions/catalog" class="top-nav-title"> Solusi </a> </div> <div class="tab"> <a href="//developers.google.com/events" class="top-nav-title"> Acara </a> </div> <div class="tab"> <a href="//developers.google.com/learn" class="top-nav-title"> Pelajari </a> </div> <div class="tab" dropdown> <a href="//developers.google.com/community" class="top-nav-title"> Komunitas </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="true" aria-label="Menu dropdown untuk Komunitas" class="dropdown-toggle"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#arrow-drop-down"></use> </svg> </a> <div class="tabs-dropdown" aria-label="Submenu"> <div class="tabs-dropdown-content"> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Grup">Grup</li> <li class="nav-item"> <a href="//developers.google.com/community/gdg"> <div class="nav-item-title"> Google Developer Groups </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/gdsc"> <div class="nav-item-title"> Google Developer Student Clubs </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/womentechmakers"> <div class="nav-item-title"> Woman Techmakers </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/experts"> <div class="nav-item-title"> Google Developer Experts </div> </a> </li> <li class="nav-item"> <a href="//www.techequitycollective.com/"> <div class="nav-item-title"> Tech Equity Collective </div> </a> </li> </ul> </div> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Program">Program</li> <li class="nav-item"> <a href="//developers.google.com/community/accelerators"> <div class="nav-item-title"> Accelerator </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/gdsc-solution-challenge"> <div class="nav-item-title"> Solution Challenge </div> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/devfest"> <div class="nav-item-title"> DevFest </div> </a> </li> </ul> </div> <div class="tabs-dropdown-column"> <ul class="tabs-dropdown-section"> <li class="nav-title" aria-label="Menu Cerita">Cerita</li> <li class="nav-item"> <a href="//developers.google.com/community/stories"> <div class="nav-item-title"> Semua Cerita </div> </a> </li> </ul> </div> </div> </div> </div> <div class="tab"> <a href="//developers.google.com/profile/u/me" class="top-nav-title"> Program Developer </a> </div> <div class="tab"> <a href="//developers.googleblog.com/" class="top-nav-title"> Blog </a> </div> </nav> </div> </div> </div> </div> <div class="dgc-header-search"> <div class="search-wrapper glue-page"> <div class="glue-grid"> <form id="search-form" action="/id/search/" method="get" class="search-content glue-grid__col glue-grid__col--span-4-sm glue-grid__col--span-9-md glue-grid__col--span-7-lg"> <div class="search-input-wrapper"> <svg role="presentation" aria-hidden="true" class="glue-icon search-icon"> <use href="/glue-icon/#search"></use> </svg> <input type="text" name="query" placeholder="Telusuri semua artikel..." aria-label="Penelusuran" class="search-input-field" /> </div> <button class="glue-button glue-button--high-emphasis"> Penelusuran </button> </form> <div class="language-selector glue-grid__col glue-grid__col--span-4-sm glue-grid__col--span-3-md glue-grid__col--span-5-lg" aria-label="Pilih preferensi bahasa Anda"> <button type="button" aria-controls="lang-menu-header" aria-haspopup="true"> <svg role="presentation" aria-hidden="true" class="glue-icon lang-icon"> <use href="/glue-icon/#language"></use> </svg> <span class="lang-label">Bahasa Indonesia</span> <svg role="presentation" aria-hidden="true" class="glue-icon lang-icon"> <use href="/glue-icon/#arrow-drop-down"></use> </svg> </button> <div id="lang-menu-header" class="lang-menu hidden" role="menu"> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" href="/en/how-we-built-purrfect-code"> English </a> </li> <li role="presentation"> <a role="menuitem" lang="es" href="/es/how-we-built-purrfect-code"> Español (Latam) </a> </li> <li role="presentation"> <a role="menuitem" lang="id" href="/id/how-we-built-purrfect-code"> Bahasa Indonesia </a> </li> <li role="presentation"> <a role="menuitem" lang="ja" href="/ja/how-we-built-purrfect-code"> 日本語 </a> </li> <li role="presentation"> <a role="menuitem" lang="ko" href="/ko/how-we-built-purrfect-code"> 한국어 </a> </li> <li role="presentation"> <a role="menuitem" lang="pt-br" href="/pt-br/how-we-built-purrfect-code"> Português (Brasil) </a> </li> <li role="presentation"> <a role="menuitem" lang="zh-hans" href="/zh-hans/how-we-built-purrfect-code"> 简体中文 </a> </li> </ul> </div> </div> </div> </div> </div> </header> <div class="mobile-drawer" top-level-nav> <nav class="nav-content" aria-label="Menu samping"> <div class="mobile-header"> <button class="nav-close-btn nav-btn" aria-label="Tutup navigasi"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#close"></use> </svg> </button> <button class="nav-back-btn nav-btn hidden" aria-label="Kembali ke Menu"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#arrow-back"></use> </svg> </button> <div class="product-name-wrapper"> <a href="https://developers.google.com/" class="site-logo-link" data-label="Site logo"> <img src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/images/g-dev.svg" class="site-logo" alt="Google for Developers"> </a> </div> </div> <div class="nav-wrapper"> <div class="mobile-nav-top"> <ul class="nav-list"> <li class="nav-item"> <a href="//developers.google.com/products" class="nav-title" data-label="Tab: Products"> <span class="nav-text" tooltip=""> Produk </span> </a> <ul class="nav-responsive-tabs"> <li class="nav-item"> <span tabindex="0" class="nav-title products-btn" data-label="More Products"> <span class="nav-text" menu="Products"> Lebih banyak </span> <span class="nav-icon" menu="Products"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#arrow-forward"></use> </svg> </span> </span> </li> </ul> </li> <li class="nav-item"> <a href="//developers.google.com/solutions/catalog" class="nav-title" data-label="Tab: Solutions"> <span class="nav-text" tooltip=""> Solusi </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/events" class="nav-title" data-label="Tab: Events"> <span class="nav-text" tooltip=""> Acara </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/learn" class="nav-title" data-label="Tab: Learn"> <span class="nav-text" tooltip=""> Pelajari </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community" class="nav-title" data-label="Tab: Community"> <span class="nav-text" tooltip=""> Komunitas </span> </a> <ul class="nav-responsive-tabs"> <li class="nav-item"> <span tabindex="0" class="nav-title community-btn" data-label="More Community"> <span class="nav-text" menu="Community"> Lebih banyak </span> <span class="nav-icon" menu="Community"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#arrow-forward"></use> </svg> </span> </span> </li> </ul> </li> <li class="nav-item"> <a href="//developers.google.com/profile/u/me" class="nav-title" data-label="Tab: Developer Program"> <span class="nav-text" tooltip=""> Program Developer </span> </a> </li> <li class="nav-item"> <a href="//developers.googleblog.com/" class="nav-title" data-label="Tab: Blog"> <span class="nav-text" tooltip=""> Blog </span> </a> </li> </ul> </div> <div class="mobile-nav-bottom"> <ul class="nav-list products-submenu" menu="Products" aria-label="Menu samping"> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Develop </span> </span> </li> <li class="nav-item"> <a href="//developer.android.com" class="nav-title"> <span class="nav-text"> Android </span> </a> </li> <li class="nav-item"> <a href="//developer.chrome.com" class="nav-title"> <span class="nav-text"> Chrome </span> </a> </li> <li class="nav-item"> <a href="//chromeos.dev/" class="nav-title"> <span class="nav-text"> ChromeOS </span> </a> </li> <li class="nav-item"> <a href="//cloud.google.com" class="nav-title"> <span class="nav-text"> Cloud </span> </a> </li> <li class="nav-item"> <a href="//firebase.google.com" class="nav-title"> <span class="nav-text"> Firebase </span> </a> </li> <li class="nav-item"> <a href="//flutter.dev" class="nav-title"> <span class="nav-text"> Flutter </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/assistant" class="nav-title"> <span class="nav-text"> Google Assistant </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/maps" class="nav-title"> <span class="nav-text"> Google Maps Platform </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/workspace" class="nav-title"> <span class="nav-text"> Google Workspace </span> </a> </li> <li class="nav-item"> <a href="//www.tensorflow.org" class="nav-title"> <span class="nav-text"> TensorFlow </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/youtube" class="nav-title"> <span class="nav-text"> YouTube </span> </a> </li> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Tumbuh </span> </span> </li> <li class="nav-item"> <a href="//firebase.google.com" class="nav-title"> <span class="nav-text"> Firebase </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/google-ads" class="nav-title"> <span class="nav-text"> Google Ads </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/analytics" class="nav-title"> <span class="nav-text"> Google Analytics </span> </a> </li> <li class="nav-item"> <a href="//developer.android.com/distribute" class="nav-title"> <span class="nav-text"> Google Play </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/search" class="nav-title"> <span class="nav-text"> Search </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/web/fundamentals/engage-and-retain/push-notifications" class="nav-title"> <span class="nav-text"> Web Push and Notification APIs </span> </a> </li> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Hasilkan uang </span> </span> </li> <li class="nav-item"> <a href="//developers.google.com/admob" class="nav-title"> <span class="nav-text"> AdMob </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/google-ads/api" class="nav-title"> <span class="nav-text"> Google Ads API </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/pay" class="nav-title"> <span class="nav-text"> Google Pay </span> </a> </li> <li class="nav-item"> <a href="//developer.android.com/google/play/billing/" class="nav-title"> <span class="nav-text"> Google Play Billing </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/interactive-media-ads" class="nav-title"> <span class="nav-text"> Interactive Media Ads </span> </a> </li> </ul> <ul class="nav-list community-submenu hidden" menu="Community" aria-label="Menu samping"> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Grup </span> </span> </li> <li class="nav-item"> <a href="//developers.google.com/community/gdg" class="nav-title"> <span class="nav-text"> Google Developer Groups </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/gdsc" class="nav-title"> <span class="nav-text"> Google Developer Student Clubs </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/womentechmakers" class="nav-title"> <span class="nav-text"> Woman Techmakers </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/experts" class="nav-title"> <span class="nav-text"> Google Developer Experts </span> </a> </li> <li class="nav-item"> <a href="//www.techequitycollective.com/" class="nav-title"> <span class="nav-text"> Tech Equity Collective </span> </a> </li> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Program </span> </span> </li> <li class="nav-item"> <a href="//developers.google.com/community/accelerators" class="nav-title"> <span class="nav-text"> Accelerator </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/gdsc-solution-challenge" class="nav-title"> <span class="nav-text"> Solution Challenge </span> </a> </li> <li class="nav-item"> <a href="//developers.google.com/community/devfest" class="nav-title"> <span class="nav-text"> DevFest </span> </a> </li> <li class="nav-item nav-heading"> <span class="nav-title"> <span class="nav-text"> Cerita </span> </span> </li> <li class="nav-item"> <a href="//developers.google.com/community/stories" class="nav-title" aria-label="All Stories"> <span class="nav-text"> Semua Cerita </span> </a> </li> </ul> </div> </div> </nav> <select aria-label="Ganti bahasa" name="lang-selector" id="lang-selector-nav" class="glue-form__dropdown glue-mobile-nav__lang-dropdown" onchange="window.location.href=this.value" > <option value="/en/how-we-built-purrfect-code/" lang="en" > English </option> <option value="/es/how-we-built-purrfect-code/" lang="es" > Español (Latam) </option> <option value="/id/how-we-built-purrfect-code/" lang="id" selected > Bahasa Indonesia </option> <option value="/ja/how-we-built-purrfect-code/" lang="ja" > 日本語 </option> <option value="/ko/how-we-built-purrfect-code/" lang="ko" > 한국어 </option> <option value="/pt-br/how-we-built-purrfect-code/" lang="pt-br" > Português (Brasil) </option> <option value="/zh-hans/how-we-built-purrfect-code/" lang="zh-hans" > 简体中文 </option> </select> </div> <div class="backdrop"></div> <div class="blog-detail-container"> <section class="tags-container glue-page glue-spacer-5-top"> <div class="glue-eyebrow"><a href="/id/search/?product_categories=Flutter">Flutter</a> / <a href="/id/search/?product_categories=IDX">IDX</a></div> </section> <section class="heading-container glue-page glue-spacer-1-top"> <h1 class="glue-headline glue-headline--headline-1">Bagaimana Kami Membangun Purrfect Code: Game Teka-teki untuk Developer</h1> </section> <section class="summary-container glue-page glue-spacer-4-top"> <div class="date-time"> <div class="published-date glue-font-weight-medium">AGU 01, 2024</div> </div> </section> <section class="glue-page glue-grid glue-spacer-1-top"> <section class="author-container glue-grid__col glue-grid__col--span-4-sm glue-grid__col--span-10-md"> <div class="author-obj"> <a class="glue-font-weight-medium" href="/id/search/?author=Google+for+Developers">Google for Developers</a> </div> </section> <section class="social-container glue-grid__col glue-grid__col--span-4-sm glue-grid__col--span-2-md"> <button id="social-button" class="glue-button glue-button--low-emphasis glue-button--icon" aria-haspopup="true" aria-expanded="false"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#share"></use> </svg> <span>Bagikan</span> </button> <ul id="social-menu" class="glue-elevation-level-1" role="menu" aria-labelledby="social-button"> <li> <a href="https://www.facebook.com/sharer/sharer.php?u={url}" title="Share on Facebook" target="_blank" rel="noopener"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--social glue-icon--32px"> <use href="/glue-icon/#post-facebook"></use> </svg> <span>Facebook</span> </a> </li> <li> <a href="https://twitter.com/intent/tweet?text={url}" title="Share on Twitter" target="_blank" rel="noopener"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--social glue-icon--32px"> <use href="/glue-icon/#twitter-x"></use> </svg> <span>Twitter</span> </a> </li> <li> <a href="https://www.linkedin.com/shareArticle?url={url}&mini=true" title="Share on LinkedIn" target="_blank" rel="noopener"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--social glue-icon--32px"> <use href="/glue-icon/#post-linkedin"></use> </svg> <span>LinkedIn</span> </a> </li> <li> <a href="mailto:name@example.com?subject=Check%20out%20this%20site&body=Check%20out%20{url}" title="Send via Email"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--social glue-icon--32px"> <use href="/glue-icon/#email"></use> </svg> <span>Mail</span> </a> </li> <li> <a href="#" title="Get shareable link" data-link="" data-copy-text="Salin Link" data-copied-text="Disalin!"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--social glue-icon--32px"> <use href="/glue-icon/#link"></use> </svg> <span></span> </a> </li> </ul> </section> </section> <section class="blocks-container glue-page glue-spacer-3-top"> <div class="block"> <div class="inner-block-content yt-video"> <div class="glue-video"> <div class="glue-video__container glue-video__container--inline" data-glue-yt-video-vid="kPzov5wYXAI" > </div> <div class="glue-video__nojs"> <p><a href="https://www.youtube.com/watch?v=kPzov5wYXAI">Link to Youtube Video</a> (visible only when JS is disabled)</p> </div> </div> </div> <div class="inner-block-content rich-content"> <p data-block-key="k83go">"<a href="https://goo.gle/purrfect-code-hub">Purrfect Code</a>" adalah game teka-teki pemrograman dorong-kotak baru, yang didukung oleh Flutter, Dart, dan game engine Flame serta dirancang untuk menantang developer memecahkan teka-teki dengan menulis kode.</p><h2 data-block-key="4pmbp"><b><br/>Ringkasan Game</b></h2><p data-block-key="ch3h">Dalam "Purrfect Code," pemain ditugaskan mengupdate pemrograman robot petugas kebersihan di markas stasiun luar angkasa baru Google ketika kiriman kucing datang secara keliru. Tujuan game ini adalah membantu robot mengumpulkan kotak-kotak yang berisi kucing tersebut secara aman dan mendorongnya ke pelat teleporter agar mereka bisa pulang ke rumah. Pemain menulis JavaScript untuk mengontrol gerakan robot sembari mencoba menemukan solusi yang efisien untuk menyelesaikan teka-teki berbasis grid.</p><p data-block-key="bt816">Game ini adalah cara yang menyenangkan untuk mengeksplorasi coding, menggunakan kecerdasan dan kreativitas Anda. Setiap level berfokus pada konsep pemrograman dan secara perlahan kompleksitasnya meningkat selama lima level dalam game.</p><p data-block-key="1sq75">Game loop berjalan seperti berikut ini:</p><p data-block-key="e8dsg"></p><ol><li data-block-key="e9f28">Pemain menulis kode JavaScript untuk menggerakkan robot (atas, bawah, kiri, atau kanan)</li></ol><p data-block-key="1tjkf"></p><p data-block-key="huc9">2. Mereka kemudian menjalankan kodenya dan melihat robot mencoba menyelesaikan level tersebut</p><p data-block-key="8kg3e"></p><p data-block-key="51qmn">3. Level ini selesai ketika semua kotak yang berisi kucing didorong ke pelat teleporter</p><p data-block-key="bltb2"></p><p data-block-key="dphrh">4. Pemain dinilai berdasarkan efisiensi solusinya, termasuk jumlah ruang yang dipindahkan dan keringkasan kodenya</p> </div> <div class="inner-block-content video-block"> <video autoplay="" loop="" muted="" playsinline="" poster="https://storage.googleapis.com/gweb-developer-goog-blog-assets/original_videos/wagtailvideo-gizol0ut_thumb.jpg"> <source src='https://storage.googleapis.com/gweb-developer-goog-blog-assets/original_videos/purrfect_code.mp4' type='video/mp4'> <p>Sorry, your browser doesn't support playback for this video</p> </video> </div> <div class="inner-block-content rich-content"> <h2 data-block-key="k83go"><b>Membangun Game dengan Flutter, Dart, dan Flame</b></h2><p data-block-key="b0m5v">Kami memilih membangun "<a href="https://goo.gle/purrfect-code-hub">Purrfect Code</a>" menggunakan Flutter dan Dart, karena keduanya menyediakan framework yang kuat dan fleksibel untuk membuat aplikasi dan game multiplatform. Sistem widget dan model pemrograman reaktif Flutter memungkinkan kami membuat antarmuka pengguna yang responsif untuk berbagai ukuran layar di browser. Fitur pemrograman Dart yang sangat kuat dan berorientasi objek mempermudah penyusunan kode dan menjaga codebase kami tetap bersih. Game engine Flame, yang dibangun berbasis Flutter, menawarkan fondasi yang bagus untuk fitur-fitur dasar yang diperlukan untuk pengembangan game, sehingga kami dapat fokus pada logika gameplay dan berbagai aspek unik dari game ini. Flutter dan Flame adalah pilihan yang tepat untuk project ini karena karakter Purrfect Code yang unik sebagai game/aplikasi hibrida dengan UI yang terinspirasi dari IDE <i>dan</i> tampilan game dengan animasi sprite dan suara.</p><h3 data-block-key="36ihr"><br/><b>Chrome dan JavaScript: Memanfaatkan Dukungan Browser Bawaan</b></h3><p data-block-key="1ms1k">Setelah menentukan konsep pemrograman untuk game ini, kami harus memilih bahasa pemrograman yang akan digunakan oleh para pemain. Kami menginginkan sesuatu yang familier dan populer di kalangan developer. Awalnya kami mempertimbangkan menggunakan Python sebagai bahasa pemrograman dalam game. Namun, setelah beberapa pertimbangan, kami memutuskan menggunakan JavaScript untuk memanfaatkan dukungan JavaScript bawaan yang disediakan Chrome. Dengan menggunakan JavaScript, kami bisa memanfaatkan kemampuan native browser tanpa perlu memuat penerjemah bahasa tambahan. Keputusan ini tidak hanya menyederhanakan proses pengembangan kami, tetapi juga memastikan pengalaman yang mulus bagi pemain, karena game dapat dimuat secara cepat dengan dependensi minimal.</p><p data-block-key="bce1m"><a href="https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3">Rilis Flutter 3.22 di Google I/O</a> tahun ini memperkenalkan dukungan stabil untuk WebAssembly (WASM) yang memungkinkan kami mengoptimalkan bagian performa terpenting dalam game. Dengan mengompilasi logika game tertentu ke WASM, kami memastikan bahwa "Purrfect Code" berjalan secara efisien di browser, memberikan pengalaman bermain game yang mulus dan responsif tanpa mengorbankan performa.</p> </div> <div class="inner-block-content code-block"> <div class="highlight"><pre class="javascript"><span></span><span class="kd">var</span><span class="w"> </span><span class="nx">dir</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="nx">moveEast</span><span class="p">,</span><span class="nx">moveNorth</span><span class="p">,</span><span class="nx">moveWest</span><span class="p">,</span><span class="nx">moveSouth</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mf">0</span><span class="p">;</span><span class="nx">i</span><span class="o"><</span><span class="mf">4</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">){</span> <span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="nx">j</span><span class="o">=</span><span class="mf">0</span><span class="p">;</span><span class="nx">j</span><span class="o"><</span><span class="mf">5</span><span class="p">;</span><span class="nx">j</span><span class="o">++</span><span class="p">)</span><span class="nx">dir</span><span class="p">[</span><span class="nx">i</span><span class="p">]();</span> <span class="p">}</span> </pre></div> </div> <div class="inner-block-content rich-content"> <h3 data-block-key="k83go"><b>Game Engine Flame: Pengembangan Game yang Modular dan Efisien</b></h3><p data-block-key="315nu">Untuk menghidupkan "Purrfect Code", kami menggunakan Game Engine Flame, sebuah game engine modular open source berbasis Flutter yang menyediakan banyak fitur yang dibutuhkan untuk pengembangan game. Flame memanfaatkan infrastruktur Flutter yang andal sekaligus menyederhanakan kode yang dibutuhkan untuk membangun project kami. Flame menawarkan implementasi game loop yang sederhana tetapi efektif dan berbagai fungsionalitas penting, seperti pemutaran audio, manajemen sprite, fitur animasi, tabrakan, dan Flame Component System (FCS). Arsitektur berbasis komponen, rendering sprite, dan dukungan animasi dari engine ini memungkinkan kami menciptakan grafik yang menarik secara visual, animasi yang halus, dan elemen gameplay yang interaktif tanpa harus membuat semuanya dari awal. Pemanfaatan Flame, membuat proses pengembangan semakin efisien dengan fitur-fitur penting yang sudah tersedia, sehingga kami dapat fokus untuk menciptakan pengalaman bermain yang menarik bagi pemain.</p><h3 data-block-key="aqgd7"><br/><b>Mengimplementasikan Fitur Game dengan Flame</b></h3><h6 data-block-key="bs76o">Flame menawarkan implementasi game loop yang sederhana tetapi efektif dan berbagai fungsi penting, seperti pemutaran audio, manajemen sprite, fitur animasi, tabrakan, dan Flame Component System (FCS).</h6><p data-block-key="9jjat">Sistem rendering sprite dan animasi Flame memungkinkan kami menghidupkan karakter dan lingkungan game tanpa harus menulis kode grafik. Kami bisa membuat sprite sheet, menentukan urutan animasi, dan menganimasikan gerakan karakter serta efek khusus dengan baik. Kami menggunakan sistem prioritas Flame untuk menulis sistem pengurutan visual untuk perspektif game "top down" kami. Artis kami membuat level dengan banyak fitur yang tumpang tindih untuk meningkatkan kesan mendalam pada sprite dan memberikan tampilan game yang tidak terlalu "seperti grid". Kami harus memastikan bahwa ketika robot bergerak di belakangnya, robot tersebut akan tertutupi dengan benar. Sistem prioritas Flame memungkinkan kami menetapkan prioritas pada elemen visual berbeda, yang memastikan bahwa elemen-elemen tersebut digambar dengan urutan yang benar dan saling tumpang tindih dengan tepat. Sistem ini cukup fleksibel bagi kami untuk menyertakan sistem bayangan dengan masing-masing komponen dapat menampilkan animasi bayangan yang mencerminkan tindakan objek dan memberi kesan mendalam sehingga membuat adegan terlihat lebih hidup dan lebih mudah dipahami secara visual.</p><p data-block-key="54llu">Class BoxShadow dalam codebase kami adalah contoh bagus untuk hal ini dan menunjukkan bagaimana kami membuat bayangan yang dinamis dan interaktif untuk objek kotak yang bergerak dalam game. Dengan memperluas SpriteAnimationComponent dan mengimplementasikan campuran GridElement dan HasVisibility, kami bisa memuat sprite sheet untuk bayangan kotak dan animasi teleportasi kotak, menentukan beberapa animasi untuk status teleportasi, terbuka, tertutup, dan tidak ada aktivitas, serta mengintegrasikannya ke dalam tata letak berbasis grid. Metode onLoad memuat animasi dan menetapkan posisi awal serta prioritas komponen berdasarkan posisi grid, sementara metode update memastikan bahwa komponen prioritas diupdate secara dinamis jika kotak bergerak di depan atau di belakang objek yang menghalangi. Dengan menggunakan sistem animasi dan prioritas Flame seperti ini, kami dapat menciptakan efek bayangan yang senantiasa membantu pengguna untuk memahami ruang virtual secara visual dan membuatnya lebih realistis serta menghasilkan presentasi visual yang lebih terintegrasi.</p><p data-block-key="b0er"><i>Cuplikan dari box_shadow.dart,</i> <a href="https://github.com/devchallengedemo/purrfect_code/blob/main/lib/src/sokoban_view/components/box_shadow.dart"><i>lihat class lengkapnya</i></a><i> di GitHub untuk mempelajari lebih lanjut.</i></p> </div> <div class="inner-block-content code-block"> <div class="highlight"><pre class="dart"><span></span><span class="nd">@override</span> <span class="w"> </span><span class="n">Future</span><span class="o"><</span><span class="kt">void</span><span class="o">></span><span class="w"> </span><span class="n">onLoad</span><span class="p">()</span><span class="w"> </span><span class="kd">async</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kd">await</span><span class="w"> </span><span class="n">_loadAnimations</span><span class="p">().</span><span class="n">then</span><span class="p">((</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="n">animation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_boxClosed</span><span class="p">});</span> <span class="w"> </span> <span class="w"> </span> <span class="w"> </span><span class="n">position</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">Vector2</span><span class="p">(</span> <span class="w"> </span><span class="p">((</span><span class="n">gridPosition</span><span class="p">.</span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">gridPixelDimensions</span><span class="p">.</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">gridPixelOffset</span><span class="p">.</span><span class="n">x</span><span class="p">),</span> <span class="w"> </span><span class="p">((</span><span class="n">gridPosition</span><span class="p">.</span><span class="n">y</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">gridPixelDimensions</span><span class="p">.</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">gridPixelOffset</span><span class="p">.</span><span class="n">y</span><span class="p">)));</span> <span class="w"> </span><span class="n">priority</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getLayeredGridValue</span><span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="nd">@override</span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">update</span><span class="p">(</span><span class="kt">double</span><span class="w"> </span><span class="n">dt</span><span class="p">)</span><span class="w"> </span><span class="kd">async</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">super</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">dt</span><span class="p">);</span> <span class="w"> </span> <span class="w"> </span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">getLayeredGridValue</span><span class="p">()</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">priority</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="n">priority</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getLayeredGridValue</span><span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> </pre></div> </div> <div class="inner-block-content rich-content"> <h3 data-block-key="k83go"><b>Badge dan Program Developer Google</b></h3><p data-block-key="5rbi4">Karena kami ingin menjaga cakupan game tetap kecil, dan menerapkannya sebagai halaman web sederhana, kami menghindari pengaturan backend untuk game. Namun, kami menginginkan suatu cara bagi developer untuk mendapatkan reward atas progres mereka, mirip dengan sistem pencapaian di platform game populer. Alih-alih membangun sistem backend terpisah untuk melacak progres dan pencapaian pemain, kami mengintegrasikannya dengan Program Developer Google dengan mengizinkan pemain untuk mengklik link dan mengumpulkan badge di profilnya setelah mereka menyelesaikan sebuah level, sehingga memberikan rasa pencapaian dan pengakuan di dalam komunitas developer.</p> </div> <div class="inner-block-content"> <div class="image-wrapper"> <img class="regular-image" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/image1_vQeaWU2.original.png" alt="Purrfect Code Google Developer Program profile badges" /> </div> </div> <div class="inner-block-content rich-content"> <h3 data-block-key="k83go"><b>Project IDX: Lingkungan Pengembangan yang Efisien</b></h3><p data-block-key="fehun">Selama pengembangan "Purrfect Code", kami memanfaatkan Project IDX Google, ruang kerja berbantuan AI untuk pengembangan aplikasi multi-platform full-stack di cloud. Karena kami sudah merasa nyaman bekerja di VS Code, Project IDX menyediakan lingkungan yang familier untuk pengkodean, debugging, dan pengujian game kami dan memungkinkan kami untuk memulai dan menjalankannya dengan cepat. Dengan Flutter dan Dart yang sudah disiapkan dan siap digunakan di browser, kita dapat langsung terjun ke pengembangan tanpa perlu repot mengonfigurasi lingkungan lokal. Penyelesaian kode yang cerdas, pemeriksaan kesalahan waktu nyata, dan alat debugging terintegrasi yang ditawarkan oleh Project IDX membantu kami menjaga produktivitas tetap tinggi. Jika Anda penasaran, Project IDX adalah cara terbaik untuk mencoba Purrfect Code dengan cepat dan menjelajahi kodenya langsung dari browser Anda. <a href="https://goo.gle/purrfect-code-idx">Klik link ini untuk membuka proyek langsung di IDX dan menjalankan proyek sendiri</a>. Pastikan untuk mencentang kotak yang menanyakan apakah ini adalah aplikasi Flutter.</p><h3 data-block-key="ebkeg"><br/><b>Firebase untuk Hosting yang Cepat dan Aman</b></h3><p data-block-key="8vv87">Kami memilih Firebase Hosting untuk memastikan peluncuran Purrfect Code ke seluruh dunia secara aman dan efisien. Platform SSL tanpa konfigurasi ini menjamin konten disalurkan melalui HTTPS sehingga meningkatkan keamanan. Selain itu, dukungannya untuk framework web modern dan build otomatis dari repositori GitHub memungkinkan deployment update yang cepat. Firebase CLI, emulasi lokal, dan URL pratinjau menyederhanakan proses pengujian dan kolaborasi kami. Fitur-fitur ini, ditambah dengan potensi evolusi game di masa depan yang memanfaatkan template contoh Gemini untuk integrasi AI, yang menjadikan Firebase Hosting pilihan ideal untuk meluncurkan game kami.</p><h3 data-block-key="f6kv5"><br/><b>Konfigurasi Firebase dengan WASM</b></h3><p data-block-key="fd5ju">Purrfect Code menggunakan Web Assembly yang membutuhkan beberapa langkah tambahan selama deployment. Dalam konfigurasi firebase.json, kami menambahkan perintah predeploy yang memungkinkan build web kami dibangun dengan WASM. Argumen “--no-strip-wasm” mencegah kode berjalan melewati satu langkah minimalisasi terakhir yang membuat error semakin sulit dibaca dan di-debug. WASM juga memerlukan cross-origin opener policy dan cross origin embedder policy untuk multi-threading dan berbagi memori.</p> </div> <div class="inner-block-content code-block"> <div class="highlight"><pre class="go"><span></span><span class="s">"hosting"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="s">"predeploy"</span><span class="p">:</span><span class="w"> </span><span class="s">"flutter build web --wasm"</span><span class="p">,</span> <span class="w"> </span><span class="s">"public"</span><span class="p">:</span><span class="w"> </span><span class="s">"build/web"</span><span class="p">,</span> <span class="w"> </span><span class="s">"ignore"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> <span class="w"> </span><span class="s">"firebase.json"</span><span class="p">,</span> <span class="w"> </span><span class="s">"**/.*"</span> <span class="w"> </span><span class="p">],</span> <span class="w"> </span><span class="s">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="s">"source"</span><span class="p">:</span><span class="w"> </span><span class="s">"**/*"</span><span class="p">,</span> <span class="w"> </span><span class="s">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="s">"key"</span><span class="p">:</span><span class="w"> </span><span class="s">"cross-origin-opener-policy"</span><span class="p">,</span> <span class="w"> </span><span class="s">"value"</span><span class="p">:</span><span class="w"> </span><span class="s">"same-origin"</span> <span class="w"> </span><span class="p">},</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="s">"key"</span><span class="p">:</span><span class="w"> </span><span class="s">"cross-origin-embedder-policy"</span><span class="p">,</span> <span class="w"> </span><span class="s">"value"</span><span class="p">:</span><span class="w"> </span><span class="s">"require-corp"</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">]</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">]</span> <span class="w"> </span><span class="p">}</span> </pre></div> </div> <div class="inner-block-content rich-content"> <h2 data-block-key="k83go"><b>Pembelajaran dan Referensi</b></h2><p data-block-key="62gpp">Selama pengembangan "Purrfect Code," kami menggunakan berbagai referensi dan mendapatkan inspirasi dari project-project yang sudah ada, yang diharapkan dapat menambahkan project ini. Berikut adalah beberapa materi pembelajaran dan referensi utama yang kami anggap penting:</p><h3 data-block-key="ccgda"><br/><b>Project Referensi</b></h3><p data-block-key="f5pio">Kami menggunakan game <a href="https://medium.com/@vgv_team/how-we-built-the-new-super-dash-demo-in-flutter-and-flame-in-just-six-weeks-9c7aa2a5ad31">Super Dash</a> dan <a href="https://developers.googleblog.com/en/how-its-made-io-flip-adds-a-twist-to-a-classic-card-game-with-generative-ai/">I/O Flip</a> sebagai referensi untuk praktik terbaik dan ide implementasi. Kedua project ini memberikan insight yang penting dalam menyusun game Flutter, menangani status game, dan mengimplementasikan mekanisme game. Super Dash secara langsung relevan karena sederhana dan tidak memerlukan layanan backend, seperti game kami. I/O Flip lebih besar dan mendukung backend serta fitur AI generatif sehingga mungkin menarik bagi developer yang membangun game yang membutuhkan fitur-fitur tersebut. Keduanya merupakan referensi yang penting jika Anda tertarik untuk membuat <a href="https://flutter.dev/games">game di Flutter</a>.</p><h2 data-block-key="66fvv"><b><br/>Kesimpulan</b></h2><p data-block-key="694q4">Kami berharap "<a href="https://goo.gle/purrfect-code-hub">Purrfect Code</a>" tidak hanya memberikan pengalaman bermain game yang menyenangkan tetapi juga berfungsi sebagai sumber pembelajaran bagi pengembang yang tertarik dalam pengembangan game dengan Flutter dan Flame. Kombinasi <a href="https://flutter.dev/">Flutter</a>, <a href="https://flame-engine.org/">Flame</a> dan <a href="https://www.google.com/chrome/">Chrome</a> terbukti sangat cocok untuk game/aplikasi hybrid kami, memberikan kami dasar yang kuat untuk pengembangan UI, rendering grafis, manajemen suara, dan banyak lagi. Kami mendorong Anda untuk menjelajahi kode sumber permainan dan bereksperimen dengan memperluasnya lebih jauh. Ada banyak kemungkinan untuk menambahkan fitur, level, dan mekanisme gameplay baru. Masuk ke basis kode di <a href="https://goo.gle/purrfect-code-idx">Project IDX</a>, centang kotak yang menanyakan apakah ini aplikasi Flutter, dan biarkan kreativitas Anda menjadi liar! </p> </div> </div> </section> <section class="navigation-container glue-page glue-spacer-6-top"> <div class="posted-in-section"> <div class="posted-in-section__heading"> <span class="glue-caption"> diposting di: </span> </div> <div class="posted-in-section__tags"> <ul> <li> <a href="/id/search/?product_categories=Flutter" class="glue-caption">Flutter</a> </li> <li> <a href="/id/search/?product_categories=IDX" class="glue-caption">IDX</a> </li> <li> <a href="/id/search/?technology_categories=Web" class="glue-caption">Web</a> </li> <li> <a href="/id/search/?content_type_categories=How-To+Guides" class="glue-caption">How-To Guides</a> </li> <li> <a href="/id/search/?tag=Learning To Code" class="glue-caption">Learning To Code</a> </li> <li> <a href="/id/search/?tag=Learn" class="glue-caption">Learn</a> </li> </ul> </div> </div> <div class="buttons-section"> <div class="buttons-section__left"> <a href="/id/build-a-text-based-adventure-game-with-gemma-2/" class="glue-button--icon glue-elevation-level-1 " aria-label="Sebelumnya"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#chevron-left"></use> </svg> </a> <span class="caption ">Sebelumnya</span> </div> <div class="buttons-section__right"> <span class="caption ">Berikutnya</span> <a href="/id/smaller-safer-more-transparent-advancing-responsible-ai-with-gemma/" class="glue-button--icon glue-elevation-level-1 " aria-label="Berikutnya"> <svg role="presentation" aria-hidden="true" class="glue-icon"> <use href="/glue-icon/#chevron-right"></use> </svg> </a> </div> </div> </section> <section class="related-posts-container glue-page glue-spacer-6-top glue-spacer-3-bottom"> <span class="glue-headline glue-headline--headline-3">Postingan Terkait</span> <div class="related-posts-container__carousel glue-page glue-spacer-5-top"> <div class="glue-carousel glue-carousel--cards glue-carousel-related-posts" aria-label="Postingan Terkait"> <!-- Previous --> <button class="glue-carousel__button glue-carousel__button--prev" aria-label="Ke slide sebelumnya"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--32px"> <use href="/glue-icon/#chevron-left"></use> </svg> </button> <!-- Next --> <button class="glue-carousel__button glue-carousel__button--next" aria-label="Ke slide berikutnya"> <svg role="presentation" aria-hidden="true" class="glue-icon glue-icon--32px"> <use href="/glue-icon/#chevron-right"></use> </svg> </button> <!-- List --> <div class="glue-carousel__viewport"> <div class="glue-carousel__list"> <a class="glue-card glue-carousel__item" href="/id/beyond-the-chatbot-agentic-ai-with-gemma/"> <div aria-label="Lebih dari sekadar Chatbot: Agentic AI dengan Gemma" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Lebih dari sekadar Chatbot: Agentic AI dengan Gemma" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Gemma-Logo-Agentic-AI.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">Gemma</span> <span class="glue-label">AI</span> <span class="glue-label">How-To Guides</span> </div> <p class="glue-headline glue-headline--headline-5">Lebih dari sekadar Chatbot: Agentic AI dengan Gemma</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">13 Feb. 2025</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> <a class="glue-card glue-carousel__item" href="/id/celebrating-flutters-production-era/"> <div aria-label="Merayakan “Era Produksi” Flutter" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Merayakan “Era Produksi” Flutter" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/GfD_blog_header_1600x873px.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">Flutter</span> <span class="glue-label">Mobile</span> <span class="glue-label">Web</span> <span class="glue-label">Announcements</span> <span class="glue-label">Release Notes</span> </div> <p class="glue-headline glue-headline--headline-5">Merayakan “Era Produksi” Flutter</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">17 Des. 2024</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> <a class="glue-card glue-carousel__item" href="/id/gemini-2-0-level-up-your-apps-with-real-time-multimodal-interactions/"> <div aria-label="Gemini 2.0: Naikkan Level Aplikasi Anda dengan Interaksi Multimodal Real-Time" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Gemini 2.0: Naikkan Level Aplikasi Anda dengan Interaksi Multimodal Real-Time" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Stream-meta.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">AI</span> <span class="glue-label">Tutorials</span> <span class="glue-label">How-To Guides</span> </div> <p class="glue-headline glue-headline--headline-5">Gemini 2.0: Naikkan Level Aplikasi Anda dengan Interaksi Multimodal Real-Time</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">23 Des. 2024</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> <a class="glue-card glue-carousel__item" href="/id/build-the-future-of-home-with-google-home-apis-1/"> <div aria-label="Build the future of home with Google Home APIs" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Build the future of home with Google Home APIs" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Generic_16x9.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">Matter</span> <span class="glue-label">Smart Home</span> <span class="glue-label">Web</span> <span class="glue-label">AI</span> <span class="glue-label">Announcements</span> </div> <p class="glue-headline glue-headline--headline-5">Build the future of home with Google Home APIs</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">7 Jan. 2025</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> <a class="glue-card glue-carousel__item" href="/id/get-ready-for-google-io-2025/"> <div aria-label="Bersiaplah untuk Google I/O 20-21 Mei" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Bersiaplah untuk Google I/O 20-21 Mei" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/SVD_Blog_Header_-_GfD_Metadata_Car.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">Mobile</span> <span class="glue-label">Web</span> <span class="glue-label">Announcements</span> <span class="glue-label">Community</span> </div> <p class="glue-headline glue-headline--headline-5">Bersiaplah untuk Google I/O 20-21 Mei</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">11 Feb. 2025</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> <a class="glue-card glue-carousel__item" href="/id/build-go-applications-project-idx-gemini-api/"> <div aria-label="Membangun aplikasi Go menggunakan Project IDX dan Gemini API" class="glue-card__inner"> <picture class="glue-card__asset"> <img alt="Membangun aplikasi Go menggunakan Project IDX dan Gemini API" src="https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Go-Gopher_IDX-rev2.2e16d0ba.fill-800x400.png"> </picture> <div class="glue-card__content"> <div class="glue-card__tags glue-spacer-2-top"> <span class="glue-label">Gemini</span> <span class="glue-label">IDX</span> <span class="glue-label">Web</span> <span class="glue-label">AI</span> <span class="glue-label">Tutorials</span> <span class="glue-label">How-To Guides</span> </div> <p class="glue-headline glue-headline--headline-5">Membangun aplikasi Go menggunakan Project IDX dan Gemini API</p> <div class="glue-card__cta-custom glue-spacer-3-top"> <span class="glue-cta">18 Des. 2024</span> <svg aria-hidden="true" class="glue-icon glue-icon--24px" role="presentation"> <use href="/glue-icon/#arrow-forward"></use> </svg> </div> </div> </div> </a> </div> </div> <!-- Navigation dots --> <div class="glue-carousel__navigation" aria-label="Choose a page" data-glue-carousel-navigation-label="Selected tab $glue_carousel_page_number$ of $glue_carousel_page_total$"> </div> </div> </div> </section> </div> <div class="footer-linkboxes__wrapper"> <nav class="footer-linkboxes" aria-label="Link footer"> <ul class="footer-linkboxes__list"> <li class="footer-linkbox"> <span class="footer-linkbox-heading"> Terhubung </span> <ul class="footer-linkbox-list"> <li class="footer-linkbox-list__item"> <a href="//googledevelopers.blogspot.com" class="footer-linkbox-list__link"> Blog </a> </li> <li class="footer-linkbox-list__item"> <a href="https://goo.gle/googlefordevs" class="footer-linkbox-list__link"> Instagram </a> </li> <li class="footer-linkbox-list__item"> <a href="https://goo.gle/gdevs-li" class="footer-linkbox-list__link"> LinkedIn </a> </li> <li class="footer-linkbox-list__item"> <a href="https://goo.gle/gdevs-tw" class="footer-linkbox-list__link"> Twitter </a> </li> <li class="footer-linkbox-list__item"> <a href="https://goo.gle/developers" class="footer-linkbox-list__link"> YouTube </a> </li> </ul> </li> <li class="footer-linkbox"> <span class="footer-linkbox-heading"> Program </span> <ul class="footer-linkbox-list"> <li class="footer-linkbox-list__item"> <a href="//www.womentechmakers.com" class="footer-linkbox-list__link"> Women Techmakers </a> </li> <li class="footer-linkbox-list__item"> <a href="//developers.google.com/community/gdg" class="footer-linkbox-list__link"> Google Developer Groups </a> </li> <li class="footer-linkbox-list__item"> <a href="//developers.google.com/community/experts" class="footer-linkbox-list__link"> Google Developer Experts </a> </li> <li class="footer-linkbox-list__item"> <a href="//developers.google.com/community/accelerators" class="footer-linkbox-list__link"> Accelerators </a> </li> <li class="footer-linkbox-list__item"> <a href="//developers.google.com/community/gdsc" class="footer-linkbox-list__link"> Google Developer Student Clubs </a> </li> </ul> </li> <li class="footer-linkbox"> <span class="footer-linkbox-heading"> Konsol developer </span> <ul class="footer-linkbox-list"> <li class="footer-linkbox-list__item"> <a href="//console.developers.google.com" class="footer-linkbox-list__link"> Google API Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//console.cloud.google.com" class="footer-linkbox-list__link"> Google Cloud Platform Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//play.google.com/apps/publish" class="footer-linkbox-list__link"> Google Play Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//console.firebase.google.com" class="footer-linkbox-list__link"> Firebase Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//console.actions.google.com" class="footer-linkbox-list__link"> Actions on Google Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//cast.google.com/publish" class="footer-linkbox-list__link"> Cast SDK Developer Console </a> </li> <li class="footer-linkbox-list__item"> <a href="//chrome.google.com/webstore/developer/dashboard" class="footer-linkbox-list__link"> Chrome Web Store Dashboard </a> </li> </ul> </li> </ul> </nav> </div> <div class="footer-utility__wrapper"> <div> <nav class="footer-sites" aria-label="Situs Google Developers lainnya"> <a href="https://developers.google.com/" class="site-logo-link" data-label="Site logo"> <img src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/images/g-dev.svg" class="site-logo" alt="Google for Developers"> </a> <ul class="footer-sites-list"> <li class="footer-sites-item"> <a href="//developer.android.com" class="footer-sites-link"> Android </a> </li> <li class="footer-sites-item"> <a href="//developer.chrome.com/home" class="footer-sites-link"> Chrome </a> </li> <li class="footer-sites-item"> <a href="//firebase.google.com" class="footer-sites-link"> Firebase </a> </li> <li class="footer-sites-item"> <a href="//cloud.google.com" class="footer-sites-link"> Google Cloud Platform </a> </li> <li class="footer-sites-item"> <a href="//developers.google.com/products" class="footer-sites-link"> All products </a> </li> <li class="footer-sites-item"> <button aria-hidden="true" class="glue-cookie-notification-bar-control footer-sites-link"> Manage cookies </button> </li> </ul> </nav> <nav class="footer-utility-links"> <ul class="footer-utility-list"> <li class="footer-utility-item"> <a href="//developers.google.com/terms/site-terms" class="footer-utility-link"> Persyaratan </a> </li> <li class="footer-utility-item"> <a href="//policies.google.com/privacy" class="footer-utility-link"> Privasi </a> </li> </ul> <div class="language-selector footer" aria-label="Pilih preferensi bahasa Anda"> <button type="button" aria-controls="lang-selector-footer" aria-haspopup="true"> <svg role="presentation" aria-hidden="true" class="glue-icon lang-icon"> <use href="/glue-icon/#language"></use> </svg> <span class="lang-label">Bahasa Indonesia</span> <svg role="presentation" aria-hidden="true" class="glue-icon lang-icon"> <use href="/glue-icon/#arrow-drop-down"></use> </svg> </button> <div id="lang-selector-footer" class="lang-menu hidden" role="menu"> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" href="/en/how-we-built-purrfect-code"> English </a> </li> <li role="presentation"> <a role="menuitem" lang="es" href="/es/how-we-built-purrfect-code"> Español (Latam) </a> </li> <li role="presentation"> <a role="menuitem" lang="id" href="/id/how-we-built-purrfect-code"> Bahasa Indonesia </a> </li> <li role="presentation"> <a role="menuitem" lang="ja" href="/ja/how-we-built-purrfect-code"> 日本語 </a> </li> <li role="presentation"> <a role="menuitem" lang="ko" href="/ko/how-we-built-purrfect-code"> 한국어 </a> </li> <li role="presentation"> <a role="menuitem" lang="pt-br" href="/pt-br/how-we-built-purrfect-code"> Português (Brasil) </a> </li> <li role="presentation"> <a role="menuitem" lang="zh-hans" href="/zh-hans/how-we-built-purrfect-code"> 简体中文 </a> </li> </ul> </div> </div> </nav> </div> </div> <script src="https://www.youtube.com/player_api"></script> <script src="//www.gstatic.com/glue/v27_1/glue.min.js"></script> <script type="text/javascript" src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/js/dgc_blog.js"></script> <script src="https://www.gstatic.com/glue/cookienotificationbar/cookienotificationbar.min.js" data-glue-cookie-notification-bar-category="2A" data-glue-cookie-notification-bar-site-id="developers.googleblog.com"> </script> <script src="https://storage.googleapis.com/gweb-developer-goog-blog-cms-assets/site/20250213-150947/js/blog_detail.js"></script> </body> </html>