Geckoo1337

Ludum Dare 50

Loop need more ratings

Hello everyone. This is my entry for the 50th LudumDare session. A few hours before starting, my computer let me down. I used an old laptop to participate at this event, but you can imagine that it was not really easy for me. For this reason, I did a simple casual game in which you control a bullet in an infinite loop trying to avoid other sprites - but the end is just inevitable. There is a leaderboard on-line in order to save your best score. Rate my game and I will rate yours. Leave a comment. This way I can find your project quickly. Have fun ++

https://ldjam.com/events/ludum-dare/50/loop

Use Left Mouse Button to change direction or SpaceBar

Loop.png

Ludum Dare 51

Theme Suggestions

Theme always sucks

Theme always sucks

Done

LD51.png

Theorem on Steam

Some keys for my game Theorem on Steam. If you like it, post a comment. I wish you the best ++

WGGK2-KTBA4-MYL33

4DK02-B6J0A-KJRTK

8Z9YN-7T4YC-KJ2QJ

44HZL-PTEQ2-QAPG5

CKV3E-RDVEW-B2A7V

HGP97-D3LVT-HAH29

IFI92-NPXF2-PITC3

LTXG9-DK9DA-5B6JF

AIYCX-CHYIX-IA30F

0B4YN-JPZQR-EVX3V

RXVLX-W06MX-PMGJ0

DJKK2-GX88T-Z7ANG

8QCMG-76PWW-XF7LQ

Q7K58-YM3Z8-9XPF9

2HYLP-57EX0-LI2C3

BVFXA-JRM52-VCEPQ

0CKBQ-3JKPR-PX4XL

8KPX5-Q0CJR-9KBIB

X9WXE-HV65B-3PVR4

GTT9J-7ER95-3DVR8

Shabadoo

I am creating a physical game - something between a snooker and a golf. The physics is done and works pretty well. You lose a stroke every 10 seconds. I don't use any engine for this project - only my template which has been developed in C++ without any dependencies. Tomorrow I will work on the levels. I hope that all is fine for you too. I wish you the best. Bye ++

shabadoo.png

LudumDare 52

LudumDare 52 for the January 6th 2023. What a great new!!! If I understand correctly we have 3 LudumDare events each year? Like a few years ago. YOU MADE MY DAY ++

dumbos-modi-ji.gif

Shabadoo

https://ldjam.com/events/ludum-dare/51/shabadoo

4fa8b.png

Hello. 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...

I 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 : ```(c++) struct Pixel { union { // opaque black pixel uint32_t n = 0xFF000000;

        struct
        {
            uint8_t r;
            uint8_t g;
            uint8_t b;
            uint8_t a; // alpha
        };
    };
};

(...)

bool xGameEngine::Draw(const gck::vi2d& pos, Pixel p)
{
    if (!pDrawTarget) 
        return false;

    Pixel d = pDrawTarget->GetPixel(pos);
    // escape quickly if the pixel has the same color
    if (p == d) 
        return false;

    float a = (float)(p.a / 255.0f);
    float c = 1 - a;
    float r = a * (float)p.r + c * (float)d.r;
    float g = a * (float)p.g + c * (float)d.g;
    float b = a * (float)p.b + c * (float)d.b;
    // new pixel at pos
    return pDrawTarget->SetPixel(pos, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
}

When 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 : std::vector keyA{ 0x7E, 0x09, 0x09, 0x09, 0x7E }; For each letter, number or special char, I created them using 5 hexadecimal values. I wasted many time, but this font is mine – and it works as expected giving retro vibes to the game. Take a look at the function – notice how it converts a char to booleans : void xGameEngine::DrawString(gck::vi2d pos, std::string &str, gck::Pixel p, int32_t scale) { // our letters scale - only 5x7 pixels short fontX = 5; short fontY = 7; short pp = pos.x;

    if (stamp == nullptr) 
        DrawFont(fontX, fontY);
    // only lower case
    std::vector<unsigned char> byte;
    transform(str.begin(), str.end(), str.begin(), ::toupper);

    for (size_t i = 0; i < str.length(); i++)
    {
        if (str[i] == '

') { pos.y += (fontY + 1) * scale; pos.x = pp * scale; continue; }

        byte = checkChar(str[i]);

        for (int x = 0; x < fontX; x++)
            for (int y = 0; y < fontY; y++)
                if ((byte[x] >> y) & 0x1)
                    stamp->SetPixel(gck::vi2d(x, y), p); // this one !!!
                else
                    stamp->SetPixel(gck::vi2d(x, y), gck::BLANK);

        DrawSprite(pos, stamp, scale);
        pos.x += (fontX + 1) * scale; // shift to the next char
    }
}

The 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. // function in order to check if a point is inside a polygon bool xGameEngine::isPointInsidePolygon(std::vector vertices, gck::vi2d pos) { bool isInside = false; auto num_verts = vertices.size();

    for (size_t i = 0, j = num_verts - 1; i < num_verts; j = i++)
    {
        double x1 = vertices[i].x;
        double y1 = vertices[i].y;
        double x2 = vertices[j].x;
        double y2 = vertices[j].y;

        if (((y1 > pos.y) != (y2 > pos.y)) && (pos.x < (x2 - x1) * (pos.y - y1) / (y2 - y1) + x1))
            isInside = !isInside;
    }

    return isInside;
}

``` Sans titre.png

