{"id":250,"date":"2021-05-06T15:09:17","date_gmt":"2021-05-06T15:09:17","guid":{"rendered":"https:\/\/erdbeerbeet.com\/?p=250"},"modified":"2021-09-06T13:42:50","modified_gmt":"2021-09-06T13:42:50","slug":"my-flame-game-ultimate-background-image","status":"publish","type":"post","link":"https:\/\/erdbeerbeet.com\/de\/my-flame-game-ultimate-background-image","title":{"rendered":"Mein Flame Game &#8211; das ultimative Hintergrundbild"},"content":{"rendered":"\n<p>Ich sitze aktuell an meinem ersten Flutter-Flame-Spiel. Es beinhaltet Erdbeerpflanzen und au\u00dferdem k\u00fcmmere ich mich selbst um die Grafiken. Momentan befindet es sich noch mitten im Prototyp-Status.<\/p>\n\n\n\n<p>Da das Aussehen wichtig ist fange ich mit dem Hintergrundbild an und versuche alles weitere darauf aufzubauen. Und damit kommen wir zu meinem Problem mit den \u00fcblichen Hintergrundbildern&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das Problem<\/h2>\n\n\n\n<p>Alle Tutorials, die ich bisher so entdeckt habe, zwingen das Ger\u00e4t einfach, den Portr\u00e4t-Modus zu nutzen (bzw. den Landschafts-Modus). Ich m\u00f6chte aber, dass sich mein Hintergrund dynamisch anpasst, erst recht seit Flutter auch Webanwendungen unterst\u00fctzt.<\/p>\n\n\n\n<p>Entsprechend m\u00f6chte ich, dass mein Bild f\u00fcr jedes Seitenverh\u00e4ltnis funktioniert und immer noch spielbar ist. Vielleicht gibt es eine Lehrbuch-L\u00f6sung, die ich einfach noch nicht gefunden habe &#8211; hier ist jedenfalls meine.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die L\u00f6sung<\/h2>\n\n\n\n<p>Das konkrete Spielprinzip dreht sich darum, Pflanzen auf einer Fensterbank vor einem Fenster zu platzieren. Meine bespielbare Fl\u00e4che ist also nur ein Fenster, alles andere ist Hintergrund.<\/p>\n\n\n\n<figure class=\"wp-block-gallery alignwide columns-2 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-1024x1024.png\" alt=\"\" data-id=\"252\" data-full-url=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1.png\" data-link=\"https:\/\/erdbeerbeet.com\/?attachment_id=252\" class=\"wp-image-252\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-1024x1024.png 1024w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-300x300.png 300w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-150x150.png 150w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-768x768.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1-1536x1536.png 1536w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgsketch-1.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"blocks-gallery-item__caption\">Die Skizze meines Spiel-Hintergrunds<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-1024x1024.png\" alt=\"\" data-id=\"254\" data-full-url=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1.png\" data-link=\"https:\/\/erdbeerbeet.com\/?attachment_id=254\" class=\"wp-image-254\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-1024x1024.png 1024w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-300x300.png 300w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-150x150.png 150w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-768x768.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1-1536x1536.png 1536w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/bgdebug-1.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"blocks-gallery-item__caption\">F\u00fcr einfache Berechnungen werden die Seiten gedrittelt<\/figcaption><\/figure><\/li><\/ul><\/figure>\n\n\n\n<p>Ich m\u00f6chte das Hintergrundbild so anpassen, dass der zentrale Quadrat immer in den Screen passt. Zus\u00e4tzlich etwas Hintergrund an den Seiten, je nach Gr\u00f6\u00dfe und Modus des Screens.<\/p>\n\n\n\n<p>Au\u00dferdem definiere ich hier ein gameRect, das von Screen und Bildgr\u00f6\u00dfe abh\u00e4ngt und die einzige Instanz ist, die ich f\u00fcr weitere Handhabung von Spiel-Elementen nutze. Alles innerhalb des zentralen Quadrats.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das Programmieren<\/h2>\n\n\n\n<p>Da wir uns in der Flame-Logik bewegen, findet alles innerhalb einer game Komponente statt. Ich werde all die anderen Klassen auslassen und mich nur auf Gr\u00f6\u00dfe, Position und Resize des Hintergrundes konzentrieren.<\/p>\n\n\n\n<p><strong>mygame.dart <\/strong>erstellt eine neue Garten-Komponente und ruft die eigene resize Methode auf, um die Bildgr\u00f6\u00dfe entsprechend der Spielgr\u00f6\u00dfe zu berechnen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class MyGame extends BaseGame {\n\nGarden garden;\n  @override\n  Future&lt;void&gt; onLoad() async {\n    garden = new Garden(this);\n    garden.resize(this.size);\n  }\n\n  @override\n  void render(Canvas canvas) {\n    if(garden != null) garden.render(canvas);\n  }\n\n  @override\n  void onResize(Vector2 canvasSize) {\n    super.onResize(canvasSize);\n    if (canvasSize != null &amp;&amp; garden != null) garden.resize(canvasSize);\n  }\n}<\/code><\/pre>\n\n\n\n<p>In meinem Falle ist <strong>garden.dart<\/strong> eine Super-Klasse f\u00fcr verschiedene G\u00e4rten, die sich sehr \u00e4hnlich verhalten. Die wichtigste Information ist das gameRect, das f\u00fcr weitere Berechnungen der Spiele-Komponenten genutzt wird (was nicht in diesem Blog-Beitrag enthalten ist).<\/p>\n\n\n\n<p>Zun\u00e4chst \u00fcberpr\u00fcfen wir, ob der Screen breiter oder h\u00f6her ist (Landschaft oder Portr\u00e4t). Die kleinere Gr\u00f6\u00dfe entspricht dann der Seitenl\u00e4nge unseres zentralen Quadrats im Hintergrundbild. Die scaleValue wird ben\u00f6tigt, damit das Hintergrundbild an den Screen angepasst wird, unabh\u00e4ngig von der jeweiligen Aufl\u00f6sung.<\/p>\n\n\n\n<p>Beim rendern muss das \u00dcberbleibsel der gr\u00f6\u00dferen Screen-Seite in die Berechnung der Hintergrund-Position einbezogen werden, damit wir mehr Hintergrund anzeigen und trotzdem alles zentriert behalten.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Garden {\n  final MyGame game;\n  Sprite _bgSprite;\n  Image bgImage;\n  double gameBaseSize;\n  Rect gameRect;\n  double scaleValue = 1;\n\n  Garden(this.game);\n\n  Future&lt;void&gt; onLoad() async {\n    _bgSprite = Sprite(bgImage);\n  }\n\n  Future&lt;void&gt; resize(Vector2 canvasSize) async {\n    if (game.hasLayout &amp;&amp; _bgSprite != null) {\n      gameBaseSize = min(canvasSize.x, canvasSize.y);\n      scaleValue = gameBaseSize \/ (_bgSprite.srcSize&#91;0] \/ 3);\n\n      gameRect = Rect.fromCenter(\n          center: Offset(\n            canvasSize.x \/ 2 \/ scaleValue,\n            canvasSize.y \/ 2 \/ scaleValue,\n          ),\n          width: gameBaseSize \/ scaleValue,\n          height: gameBaseSize \/ scaleValue\n      );\n    }\n    return;\n  }\n\n  void render(Canvas c) {\n    c.scale(scaleValue);\n\n    if(_bgSprite != null) {\n      Vector2 bgOffset = Vector2(\n        _bgSprite.srcPosition.x - (_bgSprite.image.width \/ 3) + (game.size&#91;0] - gameBaseSize) \/ 2,\n        _bgSprite.srcPosition.y - (_bgSprite.image.height \/ 3) + (game.size&#91;1] - gameBaseSize) \/ 2,\n      );\n      _bgSprite.render(\n          c,\n          position: bgOffset\n      );\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Eine Subklasse von garden ist <strong>ledgegarden.dart<\/strong>. Der wichtigste Teil ist, dass wir abwarten m\u00fcssen, bis super.resize beendet wurde, um mit dem neu berechneten gameRect weiter arbeiten zu k\u00f6nnen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class LedgeGarden extends Garden {\n  LedgeGarden(game) : super(game) {\n    onLoad();<span data-mce-type=\"bookmark\" id=\"mce_1_start\" data-mce-style=\"overflow:hidden;line-height:0px\" style=\"overflow:hidden;line-height:0px\">\n  }\n\n  @override\n  Future&lt;void&gt; onLoad() async {\n    bgImage = await Flame.images.load('backgrounds\/bgdebug.png');\n    super.onLoad();\n  }\n\n  @override\n  Future&lt;void&gt; resize(Vector2 canvasSize) async {\n    await super.resize(canvasSize).then((value) {\n      if (game.hasLayout &amp;&amp; gameRect != null) {\n        \/\/ calculate placement of further components\n     }\n\n    return;\n  }\n}<\/span><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Das Ergebnis<\/h2>\n\n\n\n<p>Ich muss sagen, dass es sehr fluffig funktioniert. Und der n\u00f6tige Code ist auch nicht sonderlich umfangreich. Ich habe mit der Flutter-Webversion herum gespielt und kann es nun kaum abwarten, die anderen Komponenten meinem Spiel hinzu zu f\u00fcgen.<\/p>\n\n\n\n<figure class=\"wp-block-gallery columns-2 wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"171\" height=\"300\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53-171x300.png\" alt=\"\" data-id=\"255\" data-full-url=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53.png\" data-link=\"https:\/\/erdbeerbeet.com\/?attachment_id=255\" class=\"wp-image-255\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53-171x300.png 171w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53-583x1024.png 583w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53-768x1348.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53-875x1536.png 875w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.30.53.png 1030w\" sizes=\"auto, (max-width: 171px) 100vw, 171px\" \/><figcaption class=\"blocks-gallery-item__caption\">Portr\u00e4t Modus<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-300x200.png\" alt=\"\" data-id=\"256\" data-full-url=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12.png\" data-link=\"https:\/\/erdbeerbeet.com\/?attachment_id=256\" class=\"wp-image-256\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-300x200.png 300w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-1024x684.png 1024w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-768x513.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-1536x1026.png 1536w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.12-2048x1368.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><figcaption class=\"blocks-gallery-item__caption\">Landschafts Modus<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"122\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-300x122.png\" alt=\"\" data-id=\"257\" data-full-url=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58.png\" data-link=\"https:\/\/erdbeerbeet.com\/?attachment_id=257\" class=\"wp-image-257\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-300x122.png 300w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-1024x418.png 1024w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-768x313.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-1536x627.png 1536w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2021\/05\/Bildschirmfoto-2021-05-06-um-16.31.58-2048x836.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><figcaption class=\"blocks-gallery-item__caption\">Sehr extremer Landschafts Modus<\/figcaption><\/figure><\/li><\/ul><\/figure>\n\n\n\n<p>Im moment ist die L\u00f6sung noch nicht ideal f\u00fcr gro\u00dfe Screens, wo wir neben dem zentralen Quadrat noch genug Platz f\u00fcr schm\u00fcckenden Hintergrund h\u00e4tten. Das das bleibt vorerst ein sekund\u00e4res Problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich m\u00f6chte, dass mein Spiel im Portr\u00e4t- UND Landschafts-Modus spielbar ist. Und so hab ich das angestellt.<\/p>\n","protected":false},"author":1,"featured_media":384,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,13,50,12],"tags":[27,14,28],"class_list":["post-250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-flame","category-flutter","category-grow_greens","category-programming","tag-flame","tag-flutter","tag-grow-greens"],"translation":{"provider":"WPGlobus","version":"3.0.0","language":"de","enabled_languages":["en","de"],"languages":{"en":{"title":true,"content":true,"excerpt":true},"de":{"title":true,"content":true,"excerpt":true}}},"_links":{"self":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/comments?post=250"}],"version-history":[{"count":6,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":264,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/250\/revisions\/264"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/media\/384"}],"wp:attachment":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}