very basic thing
parent
7579665e62
commit
b2eb646979
@ -0,0 +1,3 @@
|
||||
*.sw*
|
||||
*.o
|
||||
game
|
@ -0,0 +1,3 @@
|
||||
[submodule "entt"]
|
||||
path = entt
|
||||
url = https://github.com/skypjack/entt
|
@ -0,0 +1,14 @@
|
||||
CXXFLAGS := -std=c++23 -O0 -g3 -ggdb \
|
||||
-Ientt/single_include
|
||||
LDFLAGS := -lSDL2 -lSDL2_image
|
||||
|
||||
OBJS := $(subst .cpp,.o,$(wildcard *.cpp))
|
||||
|
||||
all: game
|
||||
|
||||
clean:
|
||||
rm -f game $(OBJS)
|
||||
|
||||
game: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
|
||||
|
@ -0,0 +1 @@
|
||||
Subproject commit 93f7d516f21e5f63422df983c02827ab1c8e050e
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1,184 @@
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
static constexpr auto WINDOW_WIDTH = 640;
|
||||
static constexpr auto WINDOW_HEIGHT = 480;
|
||||
|
||||
static SDL_Window *window = nullptr;
|
||||
static SDL_Renderer *renderer = nullptr;
|
||||
|
||||
static int sdl2Initialize();
|
||||
static SDL_Texture *sdl2LoadTexture(const char *path);
|
||||
|
||||
struct Player {
|
||||
char unused = 0;
|
||||
};
|
||||
|
||||
struct Vec2 {
|
||||
float x, y;
|
||||
|
||||
auto& operator+=(const Vec2& o) noexcept {
|
||||
x += o.x;
|
||||
y += o.y;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct Point : public Vec2 {};
|
||||
struct Velocity : public Vec2 {};
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
Texture(const char *path) {
|
||||
tex = sdl2LoadTexture(path);
|
||||
}
|
||||
|
||||
~Texture() {
|
||||
if (tex != nullptr)
|
||||
SDL_DestroyTexture(tex);
|
||||
}
|
||||
|
||||
void operator()(SDL_Renderer *rend, Point p) const noexcept {
|
||||
const int x = static_cast<int>(p.x);
|
||||
const int y = static_cast<int>(p.y);
|
||||
SDL_Rect rect {x, y, 0, 0};
|
||||
|
||||
/* TODO err check */
|
||||
SDL_QueryTexture(tex, nullptr, nullptr, &rect.w, &rect.h);
|
||||
SDL_RenderCopy(rend, tex, nullptr, &rect);
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_Texture *tex;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
if (auto err = sdl2Initialize(); err)
|
||||
return err;
|
||||
|
||||
entt::registry registry;
|
||||
|
||||
const auto ent = registry.create();
|
||||
registry.emplace<Player>(ent);
|
||||
registry.emplace<Point>(ent, 0.f, WINDOW_HEIGHT - 100.f);
|
||||
registry.emplace<Velocity>(ent, 0.f, 0.f);
|
||||
registry.emplace<Texture>(ent, "img/player.png");
|
||||
|
||||
SDL_Event e;
|
||||
bool quit = false;
|
||||
while (!quit) {
|
||||
const auto nextFrame = std::chrono::high_resolution_clock::now() +
|
||||
std::chrono::microseconds(1'000'000 / 60);
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
registry.view<Texture, Point>().each(
|
||||
[](Texture& tex, Point& p) { tex(renderer, p); });
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
registry.view<Velocity, Point>().each(
|
||||
[](Velocity& v, Point& p) { p += v; });
|
||||
|
||||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
quit = true;
|
||||
} else if (e.type == SDL_KEYDOWN) {
|
||||
auto view = registry.view<Player, Velocity>();
|
||||
|
||||
if (e.key.repeat) {
|
||||
// do nothing
|
||||
} else if (e.key.keysym.sym == SDLK_d) {
|
||||
view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
|
||||
} else if (e.key.keysym.sym == SDLK_a) {
|
||||
view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
|
||||
}
|
||||
} else if (e.type == SDL_KEYUP) {
|
||||
auto view = registry.view<Player, Velocity>();
|
||||
|
||||
if (e.key.repeat) {
|
||||
// do nothing
|
||||
} else if (e.key.keysym.sym == SDLK_d) {
|
||||
view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
|
||||
} else if (e.key.keysym.sym == SDLK_a) {
|
||||
view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_until(nextFrame);
|
||||
}
|
||||
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
int sdl2Initialize()
|
||||
{
|
||||
if (auto err = SDL_Init(SDL_INIT_VIDEO); err < 0) {
|
||||
std::cerr << "SDL error: " << SDL_GetError() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
atexit(SDL_Quit);
|
||||
}
|
||||
|
||||
if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
|
||||
std::cerr << "IMG error: " << IMG_GetError() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
atexit(IMG_Quit);
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow("game",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
WINDOW_WIDTH, WINDOW_HEIGHT,
|
||||
SDL_WINDOW_SHOWN);
|
||||
|
||||
if (window == nullptr) {
|
||||
std::cerr << "SDL error: " << SDL_GetError() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
atexit([] { SDL_DestroyWindow(window); });
|
||||
}
|
||||
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
if (renderer == nullptr) {
|
||||
std::cerr << "SDL error: " << SDL_GetError() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
atexit([] { SDL_DestroyRenderer(renderer); });
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Texture *sdl2LoadTexture(const char *path)
|
||||
{
|
||||
SDL_Texture *tex = nullptr;
|
||||
|
||||
auto surface = IMG_Load(path);
|
||||
if (surface == nullptr) {
|
||||
std::cerr << "Unable to load image " << path << '!' << std::endl;
|
||||
std::cerr << "SDL error: " << IMG_GetError() << std::endl;
|
||||
} else {
|
||||
tex = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
|
||||
if (tex == nullptr) {
|
||||
std::cerr << "Unable to create texture for " << path << '!' << std::endl;
|
||||
std::cerr << "SDL error: " << SDL_GetError() << std::endl;
|
||||
} else {
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
Loading…
Reference in New Issue