I 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 « clean » the main screen, but I wanted more...

In C++, we can use some ternary operator and I really like it. It is more than a simple condition variable – 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 :

So 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...
``` // clear the entire sprite (or screen) according a specific color void xGameEngine::Clear(Pixel p, Pixel pp, int stripe) { int pixels = pDrawTarget->width * pDrawTarget->height; Pixel* m = GetDrawTarget()->GetData();

    for (int i = 0; i < pixels; ++i)
        stripe != 0 ? (i % stripe ? m[i] = p : m[i] = pp) : m[i] = p;
}

At the end, my template was able to draw many shapes. below you can see every declaration which are explicit : /////////////////////////////////////////////////////// // useful functions declarations /////////////////////////////////////////////////////// inline float map(int s, float a1, float a2, float b1, float b2); inline float computeDistance(const gck::vi2d& p1, const gck::vi2d& p2); inline float lerp(float a, float b, float f); inline vf2d GetVector(int32t nIndex, int32t fRadius, int32t fFactor); vi2d rotatePoint(gck::vi2d p, gck::vi2d axis, float angle); bool inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3); bool isPointInsidePolygon(std::vector vertices, gck::vi2d px); /////////////////////////////////////////////////////// // functions declarations in order to draw everything /////////////////////////////////////////////////////// virtual bool Draw(const gck::vi2d& pos, Pixel p = gck::WHITE); void DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE); void DrawFrame(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE, bool fill = false); // simple rectangle void DrawRect(const gck::vi2d& pos, const int32t w, const int32t h, const int& angle = 0, Pixel p = gck::WHITE, bool fill = false); // rotation available void DrawTris(const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3, const int& angle, Pixel p = gck::WHITE, bool fill = false); void DrawCircle(const gck::vi2d& pos, const int& fRadius, Pixel p = gck::WHITE, bool fill = false, const int& thickness = 0); void DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32t fFactor, const int& angle, Pixel p = gck::WHITE, bool fill = false); // regular polygon void DrawPolygon(const std::vector vertices, Pixel p = gck::WHITE, bool fill = false); // no regular polygon void DrawSprite(const gck::vi2d& pos, Sprite* sprite, uint32t scale = 1); void DrawFont(int32t x, int32t y); // in order to write string std::vector checkChar(char c); void DrawString(gck::vi2d pos, std::string &str, gck::Pixel p = gck::WHITE, int32t scale = 1); void Clear(Pixel p, Pixel pp = VERYDARKGREY, int stripe = 0); // to clear screen each frame ``` And it is enough so as to create a game :golf:

