{"id":168,"date":"2024-11-11T12:48:14","date_gmt":"2024-11-11T12:48:14","guid":{"rendered":"https:\/\/matthiasvanherk.com\/?page_id=168"},"modified":"2024-11-15T11:29:08","modified_gmt":"2024-11-15T11:29:08","slug":"kronos-rush","status":"publish","type":"page","link":"https:\/\/matthiasvanherk.com\/index.php\/kronos-rush\/","title":{"rendered":"Kronos Rush"},"content":{"rendered":"<h2 class=\"wp-block-post-title\">Kronos Rush<\/h2>\n\n\n<p class=\"has-text-align-left has-custom-color-3-color has-text-color\" style=\"margin-top:0rem;font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.409), 1.1rem);font-style:normal;font-weight:400;line-height:1.6\">This game is a bullet hell game based on the greek mythology. We used c# and monogame for this project. We also had to use some sql and design a database.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4-1024x576.png\" alt=\"\" class=\"wp-image-65\" style=\"border-radius:39px\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4-1024x576.png 1024w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4-300x169.png 300w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4-768x432.png 768w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4-1536x864.png 1536w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/10\/image-4.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Since we weren&#8217;t able to make a webGL build with monogame I have uploaded a video of the gameplay below. There were quite a few mistakes left at the end of the project. To name the obvious: the cursor isn&#8217;t visible, some of the UI text is practically illegible, the background is very busy and the shield doesn&#8217;t clearly show what it does. Furthermore the game is way too difficult. Sadly the person who was responsible for these fixes had some personal things going on near the end of the project and we were never able to fix them.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" controls src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/2024-11-15-09-04-54-Copy.mp4\"><\/video><\/figure>\n\n\n\n<p style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.409), 1.1rem);\">In this project I created the different types of movement for the enemies using a state machine. I also made the invincibility ability, allowing the player to be invincible when the bar on the right is filled. Furthermore I made the spawning of enemies and the collision. Last, but not least I set up a connection to the database.<\/p>\n\n\n\n<p style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.409), 1.1rem);\">This project we worked with a team of 5 people including me. I had the most experience of everyone in the team so I spent a lot of time setting things up that were important and easy to work with for people who weren&#8217;t completely used to coding yet. I used code inspired by the state pattern to allow other people working on the project to easily add new enemy types.<\/p>\n\n\n\n<p>This pattern allowed us to simply call an enemy&#8217;s <em>ChangeBehaviour<\/em> method to change it&#8217;s behaviour. As can be seen in the image below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"581\" height=\"517\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-2.png\" alt=\"\" class=\"wp-image-175\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-2.png 581w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-2-300x267.png 300w\" sizes=\"auto, (max-width: 581px) 100vw, 581px\" \/><\/figure>\n\n\n\n<p style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.409), 1.1rem);\">Next we&#8217;ll take a look at the <em>Update<\/em> method. Here we set <em>newPosition<\/em> which is a <em>Vector2<\/em> that is used as the destination of the enemy. We also call the <em>MoveToPosition<\/em> method.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"858\" height=\"111\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-4.png\" alt=\"\" class=\"wp-image-233\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-4.png 858w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-4-300x39.png 300w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-4-768x99.png 768w\" sizes=\"auto, (max-width: 858px) 100vw, 858px\" \/><\/figure>\n\n\n\n<p>The <em>MoveToPosition<\/em> method handles moving the enemies towards the <em>Vector2<\/em> <em>newPosition<\/em>. The character gets animated and there is a check to see if the enemy is already at the <em>newPosition<\/em>. After this we extract the position of the enemy from the <em>newPosition<\/em> to create a direction and we normalize this value. We then move the enemy towards the new position using <em>Vector2.Lerp<\/em>. Lastly we call the ClampPosition method which clamps the position of enemies to the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"863\" height=\"217\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-5.png\" alt=\"\" class=\"wp-image-234\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-5.png 863w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-5-300x75.png 300w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-5-768x193.png 768w\" sizes=\"auto, (max-width: 863px) 100vw, 863px\" \/><\/figure>\n\n\n\n<p>The <em>newPosition<\/em> is set because in the <em>Update<\/em> method we call the <em>currentBehaviour.NewPosition()<\/em>. To make sure we always get a <em>Vector2<\/em> I have made an interface that the behaviours use.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"983\" height=\"93\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-7.png\" alt=\"\" class=\"wp-image-237\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-7.png 983w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-7-300x28.png 300w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-7-768x73.png 768w\" sizes=\"auto, (max-width: 983px) 100vw, 983px\" \/><\/figure>\n\n\n\n<p>The image below shows an example of one of the behaviours added to the game. This behaviour will make the enemy move in a circle around the player and switch direction every few seconds. I had already made code to make an enemy rotate around the player with a boolean stating whether it should move clockwise or counterclockwise. In the behaviour below I have simply added a timer that changes whether the enemy should move clockwise or counterclockwise and I then return the result of the <em>CircleObject<\/em> behaviour.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"273\" src=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-6-1024x273.png\" alt=\"\" class=\"wp-image-236\" srcset=\"https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-6-1024x273.png 1024w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-6-300x80.png 300w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-6-768x205.png 768w, https:\/\/matthiasvanherk.com\/wp-content\/uploads\/2024\/11\/image-6.png 1223w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-large-font-size\">Review<\/p>\n\n\n\n<p>In hindsight I find quite a few mistakes in my code and decision making.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Some of the names can be very confusing. the newPosition variable should probably be called targetPosition, or something similar.<\/li>\n\n\n\n<li>The state pattern is best used when an object often has to switch states which wasn&#8217;t the case in our project. Enemies usually got assigned a state when they were instantiated and never switched. So the state pattern was a bit of an overkill.<\/li>\n\n\n\n<li>As we had just learned about interfaces I was overly eager to use them. In this case an abstract class would&#8217;ve been better suited as used in the state pattern, because the behaviours are all the same type of object, a behaviour. They don&#8217;t just have the same capability.<\/li>\n\n\n\n<li>Last but not least, my approach was all wrong. I added all sorts of behaviours. Most haven&#8217;t been used in the game. I created a lot of possibility with the idea that you could create hundreds of different enemies with all sorts of unique movements, but I never consider whether it would ever come to that or whether we even wanted that to be part of the game.<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This game is a bullet hell game based on the greek mythology. We used c# and monogame for this project. We also had to use some sql and design a database. Since we weren&#8217;t able to make a webGL build with monogame I have uploaded a video of the gameplay below. There were quite a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-168","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/pages\/168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/comments?post=168"}],"version-history":[{"count":21,"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/pages\/168\/revisions"}],"predecessor-version":[{"id":282,"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/pages\/168\/revisions\/282"}],"wp:attachment":[{"href":"https:\/\/matthiasvanherk.com\/index.php\/wp-json\/wp\/v2\/media?parent=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}