{"author_link":"\/users\/geckoo1337","author_name":"Geckoo1337","author_uid":"geckoo1337","comments":[],"epoch":1666374414,"event":"LD51","format":"md","ldjam_node_id":310815,"likes":3,"metadata":{"p_key":"169538","p_author":"Geckoo1337","p_authorkey":"1000409","p_urlkey":"397313","p_title":"Shabadoo - a last devlog","p_cat":"LDJam ","p_event":"LD51","p_time":"1666374414","p_likes":"3","p_comments":"0","p_status":"WAYBACK","us_key":"1000409","us_name":"Geckoo1337","us_username":"geckoo1337","event_start":"1664496000","event_key":"114","event_name":"Ludum Dare 51"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD51","removed_author":false},"_superparent":296586,"_trust":15,"author":409,"body":"https:\/\/ldjam.com\/events\/ludum-dare\/51\/shabadoo\n\n![4fa8b.png](\/\/\/raw\/991\/z\/53290.png)\n\nHello. Today I have the time in order to rate games - and also explain how I created my project - Shabadoo. Its main particularity is the template which I made so as to simplify the game development. At first I thought that the **OLC::PixelGameEngine** (Javidx9) could be an interesting way to create my game. I don't know if you know it, but it is a single header file in pure C++ without any dependencies using OpenGL as a way to create inside a GDI+ frame a single texture on which you control every pixel. I quickly resumed how it works, but it is a great tool with many functions and a clever ECS system which reminds us of some Unity script including an appUpdate() section. However (like with Pico-8) there are harsh limitations. Ok! Let's go... \n\nI said to myself that it could be fun to create my own Template for GameJam(s). Fundamentally it is not too hard to create a 2d game engine from scratch in pure C++ and inspired by the PGE template. The core can be developed in less than 500 code lines, but after this work I struggled hard in order to draw, shape and compute game objects. If we can understand easily what a line is (x1,y1 to x2, y2), just a moment think about a hexagon or a filled non-regular polygon... At first, I show you what is a pixel structure according to this template - and how it draws them on screen :\n```(c++)\n    struct Pixel\n\t{\n\t\tunion\n\t\t{\t\/\/ opaque black pixel\n\t\t\tuint32_t n = 0xFF000000;\n\n\t\t\tstruct\n\t\t\t{\n\t\t\t\tuint8_t r;\n\t\t\t\tuint8_t g;\n\t\t\t\tuint8_t b;\n\t\t\t\tuint8_t a; \/\/ alpha\n\t\t\t};\n\t\t};\n\t};\n\n(...)\n\n    bool xGameEngine::Draw(const gck::vi2d& pos, Pixel p)\n\t{\n\t\tif (!pDrawTarget) \n\t\t\treturn false;\n\n\t\tPixel d = pDrawTarget->GetPixel(pos);\n\t\t\/\/ escape quickly if the pixel has the same color\n\t\tif (p == d) \n\t\t\treturn false;\n\n\t\tfloat a = (float)(p.a \/ 255.0f);\n\t\tfloat c = 1 - a;\n\t\tfloat r = a * (float)p.r + c * (float)d.r;\n\t\tfloat g = a * (float)p.g + c * (float)d.g;\n\t\tfloat b = a * (float)p.b + c * (float)d.b;\n\t\t\/\/ new pixel at pos\n\t\treturn pDrawTarget->SetPixel(pos, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));\n\t}\n```\nWhen I started my project canvas, I thought about a clean font in-game without any third part. I remembered a script which I made under Unity in order to write text as a single sprite. If you remember TakeYourMedsDarling (a previous entry for the LD 49), I used a system like this... How does it work? In fact, it is more or less similar to the Chip-8 font system (lol). Imagine a sprite 5x7 pixels (chip-8 used a 4x4 pixels size). Imagine now 5 bytes and their bits. For each column the function reads a hexadecimal value and each converted bit 1 becomes a colored pixel - a bit 0 becomes an alpha null pixel. So the letter A can be write with the bits : \n```\nstd::vector<unsigned char> keyA{ 0x7E, 0x09, 0x09, 0x09, 0x7E }; \n```\nFor each letter, number or special char, I created them using 5 hexadecimal values. I wasted many time, but this font is mine \u2013 and it works as expected giving retro vibes to the game. Take a look at the function \u2013 notice how it converts a char to booleans\u00a0: \n```\n    void xGameEngine::DrawString(gck::vi2d pos, std::string &str, gck::Pixel p, int32_t scale)\n\t{\t\/\/ our letters scale - only 5x7 pixels\n\t\tshort fontX = 5; \n\t\tshort fontY = 7; \n\t\tshort pp = pos.x;\n\n\t\tif (stamp == nullptr) \n\t\t\tDrawFont(fontX, fontY);\n\t\t\/\/ only lower case\n\t\tstd::vector<unsigned char> byte;\n\t\ttransform(str.begin(), str.end(), str.begin(), ::toupper);\n\n\t\tfor (size_t i = 0; i < str.length(); i++)\n\t\t{\n\t\t\tif (str[i] == '\\n')\n\t\t\t{\n\t\t\t\tpos.y += (fontY + 1) * scale;\n\t\t\t\tpos.x = pp * scale;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tbyte = checkChar(str[i]);\n\n\t\t\tfor (int x = 0; x < fontX; x++)\n\t\t\t\tfor (int y = 0; y < fontY; y++)\n\t\t\t\t\tif ((byte[x] >> y) & 0x1)\n\t\t\t\t\t\tstamp->SetPixel(gck::vi2d(x, y), p); \/\/ this one !!!\n\t\t\t\t\telse\n\t\t\t\t\t\tstamp->SetPixel(gck::vi2d(x, y), gck::BLANK);\n\n\t\t\tDrawSprite(pos, stamp, scale);\n\t\t\tpos.x += (fontX + 1) * scale; \/\/ shift to the next char\n\t\t}\n\t}\n```\nThe main difficulty had been to draw some non-regular polygons - the levels on which rebounds the colored balls. It was not too hard to draw a shape, just lines using a main **std::vector** with coordinates (x,y). I could use **std::pair**, but no... However I had no clue how I could fill shapes. There are many ways in order to fill a shape, but they wasted my tiny CPU resources - and as I said I had to use them carefully. Then I saw a raylight in the darkest fog! According to the same **std::vector** I implemented a function which checks all pixels and stores them if they are inside a non-regular polygon coordinates. However I called this function in the appCreate() section - so storing pixels during the first frame, drawing them in the appUpdate() section. The renderer was really smooth - and the resources were saved. \n```\n    \/\/ function in order to check if a point is inside a polygon\n\tbool xGameEngine::isPointInsidePolygon(std::vector<gck::vi2d> vertices, gck::vi2d pos)\n\t{\n\t\tbool isInside = false;\n\t\tauto num_verts = vertices.size();\n\n\t\tfor (size_t i = 0, j = num_verts - 1; i < num_verts; j = i++)\n\t\t{\n\t\t\tdouble x1 = vertices[i].x;\n\t\t\tdouble y1 = vertices[i].y;\n\t\t\tdouble x2 = vertices[j].x;\n\t\t\tdouble y2 = vertices[j].y;\n\n\t\t\tif (((y1 > pos.y) != (y2 > pos.y)) && (pos.x < (x2 - x1) * (pos.y - y1) \/ (y2 - y1) + x1))\n\t\t\t\tisInside = !isInside;\n\t\t}\n\n\t\treturn isInside;\n\t}\n```\n![Sans titre.png](\/\/\/raw\/991\/z\/53293.png)\n\nI really like the background under some games developed using Pico-8. It is like a canvas or a curtain. In my template, I had a function in order to apply a single color to each pixel so as to \u00ab clean \u00bb the main screen, but I wanted more...\t\n\nIn C++, we can use some ternary operator and I really like it. It is more than a simple condition variable \u2013 it allows us to develop some behavior according to a condition. I said to myself that using coordinates I could apply another color to the pixel if it has a particular feature. So I check pixels using this ternary operator :\t\n\nSo I got vertical lines according to the width. Then I found a tip. Simply I add +1 pixel to my game X resolution and it shifts everything on screen. Again I used a ternary operator. Finally I have some zebra lines. Sometimes a little thing can change everything...\t\n```\n    \/\/ clear the entire sprite (or screen) according a specific color\n\tvoid xGameEngine::Clear(Pixel p, Pixel pp, int stripe)\n\t{\n\t\tint pixels = pDrawTarget->width * pDrawTarget->height;\n\t\tPixel* m = GetDrawTarget()->GetData();\n\n\t\tfor (int i = 0; i < pixels; ++i)\n\t\t\tstripe != 0 ? (i % stripe ? m[i] = p : m[i] = pp) : m[i] = p;\n\t}\n```\nAt the end, my template was able to draw many shapes. below you can see every declaration which are explicit :\n```\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ useful functions declarations\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ninline float map(int s, float a1, float a2, float b1, float b2);\ninline float computeDistance(const gck::vi2d& p1, const gck::vi2d& p2);\ninline float lerp(float a, float b, float f);\ninline vf2d GetVector(int32_t nIndex, int32_t fRadius, int32_t fFactor);\nvi2d rotatePoint(gck::vi2d p, gck::vi2d axis, float angle);\nbool inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3);\nbool isPointInsidePolygon(std::vector<gck::vi2d> vertices, gck::vi2d px);\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ functions declarations in order to draw everything\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\nvirtual bool Draw(const gck::vi2d& pos, Pixel p = gck::WHITE);\nvoid DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE);\nvoid DrawFrame(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE, bool fill = false); \/\/ simple rectangle\nvoid DrawRect(const gck::vi2d& pos, const int32_t w, const int32_t h, const int& angle = 0, Pixel p = gck::WHITE, bool fill = false); \/\/ rotation available\nvoid DrawTris(const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3, const int& angle, Pixel p = gck::WHITE, bool fill = false);\nvoid DrawCircle(const gck::vi2d& pos, const int& fRadius, Pixel p = gck::WHITE, bool fill = false, const int& thickness = 0);\nvoid DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p = gck::WHITE, bool fill = false); \/\/ regular polygon\nvoid DrawPolygon(const std::vector<gck::vi2d> vertices, Pixel p = gck::WHITE, bool fill = false); \/\/ no regular polygon\nvoid DrawSprite(const gck::vi2d& pos, Sprite* sprite, uint32_t scale = 1);\nvoid DrawFont(int32_t x, int32_t y); \/\/ in order to write string\nstd::vector<unsigned char> checkChar(char c);\nvoid DrawString(gck::vi2d pos, std::string &str, gck::Pixel p = gck::WHITE, int32_t scale = 1);\nvoid Clear(Pixel p, Pixel pp = VERY_DARK_GREY, int stripe = 0); \/\/ to clear screen each frame\n```\nAnd it is enough so as to create a game :golf: \n\nAmong all these functions I really like this one which allows to draw a regular polygon. One single function to draw a square, a pentagon, a hexagon, a heptagon or an octagon - really useful. Take a look at the way in order to fill them. Each edge has two points and the third is the center of the polygon. Then I fill these triangular shapes (as you can see, there is a function to rotate each shape or point) : \n```\n    \/\/ check if a point is inside a triangle (used to fill regular polygons)\n\tbool xGameEngine::inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3)\n\t{\n\t\tint s = (pos1.x - pos3.x) * (p.y - pos3.y) - (pos1.y - pos3.y) * (p.x - pos3.x);\n\t\tint t = (pos2.x - pos1.x) * (p.y - pos1.y) - (pos2.y - pos1.y) * (p.x - pos1.x);\n\n\t\tif ((s < 0) != (t < 1) && s != 0 && t != 1)\n\t\t\treturn false;\n\n\t\tint d = (pos3.x - pos2.x) * (p.y - pos2.y) - (pos3.y - pos2.y) * (p.x - pos2.x);\n\n\t\treturn d == 0 || (d < 0) == (s + t <= 0);\n\t}\n\n(...)\n\n    \/\/ draws a regular polygon according to a single point, a factor and a radius\n\tvoid xGameEngine::DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p, bool fill)\n\t{\n\t\tif (fFactor > 8) \n\t\t\tfFactor = 8; \/\/ beyond 8 it's almost a circle no ?\n\t\t\/\/ sometimes a point at the center is required\n\t\tif (fill) \n\t\t\tDraw(pos, p);\n\n\t\tfor (int i = 0; i < fFactor; i++)\n\t\t{\n\t\t\tgck::vf2d vPoint = rotatePoint(GetVector(i, fRadius, fFactor) + pos, pos, static_cast<float>(angle));\n\t\t\tgck::vf2d pPoint = rotatePoint(GetVector(i - 1, fRadius, fFactor) + pos, pos, static_cast<float>(angle));\n\n\t\t\tfill ? DrawTris(pos, vPoint, pPoint, 0, p, true) : DrawLine(vPoint, pPoint, p);\n\t\t}\n\t}\n```\nI could continue to explain many, many, many things about this template - and especially how I developed the physics for Shabodoo, but I guess that for now it is enough. You can try Shabadoo - and of course you can rate it. Leave a comment - I really appreciate it, and then I have a link in order to rate your own project. I hope that you liked those explanations. If I can improve some parts of my template I will share it on GitHub, but right now it is still bugged and not clearly coded. Stay tuned ++ \n\nhttps:\/\/ldjam.com\/events\/ludum-dare\/51\/shabadoo","comments":0,"created":"2022-10-21T17:45:44Z","files":[],"files-timestamp":0,"id":310815,"love":3,"love-timestamp":"2022-10-24T13:26:25Z","meta":[],"modified":"2022-10-24T13:26:25Z","name":"Shabadoo - a last devlog","node-timestamp":"2022-10-21T17:46:54Z","parent":297081,"parents":[1,5,9,296586,297081],"path":"\/events\/ludum-dare\/51\/shabadoo\/shabadoo-a-last-devlog","published":"2022-10-21T17:46:54Z","scope":"public","slug":"shabadoo-a-last-devlog","subsubtype":"","subtype":"","type":"post","version":969753},"node_metadata":{"n_key":"310815","n_urlkey":"397313","n_parent":"297081","n_path":"\/events\/ludum-dare\/51\/shabadoo\/shabadoo-a-last-devlog","n_slug":"shabadoo-a-last-devlog","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"409","n_created":"1666374344","n_modified":"1666617985","n_version":"969753","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/51\/shabadoo\/shabadoo-a-last-devlog","text":"https:\/\/ldjam.com\/events\/ludum-dare\/51\/shabadoo\n\n![4fa8b.png](\/\/\/raw\/991\/z\/53290.png)\n\nHello. Today I have the time in order to rate games - and also explain how I created my project - Shabadoo. Its main particularity is the template which I made so as to simplify the game development. At first I thought that the **OLC::PixelGameEngine** (Javidx9) could be an interesting way to create my game. I don't know if you know it, but it is a single header file in pure C++ without any dependencies using OpenGL as a way to create inside a GDI+ frame a single texture on which you control every pixel. I quickly resumed how it works, but it is a great tool with many functions and a clever ECS system which reminds us of some Unity script including an appUpdate() section. However (like with Pico-8) there are harsh limitations. Ok! Let's go... \n\nI said to myself that it could be fun to create my own Template for GameJam(s). Fundamentally it is not too hard to create a 2d game engine from scratch in pure C++ and inspired by the PGE template. The core can be developed in less than 500 code lines, but after this work I struggled hard in order to draw, shape and compute game objects. If we can understand easily what a line is (x1,y1 to x2, y2), just a moment think about a hexagon or a filled non-regular polygon... At first, I show you what is a pixel structure according to this template - and how it draws them on screen :\n```(c++)\n    struct Pixel\n\t{\n\t\tunion\n\t\t{\t\/\/ opaque black pixel\n\t\t\tuint32_t n = 0xFF000000;\n\n\t\t\tstruct\n\t\t\t{\n\t\t\t\tuint8_t r;\n\t\t\t\tuint8_t g;\n\t\t\t\tuint8_t b;\n\t\t\t\tuint8_t a; \/\/ alpha\n\t\t\t};\n\t\t};\n\t};\n\n(...)\n\n    bool xGameEngine::Draw(const gck::vi2d& pos, Pixel p)\n\t{\n\t\tif (!pDrawTarget) \n\t\t\treturn false;\n\n\t\tPixel d = pDrawTarget->GetPixel(pos);\n\t\t\/\/ escape quickly if the pixel has the same color\n\t\tif (p == d) \n\t\t\treturn false;\n\n\t\tfloat a = (float)(p.a \/ 255.0f);\n\t\tfloat c = 1 - a;\n\t\tfloat r = a * (float)p.r + c * (float)d.r;\n\t\tfloat g = a * (float)p.g + c * (float)d.g;\n\t\tfloat b = a * (float)p.b + c * (float)d.b;\n\t\t\/\/ new pixel at pos\n\t\treturn pDrawTarget->SetPixel(pos, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));\n\t}\n```\nWhen I started my project canvas, I thought about a clean font in-game without any third part. I remembered a script which I made under Unity in order to write text as a single sprite. If you remember TakeYourMedsDarling (a previous entry for the LD 49), I used a system like this... How does it work? In fact, it is more or less similar to the Chip-8 font system (lol). Imagine a sprite 5x7 pixels (chip-8 used a 4x4 pixels size). Imagine now 5 bytes and their bits. For each column the function reads a hexadecimal value and each converted bit 1 becomes a colored pixel - a bit 0 becomes an alpha null pixel. So the letter A can be write with the bits : \n```\nstd::vector<unsigned char> keyA{ 0x7E, 0x09, 0x09, 0x09, 0x7E }; \n```\nFor each letter, number or special char, I created them using 5 hexadecimal values. I wasted many time, but this font is mine \u2013 and it works as expected giving retro vibes to the game. Take a look at the function \u2013 notice how it converts a char to booleans\u00a0: \n```\n    void xGameEngine::DrawString(gck::vi2d pos, std::string &str, gck::Pixel p, int32_t scale)\n\t{\t\/\/ our letters scale - only 5x7 pixels\n\t\tshort fontX = 5; \n\t\tshort fontY = 7; \n\t\tshort pp = pos.x;\n\n\t\tif (stamp == nullptr) \n\t\t\tDrawFont(fontX, fontY);\n\t\t\/\/ only lower case\n\t\tstd::vector<unsigned char> byte;\n\t\ttransform(str.begin(), str.end(), str.begin(), ::toupper);\n\n\t\tfor (size_t i = 0; i < str.length(); i++)\n\t\t{\n\t\t\tif (str[i] == '\\n')\n\t\t\t{\n\t\t\t\tpos.y += (fontY + 1) * scale;\n\t\t\t\tpos.x = pp * scale;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tbyte = checkChar(str[i]);\n\n\t\t\tfor (int x = 0; x < fontX; x++)\n\t\t\t\tfor (int y = 0; y < fontY; y++)\n\t\t\t\t\tif ((byte[x] >> y) & 0x1)\n\t\t\t\t\t\tstamp->SetPixel(gck::vi2d(x, y), p); \/\/ this one !!!\n\t\t\t\t\telse\n\t\t\t\t\t\tstamp->SetPixel(gck::vi2d(x, y), gck::BLANK);\n\n\t\t\tDrawSprite(pos, stamp, scale);\n\t\t\tpos.x += (fontX + 1) * scale; \/\/ shift to the next char\n\t\t}\n\t}\n```\nThe main difficulty had been to draw some non-regular polygons - the levels on which rebounds the colored balls. It was not too hard to draw a shape, just lines using a main **std::vector** with coordinates (x,y). I could use **std::pair**, but no... However I had no clue how I could fill shapes. There are many ways in order to fill a shape, but they wasted my tiny CPU resources - and as I said I had to use them carefully. Then I saw a raylight in the darkest fog! According to the same **std::vector** I implemented a function which checks all pixels and stores them if they are inside a non-regular polygon coordinates. However I called this function in the appCreate() section - so storing pixels during the first frame, drawing them in the appUpdate() section. The renderer was really smooth - and the resources were saved. \n```\n    \/\/ function in order to check if a point is inside a polygon\n\tbool xGameEngine::isPointInsidePolygon(std::vector<gck::vi2d> vertices, gck::vi2d pos)\n\t{\n\t\tbool isInside = false;\n\t\tauto num_verts = vertices.size();\n\n\t\tfor (size_t i = 0, j = num_verts - 1; i < num_verts; j = i++)\n\t\t{\n\t\t\tdouble x1 = vertices[i].x;\n\t\t\tdouble y1 = vertices[i].y;\n\t\t\tdouble x2 = vertices[j].x;\n\t\t\tdouble y2 = vertices[j].y;\n\n\t\t\tif (((y1 > pos.y) != (y2 > pos.y)) && (pos.x < (x2 - x1) * (pos.y - y1) \/ (y2 - y1) + x1))\n\t\t\t\tisInside = !isInside;\n\t\t}\n\n\t\treturn isInside;\n\t}\n```\n![Sans titre.png](\/\/\/raw\/991\/z\/53293.png)\n\nI really like the background under some games developed using Pico-8. It is like a canvas or a curtain. In my template, I had a function in order to apply a single color to each pixel so as to \u00ab clean \u00bb the main screen, but I wanted more...\t\n\nIn C++, we can use some ternary operator and I really like it. It is more than a simple condition variable \u2013 it allows us to develop some behavior according to a condition. I said to myself that using coordinates I could apply another color to the pixel if it has a particular feature. So I check pixels using this ternary operator :\t\n\nSo I got vertical lines according to the width. Then I found a tip. Simply I add +1 pixel to my game X resolution and it shifts everything on screen. Again I used a ternary operator. Finally I have some zebra lines. Sometimes a little thing can change everything...\t\n```\n    \/\/ clear the entire sprite (or screen) according a specific color\n\tvoid xGameEngine::Clear(Pixel p, Pixel pp, int stripe)\n\t{\n\t\tint pixels = pDrawTarget->width * pDrawTarget->height;\n\t\tPixel* m = GetDrawTarget()->GetData();\n\n\t\tfor (int i = 0; i < pixels; ++i)\n\t\t\tstripe != 0 ? (i % stripe ? m[i] = p : m[i] = pp) : m[i] = p;\n\t}\n```\nAt the end, my template was able to draw many shapes. below you can see every declaration which are explicit :\n```\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ useful functions declarations\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ninline float map(int s, float a1, float a2, float b1, float b2);\ninline float computeDistance(const gck::vi2d& p1, const gck::vi2d& p2);\ninline float lerp(float a, float b, float f);\ninline vf2d GetVector(int32_t nIndex, int32_t fRadius, int32_t fFactor);\nvi2d rotatePoint(gck::vi2d p, gck::vi2d axis, float angle);\nbool inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3);\nbool isPointInsidePolygon(std::vector<gck::vi2d> vertices, gck::vi2d px);\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ functions declarations in order to draw everything\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\nvirtual bool Draw(const gck::vi2d& pos, Pixel p = gck::WHITE);\nvoid DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE);\nvoid DrawFrame(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE, bool fill = false); \/\/ simple rectangle\nvoid DrawRect(const gck::vi2d& pos, const int32_t w, const int32_t h, const int& angle = 0, Pixel p = gck::WHITE, bool fill = false); \/\/ rotation available\nvoid DrawTris(const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3, const int& angle, Pixel p = gck::WHITE, bool fill = false);\nvoid DrawCircle(const gck::vi2d& pos, const int& fRadius, Pixel p = gck::WHITE, bool fill = false, const int& thickness = 0);\nvoid DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p = gck::WHITE, bool fill = false); \/\/ regular polygon\nvoid DrawPolygon(const std::vector<gck::vi2d> vertices, Pixel p = gck::WHITE, bool fill = false); \/\/ no regular polygon\nvoid DrawSprite(const gck::vi2d& pos, Sprite* sprite, uint32_t scale = 1);\nvoid DrawFont(int32_t x, int32_t y); \/\/ in order to write string\nstd::vector<unsigned char> checkChar(char c);\nvoid DrawString(gck::vi2d pos, std::string &str, gck::Pixel p = gck::WHITE, int32_t scale = 1);\nvoid Clear(Pixel p, Pixel pp = VERY_DARK_GREY, int stripe = 0); \/\/ to clear screen each frame\n```\nAnd it is enough so as to create a game :golf: \n\nAmong all these functions I really like this one which allows to draw a regular polygon. One single function to draw a square, a pentagon, a hexagon, a heptagon or an octagon - really useful. Take a look at the way in order to fill them. Each edge has two points and the third is the center of the polygon. Then I fill these triangular shapes (as you can see, there is a function to rotate each shape or point) : \n```\n    \/\/ check if a point is inside a triangle (used to fill regular polygons)\n\tbool xGameEngine::inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3)\n\t{\n\t\tint s = (pos1.x - pos3.x) * (p.y - pos3.y) - (pos1.y - pos3.y) * (p.x - pos3.x);\n\t\tint t = (pos2.x - pos1.x) * (p.y - pos1.y) - (pos2.y - pos1.y) * (p.x - pos1.x);\n\n\t\tif ((s < 0) != (t < 1) && s != 0 && t != 1)\n\t\t\treturn false;\n\n\t\tint d = (pos3.x - pos2.x) * (p.y - pos2.y) - (pos3.y - pos2.y) * (p.x - pos2.x);\n\n\t\treturn d == 0 || (d < 0) == (s + t <= 0);\n\t}\n\n(...)\n\n    \/\/ draws a regular polygon according to a single point, a factor and a radius\n\tvoid xGameEngine::DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p, bool fill)\n\t{\n\t\tif (fFactor > 8) \n\t\t\tfFactor = 8; \/\/ beyond 8 it's almost a circle no ?\n\t\t\/\/ sometimes a point at the center is required\n\t\tif (fill) \n\t\t\tDraw(pos, p);\n\n\t\tfor (int i = 0; i < fFactor; i++)\n\t\t{\n\t\t\tgck::vf2d vPoint = rotatePoint(GetVector(i, fRadius, fFactor) + pos, pos, static_cast<float>(angle));\n\t\t\tgck::vf2d pPoint = rotatePoint(GetVector(i - 1, fRadius, fFactor) + pos, pos, static_cast<float>(angle));\n\n\t\t\tfill ? DrawTris(pos, vPoint, pPoint, 0, p, true) : DrawLine(vPoint, pPoint, p);\n\t\t}\n\t}\n```\nI could continue to explain many, many, many things about this template - and especially how I developed the physics for Shabodoo, but I guess that for now it is enough. You can try Shabadoo - and of course you can rate it. Leave a comment - I really appreciate it, and then I have a link in order to rate your own project. I hope that you liked those explanations. If I can improve some parts of my template I will share it on GitHub, but right now it is still bugged and not clearly coded. Stay tuned ++ \n\nhttps:\/\/ldjam.com\/events\/ludum-dare\/51\/shabadoo","title":"Shabadoo - a last devlog","wayback_source":[]}