Among 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) : ``` // check if a point is inside a triangle (used to fill regular polygons) bool xGameEngine::inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3) { int s = (pos1.x - pos3.x) * (p.y - pos3.y) - (pos1.y - pos3.y) * (p.x - pos3.x); int t = (pos2.x - pos1.x) * (p.y - pos1.y) - (pos2.y - pos1.y) * (p.x - pos1.x);

    if ((s < 0) != (t < 1) && s != 0 && t != 1)
        return false;

    int d = (pos3.x - pos2.x) * (p.y - pos2.y) - (pos3.y - pos2.y) * (p.x - pos2.x);

    return d == 0 || (d < 0) == (s + t <= 0);
}

(...)

// draws a regular polygon according to a single point, a factor and a radius
void xGameEngine::DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p, bool fill)
{
    if (fFactor > 8) 
        fFactor = 8; // beyond 8 it's almost a circle no ?
    // sometimes a point at the center is required
    if (fill) 
        Draw(pos, p);

    for (int i = 0; i < fFactor; i++)
    {
        gck::vf2d vPoint = rotatePoint(GetVector(i, fRadius, fFactor) + pos, pos, static_cast<float>(angle));
        gck::vf2d pPoint = rotatePoint(GetVector(i - 1, fRadius, fFactor) + pos, pos, static_cast<float>(angle));

        fill ? DrawTris(pos, vPoint, pPoint, 0, p, true) : DrawLine(vPoint, pPoint, p);
    }
}

``` I 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 ++

https://ldjam.com/events/ludum-dare/51/shabadoo

Shabadoo

https://ldjam.com/events/ludum-dare/51/shabadoo

4fa8b.png

Hello. 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...

I 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 : ```(c++) struct Pixel { union { // opaque black pixel uint32_t n = 0xFF000000;

        struct
        {
            uint8_t r;
            uint8_t g;
            uint8_t b;
            uint8_t a; // alpha
        };
    };
};

(...)

bool xGameEngine::Draw(const gck::vi2d& pos, Pixel p)
{
    if (!pDrawTarget) 
        return false;

    Pixel d = pDrawTarget->GetPixel(pos);
    // escape quickly if the pixel has the same color
    if (p == d) 
        return false;

    float a = (float)(p.a / 255.0f);
    float c = 1 - a;
    float r = a * (float)p.r + c * (float)d.r;
    float g = a * (float)p.g + c * (float)d.g;
    float b = a * (float)p.b + c * (float)d.b;
    // new pixel at pos
    return pDrawTarget->SetPixel(pos, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
}

When 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 : std::vector keyA{ 0x7E, 0x09, 0x09, 0x09, 0x7E }; For each letter, number or special char, I created them using 5 hexadecimal values. I wasted many time, but this font is mine – and it works as expected giving retro vibes to the game. Take a look at the function – notice how it converts a char to booleans : void xGameEngine::DrawString(gck::vi2d pos, std::string &str, gck::Pixel p, int32_t scale) { // our letters scale - only 5x7 pixels short fontX = 5; short fontY = 7; short pp = pos.x;

    if (stamp == nullptr) 
        DrawFont(fontX, fontY);
    // only lower case
    std::vector<unsigned char> byte;
    transform(str.begin(), str.end(), str.begin(), ::toupper);

    for (size_t i = 0; i < str.length(); i++)
    {
        if (str[i] == '

') { pos.y += (fontY + 1) * scale; pos.x = pp * scale; continue; }

        byte = checkChar(str[i]);

        for (int x = 0; x < fontX; x++)
            for (int y = 0; y < fontY; y++)
                if ((byte[x] >> y) & 0x1)
                    stamp->SetPixel(gck::vi2d(x, y), p); // this one !!!
                else
                    stamp->SetPixel(gck::vi2d(x, y), gck::BLANK);

        DrawSprite(pos, stamp, scale);
        pos.x += (fontX + 1) * scale; // shift to the next char
    }
}

The 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. // function in order to check if a point is inside a polygon bool xGameEngine::isPointInsidePolygon(std::vector vertices, gck::vi2d pos) { bool isInside = false; auto num_verts = vertices.size();

    for (size_t i = 0, j = num_verts - 1; i < num_verts; j = i++)
    {
        double x1 = vertices[i].x;
        double y1 = vertices[i].y;
        double x2 = vertices[j].x;
        double y2 = vertices[j].y;

        if (((y1 > pos.y) != (y2 > pos.y)) && (pos.x < (x2 - x1) * (pos.y - y1) / (y2 - y1) + x1))
            isInside = !isInside;
    }

    return isInside;
}

``` Sans titre.png

I 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 « clean » the main screen, but I wanted more...

In C++, we can use some ternary operator and I really like it. It is more than a simple condition variable – 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 :

