You can now set a sprite as a background in Background which will simplify a lot of games that just place sprites over a single image.
This commit is contained in:
parent
6fb20c5085
commit
e1d61dc2c1
9 changed files with 79 additions and 22 deletions
|
@ -81,7 +81,12 @@ struct ClickerUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser, {0, 0, 0, 255}});
|
guecs::Background bg{$gui.$parser, };
|
||||||
|
|
||||||
|
bg.set_color({0, 0, 0, 255});
|
||||||
|
bg.set_sprite("clicker_treat_bone");
|
||||||
|
|
||||||
|
$gui.set<guecs::Background>($gui.MAIN, bg);
|
||||||
|
|
||||||
for(auto& [name, cell] : $gui.cells()) {
|
for(auto& [name, cell] : $gui.cells()) {
|
||||||
auto id = $gui.entity(name);
|
auto id = $gui.entity(name);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
namespace lel {
|
namespace lel {
|
||||||
|
|
||||||
struct Cell {
|
struct Cell {
|
||||||
|
int col = 0;
|
||||||
|
int row = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int w = 0;
|
int w = 0;
|
||||||
|
@ -15,16 +17,11 @@ namespace lel {
|
||||||
int mid_y = 0;
|
int mid_y = 0;
|
||||||
int max_w = 0;
|
int max_w = 0;
|
||||||
int max_h = 0;
|
int max_h = 0;
|
||||||
int col = 0;
|
|
||||||
int row = 0;
|
|
||||||
bool right = false;
|
bool right = false;
|
||||||
bool bottom = false;
|
bool bottom = false;
|
||||||
bool expand = false;
|
bool expand = false;
|
||||||
bool center = false;
|
bool center = false;
|
||||||
bool percent = false;
|
bool percent = false;
|
||||||
|
|
||||||
Cell(int col, int row) : col(col), row(row) {}
|
|
||||||
Cell() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using Row = std::vector<std::string>;
|
using Row = std::vector<std::string>;
|
||||||
|
@ -36,16 +33,17 @@ namespace lel {
|
||||||
int grid_w = 0;
|
int grid_w = 0;
|
||||||
int grid_h = 0;
|
int grid_h = 0;
|
||||||
Cell cur;
|
Cell cur;
|
||||||
|
Cell main;
|
||||||
std::vector<Row> grid;
|
std::vector<Row> grid;
|
||||||
CellMap cells;
|
CellMap cells;
|
||||||
|
|
||||||
Parser(int x, int y, int width, int height);
|
Parser(int x, int y, int width, int height);
|
||||||
Parser();
|
Parser() : cur{.col=0, .row=0} {};
|
||||||
|
|
||||||
void position(int x, int y, int width, int height);
|
void position(int x, int y, int width, int height);
|
||||||
void id(std::string name);
|
void id(const std::string& name);
|
||||||
void reset();
|
void reset();
|
||||||
bool parse(std::string input);
|
bool parse(const std::string& input);
|
||||||
void finalize();
|
void finalize();
|
||||||
std::optional<std::string> hit(int x, int y);
|
std::optional<std::string> hit(int x, int y);
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,6 +104,7 @@ namespace guecs {
|
||||||
float h = 0.0f;
|
float h = 0.0f;
|
||||||
sf::Color color=THEME.BG_COLOR;
|
sf::Color color=THEME.BG_COLOR;
|
||||||
shared_ptr<sf::RectangleShape> shape = nullptr;
|
shared_ptr<sf::RectangleShape> shape = nullptr;
|
||||||
|
shared_ptr<sf::Sprite> sprite = nullptr;
|
||||||
|
|
||||||
Background(lel::Parser& parser, sf::Color bg_color=THEME.BG_COLOR) :
|
Background(lel::Parser& parser, sf::Color bg_color=THEME.BG_COLOR) :
|
||||||
x(parser.grid_x),
|
x(parser.grid_x),
|
||||||
|
@ -117,5 +118,8 @@ namespace guecs {
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void render(sf::RenderWindow& window);
|
void render(sf::RenderWindow& window);
|
||||||
|
|
||||||
|
void set_color(sf::Color c);
|
||||||
|
void set_sprite(const std::string& name, bool stretch=false);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,36 @@ namespace lel {
|
||||||
grid_x(x),
|
grid_x(x),
|
||||||
grid_y(y),
|
grid_y(y),
|
||||||
grid_w(width),
|
grid_w(width),
|
||||||
grid_h(height),
|
grid_h(height)
|
||||||
cur(0, 0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser() : cur(0, 0) { }
|
|
||||||
|
|
||||||
void Parser::position(int x, int y, int width, int height) {
|
void Parser::position(int x, int y, int width, int height) {
|
||||||
grid_x = x;
|
grid_x = x;
|
||||||
grid_y = y;
|
grid_y = y;
|
||||||
grid_w = width;
|
grid_w = width;
|
||||||
grid_h = height;
|
grid_h = height;
|
||||||
|
|
||||||
|
// used in GUIs for setting backgrounds
|
||||||
|
main = {
|
||||||
|
.x=grid_x,
|
||||||
|
.y=grid_y,
|
||||||
|
.w=grid_w,
|
||||||
|
.h=grid_h,
|
||||||
|
.mid_x=std::midpoint(grid_x, grid_x + grid_w),
|
||||||
|
.mid_y=std::midpoint(grid_y, grid_y + grid_h),
|
||||||
|
.max_w=grid_w,
|
||||||
|
.max_h=grid_h
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::id(std::string name) {
|
void Parser::id(const std::string& name) {
|
||||||
if(name != "_") {
|
if(name != "_") {
|
||||||
assert(!cells.contains(name) && "duplicate cell name");
|
assert(!cells.contains(name) && "duplicate cell name");
|
||||||
cells.insert_or_assign(name, cur);
|
cells.insert_or_assign(name, cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = {cur.col + 1, cur.row};
|
cur = {.col=cur.col + 1, .row=cur.row};
|
||||||
auto& row = grid.back();
|
auto& row = grid.back();
|
||||||
row.push_back(name);
|
row.push_back(name);
|
||||||
}
|
}
|
||||||
|
@ -87,15 +96,18 @@ namespace lel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::reset() {
|
void Parser::reset() {
|
||||||
cur = {0, 0};
|
cur = {.col=0, .row=0};
|
||||||
|
main = {.col=0, .row=0};
|
||||||
grid.clear();
|
grid.clear();
|
||||||
cells.clear();
|
cells.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Parser::hit(int x, int y) {
|
std::optional<std::string> Parser::hit(int x, int y) {
|
||||||
for(auto& [name, cell] : cells) {
|
for(auto& [name, cell] : cells) {
|
||||||
if((x >= cell.x && x <= cell.x + cell.w) &&
|
if(name != "_MAIN" &&
|
||||||
(y >= cell.y && y <= cell.y + cell.h)) {
|
(x >= cell.x && x <= cell.x + cell.w) &&
|
||||||
|
(y >= cell.y && y <= cell.y + cell.h))
|
||||||
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +118,7 @@ namespace lel {
|
||||||
Cell center(int width, int height, Cell &parent) {
|
Cell center(int width, int height, Cell &parent) {
|
||||||
Cell copy = parent;
|
Cell copy = parent;
|
||||||
|
|
||||||
|
// BUG: could I use std::midpoint here or am I even using this?
|
||||||
copy.x = parent.mid_x - width / 2;
|
copy.x = parent.mid_x - width / 2;
|
||||||
copy.y = parent.mid_y - height / 2;
|
copy.y = parent.mid_y - height / 2;
|
||||||
copy.w = width;
|
copy.w = width;
|
||||||
|
|
|
@ -86,7 +86,7 @@ static const int Parser_en_main = 1;
|
||||||
|
|
||||||
#line 44 "src/guecs/lel_parser.rl"
|
#line 44 "src/guecs/lel_parser.rl"
|
||||||
|
|
||||||
bool Parser::parse(std::string input) {
|
bool Parser::parse(const std::string& input) {
|
||||||
reset();
|
reset();
|
||||||
int cs = 0;
|
int cs = 0;
|
||||||
const char *start = nullptr;
|
const char *start = nullptr;
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace lel {
|
||||||
|
|
||||||
%% write data;
|
%% write data;
|
||||||
|
|
||||||
bool Parser::parse(std::string input) {
|
bool Parser::parse(const std::string& input) {
|
||||||
reset();
|
reset();
|
||||||
int cs = 0;
|
int cs = 0;
|
||||||
const char *start = nullptr;
|
const char *start = nullptr;
|
||||||
|
|
|
@ -121,10 +121,38 @@ namespace guecs {
|
||||||
assert(shape != nullptr && "failed to make rectangle");
|
assert(shape != nullptr && "failed to make rectangle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Background::set_color(sf::Color c) {
|
||||||
|
color = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Background::set_sprite(const std::string& name, bool stretch) {
|
||||||
|
auto sprite_texture = BACKEND->texture_get(name);
|
||||||
|
|
||||||
|
sprite = make_shared<sf::Sprite>(
|
||||||
|
*sprite_texture.texture,
|
||||||
|
sprite_texture.sprite->getTextureRect());
|
||||||
|
|
||||||
|
sprite->setPosition({float(x), float(y)});
|
||||||
|
|
||||||
|
if(stretch) {
|
||||||
|
auto bounds = sprite->getLocalBounds();
|
||||||
|
|
||||||
|
sprite->setScale({
|
||||||
|
float(w) / bounds.size.x,
|
||||||
|
float(h) / bounds.size.y});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Background::render(sf::RenderWindow& window) {
|
void Background::render(sf::RenderWindow& window) {
|
||||||
|
if(shape != nullptr) {
|
||||||
window.draw(*shape);
|
window.draw(*shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sprite != nullptr) {
|
||||||
|
window.draw(*sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Effect::init(lel::Cell &cell) {
|
void Effect::init(lel::Cell &cell) {
|
||||||
$shader = BACKEND->shader_get(name);
|
$shader = BACKEND->shader_get(name);
|
||||||
$shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)}));
|
$shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)}));
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace guecs {
|
||||||
|
|
||||||
bool UI::mouse(float x, float y, bool hover) {
|
bool UI::mouse(float x, float y, bool hover) {
|
||||||
int action_count = 0;
|
int action_count = 0;
|
||||||
// BUG: use lel::Parser.hit instead of this
|
// BUG: Is Parser::hit useful?
|
||||||
|
|
||||||
query<lel::Cell>([&](auto ent, auto& cell) {
|
query<lel::Cell>([&](auto ent, auto& cell) {
|
||||||
if((x >= cell.x && x <= cell.x + cell.w) &&
|
if((x >= cell.x && x <= cell.x + cell.w) &&
|
||||||
|
|
|
@ -21,6 +21,15 @@ TEST_CASE("test basic ops", "[lel]") {
|
||||||
auto &name = row[colcount];
|
auto &name = row[colcount];
|
||||||
if(name == "_") {
|
if(name == "_") {
|
||||||
REQUIRE(!parser.cells.contains(name));
|
REQUIRE(!parser.cells.contains(name));
|
||||||
|
} else if(name == "_MAIN") {
|
||||||
|
// it's the main cell which covers the whole area
|
||||||
|
auto &cell = parser.cells.at(name);
|
||||||
|
REQUIRE(cell.row == 0);
|
||||||
|
REQUIRE(cell.col == 0);
|
||||||
|
REQUIRE(cell.x == parser.grid_x);
|
||||||
|
REQUIRE(cell.y == parser.grid_y);
|
||||||
|
REQUIRE(cell.w == parser.grid_w);
|
||||||
|
REQUIRE(cell.h == parser.grid_h);
|
||||||
} else {
|
} else {
|
||||||
auto &cell = parser.cells.at(name);
|
auto &cell = parser.cells.at(name);
|
||||||
REQUIRE(cell.row == int(rowcount));
|
REQUIRE(cell.row == int(rowcount));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue