W jakiej technologii najłatwiej zrobić prostą grę?

0

Gra jest bardzo prosta. Trójkąt przesuwa się na boki i strzela w obiekty u góry planszy, obiekty strzelają do trójkąta. Jak trójkąt dostanie strzał zmienia się w ludzika, który jest bezbronny, nie strzela, gdy ludzik stanie pod czarnym kwadratem jest broniony przez ten kwadrat (trójkąt również jest broniony przez kwadrat) i zamienić się może w strzelający trójkąt ponownie, ale po zamianie w trójkąt czarny kwadrat znika. Są więc 3 kwadraty, czyli 3 szanse że po otrzymaniu strzału trójkąt może powrócić do gry i zlikwidować wszystkie obiekty u góry planszy. Są jeszcze inne elementy tej gry, ale szkielet jest taki.
W czym to najłatwiej wykonać? Może monogame byłoby dobre?

gra retro.jpg

0

A co znasz?

0
stivens napisał(a):

A co znasz?

Głównie delphi i trochę monogame i c#. Ale chętnie spróbowałbym Godota, bo wydaje się łatwy do tego celu. Może jest jeszcze coś łatwiejszego?

2

No to najlatwiej w tym co znasz.

2

Możesz to szybko wyklikać w czymś takim jak GameMaker, ale do tak prostej gierki nada się cokolwiek, choćby goły język programowania plus jakieś API multimedialne, pokroju SDL. Najszybciej będzie zrobić tę grę w technologii, którą znasz, ewentualnie w której da się sporo wyklikać.

0
furious programming napisał(a):

Możesz to szybko wyklikać w czymś takim jak GameMaker, ale do tak prostej gierki nada się cokolwiek, choćby goły język programowania plus jakieś API multimedialne, pokroju SDL. Najszybciej będzie zrobić tę grę w technologii, którą znasz, ewentualnie w której da się sporo wyklikać.

Spróbuję zatem w unDelphix w Delphi xe8.

1

Najprościej byłoby w jakimś dużym frameworku do gier jak Unity (c#), libdx (js, java) i pygame (python).

1

Dodam, że nawet w dobrym narzędziu nie ma drogi na skróty. Musisz się nauczyć je obsługiwać, żeby stworzyć grę. Nawet taką prostą.

W gotowej grze możesz podmienić grafiki na dowolne obiekty. Więc to, że gra ma retro grafikę, nie oznacza, że stworzenie takiej gry będzie łatwiejsze.

1
Romlus napisał(a):
stivens napisał(a):

A co znasz?

Głównie delphi i trochę monogame i c#. Ale chętnie spróbowałbym Godota, bo wydaje się łatwy do tego celu. Może jest jeszcze coś łatwiejszego?

I powinieneś zostać przy Godocie, to byłby najlepszy wybór do takiego prostego projektu. W oficjalnej dokumentacji masz przykłady z omówionym kodem i fajne projekty na YT od początku do końca.

0
tmk3 napisał(a):
Romlus napisał(a):
stivens napisał(a):

A co znasz?

Głównie delphi i trochę monogame i c#. Ale chętnie spróbowałbym Godota, bo wydaje się łatwy do tego celu. Może jest jeszcze coś łatwiejszego?

I powinieneś zostać przy Godocie, to byłby najlepszy wybór do takiego prostego projektu. W oficjalnej dokumentacji masz przykłady z omówionym kodem i fajne projekty na YT od początku do końca.

Właśnie zająłem się tym w Godocie. Jest jakaś książka po polsku o Godocie? Albo jakieś tutoriale po polsku?

1

@Romlus: nie szukałem w języku polskim, pamiętam, że część dokumentacji jest na polski przetłumaczona. Większość tutoriali jest w "prostym" angielskim, więc pewnie uda ci się zrozumieć kontekst (ewentualnie z małą pomocą translatora). Są też grupy discordowe, gdzie można znaleźć naprawdę szybką pomoc, jeśli będziesz potrzebował, to mogę wieczorem poszukać do nich linku i ci wysłać. Na pewno to dobre miejsce na początek

3

Dla prostej grafiki stary poczciwy OpenGL byłby w stanie takie coś narysować. Wiem, że teraz jest inny nowocześniejszy styl programowania w OGL z szaderami, ale stary nadal działa i będzie działać. Taki prosty przykład z wykorzystaniem SDL oraz OpenGL w trybie bezpośrednim.

// g++ -o main main.cpp -std=c++20 -Wall -Wextra `sdl2-config --cflags --libs` -lOpenGL32 -lGLU32 -lm && ./main

#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL2/SDL.h>

#include <cmath>
#include <iostream>
#include <numbers>

using std::numbers::pi;

struct vec2 { float x, y; };
struct vec3 { float x, y, z; };

const vec3 orange{0.8, 0.5, 0.0};
const vec3 light{0.8, 0.8, 0.8};
const vec3 dark{0.1, 0.1, 0.1};

constexpr int width  = 480;
constexpr int height = 320;

// functions declarations
void initGL();
void setOrigin(const vec3& position);
void drawTriangle(const vec2& v1, const vec2& v2, const vec2& v3, const vec3& color);
void drawQuad(const float width, const float height, const vec3& color);
void drawHexagon(const float radius, const vec3& color);

int main(int, char*[]) {
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window* ws = SDL_CreateWindow("gra", 50, 50, width, height, SDL_WINDOW_OPENGL);
    SDL_GLContext ctx = SDL_GL_CreateContext(ws);
    SDL_GL_MakeCurrent(ws, ctx);

    initGL();

    bool quit = false;
    for (;;) {
        // process events
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (((event.type == SDL_QUIT) || (event.type == SDL_KEYDOWN)) &&
                (event.key.keysym.sym == SDLK_ESCAPE)) {
                quit = true;
            }
        }
        if (quit) break;

        // clear screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // draw section
        setOrigin({(width / 10.0)*1.5, height - 20, 0});
        for (int i = 0; i < 8; i++) {
            drawHexagon(10, orange);
            glTranslatef(width / 10, 0, 0);
        }

        setOrigin({width / 2, 20, 0});
        drawTriangle({0, 0}, {20, 0}, {10, 20}, light);

        setOrigin({40, 100, 0});
        drawQuad(100, 50, dark);

        // swap buffers
        SDL_GL_SwapWindow(ws);
    }

    SDL_GL_DeleteContext(ctx);
    SDL_DestroyWindow(ws);
    SDL_Quit();

    return 0;
}