So 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...
``` // clear the entire sprite (or screen) according a specific color void xGameEngine::Clear(Pixel p, Pixel pp, int stripe) { int pixels = pDrawTarget->width * pDrawTarget->height; Pixel* m = GetDrawTarget()->GetData();

    for (int i = 0; i < pixels; ++i)
        stripe != 0 ? (i % stripe ? m[i] = p : m[i] = pp) : m[i] = p;
}

At the end, my template was able to draw many shapes. below you can see every declaration which are explicit : /////////////////////////////////////////////////////// // useful functions declarations /////////////////////////////////////////////////////// inline float map(int s, float a1, float a2, float b1, float b2); inline float computeDistance(const gck::vi2d& p1, const gck::vi2d& p2); inline float lerp(float a, float b, float f); inline vf2d GetVector(int32t nIndex, int32t fRadius, int32t fFactor); vi2d rotatePoint(gck::vi2d p, gck::vi2d axis, float angle); bool inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3); bool isPointInsidePolygon(std::vector vertices, gck::vi2d px); /////////////////////////////////////////////////////// // functions declarations in order to draw everything /////////////////////////////////////////////////////// virtual bool Draw(const gck::vi2d& pos, Pixel p = gck::WHITE); void DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE); void DrawFrame(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE, bool fill = false); // simple rectangle void DrawRect(const gck::vi2d& pos, const int32t w, const int32t h, const int& angle = 0, Pixel p = gck::WHITE, bool fill = false); // rotation available void DrawTris(const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3, const int& angle, Pixel p = gck::WHITE, bool fill = false); void DrawCircle(const gck::vi2d& pos, const int& fRadius, Pixel p = gck::WHITE, bool fill = false, const int& thickness = 0); void DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32t fFactor, const int& angle, Pixel p = gck::WHITE, bool fill = false); // regular polygon void DrawPolygon(const std::vector vertices, Pixel p = gck::WHITE, bool fill = false); // no regular polygon void DrawSprite(const gck::vi2d& pos, Sprite* sprite, uint32t scale = 1); void DrawFont(int32t x, int32t y); // in order to write string std::vector checkChar(char c); void DrawString(gck::vi2d pos, std::string &str, gck::Pixel p = gck::WHITE, int32t scale = 1); void Clear(Pixel p, Pixel pp = VERYDARKGREY, int stripe = 0); // to clear screen each frame ``` And it is enough so as to create a game :golf:

Among 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) : ``` // check if a point is inside a triangle (used to fill regular polygons) bool xGameEngine::inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3) { int s = (pos1.x - pos3.x) * (p.y - pos3.y) - (pos1.y - pos3.y) * (p.x - pos3.x); int t = (pos2.x - pos1.x) * (p.y - pos1.y) - (pos2.y - pos1.y) * (p.x - pos1.x);

    if ((s < 0) != (t < 1) && s != 0 && t != 1)
        return false;

    int d = (pos3.x - pos2.x) * (p.y - pos2.y) - (pos3.y - pos2.y) * (p.x - pos2.x);

    return d == 0 || (d < 0) == (s + t <= 0);
}

(...)

// draws a regular polygon according to a single point, a factor and a radius
void xGameEngine::DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p, bool fill)
{
    if (fFactor > 8) 
        fFactor = 8; // beyond 8 it's almost a circle no ?
    // sometimes a point at the center is required
    if (fill) 
        Draw(pos, p);

    for (int i = 0; i < fFactor; i++)
    {
        gck::vf2d vPoint = rotatePoint(GetVector(i, fRadius, fFactor) + pos, pos, static_cast<float>(angle));
        gck::vf2d pPoint = rotatePoint(GetVector(i - 1, fRadius, fFactor) + pos, pos, static_cast<float>(angle));

        fill ? DrawTris(pos, vPoint, pPoint, 0, p, true) : DrawLine(vPoint, pPoint, p);
    }
}

``` I 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 ++

https://ldjam.com/events/ludum-dare/51/shabadoo

Shabadoo - a last devlog

https://ldjam.com/events/ludum-dare/51/shabadoo

4fa8b.png

Hello. 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...

