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?
A co znasz?
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?
No to najlatwiej w tym co znasz.
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ć.
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.
Najprościej byłoby w jakimś dużym frameworku do gier jak Unity (c#), libdx (js, java) i pygame (python).
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.
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.
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?
@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
https://gamemaker.io/pl-PL  Kliknij
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();
}
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.
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. ;)
A w Unity dodajesz mesh na scenę, dodajesz do obiektu skrypt i w tym skrypcie już sobie programujesz samo zachowanie obiektu.
Kolor obiektu można zrealizować tworząc materiał, który potem trzeba podpiąć pod odpowiednie pole skryptu renderera dołączonego do obiektu.
@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ć
@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.
- rysowanie prostokąta: https://love2d.org/wiki/love.graphics.rectangle
- rysowanie wielokąta: https://love2d.org/wiki/love.graphics.polygon
W Love 2D dawno temu stworzono remake gry Super Mario Bros z mechanizmem portali:
https://stabyourself.net/mari0/
@Spine: śmiejesz się, że kupa kodu do naklepania w C++, a ile trzeba się naklikać w Unity, żeby namalować te kształty. :P
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
Zacząłem się bawić tą gierką w Godocie i zdaje mi się, że jest najodpowiedniejszy do tego.
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).