Implemented grid. Modified map renderer so that it can render tiles that have a different size than the map tiles. (Note: this change is not tested yet).
This commit is contained in:
146
src/components/basic/Grid.cpp
Normal file
146
src/components/basic/Grid.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Grid.cpp
|
||||
*
|
||||
* Created on: Dec 4, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#include <components/basic/Grid.h>
|
||||
#include <components/basic/Transform.h>
|
||||
#include <utils/Assert.h>
|
||||
#include <utils/Exceptions.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace farmlands::model;
|
||||
using namespace farmlands::utils;
|
||||
|
||||
namespace farmlands {
|
||||
namespace components {
|
||||
namespace basic {
|
||||
|
||||
Grid::Grid()
|
||||
: m_bounds(0, 0, 1, 1),
|
||||
m_grid(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Grid::~Grid()
|
||||
{
|
||||
if (m_grid != nullptr)
|
||||
delete[] m_grid;
|
||||
}
|
||||
|
||||
model::Component* Grid::clone()
|
||||
{
|
||||
Grid* clone = new Grid();
|
||||
clone->m_bounds = m_bounds;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
void Grid::dump(unsigned level)
|
||||
{
|
||||
for (unsigned i = 0; i < level; i++)
|
||||
std::cout<<" ";
|
||||
|
||||
std::cout << " .Component: Grid bounds=[";
|
||||
std::cout << m_bounds.x << "," << m_bounds.y << ",";
|
||||
std::cout << m_bounds.w << "," << m_bounds.h << "]\n";
|
||||
}
|
||||
|
||||
void Grid::onInitialize()
|
||||
{
|
||||
// Allocate memory
|
||||
m_grid = new model::GameObject*[m_bounds.w * m_bounds.h];
|
||||
memset(m_grid, 0, sizeof(model::GameObject*) * m_bounds.w * m_bounds.h);
|
||||
|
||||
// Add objects
|
||||
for (auto it = gameObject->childrenBegin(); it != gameObject->childrenEnd(); it++)
|
||||
{
|
||||
GameObject* obj = *it;
|
||||
|
||||
// Get transform
|
||||
Transform* tr = obj->component<Transform>();
|
||||
if (tr == nullptr)
|
||||
{
|
||||
std::cerr << "Grid: ignoring object " << obj->name << ": object has no transform.";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compute grid position(s)
|
||||
Rect<int> bounds(tr->x, tr->y, roundf(tr->w), roundf(tr->h));
|
||||
if (!bounds.intersects(m_bounds))
|
||||
{
|
||||
std::cerr << "Grid: ignoring object " << obj->name << ": object outside allowed bounds.";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set
|
||||
for (int y = bounds.y; y < bounds.y + bounds.h; y++)
|
||||
for (int x = bounds.x; x < bounds.x + bounds.w; x++)
|
||||
set(obj, x, y, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::setBounds(const utils::Rect<int>& bounds)
|
||||
{
|
||||
if (m_grid == nullptr)
|
||||
m_bounds = bounds;
|
||||
|
||||
else
|
||||
{
|
||||
// Get rid of old grid
|
||||
delete[] m_grid;
|
||||
m_grid = nullptr;
|
||||
|
||||
m_bounds = bounds;
|
||||
|
||||
// Reinitialize
|
||||
onInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
utils::Rect<int> Grid::bounds() const
|
||||
{
|
||||
return m_bounds;
|
||||
}
|
||||
|
||||
model::GameObject* Grid::get(int x, int y)
|
||||
{
|
||||
Assert(m_grid != nullptr, "Grid not initialized!!!");
|
||||
|
||||
if (m_bounds.contains(x, y))
|
||||
{
|
||||
int gx = x - m_bounds.x;
|
||||
int gy = y - m_bounds.y;
|
||||
|
||||
return m_grid[gy * m_bounds.w + gx];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Grid::set(model::GameObject* obj, int x, int y, bool throwOnOverwrite)
|
||||
{
|
||||
int gx = x - m_bounds.x;
|
||||
int gy = y - m_bounds.y;
|
||||
int index = gy * m_bounds.w + gx;
|
||||
|
||||
if (m_grid[index] != nullptr)
|
||||
{
|
||||
if (throwOnOverwrite)
|
||||
THROW(InvalidArgumentException, "Position already occupied!");
|
||||
else
|
||||
{
|
||||
std::cerr << "Grid: cannot set " << obj->name << " to position " << x << ", " << y;
|
||||
std::cerr << ": cell already occupied";
|
||||
}
|
||||
}
|
||||
|
||||
m_grid[index] = obj;
|
||||
}
|
||||
|
||||
} /* namespace basic */
|
||||
} /* namespace components */
|
||||
} /* namespace farmlands */
|
Reference in New Issue
Block a user