I 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 : ```(c++) struct Pixel { union { // opaque black pixel uint32_t n = 0xFF000000;

        struct
        {
            uint8_t r;
            uint8_t g;
            uint8_t b;
            uint8_t a; // alpha
        };
    };
};

(...)

bool xGameEngine::Draw(const gck::vi2d& pos, Pixel p)
{
    if (!pDrawTarget) 
        return false;

    Pixel d = pDrawTarget->GetPixel(pos);
    // escape quickly if the pixel has the same color
    if (p == d) 
        return false;

    float a = (float)(p.a / 255.0f);
    float c = 1 - a;
    float r = a * (float)p.r + c * (float)d.r;
    float g = a * (float)p.g + c * (float)d.g;
    float b = a * (float)p.b + c * (float)d.b;
    // new pixel at pos
    return pDrawTarget->SetPixel(pos, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
}

When 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 : std::vector keyA{ 0x7E, 0x09, 0x09, 0x09, 0x7E }; For each letter, number or special char, I created them using 5 hexadecimal values. I wasted many time, but this font is mine – and it works as expected giving retro vibes to the game. Take a look at the function – notice how it converts a char to booleans : void xGameEngine::DrawString(gck::vi2d pos, std::string &str, gck::Pixel p, int32_t scale) { // our letters scale - only 5x7 pixels short fontX = 5; short fontY = 7; short pp = pos.x;

    if (stamp == nullptr) 
        DrawFont(fontX, fontY);
    // only lower case
    std::vector<unsigned char> byte;
    transform(str.begin(), str.end(), str.begin(), ::toupper);

    for (size_t i = 0; i < str.length(); i++)
    {
        if (str[i] == '

') { pos.y += (fontY + 1) * scale; pos.x = pp * scale; continue; }

        byte = checkChar(str[i]);

        for (int x = 0; x < fontX; x++)
            for (int y = 0; y < fontY; y++)
                if ((byte[x] >> y) & 0x1)
                    stamp->SetPixel(gck::vi2d(x, y), p); // this one !!!
                else
                    stamp->SetPixel(gck::vi2d(x, y), gck::BLANK);

        DrawSprite(pos, stamp, scale);
        pos.x += (fontX + 1) * scale; // shift to the next char
    }
}

The 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. // function in order to check if a point is inside a polygon bool xGameEngine::isPointInsidePolygon(std::vector vertices, gck::vi2d pos) { bool isInside = false; auto num_verts = vertices.size();

    for (size_t i = 0, j = num_verts - 1; i < num_verts; j = i++)
    {
        double x1 = vertices[i].x;
        double y1 = vertices[i].y;
        double x2 = vertices[j].x;
        double y2 = vertices[j].y;

        if (((y1 > pos.y) != (y2 > pos.y)) && (pos.x < (x2 - x1) * (pos.y - y1) / (y2 - y1) + x1))
            isInside = !isInside;
    }

    return isInside;
}

``` Sans titre.png

I 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 « clean » the main screen, but I wanted more...

In C++, we can use some ternary operator and I really like it. It is more than a simple condition variable – 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 :

So 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...
``` // clear the entire sprite (or screen) according a specific color void xGameEngine::Clear(Pixel p, Pixel pp, int stripe) { int pixels = pDrawTarget->width * pDrawTarget->height; Pixel* m = GetDrawTarget()->GetData();

    for (int i = 0; i < pixels; ++i)
        stripe != 0 ? (i % stripe ? m[i] = p : m[i] = pp) : m[i] = p;
}

At the end, my template was able to draw many shapes. below you can see every declaration which are explicit : /////////////////////////////////////////////////////// // useful functions declarations /////////////////////////////////////////////////////// inline float map(int s, float a1, float a2, float b1, float b2); inline float computeDistance(const gck::vi2d& p1, const gck::vi2d& p2); inline float lerp(float a, float b, float f); inline vf2d GetVector(int32t nIndex, int32t fRadius, int32t fFactor); vi2d rotatePoint(gck::vi2d p, gck::vi2d axis, float angle); bool inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3); bool isPointInsidePolygon(std::vector vertices, gck::vi2d px); /////////////////////////////////////////////////////// // functions declarations in order to draw everything /////////////////////////////////////////////////////// virtual bool Draw(const gck::vi2d& pos, Pixel p = gck::WHITE); void DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE); void DrawFrame(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p = gck::WHITE, bool fill = false); // simple rectangle void DrawRect(const gck::vi2d& pos, const int32t w, const int32t h, const int& angle = 0, Pixel p = gck::WHITE, bool fill = false); // rotation available void DrawTris(const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3, const int& angle, Pixel p = gck::WHITE, bool fill = false); void DrawCircle(const gck::vi2d& pos, const int& fRadius, Pixel p = gck::WHITE, bool fill = false, const int& thickness = 0); void DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32t fFactor, const int& angle, Pixel p = gck::WHITE, bool fill = false); // regular polygon void DrawPolygon(const std::vector vertices, Pixel p = gck::WHITE, bool fill = false); // no regular polygon void DrawSprite(const gck::vi2d& pos, Sprite* sprite, uint32t scale = 1); void DrawFont(int32t x, int32t y); // in order to write string std::vector checkChar(char c); void DrawString(gck::vi2d pos, std::string &str, gck::Pixel p = gck::WHITE, int32t scale = 1); void Clear(Pixel p, Pixel pp = VERYDARKGREY, int stripe = 0); // to clear screen each frame ``` And it is enough so as to create a game :golf:

