diff options
author | David Luevano Alvarado <david@luevano.xyz> | 2023-08-27 18:38:10 -0600 |
---|---|---|
committer | David Luevano Alvarado <david@luevano.xyz> | 2023-08-27 18:38:10 -0600 |
commit | 06184c13af639917e1af5a1bc298b0022c1398ea (patch) | |
tree | c725aac7f7fc72613c518d59756137834f7894e9 | |
parent | 6629c2c9830cf1c6b0e18e8acdd15dc986e78f3a (diff) |
build site with new godot entry
-rw-r--r-- | db/db_blog.psv | 3 | ||||
-rw-r--r-- | live/blog/a/pastebin_alt_with_privatebin.html | 6 | ||||
-rw-r--r-- | live/blog/g/flappybird_godot_devlog_1.html | 9 | ||||
-rw-r--r-- | live/blog/g/flappybird_godot_devlog_2.html | 340 | ||||
-rw-r--r-- | live/blog/index.html | 1 | ||||
-rw-r--r-- | live/blog/rss.xml | 204 | ||||
-rw-r--r-- | live/blog/sitemap.xml | 8 | ||||
-rw-r--r-- | live/blog/tag/@english.html | 1 | ||||
-rw-r--r-- | live/blog/tag/@gamedev.html | 4 | ||||
-rw-r--r-- | live/blog/tag/@gdscript.html | 4 | ||||
-rw-r--r-- | live/blog/tag/@godot.html | 4 | ||||
-rw-r--r-- | src/blog/g/flappybird_godot_devlog_2.md (renamed from src/blog/temp/flappybird_godot_devlog_2.md) | 4 |
12 files changed, 575 insertions, 13 deletions
diff --git a/db/db_blog.psv b/db/db_blog.psv index 63aa466..cd255e5 100644 --- a/db/db_blog.psv +++ b/db/db_blog.psv @@ -15,7 +15,7 @@ a/devs_android_me_trozaron.md|1652608264.4901433|1652609027.0201497|41c897ac0c6e a/password_manager_authenticator_setup.md|1652654434.4686146|1683172189.1237748|ee21642502116ac50d2ef437e69b306c|english,short,tools
g/starting_gamedev_blogging.md|1652764794.9016073|1683275869.3270695|dad847b856598f6c6eab2f7ec94efac9|english,gamedev,godot,short,update
g/godot_project_structure.md|1653182170.4395845|1683275847.2870727|8b04f0ba5c8afb92d19c1898f4f9186b|english,gamedev,godot,short
-g/flappybird_godot_devlog_1.md|1653795523.5988536|1683620894.9660125|e6b798f0be638f29c242195bd75b797c|english,gamedev,gdscript,godot
+g/flappybird_godot_devlog_1.md|1653795523.5988536|1693025139.62647|09fece4c350f4eb1575d12dc60c5b52a|english,gamedev,gdscript,godot
g/gogodot_jam3_devlog_1.md|1654852625.58801|1683219939.7152278|89b18f87b523d721bdf8b7fd752e47a6|english,gamedev,gamejam,gdscript,godot
a/rewrote_pyssg_again.md|1671510665.5266156|1683375981.802067|e7d3dc8a4a2cd2abda2f653c9cbd3049|english,short,tools,update
a/updated_pyssg_pymdvar_and_website.md|1683376754.7018104|0.0|442ad5da7342439101abcc076a73cb22|english,short,tools,update
@@ -27,3 +27,4 @@ a/arch_logs_flooding_disk.md|1686824540.5338242|1686824666.933781|261eeee98ecbb2 a/torrenting_with_qbittorrent.md|1690164384.3800702|1690170668.4089742|413b7f2764a40fea97f2a22a942ff305|code,english,server,tools,tutorial
a/jellyfin_server_with_sonarr_radarr.md|1690173014.2185652|1690173137.3785434|831c3b7c4183648dbc3be4547fe50686|code,english,server,tools,tutorial
a/pastebin_alt_with_privatebin.md|1692524793.86829|1692527331.9501805|7605e02fc2b613617be56fdf43471664|code,english,server,tools,tutorial
+g/flappybird_godot_devlog_2.md|1693178890.8924305|1693183054.9629443|f4e75adc747b9bf150a7126667185039|english,gamedev,gdscript,godot
diff --git a/live/blog/a/pastebin_alt_with_privatebin.html b/live/blog/a/pastebin_alt_with_privatebin.html index 85f05cf..ef62906 100644 --- a/live/blog/a/pastebin_alt_with_privatebin.html +++ b/live/blog/a/pastebin_alt_with_privatebin.html @@ -333,6 +333,12 @@ opt[12] = true ; PDO::ATTR_PERSISTENT </code></pre> <div class="page-nav"> + <span class="next"> + <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html" alt="Next"> + <i class="fas fa-arrow-left" alt="Arrow left"></i> + <span>Next</span> + </a> + </span> <span class="index"> <a href="https://blog.luevano.xyz" alt="Index"> diff --git a/live/blog/g/flappybird_godot_devlog_1.html b/live/blog/g/flappybird_godot_devlog_1.html index 616d75c..8b85c23 100644 --- a/live/blog/g/flappybird_godot_devlog_1.html +++ b/live/blog/g/flappybird_godot_devlog_1.html @@ -7,7 +7,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="https://static.luevano.xyz/images/icons/favicon.ico"> <title>Creating a FlappyBird clone in Godot 3.5 devlog 1 -- Luévano's Blog</title> - <meta name="description" content="Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to keep consistent. This shows as "devlog 1" just in case I want to include more parts for extra stuff."/> + <meta name="description" content="Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to stay consistent."/> <link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS"> <!-- general style --> <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/style.css"> @@ -37,7 +37,7 @@ <meta property="og:type" content="article"/> <meta property="og:url" content="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.md"/> <meta property="og:image" content="https://static.luevano.xyz/images/b/default.png"/> - <meta property="og:description" content="Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to keep consistent. This shows as "devlog 1" just in case I want to include more parts for extra stuff."/> + <meta property="og:description" content="Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to stay consistent."/> <meta property="og:locale" content="en"/> <meta property="og:site_name" content="Luévano's Blog"/> </head> @@ -96,9 +96,10 @@ <li>If you touch the pipes, the ground or go past the “ceiling” you lose.</li> </ul> <p>The game was originally developed with <em>Godot 4.0 alpha 8</em>, but it didn’t support HTML5 (webassembly) export… so I backported to <em>Godot 3.5 rc1</em>.</p> +<p><ins><mark>Note:</mark> I’ve updated the game to <em>Godot 4</em> and documented it on my <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">FlappyBird devlog 2</a> entry.</ins></p> <p>Not going to specify all the details, only the needed parts and what could be confusing, as the source code is available and can be inspected; also this assumes minimal knowledge of <em>Godot</em> in general. Usually when I mention that a set/change of something it usually it’s a property and it can be found under the <em>Inspector</em> on the relevant node, unless stated otherwise; also, all scripts attached have the same name as the scenes, but in <em>snake_case</em> (scenes/nodes in <em>PascalCase</em>).</p> <p>One thing to note, is that I started writing this when I finished the game, so it’s hard to go part by part, and it will be hard to test individual parts when going through this as everything is depending on each other. For the next devlog, I’ll do it as I go and it will include all the changes to the nodes/scripts as I was finding them, probably better idea and easier to follow.</p> -<p>The source code can be found at <a href="https://github.com/luevano/flappybird_godot/tree/godot-3.5">luevano/flappybird_godot#godot-3.5</a>, it also contains the exported versions for HTML5, Windows and Linux (be aware that the sound might be too high and I’m too lazy to make it configurable, it was the last thing I added), or you could also go to the <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a> page I setup where it’s playable in the browser:</p> +<p>The source code can be found at <a href="https://github.com/luevano/flappybirdgodot/tree/godot-3.5">luevano/flappybirdgodot#godot-3.5</a> (<code>godot-3.5</code> branch), it also contains the exported versions for HTML5, Windows and Linux (<del>be aware that the sound might be too high and I’m too lazy to make it configurable, it was the last thing I added</del> <ins>on the latest version this is fixed and audio level is configurable now</ins>). Playable on <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a> (<em>Godot 4</em> version):</p> <p style="text-align:center"><iframe src="https://itch.io/embed/1551015?dark=true" width="208" height="167" frameborder="0"><a href="https://lorentzeus.itch.io/flappybirdgodot">FlappyBirdGodot by Lorentzeus</a></iframe></p> <h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2> @@ -750,7 +751,7 @@ func _ready() -> void: <div class="article-info"> <p>By David Luévano</p> <p>Created: Sun, May 29, 2022 @ 03:38 UTC</p> - <p>Modified: Tue, May 09, 2023 @ 08:28 UTC</p> + <p>Modified: Sat, Aug 26, 2023 @ 04:45 UTC</p> <div class="article-tags"> <p>Tags: <a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@gamedev.html">gamedev</a>, <a href="https://blog.luevano.xyz/tag/@gdscript.html">gdscript</a>, <a href="https://blog.luevano.xyz/tag/@godot.html">godot</a> </p> diff --git a/live/blog/g/flappybird_godot_devlog_2.html b/live/blog/g/flappybird_godot_devlog_2.html new file mode 100644 index 0000000..b7a5047 --- /dev/null +++ b/live/blog/g/flappybird_godot_devlog_2.html @@ -0,0 +1,340 @@ +<!DOCTYPE html> +<html class="theme-dark" lang="en +" + prefix="og: https://ogp.me/ns#"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="icon" href="https://static.luevano.xyz/images/icons/favicon.ico"> +<title>Porting the FlappyBird clone to Godot 4.1 devlog 2 -- Luévano's Blog</title> + <meta name="description" content="Notes on porting my FlappyBird clone to Godot 4.1, as well as notes on the improvements and changes made overall."/> +<link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS"> + <!-- general style --> + <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/style.css"> + <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/fork-awesome/css/fork-awesome.min.css"> + <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/font-awesome/css/all.min.css"> + <!-- theme related --> + <script type="text/javascript" src="https://static.luevano.xyz/scripts/theme.js"></script> + <link id="theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/theme.css"> + <!-- misc functions--> + <script type="text/javascript" src="https://static.luevano.xyz/scripts/return_top.js"></script> + <!-- extra --> + + + <!-- highlight support for code blocks --> +<script type="text/javascript" src="https://static.luevano.xyz/hl/highlight.min.js"></script> +<script type="text/javascript"> + hljs.initHighlightingOnLoad(); +</script> +<link id="code-theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/hl/styles/nord.min.css"> + + + <!-- Specific to GDScript --> + <script type="text/javascript" src="https://static.luevano.xyz/hl/languages/gdscript.min.js"></script> + + <!-- og meta --> + <meta property="og:title" content="Porting the FlappyBird clone to Godot 4.1 devlog 2 -- Luévano's Blog"/> + <meta property="og:type" content="article"/> + <meta property="og:url" content="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.md"/> + <meta property="og:image" content="https://static.luevano.xyz/images/b/default.png"/> + <meta property="og:description" content="Notes on porting my FlappyBird clone to Godot 4.1, as well as notes on the improvements and changes made overall."/> + <meta property="og:locale" content="en"/> + <meta property="og:site_name" content="Luévano's Blog"/> + </head> + + <body> + <header> +<nav> + <ul> + <li> + <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a> + </li> + + <li> + <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a> + </li> + + <li> + <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a> + </li> + + <li><i class="fab fa-git" alt="Git"></i><span>Git</span> + <ul> + <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li> + + <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li> + + <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li> + </ul> + </li> + + <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span> + <ul> + <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li> + </ul> + </li> + </ul> +</nav> + +<button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button> + + </header> + + <main> + <div class="return-top"> + <button class="return-top" onclick="returnTop()" id="returnTopButton"> + <i class="fas fa-arrow-up" alt="Return to top"></i> + </button> + </div> + <h1>Porting the FlappyBird clone to Godot 4.1 devlog 2</h1> + + <p>As stated in my <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html">FlappyBird devlog 1</a> entry I originally started the clone in <em>Godot 4</em>, then backported back to <em>Godot 3</em> because of HTML5 support, and now I’m porting it back again to <em>Godot 4</em> as there is support again and I want to start getting familiar with it for future projects.</p> +<p>The source code can be found at <a href="https://github.com/luevano/flappybirdgodot">luevano/flappybirdgodot</a> (<code>main</code> branch). Playable at <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a>:</p> +<p style="text-align:center"><iframe src="https://itch.io/embed/1551015?dark=true" width="208" height="167" frameborder="0"><a href="https://lorentzeus.itch.io/flappybirdgodot">FlappyBirdGodot by Lorentzeus</a></iframe></p> + +<h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2> +<div class="toc"> +<ul> +<li><a href="#table-of-contents">Table of contents</a></li> +<li><a href="#porting-to-godot-4">Porting to Godot 4</a><ul> +<li><a href="#general-changes">General changes</a></li> +<li><a href="#player">Player</a></li> +<li><a href="#world">World</a><ul> +<li><a href="#scene">Scene</a></li> +<li><a href="#script">Script</a></li> +</ul> +</li> +</ul> +</li> +<li><a href="#changes-and-improvements">Changes and improvements</a><ul> +<li><a href="#audio">Audio</a></li> +<li><a href="#event-bus">Event bus</a></li> +<li><a href="#ui">UI</a></li> +<li><a href="#misc">Misc</a></li> +</ul> +</li> +</ul> +</div> +<h2 id="porting-to-godot-4">Porting to Godot 4<a class="headerlink" href="#porting-to-godot-4" title="Permanent link">¶</a></h2> +<p><strong>Disclaimer:</strong> I started the port back in <em>Godot 4.0</em> something and left the project for a while, then opened the project again in <em>Godot 4.1</em>, and it didn’t ask to convert anything so probably nowadays the conversion is better.</p> +<h3 id="general-changes">General changes<a class="headerlink" href="#general-changes" title="Permanent link">¶</a></h3> +<p>These include the first changes for fixing some of the conflicting code to at least make it run (no gameplay) as well as project settings adjustments.</p> +<ul> +<li>Changing the <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#default-import-settings">default import settings</a> for pixel art no longer works (though it’s worth to double check as they changed from <code>Texture</code> to a <code>Texture2D</code>). The important parameter to <a href="https://ask.godotengine.org/122518/how-to-import-pixel-art-in-godot-4">change is the <em>Filter</em> for the textures</a>.<ul> +<li>Since all nodes inherit parameters by default, changing on the parent nodes (or just once in the root such as <code>Main.tscn</code>) will suffice: Go to <em>Inspector -> CanvasItem -> Texture</em> and change <em>Filter</em> from “Inherit” to “Nearest”.</li> +</ul> +</li> +<li>Re-set the <em>InputMap</em> as the system probably changed from <em>Godot 3</em> to <em>Godot 4</em>.</li> +<li>For <code>SavedData</code> singleton, change from <code>File</code> to <code>ConfigFile</code> and refactor. This is really not needed for making it run, but I changed this right away.</li> +<li>Remove <code>velocity</code> property of <code>Player</code> which is already included in <code>CharacterBody2D</code>.</li> +<li>Disable all <code>TileMap</code> related code as tile maps have changed drastically, they need more effort to covnert.</li> +<li>Change <code>String(int)</code> to <code>str(int)</code>.</li> +</ul> +<h3 id="player">Player<a class="headerlink" href="#player" title="Permanent link">¶</a></h3> +<p>Now that the game at least runs, next thing is to make it “playable”:</p> +<ul> +<li><code>AnimatedSprite</code> changed to <code>AnimatedSprite2D</code> (with the inclusion of <code>AnimatedSprite3D</code>). This node type changed with the automatic conversion.<ul> +<li>Instead of checking if an animation is playing with the the <code>playing</code> property, the method <code>is_playing()</code> needs to be used.</li> +</ul> +</li> +<li>The <code>default_gravity</code> from the <code>ProjectSettings</code> no longer needs to be multiplied by <code>10</code> to have reasonable numbers. The default is now <code>980</code> instead of <code>98</code>. I later changed this when refactoring the code and fine-tuning the feel of the movement.</li> +<li>The <em>Collision mask</em> can be changed programatically with the <code>set_collision_mask_value</code> (and similar with the layer). Before, the mask/layer was specified by the <code>bit</code> which started from <code>0</code>, but now it is accessed by the <code>layer_number</code> which starts from <code>1</code>.</li> +</ul> +<h3 id="world">World<a class="headerlink" href="#world" title="Permanent link">¶</a></h3> +<p>This is the most challenging part as the <code>TileMap</code> system changed drastically, it is basically a <em>from the ground up redesign</em>, luckily the <code>TileMap</code>s I use are really simple. Since this is not intuitive from the get-go, I took some notes on the steps I took to set up the world <code>TileMap</code>.</p> +<h4 id="scene">Scene<a class="headerlink" href="#scene" title="Permanent link">¶</a></h4> +<p>Instead of using one scene per <code>TileMap</code> only one <code>TileMap</code> can be used with multiple <em>Atlas</em> in the <code>TileSet</code>. Multiple physics layers can now be used per <code>TileSet</code> so you can separate the physics collisions on a per <em>Atlas</em> or <em>Tile</em> basis. The inclusion of <em>Tile patterns</em> also helps when working with multiple <em>Tiles</em> for a single cell “placement”. How I did it:</p> +<ol> +<li>Created one scene with one <code>TileMap</code> node, called <code>WorldTileMap.tscn</code>, with only one <code>TileSet</code> as multiple <em>Atlas</em>‘ can be used (this would be a single <code>TileSet</code> in <em>Godot 3</em>).<ul> +<li>To add a <code>TileSet</code>, select the <code>WorldTileMap</code> and go to <em>Inspector -> TileMap -> TileSet</em> then click on “<empty>” and then “New TileSet” button.</li> +<li>To manipulate a <code>TileSet</code>, it needs to be selected, either by clicking in the <em>Inspector</em> section or on the bottom of the screen (by default) to the left of <em>TileMap</em>, as shown in the image below.</li> +</ul> +</li> +</ol> +<figure id="__yafg-figure-48"> +<img alt="TileMap's TileSet selection highlighted in red, "Add" button in green." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_selected_add_atlas.png.png "TileMap's TileSet selection highlighted in red, "Add" button in green"."> +<figcaption></figcaption> +</figure> +<ol start="2"> +<li>Add two <em>Atlas</em> to the <code>TileSet</code> (one for the ground tiles and another for the pipes) by clicking on the “Add” button (as shown in the image above) and then on “Atlas”.</li> +<li>By selecting an atlas and having the “Setup” selected, change the <em>Name</em> to something recognizable like <code>ground</code> and add the texture atlas (the spritesheet) by dragging and dropping in the “<empty>” <em>Texture</em> field, as shown in the image below. Take a not of the <em>ID</em>, they start from <code>0</code> and increment for each atlas, but if they’re not <code>0</code> and <code>1</code> change them.</li> +</ol> +<figure id="__yafg-figure-49"> +<img alt="TileSet atlas setup selection highlighted in red, atlas name and id in green." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_setup_selection.png" title="TileSet atlas setup selection highlighted in red, atlas name and id in green."> +<figcaption>TileSet atlas setup selection highlighted in red, atlas name and id in green.</figcaption> +</figure> +<ol start="4"> +<li>I also like to delete unnecessary tiles (for now) by selecting the atlas “Setup” and the “Eraser” tool, as shown in the image below. Then to erase tiles just select them and they’ll be highlighted in black, once deleted they will be grayed out. If you want to activate tiles again just deselect the “Eraser” tool and select wanted tiles.</li> +</ol> +<figure id="__yafg-figure-50"> +<img alt="Atlas setup erase tiles. "Setup" selection and "Eraser" tool highlighted in red and green, respectively." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_setup_selection.png" title="Atlas setup erase tiles. "Setup" selection and "Eraser" tool highlighted in red and green, respectively."> +<figcaption>Atlas setup erase tiles. “Setup” selection and “Eraser” tool highlighted in red and green, respectively.</figcaption> +</figure> +<ol start="5"> +<li>For the pipes it is a good idea to modify the “tile width” for horizontal <code>1x2</code> tiles. This can be acomplished by removing all tiles except for one, then going to the “Select” section of the atlas, selecting a tile and extending it either graphically by using the yellow circles or by using the properties, as shown in the image below.</li> +</ol> +<figure id="__yafg-figure-51"> +<img alt="Atlas resize tile. "Select" selection and "Size in Atlas" highlighted in red and green, respectively." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_pipe_wide.png" title="Atlas resize tile. "Select" selection and "Size in Atlas" highlighted in red and green, respectively."> +<figcaption>Atlas resize tile. “Select” selection and “Size in Atlas” highlighted in red and green, respectively.</figcaption> +</figure> +<ol start="6"> +<li>Add physics (collisions) by selecting the <code>WorldTileMap</code>‘s <code>TileSet</code> and clicking on “Add Element” at the <em>TileMap -> TileSet -> Physics Layer</em> twice, one physics layer per atlas. Then set the collision’s layers and masks accordingly (ground on layer 2, pipe on 3). In my case, based on my already set <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#layers">layers</a>.<ul> +<li>This will enable physics properties on the tiles when selecting them (by selecting the atlas, being in the correct “Select” section and selecting a tile) and start drawing a polygon with the tools provided. This part is hard to explain in text, but below is an image of how it looks once the polygon is set.</li> +</ul> +</li> +</ol> +<figure id="__yafg-figure-52"> +<img alt="Tile add physics polygon in Physics Layer 0." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_selected_add_atlas.png" title="Tile add physics polygon on physics layer 0."> +<figcaption>Tile add physics polygon on physics layer 0.</figcaption> +</figure> +<pre><code>- Notice that the polygon is drawn in *Physics Layer 0*. Using the grid option to either `1` or `2` is useful when drawing the polygon, make sure the polygon closes itself or it wont be drawn. +</code></pre> +<ol start="8"> +<li>Create a tile pattern by drawing the tiles wanted in the editor and then going to the <em>Patterns</em> tab (to the right of <em>Tiles</em>) in the <em>TileMap</em>, selecting all tiles wanted in the pattern and dragging the tiles to the <em>Patterns</em> window. Added patterns will show in this window as shown in the image below, and assigned with IDs starting from <code>0</code>.</li> +</ol> +<figure id="__yafg-figure-53"> +<img alt="Tileset pattern." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_pattern.png" title="Tileset pattern."> +<figcaption>Tileset pattern.</figcaption> +</figure> +<h4 id="script">Script<a class="headerlink" href="#script" title="Permanent link">¶</a></h4> +<p>Basically merged all 3 scripts (<code>ground_tile_map.gd</code>, <code>pipe_tile_map.gd</code> and <code>world_tiles.gd</code>) into one (<code>world_tile_map.gd</code>) and immediatly was able to delete a lot of signal calls between those 3 scripts and redundant code.</p> +<p>The biggest change in the scripting side are the functions to place tiles. For <em>Godot 3</em>:</p> +<pre><code class="language-gdscript"># place single tile in specific cell +void set_cell(x: int, y: int, tile: int, flip_x: bool = false, flip_y: bool = false, transpose: bool = false, autotile_coord: Vector2 = Vector2( 0, 0 )) +void set_cellv(position: Vector2, tile: int, flip_x: bool = false, flip_y: bool = false, transpose: bool = false, autotile_coord: Vector2 = Vector2( 0, 0 )) +</code></pre> +<p>Whereas in <em>Godot 4</em>:</p> +<pre><code class="language-gdscript"># place single tile in specific cell +void set_cell(layer: int, coords: Vector2i, source_id: int = -1, atlas_coords: Vector2i = Vector2i(-1, -1), alternative_tile: int = 0) +# erase tile at specific cell +void erase_cell(layer: int, coords: Vector2i) +</code></pre> +<p>How to use these functions in <em>Godot 4</em> (new properties or differences/changes):</p> +<ul> +<li><code>layer</code>: for my case I only use 1 layer so it is always set to <code>0</code>.</li> +<li><code>coords</code>: would be the equivalent to <code>position</code> for <code>set_cellv</code> in <em>Godot 3</em>.</li> +<li><code>source_id</code>: which atlas to use (ground: <code>0</code> or pipe <code>1</code>).</li> +<li><code>atlas_coords</code>: tile to use in the atlas. This would be the equivalent to <code>tile</code> in <em>Godot 3</em>.</li> +<li><code>alternative_tile</code>: for tiles that have alternatives such as mirrored or rotated tiles, not required in my case.</li> +</ul> +<p>Setting <code>source_id=-1</code>, <code>atlas_coords=Vector21(-1,-1)</code> or <code>alternative_tile=-1</code> will delete the tile at <code>coords</code>, similar to just using <code>erase_cell</code>.</p> +<p>With the addition to <em>Tile patterns</em> (to place multiple tiles), there is a new function:</p> +<pre><code class="language-gdscript"># place pattern +void set_pattern(layer: int, position: Vector2i, pattern: TileMapPattern) +</code></pre> +<p>Where <code>position</code> has the same meaning as <code>coords</code> in <code>set_cell</code>/<code>erase_cell</code>, not sure why it has a different name. The <code>pattern</code> can be obtained by using <code>get_pattern</code> method on the <code>tile_set</code> property of the <code>TileMap</code>. Something like:</p> +<pre><code class="language-gdscript">var pattern: TileMapPattern = tile_set.get_pattern(index) +</code></pre> +<p>Other than that, <code>Vector2</code> needs to be changed to <code>Vector2i</code>.</p> +<h2 id="changes-and-improvements">Changes and improvements<a class="headerlink" href="#changes-and-improvements" title="Permanent link">¶</a></h2> +<p>General changes and additions that have nothing to do with porting to <em>Godot 4</em>, things I wanted to add regardless of the version.</p> +<h3 id="audio">Audio<a class="headerlink" href="#audio" title="Permanent link">¶</a></h3> +<p>The audio in the <em>Godot 3</em> version was added in the last minute and it was blasting by default with no option to decrease the volume or mute it. To deal with this:</p> +<ol> +<li>Refactored the code into a single scene/script to have better control.</li> +<li>Added a volume control slider by following <a href="https://www.gdquest.com/tutorial/godot/audio/volume-slider/">this GDQuest guide</a>.</li> +<li>Added a mute button, following the same principle as with the volume control.</li> +</ol> +<p>The basic code required for these features is the following:</p> +<pre><code class="language-gdscript"># get audio bus index +var audio_bus_name: String = "Master" +var _bus: int = AudioServer.get_bus_index(audio_bus_name) + +# change the volume +var linear_volume: float = 0.5 # 50%, needs to be between 0.0 and 1.0 +var db_volume: float = linear_to_db(linear_volume) +AudioServer.set_bus_volume_db(_bus, db_volume) + +# mute +AudioServer.set_bus_mute(_bus, true) # false to unmute +</code></pre> +<p>Just be careful with how the <code>linear_volume</code> is set (from a button or slider) as it has to be between <code>0.0</code> and <code>1.0</code>.</p> +<h3 id="event-bus">Event bus<a class="headerlink" href="#event-bus" title="Permanent link">¶</a></h3> +<p>Moved all the signal logic into an event bus to get rid of the coupling I had. This is accomplished by:</p> +<ol> +<li>Creating a singleton (autoload) script which I called <code>event.gd</code> and can be accessed with <code>Event</code>.</li> +<li>All the signals are now defined in <code>event.gd</code>.</li> +<li>When a signal needs to be emited instead of emitting the signal from any particular script, emit it from the event bus with <code>Event.<signal_name>.emit(<optional_args>)</code>.</li> +<li>When connecting to a signal instead of taking a reference to where the signal is defined, simply connect it with with <code>Event.<signal_name>.connect(<callable>[.bind(<optional_args>)])</code><ul> +<li>For signals that already send arguments to the callable, they do not need to be specified in <code>bind</code>, only extras are needed here.</li> +</ul> +</li> +</ol> +<h3 id="ui">UI<a class="headerlink" href="#ui" title="Permanent link">¶</a></h3> +<p>Really the only UI I had before was for rendering fonts, and the way fonts work changed a bit. Before, 3 resources were needed as <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#fonts">noted in my previous entry</a>:</p> +<ol> +<li>Font file itself (<code>.ttf</code> for example).</li> +<li><code>DynamicFontData</code>: used to point to a font file (<code>.ttf</code>) and then used as base resource.</li> +<li><code>DynamicFont</code>: usable in godot control nodes which holds the <code>DynamicFontData</code> and configuration such as size.</li> +</ol> +<p>Now only 1 resource is needed: <code>FontFile</code> which is the <code>.ttf</code> file itself or a godot-created resource. There is also a <code>FontVariation</code> option, which takes a <code>FontFile</code> and looks like its used to create fallback options for fonts. The configuration (such as size) is no longer held in the font resource, but rather in the parent control node (like a <code>Label</code>). Double clicking on the <code>.ttf</code> file and disabling antialiasing and compression is something that might be needed. Optionally create a <code>FontLabelSettings</code> which will hold the <code>.ttf</code> file and used as base for <code>Label</code>s. Use “Make Unique” for different sizes. Another option is to use <em>Themes</em> and <em>Variations</em>.</p> +<p>I also created the respective volume button and slider UI for the added audio functionality as well as creating a base <code>Label</code> to avoid repeating configuration on each <code>Label</code> node.</p> +<h3 id="misc">Misc<a class="headerlink" href="#misc" title="Permanent link">¶</a></h3> +<p>Small changes that don’t affect much:</p> +<ul> +<li>Updated <code>@export</code> to <code>@export_range</code>. The auto conversion didn’t use the correct annotation and instead used a comment.</li> +<li>Refactored the <code>game_scale</code> methodolgy as it was inconsistent. Now only one size is used as base and everything else is just scaled with the <code>root</code> <code>Window</code>.</li> +<li>Got rid of the FPS monitoring, was only using it for debugging purposes back then.</li> +</ul> + + <div class="page-nav"> + + <span class="index"> + <a href="https://blog.luevano.xyz" alt="Index"> + <i class="fas fa-home" alt="Home"></i> + <span>Index</span> + </a> + </span> + + <span class="previous"> + <a href="https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html" alt="Previous"> + <i class="fas fa-arrow-right" alt="Arrow right"></i> + <span>Previous</span> + </a> + </span> +</div> + + + <hr> + <div class="article-info"> + <p>By David Luévano</p> + <p>Created: Sun, Aug 27, 2023 @ 23:28 UTC</p> + <p>Modified: Mon, Aug 28, 2023 @ 00:37 UTC</p> + <div class="article-tags"> + <p>Tags: +<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@gamedev.html">gamedev</a>, <a href="https://blog.luevano.xyz/tag/@gdscript.html">gdscript</a>, <a href="https://blog.luevano.xyz/tag/@godot.html">godot</a> </p> +</div> + + </div> + </main> + + <footer> +<span> + <i class="fas fa-address-card" alt="Contact"></i> + <a href="https://blog.luevano.xyz/contact.html">Contact</a> +</span> + +<span> + <i class="fas fa-donate" alt="Donate"></i> + <a href="https://blog.luevano.xyz/donate.html">Donate</a> +</span> + +<span> + <i class="fas fa-rss" alt="RSS"></i> + <a target="_blank" href="https://blog.luevano.xyz/rss.xml">RSS</a> +</span> + +<br> +<span class="created-with"> + <i class="fas fa-hammer" alt="Hammer"></i> + Created with <a href="https://github.com/luevano/pyssg">pyssg</a> +</span> + +<br> +<span class="copyright"> + Copyright <i class="far fa-copyright" alt="Copyright"></i> 2023 David Luévano Alvarado +</span> + + </footer> + </body> +</html>
\ No newline at end of file diff --git a/live/blog/index.html b/live/blog/index.html index 716c30c..62e68e7 100644 --- a/live/blog/index.html +++ b/live/blog/index.html @@ -88,6 +88,7 @@ <h2>Articles</h2> <ul class="page-list"> <h3>2023</h3> + <li><span class="page-list-item">Aug 27</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">Porting the FlappyBird clone to Godot 4.1 devlog 2</a></li> <li><span class="page-list-item">Aug 20</span> - <a href="https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html">Set up a pastebin alternative with PrivateBin and YOURLS</a></li> <li><span class="page-list-item">Jul 24</span> - <a href="https://blog.luevano.xyz/a/jellyfin_server_with_sonarr_radarr.html">Set up a media server with Jellyfin, Sonarr and Radarr</a></li> <li><span class="page-list-item">Jul 24</span> - <a href="https://blog.luevano.xyz/a/torrenting_with_qbittorrent.html">Set up qBitTorrent with Jackett for use with Starr apps</a></li> diff --git a/live/blog/rss.xml b/live/blog/rss.xml index e068ac4..82a3256 100644 --- a/live/blog/rss.xml +++ b/live/blog/rss.xml @@ -23,6 +23,205 @@ <link>https://blog.luevano.xyz</link> </image> <item> + <title>Porting the FlappyBird clone to Godot 4.1 devlog 2</title> + <link>https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html</link> + <guid isPermaLink="true">https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html</guid> + <pubDate>Sun, 27 Aug 2023 23:28:10 GMT</pubDate> + <category>English</category> + <category>Gamedev</category> + <category>Gdscript</category> + <category>Godot</category> + <description>Notes on porting my FlappyBird clone to Godot 4.1, as well as notes on the improvements and changes made overall.</description> + <content:encoded><![CDATA[<p>As stated in my <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html">FlappyBird devlog 1</a> entry I originally started the clone in <em>Godot 4</em>, then backported back to <em>Godot 3</em> because of HTML5 support, and now I’m porting it back again to <em>Godot 4</em> as there is support again and I want to start getting familiar with it for future projects.</p> +<p>The source code can be found at <a href="https://github.com/luevano/flappybirdgodot">luevano/flappybirdgodot</a> (<code>main</code> branch). Playable at <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a>:</p> +<p style="text-align:center"><iframe src="https://itch.io/embed/1551015?dark=true" width="208" height="167" frameborder="0"><a href="https://lorentzeus.itch.io/flappybirdgodot">FlappyBirdGodot by Lorentzeus</a></iframe></p> + +<h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2> +<div class="toc"> +<ul> +<li><a href="#table-of-contents">Table of contents</a></li> +<li><a href="#porting-to-godot-4">Porting to Godot 4</a><ul> +<li><a href="#general-changes">General changes</a></li> +<li><a href="#player">Player</a></li> +<li><a href="#world">World</a><ul> +<li><a href="#scene">Scene</a></li> +<li><a href="#script">Script</a></li> +</ul> +</li> +</ul> +</li> +<li><a href="#changes-and-improvements">Changes and improvements</a><ul> +<li><a href="#audio">Audio</a></li> +<li><a href="#event-bus">Event bus</a></li> +<li><a href="#ui">UI</a></li> +<li><a href="#misc">Misc</a></li> +</ul> +</li> +</ul> +</div> +<h2 id="porting-to-godot-4">Porting to Godot 4<a class="headerlink" href="#porting-to-godot-4" title="Permanent link">¶</a></h2> +<p><strong>Disclaimer:</strong> I started the port back in <em>Godot 4.0</em> something and left the project for a while, then opened the project again in <em>Godot 4.1</em>, and it didn’t ask to convert anything so probably nowadays the conversion is better.</p> +<h3 id="general-changes">General changes<a class="headerlink" href="#general-changes" title="Permanent link">¶</a></h3> +<p>These include the first changes for fixing some of the conflicting code to at least make it run (no gameplay) as well as project settings adjustments.</p> +<ul> +<li>Changing the <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#default-import-settings">default import settings</a> for pixel art no longer works (though it’s worth to double check as they changed from <code>Texture</code> to a <code>Texture2D</code>). The important parameter to <a href="https://ask.godotengine.org/122518/how-to-import-pixel-art-in-godot-4">change is the <em>Filter</em> for the textures</a>.<ul> +<li>Since all nodes inherit parameters by default, changing on the parent nodes (or just once in the root such as <code>Main.tscn</code>) will suffice: Go to <em>Inspector -> CanvasItem -> Texture</em> and change <em>Filter</em> from “Inherit” to “Nearest”.</li> +</ul> +</li> +<li>Re-set the <em>InputMap</em> as the system probably changed from <em>Godot 3</em> to <em>Godot 4</em>.</li> +<li>For <code>SavedData</code> singleton, change from <code>File</code> to <code>ConfigFile</code> and refactor. This is really not needed for making it run, but I changed this right away.</li> +<li>Remove <code>velocity</code> property of <code>Player</code> which is already included in <code>CharacterBody2D</code>.</li> +<li>Disable all <code>TileMap</code> related code as tile maps have changed drastically, they need more effort to covnert.</li> +<li>Change <code>String(int)</code> to <code>str(int)</code>.</li> +</ul> +<h3 id="player">Player<a class="headerlink" href="#player" title="Permanent link">¶</a></h3> +<p>Now that the game at least runs, next thing is to make it “playable”:</p> +<ul> +<li><code>AnimatedSprite</code> changed to <code>AnimatedSprite2D</code> (with the inclusion of <code>AnimatedSprite3D</code>). This node type changed with the automatic conversion.<ul> +<li>Instead of checking if an animation is playing with the the <code>playing</code> property, the method <code>is_playing()</code> needs to be used.</li> +</ul> +</li> +<li>The <code>default_gravity</code> from the <code>ProjectSettings</code> no longer needs to be multiplied by <code>10</code> to have reasonable numbers. The default is now <code>980</code> instead of <code>98</code>. I later changed this when refactoring the code and fine-tuning the feel of the movement.</li> +<li>The <em>Collision mask</em> can be changed programatically with the <code>set_collision_mask_value</code> (and similar with the layer). Before, the mask/layer was specified by the <code>bit</code> which started from <code>0</code>, but now it is accessed by the <code>layer_number</code> which starts from <code>1</code>.</li> +</ul> +<h3 id="world">World<a class="headerlink" href="#world" title="Permanent link">¶</a></h3> +<p>This is the most challenging part as the <code>TileMap</code> system changed drastically, it is basically a <em>from the ground up redesign</em>, luckily the <code>TileMap</code>s I use are really simple. Since this is not intuitive from the get-go, I took some notes on the steps I took to set up the world <code>TileMap</code>.</p> +<h4 id="scene">Scene<a class="headerlink" href="#scene" title="Permanent link">¶</a></h4> +<p>Instead of using one scene per <code>TileMap</code> only one <code>TileMap</code> can be used with multiple <em>Atlas</em> in the <code>TileSet</code>. Multiple physics layers can now be used per <code>TileSet</code> so you can separate the physics collisions on a per <em>Atlas</em> or <em>Tile</em> basis. The inclusion of <em>Tile patterns</em> also helps when working with multiple <em>Tiles</em> for a single cell “placement”. How I did it:</p> +<ol> +<li>Created one scene with one <code>TileMap</code> node, called <code>WorldTileMap.tscn</code>, with only one <code>TileSet</code> as multiple <em>Atlas</em>‘ can be used (this would be a single <code>TileSet</code> in <em>Godot 3</em>).<ul> +<li>To add a <code>TileSet</code>, select the <code>WorldTileMap</code> and go to <em>Inspector -> TileMap -> TileSet</em> then click on “<empty>” and then “New TileSet” button.</li> +<li>To manipulate a <code>TileSet</code>, it needs to be selected, either by clicking in the <em>Inspector</em> section or on the bottom of the screen (by default) to the left of <em>TileMap</em>, as shown in the image below.</li> +</ul> +</li> +</ol> +<figure id="__yafg-figure-48"> +<img alt="TileMap's TileSet selection highlighted in red, "Add" button in green." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_selected_add_atlas.png.png "TileMap's TileSet selection highlighted in red, "Add" button in green"."> +<figcaption></figcaption> +</figure> +<ol start="2"> +<li>Add two <em>Atlas</em> to the <code>TileSet</code> (one for the ground tiles and another for the pipes) by clicking on the “Add” button (as shown in the image above) and then on “Atlas”.</li> +<li>By selecting an atlas and having the “Setup” selected, change the <em>Name</em> to something recognizable like <code>ground</code> and add the texture atlas (the spritesheet) by dragging and dropping in the “<empty>” <em>Texture</em> field, as shown in the image below. Take a not of the <em>ID</em>, they start from <code>0</code> and increment for each atlas, but if they’re not <code>0</code> and <code>1</code> change them.</li> +</ol> +<figure id="__yafg-figure-49"> +<img alt="TileSet atlas setup selection highlighted in red, atlas name and id in green." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_setup_selection.png" title="TileSet atlas setup selection highlighted in red, atlas name and id in green."> +<figcaption>TileSet atlas setup selection highlighted in red, atlas name and id in green.</figcaption> +</figure> +<ol start="4"> +<li>I also like to delete unnecessary tiles (for now) by selecting the atlas “Setup” and the “Eraser” tool, as shown in the image below. Then to erase tiles just select them and they’ll be highlighted in black, once deleted they will be grayed out. If you want to activate tiles again just deselect the “Eraser” tool and select wanted tiles.</li> +</ol> +<figure id="__yafg-figure-50"> +<img alt="Atlas setup erase tiles. "Setup" selection and "Eraser" tool highlighted in red and green, respectively." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_setup_selection.png" title="Atlas setup erase tiles. "Setup" selection and "Eraser" tool highlighted in red and green, respectively."> +<figcaption>Atlas setup erase tiles. “Setup” selection and “Eraser” tool highlighted in red and green, respectively.</figcaption> +</figure> +<ol start="5"> +<li>For the pipes it is a good idea to modify the “tile width” for horizontal <code>1x2</code> tiles. This can be acomplished by removing all tiles except for one, then going to the “Select” section of the atlas, selecting a tile and extending it either graphically by using the yellow circles or by using the properties, as shown in the image below.</li> +</ol> +<figure id="__yafg-figure-51"> +<img alt="Atlas resize tile. "Select" selection and "Size in Atlas" highlighted in red and green, respectively." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_atlas_pipe_wide.png" title="Atlas resize tile. "Select" selection and "Size in Atlas" highlighted in red and green, respectively."> +<figcaption>Atlas resize tile. “Select” selection and “Size in Atlas” highlighted in red and green, respectively.</figcaption> +</figure> +<ol start="6"> +<li>Add physics (collisions) by selecting the <code>WorldTileMap</code>‘s <code>TileSet</code> and clicking on “Add Element” at the <em>TileMap -> TileSet -> Physics Layer</em> twice, one physics layer per atlas. Then set the collision’s layers and masks accordingly (ground on layer 2, pipe on 3). In my case, based on my already set <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#layers">layers</a>.<ul> +<li>This will enable physics properties on the tiles when selecting them (by selecting the atlas, being in the correct “Select” section and selecting a tile) and start drawing a polygon with the tools provided. This part is hard to explain in text, but below is an image of how it looks once the polygon is set.</li> +</ul> +</li> +</ol> +<figure id="__yafg-figure-52"> +<img alt="Tile add physics polygon in Physics Layer 0." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_selected_add_atlas.png" title="Tile add physics polygon on physics layer 0."> +<figcaption>Tile add physics polygon on physics layer 0.</figcaption> +</figure> +<pre><code>- Notice that the polygon is drawn in *Physics Layer 0*. Using the grid option to either `1` or `2` is useful when drawing the polygon, make sure the polygon closes itself or it wont be drawn. +</code></pre> +<ol start="8"> +<li>Create a tile pattern by drawing the tiles wanted in the editor and then going to the <em>Patterns</em> tab (to the right of <em>Tiles</em>) in the <em>TileMap</em>, selecting all tiles wanted in the pattern and dragging the tiles to the <em>Patterns</em> window. Added patterns will show in this window as shown in the image below, and assigned with IDs starting from <code>0</code>.</li> +</ol> +<figure id="__yafg-figure-53"> +<img alt="Tileset pattern." src="https://static.luevano.xyz/images/g/flappybird_godot4/godot4_tileset_pattern.png" title="Tileset pattern."> +<figcaption>Tileset pattern.</figcaption> +</figure> +<h4 id="script">Script<a class="headerlink" href="#script" title="Permanent link">¶</a></h4> +<p>Basically merged all 3 scripts (<code>ground_tile_map.gd</code>, <code>pipe_tile_map.gd</code> and <code>world_tiles.gd</code>) into one (<code>world_tile_map.gd</code>) and immediatly was able to delete a lot of signal calls between those 3 scripts and redundant code.</p> +<p>The biggest change in the scripting side are the functions to place tiles. For <em>Godot 3</em>:</p> +<pre><code class="language-gdscript"># place single tile in specific cell +void set_cell(x: int, y: int, tile: int, flip_x: bool = false, flip_y: bool = false, transpose: bool = false, autotile_coord: Vector2 = Vector2( 0, 0 )) +void set_cellv(position: Vector2, tile: int, flip_x: bool = false, flip_y: bool = false, transpose: bool = false, autotile_coord: Vector2 = Vector2( 0, 0 )) +</code></pre> +<p>Whereas in <em>Godot 4</em>:</p> +<pre><code class="language-gdscript"># place single tile in specific cell +void set_cell(layer: int, coords: Vector2i, source_id: int = -1, atlas_coords: Vector2i = Vector2i(-1, -1), alternative_tile: int = 0) +# erase tile at specific cell +void erase_cell(layer: int, coords: Vector2i) +</code></pre> +<p>How to use these functions in <em>Godot 4</em> (new properties or differences/changes):</p> +<ul> +<li><code>layer</code>: for my case I only use 1 layer so it is always set to <code>0</code>.</li> +<li><code>coords</code>: would be the equivalent to <code>position</code> for <code>set_cellv</code> in <em>Godot 3</em>.</li> +<li><code>source_id</code>: which atlas to use (ground: <code>0</code> or pipe <code>1</code>).</li> +<li><code>atlas_coords</code>: tile to use in the atlas. This would be the equivalent to <code>tile</code> in <em>Godot 3</em>.</li> +<li><code>alternative_tile</code>: for tiles that have alternatives such as mirrored or rotated tiles, not required in my case.</li> +</ul> +<p>Setting <code>source_id=-1</code>, <code>atlas_coords=Vector21(-1,-1)</code> or <code>alternative_tile=-1</code> will delete the tile at <code>coords</code>, similar to just using <code>erase_cell</code>.</p> +<p>With the addition to <em>Tile patterns</em> (to place multiple tiles), there is a new function:</p> +<pre><code class="language-gdscript"># place pattern +void set_pattern(layer: int, position: Vector2i, pattern: TileMapPattern) +</code></pre> +<p>Where <code>position</code> has the same meaning as <code>coords</code> in <code>set_cell</code>/<code>erase_cell</code>, not sure why it has a different name. The <code>pattern</code> can be obtained by using <code>get_pattern</code> method on the <code>tile_set</code> property of the <code>TileMap</code>. Something like:</p> +<pre><code class="language-gdscript">var pattern: TileMapPattern = tile_set.get_pattern(index) +</code></pre> +<p>Other than that, <code>Vector2</code> needs to be changed to <code>Vector2i</code>.</p> +<h2 id="changes-and-improvements">Changes and improvements<a class="headerlink" href="#changes-and-improvements" title="Permanent link">¶</a></h2> +<p>General changes and additions that have nothing to do with porting to <em>Godot 4</em>, things I wanted to add regardless of the version.</p> +<h3 id="audio">Audio<a class="headerlink" href="#audio" title="Permanent link">¶</a></h3> +<p>The audio in the <em>Godot 3</em> version was added in the last minute and it was blasting by default with no option to decrease the volume or mute it. To deal with this:</p> +<ol> +<li>Refactored the code into a single scene/script to have better control.</li> +<li>Added a volume control slider by following <a href="https://www.gdquest.com/tutorial/godot/audio/volume-slider/">this GDQuest guide</a>.</li> +<li>Added a mute button, following the same principle as with the volume control.</li> +</ol> +<p>The basic code required for these features is the following:</p> +<pre><code class="language-gdscript"># get audio bus index +var audio_bus_name: String = "Master" +var _bus: int = AudioServer.get_bus_index(audio_bus_name) + +# change the volume +var linear_volume: float = 0.5 # 50%, needs to be between 0.0 and 1.0 +var db_volume: float = linear_to_db(linear_volume) +AudioServer.set_bus_volume_db(_bus, db_volume) + +# mute +AudioServer.set_bus_mute(_bus, true) # false to unmute +</code></pre> +<p>Just be careful with how the <code>linear_volume</code> is set (from a button or slider) as it has to be between <code>0.0</code> and <code>1.0</code>.</p> +<h3 id="event-bus">Event bus<a class="headerlink" href="#event-bus" title="Permanent link">¶</a></h3> +<p>Moved all the signal logic into an event bus to get rid of the coupling I had. This is accomplished by:</p> +<ol> +<li>Creating a singleton (autoload) script which I called <code>event.gd</code> and can be accessed with <code>Event</code>.</li> +<li>All the signals are now defined in <code>event.gd</code>.</li> +<li>When a signal needs to be emited instead of emitting the signal from any particular script, emit it from the event bus with <code>Event.<signal_name>.emit(<optional_args>)</code>.</li> +<li>When connecting to a signal instead of taking a reference to where the signal is defined, simply connect it with with <code>Event.<signal_name>.connect(<callable>[.bind(<optional_args>)])</code><ul> +<li>For signals that already send arguments to the callable, they do not need to be specified in <code>bind</code>, only extras are needed here.</li> +</ul> +</li> +</ol> +<h3 id="ui">UI<a class="headerlink" href="#ui" title="Permanent link">¶</a></h3> +<p>Really the only UI I had before was for rendering fonts, and the way fonts work changed a bit. Before, 3 resources were needed as <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html#fonts">noted in my previous entry</a>:</p> +<ol> +<li>Font file itself (<code>.ttf</code> for example).</li> +<li><code>DynamicFontData</code>: used to point to a font file (<code>.ttf</code>) and then used as base resource.</li> +<li><code>DynamicFont</code>: usable in godot control nodes which holds the <code>DynamicFontData</code> and configuration such as size.</li> +</ol> +<p>Now only 1 resource is needed: <code>FontFile</code> which is the <code>.ttf</code> file itself or a godot-created resource. There is also a <code>FontVariation</code> option, which takes a <code>FontFile</code> and looks like its used to create fallback options for fonts. The configuration (such as size) is no longer held in the font resource, but rather in the parent control node (like a <code>Label</code>). Double clicking on the <code>.ttf</code> file and disabling antialiasing and compression is something that might be needed. Optionally create a <code>FontLabelSettings</code> which will hold the <code>.ttf</code> file and used as base for <code>Label</code>s. Use “Make Unique” for different sizes. Another option is to use <em>Themes</em> and <em>Variations</em>.</p> +<p>I also created the respective volume button and slider UI for the added audio functionality as well as creating a base <code>Label</code> to avoid repeating configuration on each <code>Label</code> node.</p> +<h3 id="misc">Misc<a class="headerlink" href="#misc" title="Permanent link">¶</a></h3> +<p>Small changes that don’t affect much:</p> +<ul> +<li>Updated <code>@export</code> to <code>@export_range</code>. The auto conversion didn’t use the correct annotation and instead used a comment.</li> +<li>Refactored the <code>game_scale</code> methodolgy as it was inconsistent. Now only one size is used as base and everything else is just scaled with the <code>root</code> <code>Window</code>.</li> +<li>Got rid of the FPS monitoring, was only using it for debugging purposes back then.</li> +</ul>]]></content:encoded> + </item> + <item> <title>Set up a pastebin alternative with PrivateBin and YOURLS</title> <link>https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html</link> <guid isPermaLink="true">https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html</guid> @@ -2246,7 +2445,7 @@ func physics_process(delta: float) -> void: <category>Gamedev</category> <category>Gdscript</category> <category>Godot</category> - <description>Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to keep consistent. This shows as "devlog 1" just in case I want to include more parts for extra stuff.</description> + <description>Since I'm starting to get more into gamedev stuff, I'll start blogging about it just to stay consistent.</description> <content:encoded><![CDATA[<p>I just have a bit of experience with <em>Godot</em> and with gamedev in general, so I started with this game as it is pretty straight forward. On a high level the main characteristics of the game are:</p> <ul> <li>Literally just one sprite going up and down.</li> @@ -2255,9 +2454,10 @@ func physics_process(delta: float) -> void: <li>If you touch the pipes, the ground or go past the “ceiling” you lose.</li> </ul> <p>The game was originally developed with <em>Godot 4.0 alpha 8</em>, but it didn’t support HTML5 (webassembly) export… so I backported to <em>Godot 3.5 rc1</em>.</p> +<p><ins><mark>Note:</mark> I’ve updated the game to <em>Godot 4</em> and documented it on my <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">FlappyBird devlog 2</a> entry.</ins></p> <p>Not going to specify all the details, only the needed parts and what could be confusing, as the source code is available and can be inspected; also this assumes minimal knowledge of <em>Godot</em> in general. Usually when I mention that a set/change of something it usually it’s a property and it can be found under the <em>Inspector</em> on the relevant node, unless stated otherwise; also, all scripts attached have the same name as the scenes, but in <em>snake_case</em> (scenes/nodes in <em>PascalCase</em>).</p> <p>One thing to note, is that I started writing this when I finished the game, so it’s hard to go part by part, and it will be hard to test individual parts when going through this as everything is depending on each other. For the next devlog, I’ll do it as I go and it will include all the changes to the nodes/scripts as I was finding them, probably better idea and easier to follow.</p> -<p>The source code can be found at <a href="https://github.com/luevano/flappybird_godot/tree/godot-3.5">luevano/flappybird_godot#godot-3.5</a>, it also contains the exported versions for HTML5, Windows and Linux (be aware that the sound might be too high and I’m too lazy to make it configurable, it was the last thing I added), or you could also go to the <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a> page I setup where it’s playable in the browser:</p> +<p>The source code can be found at <a href="https://github.com/luevano/flappybirdgodot/tree/godot-3.5">luevano/flappybirdgodot#godot-3.5</a> (<code>godot-3.5</code> branch), it also contains the exported versions for HTML5, Windows and Linux (<del>be aware that the sound might be too high and I’m too lazy to make it configurable, it was the last thing I added</del> <ins>on the latest version this is fixed and audio level is configurable now</ins>). Playable on <a href="https://lorentzeus.itch.io/flappybirdgodot">itch.io</a> (<em>Godot 4</em> version):</p> <p style="text-align:center"><iframe src="https://itch.io/embed/1551015?dark=true" width="208" height="167" frameborder="0"><a href="https://lorentzeus.itch.io/flappybirdgodot">FlappyBirdGodot by Lorentzeus</a></iframe></p> <h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2> diff --git a/live/blog/sitemap.xml b/live/blog/sitemap.xml index c9c5e77..0f0ece6 100644 --- a/live/blog/sitemap.xml +++ b/live/blog/sitemap.xml @@ -46,6 +46,12 @@ </url> <url> + <loc>https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html</loc> + <lastmod>2023-08-28</lastmod> + <changefreq>weekly</changefreq> + <priority>1.0</priority> + </url> + <url> <loc>https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html</loc> <lastmod>2023-08-20</lastmod> <changefreq>weekly</changefreq> @@ -113,7 +119,7 @@ </url> <url> <loc>https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html</loc> - <lastmod>2023-05-09</lastmod> + <lastmod>2023-08-26</lastmod> <changefreq>weekly</changefreq> <priority>1.0</priority> </url> diff --git a/live/blog/tag/@english.html b/live/blog/tag/@english.html index 3481735..2f98448 100644 --- a/live/blog/tag/@english.html +++ b/live/blog/tag/@english.html @@ -78,6 +78,7 @@ <h2>Articles</h2> <ul class="page-list"> <h3>2023</h3> + <li><span class="page-list-item">Aug 27</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">Porting the FlappyBird clone to Godot 4.1 devlog 2</a></li> <li><span class="page-list-item">Aug 20</span> - <a href="https://blog.luevano.xyz/a/pastebin_alt_with_privatebin.html">Set up a pastebin alternative with PrivateBin and YOURLS</a></li> <li><span class="page-list-item">Jul 24</span> - <a href="https://blog.luevano.xyz/a/jellyfin_server_with_sonarr_radarr.html">Set up a media server with Jellyfin, Sonarr and Radarr</a></li> <li><span class="page-list-item">Jul 24</span> - <a href="https://blog.luevano.xyz/a/torrenting_with_qbittorrent.html">Set up qBitTorrent with Jackett for use with Starr apps</a></li> diff --git a/live/blog/tag/@gamedev.html b/live/blog/tag/@gamedev.html index ca64956..512bd9c 100644 --- a/live/blog/tag/@gamedev.html +++ b/live/blog/tag/@gamedev.html @@ -77,7 +77,9 @@ <h2>Articles</h2> <ul class="page-list"> - <h3>2022</h3> + <h3>2023</h3> + <li><span class="page-list-item">Aug 27</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">Porting the FlappyBird clone to Godot 4.1 devlog 2</a></li> + <h3>2022</h3> <li><span class="page-list-item">Jun 10</span> - <a href="https://blog.luevano.xyz/g/gogodot_jam3_devlog_1.html">Creating my Go Godot Jam 3 entry using Godot 3.5 devlog 1</a></li> <li><span class="page-list-item">May 29</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html">Creating a FlappyBird clone in Godot 3.5 devlog 1</a></li> <li><span class="page-list-item">May 22</span> - <a href="https://blog.luevano.xyz/g/godot_project_structure.html">General Godot project structure</a></li> diff --git a/live/blog/tag/@gdscript.html b/live/blog/tag/@gdscript.html index 6be0ee0..f004012 100644 --- a/live/blog/tag/@gdscript.html +++ b/live/blog/tag/@gdscript.html @@ -77,7 +77,9 @@ <h2>Articles</h2> <ul class="page-list"> - <h3>2022</h3> + <h3>2023</h3> + <li><span class="page-list-item">Aug 27</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">Porting the FlappyBird clone to Godot 4.1 devlog 2</a></li> + <h3>2022</h3> <li><span class="page-list-item">Jun 10</span> - <a href="https://blog.luevano.xyz/g/gogodot_jam3_devlog_1.html">Creating my Go Godot Jam 3 entry using Godot 3.5 devlog 1</a></li> <li><span class="page-list-item">May 29</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html">Creating a FlappyBird clone in Godot 3.5 devlog 1</a></li> </ul> diff --git a/live/blog/tag/@godot.html b/live/blog/tag/@godot.html index 12819b0..fd622f7 100644 --- a/live/blog/tag/@godot.html +++ b/live/blog/tag/@godot.html @@ -77,7 +77,9 @@ <h2>Articles</h2> <ul class="page-list"> - <h3>2022</h3> + <h3>2023</h3> + <li><span class="page-list-item">Aug 27</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_2.html">Porting the FlappyBird clone to Godot 4.1 devlog 2</a></li> + <h3>2022</h3> <li><span class="page-list-item">Jun 10</span> - <a href="https://blog.luevano.xyz/g/gogodot_jam3_devlog_1.html">Creating my Go Godot Jam 3 entry using Godot 3.5 devlog 1</a></li> <li><span class="page-list-item">May 29</span> - <a href="https://blog.luevano.xyz/g/flappybird_godot_devlog_1.html">Creating a FlappyBird clone in Godot 3.5 devlog 1</a></li> <li><span class="page-list-item">May 22</span> - <a href="https://blog.luevano.xyz/g/godot_project_structure.html">General Godot project structure</a></li> diff --git a/src/blog/temp/flappybird_godot_devlog_2.md b/src/blog/g/flappybird_godot_devlog_2.md index c2192bf..3363f0e 100644 --- a/src/blog/temp/flappybird_godot_devlog_2.md +++ b/src/blog/g/flappybird_godot_devlog_2.md @@ -1,7 +1,7 @@ -title: Porting the FlappyBird clone to Godot 4 devlog 2 +title: Porting the FlappyBird clone to Godot 4.1 devlog 2 author: David Luévano lang: en -summary: Notes on porting my FlappyBird clone to Godot 4, as well as notes on the improvements and changes made overall. +summary: Notes on porting my FlappyBird clone to Godot 4.1, as well as notes on the improvements and changes made overall. tags: gamedev godot gdscript |