Field of view, discovered tiles, opaque fog of war rendering

This commit is contained in:
John McCardle 2023-03-10 19:39:44 -05:00
parent 9441f357df
commit 99fa92f8ba
4 changed files with 90 additions and 6 deletions

View File

@ -3,7 +3,7 @@
#include "Entity.h" #include "Entity.h"
GridPoint::GridPoint(): GridPoint::GridPoint():
color(0, 0, 0, 0), walkable(true), tilesprite(-1), transparent(true), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1) color(0, 0, 0, 0), walkable(false), tilesprite(-1), transparent(false), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1)
{}; {};
void Grid::setSprite(int ti) void Grid::setSprite(int ti)
@ -22,6 +22,7 @@ Grid::Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h):
//zoom = 1.0f; //zoom = 1.0f;
//grid_x = gx; //grid_x = gx;
//grid_y = gy; //grid_y = gy;
tcodmap = new TCODMap(gx, gy);
points.resize(gx*gy); points.resize(gx*gy);
box.setSize(sf::Vector2f(_w, _h)); box.setSize(sf::Vector2f(_w, _h));
box.setPosition(sf::Vector2f(_x, _y)); box.setPosition(sf::Vector2f(_x, _y));
@ -45,6 +46,33 @@ Grid::Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h):
sprite.setTexture(texture); sprite.setTexture(texture);
} }
void Grid::refreshTCODmap() {
int total = 0, walkable = 0, transparent = 0;
for (int x = 0; x < grid_x; x++) {
for (int y = 0; y < grid_y; y++) {
auto p = at(x, y);
total++; if (p.walkable) walkable++; if (p.transparent) transparent++;
tcodmap->setProperties(x, y, p.transparent, p.walkable);
}
}
std::cout << "Map refreshed: " << total << " squares, " << walkable << "walkable, " << transparent << " transparent" << std::endl;
}
void Grid::refreshTCODsight(int x, int y) {
tcodmap->computeFov(x,y);
for (int x = 0; x < grid_x; x++) {
for (int y = 0; y < grid_y; y++) {
auto& p = at(x, y);
if (p.visible && !tcodmap->isInFov(x, y)) {
p.discovered = true;
p.visible = false;
} else if (!p.visible && tcodmap->isInFov(x,y)) {
p.discovered = true;
p.visible = true;
}
}
}
}
bool Grid::inBounds(int x, int y) { bool Grid::inBounds(int x, int y) {
return (x >= 0 && y >= 0 && x < grid_x && y < grid_y); return (x >= 0 && y >= 0 && x < grid_x && y < grid_y);
} }
@ -231,9 +259,7 @@ void Grid::render(sf::RenderWindow & window)
renderTexture.draw(sprite); renderTexture.draw(sprite);
} }
// overlay
// uisprite
} }
} }
@ -248,6 +274,41 @@ void Grid::render(sf::RenderWindow & window)
renderTexture.draw(drawent); renderTexture.draw(drawent);
} }
// loop again and draw on top of entities
for (int x = (left_edge - 1 >= 0 ? left_edge - 1 : 0);
x < x_limit; //x < view_width;
x+=1)
{
//for (float y = (top_edge >= 0 ? top_edge : 0);
for (int y = (top_edge - 1 >= 0 ? top_edge - 1 : 0);
y < y_limit; //y < view_height;
y+=1)
{
auto pixel_pos = sf::Vector2f(
(x*grid_size - left_spritepixels) * zoom,
(y*grid_size - top_spritepixels) * zoom );
auto gridpoint = at(std::floor(x), std::floor(y));
sprite.setPosition(pixel_pos);
r.setPosition(pixel_pos);
// visible & discovered layers for testing purposes
if (!gridpoint.discovered) {
r.setFillColor(sf::Color(16, 16, 20, 255));
renderTexture.draw(r);
} else if (!gridpoint.visible) {
r.setFillColor(sf::Color(32, 32, 40, 128));
renderTexture.draw(r);
}
// overlay
// uisprite
}
}
// grid lines for testing & validation // grid lines for testing & validation
/* /*
sf::Vertex line[] = sf::Vertex line[] =

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "Common.h" #include "Common.h"
#include "libtcod.h"
//#include "Entity.h" //#include "Entity.h"
class Entity; // forward declare class Entity; // forward declare
@ -26,6 +28,7 @@ public:
sf::Texture texture; sf::Texture texture;
sf::Sprite sprite, output; sf::Sprite sprite, output;
sf::RenderTexture renderTexture; sf::RenderTexture renderTexture;
TCODMap* tcodmap;
void setSprite(int); void setSprite(int);
const int texture_width, texture_height; const int texture_width, texture_height;
auto contains(sf::Vector2i p) { return box.getGlobalBounds().contains(p.x, p.y); } auto contains(sf::Vector2i p) { return box.getGlobalBounds().contains(p.x, p.y); }
@ -46,4 +49,8 @@ public:
void renderPxToGrid(int, int, int&, int&); void renderPxToGrid(int, int, int&, int&);
void gridToRenderPx(int, int, int&, int&); void gridToRenderPx(int, int, int&, int&);
void integerGrid(float, float, int&, int&); void integerGrid(float, float, int&, int&);
void refreshTCODmap();
void refreshTCODsight(int, int);
TCODDijkstra *dijkstra; //= new TCODDijkstra(myMap);
}; };

View File

@ -91,6 +91,7 @@ static PyMethodDef mcrfpyMethods[] = {
{"turnNumber", McRFPy_API::_turnNumber, METH_VARARGS, ""}, {"turnNumber", McRFPy_API::_turnNumber, METH_VARARGS, ""},
{"createEntity", McRFPy_API::_createEntity, METH_VARARGS, ""}, {"createEntity", McRFPy_API::_createEntity, METH_VARARGS, ""},
//{"listEntities", McRFPy_API::_listEntities, METH_VARARGS, ""}, //{"listEntities", McRFPy_API::_listEntities, METH_VARARGS, ""},
{"refreshFov", McRFPy_API::_refreshFov, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -681,6 +682,12 @@ PyObject* McRFPy_API::_modGrid(PyObject* self, PyObject* args) {
grid->points[i].tile_overlay = PyLong_AsLong(PyObject_GetAttrString(gpointobj, "tile_overlay")); grid->points[i].tile_overlay = PyLong_AsLong(PyObject_GetAttrString(gpointobj, "tile_overlay"));
grid->points[i].uisprite = PyLong_AsLong(PyObject_GetAttrString(gpointobj, "uisprite")); grid->points[i].uisprite = PyLong_AsLong(PyObject_GetAttrString(gpointobj, "uisprite"));
} }
// update grid pathfinding & visibility
grid->refreshTCODmap();
for (auto e : McRFPy_API::entities.getEntities("player")) {
grid->refreshTCODsight(e->cGrid->x, e->cGrid->y);
}
} }
PyObject* entlist = PyObject_GetAttrString(o, "entities"); PyObject* entlist = PyObject_GetAttrString(o, "entities");
//std::cout << PyUnicode_AsUTF8(PyObject_Repr(entlist)) << std::endl; //std::cout << PyUnicode_AsUTF8(PyObject_Repr(entlist)) << std::endl;
@ -697,6 +704,14 @@ PyObject* McRFPy_API::_modGrid(PyObject* self, PyObject* args) {
return Py_None; return Py_None;
} }
PyObject* McRFPy_API::_refreshFov(PyObject* self, PyObject* args) {
for (auto e : McRFPy_API::entities.getEntities("player")) {
e->cGrid->grid->refreshTCODsight(e->cGrid->x, e->cGrid->y);
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* _test_createAnimation(PyObject *self, PyObject *args) { PyObject* _test_createAnimation(PyObject *self, PyObject *args) {
//LerpAnimation<T>::LerpAnimation(float _d, T _ev, T* _t, std::function<void()> _cb, std::function<void(T)> _w, bool _l) //LerpAnimation<T>::LerpAnimation(float _d, T _ev, T* _t, std::function<void()> _cb, std::function<void(T)> _w, bool _l)
std::string menu_key = "demobox1"; std::string menu_key = "demobox1";

View File

@ -106,6 +106,7 @@ public:
// turn cycle // turn cycle
static int turn_number; static int turn_number;
static PyObject* _turnNumber(PyObject*, PyObject*); static PyObject* _turnNumber(PyObject*, PyObject*);
static PyObject* _refreshFov(PyObject*, PyObject*);
// accept keyboard input from scene // accept keyboard input from scene
static sf::Vector2i cursor_position; static sf::Vector2i cursor_position;