Among 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) : ``` // check if a point is inside a triangle (used to fill regular polygons) bool xGameEngine::inTriangle(const gck::vi2d& p, const gck::vi2d& pos1, const gck::vi2d& pos2, const gck::vi2d& pos3) { int s = (pos1.x - pos3.x) * (p.y - pos3.y) - (pos1.y - pos3.y) * (p.x - pos3.x); int t = (pos2.x - pos1.x) * (p.y - pos1.y) - (pos2.y - pos1.y) * (p.x - pos1.x);

    if ((s < 0) != (t < 1) && s != 0 && t != 1)
        return false;

    int d = (pos3.x - pos2.x) * (p.y - pos2.y) - (pos3.y - pos2.y) * (p.x - pos2.x);

    return d == 0 || (d < 0) == (s + t <= 0);
}

(...)

// draws a regular polygon according to a single point, a factor and a radius
void xGameEngine::DrawPolygon(const gck::vi2d& pos, const int& fRadius, int32_t fFactor, const int& angle, Pixel p, bool fill)
{
    if (fFactor > 8) 
        fFactor = 8; // beyond 8 it's almost a circle no ?
    // sometimes a point at the center is required
    if (fill) 
        Draw(pos, p);

    for (int i = 0; i < fFactor; i++)
    {
        gck::vf2d vPoint = rotatePoint(GetVector(i, fRadius, fFactor) + pos, pos, static_cast<float>(angle));
        gck::vf2d pPoint = rotatePoint(GetVector(i - 1, fRadius, fFactor) + pos, pos, static_cast<float>(angle));

        fill ? DrawTris(pos, vPoint, pPoint, 0, p, true) : DrawLine(vPoint, pPoint, p);
    }
}

``` I 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 ++

https://ldjam.com/events/ludum-dare/51/shabadoo

Is there anybody here?

Hello. Just a little message in order to break this continuous overflow, entailing each day a big amount of spams. It is just an ugly nightmare... I wish you the best, my dear fellows waiting for the next LudumDare. Maybe I will try to participate in the next 7FPS which will be in december. Stay safe. Be careful - we live in a strange world :) God bless you ++

PS : you will find here a few keys for my game Theorem. Have fun ++

gogo.png

Ludum Dare 52

Theme Suggestions

sugg.png

I would like to create something, but not a game - maybe a compiler, an engine, a graphical template, a proof of concept or something else. Why not?

Done

Maybe I am the first one :)

ld.png

Theorem for free (itch.io platform)

This is not a spam post :)

https://geckoo1337.itch.io/theorem/download/teuwp8PGWVaF7jt7WmKR28Dfa-nbheadKrSLFiB2WacVxQ6SfaPvnp

https://geckoo1337.itch.io/theorem/download/Jjuwp8PGWVaF7jt7WmKR28Dfa-pxuHoKEafAqqL9rR3x3qNdxmNVjs

https://geckoo1337.itch.io/theorem/download/5ouwp8PGWVaF7jt7WmKR28Dfa-NG9hhKZ5e3BbX8i8c4yxXevCwPnh