void initGL() {
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.3f, 0.3f, 0.5f, 1.0f);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);

    glMatrixMode(GL_MODELVIEW);
}

void setOrigin(const vec3& position) {
    glLoadIdentity();
    glTranslatef(position.x, position.y, position.z);
}

void drawTriangle(const vec2& v1, const vec2& v2, const vec2& v3, const vec3& color) {
    glBegin(GL_TRIANGLES);
        glColor3fv(&color.x);
        glVertex2fv(&v1.x);
        glVertex2fv(&v2.x);
        glVertex2fv(&v3.x);
    glEnd();
}

void drawQuad(const float width, const float height, const vec3& color) {
    glBegin(GL_QUADS);
        glColor3fv(&color.x);
        glVertex2f(0, 0);
        glVertex2f(width, 0);
        glVertex2f(width, height);
        glVertex2f(0, height);
    glEnd();
}

void drawHexagon(const float radius, const vec3& color) {
    glBegin(GL_POLYGON);
        glColor3fv(&color.x);
        for (int i = 0; i < 6; ++i) {
            glVertex2f(radius * cos(i * 60 * pi / 180.0),
                       radius * sin(i * 60 * pi / 180.0));
        }
    glEnd();
}

screenshot-20230129231903.png

SDL jest tutaj do tworzenia okna i zainicjowania OpenGLa, ale dla grafiki tylko 2D to może się on bez niego obejść. Osobiście dla mnie OGL jest wygodniejszy i ma więcej możliwości dlatego wole z niego korzystać nawet do grafiki dwuwymiarowej.

Sprawdź też koniecznie SFML https://www.sfml-dev.org/ . Dość ciekawa biblioteka w funkcjonalności podobna do SDLa. W przeciwieństwie do SDL napisana w stylu obiektowym.

0
jvoytech napisał(a):

SDL jest tutaj do tworzenia okna i zainicjowania OpenGLa, ale dla grafiki tylko 2D to może się on bez niego obejść. Osobiście dla mnie OGL jest wygodniejszy i ma więcej możliwości dlatego wole z niego korzystać nawet do grafiki dwuwymiarowej.

OGL ma więcej możliwości, ale na pewno nie jest wygodniejszy od renderera SDL-a. Sam pokazałeś, że do namalowania prymitywów najpierw trzeba zainicjalizować OGL-a i go poustawiać, a potem napisać kupę kodu. Tymczasem renderer SDL-a nie tylko może używać dowolnego API (OpenGL, DirectX, Vulkan, Metal itd.), ale też posiada wrappery na wiele rzeczy, w tym SDL_RenderGeometry do prymitywów. Poza tym, renderer jest częścią SDL-a, więc nie potrzeba żadnych dodatkowych nagłówków.

