{"id":754,"date":"2019-12-09T03:21:10","date_gmt":"2019-12-09T03:21:10","guid":{"rendered":"https:\/\/www.danielparente.net\/en\/2019\/12\/09\/games-in-flutter-flame-box2d-part-1-flutter-community\/"},"modified":"2019-12-09T03:21:10","modified_gmt":"2019-12-09T03:21:10","slug":"games-in-flutter-flame-box2d-part-1-flutter-community","status":"publish","type":"post","link":"https:\/\/www.danielparente.net\/en\/2019\/12\/09\/games-in-flutter-flame-box2d-part-1-flutter-community\/","title":{"rendered":"Games in Flutter \u2014 Flame &#038; Box2D Part 1 &#8211; Flutter Community"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<div>\n<div class=\"ep\">\n<div class=\"n eq er es et\">\n<div class=\"o n\">\n<div><a rel=\"noopener\" href=\"https:\/\/medium.com\/@c.muehle18?source=post_page-----4c23a1cbc102----------------------\" target=\"_blank\"><\/p>\n<div class=\"eu ev ew\"><img decoding=\"async\" alt=\"Christian Muehle\" class=\"r fe ew ev\" src=\"https:\/\/miro.medium.com\/fit\/c\/96\/96\/2*33dep1N4p1DanY6KzQIz9A.jpeg\" width=\"48\" height=\"48\"\/><\/div>\n<p><\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Photo by <a href=\"https:\/\/unsplash.com\/@geekyshots?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Geeky Shots<\/a> on <a href=\"https:\/\/unsplash.com\/s\/photos\/gamer?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Unsplash<\/a><\/figcaption><\/figure>\n<p id=\"deab\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">I<\/span> really like video games. And I like to create and develop software. So I started a lot of attempts to give game development a try, even with the fact in my mind that I can\u2019t even draw round circles on a sheet of paper\u2026<br \/>During the development of my Game of Life clone in Flutter (linked below) I decided to start again \u2014 I welcome you to my first series of posts about how to get \u201creal\u201d game done, using Flutter, Flame and Box2d.<\/p>\n<p id=\"e7db\" class=\"hv hw ef at hx b hy kt ia ku ic kv ie kw ig kx ii\">My goal is to have at least 5 posts describing the process and the involved tools. Let\u2019s start with the basic things you will need to get started. Besides a <a href=\"https:\/\/flutter.dev\/docs\/get-started\/install\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">fully installed and working Flutter environment<\/a> we will make use of the following libraries:<\/p>\n<p id=\"b54c\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The game we will create will render a maze on your screen and the player will control a ball rolling through it by moving his phone (gyroscope required). The goal is to get out of the maze as quick as possible. I will explain each package along the way \u2014 let\u2019s start and create a new project:<\/p>\n<p id=\"5032\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\"><strong class=\"hx lg\">flutter create mazeball<\/strong><\/p>\n<p id=\"cb28\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Add the mentioned libraries to your <strong class=\"hx lg\">pubspec.yaml<\/strong> file. Please note that Box2D will be added automatically as soon as you add dependencies on Flame (as it is a part of it). The file should look like this:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"36b6\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Please remove the test folder after updating the <strong class=\"hx lg\">pubspec<\/strong> file (the above file doesn\u2019t contain a reference to it anymore) because for now we do not create tests for our game.<\/p>\n<figure class=\"gr gs gt gu gv gw\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Cat in the game loop \u2014 giphy<\/figcaption><\/figure>\n<p id=\"beaf\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">We<\/span> will use Flame as our game engine. Flame does offer a nice set of features for 2D games. Sure, it\u2019s not the next Unity or Unreal but it is easy to use and will offer all we need. We need to initialize Flame and make sure our app creates and starts our game. <br \/>Head over to the main.dart file and replace it with the one below. Don\u2019t worry if you see any errors, we will solve them in a moment. In case you choose another name for the project change it accordingly.<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"0eaf\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">I will explain each part now, feel free to skip if the code alone is fine. The file starts with our imports:<\/p>\n<ol class=\"\">\n<li id=\"2af4\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii lj kz la\">Flame utils\u2014 helps us to start up the app as we need it<\/li>\n<li id=\"763a\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Material \u2014 finally kicking off the app<\/li>\n<li id=\"8cce\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Services \u2014 same as point one, required in our <strong class=\"hx lg\">setupFlame()<\/strong> method<\/li>\n<li id=\"7b68\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Game \u2014 created in the next step<\/li>\n<li id=\"0e00\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Async \u2014 asynchronous support<\/li>\n<\/ol>\n<p id=\"b9ea\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">A<\/span>fter the import section the well known <strong class=\"hx lg\">main() <\/strong>function, this time with the <strong class=\"hx lg\">async <\/strong>keyword. This allows us to wait for other functions inside, exactly what we will do while calling <strong class=\"hx lg\">setupFlame()<\/strong>. Below this call you can find the creation of our game object and the call to the build in <strong class=\"hx lg\">runApp<\/strong>. Thanks to Flame, we have the handy <strong class=\"hx lg\">widget<\/strong> property that we simply hand in and all starts. The <strong class=\"hx lg\">setupFlame() <\/strong>function does the following:<\/p>\n<ol class=\"\">\n<li id=\"852b\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii lj kz la\">Creates a new <strong class=\"hx lg\">Util<\/strong> object<\/li>\n<li id=\"4cf7\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Ensures our app is running in fullscreen<\/li>\n<li id=\"4449\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii lj kz la\">Ensures our app is fixed to the portrait-up orientation, no rotation is allowed<\/li>\n<\/ol>\n<p id=\"a98b\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">You might have spotted the <strong class=\"hx lg\">async <\/strong>keyword here, too. The <strong class=\"hx lg\">setupFlame() <\/strong>function has to wait until the <strong class=\"hx lg\">Util<\/strong> methods are finished.<\/p>\n<p id=\"d570\" class=\"hv hw ef at hx b hy kt ia ku ic kv ie kw ig kx ii\">Create a new file in the <strong class=\"hx lg\">lib<\/strong> folder called <strong class=\"hx lg\">game.dart <\/strong>and copy in the content below:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"7bae\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The class <strong class=\"hx lg\">MazeBallGame<\/strong> is our main element, it extends the <strong class=\"hx lg\">Game<\/strong> class offered by Flame. Thanks to the base class we don\u2019t have to build our own game loop or take care about resize events. It will also be the first element called by Flame to render\/draw and update all elements of our game. <br \/>You might have noticed the <strong class=\"hx lg\">World<\/strong> object or <strong class=\"hx lg\">_gravity<\/strong> property in the above file, below are all details about our game class.<\/p>\n<figure class=\"gr gs gt gu gv gw\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Giphy \u2014 <a href=\"https:\/\/gph.is\/g\/4Ayrv50\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">https:\/\/gph.is\/g\/4Ayrv50<\/a><\/figcaption><\/figure>\n<p id=\"6908\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">B<\/span>ox2D will take care of all our physic related operations. This includes handling of collisions, accelerating\/decelerating a body\/mass and simulating the different shapes\/materials in our game. <br \/>The two constant int properties are needed to create our <strong class=\"hx lg\">World<\/strong> object; this happens during the construct of our <strong class=\"hx lg\">MazeBall<\/strong> class. To set up the world you also need to define gravity (if this would be as easy as in the real world).<br \/>In our game gravity is not needed \u2014 so we define this as a zero <strong class=\"hx lg\">Vector2<\/strong>. If you don\u2019t know what a vector is (in our case always a <strong class=\"hx lg\">Vector2<\/strong>) imagine it as a point inside a coordinate system: each <strong class=\"hx lg\">Vector2<\/strong> has an <strong class=\"hx lg\">X<\/strong> and an <strong class=\"hx lg\">Y<\/strong> value. Our <strong class=\"hx lg\">_gravity<\/strong> vector is set to (0,0). A <strong class=\"hx lg\">Vector3<\/strong> would have <strong class=\"hx lg\">X<\/strong>, <strong class=\"hx lg\">Y<\/strong> and <strong class=\"hx lg\">Z <\/strong>and<strong class=\"hx lg\"> <\/strong>this would go on like this for <strong class=\"hx lg\">Vector4,<\/strong> <strong class=\"hx lg\">Vector5,<\/strong> etc.<\/p>\n<p id=\"95e0\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">A gravity of (0,1) would make sure elements are falling down from the top of the screen to the bottom. Keep in mind our coordinate system starts in the top left corner with (0,0).<\/p>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Cordinate system in our app<\/figcaption><\/figure>\n<p id=\"aa03\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">A<\/span>fter the world has been created, we call <strong class=\"hx lg\">initialize<\/strong> that will call resize as soon as the app is ready. Ready in this case means launched and Flame was able to check the display size.<br \/>Below the resize method you will find the two mentioned methods from the start:<\/p>\n<ul class=\"\">\n<li id=\"a535\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ky kz la\"><strong class=\"hx lg\">render \u2014 <\/strong>render is called to draw elements on our <strong class=\"hx lg\">canvas<\/strong><\/li>\n<li id=\"3957\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\"><strong class=\"hx lg\">update \u2014 <\/strong>update is called with a time parameter (called <strong class=\"hx lg\">t<\/strong>); it contains the time since the last call. The goal is to run at 60fps which means the function will be called 60 times in one second. As this is not always the case, the time parameter tells you how much time has passed by since the last call.<\/li>\n<\/ul>\n<p id=\"8b36\" class=\"hv hw ef at hx b hy kt ia ku ic kv ie kw ig kx ii\">If all is set up correctly you should be able to start the app on your phone or simulator. I know, nothing special, just a black\/blank screen but this is how all great things start \ud83d\ude42<\/p>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"\/>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"7223\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij\"><span class=\"r ik il im in io ip iq ir is eu\">I<\/span> don\u2019t want to close the first part without drawing something \u2014 let\u2019s hack something in very quickly. Please replace the part from resize to update with the following code:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"c43f\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">What happens in here is the following:<\/p>\n<ul class=\"\">\n<li id=\"964d\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ky kz la\">Declaring a <strong class=\"hx lg\">Paint<\/strong> object \u2014 required to paint something<\/li>\n<li id=\"b4e5\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">Saving the screen size and a related rectangle for later use \u2014 the values are provided by Flame inside the resize event<\/li>\n<li id=\"7ff7\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">Defining a scale factor to increase the elements in our app \u2014 we need this later to have at least somehow correct dimensions for our physic interactions. A scale factor of 5 was chosen because I like this number \ud83d\ude42<\/li>\n<\/ul>\n<p id=\"a816\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Inside the render function we have to perform this:<\/p>\n<ul class=\"\">\n<li id=\"ea69\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ky kz la\">Make sure we are ready to draw \u2014 the <strong class=\"hx lg\">screenSize <\/strong>property should be set<\/li>\n<li id=\"37fc\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">Save the canvas before we draw using the build in <strong class=\"hx lg\">save()<\/strong> method<\/li>\n<li id=\"7766\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">Apply our scale factor using the width of the screen \u2014 thanks to the build in <strong class=\"hx lg\">scale()<\/strong> method this is very easy<\/li>\n<li id=\"315c\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">We move the (0,0) point of our canvas to the center (see phone graphic for a reminder) \u2014 the build in <strong class=\"hx lg\">translate<\/strong> method allows you to move the canvas starting point to a given set of coordinates<\/li>\n<li id=\"6d0a\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">Using the <strong class=\"hx lg\">drawCircle()<\/strong> method we draw a circle at (0,0) with a radius of 0.1 using our <strong class=\"hx lg\">paint<\/strong> object<\/li>\n<li id=\"e32c\" class=\"hv hw ef at hx b hy lb ia lc ic ld ie le ig lf ii ky kz la\">The call to <strong class=\"hx lg\">restore<\/strong> will finish our render loop for a single frame<\/li>\n<\/ul>\n<p id=\"d4f9\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Starting the app now should render a small circle near the center of the screen like below. Keep in mind that this was just added to have something on the screen, we will remove it in our next step.<\/p>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"\/>\n<p id=\"d6d9\" class=\"hv hw ef at hx b hy kt ia ku ic kv ie kw ig kx ii\">You got into contact with Flame, Box2D. You learned a little about vectors and what you need to get a basic game started. You even had a tiny lesson about gravity. Sure, we don\u2019t have the next AAA game on the screen, but we are on our way to build something using Flutter that will definitely be counted as a game.<\/p>\n<p id=\"1e24\" class=\"hv hw ef at hx b hy kt ia ku ic kv ie kw ig kx ii\">In the next part we will add our player and the related movement\/physic we need to make him move by using the gyroscope. In case you would like a head start checkout demos for the <a href=\"https:\/\/pub.dev\/packages\/sensors\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Sensors<\/a> library or have a look at the (written in C++) Box2D <a href=\"https:\/\/www.iforce2d.net\/b2dtut\/constant-speed\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">examples<\/a>.<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"https:\/\/medium.com\/flutter-community\/games-in-flutter-flame-box2d-part-1-4c23a1cbc102?_branch_match_id=729690391634787833\" target=\"_blank\" rel=\"noopener\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Photo by Geeky Shots on Unsplash I really like video games. And I like to create and develop software. So I started a lot of attempts to give game development a try, even with the fact in my mind that I can\u2019t even draw round circles on a sheet of paper\u2026During the development of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":755,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"blocksy_meta":[],"jetpack_featured_media_url":"https:\/\/e928cfdc7rs.exactdn.com\/info\/uploads\/sites\/3\/2019\/12\/Games-in-Flutter-\u2014-Flame-Box2D-Part-1-scaled.jpeg?strip=all","jetpack_shortlink":"https:\/\/wp.me\/p2TFCd-ca","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/comments?post=754"}],"version-history":[{"count":0,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/754\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media\/755"}],"wp:attachment":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media?parent=754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/categories?post=754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/tags?post=754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}