https://geckoo1337.itch.io/theorem/download/3tuwp8PGWVaF7jt7WmKR28Dfa-Gz9xfQve77rcMDnJWbxoZMUa72Uh

https://geckoo1337.itch.io/theorem/download/Yxuwp8PGWVaF7jt7WmKR28Dfa-CqEzp32ukyzQQZRaUL1oUwwqBFH

https://geckoo1337.itch.io/theorem/download/8Bvwp8PGWVaF7jt7WmKR28Dfa-L1kJ2b1RuFGZ3mYc8XHPjWg5H4rs

https://geckoo1337.itch.io/theorem/download/UGvwp8PGWVaF7jt7WmKR28Dfa-d4fKQny3ByBPGbAtWeyAbbEoH76p

Ludum Dare 52

My playlist for this LD52 :)

https://youtu.be/3UaInoDl1YM

Всё я запланировал заранее, чтоб я мог разрабатывать спокойно. Я работаю ночью, а завтра смогу начать мой новый проект. Я не ожидаю ничего от темы, как говорят "theme always sucks". Попробую использовать свой собственный шаблон, но иногда это не достаточно. Поэтому, Юнити остается альтернативой. Я желаю вам всего хорошего. Пока друзья ++

I would like to use my own template in order to create something good, but it is not always possible due to its limited scope. If I cannot develop as I would like, I will use Unity. I wish you the best my dear friends - and don't forget to have fun. Bye ++

Et un dernier mot pour mes amis francophones - bonne session à chacun ++

Star Harvest

StarHarvest.jpg

Hello everyone. I hope that all is fine for you. My project is done - a casual game. If you want to know more - click on the link below. As usual, there is a LeaderBoard on-line :)

Rate my game, leave a comment - and I will rate yours too ++

https://ldjam.com/events/ludum-dare/52/star-harvest

Thank you

LD52.png

https://ldjam.com/events/ludum-dare/52/star-harvest

Thank you everyone. This LudumDare session was amazing as usual - and I had fun developing my project, playing other games. Some of them were just amazing. Bravo to the winners. I did not expect anything about my own project, but I am surprised by its scores which are not bad at all. Thank you ++

PS : the Pixel game Engine which I use for my projects is now available on GitHub with some other stuffs. If you are searching for a simple way to create a prototype (or participating in a GameJam/CodeJam), you could be interested by its simplicity. Take a look at this single header file. High C++ skill required ++

https://github.com/geckoo1337/Geckoo1337-engine

ChatGPT ?

A new post breaking the spam flood? Is there a real being here?

If you are an Unity dev I guess that you know Keijiro Takahashi - an amazing artist with a brilliant skill using Unity and other things. Recently he created a proof-of-concept on how to use ChatGPT inside an Unity project. Many LD members posted some complimentary posts about ChatGPT especially during the last session. Technically ChatGPT is really impressive, but what about us? As Keijiro said "Is it practical? Definitely no! I created this proof-of-concept and proved that it doesn't work yet. It works nicely in some cases and fails very poorly in others. I got several ideas from those successes and failures, which is this project's main aim". So boys, stay on your keyboard working hard to do your own code. He made my day :)

https://github.com/keijiro/AICommand

Ludum Dare 53

Enthusiasm about ChatGPT

I am a little bit disappointed reading all these comments about ChatGPT. I dislike this way in order to define a set of themes - or a behavior. Boys, where is your creativity? Of course, ChatGPT is fun - and the technology behind the curtain is amazing. Honestly I like how it can structure its answers - more concisely than Wikipedia for mobile devices and often clever, but what about us - the LudumDare Community? Do you really need to free your brain of pure human being's reflections? However, if you want to try ChatGPT, I created a console application in C# which allows you to send some requests to OpenAI according to its protocol. It's fun for a while - no more. The repository is shared on GitHub at the link below. See you later. I wish you the best ++

https://github.com/geckoo1337/ChatGPT

LD53.png

Done

Whatever it will be, don't forget that The Theme Always Sucks ++

LD53.png

Theorem for free

​During a few days - and before the next LudumDare - my project Theorem is available on Itch.io for free. If you like Puzzle games I guess that you could appreciate it. Have fun ++

https://geckoo1337.itch.io/theorem

rsbv3Q.png