COLLISIONS, i forgot to commit but i also did a lot of other shit
This commit is contained in:
18
TODO
18
TODO
@@ -1,7 +1,17 @@
|
||||
[x] Dungeon generation
|
||||
[x] Tile movement / playable character
|
||||
[-] Tile collisions
|
||||
[ ] Lighting
|
||||
[ ] Gameplay
|
||||
[ ] Actually figure out Gameplay
|
||||
[X] Tile collisions
|
||||
|
||||
# Today
|
||||
|
||||
[-] Lighting (and torches)
|
||||
[ ] Lighting flicker (fire)
|
||||
[ ] NO TIME raytraced lighting
|
||||
[ ] Fix collision
|
||||
[ ] Better player spritesheet
|
||||
[ ] Animation system
|
||||
[ ] Enemies / AI
|
||||
[ ] Dungeon fixed entity spawning
|
||||
[ ] Enemy AI
|
||||
[ ] Gameplay
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
void Camera::Update(float fTime)
|
||||
{
|
||||
if (_Track == nullptr) return;
|
||||
_DesiredCoords.x = _Track->Coords.x - (ViewPort.x / 2);
|
||||
_DesiredCoords.y = _Track->Coords.y - (ViewPort.y / 2);
|
||||
_DesiredCoords = _Track->Coords - (ViewPort / 2);
|
||||
|
||||
float lerpX = std::lerp(Coords.x, _DesiredCoords.x, _SmoothSpeed);
|
||||
float lerpY = std::lerp(Coords.y, _DesiredCoords.y, _SmoothSpeed);
|
||||
|
||||
@@ -1,18 +1,64 @@
|
||||
#include "Collisions.hpp"
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "Things.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "Things.hpp"
|
||||
#include "Camera.hpp"
|
||||
#include "Collisions.hpp"
|
||||
|
||||
bool EntityCollide(Entity* entity, std::vector<Tile*>& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine)
|
||||
{
|
||||
if (!entity->HitBox) return false;
|
||||
|
||||
static Logger& _Logger = Logger::getInstance();
|
||||
|
||||
engine->SetDrawTarget(uint8_t(0));
|
||||
engine->Clear(olc::BLANK);
|
||||
|
||||
float entityX = static_cast<float>(entity->Coords.x - entity->TrackingCamera->Coords.x);
|
||||
float entityY = static_cast<float>(entity->Coords.y - entity->TrackingCamera->Coords.y);
|
||||
float entityW = static_cast<float>(tileSize / 3.0f) * 2.0f;
|
||||
float entityH = static_cast<float>(tileSize / 3.0f) * 2.0f;
|
||||
|
||||
int entityLeft = static_cast<int>(entityX);
|
||||
int entityRight = static_cast<int>(entityX + entityW);
|
||||
int entityTop = static_cast<int>(entityY);
|
||||
int entityBottom = static_cast<int>(entityY + entityH);
|
||||
|
||||
//engine->DrawRect({(entity->HitBox->x + (int)entity->Coords.x) - (int)entity->TrackingCamera->Coords.x, (entity->HitBox->y + (int)entity->Coords.y) - (int)entity->TrackingCamera->Coords.y}, {entity->HitBox->w, entity->HitBox->h}, olc::RED);
|
||||
|
||||
for (auto tile : nearby)
|
||||
{
|
||||
Logger::getInstance().Debug(tile->Coords.x, " ", tile->Coords.y);
|
||||
engine->DrawRect({ static_cast<int>((tile->Coords.x + tileSize) - entity->TrackingCamera->Coords.x), static_cast<int>((tile->Coords.y + tileSize) - entity->TrackingCamera->Coords.y) }, {tileSize, tileSize}, olc::RED);
|
||||
//engine->DrawRect({ static_cast<int>(static_cast<float>((tile->Coords.x * tileSize) - entity->TrackingCamera->Coords.x)), static_cast<int>(static_cast<float>((tile->Coords.y * tileSize) - entity->TrackingCamera->Coords.y)) }, {tileSize, tileSize}, olc::BLUE);
|
||||
|
||||
// return if not collidable
|
||||
if (!tile->IsSolid) continue;
|
||||
|
||||
int tileLeft = static_cast<int>(static_cast<float>(tile->Coords.x * tileSize) - entity->TrackingCamera->Coords.x);
|
||||
int tileRight = static_cast<int>(static_cast<float>(tile->Coords.x * tileSize) - entity->TrackingCamera->Coords.x) + tileSize;
|
||||
int tileTop = static_cast<int>(static_cast<float>(tile->Coords.y * tileSize) - entity->TrackingCamera->Coords.y);
|
||||
int tileBottom = static_cast<int>(static_cast<float>(tile->Coords.y * tileSize) - entity->TrackingCamera->Coords.y) + tileSize;
|
||||
|
||||
// _Logger.Debug(entityLeft, " ", tileRight);
|
||||
|
||||
bool xOverlaps = (entityLeft <= tileRight) && (entityRight >= tileLeft);
|
||||
bool yOverlaps = (entityTop <= tileBottom) && (entityBottom >= tileTop);
|
||||
|
||||
bool collision = xOverlaps && yOverlaps;
|
||||
|
||||
//engine->FillRect({static_cast<int>(static_cast<float>((tile->Coords.x * tileSize) - entity->TrackingCamera->Coords.x)), static_cast<int>(static_cast<float>((tile->Coords.y * tileSize) - entity->TrackingCamera->Coords.y))}, {tileSize, tileSize}, collision ? olc::RED : olc::BLUE);
|
||||
|
||||
if (!collision) continue;
|
||||
|
||||
info->TileCollided = tile;
|
||||
|
||||
//info->CollidingX = xOverlaps;
|
||||
//info->CollidingY = yOverlaps;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,13 @@ class Collider
|
||||
class CollisionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
Tile* TileCollided;
|
||||
bool CollidingX;
|
||||
bool CollidingY;
|
||||
};
|
||||
|
||||
bool EntityCollide(Entity* entity, std::vector<Tile*>& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,18 +17,14 @@ Dungeon::Dungeon()
|
||||
|
||||
Player = new Playable();
|
||||
|
||||
Player->Coords = { 0, 0 };
|
||||
Player->Coords = { 2, 2 };
|
||||
Player->Type = EEntity::Type::Player;
|
||||
// Relative to player TL corner
|
||||
// not really used ? lol
|
||||
Player->HitBox = new Collider{ 0, 0, static_cast<int>((static_cast<float>(TileSize) / 3.0f) * 2.0f), static_cast<int>((static_cast<float>(TileSize) / 3.0f) * 2.0f) } ;
|
||||
|
||||
ActiveCamera->TrackEntity(Player);
|
||||
ActiveCamera->Update(0.0f);
|
||||
}
|
||||
|
||||
void Dungeon::Generate()
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
TileSetDictionary = new TileDictionary();
|
||||
TileSetDictionary->Register();
|
||||
@@ -37,6 +33,15 @@ void Dungeon::Generate()
|
||||
TileSet->Load("res/dungeon_tileset.png");
|
||||
_Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->Sprite()->width, " ", TileSet->Sprite()->height);
|
||||
|
||||
FireOverlay = new olc::Renderable();
|
||||
FireOverlay->Load("res/torch.png");
|
||||
|
||||
}
|
||||
|
||||
void Dungeon::Generate()
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
DungeonWidth = 0;
|
||||
DungeonHeight = 0;
|
||||
|
||||
@@ -58,7 +63,7 @@ void Dungeon::Generate()
|
||||
|
||||
int directionChance = 5;
|
||||
int roomChance = 5;
|
||||
int dungeonMinSize = 5000;
|
||||
int dungeonMinSize = 3000;
|
||||
|
||||
struct Agent
|
||||
{
|
||||
@@ -188,6 +193,8 @@ void Dungeon::SpawnEntity(Entity* entity)
|
||||
|
||||
void Dungeon::Input(olc::PixelGameEngine* engine, float fTime)
|
||||
{
|
||||
olc::vf2d oldCoords = Player->Coords;
|
||||
|
||||
if (engine->GetKey(olc::W).bHeld)
|
||||
Player->Coords.y -= static_cast<float>(TileSize) * (fTime * Player->Speed);
|
||||
if (engine->GetKey(olc::A).bHeld)
|
||||
@@ -217,55 +224,95 @@ void Dungeon::Input(olc::PixelGameEngine* engine, float fTime)
|
||||
Player->Coords.y -= static_cast<float>(TileSize) * (fTime * (Player->Speed / 3.0f));
|
||||
Player->Coords.x += static_cast<float>(TileSize) * (fTime * (Player->Speed / 3.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Dungeon::Update(olc::PixelGameEngine* engine, float fTime)
|
||||
{
|
||||
|
||||
// Map collisions
|
||||
|
||||
olc::vi2d currentTile = { static_cast<int>(Player->Coords.x / TileSize), static_cast<int>(Player->Coords.y / TileSize) };
|
||||
|
||||
static olc::vi2d lastTile;
|
||||
|
||||
auto IsMapMember = [&] (int x, int y) {
|
||||
std::unordered_map<olc::vi2d, Tile*>::const_iterator found = DungeonTiles.find({x, y});
|
||||
if (found == DungeonTiles.end()) return false;
|
||||
return false;
|
||||
};
|
||||
|
||||
if (lastTile != currentTile)
|
||||
_Logger.Debug("Player Tile: ", currentTile.x, " ", currentTile.y);
|
||||
|
||||
auto IsMapMember = [&] (int x, int y) {
|
||||
std::unordered_map<olc::vi2d, Tile*>::const_iterator found = DungeonTiles.find({x, y});
|
||||
return found != DungeonTiles.end();
|
||||
};
|
||||
|
||||
auto IsNeighbouringMapMember = [&] (int x, int y) {
|
||||
if (IsMapMember(x + 1, y)) return true;
|
||||
if (IsMapMember(x - 1, y)) return true;
|
||||
if (IsMapMember(x, y + 1)) return true;
|
||||
if (IsMapMember(x, y - 1)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
// get nearby collidables
|
||||
std::vector<Tile*> nearbyCollidables;
|
||||
|
||||
for (int x = currentTile.x - 2; x <= currentTile.x + 2; x++)
|
||||
for (int y = currentTile.y - 2; y <= currentTile.y + 2; y++)
|
||||
for (int x = currentTile.x - 1; x <= currentTile.x + 1; x++)
|
||||
for (int y = currentTile.y - 1; y <= currentTile.y + 1; y++)
|
||||
{
|
||||
//_Logger.Debug("IsMapMember ", x, " ", y, " ", IsMapMember(x,y));
|
||||
//_Logger.Debug("IsNeighbouringMapMember ", x, " ", y, " ", IsNeighbouringMapMember(x,y));
|
||||
|
||||
// If isnt in the map but borders a map tile, add a void type for collision
|
||||
if (IsMapMember(x,y))
|
||||
{
|
||||
nearbyCollidables.push_back(DungeonTiles[{x, y}]);
|
||||
} else
|
||||
{
|
||||
if (IsNeighbouringMapMember(x,y))
|
||||
nearbyCollidables.push_back(new Tile({x, y}, ETile::Type::Void, ETile::State::Default));
|
||||
}
|
||||
}
|
||||
|
||||
// Passes ownership back
|
||||
CollisionInfo* collisionInfo = new CollisionInfo();
|
||||
bool colliding = EntityCollide(Player, nearbyCollidables, TileSize, collisionInfo, engine);
|
||||
CollisionInfo collisionInfo;
|
||||
bool colliding = EntityCollide(Player, nearbyCollidables, TileSize, &collisionInfo, engine);
|
||||
|
||||
delete collisionInfo;
|
||||
// collision response
|
||||
if (colliding)
|
||||
Player->Coords = oldCoords;
|
||||
|
||||
//if (collisionInfo.CollidingY)
|
||||
//Player->Coords.y = oldCoords.y;
|
||||
//if (collisionInfo.CollidingX)
|
||||
//Player->Coords.x = oldCoords.x;
|
||||
|
||||
// delete nearbyCollidables that are void
|
||||
for (int i = 0; i < nearbyCollidables.size(); i++)
|
||||
{
|
||||
if (nearbyCollidables[i]->Type == ETile::Type::Void)
|
||||
delete nearbyCollidables[i];
|
||||
}
|
||||
|
||||
lastTile = currentTile;
|
||||
}
|
||||
|
||||
void Dungeon::Update(olc::PixelGameEngine* engine, float fTime)
|
||||
{
|
||||
ActiveCamera->Update(fTime);
|
||||
}
|
||||
|
||||
olc::Pixel pixelMultiply(const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest)
|
||||
{
|
||||
olc::Pixel ret;
|
||||
ret.r = pDest.r * pSource.r;
|
||||
ret.g = pDest.g * pSource.g;
|
||||
ret.b = pDest.b * pSource.b;
|
||||
ret.a = pDest.a * pSource.a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Dungeon::Draw(olc::PixelGameEngine* engine)
|
||||
{
|
||||
// Maps not gonna be big enough for me to care about optimistaion
|
||||
// maybe i should care? i don't :^)
|
||||
// maybe i should care? i don't
|
||||
|
||||
//engine->SetDrawTarget(4);
|
||||
//engine->Clear({38, 36, 40});
|
||||
// Entities are always (tilesize / 3) * 2
|
||||
|
||||
engine->SetDrawTarget(1);
|
||||
// Dungeon Layer
|
||||
engine->SetDrawTarget(4);
|
||||
engine->Clear({38, 36, 40});
|
||||
|
||||
engine->SetPixelMode(olc::Pixel::ALPHA);
|
||||
@@ -279,14 +326,38 @@ void Dungeon::Draw(olc::PixelGameEngine* engine)
|
||||
|
||||
// engine->SetPixelMode(olc::Pixel::NORMAL);
|
||||
|
||||
engine->SetDrawTarget(static_cast<uint8_t>(0));
|
||||
// Entity Layer
|
||||
engine->SetDrawTarget(3);
|
||||
engine->Clear(olc::BLANK);
|
||||
|
||||
// Draw character
|
||||
engine->DrawPartialDecal({ static_cast<float>(Player->Coords.x - ActiveCamera->Coords.x), static_cast<float>(Player->Coords.y - ActiveCamera->Coords.y) },
|
||||
{ (static_cast<float>(TileSize) / 3.0f) * 2.0f, (static_cast<float>(TileSize) / 3.0f) * 2.0f }, TileSet->Decal(), { 143, 130 }, { 16, 16 });
|
||||
|
||||
engine->DrawRect({(Player->HitBox->x + (int)Player->Coords.x) - (int)ActiveCamera->Coords.x, (Player->HitBox->y + (int)Player->Coords.y) - (int)ActiveCamera->Coords.y}, {Player->HitBox->w, Player->HitBox->h}, olc::RED);
|
||||
// Lighting layers
|
||||
engine->SetDrawTarget(2);
|
||||
engine->Clear(olc::BLANK);
|
||||
|
||||
static std::function<olc::Pixel(const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest)> fPixelMultiply = pixelMultiply;
|
||||
|
||||
float lightX = static_cast<float>(Player->Coords.x - ActiveCamera->Coords.x) - (FireOverlay->Sprite()->width / 2.0f);
|
||||
float lightY = static_cast<float>(Player->Coords.y - ActiveCamera->Coords.y) - (FireOverlay->Sprite()->height / 2.0f);
|
||||
|
||||
float lightLeft = lightX;
|
||||
float lightRight = lightX + FireOverlay->Sprite()->width;
|
||||
float lightTop = lightY;
|
||||
float lightBottom = lightY + FireOverlay->Sprite()->height;
|
||||
|
||||
engine->SetPixelMode(fPixelMultiply);
|
||||
engine->DrawDecal({ lightX, lightY }, FireOverlay->Decal());
|
||||
|
||||
engine->SetDrawTarget(1);
|
||||
engine->Clear(olc::BLANK);
|
||||
// top
|
||||
|
||||
engine->FillRect({0, static_cast<int>(lightTop)}, {engine->ScreenWidth(), engine->ScreenHeight()}, olc::BLACK);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Dungeon::~Dungeon()
|
||||
@@ -295,7 +366,6 @@ Dungeon::~Dungeon()
|
||||
delete ActiveCamera;
|
||||
delete TileSetDictionary;
|
||||
delete TileSet;
|
||||
delete DungeonRenderTarget;
|
||||
for (std::pair<olc::vi2d, Tile*> tile : DungeonTiles)
|
||||
delete tile.second;
|
||||
for (std::pair<olc::vi2d, Entity*> entity : Entities)
|
||||
|
||||
@@ -31,7 +31,7 @@ class Dungeon
|
||||
Playable* Player;
|
||||
Camera* ActiveCamera;
|
||||
|
||||
int TileSize = 32;
|
||||
int TileSize = 64;
|
||||
|
||||
int DungeonWidth;
|
||||
int DungeonHeight;
|
||||
@@ -42,7 +42,7 @@ class Dungeon
|
||||
TileDictionary* TileSetDictionary;
|
||||
olc::Renderable* TileSet;
|
||||
|
||||
olc::Renderable* DungeonRenderTarget;
|
||||
olc::Renderable* FireOverlay;
|
||||
|
||||
~Dungeon();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
The Great Machine/res/torch.png
Normal file
BIN
The Great Machine/res/torch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
BIN
res/torch.png
Normal file
BIN
res/torch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
Reference in New Issue
Block a user