Sprawdź też koniecznie SFML https://www.sfml-dev.org/ . Dość ciekawa biblioteka w funkcjonalności podobna do SDLa. W przeciwieństwie do SDL napisana w stylu obiektowym.

Nie powiedziałbym, że obiektowość jest zaletą (dla mnie nie jest), ale to już kwestia gustu. ;)

0

A w Unity dodajesz mesh na scenę, dodajesz do obiektu skrypt i w tym skrypcie już sobie programujesz samo zachowanie obiektu.

screenshot-20230130002755.png

Kolor obiektu można zrealizować tworząc materiał, który potem trzeba podpiąć pod odpowiednie pole skryptu renderera dołączonego do obiektu.

0

@jvoytech: pamiętaj, że OP zna, jak sam napisał:

Romlus napisał(a):

Głównie delphi i trochę monogame i c#. Ale chętnie spróbowałbym Godota, bo wydaje się łatwy do tego celu. Może jest jeszcze coś łatwiejszego?

Rzucanie w twarz taką ilością kodu z c++ to raczej nie jest dobry pomysł w takiej sytuacji. OP ma zrobić prostą grę i nie zakopać się wcześniej w tonie kodu, zanim w ogóle wyświetli proste okienko. No i ma przy tym się nie zniechęcić

0

@tmk3: Podejrzewam, że @jvoytech nie zna prostszych alternatyw i wrzucił ten kod, żeby pokazać jak prosto w jego mniemaniu można pisać grę w C++.


@Romlus:
Jeśli miałbym zaproponować coś prostego, to spróbuj: https://love2d.org/
Już na stronie głównej są przykłady prostoty.
A w dokumentacji można szybko uzupełnić wiedzę, np.

W Love 2D dawno temu stworzono remake gry Super Mario Bros z mechanizmem portali:
https://stabyourself.net/mari0/

2

@Spine: śmiejesz się, że kupa kodu do naklepania w C++, a ile trzeba się naklikać w Unity, żeby namalować te kształty. :P

2

Najlatwiej w tym co znasz :P

Latwo np. w C++ i SFML:
Moze byc Pygame
Moze byc czysty JS albo JS + jakies libki 2d (np. Phaser).

Jak pojdziesz w cos w stylu Unity, to w tym sie robi szybko, ale dopiero po spedzeniu kilkuset godzin i ogarnieciu co gdzie i jak :P

0

Zacząłem się bawić tą gierką w Godocie i zdaje mi się, że jest najodpowiedniejszy do tego.

0
Romlus napisał(a):

Gra jest bardzo prosta. Trójkąt przesuwa się na boki i strzela w obiekty u góry planszy, obiekty strzelają do trójkąta. Jak trójkąt dostanie strzał zmienia się w ludzika, który jest bezbronny, nie strzela, gdy ludzik stanie pod czarnym kwadratem jest broniony przez ten kwadrat (trójkąt również jest broniony przez kwadrat) i zamienić się może w strzelający trójkąt ponownie, ale po zamianie w trójkąt czarny kwadrat znika. Są więc 3 kwadraty, czyli 3 szanse że po otrzymaniu strzału trójkąt może powrócić do gry i zlikwidować wszystkie obiekty u góry planszy. Są jeszcze inne elementy tej gry, ale szkielet jest taki.
W czym to najłatwiej wykonać? Może monogame byłoby dobre?

w JavaScript możesz.
Przy czym w JS masz różne możliwości do stworzenia grafiki.
Np.

  • możesz obiekty w grze napisać jako elementy HTML czy SVG - zaleta, że wszystko są to elementy na stronie, więc przeglądarka je rozumie i możesz np. zdarzenia myszy podczepić.
  • Canvas. Taki element HTML do rysowania. Przy czym rysuje się prosto, jednak sam będziesz musiał napisać kod do wykrywania kolizji, samemu przeliczać współrzędne itp.
  • Pixi.js, Fabric.js albo inna podobna biblioteka do grafiki 2D (które pod spodem korzystają z Canvas czy WebGL, ale opakowują to w wyższą abstrakcję i zawierają różne pomocnicze funkcje. Więc może być łatwiej).

1 użytkowników online, w tym zalogowanych: 0, gości: 1